Sign in to follow this  
vraim

Inverted point transformation.

Recommended Posts

vraim    122
Hi, I got very quick question. Does anyone know how to do such a thing: 1. I got cloud of points with it's weight other then the 0,0,0. 2. I'm moving it to 0,0,0 then rotate and scale. 3. After that I'm getting the MODELVIEW_MATRIX: glGetFloatv(GL_MODELVIEW_MATRIX ,mr); 4. After that I'm drawing the box with corners (X0,Y0,Z0) -> (X1,Y1,Z1) 5. What I would like to do is to check are any of points from the cloud are in this box. What's more to make it work faster I would like to do it while I'm creating the lists ;-) I made it this way (by invertinf the MODELVIEW_MATRIX), but it works only when the object is not rotated and it's weight is in 0,0,0. int i,j, ti, tj, idst, jdst; // inverting the matrices for ( ti = 0; ti < 4; ti++ ) { if ( ti < i ) idst = ti; else if ( ti > i ) idst = ti-1; for ( tj = 0; tj < 4; tj++ ) { if ( tj < j ) jdst = tj; else if ( tj > j ) jdst = tj-1; if ( ti != i && tj != j ) mb[idst*3 + jdst] = mr[ti*4 + tj ]; } } // counting the new points selX0 = ((mb[0]*selX0)+(mb[4]*selX0)+(mb[8]*selX0)+(mb[12]*selX0)); selY0 = ((mb[1]*selY0)+(mb[5]*selY0)+(mb[9]*selY0)+(mb[13]*selY0)); selZ0 = ((mb[2]*selZ0)+(mb[6]*selZ0)+(mb[10]*selZ0)+(mb[14]*selZ0)); selX1 = ((mb[0]*selX1)+(mb[4]*selX1)+(mb[8]*selX1)+(mb[12]*selX1)); selY1 = ((mb[1]*selY1)+(mb[5]*selY1)+(mb[9]*selY1)+(mb[13]*selY1)); selZ1 = ((mb[2]*selZ1)+(mb[6]*selZ1)+(mb[10]*selZ1)+(mb[14]*selZ1)); // after that I'm just checking is the point from the cloud between those points. // I'm using PROJECTION MATRIX only in the beginning or while window changes. Any ideas how can I make it work? Jacek

Share this post


Link to post
Share on other sites
Sergi    138
In order to test if a point is inside an oriented bounding box, you must transform the point to box space (by multiplying the point by the inverse transform of the box). After that, check if the transformed point is inside the box extents.

I think you are transposing the modelview matrix and it is not correct because the modelview is not only a rotation matrix (it may be a concatenation of scale, translate and rotation transforms).

The inverse of rotation matrix is the transposed one. If the matrix is not only a rotation matrix you must use another method to invert the matrix. You can find source code in Eberly's site (http://www.geometrictools.com).

Sergi

Share this post


Link to post
Share on other sites
Sergi    138
I think you are confused with model, view and projection matrices. Model matrix represents the world transformation of the object, you must invert only the model matrix.

The view matrix transforms the vertices from world space to camera space (in camera space the origin is 0,0,0). The projection matrix transform the vertices from camera space to clip space (normalized devices coordinates).

The problem is that opengl stores the model and view in the same matrix (gl_modelview). You should split this matrix into two matrices.

You can use the following equations (MV = modelview, M = model, V = view):

MV = M * V

MV * V~-1 = M

where V~-1 is the inverse of the view matrix (the view matrix is usually generated with a gluLookAt call).

Share this post


Link to post
Share on other sites
vraim    122
Quote:
Original post by Sergi
You can use the following equations (MV = modelview, M = model, V = view):

MV = M * V

MV * V~-1 = M

where V~-1 is the inverse of the view matrix (the view matrix is usually generated with a gluLookAt call).


Yeah, I am confused, you're right :/

But I finally see something :-)

Because to get my points variables i need M~-1 (am I thinking good?)

And if my V is static (gluLookAt(0.0,0.0,5.0f,0.0,0.0,0.0f,0.0,1.0,0.0);) is there any other easier way to get it?
I'm still not quite sure how can I get 4x4 matrix from 3x3 matrix which I got in gluLookAt.

Any way you're a god to me. While reading books aout OGL I didn't get that the MODELVIEW MATRIX is a MODEL & VIEW MATRIX. :/

Share this post


Link to post
Share on other sites
vraim    122
According to the last mail.
I find the following thing on IBM site, does it works with OpenGL?

The 3x3 matrix is expanded by the graPHIGS API into a 4x4 matrix as follows:

__|a b c|_________|a b 0 c|
__|d e f |__---->__|d e 0 f|
__|g h i |_________|0 0 1 0|
_________________|g h 0 i|

Can I change the 3x3 gluLookAt matrix into 4x4 as it is above? Is it mathematicaly correctly? ;-)

