Rotating a node in SceneKit

I'm trying to figure out a few twists and turns of node.

First, I created and placed a plane:

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

      

Then I positioned and set the direction of the spotlight node on that plane:

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

      

Then I animate the rotation of the light node 90 degrees clockwise around the x-axis:

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

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

[SCNTransaction commit];

      

But I am confused as to why the following rotates the light node back to its original position around the same axis:

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

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

[SCNTransaction commit];

      

It reads to me when we rotate the node 90 degrees clockwise around the y-axis.

Can anyone explain why this works? Or, better yet, would you suggest a clearer method to rotate a node and then return it to its original position?

+3


source to share


2 answers


I think I solved it by using eulerAngles, which seems to work this way as far as I understand it.

So I replaced:

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

      

FROM



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

      

And similar to other turns.

I have to admit that I'm still very confused about what the rotation method does, but happy that I have something to work with now.

+7


source


I'm not sure to fully understand the question, but when you write lightNode.rotation = SCNVector4Make(0, 1, 0, M_PI/2);

you are not merging the rotation of the current rotation of the node. You are specifying a new "absolute" rotation.

As there SCNVector4Make(0, 1, 0, M_PI/2)

was a twist of the original lightNode

, installing SCNVector4Make(0, 1, 0, M_PI/2)

again will force the node to return to its original state.

EDIT

the following code does two things



  • first it sets the initial value for the rotation node
  • then it specifies a new value for the rotation node. Since this is done in a transaction (whose duration is not 0), SceneKit will animate this change. But the animation options , including the rotation axis , are selected by 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];
    
          

The same goes for the property position

. The following code animates the position of the node from (1,0,1)

to (2,3,4)

, not from (1,1,1)

to (3,3,5)

.

    aNode.position = SCNVector3Make(1, 0, 1);

    [SCNTransaction begin];
    [SCNTransaction setAnimationDuration:2.0];
    aNode.position = SCNVector3Make(2, 3, 4);
    [SCNTransaction commit];

      

you want to animate a node and want to be able to control the animation parameters, you can use CABasicAnimation

with byValue

.

+3


source







All Articles