【问题标题】:Rotating a node in SceneKit在 SceneKit 中旋转节点
【发布时间】:2015-07-10 20:50:03
【问题描述】:

我很难理解节点的多次旋转。

首先,我创建并定位了一个平面:

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 度。

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

【问题讨论】:

    标签: objective-c cocoa-touch rotation scenekit


    【解决方案1】:

    我想我已经通过使用 eulerAngles 解决了这个问题,这似乎以我理解的方式工作。

    所以我换了:

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

    与:

    lightNode.eulerAngles = SCNVector3Make(0, M_PI/2, 0);
    

    对于其他旋转也是如此。

    我不得不承认我对轮换方法的作用仍然很困惑,但很高兴我现在可以使用一些东西。

    【讨论】:

      【解决方案2】:

      我不确定是否完全理解这个问题,但是当您编写 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];
        

      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];
      

      如果您想为节点设置动画,并且希望能够控制动画参数,您可以使用CABasicAnimationbyValue

      【讨论】:

      • 感谢您的回复,尽管我认为我现在比以前更困惑 :( 与我在这里尝试做的相比,我完全不确定绝对旋转是什么(简单地旋转相对于平面的光节点)。我想我的问题基本上是:我怎样才能旋转一个节点,然后两次都回到它相对于同一轴工作的原始位置?如果我做了什么导致了绝对旋转(我猜这很糟糕),我应该使用另一种方法来实现我所追求的目标吗?
      • 再次感谢您的回复。不确定这是我所追求的,因为我不希望 SceneKit 为我的动画选择旋转轴;我需要在给定方向上进行非常具体的运动。在我看来,eulerAngles 为我提供了这种级别的控制,而且它不会因为切换我需要使用的旋转轴而让我感到困惑。
      【解决方案3】:

      因为当你搜索“scnnode rotate”时它首先出现

      node.localRotate(by: SCNQuaternion(x: 0, y: 0, z: -0.7071, w: 0.7071))
      

      【讨论】:

        猜你喜欢
        • 2018-12-17
        • 2018-12-24
        • 2017-04-25
        • 2018-07-05
        • 2018-11-01
        • 2016-07-22
        • 2017-11-30
        • 1970-01-01
        • 2015-03-05
        相关资源
        最近更新 更多