I have scene graph system with nodes that have "position" and "rotation" vectors. Each node can have one or more linked entities that have also "position" and "rotation" vectors.
All those vectors are RELATIVE position and rotation to the parent node. When drawing my hierarchy, I simply use the OpenGL matrix stack and add transformations to the current ModelView matrix.
But I want to improve my system so that a camera can be a linked entity. So, it can be nested deeply in the nodes hierarchy.
The problem is I need the ABSOLUTE transformation of my camera to be able to "move" my world before drawing the scene ... and I only store RELATIVE transformation.
I know that to get the absolute transformation, I must start from my nested entity, add transformations and go back to the root. Then I must invert the result matrix. But I'm not really sure of how to implement it.
This is my first attempt:
In my Entity class:
Public Function GetAbsoluteTransformation() As Matrix4 'Create an matrix to accumulate transformations Dim accuMat As Matrix4 = New Matrix4 accuMat = Matrix4.Identity 'normal order (drawing) is translate and rotate X,Y and Z. Do I need to do the the inverse ? Dim rotMatX As Matrix4 = Matrix4.CreateRotationX(-DegreesToRadians(_RotX)) Dim rotMatY As Matrix4 = Matrix4.CreateRotationY(-DegreesToRadians(_RotY)) Dim rotMatZ As Matrix4 = Matrix4.CreateRotationZ(-DegreesToRadians(_RotZ)) Dim transMat As Matrix4 = Matrix4.CreateTranslation(Position) Dim tmpMat As Matrix4 = rotMatZ * rotMatY * rotMatX * transMat Matrix4.Mult(accuMat, tmpMat, accuMat) GetAbsTransRecurs(ParentLinkedNode, accuMat) accuMat.Invert() Return accuMat End Function Public Sub GetAbsTransRecurs(ByVal parentNode As SceneNode, ByRef accuMat As Matrix4) If parentNode IsNot Nothing Then Dim rotMatZ_p As Matrix4 = Matrix4.CreateRotationZ(-DegreesToRadians(parentNode.Rotation.Z)) Dim rotMatY_p As Matrix4 = Matrix4.CreateRotationY(-DegreesToRadians(parentNode.Rotation.Y)) Dim rotMatX_p As Matrix4 = Matrix4.CreateRotationX(-DegreesToRadians(parentNode.Rotation.X)) Dim transMat_p As Matrix4 = Matrix4.CreateTranslation(parentNode.Position) Dim tmpMat_p As Matrix4 = rotMatZ_p * rotMatY_p * rotMatX_p * transMat_p Matrix4.Mult(accuMat, tmpMat_p, accuMat) If parentNode.ParentNode IsNot Nothing Then GetAbsTransRecurs(parentNode.ParentNode, accuMat) End If End If End Sub
Are my maths good (I'm really bad at maths) ?
I just start to test this, and it seems that I must invert rotations angles. strange results but I think I'm on the right way.