Sign in to follow this  
Delfi

instead of glRotatef build a matrix

Recommended Posts

Delfi    106
I'm not very skilled with math, but i'm wondering what does glRotatef do internally?

I have some legacy code which does some math i don't really understand and sends values to glRotatef. I am implementing a physics engine to go with this legacy code and i need a 4x4 matrix instead of that output, i don't really understand how the rotation along a vector glrotatef thing works, but i just need a resulting matrix - which if i multiplied with glMultMatrixf instead of glrotatef would result in same working output.

Thanks.

Share this post


Link to post
Share on other sites
mrchrismnh    82
[quote name='Delfi' timestamp='1303587657' post='4802033']
I'm not very skilled with math, but i'm wondering what does glRotatef do internally?

I have some legacy code which does some math i don't really understand and sends values to glRotatef. I am implementing a physics engine to go with this legacy code and i need a 4x4 matrix instead of that output, i don't really understand how the rotation along a vector glrotatef thing works, but i just need a resulting matrix - which if i multiplied with glMultMatrixf instead of glrotatef would result in same working output.

Thanks.
[/quote]


Try the Euler matrices for x,y,and z axes; glMultMatrixf(euler_y_mat_with_desired_angle); will get you spin around the y axis, and you can also multiply them together for multi-axis transforms taking care to avoid locks.

Share this post


Link to post
Share on other sites
Aks9    1499
If you need just a matrix, here it is:

[code]
| x^2*(1-c)+c x*y*(1-c)-z*s x*z*(1-c)+y*s 0 |
R = | y*x*(1-c)+z*s y^2*(1-c)+c y*z*(1-c)-x*s 0 |
| x*z*(1-c)-y*s y*z*(1-c)+x*s z^2*(1-c)+c 0 |
| 0 0 0 1 |
[/code]

[[b]x[/b],[b] y[/b],[b] z[/b]] - a vector about which the rotation should be done

[b]c[/b] - cos(alpha)

[b]s[/b] - sin(alpha)

[b]alpha[/b] - rotation angle

Share this post


Link to post
Share on other sites
Nanoha    2682
May be of some use to you:
[url="http://en.wikipedia.org/wiki/Rotation_matrix"]http://en.wikipedia.org/wiki/Rotation_matrix[/url]
Most are 3x3, just add 0, 0, 0, 1 column/row vectors in the 4th colum/row to get it 4x4.
The [url="http://en.wikipedia.org/wiki/Rotation_matrix#General_rotations"]http://en.wikipedia.org/wiki/Rotation_matrix#General_rotations[/url] section shows you euler angles

Share this post


Link to post
Share on other sites
Delfi    106
Ok thanks, based on that i wrote this function (sorry for pascal syntax):

[code]
function CreateGlRotateMatrix(angle, x, y, z: single) : TMatrix;
var
axis: TVector3f;
b, c, ac, s: single;
begin
result:= IdentityHmgMatrix;

c:= cos(angle);
s:= sin(angle);

result[0,0] := (x*x) * (1-c)+c;
result[1,0] := x*y * (1-c)-z*s;
result[2,0] := x*z * (1-c)+y*s;

result[0,1] := y*x * (1-c)+z*s;
result[1,1] := (y*y) * (1-c)+c;
result[2,1] := y*z * (1-c)-x*s;

result[0,2] := x*z * (1-c)-y*s;
result[1,2] := y*z * (1-c)+x*s;
result[2,2] := (z*z) * (1-c)+c;

end;
[/code]

The results aren't what it's supposed to be:

I replaced: glRotatef(Angle * 180 / Pi, Axis[0], Axis[1], Axis[2]);

With:

rotang:= CreateGlRotateMatrix( Angle * 180 / Pi, Axis[0], Axis[1], Axis[2]);
glMultMatrixf(@rotang[0,0]);

The results make a total mess when objects are rendered, none of rotations look correctly, did i get the matrix array addressing right? in delphi the matrix order are row-col based.

Share this post


Link to post
Share on other sites
Brother Bob    10344
[quote name='Aks9' timestamp='1303588668' post='4802038']
[[b]x[/b],[b] y[/b],[b] z[/b]] - a vector about which the rotation should be done
[/quote]
A [i]normalized[/i] vector. I guess you knew that already, but just making sure everyone knows it as well :cool:.

Share this post


Link to post
Share on other sites
Aks9    1499
[quote name='Brother Bob' timestamp='1303590032' post='4802049']
A [i]normalized[/i] vector. I guess you knew that already, but just making sure everyone knows it as well :cool:.
[/quote]

Yes, I've forgotten to say that. glRotatef auto-normalizes that vector. In our code, we should take care of normalization.


Also, be aware that GL assumes column-major order of matrices. If normalization doesn't help alone, transpose your matrix.

Share this post


Link to post
Share on other sites
Delfi    106
Ok, i tried normalizing the vector & transposing / not transposing but still no luck, here's new function i have:

[code]
function CreateGlRotateMatrix(angle, x, y, z: single) : TMatrix;
var
axis: TVector3f;
b, c, ac, s: single;
invLen : Single;
begin

invLen:= RSqrt(x * x + y * y + z * z);
x:= x * invLen;
y:= y * invLen;
z:= z * invLen;

