iOS开发之SceneKit框架--实战地月系统围绕太阳旋转

  

 

1、创建地月太阳系统scn文件

  注意:moon在earth结构下,earth和moon在sun结构下。

 

2、获取scn中模型的对应节点和自转(太阳为例)

  • 获取节点: name是对应的Identity字符串
    self.sunNode = [scene.rootNode childNodeWithName:@"sun" recursively:YES];

  • 自转:围绕Y轴旋转
    [self.sunNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:1 z:0 duration:1]]];

 

3、地月系统的公转和月亮公转

  • 月亮公转是围绕地球的中心转,但是旋转动画只会围绕自身的轴旋转,所以将moonNode添加到earthNode,这样月球的公转和地球自转一样;
  • 但是月亮公转不和地球自转一致,所以需要新建node节点,位置和地球node一样,将moomNode添加到新建的node上,新建node添加到地球node;
    //新建月球公转node和设置旋转
    self.moonRotationNode = [SCNNode node];
    self.moonRotationNode.position = self.sunNode.position;
    [self.moonRotationNode addChildNode: self.moonNode];
    [self.earthNode addChildNode:self.moonRotationNode];
    [self.moonRotationNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:3 z:0 duration:1]]];
  • 同样地月系统也新建node与太阳node位置相同,添加到太阳node上
    //新建地月系统和设置旋转
    self.earthGroupNode = [SCNNode node];
    self.earthGroupNode.position = self.sunNode.position;
    [self.earthGroupNode addChildNode:self.earthNode];
    [self.earthGroupNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:1 z:0 duration:1]]];
    [self.sunNode addChildNode:self.earthGroupNode];

 

4、父子node的关系

  • 每个node节点都拥有一个以自身为原点的坐标系

  注意:之前提到需要注意结构层次 正确的层次moon在earth下

 

  错误的层次 moon在sun下 

  • 这个模型的节点树

  说明:moonNode应该在earthNode下,此时位置为(2,0,0)。如果是错误层次位置就是(12,0,0)。效果就像上面一样。

  •  对父node添加的动画也会作用于所有的子node

  说明:地球围绕太阳公转,但没有设置月球围绕太阳转的动画?

       但是月球在地球的层次下,地月系统都是太阳的子node,所有动画就作用于月球上。

 

5、相关代码

- (void)viewDidLoad
{
    [super viewDidLoad];

    SCNScene *scene = [SCNScene sceneNamed:@"art.scnassets/sun.scn"];
    SCNNode *cameraNode = [SCNNode node];
    cameraNode.camera = [SCNCamera camera];
    [scene.rootNode addChildNode:cameraNode];
    cameraNode.position = SCNVector3Make(0, 0, 45);
    
    self.sCNView= (SCNView *)self.view;
    self.sCNView.scene = scene;
    self.sCNView.allowsCameraControl = YES;
    self.sCNView.showsStatistics = YES;
    self.sCNView.autoenablesDefaultLighting = YES;

    
    self.sunNode = [scene.rootNode childNodeWithName:@"sun" recursively:YES];
    [self.sunNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:1 z:0 duration:1]]];
    [self.sCNView.scene.rootNode addChildNode:self.sunNode];
    
    self.lightNode = [scene.rootNode childNodeWithName:@"sunOmni" recursively:YES];
    self.earthNode = [scene.rootNode childNodeWithName:@"earth" recursively:YES];
    [self.earthNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:2 z:0 duration:1]]];
    
    //新建地月系统和设置旋转
    self.earthGroupNode = [SCNNode node];
    self.earthGroupNode.position = self.sunNode.position;
    [self.earthGroupNode addChildNode:self.earthNode];
    [self.earthGroupNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:1 z:0 duration:1]]];
    [self.sunNode addChildNode:self.earthGroupNode];
    
    //获取月球node和设置自转
    self.moonNode = [scene.rootNode childNodeWithName:@"moon" recursively:YES];
    [self.moonNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:4 z:0 duration:1]]];
    
    //新建月球公转node和设置旋转
    self.moonRotationNode = [SCNNode node];
    self.moonRotationNode.position = self.sunNode.position;
    [self.moonRotationNode addChildNode: self.moonNode];
    [self.earthNode addChildNode:self.moonRotationNode];
    [self.moonRotationNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:3 z:0 duration:1]]];
}

 

posted @ 2018-05-15 13:56  ForeverGuard  阅读(890)  评论(0编辑  收藏  举报