Hi, I'm attempting to implement a first person, mouse-controlled camera for variable orientation situations. This means basically I need a regular mouse look camera to behave normally with any "up" vector. This will be used for moving around the entire surface of a spherical planet. So as you walk along, the view direction stays the same relative to the ground, so the view doesn't stay fixed on one point as you change gravity vectors. Pretty basic right?
Just try to work with matrixes and vectors. In your case the up vector is just the normalized vector from the planet center to the camera. Use this up vector for your yaw-rotation (x mouse motion) and the camera right-axis for the pitch-rotation (y mouse motion). Some pseudo code
mat44 cameraMatrix = ... ; //take from last frame vec3 worldUpVector = normalize(positionVector -planetCenterVector ); vec3 rightVector = getRightVectorFromMatrix(cameraMatrix); // create rotation matrix mat44 pitchMatrix = createRotationMatrix( rightVector , mouse_motion_y * y_factor); // use local right vector here mat44 yawMatrix = createRotationMatrix( worldUpVector , mouse_motion_x * x_factor); // use world vector here // apply rotations mat44 newCameraMatrix = cameraMatrix * yawMatrix * pitchMatrix ;
This should work as long as the lookat(aka forward) vector of the camera do not point along the current world up vector.
If you fear numerical instabilities and prefer pitch/yaw angles try something like this:
m_yaw += mouse_motion_x * x_factor; m_pitch += mouse_motion_y * y_factor; vec3 worldUpVector = normalize(positionVector -planetCenterVector ); vec3 rightVector = vec3(1,0,0); vec3 position = getPositionVectorFromMatrix(cameraMatrix); // create rotation matrix mat44 pitchMatrix = createRotationMatrix( rightVector , m_pitch); mat44 yawMatrix = createRotationMatrix( worldUpVector , m_yaw ); mat44 positionMatrix = createPositionMatrix(position); // apply rotations mat44 newCameraMatrix = positionMatrix * yawMatrix * pitchMatrix ;