Delfi 106 Report post Posted April 23, 2011 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. 0 Share this post Link to post Share on other sites
mrchrismnh 82 Report post Posted April 23, 2011 [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. 0 Share this post Link to post Share on other sites
Aks9 1499 Report post Posted April 23, 2011 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 0 Share this post Link to post Share on other sites
Nanoha 2682 Report post Posted April 23, 2011 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 0 Share this post Link to post Share on other sites
Delfi 106 Report post Posted April 23, 2011 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. 0 Share this post Link to post Share on other sites
Brother Bob 10344 Report post Posted April 23, 2011 [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 . 0 Share this post Link to post Share on other sites
Aks9 1499 Report post Posted April 23, 2011 [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 . [/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. 0 Share this post Link to post Share on other sites
Delfi 106 Report post Posted April 23, 2011 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. 0 Share this post Link to post Share on other sites
Jan-Lieuwe 206 Report post Posted April 23, 2011 [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. 0 Share this post Link to post Share on other sites
Aks9 1499 Report post Posted April 23, 2011 [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. -1 Share this post Link to post Share on other sites
Delfi 106 Report post Posted April 23, 2011 (edited) 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 April 23, 2011 by Delfi 0 Share this post Link to post Share on other sites
wolfscaptain 200 Report post Posted April 24, 2011 · Hidden 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 0 Share this post Link to post