3D Rad - Free 3D game maker - Forum

This forum is now archived!

This forum is locked, and is a read-only version. A new community-ran forum can be found at classdev.net

News:

The 3DRad community can be found at classdev.net.

Pages: [1]

Author Topic: Rotataternions: Take the bite out of Quaternions  (Read 701 times)

« on: March 15, 2013, 02:50:01 PM »
Now you don't have to spend any more sleepless nights worrying about Quaternions. Quaternions are those horrible invaders from the fourth maths dimension that creep into game programs and screw with your head.  The makers of the self writing game called Dream-on now bring you the latest and the greatest invention of all time, Rotataternions.  Rotataternions have taken the scare out of Quaternions by pulling their maths teeth, and provide you with a few set of simple functions to turn all your game objects in mid-air. We now have a special offer for the unbelievable price of $0.

If you buy your  Rotataternions now, we will throw in for free. Yes you heard us right. For free. We will throw in an extra set of functions that make your game objects rotate in both local space and in world space. Can you believe it? This unbelievable offer of Rotataternions is something that every game maker needs more than biscuits.

If you buy the Global rotations, we will throw in the Local rotations for free. If you buy the Local rotations, we will throw in the Global rotations for free.  For the low low price of only $0 you too can  make your game objects rotate by simply passing your object and an angle to a function, and the Rotataternions will do all the work for you. Impress your neighbors or even your boss with the power of Rotataternions in your own games. No one will believe their eyes, as you blow their minds with your new found game making powers.

Get your Rotataternions now. Why waste any more sleepless nights, and why pull out all your hair and go bald prematurely? Let Rotataternions turn your world upside down, and at the same time save your hair.

Brought to you by the makers of Dream-On. The game that writes itself.

Edit: Script corrected and replaced. Thanks to AllanF for pointing out the bug
 
« Last Edit: March 26, 2013, 08:08:14 AM by XingBat »
« Reply #1 on: March 15, 2013, 06:52:37 PM »
I think you pretty much summed up the possible single-spinning-object functions.
« Reply #2 on: March 16, 2013, 08:38:46 AM »
Still not quite foolproof... I suspect good old "gimbal lock"  is somehow making its presence felt?

Play around with A and S keys alternately (maybe 60deg at a time) and you end up with the SCALE :o of the plane changing (Einsteins Relativity at it best!):

AKA: The 3D Raddict http://www.3draddict.com/
« Reply #3 on: March 16, 2013, 09:04:33 AM »
Yes, that was quite interesting indeed. Thanks for the pointer Allan. I does seem to happen with large rotation angles at a time. With small rotation steps however, such as normally used in a game, everything seems to works just fine.

Just to preempt any nasty mud slinging at my functions, I need to point out that these functions use internal 3DRad function calls, and any other use of very large single step rotations based on the quaternion calls will yield the same result. I just used the tools that were available. 
« Reply #4 on: March 16, 2013, 09:45:56 AM »
Normalizing the quaternion afterwards should fix it.
(my initially posted function seemed to break 3drad. This seems not to)
Here's the script with a normalize function tied to Spacebar
Code: [Select]
void Y_yaw(int obj, float angle){
   Quaternion p,n;
   iObjectOrientation(obj,p);
   iQuaternionFromEulerAngles(n,0,angle,0,"xyz");
   iQuaternionMultiply(n,n,p);
   iObjectOrientationSet(obj,n);
}

void X_pitch(int obj, float angle){
   Quaternion p,n;
   iObjectOrientation(obj,p);
   iQuaternionFromEulerAngles(n,angle,0,0,"xyz");
   iQuaternionMultiply(n,n,p);
   iObjectOrientationSet(obj,n);
}

void Z_roll(int obj, float angle){
   Quaternion p,n;
   iObjectOrientation(obj,p);
   iQuaternionFromEulerAngles(n,0,0,angle,"xyz");
   iQuaternionMultiply(n,n,p);
   iObjectOrientationSet(obj,n);
}

void X_rotate(int obj, float angle){
   Quaternion p,n;
   iObjectOrientation(obj,p);
   iQuaternionFromEulerAngles(n,angle,0,0,"xyz");
   iQuaternionMultiply(p,p,n);
   iObjectOrientationSet(obj,p);
}

