GLM mat4 specifications

Started by
5 comments, last by Quantumcat 10 years, 11 months ago

I am using GLM to do some stuff and a function I wrote doesn't have the effect I intended, so I looked at a matrix while debugging to see what values it had in it. Surprisingly, it contains 4 arrays (vec4's?) of 12 values each! In each array, the values repeat. I am guessing that I should take the first 4 values of each array to be the actual values in the matrix. Do these become the rows? Or the columns? Do I not take the first 4 values?

Thanks!

Edit: While I do want to know the answer to the above I tried a different tack on debugging and I have a new question about the same problem that prompted the above question. Rather than make a new post I will add the question here.

I have objects I wish to calculate the centres of. Because of the way they were written in the Collada file, I need to rotate them -90 degrees on the X axis to make them sit on the ground. I had success by swapping the Y and Z axes, then multiplying the new Z axis by -1, while calculating their centres.

Then I found out about GLM and wrote a function to rotate a vector to replace the bulky code. It did not work. After looking at the points that came out on each way, realised that my old way had been rotating it +90 instead of -90, so tried sending -1* the angle into my function instead. Looked at the points and it gets the same values (approximately --- one value is 0.00097.. instead of 0.0012..) as the old way, except the world is wrong. A little less wrong than before (the floor is only five or so units off in the y and z directions instead of a thin line in the distance) but still wrong.

I just cannot figure out what might be going wrong. Can anyone shed some light on this?

Here is the function that rotates a vector in case it's wrong (I don't think it is). The find centre function is below it, it seems if I post 2 things with code tags, one of them disappears. The "working" and "try sections are the old way/new way respectively. m_Rot.x is always -90 and y and x 0.


 
vec4 RotateVec (float XAngle, float YAngle, float ZAngle, vec4 Pivot, vec4 P)
{
//TEST
mat4 test = mat4(1.0f);
//..Translate to origin
mat4 RotationMatrix = translate(test, vec3(-Pivot.x, 0.0f, 0.0f)); 
RotationMatrix = translate(RotationMatrix, vec3(0.0f, -Pivot.y, 0.0f)); 
RotationMatrix = translate(RotationMatrix, vec3(0.0f, 0.0f, -Pivot.z)); 
 
//..Do rotations
RotationMatrix = rotate(RotationMatrix, XAngle, vec3(1,0,0));
RotationMatrix = rotate(RotationMatrix, YAngle, vec3(0,1,0));
RotationMatrix = rotate(RotationMatrix, ZAngle, vec3(0,0,1));
 
//..Put back
RotationMatrix = translate(RotationMatrix, vec3(Pivot.x, 0.0f, 0.0f)); 
RotationMatrix = translate(RotationMatrix, vec3(0.0f, Pivot.y, 0.0f)); 
RotationMatrix = translate(RotationMatrix, vec3(0.0f, 0.0f, Pivot.z));
 
vec4 ResultVec =  P * RotationMatrix;
 
return ResultVec;
}
 
