AJ Z.
AJ Z.

Reputation: 495

Understanding 3D object transform property in ARKit

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

Answers (1)

rickster
rickster

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:

  1. 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.)

  2. 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

Related Questions