3D Relative to Absolute Transformations
Asked Answered
W

3

6

I am trying to create a scene graph for my 3D game in which every object's transformations are relative to it's parent. Each node of the graph has a Rotation, Scaling and Translation vector.

What is the correct way of combining the relative transformation matrices to get the absolute transformation of an object? I would be glad if you could also explain your solution.


Here is an example of to do it WRONG:
This actually turned out to be the solution:

Matrix GetAbsoluteTransformation()
{
    if (!this.IsRoot())
    {
        return this.Transformation * this.Parent.GetAbsoluteTransformation();
    }
    else
    {
        return this.Transformation;
    }
}

In this case, when the parent node is rotated, scaled or moved, the child is transformed the same amount, which is a correct behaviour! But the child will only rotate around its own origin and does not move around the parent's origin.


Applications:

There is a car model with four wheels. The wheels are relative positioned around the car's origin. The wheels can rotate just like real wheels do. If I now rotate the car, the wheels should at all time stay attached to it. In this case the car is the root and the wheels are the child nodes.

Another example would be a model of the solar system. Planets rotate around their own axis, move around the sun, and moons move around planets.

Whew answered 6/11, 2011 at 21:35 Comment(1)
Turns out that my first idea how to do it, which I then considered as not suitable, was actually the solution! I spent the past few hours trying to solve this. facepalm Thanks everybody for the quick and accurate help!Whew
B
4

With regards to your "how to do it wrong", I hate to break it to you, but it's not wrong; rather, it's incomplete. You need to do those kinds of work independently of the parent child relationship.

Here's an example of that: The wheel is attached to the car just like you mentioned. If you translate or rotate the car, you don't need to touch the wheels - they're in the same location relative to the car. However, when you try to get the wheel's new location in the 'real world', you have to traverse down the tree, applying the matrix transformations as you go. That all works, right?

When you rotate an object, it rotates around its OWN origin. So a wheel should probably be rotating around its y axis, and a planet around its z axis. But now if you need to move a planet "around the sun", you're doing something completely different. This has to be calculated separately. That's not to say it's not going to be eased by using some of the same match you already have, (although I can't say for sure without doing the math myself) but it's entirely different.

You're looking at actually changing the state of the object. That's the beauty of the scene graph! If you didn't have a scene graph, you would have to figure out all the various values all the way back to the main scene and then do all kinds of math. Here, you just have to do a little bit of trig and algebra to move around the planet (you can google the celestial mechanics) and move the planet relative to its star. The next time the main scene asks where the planet is, it will just go down the scene graph! :-D

Bestride answered 6/11, 2011 at 21:47 Comment(3)
I pick this as the best answer. My original approach was correct and I now do not know why I considered it to be wrong (too simple? :D) You are also right about the planetary rotation: I now included an additional node which handles the rotation around the sun. Thank you very much!Whew
If the sun rotates the planets will rotate aswell with this matrix algebra. Forward kinematics..Elianaelianora
@Stefan then obviously the sun should simply be a child of the solar system as the planet is, and centered at the origin.Bestride
T
1

I think this is the correct behavior.

I don't think rotating around the parent's origin is something that can be accomplished with a simple matrix stack. I think you can only propagate from parents to children.

You could try instead setting the relative rotation and transformation based on offsets from the parent's absolute origin, though that's a lot more calculations than simply pushing onto a matrix stack.

Here's a similar question: Getting absolute position and rotation from inside a scene graph?

Tricot answered 6/11, 2011 at 21:42 Comment(0)
S
1

It depends on whether you are using OpenGL or Direct3D. In OpenGL, transforms are applied right-to-left, whereas in Direct3D, they apply left-to-right. They are both perfectly valid ways of designing the transform system, but it means you have to think about them differently.

I find it easiest to think in OpenGL's system, but in reverse. Instead of thinking about how the vertices of an object move around as transforms are applied right-to-left, I imagine the coordinate system of the object being transformed in a left-to-right order. Each transform is applied relative to the new local coordinate system, not relative to the world.

In the case of the wheels on the car, there are three transforms involved: the car's position in space, a wheel's origin relative to the car, and the wheel's orientation relative to its neutral position. Simply apply these in left-to-right order (or vice-versa for Direct3D). To draw four wheels, first apply the car's transform, then remember the current transform, then apply the location and orientation transforms in turn, going back to the remembered car transform after each.

Sequin answered 6/11, 2011 at 21:47 Comment(4)
I am not sure if this answer completely fits my question. But still, I did not know about this difference yet, so thank you! :)Whew
I believe these are the defaults, and you can flip them if necessary. At least I am pretty sure you can in OpenGL.Tricot
@user the best thing to take away from Marcelos answer is that there are plenty of frameworks that are in use by hundreds of thousands (perhaps millions?) of developers, and that you should consider using one of those to do the heavy lifting in your system. Not only will they save you many hours of debugging (note, many more hours than it would take to make your own) but you'll also have a very marketable and lucrative skill set on your resume!Bestride
@glowcoder Currently I am working my way down to the fundamentals. I started game developing with complete engines and I had no clue about what was actually happening behind the scenes and this limited my ability to use them correctly. Now I work with C# and XNA and I learnt a lot which will help me for as long as I will be doing anything related to creating video games. So while the learning curve is that steep, it does not really matter to me, if what I am doing has been done better before. ;) Thanks for the advice!Whew

© 2022 - 2024 — McMap. All rights reserved.