Reputation: 495
Let's say I add a 3D model such as a dog as a child node to my scene's root node in ViewDidLoad
. I printed out the dog node's transform
and worldTransform
properties, both of which are just 4x4 identity matrices.
After rotating, scaling, and positioning, I re-printed the transform
and worldTransform
properties. I could not understand how to read them. Which column refers to position, size, or orientation?
Under any transform, how do I figure out 1) which direction the front of the dog is facing, assuming that in viewDidLoad
the front was facing (0,0,-1)
direction, and 2) the height and width of the dog?
Upvotes: 1
Views: 1038
Reputation: 126167
A full introduction to transform matrices is a) beyond the scope of a simple SO answer and b) such a basic topic in 3D graphics programming that you can find a zillion or two books, tutorials, and resources on the topic. Here are two decent writeups:
Since you're working with ARKit in SceneKit, though, there are a number of convenience utilities for working with transforms, so you often don't need to dig into the math.
which direction the front of the dog is facing?
A node is always "facing" toward (0,0,-1)
in its local coordinate space. (Note this is SceneKit's intrinsic notion of "facing", which may or may not map to how any custom assets are designed. If you've imported an OBJ, DAE, or whatever file built in a 3D authoring tool, and in that tool the dog's nose is pointed to (0,0,-1)
, your dog is facing the "right" way.)
You can get this direction from SCNNode.simdLocalFront
— notice it's a static/class property, because in local space the front is always the same direction for all nodes.
What you're probably more interested in is how the node's own idea of its "front" converts to world space — that is, which way is the dog facing relative to the rest of the scene. Here are two ways to get that:
Convert the simdLocalFront
to world space, the way you can any other vector: node.convert(node.simdLocalFront, to: nil)
. (Notice that if you leave the to
parameter nil, you convert to world space.)
Use the simdWorldFront
property, which does that conversion for you.
the height and width of the dog?
Height and width have nothing to do with transform. A transform tells you (primarily) where something is and which way it's facing.
Assuming you haven't scaled your node, though, its bounding box in local space describes its dimensions in world space:
let (min, max) = node.boundingBox
let height = abs(max.y - min.y)
let width = abs(max.x - min.x)
let depthiness = abs(max.z - min.z)
(Note this is intrinsic height, though: if you have, say, a person model that's standing up, and then you rotate it so they're lying down, this height is still head-to-toe.)
Upvotes: 3