在 SceneKit 中旋转节点
Rotating a node in SceneKit
我很难理解节点的多次旋转。
首先,我创建并定位了一个平面:
SCNPlane *plane = [SCNPlane planeWithWidth:10 height:10];
SCNNode *planeNode = [SCNNode nodeWithGeometry:plane];
planeNode.rotation = SCNVector4Make(1, 0, 0, (M_PI/2 * 3));
[scene.rootNode addChildNode:planeNode];
然后我在这个平面上定位并设置了一个聚光灯节点的方向:
SCNLight *light = [[SCNLight alloc] init];
light.type = SCNLightTypeSpot;
light.spotInnerAngle = 70;
light.spotOuterAngle = 100;
light.castsShadow = YES;
lightNode = [SCNNode node];
lightNode.light = light;
lightNode.position = SCNVector3Make(4, 0, 0.5);
lightNode.rotation = SCNVector4Make(0, 1, 0, M_PI/2);
[planeNode addChildNode:lightNode];
然后我将灯光节点绕 x 轴顺时针旋转 90 度的动画设置为:
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:2.0];
lightNode.rotation = SCNVector4Make(1, 0, 0, M_PI/2);
[SCNTransaction commit];
但我很困惑为什么以下将光节点旋转回绕同一轴的原始位置:
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:2.0];
lightNode.rotation = SCNVector4Make(0, 1, 0, M_PI/2);
[SCNTransaction commit];
对我来说,这意味着我们将节点绕 y 轴顺时针旋转 90 度。
任何人都可以解释为什么这样做吗?或者,更好的是,建议一个更清晰的旋转节点然后将其返回到其原始位置的方法?
我不确定是否完全理解这个问题,但是当您编写 lightNode.rotation = SCNVector4Make(0, 1, 0, M_PI/2);
时,您并没有将旋转与节点的当前旋转连接起来。您正在指定新的 "absolute" 旋转。
由于SCNVector4Make(0, 1, 0, M_PI/2)
是lightNode
的原始旋转,再次设置SCNVector4Make(0, 1, 0, M_PI/2)
会使节点旋转回原来的状态。
编辑
下面的代码做了两件事
- 首先它为节点的旋转设置一个初始值
然后它为节点的旋转指定一个新值。因为它是在事务中完成的(其持续时间不为 0),SceneKit 将为该更改设置动画。但是动画的参数,包括旋转轴,是由SceneKit选择的。
lightNode.rotation = SCNVector4Make(0, 1, 0, M_PI/2);
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:2.0];
lightNode.rotation = SCNVector4Make(1, 0, 0, M_PI/2);
[SCNTransaction commit];
position
属性也一样。
以下代码将节点的位置设置为从 (1,0,1)
到 (2,3,4)
,而不是从 (1,1,1)
到 (3,3,5)
。
aNode.position = SCNVector3Make(1, 0, 1);
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:2.0];
aNode.position = SCNVector3Make(2, 3, 4);
[SCNTransaction commit];
如果您想为节点设置动画,并希望能够控制动画参数,您可以使用 CABasicAnimation
和 byValue
。
我想我已经通过使用 eulerAngles 解决了这个问题,它似乎以我理解的方式工作。
所以我替换了:
lightNode.rotation = SCNVector4Make(0, 1, 0, M_PI/2);
与:
lightNode.eulerAngles = SCNVector3Make(0, M_PI/2, 0);
其他轮换也是如此。
我不得不承认我对旋转方法的作用仍然很困惑,但很高兴我现在有了可以使用的东西。
因为当您搜索“scnnode rotate”时它首先出现
node.localRotate(by: SCNQuaternion(x: 0, y: 0, z: -0.7071, w: 0.7071))
我很难理解节点的多次旋转。
首先,我创建并定位了一个平面:
SCNPlane *plane = [SCNPlane planeWithWidth:10 height:10];
SCNNode *planeNode = [SCNNode nodeWithGeometry:plane];
planeNode.rotation = SCNVector4Make(1, 0, 0, (M_PI/2 * 3));
[scene.rootNode addChildNode:planeNode];
然后我在这个平面上定位并设置了一个聚光灯节点的方向:
SCNLight *light = [[SCNLight alloc] init];
light.type = SCNLightTypeSpot;
light.spotInnerAngle = 70;
light.spotOuterAngle = 100;
light.castsShadow = YES;
lightNode = [SCNNode node];
lightNode.light = light;
lightNode.position = SCNVector3Make(4, 0, 0.5);
lightNode.rotation = SCNVector4Make(0, 1, 0, M_PI/2);
[planeNode addChildNode:lightNode];
然后我将灯光节点绕 x 轴顺时针旋转 90 度的动画设置为:
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:2.0];
lightNode.rotation = SCNVector4Make(1, 0, 0, M_PI/2);
[SCNTransaction commit];
但我很困惑为什么以下将光节点旋转回绕同一轴的原始位置:
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:2.0];
lightNode.rotation = SCNVector4Make(0, 1, 0, M_PI/2);
[SCNTransaction commit];
对我来说,这意味着我们将节点绕 y 轴顺时针旋转 90 度。
任何人都可以解释为什么这样做吗?或者,更好的是,建议一个更清晰的旋转节点然后将其返回到其原始位置的方法?
我不确定是否完全理解这个问题,但是当您编写 lightNode.rotation = SCNVector4Make(0, 1, 0, M_PI/2);
时,您并没有将旋转与节点的当前旋转连接起来。您正在指定新的 "absolute" 旋转。
由于SCNVector4Make(0, 1, 0, M_PI/2)
是lightNode
的原始旋转,再次设置SCNVector4Make(0, 1, 0, M_PI/2)
会使节点旋转回原来的状态。
编辑
下面的代码做了两件事
- 首先它为节点的旋转设置一个初始值
然后它为节点的旋转指定一个新值。因为它是在事务中完成的(其持续时间不为 0),SceneKit 将为该更改设置动画。但是动画的参数,包括旋转轴,是由SceneKit选择的。
lightNode.rotation = SCNVector4Make(0, 1, 0, M_PI/2); [SCNTransaction begin]; [SCNTransaction setAnimationDuration:2.0]; lightNode.rotation = SCNVector4Make(1, 0, 0, M_PI/2); [SCNTransaction commit];
position
属性也一样。
以下代码将节点的位置设置为从 (1,0,1)
到 (2,3,4)
,而不是从 (1,1,1)
到 (3,3,5)
。
aNode.position = SCNVector3Make(1, 0, 1);
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:2.0];
aNode.position = SCNVector3Make(2, 3, 4);
[SCNTransaction commit];
如果您想为节点设置动画,并希望能够控制动画参数,您可以使用 CABasicAnimation
和 byValue
。
我想我已经通过使用 eulerAngles 解决了这个问题,它似乎以我理解的方式工作。
所以我替换了:
lightNode.rotation = SCNVector4Make(0, 1, 0, M_PI/2);
与:
lightNode.eulerAngles = SCNVector3Make(0, M_PI/2, 0);
其他轮换也是如此。
我不得不承认我对旋转方法的作用仍然很困惑,但很高兴我现在有了可以使用的东西。
因为当您搜索“scnnode rotate”时它首先出现
node.localRotate(by: SCNQuaternion(x: 0, y: 0, z: -0.7071, w: 0.7071))