【问题标题】:Revolve a SCNode object in the 3D Space using SceneKit使用 SceneKit 在 3D 空间中旋转 SCNode 对象
【发布时间】:2014-08-10 19:25:33
【问题描述】:

我正在尝试学习如何使用 SceneKit,例如,我想尝试使用 SDK 构建太阳能系统。我能够添加 SCNode 对象并配置其材质属性,例如图案和照明。此外,我能够旋转行星,但我似乎无法理解如何沿着特定路径“旋转”它们。

到目前为止,我的代码如下所示:

// create a new scene
SCNScene *scene = [SCNScene scene];

// create and add a camera to the scene
SCNNode *cameraNode = [SCNNode node];
cameraNode.camera = [SCNCamera camera];
[scene.rootNode addChildNode:cameraNode];

// place the camera
cameraNode.position = SCNVector3Make(0, 0, 2);

// create and add a 3d sphere - sun to the scene
SCNNode *sphereNode = [SCNNode node];
sphereNode.geometry = [SCNSphere sphereWithRadius:0.3];
[scene.rootNode addChildNode:sphereNode];

// create and configure a material
SCNMaterial *material = [SCNMaterial material];
material.diffuse.contents = [NSImage imageNamed:@"SunTexture"];
material.specular.contents = [NSColor whiteColor];
material.specular.intensity = 0.2;
material.locksAmbientWithDiffuse = YES;

// set the material to the 3d object geometry
sphereNode.geometry.firstMaterial = material;

// create and add a 3d sphere - earth to the scene
SCNNode *earthNode = [SCNNode node];
earthNode.geometry = [SCNSphere sphereWithRadius:0.15];
NSLog(@"Sun position = %f, %f, %f", sphereNode.position.x, sphereNode.position.y, sphereNode.position.z);
earthNode.position = SCNVector3Make(0.7, 0.7, 0.7);
NSLog(@"Earth position = %f, %f, %f", earthNode.position.x, earthNode.position.y, earthNode.position.z);
//earthNode.physicsBody = [SCNPhysicsBody dynamicBody];
[scene.rootNode addChildNode:earthNode];

SCNMaterial *earthMaterial = [SCNMaterial material];
earthMaterial.diffuse.contents = [NSImage imageNamed:@"EarthTexture"];

earthNode.geometry.firstMaterial = earthMaterial;

我在 AppleDocs 的某处读到,您需要在太阳坐标系中添加行星,而不是在根节点中,但我不确定我是否理解正确。

让我知道你是如何做到这一点的。

【问题讨论】:

    标签: objective-c macos 3d scenekit


    【解决方案1】:

    SceneKit 不提供沿路径动画的 API。不过,有几种方法可以建立像太阳系这样的东西。

    1. 见过orrery吗?这是SCNNode 文档中提到的模型;这也是WWDC presentation 在“场景图摘要”幻灯片上所做的。诀窍是,您使用一个节点来表示行星绕太阳公转的参考系 - 就像将行星固定在 orrery 中的电枢一样,如果您使该节点围绕其中心轴旋转,您附加到的任何子节点它将遵循圆形路径。与此相关的代码在该示例代码项目中的ASCSceneGraphSummary.m 中(浓缩为此处仅显示节点层次结构设置):

      // 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. 您无法制作遵循您在 3D 空间中建模的特定路径的动画,但您可以制作在 3D 空间中的多个位置之间进行插值的关键帧动画。下面的(未经测试的)代码在 xz 平面中围绕正方形形状移动节点...添加更多点以获得更圆的形状。

      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. 使用物理学! SCNPhysicsField 类模拟径向重力,因此您可以将重力场放入场景中,为行星添加一些物理物体,然后坐下来观看您的太阳系灾难性地毁灭自己!在这里获得真实的行为需要大量的试验和错误——您需要为每个行星设置一个与您期望的轨道相切的初始速度,并调整该速度以使其正确。研究我们太阳系的一些星历表数据可能会有所帮助。

    【讨论】:

    • 作为一种解决方法,我确实实施了类似于您的观点 1 的内容。感谢您的详细回复,实施物理的想法听起来确实令人兴奋?。
    • 太棒了。简直……太棒了。
    • 这很有帮助。此外,如果您决定使用 Orrery,并且您希望所有行星都有不同的路径。您始终可以在太阳中心添加隐藏节点并旋转它们的轴;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-10
    • 2017-10-29
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    • 2019-07-07
    • 2016-11-23
    相关资源
    最近更新 更多