void Y_rotate(int obj, float angle){
   Quaternion p,n;
   iObjectOrientation(obj,p);
   iQuaternionFromEulerAngles(n,0,angle,0,"xyz");
   iQuaternionMultiply(p,p,n);
   iObjectOrientationSet(obj,p);
}

void Z_rotate(int obj, float angle){
   Quaternion p,n;
   iObjectOrientation(obj,n);
   iQuaternionFromEulerAngles(n,0,0,angle,"xyz");
   iQuaternionMultiply(p,p,n);
   iObjectOrientationSet(obj,p);
}

float s= 60;
void Main()
{
   //Local
   if (iKeyDown(iKeyCode("DIK_LEFT")))   Y_yaw(OBJ_0,  -s);
   if (iKeyDown(iKeyCode("DIK_RIGHT")))  Y_yaw(OBJ_0,   s);
   if (iKeyDown(iKeyCode("DIK_UP")))     X_pitch(OBJ_0,-s);
   if (iKeyDown(iKeyCode("DIK_DOWN")))   X_pitch(OBJ_0, s);
   if (iKeyDown(iKeyCode("DIK_COMMA")))  Z_roll(OBJ_0,  s);
   if (iKeyDown(iKeyCode("DIK_PERIOD"))) Z_roll(OBJ_0, -s);

   //Global
   if (iKeyDown(iKeyCode("DIK_Q")))   Y_rotate(OBJ_0,  -s);
   if (iKeyDown(iKeyCode("DIK_w")))   Y_rotate(OBJ_0,   s);
   if (iKeyDown(iKeyCode("DIK_A")))   X_rotate(OBJ_0,  -s);
   if (iKeyDown(iKeyCode("DIK_z")))   X_rotate(OBJ_0,   s);
   if (iKeyDown(iKeyCode("DIK_S")))   Z_rotate(OBJ_0,   s);
   if (iKeyDown(iKeyCode("DIK_d")))   Z_rotate(OBJ_0,  -s);

   if (iKeyDown(iKeyCode("DIK_SPACE")))   normalize(OBJ_0);
}

void normalize(int obj){
   Quaternion p,n;
   iObjectOrientation(obj,n); p= qNorm(p);
   iObjectOrientationSet(obj,p);
}

Quaternion qNorm(Quaternion q) {
Quaternion n;
float m= iFloatSqrt(q.w*q.w + q.x*q.x + q.y*q.y + q.z*q.z);
return Quaternion(q.x/m, q.y/m, q.z/m, q.w/m);
}

« Last Edit: March 16, 2013, 10:14:27 AM by chronocide »
« Reply #5 on: March 16, 2013, 10:22:27 AM »
XingBat:

There was a small bug in your script  ;D

Code: [Select]
void Z_rotate(int obj, float angle){
   Quaternion p,n;
   iObjectOrientation(obj,n);//<-------------------------------should be p!
   iQuaternionFromEulerAngles(n,0,0,angle,"xyz");
   iQuaternionMultiply(p,p,n);
   iObjectOrientationSet(obj,p);
}

AKA: The 3D Raddict http://www.3draddict.com/
« Reply #6 on: March 16, 2013, 10:27:26 AM »
Woops - weird, don't know how that happened
« Reply #7 on: March 16, 2013, 10:42:54 AM »
chronocide:

Just to clarify...

In my initial post to XingBat:
Quote
Play around with A and S keys alternately (maybe 60deg at a time)

I was not referring to the script to increment the angle 60deg at a time (as you have done in your last code example)... the A and S keys were still incrementing the angle by 1deg successively. I just meant to use the A key until a 60deg rotation had been obtained.
AKA: The 3D Raddict http://www.3draddict.com/
« Reply #8 on: March 16, 2013, 11:06:23 AM »
I thought something like that might be going on.
« Reply #9 on: March 16, 2013, 11:37:37 AM »
Thanks for pointing out the bug AllanF. The 60 degrees step does rescale the model, which led me to not look at the script in further detail.
« Last Edit: March 26, 2013, 08:07:21 AM by XingBat »
Pages: [1]