Forum Discussion

🚨 This forum is archived and read-only. To submit a forum post, please visit our new Developer Forum. 🚨
rupy's avatar
rupy
Honored Guest
12 years ago

Double Quaternion Problem [FIXED]

Hi, so I'm building this space flight game and I have a quaternion for the ship rotation, and one for the rift.

Everything works fine if I only modify one of these quaternions, but when I change both stuff get weird: basically the rift quaternion rotates from the world view, and I would like it to rotate from the ship view.

This is how I create my rift quaternion:


data = OculusRift.update();
rift = new Quaternion();

pitch.setFromAxisAngle(new Vector4f(1, 0, 0, -data[1]));
yaw.setFromAxisAngle(new Vector4f(0, 1, 0, data[2]));
roll.setFromAxisAngle(new Vector4f(0, 0, 1, -data[0]));

Quaternion.mul(rift, pitch, rift);
Quaternion.mul(rift, yaw, rift);
Quaternion.mul(rift, roll, rift);


How do I make the rift orientation start from the ships orientation?

I use gluLookAt (ship orientation) and then glMultMatrix (rift orientation).

------

Edit fixed:


pitch.setFromAxisAngle(new Vector4f(ship.right.x, ship.right.y, ship.right.z, data[1]));
yaw.setFromAxisAngle(new Vector4f(ship.up.x, ship.up.y, ship.up.z, data[2]));
roll.setFromAxisAngle(new Vector4f(ship.front.x, ship.front.y, ship.front.z, -data[0]));


Too bad the java JNI can't get the Quaternion directly instead of going through euler... would be great with an official JNI driver from oculus for win, mac and linux!

-----

Reopened: Now that I can get the quaternion from the Java JNI sensor API (thanks neph) (I'm astounded that Java API's where using euler until now, 6 months after release, talk about getting motion sick for nothing!) I have the problem that my ship quat and the rift quat are not oriented the same way therefore I can't multiply them correctly... actually the problem was simply getting all the data aligned (basically my ship and the rift quaternion are not oriented in the same way):


Quaternion q = new Quaternion();
Quaternion i = new Quaternion();

i.x = ship.result.x;
i.y = ship.result.y;
i.z = ship.result.z;
i.w = ship.result.w;

i.negate();

float[] xyzw = oculusvr.input.OculusRift.getOrientation();

q.x = -xyzw[0];
q.y = xyzw[1];
q.z = -xyzw[2];
q.w = xyzw[3];

Quaternion.mul(i, q, rift);


Then before rendering:


glRotatef(180, 1, 0, 0);
glRotatef(180, 0, 0, 1);

float[] matrix = new float[16];
Ship.matrix(matrix, rift); // Makes a matrix of the Quaternion
FloatBuffer buffer = BufferUtils.createFloatBuffer(16);
buffer.put(matrix);
buffer.position(0);

glMultMatrix(buffer);


These are the parts you should see:

q.x = -xyzw[0];
q.z = -xyzw[2];

glRotatef(180, 1, 0, 0);
glRotatef(180, 0, 0, 1);


Simple but hard to figure out any other way than trial and error.

Nothing fundamental learned except how quaternions work and that gluLookAt and Euler should not be used.

Actually Euler should be REMOVED for orientation in the API so no abuse leading to motion sickness due to that easily avoided problem can occur!
No RepliesBe the first to reply