我试图在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,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,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的某个地方读到你需要在Sun的坐标系中添加行星,而不是在根节点中添加行星,但我不确定我是否理解这一点.
让我知道你是如何做到这一点的.
解决方法
SceneKit不提供动态路径API.但是,有几种方法可以设置像太阳系这样的东西.
>曾见过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); [earthRotationNode addChildNode:_earthGroupNode]; // Earth _earthNode = [_wireframeBoxNode copy]; _earthNode.position = SCNVector3Make(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); [moonRotationNode addChildNode:_moonNode];
>您无法制作遵循在3D空间中建模的特定路径的动画,但您可以制作在3D空间中的多个位置之间插值的关键帧动画.下面的(未经测试的)代码在xz平面中围绕方形形状移动节点…添加更多点以获得更圆的形状.
CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPaths:@"position"]; anim.values = @[ [NSValue valueWithSCNVector3:SCNVector3Make(0,1)],[NSValue valueWithSCNVector3:SCNVector3Make(1,0)],[NSValue valueWithSCNVector3:SCNVector3Make(0,-1)],[NSValue valueWithSCNVector3:SCNVector3Make(-1,]; [node addAnimation:anim forKey:"orbit"];
>使用物理! SCNPhysicsField
类模拟了径向引力,因此您可以将重力场放入场景中,为行星添加一些物理体,然后坐下来观看您的太阳系灾难性破坏自身的生命!在这里获得真实的行为需要大量的试验和错误 – 你需要为每个行星设置一个与你预期的轨道相切的初始速度,并调整速度以使其正确.研究太阳系的一些星历数据可能会有所帮助.