result:= IdentityHmgMatrix;

c:= cos(angle);
s:= sin(angle);

result[0,0] := (x*x) * (1-c)+c;
result[1,0] := x*y * (1-c)-z*s;
result[2,0] := x*z * (1-c)+y*s;

result[0,1] := y*x * (1-c)+z*s;
result[1,1] := (y*y) * (1-c)+c;
result[2,1] := y*z * (1-c)-x*s;

result[0,2] := x*z * (1-c)-y*s;
result[1,2] := y*z * (1-c)+x*s;
result[2,2] := (z*z) * (1-c)+c;

// vectorgeometry.TransposeMatrix(result);

end;
[/code]

I can show some screenshots of the working (glrotatef) & non-working results (CreateGlRotateMatrix) if that would help in any way clear the situation on what's wrong with it.

Share this post


Link to post
Share on other sites
Jan-Lieuwe    206
[quote name='Delfi' timestamp='1303589991' post='4802048']
[code]
c:= cos(angle);
s:= sin(angle);
[/code]

The results aren't what it's supposed to be:

I replaced: glRotatef(Angle * 180 / Pi, Axis[0], Axis[1], Axis[2]);

With:

rotang:= CreateGlRotateMatrix( Angle * 180 / Pi, Axis[0], Axis[1], Axis[2]);
glMultMatrixf(@rotang[0,0]);

The results make a total mess when objects are rendered, none of rotations look correctly, did i get the matrix array addressing right? in delphi the matrix order are row-col based.
[/quote]

cos/sin take radians while glRotatef takes degrees. So you don't need the radians to degrees conversion (* 180 / PI) when calling your own function.

Share this post


Link to post
Share on other sites
Aks9    1499
[quote name='Delfi' timestamp='1303589991' post='4802048']
The results aren't what it's supposed to be:
I replaced: glRotatef(Angle * 180 / Pi, Axis[0], Axis[1], Axis[2]);

With:
rotang:= CreateGlRotateMatrix( Angle * 180 / Pi, Axis[0], Axis[1], Axis[2]);
[/quote]
Hey, I just noticed the way you pass angles... glRotatef() takes angle in degrees not in radians!!!

Previous two lines are not identical, because the angles are not the same.


Share this post


Link to post
Share on other sites
Delfi    106
Ok, thanks to everyone, here's the final working version:

[code]
function CreateGlRotateMatrix(angle, x, y, z: single) : TMatrix;
var
axis: TVector3f;
b, c, ac, s: single;
invLen : Single;
begin

angle:= vectorgeometry.degtorad(angle);

invLen:= RSqrt(x * x + y * y + z * z);
x:= x * invLen;
y:= y * invLen;
z:= z * invLen;

result:= IdentityHmgMatrix;

c:= cos(angle);
s:= sin(angle);

result[0,0] := (x*x) * (1-c)+c;
result[1,0] := x*y * (1-c)-z*s;
result[2,0] := x*z * (1-c)+y*s;

result[0,1] := y*x * (1-c)+z*s;
result[1,1] := (y*y) * (1-c)+c;
result[2,1] := y*z * (1-c)-x*s;

result[0,2] := x*z * (1-c)-y*s;
result[1,2] := y*z * (1-c)+x*s;
result[2,2] := (z*z) * (1-c)+c;

end;
[/code]

This finally matches the game's map files to build a proper matrix, it uses this with some "odd" quaternion conversion routine, which i couldn't reproduce with any other quaternion to matrix algorythm on the internet:

[code]
// preprocess quarternion rotations
X := rx;
Y := ry;
Z := rz;
W := -rw;
S := Sqrt(1.0 - W * W);

// divide by zero
if not (S = 0) then
begin
Axis[0] := X / S;
Axis[1] := Y / S;
Axis[2] := Z / S;
Angle := 2 * geometry.ArcCos(W);

if not (Angle = 0) then begin

rotang:= CreateGlRotateMatrix( Angle * 180 / Pi, Axis[0], Axis[1], Axis[2]);
glMultMatrixf(@rotang[0,0]);

//glRotatef(Angle * 180 / Pi, Axis[0], Axis[1], Axis[2]);

end;
end;
[/code]

But this only works on game file quaternions. If i use this on the game's quaternions from the memory i get some strange results, i'll post that as another question if i can't figure it out soon :S Edited by Delfi

Share this post


Link to post
Share on other sites
wolfscaptain    200
Hidden
[quote name='Delfi' timestamp='1303587657' post='4802033']
I'm not very skilled with math, but i'm wondering what does glRotatef do internally?

I have some legacy code which does some math i don't really understand and sends values to glRotatef. I am implementing a physics engine to go with this legacy code and i need a 4x4 matrix instead of that output, i don't really understand how the rotation along a vector glrotatef thing works, but i just need a resulting matrix - which if i multiplied with glMultMatrixf instead of glrotatef would result in same working output.

Thanks.
[/quote]

It multiplies the internal modelview matrix by a rotation matrix that was constructed with your parameters.
You can see how OpenGL constructs the rotation matrix in the respective page http://www.opengl.org/sdk/docs/man/xhtml/glRotate.xml

Share this post


Link to post

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