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?
source to share
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.
source to share
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
.
source to share