I am getting lost in how nodespace coordinates and rotation are handled in scenekit.
How do I get the direction a node is facing after rotation so I can then apply force in that direction.
I assumed that a force along the -z axis applied to the node would always move it forward relative to the node however this is not the case.
Negative z is the "facing" direction of a node only in its own coordinate space (i.e. the one its children and geometry are positioned in). When you apply a force, you're working in the coordinate space containing the node.
So, if you want to apply a force in a node's forward direction, you'll need to convert a vector like
{0,0,-1}
from the node's space to its parent's using a method likeconvertPosition:toNode:
.I also couldn't get
convertPosition:toNode
to work. Variations onship.convertPosition(SCNVector3(0,0,-0.1), toNode: ship.parentNode)
made the node fly off at unpredictable directions and speeds.What worked for me, was to grab the third row of the node's
worldTransform
matrix, which corresponds to it's z-forward axis:If the node has a physics body you might have to pass the
node.presentationNode
into the function.When iOS 11/ High Sierra come out, there'll be less need for overriding SCNVector3, because all the
SCNNode
properties havesimd
equivalents, so as well as.position
there's.simdPosition
and so on, and there are a lot of common simd operations built in.iOS 11 update
iOS 11 adds handy convenience functions for getting the orientation of a node. In this case the
worldForward
property is the one you want. Also, all of the properties onSCNNode
that returnSCNVector
and matrix types now have versions that return simd types. Because simd already has overloads for the arithmetic operators, you no longer need to add sets of arithmetic overrides for theSCNVector
andSCNMatrix
types.So we can get rid of out
getZForward
method above, and just have the line:The other handy set of methods that iOS 11 adds, are a set of
convertVector
methods, to complement the existingconvertPosition
methods.convertVector
is the equivalent of multiplying the matrix by the vector with0
in thew
position, so that the translation of the matrix is ignored. These are the appropriate methods to use for converting things like normals, directions and so on from one node's space to another.Because the accepted answer uses
convertPosition
, I believe it will only produce correct results for nodes whose translation is the 0,0,0 origin