Matrix

Share your ZGE-development tips and techniques here!

Moderator: Moderators

Post Reply
User avatar
Kjell
Posts: 1715
Joined: Sat Feb 23, 2008 11:15 pm

Matrix

Post by Kjell » Sun Mar 01, 2009 4:58 pm

8)

Basic Matrix library for everybody that doesn't want to wait for BeRo's physics implementation ( I assume these functions are in there somewhere as well ). Uses ZGE's build-in Euler rotation space ( a Quaternion based Lib is coming up ).

The function takes the local space coordinates of a vector relative to the rotation pivot ( usually the mesh center unless you're colliding with something .. or you could be doing something like weight transferring ), and the euler rotation.

*Since there's no way to return Arrays you'll have to fetch the results from the Matrix Array yourself.

Useful for calculating rotated 3D Bounding Boxes / Triangles / Vertices coordinates and setting up your own Raycast behavior :wink:

Code: Select all

void RotationMatrixX(int K, float Angle)
{
  float C, S;

  C = cos(Angle);
  S = sin(Angle);

  Matrix[K,0,0] = 1;
  Matrix[K,0,1] = 0;
  Matrix[K,0,2] = 0;

  Matrix[K,1,0] = 0;
  Matrix[K,1,1] = C;
  Matrix[K,1,2] = S*-1;

  Matrix[K,2,0] = 0;
  Matrix[K,2,1] = S;
  Matrix[K,2,2] = C;
}

void RotationMatrixY(int K, float Angle)
{
  float C, S;

  C = cos(Angle);
  S = sin(Angle);

  Matrix[K,0,0] = C;
  Matrix[K,0,1] = 0;
  Matrix[K,0,2] = S;

  Matrix[K,1,0] = 0;
  Matrix[K,1,1] = 1;
  Matrix[K,1,2] = 0;

  Matrix[K,2,0] = S*-1;
  Matrix[K,2,1] = 0;
  Matrix[K,2,2] = C;
}

void RotationMatrixZ(int K, float Angle)
{
  float C, S;
  
  C = cos(Angle);
  S = sin(Angle);
  
  Matrix[K,0,0] = C;
  Matrix[K,0,1] = S*-1;
  Matrix[K,0,2] = 0;
  
  Matrix[K,1,0] = S;
  Matrix[K,1,1] = C;
  Matrix[K,1,2] = 0;
  
  Matrix[K,2,0] = 0;
  Matrix[K,2,1] = 0;
  Matrix[K,2,2] = 0;
}

//

void MultiplyMatrix(int K, int A, int B)
{
  Matrix[K,0,0] = Matrix[A,0,0]*Matrix[B,0,0]+Matrix[A,0,1]*Matrix[B,1,0]+Matrix[A,0,2]*Matrix[B,2,0];
  Matrix[K,0,1] = Matrix[A,0,0]*Matrix[B,0,1]+Matrix[A,0,1]*Matrix[B,1,1]+Matrix[A,0,2]*Matrix[B,2,1];
  Matrix[K,0,2] = Matrix[A,0,0]*Matrix[B,0,2]+Matrix[A,0,1]*Matrix[B,1,2]+Matrix[A,0,2]*Matrix[B,2,2];
  
  Matrix[K,1,0] = Matrix[A,1,0]*Matrix[B,0,0]+Matrix[A,1,1]*Matrix[B,1,0]+Matrix[A,1,2]*Matrix[B,2,0];
  Matrix[K,1,1] = Matrix[A,1,0]*Matrix[B,0,1]+Matrix[A,1,1]*Matrix[B,1,1]+Matrix[A,1,2]*Matrix[B,2,1];
  Matrix[K,1,2] = Matrix[A,1,0]*Matrix[B,0,2]+Matrix[A,1,1]*Matrix[B,1,2]+Matrix[A,1,2]*Matrix[B,2,2];

  Matrix[K,2,0] = Matrix[A,2,0]*Matrix[B,0,0]+Matrix[A,2,1]*Matrix[B,1,0]+Matrix[A,2,2]*Matrix[B,2,0];
  Matrix[K,2,1] = Matrix[A,2,0]*Matrix[B,0,1]+Matrix[A,2,1]*Matrix[B,1,1]+Matrix[A,2,2]*Matrix[B,2,1];
  Matrix[K,2,2] = Matrix[A,2,0]*Matrix[B,0,2]+Matrix[A,2,1]*Matrix[B,1,2]+Matrix[A,2,2]*Matrix[B,2,2];
}

//

void Rotate(float VX, float VY, float VZ, float AX, float AY, float AZ)
{
  RotationMatrixX(1,AX);
  RotationMatrixY(2,AY);
  RotationMatrixZ(3,AZ);
  
  MultiplyMatrix(4,1,2);
  MultiplyMatrix(5,4,3);
  
  Matrix[0,0,0] = VX*Matrix[5,0,0]+VY*Matrix[5,0,1]+VZ*Matrix[5,0,2];
  Matrix[0,1,0] = VX*Matrix[5,1,0]+VY*Matrix[5,1,1]+VZ*Matrix[5,1,2];
  Matrix[0,2,0] = VX*Matrix[5,2,0]+VY*Matrix[5,2,1]+VZ*Matrix[5,2,2];
}
Attached a simple implementation.

K
Attachments
Matrix.zgeproj
(3.68 KiB) Downloaded 507 times

User avatar
diki
Posts: 140
Joined: Thu Sep 11, 2008 7:53 pm
Location: GMT+1
Contact:

Post by diki » Sat Aug 01, 2009 8:04 pm

kjell, thanks for this nice library! i could not get my head around this topic before.

i've got one question, though: when trying to rotate a z-vector only by its y-axis (like: Rotate( 0, 0, 1, 0, App.CameraRotation.Y * Pi * 2, 0 )), i only get 0 for Matrix[0, 0, 0] and [0, 2, 0]. i worked around this by simply using an x-vector and substituting accordingly, but i wonder where my thinking went wrong; maybe you spot it immediately :)

the code snippet that works for me right now is this (pushing the camera along happily):

Code: Select all

Rotate( 10, 0, 0, 0, App.CameraRotation.Y * Pi * 2, 0 );

if( CamKeys.KeyIndex == 0 ){ // W, forward
        App.CameraPosition.X = App.CameraPosition.X -( Matrix[ 0, 2, 0 ] * App.DeltaTime );
        App.CameraPosition.Z = App.CameraPosition.Z -( Matrix[ 0, 0, 0 ] * App.DeltaTime );
        }

User avatar
Kjell
Posts: 1715
Joined: Sat Feb 23, 2008 11:15 pm

Post by Kjell » Sat Aug 01, 2009 9:58 pm

Hi diki,

Can't believe this mistake has gone unnoticed for all this time. Change the 0 of "Matrix[K,2,2] = 0;" of "RotationMatrixZ" into 1 .. should do the trick.

Entschuldigung ~
K

User avatar
diki
Posts: 140
Joined: Thu Sep 11, 2008 7:53 pm
Location: GMT+1
Contact:

Post by diki » Sun Aug 02, 2009 7:18 am

Kjell wrote:Entschuldigung ~
hehe, no harm done :)
Dankeschön again for your time!

