In my recent project I'm trying to rotate a camera on the up axis to face another object.
I have a rotate to that works on an arbitrary axis but I don't have one that maintains that yaw is always left/right. Gimbal lock does not matter here since this is not a first person camera for a space game or anything.
My idea was this:
Code:
void Camera::RotateTo(const D3DXVECTOR3 &target)
{
D3DXVECTOR3 toTarget = target - m_vecPos;
D3DXVec3Normalize(&toTarget,&toTarget);
D3DXVECTOR3 toTargetLevelY(toTarget.x,m_vecPos.y,m_toTarget.z);
D3DXVec3Normalize(&toTargetLevelY,&toTargetLevelY);
float yaw_angle = acosf(D3DXVec3Dot(&toTargetLevelY,&m_vecLook));
float pitch_angle = acosf(D3DXVec3Dot(&toTargetLevelY,&toTarget));
...
...
}
The problem is that yaw_angle and pitch_angle are not negative/positive depending on if the object is left/right or above/below the camera.
Other approaches I've tried:
- Create a look at matrix and multiply camera vectors by this matrix and store result in target vectors
- Interpolate from current camera vectors to those that were computed in the previous step
- Create an infinite plane along the look vector and an infinite plane along the y axis.
- Do a plane dot coord to determine what half space the targeted object is in which would then tell me left/right up/down and then use the angles I computed from my posted code to rotate
EDIT:
I figured it out. I'm already composing the view matrix from 3 vectors. I use that information to extract the vectors from a matrix. A simple look at, set the target look vector to the right elements of the resulting matrix and then recompute the new target vectors from the look vector. In the update I do a LERP from the current vectors to the target vectors that were just computed.