I have 2 questions regarding matracies which may actually prove to be interrelated.
I am putting into practice doing translations, rotations and scaling in terms of matrices.
I have had no problem with transformations and scaling. The rotation is another matter though.
I have found examples on the internet which show how to do rotations with matrices but in each case the example has shown how to do it using 3 different matrices, one for each rotation direction. What I want to do is to work out how to do all 3 rotations by calculation values for a single matrix.
My situation is that I have Actor classes in C++ which I am using as the basis of my 3D objects. I know there are 2 schools of thought as to how to store an actors position and rotation. Once is the position plus Euler angles and the other is vector position + forward vector + up vector approach. Looking at the second more recommended approach I thought, why not just store the whole transformation matrix in each actor. I know it would use a bit more memory, 16 GLfloats instead of 9 but I think the kind of memory this will use up is insignificant vs things like Textures. As the virtue of the second approach was that the values could be easily put into a matrix. I thought that at the cost of a bit of memory I could save on some processing power calculating the other vector from the forward and up ones by just using a whole matrix to start with.
My Actors are being designed to be hierachical. This means that I want to define the position and rotation of each child object relative to it’s parent. My thought was that the child actors will have their matrix of relative transformations which they will combine with their parent to get the absolute transformations. For example if the parent is translated on the y axis by 10 and rotated round the y axis by a quarter and the child actor is traslated 10 in the z axis and rotated in the x axis by a quarter then a successful merge of the 2 matrices would have x and z transated by 10 and y and z rotated by a quarter, if you follow my logic.
What I don’t know is the correct way to merge two matrices. Knowing that could well solve the first problem as well.
Have you looked into using quaternions to represent your rotations? The math involved to rotate a quaternion and multiply them together is generally less involved than matrices, plus it’s easy to generate a rotation matrix from a quaternion. There is documentation out there detailing how to create a rotation matrix given an angle and and axis of rotation and since a quaternion just represents an rotation about an axis, they would be applied very easily. It is also possible to extract Euler angles from quaternions as well.
When it comes to combining rotations, with quaternions if you had 3 rotations represented by quaternions Q1, Q2, Q3 and you wanted to combine them in that order all you would need to do is:
Q_Rot = Q3 * Q2 * Q1.
I would suggest checking them out, they would also only require 4 data elements as opposed to 16 for matrices.
I am comming to the conclusion that I will have to approach the matter of handling 3D positioning for my actors differently as the matrix aproach doesn’t look like it is going to be the best approach at least not for storing current possition and rotation etc.
I am a bit aprehensive about using quaternions as OpenGL Superbible lays out Euler angles and their related quaternions as being a popular but in the authours opinion, not the best approach. There was talk of gymbol lock and having to work around it where as using the forward and up vector approach was not supposed to have that problem. It was also suggested that the forward and up vector approach made it a lot easier when it came to modeling an object which continues to move forward. I am not an expert in this area admittedly but deciding on an approach will be neccecary at some point for the cousework assignment I am doing. At the moment I am bogged down developing my obj/mtl file parser.
You just have to multiply the matrices. If you have two matrices A and B, the product A * B is the same as first trasforming by B, then transforming by A.
v’ = B * v
v’’ = A * v’
v’’ = A * (B * v) = (A * B) * v
Storing a matrix for each object in the hirarchy is a good approach, I don’t see any problem with it. Quaternions have the advantage that you can re-normalize them to prevent degeneration because of numerical errors. But then you have to handle the translation part seperately, which is not easy in a hierarchial scene.
I don’t think there really is a “best” approach. Each approach has advantages and disadvantages, but I don’t think one can generally say which one is best for each situation.
In particular, the matrix approach has the advantage that it is simple to implement, because a matrix is exactly what OpenGL wants.