void ColladaObject::FindRotCentre (vec4 Pivot, float XAngle, float YAngle, float ZAngle, Pos& Max, Pos& Min)
{
m_pCollada->m_MaterialMap.StartIterator ();
while(m_pCollada->m_MaterialMap.Get()->m_Mesh.size () == 0)
{
m_pCollada->m_MaterialMap.MoveNext ();
}
//***working? with no random angles
/*TPos<int> Axes (X_AXIS, Y_AXIS, Z_AXIS);
TPos<float> Angles (XAngle, YAngle, ZAngle);
int mult = 1;
 
if(m_Rot.x == 90 || m_Rot.x == -90) //this section may need tweaking if things end up facing backward or upside down or anything
{
Axes.y = Z_AXIS;
Angles.y = ZAngle;
Axes.z = Y_AXIS;
Angles.z = YAngle;
if(m_Rot.x == -90)
{
mult = -1;
}
}
if(m_Rot.y == 90 || m_Rot.y == -90)
{
Axes.x = Z_AXIS;
Angles.x = ZAngle;
Axes.z = X_AXIS;
Angles.z = XAngle;
}
if(m_Rot.z == 90 || m_Rot.z == -90)
{
Axes.y = X_AXIS;
Angles.y = XAngle;
Axes.x = Y_AXIS;
Angles.x = YAngle;
}*/
 
vec4 P; //dont comment out this line
 
 
/*P.x = m_pCollada->m_MaterialMap.Get()->m_Mesh.at(0).m_Positions[Axes.x];
P.y = m_pCollada->m_MaterialMap.Get()->m_Mesh.at(0).m_Positions[Axes.y];
P.z = mult*m_pCollada->m_MaterialMap.Get()->m_Mesh.at(0).m_Positions[Axes.z];
P.w = 1;
 
//P = RotateVec (Angles.x, Angles.y, Angles.z, Pivot, P);*/
//***end working?
 
//***try
P.x = m_pCollada->m_MaterialMap.Get()->m_Mesh.at(0).m_Positions[0];
P.y = m_pCollada->m_MaterialMap.Get()->m_Mesh.at(0).m_Positions[1];
P.z = m_pCollada->m_MaterialMap.Get()->m_Mesh.at(0).m_Positions[2];
P.w = 1;
 
P = RotateVec (-1*m_Rot.x, -1*m_Rot.y, -1*m_Rot.z, Pivot, P);
//P = RotateVec (XAngle, YAngle, ZAngle, Pivot, P);
//***end try
 
float MaxX = P.x;
float MinX = P.x;
float MaxY = P.y;
float MinY = P.y;
float MaxZ = P.z;
float MinZ = P.z;
 
while(!m_pCollada->m_MaterialMap.IsEOM ())
{
shared_ptr<Material> pMaterial = m_pCollada->m_MaterialMap.Get();
for (int i = 0; i < pMaterial->m_Mesh.size (); i ++)
{
//***working?
/*P.x = m_pCollada->m_MaterialMap.Get()->m_Mesh.at(0).m_Positions[Axes.x];
P.y = m_pCollada->m_MaterialMap.Get()->m_Mesh.at(0).m_Positions[Axes.y];
P.z = mult*m_pCollada->m_MaterialMap.Get()->m_Mesh.at(0).m_Positions[Axes.z];
P.w = 1;
 
//P = RotateVec (Angles.x, Angles.y, Angles.z, Pivot, P);*/
//***end working?
//***try
P.x = m_pCollada->m_MaterialMap.Get()->m_Mesh.at(0).m_Positions[0];
P.y = m_pCollada->m_MaterialMap.Get()->m_Mesh.at(0).m_Positions[1];
P.z = m_pCollada->m_MaterialMap.Get()->m_Mesh.at(0).m_Positions[2];
 
P = RotateVec (-1*m_Rot.x, -1*m_Rot.y, -1*m_Rot.z, Pivot, P);
//P = RotateVec (XAngle, YAngle, ZAngle, Pivot, P);
//***end try
 
if(MaxX < P.x)
{
MaxX = P.x;
}
else if(MinX > P.x)
{
MinX = P.x;
}
if(MaxY < P.y)
{
MaxY = P.y;
}
else if(MinY > P.y)
{
MinY = P.y;
}
if(MaxZ < P.z)
{
MaxZ = P.z;
}
else if(MinZ > P.z)
{
MinZ = P.z;
}
}
m_pCollada->m_MaterialMap.MoveNext ();
}
 
m_Centre.x = MinX + (MaxX - MinX)/2;
m_Centre.y = MinY + (MaxY - MinY)/2;
m_Centre.z = MinZ + (MaxZ - MinZ)/2;
 
Min.x = MinX - m_Centre.x;
Max.x = MaxX - m_Centre.x;
Min.y = MinY - m_Centre.y;
Max.y = MaxY - m_Centre.y;
Min.z = MinZ - m_Centre.z;
Max.z = MaxZ - m_Centre.z;
}
Advertisement

Are you sure you aren't looking at a union? Many matrix implementations have a union of the rows as vectors and the individual elements as an array.

EDIT: And you can also use 12 values for a 4x4 matrix if it isn't a perspective matrix since the last row (or column, depending on whether row or column major) is always (0 0 0 1), so that can be discarded when storing the matrix (i.e. store the 3x3 rotation matrix and the 1x3 translation part only).

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

jjval4.jpg

b3lsnq.png

This was supposed to be an identity matrix. It hasn't been timesed with anything so it can't be a union with anything can it? Another question, why do vec4s have 12 values when their name would suggest they have 4? What do vec4's do with their remaining 8 values when using them as a position vector?

Right, that is a union. It's a 4 element vector which can be referred to as either x,y,z,w (point/direction vector), rgba (colour) or stpq (texture coordinates).

Identity matrices have to be square, that's just a 4-element vector with the first element equal to 1.

EDIT: Looks like each row is a 4 element vector, there are probably 3 other rows (value[1], value[2], value[3]).

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

Thanks, that makes sense. So the values are just repeated, and if you want to use it for colours or textures you can use the name familiar to you instead of x, y, z, w. I suppose you don't have any ideas about my problem?

I think you need to apply 2 transforms to the point (move it back to origin, rotate and move back). You are just overwriting the translation before you apply the matrix, looks like to me (I'm guessing translate and rotate just set elements of the matrix rather than actually apply them to a point or vector).

Try stepping through with known values of inputs to see what is going on.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

Never mind, I fixed it! It was a stupid mistake! I learned about mat4's with this post though, so that's good I guess :-) This should be a rule taught very firmly to beginners .... look for the stupid mistakes before assuming there is something wrong with the harder-to-understand code. Sort of like, "If you hear hoof-beats, assume horse not zebra"

This topic is closed to new replies.

Advertisement