在SceneKit中旋转节点

bcl*_*bcl 4 cocoa-touch objective-c rotation 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];
Run Code Online (Sandbox Code Playgroud)

然后我定位并设置了这个平面上聚光灯节点的方向:

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];
Run Code Online (Sandbox Code Playgroud)

然后,我将光节点的旋转设置为围绕x轴顺时针旋转90度:

[SCNTransaction begin];
[SCNTransaction setAnimationDuration:2.0];

lightNode.rotation = SCNVector4Make(1, 0, 0, M_PI/2);

[SCNTransaction commit];
Run Code Online (Sandbox Code Playgroud)

但我很困惑为什么以下将光节点旋转回同一轴的原始位置:

[SCNTransaction begin];
[SCNTransaction setAnimationDuration:2.0];

lightNode.rotation = SCNVector4Make(0, 1, 0, M_PI/2);

[SCNTransaction commit];
Run Code Online (Sandbox Code Playgroud)

对我来说,这是因为我们将节点绕y轴顺时针旋转90度.

谁能解释为什么这有效?或者,更好的是,建议一种更清晰的方法来旋转节点然后将其返回到原始位置?

bcl*_*bcl 11

我想我已经通过使用eulerAngles解决了这个问题,这似乎与我理解的方式有关.

所以我换了:

lightNode.rotation = SCNVector4Make(0, 1, 0, M_PI/2);
Run Code Online (Sandbox Code Playgroud)

附:

lightNode.eulerAngles = SCNVector3Make(0, M_PI/2, 0);
Run Code Online (Sandbox Code Playgroud)

同样适用于其他轮换.

我不得不承认,我仍然对旋转方法的作用感到困惑,但很高兴我现在能够使用它.


mnu*_*ges 5

我不确定完全理解这个问题,但是当你写的时候,lightNode.rotation = SCNVector4Make(0, 1, 0, M_PI/2);你并没有连接节点当前旋转的旋转.您正在指定新的"绝对"旋转.

由于SCNVector4Make(0, 1, 0, M_PI/2)是的一部开拓创新的旋转lightNode,设置SCNVector4Make(0, 1, 0, M_PI/2)再次将节点旋转恢复到原来的状态.

编辑

以下代码做了两件事

  1. 首先,它为节点的旋转设置初始值
  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];
    
    Run Code Online (Sandbox Code Playgroud)

这是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];
Run Code Online (Sandbox Code Playgroud)

你想要为节点设置动画,并希望能够控制动画参数,你可以使用CABasicAnimationa byValue.