Skip to main content
gamedev.net
🔒 Locked 🎮 Unity

Getting difference between 2 rotations [SOLVED]

Started by Wrz Apr 16, 2009 at 7:03 AM 2 replies 1.2k views
Original Post
Wrz
Wrz
Well, OK, I 've I have a problem to solve, maybe anyone is able to help... Consider I have 2 objects in a 1 file (3ds or any, ain't matter), and only triangle vertices are known, i.e. there is no orientation matrices available. Now, consider that these objects are exactly the same, but orientation and scale of first object (let it be base object) differs from orientation and scale of second object. The question is : how can I build such rotation matrix, to be able to rotate base object same like the second object is rotated? I mean - I want to keep only 1 mesh, not 2 or N meshes (here might be a lot of copied objects in a file, and all of them are rotated somehow), and also a rotation matrices for any other objects cloned. Note : all triangle indexes are the same for all objects cloned, i.e. 1st triangle of 1st object 1 is the same as 1st triangle of 2nd object in their triangle arrays. I tried to solve this, but the pseudocode below not only rotates the object, but also skews it. vector3 t1,t2,t3,t4,t5,t6; t1 = obj[0].face[0].f_vertex[0]]; t2 = obj[0].face[0].f_vertex[1]]; t3 = obj[0].face[0].f_vertex[2]]; t4 = obj[1].face[0].f_vertex[0]]; t5 = obj[1].face[0].f_vertex[1]]; t6 = obj[1].face[0].f_vertex[2]]; vector3 v = t1 - t3; vector3 v2 = t3 - t2; vector3 normal = vector_normalize(vector_cross_product(v, v2)); vector3 vv = t4 - t6; vector3 vv2 = t6 - t5; vector3 normal2 = vector_normalize(vector_cross_product(vv, vv2)); vector3 up = camera.camera_up_vector; vector3 rght = vector_normalize(vector_cross_product(normal,up)); vector3 upp = vector_normalize(vector_cross_product(rght,normal)); vector3 rght2 = vector_normalize(vector_cross_product(normal2,up)); vector3 upp2 = vector_normalize(vector_cross_product(rght2,normal2)); After this, 2 matrices are constructed from these basis vectors, yielding a final matrix simply multiplying 2 matrices given. Then, I apply final matrix to other object using glMultmatrixf. Is this approach correct? Why object is not only rotated (and rotated right) , but also skewed? How can I avoid the skewing? Or what can I do to get rotation if only mesh data available? Any another way? Any ideas? [Edited by - Wrz on April 17, 2009 7:50:36 AM]
Sneftel
Sneftel
You need to solve a linear system. Pick three non-collinear vertices and line their coordinate column vectors from obj1 up side by side into a 3x3 matrix (call it M1), then do the same thing with the same vertices but from obj2 (call it M2). so you have:

R * M1 = M2
R = M2 * M1-1
So just invert M1 (this is why the vertices can't be collinear) and postmultiply it by M2.
Wrz
Wrz
Did like you told me, but it seems I did it incorrect, or maybe triangle arrays are not equal.

As result, object is rotated, skewed and flat.

Code :

Note matrix is

11 12 13
21 22 23
31 32 33

t1 = obj[0].face[0].f_vertex[0]];
t2 = obj[0].face[0].f_vertex[1]];
t3 = obj[0].face[0].f_vertex[2]];

t4 = obj[1].faces[0].f_vertex[0]];
t5 = obj[1].faces[0].f_vertex[1]];
t6 = obj[1].faces[0].f_vertex[2]];

Hmm, AFAIK triangle has 3 non-collinear vertices, so I take same like in first post

matrix3x3 m,m2;

m.m11 = t1.x;
m.m12 = t2.x;
m.m13 = t3.x;
m.m21 = t1.y;
m.m22 = t2.y;
m.m23 = t3.y;
m.m31 = t1.z;
m.m32 = t2.z;
m.m33 = t3.z;

m2.m11 = t4.x;
m2.m12 = t5.x;
m2.m13 = t6.x;
m2.m21 = t4.y;
m2.m22 = t5.y;
m2.m23 = t6.y;
m2.m31 = t4.z;
m2.m32 = t5.z;
m2.m33 = t6.z;

m = matrix_inverse(m);

matrix3x3 ma = m2*m;

After this glMultMatrixf(ma);

Also matrix functions :

inline float matrix_determinant(matrix3x3 m)
{
return (float)(m.m11 * (m.m22 * m.m33 - m.m23 * m.m32) + m.m12 * (m.m23 * m.m31 - m.m21 * m.m33) + m.m13 * (m.m21 * m.m32 - m.m22 * m.m31));
}

