Basic Quaternion help

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
MisterRose
Posts: 18
Joined: Thu Jun 16, 2011 2:46 pm

Basic Quaternion help

Post by MisterRose »

I have been looking at forum posts, sample code, and tutorials for the past week and I am still not quite understanding something.

I am making a basic model viewer that loads in a mesh from a file and renders it on the screen. I have the camera set down the negative Y axis looking towards the origin. I did this because I wanted my model (which I didn't make, I just downloaded one and this is how it was set up) to be "facing away" from me without any rotation applied to it. You can then use the arrow buttons to rotate the mesh, pitch it up and down and roll it.

I have some code that uses vector3df data passed into the scene node's setRotation function. This works well until I try to roll it over, and I start getting weird results. No problem, this was anticipated since it was a known limitation of working with these parameters.

All over the place people say to use quaternions. This is where I need my first brain check. I'm trying to get the model to point in a direction, say up and to the rightat a 45 degree angle. I would think that I could do the following...

Code: Select all

quaternion q1(-45*DEGTORAD,0,35*DEGTORAD,20*DEGTORAD);
q1.normalize();
q1.toEuler(rot);
node->setRotation(rot);
 
Since I am looking down the Y axis (+Z is towards the top of the screen and +X is off to the left), I would expect this to rotate the model 45 degrees CCW around the X axis (which should pitch it "up"), and 35 degrees CW around the Z axis (which should turn it to the "right" from my current point of view) , and then rotate the model 20 degrees clockwise around this vector.

I don't see any rotation at all.

What am I doing wrong? I'm guessing that this is a common operation, so there should be plenty of code out there, but I cannot seem to find anything that works. I would like to boil this down to the simplest example, if possible.
You are unique - just like everyone else.
HerrAlmanack
Posts: 52
Joined: Mon Jun 13, 2011 3:50 pm

Re: Basic Quaternion help

Post by HerrAlmanack »

ehh, I use quats all the time, but I don't really deal with the specifics too much, it's been a while so I'm rusty on my math. however if you just want to get this done quickly and properly i suggest using the bullet physics linear math module. since bullet is designed to be modular you can use their Quaternion class without having to include all the rest of the bullet physics library.

this shows some of the basic "common" orientations.

http://www.gpwiki.org/index.php/OpenGL: ... t_rotation

also we have to remember we are not dealing with simple "normal" representations of angles in degrees.

quaternions use imaginary number properties, a simple google search should show a nice, clean table with all the properties of those numbers and transforming quaternion rotations. however rewriting methods to deal with all that would be a bit redundant, so best to just use a small library or something that provides an easy euler interface, but with all the backend and better stability of quats.
MisterRose
Posts: 18
Joined: Thu Jun 16, 2011 2:46 pm

Re: Basic Quaternion help

Post by MisterRose »

I read the link you posted (which was very informative) and I used the FromEuler function on the page to create my quaternion. Here's the code...

vector3df rot;
quaternion q1 = FromEuler(45, 35, 0);
q1.normalize();
q1.toEuler(rot);
node->setRotation(rot);

It still does not rotate.

I have to be overthinking this or approaching it from the wrong direction. I keep hearing the sentiment that you repeat - "I don't think about it much". But I just can't seem to get this simple example to work.
You are unique - just like everyone else.
MisterRose
Posts: 18
Joined: Thu Jun 16, 2011 2:46 pm

Re: Basic Quaternion help

Post by MisterRose »

I got it! I forgot to convert back to degrees.

Code: Select all

 
quaternion q1 = FromEuler(roll, heading, pitch);
q1.normalize();
q1.toEuler(rot);
node->setRotation(rot*RADTODEG);
 
The only thing that I need to look at was the FromEuler on the link above has roll and pitch reversed. I'll have to think that through and make sure I understand what is going on and that I didn't just get lucky.
You are unique - just like everyone else.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Basic Quaternion help

Post by mongoose7 »

I can't understand why you start from Euler angles, transform to quaternion, then back to Euler angles. Why not just

node->setRotation(vector3df(45, 35, 0)); ?

Anyway, that's beside the point. Why don't you show how you create the object that 'node' is pointing to?
Radikalizm
Posts: 1215
Joined: Tue Jan 09, 2007 7:03 pm
Location: Leuven, Belgium

Re: Basic Quaternion help

Post by Radikalizm »

As mongoose said, what you're doing is completely useless and will get the same results as directly setting the rotation in euler angles, any benefits gained from quaternions (eg. no gimbal lock) will vanish when you use euler angles as input

Irrlicht's quaternion class provides a fromAngleAxis() function ( see http://irrlicht.sourceforge.net/docu/cl ... rnion.html ) which lets you set up a rotation quaternion very intuitively by providing the axis the node should face and the rotation it should have around that axis
MisterRose
Posts: 18
Joined: Thu Jun 16, 2011 2:46 pm

Re: Basic Quaternion help

Post by MisterRose »

The reason I was doing it that way was so that I could input numbers that I can visualize. I'm new to 3D graphics and so I'm still coming up to speed on the details of how this is all supposed to work.

The node is just an animated mesh scene node created with...

Code: Select all

node = smgr->addAnimatedMeshSceneNode( mesh );
I tried the fromAngleAxis before, but it does not appear to face the node in a particular direction. It just rotates the mesh around the axis. And even then there is still some funny business when the rotations are at 90 degrees. If you put roll=0 and apply that to the model, it does not face the model in the direction of the vector. As you change roll, you can see it rotate about an axis, but it is hard to visualise it as being on the (1,1,1) vector. But that is probably just me.

Code: Select all

 
quaternion qRot;
qRot.fromAngleAxis(roll*DEGTORAD,vector3df(1,1,1));     
qRot.toEuler(rot);
node->setRotation(rot*RADTODEG);


This code seems to do what I want. That is, it puts the model into the desired orientation. I don't see any gimbal lock as I pitch, roll, or yaw through 90 degrees. Is this a valid way to do this? Is there a more efficient way?

Code: Select all

 
quaternion q1, qRot;
qRot = FromEulerVector(vector3df(0,1,0));
q1.fromAngleAxis(roll*DEGTORAD,vector3df(0,1,0));
q1.normalize();
qRot *= q1;
 
q1.fromAngleAxis(pitch*DEGTORAD,vector3df(1,0,0));
q1.normalize();
qRot *= q1;
 
q1.fromAngleAxis(heading*DEGTORAD,vector3df(0,0,1));
q1.normalize();
qRot *= q1;
 
qRot.toEuler(rot);
node->setRotation(rot*RADTODEG);
 
You are unique - just like everyone else.
blAaarg
Posts: 94
Joined: Tue Mar 02, 2010 9:11 pm
Location: SoCal

Re: Basic Quaternion help

Post by blAaarg »

I made the same mistake as you did in your first post when I first started playing with quaternions. The quaternion constructor that takes four floats is for math whizzes who want a very efficient way of creating/managing the internals of a quaternion object by hand, and really understand them from the inside-out. It doesn't work at all like the fromAngleAxis() method which is actually very intuitive but requires that you normalize the axis vector first! So...

Code: Select all

quaternion qRot;
qRot.fromAngleAxis(roll*DEGTORAD,vector3df(1,1,1));    // vector3df(1,1,1) is not a "unit vector"
qRot.toEuler(rot);
node->setRotation(rot*RADTODEG);
should call normalize on the second parameter for line 2. Otherwise, as I've seen it, the "axis" of the quaternion wobbles wildly. Your method shown most recently is using unit vector axes so it works but the multiple instances of multiplication of all those quats could be avoided by setting it properly in the first place. :)
"Computers don't make mistakes! What they do they do on purpose!!"

-Dale Gribble
MisterRose
Posts: 18
Joined: Thu Jun 16, 2011 2:46 pm

Re: Basic Quaternion help

Post by MisterRose »

Thank you for that! I had overlooked that when I was coding things up.

So what I need to do now is to rotate the mesh to point along the axis and then roll about it.
You are unique - just like everyone else.
Post Reply