reman3/Rayman_X/cpa/tempgrp/OCA/src/camera.cpp

1756 lines
57 KiB
C++

#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<GLI_tdxHandleToCamera>::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<GLI_tdxHandleToCamera>(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>( (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>( (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);
}