Advertisement

[Rotating a cube using quaternion with respect to a fixed frame]

Started by May 18, 2022 02:14 PM
2 comments, last by ogldev1 2 years, 6 months ago

Hello guys,

I hope you're all doing well.

So I created an application on Qt6 that rotates a cube using quaternions. The rotation is achieved with respect to the OpenGL standard coordinate system.

As I know, the OpenGL standard coordinate system is represented in the picture below:

I added a fixed coordinate system to my scene (like the one shown in picture above). So when I insert the quaternion values as follows: w=0.7, x=0.7, y=0.0, z=0.0, the cube rotates around the x axis of the standard coordinate system.

Then I had to change the orientation of that coordinate system's axes as shown in the picture below where:

x is the Magenta axis

y is the White axis

z is the Yellow axis

and my goal is to rotate the cube using quaternion but this time around the new fixed coordinate system, I didn't know how to proceed but this is what I've done so far.

In my paintGL() function, I started by drawing the fixed coordinate system and changing its axes orientation using rotate:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//================Orbital Frame ==========================================//

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(2.0,2.0,0.0, 0.0,0.0,-5.0,0.0,1.0,0.0);

glTranslatef(0.0,0.0,-5.0);

glRotatef(180.0,0.0,1.0,0.0);

glRotatef(-90.0,1.0,0.0,0.0);

glScalef(0.4,0.4,0.4);

glMatrixMode(GL_PROJECTION);

DrawOrbitalFrame();

Then, in my program, I have shader programs (Vertex and Fragment shader programs) that I used to draw a textured cube:

program.bind();

texture->bind();

// Calculate model view transformation

QMatrix4x4 localMatrix;

//QMatrix4x4 identity;

localMatrix.lookAt(QVector3D(2.0, 2.0, 0.0), QVector3D(0.0,0.0,-5.0),QVector3D(0.0,1.0,0.0));

localMatrix.translate(0.0, 0.0, -5.0);

localMatrix.scale(0.4,0.4,0.4);

quaternion = QQuaternion(quat_w, quat_x, quat_y, quat_z);

quaternion.normalize(); // Normalizing my quaternion

localMatrix.rotate(quaternion); // the quaternion in here corresponds to the one that can be manually inserted in the spin boxes in the ui

quaternion=csvquaternion;

localMatrix.rotate(quaternion); // the quaternion in here correponds to the one extracted from a QList

program.setUniformValue("mvp_matrix", projection * localMatrix);

update();

// Use texture unit 0 which contains cube.png

program.setUniformValue("texture", 0);

// Draw cube geometry

geometries->drawCubeGeometry(&program);

texture->release();

program.release();

The rotation is achieved using the rotate function but the object is rotating around the axes of the standard coordinate system and not the new one.

Can someone please tell me what can I do to make it rotate around the new fixed coordinate system or give a little tip on how to achieve that ?

Thank you all.

Advertisement

If you have the vectors that correspond to your new coordinate system, as seen from the global coordinate system, then you should I think be able to construct one or more quaternions using those vectors as the quaternion-axes. (Using the relevant methods in the QQuaternion API.) That should then allow you to rotate around those axes.

MWAHAHAHAHAHAHA!!!

My Twitter Account: @EbornIan

Some potential sources of confusion i see:

To set up your camera and model space, you mix (deprecated?) legacy methods (glRotate, glTranslate) with the now preferred (but sometimes more cumbersome) method of calculating MVP matrix yourself and giving it to shader uniforms.
Doing the latter probably disables anything you did with the former.
On the long run it's easier to work on some camera and viewport functionality, and using that to have a consistent setup of those things. So both your models / assets and your coordinate space axis or gizmo visualizations all use the same system.

Another topic often causing me confusion about rotations is multiplication order.
For example, to do a rotation in local space i write: objectOrientation = objectOrientation * localObjectRotation. To do the orientation in world space, i write:objectOrientation = globalObjectRotation * objectOrientation.
This is the same for quaternions and matrices, but conventions across math libs vary, and it is not clear to me from reading your code which of the two options actually happen and what's intended.

Guys, hello again,

@thaumaturge @joej Thank you for your quick replies.

I tried something, it seems to work.

I created the fixed coordinate system and applied some transformations on it ( I changed the axes orientation)

Then before drawing the object ( the cube); I applied the same transformations. Now the object is rotating around the new axes of the fixed coordinate system.

Okay, I'm using the deprecated methods because I'm still trying to get familiar with shaders and how to use them. they're really really complicated.

This topic is closed to new replies.

Advertisement