If so my VIEW MATRIX should look like this:
0.0f,0.0f,0.0f,5.0f,
0.0f,0.0f,0.0f,0.0f,
0.0f,0.0f,1.0f,0.0f,
0.0f,1.0f,0.0f,0.0f

where gluLookAt =
0.0f,0.0f,5.0f,
0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f

Am I correct?

Share this post


Link to post
Share on other sites
Sergi    138
gluLookAt also generates a 4x4 matrix (because a view matrix translates to origin in camera space -0,0,0- and rotate the view to look at the center point). In your code you should have something like this:

matrix44 modelview, view, vinv, model;

glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); // set modelview to identity matrix
gluLookAt(...);
// grab modelview matrix, now its' only the view matrix
glGetFloatv(GL_MODELVIEW,view);
// invert the view matrix
Invert(view,vinv);// using a correct method to invert the matrix
// now scale, translate and rotate your models
glScale(...);
glTranslate(...);
glRotate(...);
// ... etc

// now get modelview matrix (now it's a concatenation of model and view matrices)
glGetFloatv(GL_MODELVIEW,modelview);
// compute model matrix
model = vinv * modelview; // standard 4x4 matrix multiplication

You can find how to create the transformation matrices used in OpenGL in the link below:
http://fly.cc.fer.hr/~unreal/theredbook/appendixg.html

To understand what you are doing, I suggest to read Foley et all's Computer Graphics: Principles and Practice (it's the best book to learn).

Share this post


Link to post
Share on other sites
vraim    122
Your code is almost working, but I still got some problems with model when I'm rotating the basic model.

I'm using such code for matrices:

Inverting:

float d12,d13,d23,d24,d34,d41;

float tempMatrix[16] = {0};
d12 = viewM[2] * viewM[7] - viewM[3] * viewM[6];
d13 = viewM[2] * viewM[11] - viewM[3] * viewM[10];
d23 = viewM[6] * viewM[11] - viewM[7] * viewM[10];
d24 = viewM[6] * viewM[15] - viewM[7] * viewM[14];
d34 = viewM[10] * viewM[15] - viewM[11] * viewM[14];
d41 = viewM[14] * viewM[3] - viewM[15] * viewM[2];

tempMatrix[0] = (viewM[5] * d34 - viewM[9] * d24 + viewM[13] * d23);
tempMatrix[1] = -(viewM[1] * d34 + viewM[9] * d41 + viewM[13] * d13);
tempMatrix[2] = (viewM[1] * d24 + viewM[5] * d41 + viewM[13] * d12);
tempMatrix[3] = -(viewM[1] * d23 - viewM[5] * d13 + viewM[9] * d12);

// Calculate the determinant.

float determinant = viewM[0] * tempMatrix[0] + viewM[4] * tempMatrix[1] +
viewM[8] * tempMatrix[2] + viewM[12] * tempMatrix[3];

