Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


[Solved] JBullet quaternion angles to pitch/yaw/roll


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 nerdboy64   Members   -  Reputation: 567

Like
0Likes
Like

Posted 24 July 2014 - 01:51 AM

Recently I posted a blog about my first foray into 3D game development using LWJGL. Since then, I've worked on adding simple physics to the game using JBullet (a Java port of the Bullet physics library for C++). However, I've been having difficulty with the angular measurement system it uses. It seems to use quaternion rotation, with which I am quite unfamiliar. Actually, that's a bit of an understatement -- I hadn't even heard of quaternion rotation until a few hours ago. This is especially problematic when it comes to rendering the object, as to render stuff in LWJGL I need to pass vectors in pitch/yaw/roll format. The Javadoc doesn't include any information on the subject, and while there seems to be no shortage of forum threads with similar questions, none of the code they use has actually worked for me. Does anyone know how to convert from JBullet's quaternion-based rotation system to the pitch/yaw/roll one usable in LWJGL?


My website: Brass Watch Games

Come check out Shipyard, my first real game project (Very WIP): Game Website Development Journal

Shipyard is a 2D turn-based strategy with a sci-fi theme, in which you build ships from individual parts rather than being given a selection of predefined models.


Sponsor:

#2 r-e-v-e-r-s   Members   -  Reputation: 187

Like
0Likes
Like

Posted 24 July 2014 - 04:50 AM

For conversion from quaternion to Euler angles you can use my implementation of quaternion :

public class Quat {
public float x, y, z, w;


public Quat() {
// x = y = z = 0.0f;
w = 1.0f;
}


public Quat(float x, float y, float z, float w) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}


public float pitch() {
return (float) Math.atan2(2.0 * (y * z + w * x), w * w - x * x - y * y
+ z * z);
}


public float yaw() {
return (float) Math.asin(-2.0 * (x * z - w * y));
}


public float roll() {
return (float) Math.atan2(2.0 * (x * y + w * z), w * w + x * x - y * y
- z * z);
}
// [...]
}

The returned angles are in radians. 



#3 nerdboy64   Members   -  Reputation: 567

Like
0Likes
Like

Posted 24 July 2014 - 01:11 PM

That's worked better than anything I've found previously, but I'm still getting a weird glitch with the yaw where every time I hit 90 degrees (LWJGL uses degrees, so I had to convert the angles) on the yaw, it appears to have its yaw instantly flipped. However, when I told the system to print the angle values, I discovered that it was actually the pitch and roll that were flipped, while the yaw value remained officially 90 degrees. Do you know how to fix this?
 
Here's my quat-to-Euler code. Since JBullet has its own quaternion class, I made this one as a "helper" class with static methods that take the quaternion as an argument.

import javax.vecmath.Quat4f;

public class QuatHelper {
	public static float getPitch(Quat4f q){
		return (float)(Math.atan2(2.0 * (q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z));
	}
	
	public static float getYaw(Quat4f q){
		return (float)(Math.asin(-2.0 * (q.x * q.z - q.w * q.y)));
	}

	public static float getRoll(Quat4f q){
		return (float)(Math.atan2(2.0 * (q.x * q.y + q.w * q.z), q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z));
	}
}

 
Here's my rendering code:
public void render(Transform transform){
				
     GL11.glPushMatrix();

     Vector3f position = new Vector3f(transform.origin.x, transform.origin.y, transform.origin.z);
     GL11.glTranslatef(position.x, position.y, position.z);

     //Get the Quaternion angles from JBullet
     Quat4f a = new Quat4f();
     transform.getRotation(a);
     //Get Euler angles from class above
     Vector3f v = new Vector3f(QuatHelper.getPitch(a), QuatHelper.getYaw(a), QuatHelper.getRoll(a));

     //Print pitch, yaw, roll so I can see what's going on
     System.out.println((float)Math.toDegrees(v.x) + " | " + (float)Math.toDegrees(v.y) + " | " + (float)Math.toDegrees(v.z));
     //My rendering method. Arguments are X, Y, Z, Pitch, Yaw, Roll; Yaw value is applied before pitch and roll
     hull.render(position.x, position.y, position.z, (float)Math.toDegrees(v.x), (float)Math.toDegrees(v.y), (float)Math.toDegrees(v.z));
     GL11.glPopMatrix();
}

Edited by nerdboy64, 24 July 2014 - 03:10 PM.

My website: Brass Watch Games

Come check out Shipyard, my first real game project (Very WIP): Game Website Development Journal

Shipyard is a 2D turn-based strategy with a sci-fi theme, in which you build ships from individual parts rather than being given a selection of predefined models.


#4 nerdboy64   Members   -  Reputation: 567

Like
0Likes
Like

Posted 24 July 2014 - 07:02 PM

I can't say I figured out the problem exactly, but it turned out to be related to my rendering method and not your quaternion conversions. I couldn't fix it exactly, but I found another formula to convert to an axis-angle representation that worked more natively in LWJGL. So, problem solved... I guess.


My website: Brass Watch Games

Come check out Shipyard, my first real game project (Very WIP): Game Website Development Journal

Shipyard is a 2D turn-based strategy with a sci-fi theme, in which you build ships from individual parts rather than being given a selection of predefined models.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS