/// Makes the camera look at a certain point. /** This function makes the camera look at a certain point. If that point is the same as its * current position, the camera moves back the (current) distance |camera-target|. * * \param in_vTgt The position where the camera should look at. * * \return If successfull: ERR_OK * \return If failed: An error code < 0 * * \author Pompei2 */ CFTSCamera *CFTSCamera::lookAt(const CFTSVector & in_vTgt) { // Calculate the new front vector that points to the target. CFTSVector vNewFront = (in_vTgt - m_vPos).normalize(); // The two vectors are in one plane. This gives us the cosine of the angle between // these two vectors. float fDotProd = vNewFront.dot(m_vFront); if(fDotProd > 1.0f || fDotProd < -1.0f) return this; // By getting the arc cosine of this, we get the angle in radians between the two // vectors. But we only get an angle between 0 and pi, that will be a problem. float fAlpha = acosf(fDotProd); // Here we get the normal to these two vectors, we will need to rotate our front // vector around this normal. CFTSVector vNormal = vNewFront.cross(m_vFront).normalize(); // As I said, we have a problem: as we only get an angle between 0 and pi, // we don't know if we need to rotate clockwise or counterclockwise ... // We solve this problem by just trying it out. CFTSVector vFrontTest = m_vFront.rotate(vNormal, fAlpha); // If the dot product is near to one, it means we were right. with our guess // rotating counterclockwise. // Else, we must rotate clockwise. fDotProd = vFrontTest.dot(vNewFront); if(fabs(fDotProd) > (1.0f - D_FTS_DELTA)) { m_vFront = vFrontTest; m_vUp = m_vUp.rotate(vNormal, fAlpha); m_vRight = m_vRight.rotate(vNormal, fAlpha); } else { m_vFront = m_vFront.rotate(vNormal, -fAlpha); m_vUp = m_vUp.rotate(vNormal, -fAlpha); m_vRight = m_vRight.rotate(vNormal, -fAlpha); } // If the dot product is near to -1, it means we look the wrong way. // To correct this, we just rotate pi radians (a half circle). if(fDotProd < -(1.0f - D_FTS_DELTA)) this->rotateYRadians(M_PI); return this; }
You need to create an account or log in to post comments to this site.