if(determinant != 0.0)
{
float invDeterminant = 1.0f / determinant;

// Compute rest of inverse.
tempMatrix[0] *= invDeterminant;
tempMatrix[1] *= invDeterminant;
tempMatrix[2] *= invDeterminant;
tempMatrix[3] *= invDeterminant;

tempMatrix[4] = -(viewM[4] * d34 - viewM[8] * d24 + viewM[12] * d23) * invDeterminant;
tempMatrix[5] = (viewM[0] * d34 + viewM[8] * d41 + viewM[12] * d13) * invDeterminant;
tempMatrix[6] = -(viewM[0] * d24 + viewM[4] * d41 + viewM[12] * d12) * invDeterminant;
tempMatrix[7] = (viewM[0] * d23 - viewM[4] * d13 + viewM[8] * d12) * invDeterminant;

// Pre-compute 2x2 dets for first two rows when computing cofactors
// of last two rows.
d12 = viewM[0] * viewM[5] - viewM[1] * viewM[12];
d13 = viewM[0] * viewM[9] - viewM[1] * viewM[8];
d23 = viewM[4] * viewM[9] - viewM[5] * viewM[8];
d24 = viewM[4] * viewM[13] - viewM[5] * viewM[12];
d34 = viewM[8] * viewM[13] - viewM[9] * viewM[12];
d41 = viewM[12] * viewM[1] - viewM[13] * viewM[0];

tempMatrix[8] = (viewM[7] * d34 - viewM[11] * d24 + viewM[15] * d23) * invDeterminant;
tempMatrix[9] = -(viewM[3] * d34 + viewM[11] * d41 + viewM[15] * d13) * invDeterminant;
tempMatrix[10] = (viewM[3] * d24 + viewM[7] * d41 + viewM[15] * d12) * invDeterminant;
tempMatrix[11] = -(viewM[3] * d23 - viewM[7] * d13 + viewM[11] * d12) * invDeterminant;
tempMatrix[12] = -(viewM[6] * d34 - viewM[10] * d24 + viewM[14] * d23) * invDeterminant;
tempMatrix[13] = (viewM[2] * d34 + viewM[10] * d41 + viewM[14] * d13) * invDeterminant;
tempMatrix[14] = -(viewM[2] * d24 + viewM[6] * d41 + viewM[14] * d12) * invDeterminant;
tempMatrix[15] = (viewM[2] * d23 - viewM[6] * d13 + viewM[10] * d12) * invDeterminant;

// Save the temp matrix to our matrix.
ivnViewM[0] = tempMatrix[0]; ivnViewM[1] = tempMatrix[1];
ivnViewM[2] = tempMatrix[2]; ivnViewM[3] = tempMatrix[3];
ivnViewM[4] = tempMatrix[4]; ivnViewM[5] = tempMatrix[5];
ivnViewM[6] = tempMatrix[6]; ivnViewM[7] = tempMatrix[7];
ivnViewM[8] = tempMatrix[8]; ivnViewM[9] = tempMatrix[9];
ivnViewM[10] = tempMatrix[10]; ivnViewM[11] = tempMatrix[11];
ivnViewM[12] = tempMatrix[12]; ivnViewM[13] = tempMatrix[13];
ivnViewM[14] = tempMatrix[14]; ivnViewM[15] = tempMatrix[15];


Multiply:

modelM[0] = mr[0]*ivnViewM[0] + mr[4]*ivnViewM[1] + mr[8]*ivnViewM[2] + mr[12]*ivnViewM[3];
modelM[1] = mr[0]*ivnViewM[4] + mr[4]*ivnViewM[5] + mr[8]*ivnViewM[6] + mr[12]*ivnViewM[7];
modelM[2] = mr[0]*ivnViewM[8] + mr[4]*ivnViewM[9] + mr[8]*ivnViewM[10] + mr[12]*ivnViewM[11];
modelM[3] = mr[0]*ivnViewM[12] + mr[4]*ivnViewM[13] + mr[8]*ivnViewM[14] + mr[12]*ivnViewM[15];
modelM[4] = mr[1]*ivnViewM[0] + mr[5]*ivnViewM[1] + mr[9]*ivnViewM[2] + mr[13]*ivnViewM[3];
modelM[5] = mr[1]*ivnViewM[4] + mr[5]*ivnViewM[5] + mr[9]*ivnViewM[6] + mr[13]*ivnViewM[7];
modelM[6] = mr[1]*ivnViewM[8] + mr[5]*ivnViewM[9] + mr[9]*ivnViewM[10] + mr[13]*ivnViewM[11];
modelM[7] = mr[1]*ivnViewM[12] + mr[5]*ivnViewM[13] + mr[9]*ivnViewM[14] + mr[13]*ivnViewM[15];
modelM[8] = mr[2]*ivnViewM[0] + mr[6]*ivnViewM[1] + mr[10]*ivnViewM[2] + mr[14]*ivnViewM[3];
modelM[9] = mr[2]*ivnViewM[4] + mr[6]*ivnViewM[5] + mr[10]*ivnViewM[6] + mr[14]*ivnViewM[7];
modelM[10] = mr[2]*ivnViewM[8] + mr[6]*ivnViewM[9] + mr[10]*ivnViewM[10] + mr[14]*ivnViewM[11];
modelM[11] = mr[2]*ivnViewM[12] + mr[6]*ivnViewM[13] + mr[10]*ivnViewM[14] + mr[14]*ivnViewM[15];
modelM[12] = mr[3]*ivnViewM[0] + mr[7]*ivnViewM[1] + mr[11]*ivnViewM[2] + mr[15]*ivnViewM[3];
modelM[13] = mr[3]*ivnViewM[4] + mr[7]*ivnViewM[5] + mr[11]*ivnViewM[6] + mr[15]*ivnViewM[7];
modelM[14] = mr[3]*ivnViewM[8] + mr[7]*ivnViewM[9] + mr[11]*ivnViewM[10] + mr[15]*ivnViewM[11];
modelM[15] = mr[3]*ivnViewM[12] + mr[7]*ivnViewM[13] + mr[11]*ivnViewM[14] + mr[15]*ivnViewM[15];


Any ideas? When I do all you said everything is working till I do any rotation. Because selected points are always moving with the basic model Z axis.

Share this post


Link to post
Share on other sites
vraim    122
Oh! Once more here is full path which I'm following to get the MODEL matrix:

1. get clear VIEW matrix (called viewM)
2. get full MODELVIEW matrix, after all tranformations (called mr)
3. invert the VIEW matrix (called invViewM)
4. getting MODEL matrix by multiplying mr * invViewM (called modelM)
5. invert modelM (called mb)
6. gettin' new points values by:
selX0 = (((mb[0]*selX0)+(mb[4]*selX0)+(mb[8]*selX0)+(mb[12]*selX0)));
selY0 = (((mb[1]*selY0)+(mb[5]*selY0)+(mb[9]*selY0)+(mb[13]*selY0)));
selZ0 = (((mb[2]*selZ0)+(mb[6]*selZ0)+(mb[10]*selZ0)+(mb[14]*selZ0)));

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this