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.
While the space of linear transformations is large, there are few types of transformations which are typical. We look here at dilations, shears, rotations, reflections and projections.
Transformation matrix is a basic tool for transformation. A matrix with n x m dimensions is multiplied with the coordinate of objects. Usually 3 x 3 or 4 x 4 matrices are used for transformation.
Matrix representation Such a scaling changes the diameter of an object by a factor between the scale factors, the area by a factor between the smallest and the largest product of two scale factors, and the volume by the product of all three.
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
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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With