I spent a couple of weeks on this problem and cannot find the right solution and I need some advice.
I am working on creating a Camera class using LWJGL / Java, and I use Quaternions to handle bearing rotation (rotation), rotation, and rotation. I would like this camera to handle all 6 degrees of movement in 3D space and roll. Bearings, Pitch and Roll are all quaternions. I multiply them by the quaternion “change” and create a translation matrix from it. I put this in a floating point buffer and multiplied the view matrix by my buffer containing the rotation matrix.
I can make the rotation of the bearing and the pitch work correctly, but when I do the throw, I have problems. Basically, rotating around the Z axis (rolling) does not seem to work. When I ever “roll” a camera, it seems to wrap around the global Z axis instead of the direction axis of the local camera. Usually I can get 2 out of 3 to work depending on the order of multiplication of the quaternions, but I can not get them to work together.
Since they all work independently, I assume that something is wrong with my orientation method, where I combine them and create a rotation matrix. I'm having trouble inserting the whole class, so here are the methods and declarations related to rotation:
private final static float DEGTORAD = (float)(Math.PI/180);
private Vector3f eye;
private Vector3f up;
private Vector3f right;
private Vector3f direction;
private float pitchAngle;
private float bearingAngle;
private float rollAngle;
private Quaternion pitch;
private Quaternion bearing;
private Quaternion roll;
private FloatBuffer viewMatrixBuffer = BufferUtils.createFloatBuffer(16);
private Quaternion currentOrientation;
...
public void bearing(float bearingDelta){
bearingAngle += bearingDelta;
if(bearingAngle > 360){
bearingAngle -= 360;
}else if(bearingAngle < 0){
bearingAngle += 360;
}
bearing.setFromAxisAngle(new Vector4f(0f, 1f, 0f, bearingAngle * DEGTORAD));
bearing.normalise();
}
public void pitch(float pitchDelta){
pitchAngle += pitchDelta;
if(pitchAngle > 360){
pitchAngle -= 360;
}else if(pitchAngle < 0){
pitchAngle += 360;
}
pitch.setFromAxisAngle(new Vector4f(1f, 0f, 0f, pitchAngle * DEGTORAD));
pitch.normalise();
}
public void roll(float initialRoll) {
rollAngle += initialRoll;
if(rollAngle > 360){
rollAngle -= 360;
}else if(rollAngle < 0){
rollAngle += 360;
}
roll.setFromAxisAngle(new Vector4f(0, 0, 1, rollAngle * DEGTORAD));
roll.normalise();
}
public void lookThrough(){
reorient();
GL11.glMultMatrix(viewMatrixBuffer);
}
public void reorient(){
Quaternion change = new Quaternion();
Quaternion.mul(bearing, pitch, change);
Quaternion.mul(roll, change, change);
Matrix4f rotationMatrix = getRotationMatrix(change);
direction.x = rotationMatrix.m20;
direction.y = rotationMatrix.m21;
direction.z = rotationMatrix.m22;
rotationMatrix.m30 = eye.x;
rotationMatrix.m31 = eye.y;
rotationMatrix.m32 = eye.z;
rotationMatrix.m33 = 1;
rotationMatrix.invert();
rotationMatrix.store(viewMatrixBuffer);
viewMatrixBuffer.rewind();
Vector3f.cross(new Vector3f(0,1,0), direction, null).normalise(right);
Vector3f.cross(right, direction, null).normalise(up);
}
Vector3f, Quaternion, and Matrix4f are all LWJGL classes, not custom ones.
, , 3 , Bearing, Pitch and Roll, ModelView, ?
EDIT: , . . Gist RiverC. , , . , .