Original Post
Hello, I'm trying to implement the Quaternion based camera presented here, but I am not getting the results I'd expect. I've read the top few links on Google about quaternions, but that's about as far as my understanding goes. What happens is I load up the scene, move my mouse, and nothing happens. I checked my view vector throughout the program and all I'm gettings are some very small numbers for the components. here's a copy of what I believe to be all of the relevant source code. and here is the quaternion multiplication Not the best code I've written (obviously, since it doesn't work :) ), but hopefully you guys should be able to see what I'm doing wrong. Thanks for your help. EDIT: if it matters, mouseSensivity is 2.0f; Thanks
void Camera::mouseMove()
{
POINT mousePos;
int middleX = screenWidth >> 1; // divide the width by two
int middleY = screenWidth >> 1; // divide the height by two
float angleX = 0.0f; // This is the direction for looking up or down
float angleY = 0.0f; // This will be the value we need to rotate around the Y axis (Left and Right)
// Get the mouse's current X,Y position
GetCursorPos(&mousePos);
// curser didn't move, quit wasting my time!
if( (mousePos.x == middleX) && (mousePos.y == middleY) )
return;
// move the mouse back to the center of the screen
SetCursorPos(middleX, middleY);
angleX = (float)( (middleX - mousePos.x) ) / mouseSensivity;
angleY = (float)( (middleY - mousePos.y) ) / mouseSensivity;
Vector axis = Vector::cross(Vector(c_view.getX() - c_position.getX(),
c_view.getY() - c_position.getY(),
c_view.getZ() - c_position.getZ()), c_up);
axis = Vector::normalize(axis);
// Rotate around the y axis
rotateCamera(angleY, axis.getX(), axis.getY(), axis.getZ());
// Rotate around the x axis
rotateCamera(angleX, 0, 1, 0);
updateCamera();
}
void Camera::rotateCamera(float theta, float x, float y, float z)
{
Quaternion temp;
Quaternion qview;
Quaternion final;
float sintheta = sin(theta / 2);
temp.setX(x * sintheta);
temp.setY(y * sintheta);
temp.setZ(z * sintheta);
temp.setW( cos(theta/2));
qview.setX(c_view.getX());
qview.setY(c_view.getY());
qview.setZ(c_view.getZ());
qview.setW(0);
final = Quaternion::multiply(Quaternion::multiply(temp, qview), Quaternion::conjugate(temp));
c_view.setX(final.getX());
c_view.setY(final.getY());
c_view.setZ(final.getZ());
}
void Camera::updateCamera()
{
gluLookAt(c_position.getX(), c_position.getY(), c_position.getZ(),
c_view.getX() , c_view.getY() , c_view.getZ(),
c_up.getX() , c_up.getY() , c_up.getZ());
}
Quaternion Quaternion::normalize(Quaternion quat)
{
float length = sqrt( (quat.getX() * quat.getX()) + (quat.getY() * quat.getY())
+ (quat.getZ() * quat.getZ()) + (quat.getW() * quat.getW()) );
quat.setX(quat.getX() / length);
quat.setY(quat.getY() / length);
quat.setZ(quat.getZ() / length);
quat.setW(quat.getW() / length);
return quat;
}
Quaternion Quaternion::conjugate(Quaternion quat)
{
quat.setX( -quat.getX() );
quat.setY( -quat.getY() );
quat.setZ( -quat.getZ() );
return quat;
}
Quaternion Quaternion::multiply(Quaternion one, Quaternion two)
{
Quaternion three = Quaternion();
three.setX(one.getW() * two.getX() +
one.getX() * two.getW() +
one.getY() * two.getZ() -
one.getZ() * two.getY());
three.setY(one.getW() * two.getY() -
one.getX() * two.getZ() +
one.getY() * two.getW() +
one.getZ() * two.getX());
three.setZ(one.getW() * two.getZ() +
one.getX() * two.getY() -
one.getY() * two.getX() +
one.getZ() * two.getW());
three.setW(one.getW() * two.getW() -
one.getX() * two.getX() -
one.getY() * two.getY() -
one.getZ() * two.getZ());
return three;
}