#include "stdafx.h" #include "acp_base.h" #include "ITF.h" #include "caminter.hpp" #include "camresrc.h" #include "camera.hpp" #include "propert.hpp" #include "geo.h" #include "compprop.hpp" #define M_GetDLL() ((Camera_Interface*)GetEditor()) #define C_PI (float)3.14159265 /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////// Camera ///////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// DeclareTemplateStatic(GLI_tdxHandleToCamera); //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** // FBFFBF the del function is temporary (waiting for a camera engine del function) void del(GLI_tdxHandleToCamera h) { } //fin FBFFBF //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::StaticInit() { // FBFFBF the del function is temporary (waiting for a camera engine del function) CPA_EdMot::Init(NULL,GLI_vCopyCamera,del); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** // construct an editor camera from a given camera engine structure Camera::Camera(tdeCameraType eType, CPA_ObjectDLLBase *p_oDLL, CPA_MainWorld* p_oMainWorld,GLI_tdxHandleToCamera hObj, CString csName, CString csFileName, CString csSectionName ) :CPA_BaseObject (p_oDLL , C_szCameraObjectTypeName) , CPA_EdMot(hObj) { m_eCameraType = eType; // name SetDefaultUniqueName(); // axis systems m_eRotationAxisSystem = CameraCoordinates; m_eTranslationAxisSystem = CameraCoordinates; //types m_eTargetType = tNone; m_eRotationCenterType = rTarget; //= Camera here // rotation center MTH3D_M_vNullVector(&m_stRotationCenterPoint); m_eRotationCenterPointCoordsType = Absolute; m_p_oRotationCenterSuperObject = NULL; //target point MTH3D_M_vNullVector(&m_stTargetPoint); m_p_oTargetSuperObject = NULL; //don't touch given engine camera // device, viewport m_bActive = FALSE; m_p_oViewPort = NULL; // others m_p_oActor = NULL; m_p_oActorSO = NULL; m_dTwistAngle = 0.0; m_lTwistRemoveCount = 0; m_bPrivilegeMode = TRUE; m_oDialogBar.InitInertCameraDialogBar(this); POS_fn_vSetIdentityMatrix(&m_stCameraMatrix); UpdateFromEngine(); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** // construct an editor camera, create the corresponding engine camera Camera::Camera(tdeCameraType eType, CPA_ObjectDLLBase *p_oDLL, CPA_MainWorld* p_oMainWorld, CString csName, CString csFileName, CString csSectionName ) :CPA_BaseObject (p_oDLL , C_szCameraObjectTypeName) , CPA_EdMot( (GLI_tdxHandleToCamera) NULL ) { GLI_tdxHandleToCamera hCamera; m_eCameraType = eType; POS_fn_vSetIdentityMatrix(&m_stCameraMatrix); // name SetDefaultUniqueName(); // axis systems m_eRotationAxisSystem = CameraCoordinates; m_eTranslationAxisSystem = CameraCoordinates; //types m_eTargetType = tNone; m_eRotationCenterType = rTarget; //= Camera here // rotation center MTH3D_M_vNullVector(&m_stRotationCenterPoint); m_eRotationCenterPointCoordsType = Absolute; m_p_oRotationCenterSuperObject = NULL; //target point MTH3D_M_vNullVector(&m_stTargetPoint); m_p_oTargetSuperObject = NULL; //engine camera GLI_xCreateCamera(&hCamera, GLI_C_lPersCamWithoutDistorsion); SetStruct(hCamera); // camera_matrix: ResetCamera(); // device, viewport m_bActive = FALSE; m_p_oViewPort = NULL; // others m_p_oActor = NULL; m_p_oActorSO = NULL; m_dTwistAngle = 0.0; m_lTwistRemoveCount = 0; m_bPrivilegeMode = TRUE; m_oDialogBar.InitInertCameraDialogBar(this); Update(); m_oDialogBar.SetCamera(this); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** Camera::Camera(Camera &src) : CPA_BaseObject(src), CPA_EdMot( (GLI_tdxHandleToCamera) NULL ), m_oDialogBar(src.m_oDialogBar) { GLI_tdxHandleToCamera hCamera; // name SetDefaultUniqueName(); POS_fn_vSetIdentityMatrix(&m_stCameraMatrix); m_eCameraType = src.m_eCameraType; m_eRotationAxisSystem = m_eRotationAxisSystem; m_eTranslationAxisSystem = src.m_eTranslationAxisSystem; // m_eRotationCenterType = src.m_eRotationCenterType; m_eRotationCenterType = rTarget; // m_eTargetType = src.m_eTargetType; m_eTargetType = tNone; MTH3D_M_vCopyVector(&m_stRotationCenterPoint, &src.m_stRotationCenterPoint); m_eRotationCenterPointCoordsType = src.m_eRotationCenterPointCoordsType; // m_p_oRotationCenterSuperObject = src.m_p_oRotationCenterSuperObject; m_p_oRotationCenterSuperObject = NULL; MTH3D_M_vCopyVector(&m_stTargetPoint,&src.m_stTargetPoint); // m_p_oTargetSuperObject = src.m_p_oTargetSuperObject; m_p_oTargetSuperObject = NULL; GEO_M_vCopyMatrix(&m_stCameraMatrix,&src.m_stCameraMatrix); m_bActive = FALSE; GLI_xCreateCamera(&hCamera, GLI_C_lPersCamWithoutDistorsion); GLI_vCopyCamera(hCamera,src.GetStruct()); SetStruct(hCamera); m_p_oViewPort = NULL; m_p_oActor = src.m_p_oActor; m_p_oActorSO = src.m_p_oActorSO; m_dTwistAngle = src.m_dTwistAngle; m_lTwistRemoveCount = 0; m_bPrivilegeMode = src.m_bPrivilegeMode; m_oDialogBar.SetCamera(this); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** Camera::~Camera() { } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** /*void Camera::ReInit(GLI_tdxHandleToCamera hCamera) { // axis systems m_eRotationAxisSystem = CameraCoordinates; m_eTranslationAxisSystem = CameraCoordinates; //types m_eTargetType = tNone; m_eRotationCenterType = rTarget; //= Camera here // rotation center MTH3D_M_vNullVector(&m_stRotationCenterPoint); m_eRotationCenterPointCoordsType = Absolute; m_p_oRotationCenterSuperObject = NULL; //target point MTH3D_M_vNullVector(&m_stTargetPoint); m_p_oTargetSuperObject = NULL; //engine camera GLI_vCopyCamera(GetStruct(),hCamera); // device, viewport m_bActive = FALSE; m_p_oViewPort = NULL; // others m_p_oActor = NULL; m_p_oActorSO = NULL; m_p_oToolBarParentWnd = NULL; m_oDialogBar.ReInit; UpdateFromEngine(); } */ /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::CompletePreferences() { HINSTANCE hOldInst; CompleteProperties *p_oProperties; // save dll resource handle hOldInst = AfxGetResourceHandle(); AfxSetResourceHandle( ((CPA_DLLBase*)(GetEditor()))->GetDLLIdentity()->hModule ); p_oProperties = new CompleteProperties(this); if (p_oProperties->DoModal() == IDOK) { GetMainWorld()->GetInterface()->fn_vUpdateAll(E_mc_JustDraw); } delete p_oProperties; AfxSetResourceHandle( hOldInst ); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::Preferences() { HINSTANCE hOldInst; Properties *p_oProperties; // save dll resource handle hOldInst = AfxGetResourceHandle(); AfxSetResourceHandle( ((CPA_DLLBase*)(GetEditor()))->GetDLLIdentity()->hModule ); p_oProperties = new Properties(this); if (p_oProperties->DoModal() == IDOK) { p_oProperties->DoUpdate(); if (p_oProperties->WantToOpenCompleteProperties()) CompletePreferences(); else GetMainWorld()->GetInterface()->fn_vUpdateAll(E_mc_JustDraw); } delete p_oProperties; AfxSetResourceHandle( hOldInst ); } void Camera::FrontView() { SetRotation(0,0,0); } void Camera::BackView() { SetRotation(0,0,C_PI); } void Camera::LeftView() { SetRotation(0,0,-C_PI/2); } void Camera::RightView() { SetRotation(0,0,C_PI/2); } void Camera::TopView() { SetRotation(-C_PI/2,0,0); } void Camera::BottomView() { SetRotation(C_PI/2,0,0); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::Activate(DEV_ViewPort3D *p_oViewPort, CPA_DialogBar *p_oPopUpParent, CPoint oPos) { m_p_oViewPort = p_oViewPort; GLI_xSetViewportCamera(m_p_oViewPort->m_hDisplayDevice,m_p_oViewPort->m_hDisplayViewport,GetStruct()); m_bActive = TRUE; Update(); m_oDialogBar.Create(p_oPopUpParent,oPos); // if the viewport has the focus, then show the new toolbar if (m_p_oViewPort->GetFocus() == m_p_oViewPort) m_oDialogBar.Show(); else m_oDialogBar.Hide(); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::Disactivate() { if (m_bActive) { m_oDialogBar.Destroy(); m_p_oViewPort = NULL; m_bActive = FALSE; // Update(); } } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::SetRotationAxisSystem(tdeAxisSystem eSystem) { if (m_bPrivilegeMode && eSystem != CameraCoordinates) return; m_eRotationAxisSystem = eSystem; } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::SetTranslationAxisSystem(tdeAxisSystem eSystem) { if (m_bPrivilegeMode && eSystem != CameraCoordinates) return; m_eTranslationAxisSystem = eSystem; } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** tdeAxisSystem Camera::GetRotationAxisSystem() { return m_eRotationAxisSystem; } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::GetMatrix(POS_tdstCompletePosition *p_stMatrix) { GEO_M_vCopyMatrix(p_stMatrix,&m_stCameraMatrix); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::SetMatrix(POS_tdstCompletePosition *p_stMatrix) { GEO_M_vCopyMatrix(&m_stCameraMatrix,p_stMatrix); Update(); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** tdeAxisSystem Camera::GetTranslationAxisSystem() { return m_eTranslationAxisSystem; } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** BOOL Camera::SetRotationCenterType(tdeRotationCenterType eRotCenterType) { // if given type is superobject and superobject is null, bad!!! if ( (eRotCenterType == rSuperObject) && (m_p_oRotationCenterSuperObject == NULL) ) return FALSE; // if rotcenter is the target if (eRotCenterType == rTarget) { // look what is the traget switch (m_eTargetType) { // a point, ok! case tPoint: m_eRotationCenterType = rTarget; return TRUE; break; // a superobject, ok if so is not NULL case tSuperObject: if (m_p_oTargetSuperObject == NULL) return FALSE; else { m_eRotationCenterType = rTarget; return TRUE; } break; // nothing, ok! case tNone: m_eRotationCenterType = rTarget; return TRUE; } return FALSE; } else { m_eRotationCenterType = eRotCenterType; return TRUE; } } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** tdeRotationCenterType Camera::GetRotationCenterType() { return m_eRotationCenterType; } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** BOOL Camera::SetTargetType(tdeTargetType eTargetType) { CPA_PopUpToolBar *p_oToolBar; if ( (eTargetType == tSuperObject) && (m_p_oTargetSuperObject == NULL) ) return FALSE; if ((p_oToolBar = m_oDialogBar.GetToolBar()) != NULL) { if (m_eTargetType != eTargetType) { switch(eTargetType) { case tNone: p_oToolBar->SetButton(ID_NOTTARGETED); break; case tSuperObject: p_oToolBar->SetButton(ID_SOTARGETED); break; case tPoint: p_oToolBar->SetButton(ID_POINTTARGETED); break; } } p_oToolBar->UpdateWindow(); } m_eTargetType = eTargetType; return TRUE; } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** tdeTargetType Camera::GetTargetType() { return m_eTargetType; } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::SetRotationCenterPoint(CPA_CameraCoords *p_oRotationCenter, tdeCoordsType eType) { //copy coords in the class p_oRotationCenter->GetCoords(m_stRotationCenterPoint); switch (eType) { case Absolute: // the point is absolute, so in world coordinates if (p_oRotationCenter->GetAxisSystem() == CameraCoordinates) CameraToWorldCoordinates_Point(m_stRotationCenterPoint); break; case Relative: // the point is relative, so in camera coordinates if (p_oRotationCenter->GetAxisSystem() == WorldCoordinates) WorldToCameraCoordinates_Point(m_stRotationCenterPoint); break; } m_eRotationCenterPointCoordsType = eType; } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** BOOL Camera::SetRotationCenterSuperObject(CPA_SuperObject *p_oSuperObject) { if (m_eRotationCenterType == rSuperObject && p_oSuperObject == NULL) return FALSE; m_p_oRotationCenterSuperObject = p_oSuperObject; return TRUE; } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::SetTargetPoint(CPA_CameraCoords *p_oTargetPoint) { // copy coords in the class p_oTargetPoint->GetCoords(m_stTargetPoint); // the point is always in world coordinates if (p_oTargetPoint->GetAxisSystem() == CameraCoordinates) CameraToWorldCoordinates_Point(m_stTargetPoint); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::GetTargetPoint(MTH3D_tdstVector &r_stPoint) { MTH3D_M_vCopyVector(&r_stPoint,&m_stTargetPoint); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** // result is always in world coordinates void Camera::GetRotationCenterPoint(MTH3D_tdstVector &r_stPoint, tdeCoordsType &r_eType) { // copy values r_eType = m_eRotationCenterPointCoordsType; MTH3D_M_vCopyVector(&r_stPoint,&m_stRotationCenterPoint); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** BOOL Camera::SetTargetSuperObject(CPA_SuperObject *p_oSuperObject) { CPA_PopUpToolBar *p_oToolBar; if (m_eTargetType == tSuperObject && p_oSuperObject == NULL) return FALSE; m_p_oTargetSuperObject = p_oSuperObject; if ((p_oToolBar = m_oDialogBar.GetToolBar()) != NULL) { if (m_p_oTargetSuperObject != NULL) { p_oToolBar->SetPermission(ID_SOTARGETED,TRUE); } else { p_oToolBar->SetPermission(ID_SOTARGETED,FALSE); p_oToolBar->UpdateWindow(); } } return TRUE; } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** // returns the effective (valid) target type tdeRotationCenterType Camera::GetEffectiveRotationCenterType() { if (m_eRotationCenterType == rTarget) { switch (m_eTargetType) { case tPoint: return rTarget; break; case tSuperObject: ASSERT(m_p_oTargetSuperObject != NULL); return rTarget; break; case tNone: return rCamera; default: ASSERT(0); // rotation center type unknown... return rCamera; } } else { if (m_eRotationCenterType == rSuperObject) ASSERT(m_p_oRotationCenterSuperObject != NULL); return m_eRotationCenterType; } } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** // gets the current target // if no target valid, return FALSE // target is always in world coordinates BOOL Camera::GetTarget(MTH3D_tdstVector &r_stTarget) { ACP_tdxHandleOfObject hBoundingVolume; CPA_BaseObject *p_oObject; MTH_tdxReal xRadius; switch (m_eTargetType) { case tNone: return FALSE; break; case tPoint: MTH3D_M_vCopyVector(&r_stTarget,&m_stTargetPoint); return TRUE; break; case tSuperObject: ASSERT(m_p_oTargetSuperObject != NULL); // get the object p_oObject = m_p_oTargetSuperObject->GetObject(); if (p_oObject != NULL) { // get the bounding volume of the object hBoundingVolume = ((CPA_ObjectDLLBase*) (p_oObject->GetEditor()))->fn_hGetBoundingVolume(p_oObject); // get the center of the bounding volume if (hBoundingVolume != NULL) { POS_tdstCompletePosition *p_stSOGlobalMatrix; p_stSOGlobalMatrix = HIE_fn_hGetSuperObjectGlobalMatrix(m_p_oTargetSuperObject->GetStruct()); //ANNECY TQ 22/06/98{ GEO_fn_vGetInfoFromGeometricSphere(&r_stTarget,&xRadius,hBoundingVolume); //ENDANNECY TQ} POS_fn_vMulMatrixVertex(&r_stTarget,p_stSOGlobalMatrix,&r_stTarget); } else POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(m_p_oTargetSuperObject->GetStruct()), &r_stTarget); } else { POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(m_p_oTargetSuperObject->GetStruct()),&r_stTarget); } return TRUE; break; } return FALSE; } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** // gets the current rotation center // if center is camera, return FALSE // center is always in world coordinates BOOL Camera::GetRotationCenter(MTH3D_tdstVector &r_stCenter) { switch (GetEffectiveRotationCenterType()) { case rCamera: return FALSE; break; case rPoint: MTH3D_M_vCopyVector(&r_stCenter,&m_stRotationCenterPoint); // if the point is relative, then it's camera coordinates... // and we want world coorindates if (m_eRotationCenterPointCoordsType == Relative) CameraToWorldCoordinates_Point(r_stCenter); return TRUE; break; case rSuperObject: POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(m_p_oRotationCenterSuperObject->GetStruct()), &r_stCenter); return TRUE; break; case rTarget: return GetTarget(r_stCenter); } return FALSE; } /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** //rotate the camera around the camera rotation center. //If axis = custom, axis is considered camera axis, and we perform standard axis relations. void Camera::Rotate(tdeAxis eAxis, double dAngle) { MTH3D_tdstVector stRotationCenter, stCameraPos, stTemp; POS_tdstCompletePosition stRotMatrix,stTwistRotMatrix,stTempM; // double dTwistAngle; POS_fn_vSetIdentityMatrix(&stRotMatrix); POS_fn_vSetIdentityMatrix(&stTwistRotMatrix); if (!GetRotationCenter(stRotationCenter)) { // rotation center = camera POS_fn_vGetTranslationVector(&m_stCameraMatrix,&stRotationCenter); } else { // if rotation center is not camera, the rotation angle // must be inversed in every case, but the X axe ! if (eAxis != X_Custom && eAxis != X_World && eAxis != X_Camera) dAngle = -dAngle; } // if real twist shows that camera is inversed, inverse commands ! if ( (fabs(GetRealTwistAngle()) > C_PI/2) && (m_bPrivilegeMode) && (eAxis == X_Custom || eAxis == Y_Custom) ) dAngle = -dAngle; if (m_bPrivilegeMode) { m_dTwistAngle = GetRealTwistAngle(); RemoveTwist(); // m_dTwistAngle = dTwistAngle; } POS_fn_vGetTranslationVector(&m_stCameraMatrix,&stCameraPos); // here, stRotationCenter is a valid point, in world coordinates // and stcamerapos contains the camera position MTH3D_M_vNullVector(&stTemp); if ( (eAxis == X_Custom) || (eAxis == Y_Custom) || (eAxis == Z_Custom) ) { // if the given axis is custom, then it is considered camera axis // we have to look what is the camera rotation axis system // if this default is world, we have to make a camera - world axis relation // if we rotate around Y and there is no twist, then Y IS world coordinates if ((m_eRotationAxisSystem == WorldCoordinates) || ( (eAxis == Y_Custom) && m_bPrivilegeMode)) { double dX,dY,dZ,dMax; // we build a temporary vector with X, Y or Z set to 1 according to axis // then we express this vector in world coordinates, and we look which // axis contains a 1 or a -1. switch(eAxis) { case X_Custom: MTH3D_M_vSetXofVector(&stTemp,1); CameraOriginalToWorldCoordinates(stTemp); // CameraToWorldCoordinates_Vector(stTemp); break; case Y_Custom: MTH3D_M_vSetYofVector(&stTemp,1); CameraOriginalToWorldCoordinates(stTemp); // CameraToWorldCoordinates_Vector(stTemp); break; case Z_Custom: MTH3D_M_vSetZofVector(&stTemp,1); CameraOriginalToWorldCoordinates(stTemp); // CameraToWorldCoordinates_Vector(stTemp); break; } MTH3D_M_vGetVectorElements(&dX,&dY,&dZ,&stTemp); dMax = (fabs(dX) > fabs(dY))? dX : dY; if (fabs(dMax) < fabs(dZ)) dMax = dZ; if (dMax == dX) { dAngle = (dX > 0)? dAngle : -dAngle; eAxis = X_World; } else if (dMax == dY) { dAngle = (dY > 0)? dAngle : -dAngle; eAxis = Y_World; } else if (dMax == dZ) { dAngle = (dZ > 0)? dAngle : -dAngle; eAxis = Z_World; } } else { //camera rotation axis system is camera coordinates --> ok if (eAxis == X_Custom) eAxis = X_Camera; if (eAxis == Y_Custom) eAxis = Y_Camera; if (eAxis == Z_Custom) eAxis = Z_Camera; } } switch(eAxis) { case X_World: case Y_World: case Z_World: // substract the rotation center from the camera MTH3D_M_vSubVector(&stTemp,&stCameraPos,&stRotationCenter); POS_fn_vSetTranslationVector(&m_stCameraMatrix,&stTemp); break; case X_Camera: case Y_Camera: case Z_Camera: MTH3D_M_vNullVector(&stTemp); POS_fn_vSetTranslationVector(&m_stCameraMatrix,&stTemp); // build the camera->Rotationcenter vector MTH3D_M_vSubVector(&stTemp,&stRotationCenter,&stCameraPos); } // compute Rotation Matrix switch(eAxis) { case X_Camera: case X_World: BuildRotationMatrix_X(stRotMatrix,dAngle); break; case Y_Camera: case Y_World: BuildRotationMatrix_Y(stRotMatrix,dAngle); break; case Z_Camera: case Z_World: BuildRotationMatrix_Z(stRotMatrix,dAngle); break; } //rotate the camera switch(eAxis) { case X_World: case Y_World: case Z_World: // rotate : rotation matrix * camera POS_fn_vSetIdentityMatrix(&stTempM); GEO_M_vCopyMatrix(&stTempM,&m_stCameraMatrix); POS_fn_vMulMatrixMatrix(&m_stCameraMatrix,&stRotMatrix,&stTempM); // add back the rotation center to the camera POS_fn_vGetTranslationVector(&m_stCameraMatrix,&stTemp); MTH3D_M_vAddVector(&stTemp,&stTemp,&stRotationCenter); POS_fn_vSetTranslationVector(&m_stCameraMatrix,&stTemp); break; case X_Camera: case Y_Camera: // camera-center vector to camera coords WorldToCameraCoordinates_Vector(stTemp); //rotate POS_fn_vSetIdentityMatrix(&stTempM); GEO_M_vCopyMatrix(&stTempM,&m_stCameraMatrix); POS_fn_vMulMatrixMatrix(&m_stCameraMatrix,&stTempM,&stRotMatrix); // camera-center vector to world coords CameraToWorldCoordinates_Vector(stTemp); // add rotation center to MTH3D_M_vSubVector(&stTemp,&stRotationCenter,&stTemp); // put new position POS_fn_vSetTranslationVector(&m_stCameraMatrix,&stTemp); break; case Z_Camera: // camera-center vector to camera coords WorldToCameraCoordinates_Vector(stTemp); //rotate POS_fn_vSetIdentityMatrix(&stTempM); GEO_M_vCopyMatrix(&stTempM,&m_stCameraMatrix); POS_fn_vMulMatrixMatrix(&m_stCameraMatrix,&stTempM,&stRotMatrix); // camera-center vector to world coords CameraToWorldCoordinates_Vector(stTemp); // add rotation center to MTH3D_M_vSubVector(&stTemp,&stRotationCenter,&stTemp); // put new position POS_fn_vSetTranslationVector(&m_stCameraMatrix,&stTemp); if (m_bPrivilegeMode) { SetTwist(); m_dTwistAngle += dAngle; } break; } // if rotation center is the camera, then the camera doesn't move! if (!GetRotationCenter(stRotationCenter)) { // rotation center = camera POS_fn_vSetTranslationVector(&m_stCameraMatrix,&stRotationCenter); } if (m_bPrivilegeMode) SetTwist(); Update(); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::SetRotation(double dAngleX, double dAngleY, double dAngleZ) { MTH3D_tdstVector stCameraPos,stTarget; double dDistToTarget; BOOL bCameraIsTargeted = FALSE; tdeRotationCenterType eRotSave; tdeTargetType eTargSave; if (m_bPrivilegeMode) RemoveTwist(); //save the camera position POS_fn_vGetTranslationVector(&m_stCameraMatrix,&stCameraPos); if (GetTarget(stTarget)) { // there's a valid target //compute distance to target dDistToTarget = MTH3D_M_xVectorGap(&stCameraPos,&stTarget); bCameraIsTargeted = TRUE; } // reset camera to its original state ResetCamera(); // set twist angle to NULL if (m_bPrivilegeMode) m_dTwistAngle = 0.0; // save actual target and rotation center parameters eRotSave = m_eRotationCenterType; eTargSave = m_eTargetType; // set no target and no rotation center m_eRotationCenterType = rCamera; m_eTargetType = tNone; // rotate the camera if (dAngleX != 0) Rotate(X_World,dAngleX); if (dAngleY != 0) Rotate(Y_World,dAngleY); if (dAngleZ != 0) Rotate(Z_World,dAngleZ); // if camera is targeted, move the camera to the right place if (bCameraIsTargeted) { CPA_CameraCoords oCoords; // move camera to the target center POS_fn_vSetTranslationVector(&m_stCameraMatrix,&stTarget); // translate the camera the right distance from the target oCoords.SetXYZ(0,0,(float)-dDistToTarget); oCoords.SetAxisSystem(CameraCoordinates); Translate(&oCoords); } else { //restore camera position POS_fn_vSetTranslationVector(&m_stCameraMatrix,&stCameraPos); } //restore camera parameters m_eRotationCenterType = eRotSave; m_eTargetType = eTargSave; if (m_bPrivilegeMode) SetTwist(); Update(); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** // translate the camera. Coords may be camera, world or camera default // if camera default, cameradefault == world, and not targeted --> intuitive mode void Camera::Translate(CPA_CameraCoords *p_oOffset, BOOL bUserDefinedAxis) { MTH3D_tdstVector stOffset, stCameraPos; if (m_bPrivilegeMode) RemoveTwist(); // we translate the camera... // the Offset must be in world coordinates p_oOffset->GetCoords(stOffset); if (bUserDefinedAxis) { // the translation is camera default... // so the coordinates are considered camera coordinates if (m_eTranslationAxisSystem == CameraCoordinates) { // ok, the given coordinates are right. we just have to // express them in world axis system CameraToWorldCoordinates_Vector(stOffset); } else // camera default = world coordinates { // coordinates are considered camera coordinates // but we want a translation along world axis system // we will have to make the relation between axis if (m_eTargetType == tNone) { double dX,dY,dZ,dMax,dNorme; // no target, so no visual reference --> intuitive mode // first, express coordinates in world coordinates CameraToWorldCoordinates_Vector(stOffset); // compute Norme of the offset // this value will be used to build the good offset vector dNorme = MTH3D_M_xNormVector(&stOffset); //then, look which coord is the greater (absolute value) MTH3D_M_vGetVectorElements(&dX,&dY,&dZ,&stOffset); dMax = (fabs(dX) > fabs(dY))? dX : dY; if (fabs(dMax) < fabs(dZ)) dMax = dZ; //then, according to the greater coord, build the good offset vector if (dMax == dX) { dX = (dX > 0) ? dNorme : -dNorme; dY = 0; dZ = 0; } else if (dMax == dY) { dY = (dY > 0) ? dNorme : -dNorme; dX = 0; dZ = 0; } else if (dMax == dZ) { dZ = (dZ > 0) ? dNorme : -dNorme; dX = 0; dY = 0; } // here, dX, dY and dZ represent the real offset vector, in // world coorinates MTH3D_M_vSetVectorElements(&stOffset,(float)dX,(float)dY,(float)dZ); } else { // use the standard relation //(default : X --> -X; Y --> Z; Z-->Y) CameraOriginalToWorldCoordinates(stOffset); } } } else if (p_oOffset->GetAxisSystem() == CameraCoordinates) CameraToWorldCoordinates_Vector(stOffset); // get camera position POS_fn_vGetTranslationVector(&m_stCameraMatrix,&stCameraPos); // adds offset MTH3D_M_vAddVector(&stCameraPos,&stCameraPos,&stOffset); // put back matrix in camera POS_fn_vSetTranslationVector(&m_stCameraMatrix,&stCameraPos); if (m_bPrivilegeMode) SetTwist(); Update(); //ROMTEAM Scale (Ionut Grozea 12/03/98) if ( GetMainWorld()->GetInterface()->fn_bIsScaleActive()) { GetMainWorld()->GetInterface()->fn_vScale(); } //ENDROMTEAM Scale (Ionut Grozea) } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** // set the camera at a certain position. void Camera::SetPosition(CPA_CameraCoords *p_oPos) { MTH3D_tdstVector stPos; // the Offset must be in world coordinates if (p_oPos) { p_oPos->GetCoords(stPos); if (p_oPos->GetAxisSystem() == CameraCoordinates) CameraToWorldCoordinates_Point(stPos); } else { MTH3D_M_vNullVector(&stPos); } // set the camera position POS_fn_vSetTranslationVector(&m_stCameraMatrix,&stPos); Update(); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** // Update the camera matrix, according to the target mode. // the camera may rotate to see the target if necessary. // Update the engine camera matrix too void Camera::Update() { MTH3D_tdstVector stTarget; if (GetTarget(stTarget)) //world coordinates always RotateCameraToSeePoint(&stTarget); InternalUpdate(); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** // Update the camera matrix according to the engine matrix void Camera::UpdateFromEngine() { InternalBackUpdate(); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::ZoomOnTarget(CPA_SuperObject *p_oSuperObject) { CPA_BaseObject *p_oObject; ACP_tdxHandleOfObject hBoundingVolume; MTH_tdxReal xRadius; MTH3D_tdstVector stCenter; CPA_CameraCoords oCoords; POS_tdstCompletePosition *p_stSOGlobalMatrix; if (m_bPrivilegeMode) RemoveTwist(); // get the object if (p_oSuperObject == NULL) { p_oObject = m_p_oTargetSuperObject->GetObject(); p_oSuperObject = m_p_oTargetSuperObject; } else { p_oObject = p_oSuperObject->GetObject(); } if (p_oObject != NULL) { // get the bounding volume of the object hBoundingVolume = ((CPA_ObjectDLLBase*) (p_oObject->GetEditor()))->fn_hGetBoundingVolume(p_oObject); if (hBoundingVolume != NULL) { MTH_tdxReal xAlphaX,xRatio; float fD1,fD2; // get center and radius of target //ANNECY TQ 22/06/98{ GEO_fn_vGetInfoFromGeometricSphere(&stCenter,&xRadius,hBoundingVolume); //ENDANNECY TQ} // compute the right distance to see the object in the window GLI_xGetCameraAspectAndRatio(GetStruct(),&xAlphaX,&xRatio); fD1 = MTH_M_xRealToFloat(MTH_M_xDiv(xRadius, MTH_M_xTan(MTH_M_xDiv(xAlphaX,2)))); fD2 = MTH_M_xRealToFloat(MTH_M_xDiv(xRadius, MTH_M_xTan(MTH_M_xDiv(MTH_M_xMul(xAlphaX,xRatio),2)))); xRadius = ((fD1 > fD2)? fD1 : fD2); p_stSOGlobalMatrix = HIE_fn_hGetSuperObjectGlobalMatrix(p_oSuperObject->GetStruct()); POS_fn_vMulMatrixVertex(&stCenter,p_stSOGlobalMatrix,&stCenter); //put camera at the same place that the object POS_fn_vSetTranslationVector(&m_stCameraMatrix,&stCenter); //move back the camera a distance equal to the radius oCoords.SetAxisSystem(CameraCoordinates); oCoords.SetXYZ(0,0,-xRadius); Translate(&oCoords); } else { // get superobject position p_stSOGlobalMatrix = HIE_fn_hGetSuperObjectGlobalMatrix(p_oSuperObject->GetStruct()); POS_fn_vGetTranslationVector(p_stSOGlobalMatrix, &stCenter); //put camera at the same place that the object POS_fn_vSetTranslationVector(&m_stCameraMatrix,&stCenter); //move back the camera a distance equal to the radius oCoords.SetAxisSystem(CameraCoordinates); oCoords.SetXYZ(0,0,-5.0); Translate(&oCoords); } } if (m_bPrivilegeMode) SetTwist(); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::SetPrivilegeMode(BOOL bMode) { if (bMode == m_bPrivilegeMode) return; m_bPrivilegeMode = bMode; if (bMode) // from non privilege to privilege... { m_bPrivilegeMode = TRUE; SetRotationAxisSystem(CameraCoordinates); SetTranslationAxisSystem(CameraCoordinates); ResetTwist(); Update(); } } /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// ////////////// P R I V A T E ////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// //reset camera, then rotate it to see the point // the point is world coordinates void Camera::RotateCameraToSeePoint(MTH3D_tdstVector *p_stTarget) { MTH3D_tdstVector stCamPointVector,stCameraPos,stI,stJ,stK; double dAngle,dX,dY,dZ,dTwist; tdeRotationCenterType eRotSave; tdeTargetType eTargSave; // compute the twist angle: POS_fn_vGetRotationMatrix(&m_stCameraMatrix,&stI,&stJ,&stK); dX = MTH3D_M_xGetZofVector(&stI); dY = MTH3D_M_xGetZofVector(&stJ); dTwist = atan2(dX,dY); if (m_bPrivilegeMode) RemoveTwist(); POS_fn_vGetTranslationVector(&m_stCameraMatrix,&stCameraPos); // first, reset camera rotation matrix. ResetCameraRotationMatrix(); // then, compute angles // compute camera - point vector MTH3D_M_vSubVector(&stCamPointVector,p_stTarget, &stCameraPos); // compute rotation around vertical axis MTH3D_M_vGetVectorElements(&dX,&dY,&dZ,&stCamPointVector); dAngle = atan2(-dX,dY); // rotate camera this angle eRotSave = m_eRotationCenterType; eTargSave = m_eTargetType; m_eRotationCenterType = rCamera; m_eTargetType = tNone; Rotate(Y_Camera,dAngle); // the camera just rotates, it doesn't move. // so the stCampointVector is still right. // but we must take the rotation into account WorldToCameraCoordinates_Vector(stCamPointVector); //now, stCamPointVector must have its X == 0, and Z >= 0 MTH3D_M_vGetVectorElements(&dX,&dY,&dZ,&stCamPointVector); // compute rotation around camera X axis dAngle = -atan2(dY,dZ); // rotate camera this angle Rotate(X_Camera,dAngle); // put back twist angle if (m_bPrivilegeMode) { m_dTwistAngle = dTwist; SetTwist(); } else { Rotate(Z_Camera,dTwist); } m_eRotationCenterType = eRotSave; m_eTargetType = eTargSave; } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::ResetCamera() { MTH3D_tdstVector stVect; MTH3D_M_vNullVector(&stVect); ResetCameraRotationMatrix(); POS_fn_vSetTranslationVector(&m_stCameraMatrix,&stVect); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::ResetCameraRotationMatrix() { POS_tdstCompletePosition *p_stWorldBaseMatrix; MTH3D_tdstVector stVector; // save camera position POS_fn_vGetTranslationVector(&m_stCameraMatrix,&stVector); // set rotation matrix p_stWorldBaseMatrix = &(M_GetMainApp()->m_stWorldBaseMatrix); GEO_M_vCopyMatrix(&m_stCameraMatrix,p_stWorldBaseMatrix); // restore camera position POS_fn_vSetTranslationVector(&m_stCameraMatrix,&stVector); POS_fn_vNormalizeMatrix(&m_stCameraMatrix); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** // update the engine camera. do nothing else void Camera::InternalUpdate() { POS_tdstCompletePosition stMatrix; // this function updates the GLI_tdstCamera* camera structure, // according to the information in the Camera object //invert the camera matrix POS_fn_vNormalizeMatrix(&m_stCameraMatrix); POS_fn_vInvertIsoMatrix(&stMatrix,&m_stCameraMatrix); POS_fn_vNormalizeMatrix(&stMatrix); // and set it in the engine camera structure GLI_xSetCameraMatrix(GetStruct(),&stMatrix); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** // update the editor camera from the engine camera void Camera::InternalBackUpdate() { GLI_tdxHandleToCamera hEngineCamera; POS_tdstCompletePosition stTemp; // this function update the m_stMatrix structure, // according to the information in the Camera engine matrix // get the engine camera hEngineCamera = GetStruct(); // get the engine camera matrix GLI_xGetCameraMatrix(hEngineCamera,&m_stCameraMatrix); //invert the camera matrix POS_fn_vNormalizeMatrix(&m_stCameraMatrix); GEO_M_vCopyMatrix(&stTemp,&m_stCameraMatrix); POS_fn_vInvertIsoMatrix(&m_stCameraMatrix,&stTemp); POS_fn_vNormalizeMatrix(&m_stCameraMatrix); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::CameraToWorldCoordinates_Point(MTH3D_tdstVector &r_stVector) { MTH3D_tdstVector stVect; MTH3D_M_vCopyVector(&stVect,&r_stVector); // we receive a point in camera coordinates // we must put it in world coordinates // (cameramatrix * vector) POS_fn_vMulMatrixVertex(&r_stVector,&m_stCameraMatrix,&stVect); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::CameraToWorldCoordinates_Vector(MTH3D_tdstVector &r_stVector) { MTH3D_tdstVector stVect; MTH3D_M_vCopyVector(&stVect,&r_stVector); // we receive a vector in camera coordinates // we must put it in world coordinates // (camerarotationmatrix * vector) POS_fn_vMulMatrixVector(&r_stVector,&m_stCameraMatrix,&stVect); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::CameraOriginalToWorldCoordinates(MTH3D_tdstVector &r_stVector) { MTH3D_tdstVector stVect; POS_tdstCompletePosition stMatrix; POS_fn_vSetIdentityMatrix(&stMatrix); MTH3D_M_vNullVector(&stVect); // get a copy of world base matrix GEO_M_vCopyMatrix(&stMatrix,&(M_GetMainApp()->m_stWorldBaseMatrix)); //set translation to NULL in the copy POS_fn_vSetTranslationVector(&stMatrix,&stVect); MTH3D_M_vCopyVector(&stVect,&r_stVector); // we receive a vector in camera coordinates // we must put it in world coordinates // (worldbasematrix * vector) POS_fn_vMulMatrixVertex(&r_stVector,&stMatrix,&stVect); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::WorldToCameraCoordinates_Point(MTH3D_tdstVector &r_stVector) { MTH3D_tdstVector stVect; POS_tdstCompletePosition stMatrix; MTH3D_M_vCopyVector(&stVect,&r_stVector); // we receive a point in world coordinates // we must put it in camera coordinates // (invertcameramatrix * vector) POS_fn_vInvertIsoMatrix(&stMatrix,&m_stCameraMatrix); POS_fn_vMulMatrixVertex(&r_stVector,&stMatrix,&stVect); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::WorldToCameraCoordinates_Vector(MTH3D_tdstVector &r_stVector) { MTH3D_tdstVector stVect; POS_tdstCompletePosition stMatrix; MTH3D_M_vNullVector(&stVect); // get inverse of camera matrix POS_fn_vInvertIsoMatrix(&stMatrix,&m_stCameraMatrix); //set translation to NULL in the copy POS_fn_vSetTranslationVector(&stMatrix,&stVect); MTH3D_M_vCopyVector(&stVect,&r_stVector); // we receive a vector in world coordinates // we must put it in camera coordinates // (invertcamerarotationmatrix * vector) POS_fn_vMulMatrixVertex(&r_stVector,&stMatrix,&stVect); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::WorldToCameraOriginalCoordinates(MTH3D_tdstVector &r_stVector) { MTH3D_tdstVector stVect; POS_tdstCompletePosition stMatrix; MTH3D_M_vNullVector(&stVect); // get inverse of world base matrix POS_fn_vInvertIsoMatrix(&stMatrix,&(M_GetMainApp()->m_stWorldBaseMatrix)); //set translation to NULL in the copy POS_fn_vSetTranslationVector(&stMatrix,&stVect); MTH3D_M_vCopyVector(&stVect,&r_stVector); // we receive a vector in world coordinates // we must put it in camera coordinates // (invertworldbasematrix * vector) POS_fn_vMulMatrixVertex(&r_stVector,&stMatrix,&stVect); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::BuildRotationMatrix_X( POS_tdstCompletePosition &r_stMatrix, double xXAngle ) { // build a rotation matrix MTH3D_tdstVector stVectI,stVectJ,stVectK; MTH_tdxReal xReal; xReal = MTH_M_xDoubleToReal(xXAngle); POS_fn_vSetIdentityMatrix(&r_stMatrix); POS_fn_vGetRotationMatrix(&r_stMatrix,&stVectI,&stVectJ,&stVectK); MTH3D_M_vSetYofVector(&stVectJ,GLI_M_Cos(xReal)); MTH3D_M_vSetZofVector(&stVectJ,GLI_M_Sin(xReal)); MTH3D_M_vSetYofVector(&stVectK,GLI_M_Neg(GLI_M_Sin(xReal))); MTH3D_M_vSetZofVector(&stVectK,GLI_M_Cos(xReal)); POS_fn_vSetRotationMatrix(&r_stMatrix,&stVectI,&stVectJ,&stVectK); // STM - camera's never have scale, so this shouldn't be needed POS_fn_vSetTransformMatrix (&r_stMatrix,&stVectI,&stVectJ,&stVectK); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::BuildRotationMatrix_Y( POS_tdstCompletePosition &r_stMatrix, double xYAngle ) { // build a rotation matrix MTH3D_tdstVector stVectI,stVectJ,stVectK; MTH_tdxReal xReal; xReal = MTH_M_xDoubleToReal(xYAngle); POS_fn_vSetIdentityMatrix(&r_stMatrix); POS_fn_vGetRotationMatrix(&r_stMatrix,&stVectI,&stVectJ,&stVectK); MTH3D_M_vSetXofVector(&stVectI,GLI_M_Cos(xReal)); MTH3D_M_vSetXofVector(&stVectK,GLI_M_Sin(xReal)); MTH3D_M_vSetZofVector(&stVectI,GLI_M_Neg(GLI_M_Sin(xReal))); MTH3D_M_vSetZofVector(&stVectK,GLI_M_Cos(xReal)); POS_fn_vSetRotationMatrix(&r_stMatrix,&stVectI,&stVectJ,&stVectK); // STM - camera's never have scale, so this shouldn't be needed POS_fn_vSetTransformMatrix(&r_stMatrix,&stVectI,&stVectJ,&stVectK); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::BuildRotationMatrix_Z( POS_tdstCompletePosition &r_stMatrix, double xZAngle ) { // build a rotation matrix MTH3D_tdstVector stVectI,stVectJ,stVectK; MTH_tdxReal xReal; xReal = MTH_M_xDoubleToReal(xZAngle); POS_fn_vSetIdentityMatrix(&r_stMatrix); POS_fn_vGetRotationMatrix(&r_stMatrix,&stVectI,&stVectJ,&stVectK); MTH3D_M_vSetXofVector(&stVectI,GLI_M_Cos(xReal)); MTH3D_M_vSetYofVector(&stVectI,GLI_M_Sin(xReal)); MTH3D_M_vSetXofVector(&stVectJ,GLI_M_Neg(GLI_M_Sin(xReal))); MTH3D_M_vSetYofVector(&stVectJ,GLI_M_Cos(xReal)); POS_fn_vSetRotationMatrix(&r_stMatrix,&stVectI,&stVectJ,&stVectK); // STM - camera's never have scale, so this shouldn't be needed POS_fn_vSetTransformMatrix(&r_stMatrix,&stVectI,&stVectJ,&stVectK); } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::RemoveTwist() { POS_tdstCompletePosition stTwistRotMatrix,stTemp; if (m_lTwistRemoveCount == 0) { POS_fn_vSetIdentityMatrix(&stTemp); GEO_M_vCopyMatrix(&stTemp,&m_stCameraMatrix); // remove the camera twist : BuildRotationMatrix_Z(stTwistRotMatrix,-m_dTwistAngle); POS_fn_vMulMatrixMatrix(&m_stCameraMatrix,&stTemp,&stTwistRotMatrix); } m_lTwistRemoveCount++; } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::SetTwist() { POS_tdstCompletePosition stTwistRotMatrix,stTemp; if (m_lTwistRemoveCount == 0) return; if (m_lTwistRemoveCount == 1) { POS_fn_vSetIdentityMatrix(&stTemp); GEO_M_vCopyMatrix(&stTemp,&m_stCameraMatrix); // put back the camera twist : BuildRotationMatrix_Z(stTwistRotMatrix,m_dTwistAngle); POS_fn_vMulMatrixMatrix(&m_stCameraMatrix,&stTemp,&stTwistRotMatrix); } m_lTwistRemoveCount--; } //******************************************************************************************************** //******************************************************************************************************** //******************************************************************************************************** void Camera::ResetTwist() { m_dTwistAngle = GetRealTwistAngle(); RemoveTwist(); m_dTwistAngle = 0.0; SetTwist(); } double Camera::GetRealTwistAngle() { MTH3D_tdstVector stI,stJ,stK; double dX,dY; POS_fn_vGetRotationMatrix(&m_stCameraMatrix,&stI,&stJ,&stK); dX = MTH3D_M_xGetZofVector(&stI); dY = MTH3D_M_xGetZofVector(&stJ); return atan2(dX,dY); }