0
\$\begingroup\$

Each Entity can have one parent and any number of children. They have a position vector and a quaternion orientation.

I know that I can make objects look like they're in a hierarchy by multiplying parent transforms all the way to the root, but how to I get the canonical coordinates out of those transformations? I need to have the real position of every Entity in the world in order to update their bounding meshes.

I would like to keep my drawing code for everything as just this:

XMMATRIX transform = XMMatrixRotationQuaternion(orientation); transform = XMMatrixMultiply(transform, XMMatrixTranslation(position)); transform = XMMatrixMultiply(world, transform); model->Draw(context, *states, transform, view, projection); 

Eg. without relying on visual tricks to get the hierarchy looking right, so no multiplications with parent transforms while rendering.

How do I properly change a child's position and orientation with respect to the parent?

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

Fundamentally, if you want objects that are in a hierarchy relative to a parent, you need to do a concatenation of the local-to-parent transform with the parent. This is how it works. I see now way around it, and I wouldn't describe it as 'visual tricks' - that's how a transform hierarchy works. Objects have orientations and positions in world space, but if they are relative to their parent, they need to perform transforms every time they, or their ancestors, move.

However, I think you can have your cake and eat it too: use two transforms: one a local-to-parent transform and one a cached worldspace transform. You also want a dirty flag. When an object moves in world space the local-to-parent matrix, or in your case orientation and translation, is updated and the dirty flag is set. All of the children then have their dirty flags set. Any request for an entities world matrix must first check the dirty flag. If set travel up to the first ancestor that is not dirty and recalculate each descendants world space matrix, clearing their dirty flag, back to the original entity. Then return the new world matrix. This avoids recalculating matrices of top level objects that have not moved or children who are part of a hierarchy that is static this frame. Normally this lazy evaluation is hidden behind the object's GetWorldMatrix() method so the caller never sees it. All the rest of the work is hidden behind SetWorldMatrix( ), SetLocalToParentMatrix(), etc. They do all the right operations under the hood.

I would also note that while storing orientation and translation is cheaper from a storage perspective, it is quite expensive to perform a quaternion to matrix every frame. This solution might help you for objects that do not move often, but I suspect it might actually be more performant to store the local-to-parent transform as a matrix, but I am not sure what kind of transforms you are performing.

\$\endgroup\$
2
  • \$\begingroup\$ I see the reasoning now but the part I'm having trouble is, is where the updating of the orientation and translation happens. How do I retrieve the world space coordinates of an object from matrix multiplications? \$\endgroup\$ Commented Nov 23, 2014 at 23:22
  • \$\begingroup\$ In this case the XMMATRIX is a 4x4 matrix containing rotation, scale and translation. For example the first, second and third elements of the fourth row is the translation (depends on column or row.major conventions). The scale and rotation and stored in the upper 3 rows. Here is a primer with more information:gamedev.net/page/resources/_/technical/math-and-physics/… maybe that would help. Or did I miss the point of your comment? \$\endgroup\$ Commented Nov 24, 2014 at 0:27

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.