Revolve a SCNode object in the 3D Space using SceneKit

丶灬走出姿态 提交于 2019-11-30 05:23:06

SceneKit doesn't provide an animate-along-path API. There are several ways to set up something like a solar system, though.

  1. Ever seen an orrery? This is the model that bit in the SCNNode documentation is talking about; it's also what the WWDC presentation does on the "Scene Graph Summary" slide. The trick is that you use one node to represent the frame of reference for a planet's revolution around the sun — like the armature that holds a planet in an orrery, if you make this node rotate around its central axis, any child node you attach to it will follow a circular path. The relevant code for this is in ASCSceneGraphSummary.m in that sample code project (condensed to just show node hierarchy setup here):

    // Sun
    _sunNode = [SCNNode node];
    _sunNode.position = SCNVector3Make(0, 30, 0);
    [self.contentNode addChildNode:_sunNode];
    
    // Earth-rotation (center of rotation of the Earth around the Sun)
    SCNNode *earthRotationNode = [SCNNode node];
    [_sunNode addChildNode:earthRotationNode];
    
    // Earth-group (will contain the Earth, and the Moon)
    _earthGroupNode = [SCNNode node];
    _earthGroupNode.position = SCNVector3Make(15, 0, 0);
    [earthRotationNode addChildNode:_earthGroupNode];
    
    // Earth
    _earthNode = [_wireframeBoxNode copy];
    _earthNode.position = SCNVector3Make(0, 0, 0);
    [_earthGroupNode addChildNode:_earthNode];
    
    // Moon-rotation (center of rotation of the Moon around the Earth)
    SCNNode *moonRotationNode = [SCNNode node];
    [_earthGroupNode addChildNode:moonRotationNode];
    
    // Moon
    _moonNode = [_wireframeBoxNode copy];
    _moonNode.position = SCNVector3Make(5, 0, 0);
    [moonRotationNode addChildNode:_moonNode];
    
  2. You can't make an animation that follows a specific path you model in 3D space, but you could make a keyframe animation that interpolates between several positions in 3D space. The (untested) code below moves a node around a square shape in the xz-plane... add more points to get a rounder shape.

    CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPaths:@"position"];
    anim.values = @[
        [NSValue valueWithSCNVector3:SCNVector3Make(0, 0, 1)],
        [NSValue valueWithSCNVector3:SCNVector3Make(1, 0, 0)],
        [NSValue valueWithSCNVector3:SCNVector3Make(0, 0, -1)],
        [NSValue valueWithSCNVector3:SCNVector3Make(-1, 0, 0)],
    ];
    [node addAnimation:anim forKey:"orbit"];
    
  3. Use physics! The SCNPhysicsField class models radial gravity, so you can just drop a gravity field into a scene, add some physics bodies for planets, and sit back and watch your solar system cataclysmically destroy itself come to life! Getting realistic behavior here takes a lot of trial and error — you'll need to set an initial velocity for each planet tangential to what you expect its orbit to be, and tweak that velocity to get it right. Researching some ephemeris data for our solar system might help.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!