Getting position after transformation without drawing?

hyn
Unregistered
 
Post: #1
I have a point I want to rotate around an arbitrary axis AND know its object-space coordinates (not window coordinates) after rotation.

I can't use gluProject() because it returns window coordinates, not object-space. And there seems to be no version of gluProject() that returns an object-space coordinate.

Is there no easy way, can someone tell me the calculations involved?
Is it as simple as dot-producting my point with the modelview matrix?

Thank you,

-hyn
Quote this message in a reply
Member
Posts: 184
Joined: 2004.07
Post: #2
Hey hyn,
This thread I believe is essentially what you want: http://www.idevgames.com/forum/showthread.php?t=6466

If you already have an OpenGL matrix you want to transform with, you can use glGetFloatv(MODELVIEW... or something like that to load the matrix, and then you just do a normal matrix multiplication with your vertex to transform it.
Quote this message in a reply
hyn
Unregistered
 
Post: #3
Is there a specific order in which I should call the operations?
If I recall correctly order of rotations doesn't matter.

I need to do 3 rotations:

1. 23.5 degrees about z axis.
2. Rotate x degrees about x axis.
3. Rotate y degrees about y axis.


But doing the following gives me odd results (normals are correct but positions are not):

Code:
//  rotate coords on z axis costant degrees
newMatrix = [self matrixRotate: identity angle: 23.5 x: 0.0 y: 0.0 z: 1.0];
newCoords = [self matrixVmul: newMatrix with: coords];

//  rotate same coords again on x axis x degrees
newMatrix = [self matrixRotate: newMatrix angle: rotateX x: 1.0 y: 0.0 z: 0.0];
newCoords = [self matrixVmul: newMatrix with: newCoords];

//  rotate same coords again on y axis y degrees
newMatrix = [self matrixRotate: newMatrix angle: rotateY x: 0.0 y: 1.0 z: 0.0];
newCoords = [self matrixVmul: newMatrix with: newCoords];

matrixRotate does the exact same thing as kberg's Mat4_rot except it returns by value.
Same with matrixVmul.

I am also investigating the possibility of mistyping the code (I can't use copy paste from this networked computer to my working computer).

Also, I couldn't use sinf cosf sqrtf, they don't seem to be defined in math.h?
I used sin cos sqrt instead, which may be a problem?
Quote this message in a reply
Member
Posts: 184
Joined: 2004.07
Post: #4
sinf cosf sqrtf are just the float version of sin cos sqrt (instead of double.) so they're just less precise, but for your purposes it probably doesn't matter at all.

Matrix multiplication order does matter, but since you're just doing rotations, you should be able to transform both positions and normals with the same set of matrix multiplications. What exactly is happening to your positions?
Quote this message in a reply
hyn
Unregistered
 
Post: #5
Ok, dumb mistake. I was passing in degrees (instead of radians) in 'angle'.
Now the positions are closer to where it should be, but still not close enough.
They seem to rotate in excess by a bit about a fixed axis.
Quote this message in a reply
Member
Posts: 72
Joined: 2006.10
Post: #6
I think your problem is the following:

Since Matrix operations stack, I don't think that you should multiply the vector three times, but only once with the final matrix:

Code:
//  rotate coords on z axis costant degrees
newMatrix = [self matrixRotate: identity angle: 23.5 x: 0.0 y: 0.0 z: 1.0];

//  rotate same coords again on x axis x degrees
newMatrix = [self matrixRotate: newMatrix angle: rotateX x: 1.0 y: 0.0 z: 0.0];

//  rotate same coords again on y axis y degrees
newMatrix = [self matrixRotate: newMatrix angle: rotateY x: 0.0 y: 1.0 z: 0.0];
newCoords = [self matrixVmul: newMatrix with: coords];


The first rotation was applied three times, the second on two times, and the last one once...

- Sohta
Quote this message in a reply
Member
Posts: 72
Joined: 2006.10
Post: #7
Just thought of something.
If you want to save yourself all this trouble, you CAN use gluProject(). It simply is a matter of passing identity as the projection matrix instead of the one you fetch from GL.

- Sohta
Quote this message in a reply
hyn
Unregistered
 
Post: #8
Yes, I just realized that and changed it.
It fixed the starting position but the excess rotation is still there.
It looks like a math problem, I will check my code again... I would paste it if I could but the code is on my other computer.
Quote this message in a reply
hyn
Unregistered
 
Post: #9
And it would return object-space coordinates?
Quote this message in a reply
Member
Posts: 72
Joined: 2006.10
Post: #10
Simple, The modelview matrix, tranforms GL coordinates into GL coordinates ( think as in a camera ), the projection matrix transforms ( projects ) GL coordinates into screen coordinates. That's their respective purpose... So if you ignore the projection matrix, you get whatever transformation you wanted.

gluProject is a simple mathematical function:
it takes the input vector, multiplies it by both passed matrices, and returns the result...

Code:
GLfloat lIdentity[16] = {... } ;
GLFloat lModelView[16] ;
glPushMatrix();
glLoadIdentity();
glRotatef( 23.5, 0.0  , 0.0 , 1.0 ) ;
glRotatef( rotateX , 1.0 , 0.0 , 0.0 ) ;
glRotatef( rotateY , 0.0 , 1.0 , 0.0 );

glGetfloatfv( GL_MODELVIEW_MATRIX , lModelView ) ;

gluProject( x , y , z , lModelView , lIdentity , &outX , &outY , &outZ );
glPopmatrix();

Edit: HEY! your post changed! mine doesn't make much sense anymore Wacko

- Sohta
Quote this message in a reply
hyn
Unregistered
 
Post: #11
Yeah, sorry. I misread your post, I thought you wrote "pass in identity as modelview matrix".

I tried your approach, though, passing in identity as projection matrix. I actually got window coordinates.
Quote this message in a reply
Member
Posts: 72
Joined: 2006.10
Post: #12
You shouldn't just read the modelview matrix ( since it also contains the camera transformations ). Instead, you should do as in the sample code I wrote:

push it
load identity
apply transformations
read it
pop it

- Sohta
Quote this message in a reply
hyn
Unregistered
 
Post: #13
Hm. I still get window coordinates.
Sample values:

Code:
2004-08-04 20:30:22.609 appname[7689] Coords: 689.033813, 614.114014, 0.854608
2004-08-04 20:30:22.609 appname[7689] Coords: 674.286987, 646.422302, 0.817250
2004-08-04 20:30:22.609 appname[7689] Coords: 425.501709, 505.337494, 0.970633
2004-08-04 20:30:22.686 appname[7689] Coords: 731.874939, 598.971802, 0.849627
2004-08-04 20:30:22.687 appname[7689] Coords: 689.033813, 614.114014, 0.854608
2004-08-04 20:30:22.687 appname[7689] Coords: 674.286987, 646.422302, 0.817250
2004-08-04 20:30:22.687 appname[7689] Coords: 425.501709, 505.337494, 0.970633
2004-08-04 20:30:22.711 appname[7689] Coords: 731.874939, 598.971802, 0.849627
2004-08-04 20:30:22.711 appname[7689] Coords: 689.033813, 614.114014, 0.854608
2004-08-04 20:30:22.711 appname[7689] Coords: 674.286987, 646.422302, 0.817250
2004-08-04 20:30:22.711 appname[7689] Coords: 425.501709, 505.337494, 0.970633
2004-08-04 20:30:22.731 appname[7689] Coords: 731.874939, 598.971802, 0.849627
2004-08-04 20:30:22.732 appname[7689] Coords: 689.033813, 614.114014, 0.854608
2004-08-04 20:30:22.732 appname[7689] Coords: 674.286987, 646.422302, 0.817250
2004-08-04 20:30:22.732 appname[7689] Coords: 425.501709, 505.337494, 0.970633
2004-08-04 20:30:22.795 appname[7689] Coords: 731.874939, 598.971802, 0.849627
2004-08-04 20:30:22.811 appname[7689] Coords: 689.033813, 614.114014, 0.854608
2004-08-04 20:30:22.826 appname[7689] Coords: 674.286987, 646.422302, 0.817250
2004-08-04 20:30:22.840 appname[7689] Coords: 425.501709, 505.337494, 0.970633

And my code:

Code:
glPushMatrix();
        glLoadIdentity();
        glRotatef(kEarthTilt, 0.0, 0.0, 1.0);
        glRotatef(earthRotateX, 1.0, 0.0, 0.0);
        glRotatef(earthRotateY, 0.0, 1.0, 0.0);

        glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
        glGetIntegerv(GL_VIEWPORT, viewport);
        
        gluProject(coords.x, coords.y, coords.z, modelview, projection, viewport, &currentPosition[0], &currentPosition[1], &currentPosition[2]);
        
        coords.x = currentPosition[0];
        coords.y = currentPosition[1];
        coords.z = currentPosition[2];
        NSLog(@"Coords: %f, %f, %f", coords.x, coords.y, coords.z);
        
        glPopMatrix();
Quote this message in a reply
Member
Posts: 72
Joined: 2006.10
Post: #14
sry, I completely forgot, glProject also uses the viewPort Blush ...

Honestly, though, what you really should do is search the web for gluProject, have a look at the maths involved behind it and understand how it works for yourself.

However, I will give you the answer, since I commited myself to help you on this one.

the viewPort should be { 0 , 0 , 1 , 1 }

- Sohta
Quote this message in a reply
hyn
Unregistered
 
Post: #15
Thanks for your continued help.

Is there something you have assumed in your explanation that perhaps I might have overlooked? Because even though the values are much closer, they are still about 0.2 away from where they should be (farer away in that the values are a bit larger).
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  SDL. Current music position e40pud 0 2,347 Mar 9, 2010 08:46 AM
Last Post: e40pud
  New to OpenGL -- Transformation Help Dash Rantic 4 3,261 Mar 9, 2008 06:08 PM
Last Post: Dash Rantic
  Transformation from unit cube to view frustum TomorrowPlusX 10 6,697 Jul 12, 2005 11:32 AM
Last Post: TomorrowPlusX
  Object position after rotation charon 11 6,900 Mar 2, 2005 11:33 AM
Last Post: hangt5
  Put a Auto-cam in Top Position alert 5 4,145 Dec 15, 2004 05:37 AM
Last Post: Fenris