User avatar
diki
Posts: 140
Joined: Thu Sep 11, 2008 7:53 pm
Location: GMT+1
Contact:

Post by diki » Thu Jan 07, 2010 11:45 pm

i've been trying to expand this library to 4x4-matrices so it could be used for calculating homogenous coordinates; since i don't know math, that is quite the mental challenge for me (the implementation would not be too hard). i'm stuck at the following: while i can find & understand the multiplication matrices needed to translate, rotate, scale etc., i don't know how to get the corresponding data back out of the matrix. i guess it is an obvious 'reverse' operation for people knowing their way around this topic; could you give me a hint/link/google keyword to search for?

that's be so rad :D

AndersO
Posts: 4
Joined: Mon Feb 27, 2017 7:47 pm

I'm stumped ... please help

Post by AndersO » Sat Mar 04, 2017 6:14 pm

I've managed to use the matrix functions (Thanks!) to rotate my ring of boxes, but I totally fail to get the local rotation of each box right.

This really involves more math than I have done in many a year, but I have made an attempt at understanding composing and decomposing rotation matrices.

My guess, which does not work, was the following

theta_x = atan2( Matrix[5,2,1], Matrix[5,2,2]);
theta_y = atan2( -1.0*Matrix[5,2,0], sqrt( Matrix[5,2,1]*Matrix[5,2,1] + Matrix[5,2,2]*Matrix[5,2,2] ));
theta_z = atan2( Matrix[5,1,0], Matrix[5,0,0]);

Am I on the right track, and if so, can someone please point me to where I went wrong?
help.gif
help.gif (552 Bytes) Viewed 4960 times

Post Reply