inline matrix3x3 operator*(matrix3x3 m,matrix3x3 m2)
{
return matrix3x3

(m.m11 * m2.m11 + m.m12 * m2.m21 + m.m13 * m2.m31,
m.m11 * m2.m12 + m.m12 * m2.m22 + m.m13 * m2.m32,
m.m11 * m2.m13 + m.m12 * m2.m23 + m.m13 * m2.m33,
m.m21 * m2.m11 + m.m22 * m2.m21 + m.m23 * m2.m31,
m.m21 * m2.m12 + m.m22 * m2.m22 + m.m23 * m2.m32,
m.m21 * m2.m13 + m.m22 * m2.m23 + m.m23 * m2.m33,
m.m31 * m2.m11 + m.m32 * m2.m21 + m.m33 * m2.m31,
m.m31 * m2.m12 + m.m32 * m2.m22 + m.m33 * m2.m32,
m.m31 * m2.m13 + m.m32 * m2.m23 + m.m33 * m2.m33);
}

inline matrix3x3 operator*(matrix3x3 m,float f)
{
return matrix3x3(m.m11 * f,m.m12 * f,m.m13 * f,m.m21 * f,m.m22 * f,m.m23 * f,m.m31 * f,m.m32 * f,m.m33 * f);
}

inline matrix3x3 matrix_inverse(matrix3x3 m)
{
matrix3x3 mm;

float det = matrix_determinant(m);

mm.m11 = m.m33*m.m22-m.m32*m.m23;
mm.m12 = -(m.m33*m.m12-m.m32*m.m13);
mm.m13 = m.m23*m.m12-m.m22*m.m13;
mm.m21 = -(m.m33*m.m21-m.m31*m.m23);
mm.m22 = m.m33*m.m11-m.m31*m.m13;
mm.m23 = -(m.m23*m.m11-m.m21*m.m13);
mm.m31 = m.m32*m.m21-m.m31*m.m22;
mm.m32 = -(m.m32*m.m11-m.m31*m.m12);
mm.m33 = m.m22*m.m11-m.m21*m.m12;

float d = 1/det;

mm = mm*d;

return mm;
}


Hmm, tried to transpose the final matrix, now it yields the same result as in my first post. Rotated and skewed.

Applying final matrix like :

float matrix[16];

matrix[0] = ma.m11;
matrix[1] = ma.m21;
matrix[2] = ma.m31;
matrix[3] = 0;

matrix[4] = ma.m12;
matrix[5] = ma.m22;
matrix[6] = ma.m32;
matrix[7] = 0;

matrix[8] = ma.m13;
matrix[9] = ma.m23;
matrix[10] = ma.m33;
matrix[11] = 0;

matrix[12] = position.x;
matrix[13] = position.y;
matrix[14] = position.z;
matrix[15] = 1;

glMultMatrixf(ma);

// Draw the object here

But if I apply not transposed matrix, then object becomes flat, skewed and rotated.

And else - base object and cloned object are not centered to origin, do I need to transform all the geometry such that object's center will be 0,0,0 in world coords, before constructing matrices, although all vertices are in world coords?

Edit : tried to transform all to be centered to 0,0,0 - no luck.

Dunno why it skews, eh... everything seems to be OK, but...

Maybe I got to try quaternions, but not sure it 'll help

*******

Edit again : now tested triangle arrays - 100% equal.

Well, OK... consider I have a matrix containing skew and rotation transform, how can I construct such matrix that will skew the given matrix back to 0,0,0 thus removing skew, but keeping rotation as it is?

Any ideas?

[Edited by - Wrz on April 16, 2009 9:27:39 AM]
Wrz
Wrz
Solved this skewing problem, all code above is correct, used Sneftel's method to construct matrices, but taking cross product between t1 and t2 instead t3, same for t6 (cross product between t4 and t5).

Generally skewing effect appeared due to triangle mesh data in file, both triangles (base and cloned) must be centered to world's origin (and probably must be scaled the same, i.e. cloned triangle must be scaled as base triangle is scaled).

To prove this, I created a file for testing, with only 2 triangles in. After centering both of them to origin, it yields a pure rotation matrix (note - triangles scaled to the same size, i.e. only rotation transforms given). If the same file, but with any triangle moved somehow, it yields a matrix containing skew. Not tested with scaling instead translation, but I think it will affect too.

So it seems any transforms except rotation must be removed before using the method mentioned above to rotate base object like cloned is. Otherwise, final matrix will accumulate another transforms than rotation too.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.