bool CClientCamera::ProcessFixedCamera ( CCam* pCam ) { // The purpose of this handler function is changing the Source, Front and Up vectors in CCam // when called by GTA. This is called when we are in fixed camera mode. CClientCamera* pThis = g_pClientGame->GetManager ()->GetCamera (); // Make sure we actually want to apply our custom camera position/lookat // (this handler could also be called from cinematic mode) if ( !pThis->m_bFixed ) return false; const CVector& vecPosition = pThis->m_vecFixedPosition; const CVector& vecTarget = pThis->m_vecFixedTarget; // Set the position in the CCam interface *pCam->GetSource () = vecPosition; // Calculate the front vector, target - position. If its length is 0 we'll get problems // (i.e. if position and target are the same), so make a new vector then looking horizontally CVector vecFront = vecTarget - vecPosition; if ( vecFront.Length () < FLOAT_EPSILON ) vecFront = CVector ( 0.0, 1.0f, 0.0f ); else vecFront.Normalize (); *pCam->GetFront () = vecFront; // Grab the right vector CVector vecRight = CVector ( vecFront.fY, -vecFront.fX, 0 ); if ( vecRight.Length () < FLOAT_EPSILON ) vecRight = CVector ( 1.0f, 0.0f, 0.0f ); else vecRight.Normalize (); // Calculate the up vector from this CVector vecUp = vecRight; vecUp.CrossProduct ( &vecFront ); vecUp.Normalize (); // Apply roll if needed if ( pThis->m_fRoll != 0.0f ) { float fRoll = ConvertDegreesToRadiansNoWrap ( pThis->m_fRoll ); vecUp = vecUp*cos(fRoll) - vecRight*sin(fRoll); } *pCam->GetUp () = vecUp; // Set the zoom pCam->SetFOV ( pThis->m_fFOV ); return true; }
void CClientCamera::SetFixedTarget ( const CVector& vecPosition, float fRoll ) { // Switch to fixed mode if required if ( !IsInFixedMode () ) ToggleCameraFixedMode ( true ); // Store the target so it can be updated from our hook m_vecFixedTarget = vecPosition; m_fRoll = fRoll; m_FixedCameraMode = EFixedCameraMode::TARGET; // Update fixed matrix // Calculate the front vector, target - position. If its length is 0 we'll get problems // (i.e. if position and target are the same), so make a new vector then looking horizontally CVector vecFront = m_vecFixedTarget - m_matFixedMatrix.vPos; if ( vecFront.Length () < FLOAT_EPSILON ) vecFront = CVector ( 0.0, 1.0f, 0.0f ); else vecFront.Normalize (); // Grab the right vector CVector vecRight = CVector ( vecFront.fY, -vecFront.fX, 0 ); if ( vecRight.Length () < FLOAT_EPSILON ) vecRight = CVector ( 1.0f, 0.0f, 0.0f ); else vecRight.Normalize (); // Calculate the up vector from this CVector vecUp = vecRight; vecUp.CrossProduct ( &vecFront ); vecUp.Normalize (); // Apply roll if needed if ( m_fRoll != 0.0f ) { float fRoll = ConvertDegreesToRadiansNoWrap ( m_fRoll ); vecUp = vecUp*cos(fRoll) - vecRight*sin(fRoll); } // Set rotational part of fixed matrix m_matFixedMatrix.vFront = vecFront; m_matFixedMatrix.vUp = vecUp; m_matFixedMatrix.OrthoNormalize( CMatrix::AXIS_FRONT, CMatrix::AXIS_UP ); }
int CLuaMatrixDefs::Create(lua_State* luaVM) { CMatrix matrix; CScriptArgReader argStream(luaVM); if (argStream.NextIsVector3D()) { CVector vecPosition; argStream.ReadVector3D(vecPosition); if (argStream.NextIsVector3D()) { CVector vecRotation; argStream.ReadVector3D(vecRotation); ConvertDegreesToRadiansNoWrap(vecRotation); matrix = CMatrix(vecPosition, vecRotation); } else { matrix = CMatrix(vecPosition); } } else if (argStream.NextIsUserDataOfType<CLuaMatrix>()) { argStream.ReadMatrix(matrix); matrix = CMatrix(matrix); } else if (!argStream.NextIsNone()) { argStream.SetCustomError("Expected vector3, matrix or nothing"); m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); lua_pushboolean(luaVM, false); return 1; } lua_pushmatrix(luaVM, matrix); return 1; }