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;
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:
// 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;
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