1315 lines
34 KiB
C++
1315 lines
34 KiB
C++
|
/*
|
||
|
** Command & Conquer Renegade(tm)
|
||
|
** Copyright 2025 Electronic Arts Inc.
|
||
|
**
|
||
|
** This program is free software: you can redistribute it and/or modify
|
||
|
** it under the terms of the GNU General Public License as published by
|
||
|
** the Free Software Foundation, either version 3 of the License, or
|
||
|
** (at your option) any later version.
|
||
|
**
|
||
|
** This program is distributed in the hope that it will be useful,
|
||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
** GNU General Public License for more details.
|
||
|
**
|
||
|
** You should have received a copy of the GNU General Public License
|
||
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
/***********************************************************************************************
|
||
|
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||
|
***********************************************************************************************
|
||
|
* *
|
||
|
* Project Name : LevelEdit *
|
||
|
* *
|
||
|
* $Archive:: /Commando/Code/Tools/LevelEdit/CameraMgr.cpp $*
|
||
|
* *
|
||
|
* Author:: Patrick Smith *
|
||
|
* *
|
||
|
* $Modtime:: 11/06/01 10:29a $*
|
||
|
* *
|
||
|
* $Revision:: 46 $*
|
||
|
* *
|
||
|
*---------------------------------------------------------------------------------------------*
|
||
|
* Functions: *
|
||
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||
|
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "utils.h"
|
||
|
#include "camera.h"
|
||
|
#include "cameramgr.h"
|
||
|
#include "mousemgr.h"
|
||
|
#include "leveleditdoc.h"
|
||
|
#include "groupmgr.h"
|
||
|
#include "formtoolbar.h"
|
||
|
#include "camerasettingsform.h"
|
||
|
#include "mainfrm.h"
|
||
|
#include "filemgr.h"
|
||
|
#include "editorassetmgr.h"
|
||
|
#include "_assetmgr.h"
|
||
|
#include "sceneeditor.h"
|
||
|
#include "node.h"
|
||
|
#include "quat.h"
|
||
|
#include "combat.h"
|
||
|
#include "filelocations.h"
|
||
|
#include "combatchunkid.h"
|
||
|
#include "ccamera.h"
|
||
|
#include "input.h"
|
||
|
#include "leveleditview.h"
|
||
|
#include "nodemgr.h"
|
||
|
#include "actionparams.h"
|
||
|
#include "soldier.h"
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Constants
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
const float DEF_CAMERA_DIST = 80.00F;
|
||
|
const float MIN_MOVE_SCALE = 30.00F;
|
||
|
|
||
|
const float WALK_THRU_VEL_FWD = 3.5F;
|
||
|
const float WALK_THRU_VEL_BKWD = -WALK_THRU_VEL_FWD;
|
||
|
const float WALK_THRU_VEL_LEFT = 0.8F;
|
||
|
const float WALK_THRU_VEL_RIGHT = -WALK_THRU_VEL_LEFT;
|
||
|
const float WALK_THRU_VEL_STRAFE = 4.5F;
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Static member initialization
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
CameraMgr::UPDATE_CAMERA_FN CameraMgr::_pfnUpdateMethods[CAMERA_MODE::MODE_COUNT] =
|
||
|
{
|
||
|
CameraMgr::Update_Camera_MOVE_ZOOM,
|
||
|
CameraMgr::Update_Camera_MOVE_PLANE,
|
||
|
CameraMgr::Update_Camera_FLY_THROUGH,
|
||
|
CameraMgr::Update_Camera_WALK_THROUGH,
|
||
|
CameraMgr::Update_Camera_ROTATE_FREE,
|
||
|
CameraMgr::Update_Camera_ROTATE_X,
|
||
|
CameraMgr::Update_Camera_ROTATE_Y,
|
||
|
CameraMgr::Update_Camera_ROTATE_Z,
|
||
|
CameraMgr::Update_Camera_ORBIT,
|
||
|
CameraMgr::Update_Camera_FLY_TO
|
||
|
};
|
||
|
|
||
|
|
||
|
bool CameraMgr::_pKeyboardState[256] = { 0 };
|
||
|
HHOOK CameraMgr::_hHook = NULL;
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CameraMgr
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
CameraMgr::CameraMgr (void)
|
||
|
: m_pCamera (NULL),
|
||
|
m_bAutoLevel (false),
|
||
|
m_CameraMode (MODE_MOVE_PLANE),
|
||
|
m_SpeedModifier (6.0F),
|
||
|
m_WalkThruObj (NULL),
|
||
|
m_WalkThruDef (NULL)
|
||
|
{
|
||
|
Init_Camera ();
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CameraMgr
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
CameraMgr::~CameraMgr (void)
|
||
|
{
|
||
|
MEMBER_RELEASE (m_pCamera);
|
||
|
|
||
|
if (m_WalkThruObj != NULL) {
|
||
|
m_WalkThruObj->Set_Delete_Pending ();
|
||
|
m_WalkThruObj = NULL;
|
||
|
Input::Shutdown ();
|
||
|
}
|
||
|
|
||
|
if (m_WalkThruDef != NULL) {
|
||
|
delete m_WalkThruDef;
|
||
|
}
|
||
|
|
||
|
|
||
|
//MEMBER_RELEASE (m_pWalkThroughPhys);
|
||
|
|
||
|
// Remove our hook procedure from the chain
|
||
|
if (_hHook != NULL) {
|
||
|
::UnhookWindowsHookEx (_hHook);
|
||
|
_hHook = NULL;
|
||
|
}
|
||
|
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// fnCameraKeyboardHook
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
LRESULT CALLBACK
|
||
|
fnCameraKeyboardHook
|
||
|
(
|
||
|
int code,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam
|
||
|
)
|
||
|
{
|
||
|
// Should we process this message?
|
||
|
if (code >= 0) {
|
||
|
if ((wParam >= 0) && (wParam <= 255)) {
|
||
|
CameraMgr::_pKeyboardState[wParam] = bool((lParam & 0x80000000) != 0x80000000);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Call the next hook procedure in the chain
|
||
|
return ::CallNextHookEx (CameraMgr::_hHook, code, wParam, lParam);
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Init_Camera
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Init_Camera (void)
|
||
|
{
|
||
|
if (m_pCamera == NULL) {
|
||
|
// Create a new camera object
|
||
|
m_pCamera = new CameraClass;
|
||
|
}
|
||
|
|
||
|
// Were we able to create a new object?
|
||
|
ASSERT (m_pCamera!= NULL);
|
||
|
if (m_pCamera) {
|
||
|
|
||
|
// Create a transformation matrix
|
||
|
Matrix3D transform_matrix (1);
|
||
|
transform_matrix.Translate (Vector3 (0.0F, 0.0F, DEF_CAMERA_DIST));
|
||
|
m_pCamera->Set_Clip_Planes (0.1F, 200.0F);
|
||
|
//m_pCamera->Set_Environment_Range (9000.0F, 10000.0F);
|
||
|
|
||
|
// Move the camera back along the z-axis looking at world center
|
||
|
Set_Transform (transform_matrix);
|
||
|
m_pCamera->Set_Transform (transform_matrix);
|
||
|
}
|
||
|
|
||
|
// Install a windows hook procedure so we know when keys are pressed
|
||
|
if (_hHook == NULL) {
|
||
|
::memset (_pKeyboardState, 0, sizeof (_pKeyboardState));
|
||
|
_hHook = ::SetWindowsHookEx (WH_KEYBOARD,
|
||
|
fnCameraKeyboardHook,
|
||
|
::AfxGetInstanceHandle (),
|
||
|
::GetCurrentThreadId ());
|
||
|
}
|
||
|
|
||
|
// Reset the camera mode
|
||
|
m_CameraMode = MODE_MOVE_PLANE;
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
double _XRot = 0;
|
||
|
double _YRot = 0;
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Set_Camera_Mode
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Set_Camera_Mode (CAMERA_MODE new_mode)
|
||
|
{
|
||
|
// Is this really a new mode?
|
||
|
if (new_mode != m_CameraMode) {
|
||
|
|
||
|
if (new_mode == MODE_WALK_THROUGH) {
|
||
|
::Get_Scene_Editor ()->Set_Selection (NULL);
|
||
|
|
||
|
GameInFocus = true;
|
||
|
if (m_WalkThruObj == NULL) {
|
||
|
Input::Init ();
|
||
|
Input::Load_Configuration (DEFAULT_INPUT_FILENAME);
|
||
|
Input::Set_Mouse_Invert (true);
|
||
|
|
||
|
//
|
||
|
// Create a commando game object and initialize it
|
||
|
// with the first commando preset we found
|
||
|
//
|
||
|
SoldierGameObjDef *definition = (SoldierGameObjDef *)DefinitionMgrClass::Find_Typed_Definition ("Walk-Thru", CLASSID_GAME_OBJECT_DEF_SOLDIER, false);
|
||
|
m_WalkThruObj = new SoldierGameObj;
|
||
|
m_WalkThruObj->Init (*definition);
|
||
|
|
||
|
ActionParamsStruct parameters;
|
||
|
m_WalkThruObj->Get_Action()->Follow_Input( parameters );
|
||
|
}
|
||
|
|
||
|
m_WalkThruObj->Control_Enable (true);
|
||
|
m_WalkThruObj->Set_Control_Owner (CombatManager::Get_My_Id ());
|
||
|
CombatManager::Set_I_Am_Client (true);
|
||
|
CombatManager::Set_The_Star (m_WalkThruObj);
|
||
|
|
||
|
//
|
||
|
// Give the physics object an initial transform
|
||
|
//
|
||
|
PhysClass *phys_obj = m_WalkThruObj->Peek_Physical_Object ();
|
||
|
if (phys_obj != NULL) {
|
||
|
Matrix3D transform = m_pCamera->Get_Transform ();
|
||
|
|
||
|
Matrix3D cam_to_world (Vector3 (0, 0, -1), Vector3 (-1, 0, 0), Vector3 (0, 1, 0), Vector3 (0, 0, 0));
|
||
|
transform = transform * cam_to_world;
|
||
|
phys_obj->Set_Transform (transform);
|
||
|
}
|
||
|
|
||
|
|
||
|
} else if (m_WalkThruObj != NULL) {
|
||
|
|
||
|
m_WalkThruObj->Set_Delete_Pending ();
|
||
|
m_WalkThruObj = NULL;
|
||
|
Input::Shutdown ();
|
||
|
}
|
||
|
|
||
|
m_CameraMode = new_mode;
|
||
|
}
|
||
|
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Update_Camera
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Update_Camera
|
||
|
(
|
||
|
float deltax,
|
||
|
float deltay
|
||
|
)
|
||
|
{
|
||
|
// State OK?
|
||
|
ASSERT (m_pCamera != NULL);
|
||
|
if (m_pCamera != NULL) {
|
||
|
|
||
|
// Call into the state table to perform the update
|
||
|
_pfnUpdateMethods[m_CameraMode] (*m_pCamera, deltax, deltay);
|
||
|
|
||
|
if (m_bAutoLevel) {
|
||
|
|
||
|
// If ew are auto-leveling, then reset the initial
|
||
|
// rotation matrix and percent
|
||
|
m_AutoLevelInitalMatrix = m_pCamera->Get_Transform ();
|
||
|
m_AutoLevelPercent = 0.00F;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Level_Camera
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Level_Camera (void)
|
||
|
{
|
||
|
m_bAutoLevel = true;
|
||
|
|
||
|
// Reset the initial rotation matrix and percent
|
||
|
m_AutoLevelInitalMatrix = m_pCamera->Get_Transform ();
|
||
|
m_AutoLevelPercent = 0.00F;
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Auto_Level
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Auto_Level (void)
|
||
|
{
|
||
|
// Is there a mouse button down?
|
||
|
// We don't want to auto-level if the mouse button is down
|
||
|
BOOL mouse_down = BOOL(::GetKeyState (VK_LBUTTON) & 0xF000);
|
||
|
mouse_down |= BOOL(::GetKeyState (VK_RBUTTON) & 0xF000);
|
||
|
|
||
|
// Should we auto-level the camera?
|
||
|
if ((m_AutoLevelPercent <= 1) && (mouse_down == false)) {
|
||
|
|
||
|
// Get the camera's current transformation matrix
|
||
|
Matrix3D matrix = m_pCamera->Get_Transform ();
|
||
|
|
||
|
Vector3 cam_pos;
|
||
|
Vector3 cam_target;
|
||
|
|
||
|
// Get the camera position
|
||
|
matrix.Get_Translation (&cam_pos);
|
||
|
|
||
|
// Get a vector 1 meter below the camera position
|
||
|
cam_target = matrix * Vector3 (0.00F, 0.00F, -1.00F);
|
||
|
|
||
|
// Force the z components of the 2 vectors to be the same.
|
||
|
cam_target.Z = cam_pos.Z;
|
||
|
|
||
|
// Create a new transformation matrix which is positioned
|
||
|
// at the camera and is looking at the vector we created
|
||
|
Matrix3D new_matrix;
|
||
|
new_matrix.Look_At (cam_pos, cam_target, 0.0F);
|
||
|
|
||
|
// Build quaternions for the start and end rotation matricies
|
||
|
Quaternion initial_quat = ::Build_Quaternion (m_AutoLevelInitalMatrix);
|
||
|
Quaternion end_quat = ::Build_Quaternion (new_matrix);
|
||
|
|
||
|
// Linerally-interpolate between the 2 rotations (from 0.0 - 1.0)
|
||
|
Quaternion rotation_now;
|
||
|
::Slerp (rotation_now, initial_quat, end_quat, m_AutoLevelPercent);
|
||
|
|
||
|
// Increment the current interpolation percent
|
||
|
m_AutoLevelPercent += 0.04F;
|
||
|
|
||
|
// Set the rotation for the camera's transormation matrix
|
||
|
matrix.Set_Rotation (rotation_now);
|
||
|
|
||
|
// Set the camera's new rotation
|
||
|
Set_Transform (matrix);
|
||
|
|
||
|
if (m_AutoLevelPercent >= 1) {
|
||
|
m_bAutoLevel = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Increase_Speed
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Increase_Speed (void)
|
||
|
{
|
||
|
if (m_SpeedModifier < 1.0F) {
|
||
|
m_SpeedModifier += 0.1F;
|
||
|
} else {
|
||
|
m_SpeedModifier += 0.75F;
|
||
|
}
|
||
|
|
||
|
// Normalize the speed
|
||
|
if (m_SpeedModifier > 25.00F) {
|
||
|
m_SpeedModifier = 25.00F;
|
||
|
}
|
||
|
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Decrease_Speed
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Decrease_Speed (void)
|
||
|
{
|
||
|
if (m_SpeedModifier < 2.0F) {
|
||
|
m_SpeedModifier -= 0.1F;
|
||
|
} else {
|
||
|
m_SpeedModifier -= 0.75F;
|
||
|
}
|
||
|
|
||
|
// Normalize the speed
|
||
|
if (m_SpeedModifier < 0.25F) {
|
||
|
m_SpeedModifier = 0.25F;
|
||
|
}
|
||
|
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// On_Frame
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::On_Frame (void)
|
||
|
{
|
||
|
float speed_mod = CameraMgr::_pKeyboardState[VK_CONTROL] ? m_SpeedModifier : 1.0F;
|
||
|
|
||
|
if ((_pKeyboardState[VK_NUMPAD8]) ||
|
||
|
(_pKeyboardState[VK_NUMPAD2])) {
|
||
|
|
||
|
// Get the camera's current position
|
||
|
Vector3 position = m_pCamera->Get_Position ();
|
||
|
float orig_z = position.Z;
|
||
|
|
||
|
// Get the current direction the camera is looking at
|
||
|
Matrix3D matrix = m_pCamera->Get_Transform ();
|
||
|
|
||
|
float delta = _pKeyboardState[VK_NUMPAD8] ? -0.35F : 0.35F;
|
||
|
delta *= speed_mod;
|
||
|
|
||
|
// Should we lock the z-position?
|
||
|
if (::GetKeyState (VK_CAPITAL) & 0x0001) {
|
||
|
|
||
|
// Scale the position 'forward' and 'backward'
|
||
|
//position += (delta * matrix.Get_Z_Vector ());
|
||
|
//position.Z = orig_z;
|
||
|
|
||
|
Vector3 y_vector = Vector3::Cross_Product (matrix.Get_X_Vector (), Vector3 (0, 0, 1));
|
||
|
y_vector.Normalize ();
|
||
|
position += delta * y_vector;
|
||
|
//delta += y_vector * (-0.05F * modifier);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
// Scale the position along the direction vector
|
||
|
position += (delta * matrix.Get_Z_Vector ());
|
||
|
}
|
||
|
|
||
|
// Set the camera's new position
|
||
|
Set_Position (position);
|
||
|
}
|
||
|
|
||
|
if ((_pKeyboardState[VK_NUMPAD9]) ||
|
||
|
(_pKeyboardState[VK_NUMPAD3])) {
|
||
|
|
||
|
// Get the camera's current transform
|
||
|
Matrix3D transform = m_pCamera->Get_Transform ();
|
||
|
|
||
|
// Rotate by the specified number of radians
|
||
|
float rotation = _pKeyboardState[VK_NUMPAD9] ? 0.0314F : -0.0314F;
|
||
|
rotation *= (speed_mod / 2.5F);
|
||
|
if (rotation > 0.045F) {
|
||
|
rotation = 0.045F;
|
||
|
} else if (rotation < -0.045F) {
|
||
|
rotation = -0.045F;
|
||
|
}
|
||
|
|
||
|
transform.Rotate_X (rotation);
|
||
|
|
||
|
// Set the camera's new transform
|
||
|
Set_Transform (transform);
|
||
|
}
|
||
|
|
||
|
if ((_pKeyboardState[VK_NUMPAD4]) ||
|
||
|
(_pKeyboardState[VK_NUMPAD6])) {
|
||
|
|
||
|
if (::GetKeyState (VK_MENU) < 0) {
|
||
|
|
||
|
// Get the camera's current position
|
||
|
Vector3 position = m_pCamera->Get_Position ();
|
||
|
|
||
|
float delta = (_pKeyboardState[VK_NUMPAD4]) ? -0.25F : 0.25F;
|
||
|
delta *= speed_mod;
|
||
|
position += (delta * m_pCamera->Get_Transform ().Get_X_Vector ());
|
||
|
|
||
|
// Set the camera's new position
|
||
|
Set_Position (position);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
// Get the pure rotation from the transform
|
||
|
Matrix3D transform = m_pCamera->Get_Transform ();
|
||
|
Vector3 translation = transform.Get_Translation ();
|
||
|
transform.Set_Translation (Vector3 (0, 0, 0));
|
||
|
|
||
|
// Determine an appropriate rotation delta
|
||
|
float delta = (_pKeyboardState[VK_NUMPAD4]) ? 0.0314F : -0.0314F;
|
||
|
delta *= speed_mod;
|
||
|
if (delta > 0.06F) {
|
||
|
delta = 0.06F;
|
||
|
} else if (delta < -0.06F) {
|
||
|
delta = -0.06F;
|
||
|
}
|
||
|
|
||
|
Matrix3D world_rotation(1);
|
||
|
world_rotation.Rotate_Z (delta);
|
||
|
|
||
|
// Rotate using the world's coord system
|
||
|
transform = world_rotation * transform;
|
||
|
transform.Set_Translation (translation);
|
||
|
|
||
|
// Set the camera's new transform
|
||
|
Set_Transform (transform);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ((_pKeyboardState[VK_NUMPAD7]) ||
|
||
|
(_pKeyboardState[VK_NUMPAD1])) {
|
||
|
|
||
|
// Get the camera's current position
|
||
|
Vector3 position = m_pCamera->Get_Position ();
|
||
|
|
||
|
float delta = (_pKeyboardState[VK_NUMPAD1]) ? -0.25F : 0.25F;
|
||
|
delta *= speed_mod;
|
||
|
position.Z += delta;
|
||
|
|
||
|
// Set the camera's new position
|
||
|
Set_Position (position);
|
||
|
}
|
||
|
|
||
|
// Are we currently in 'walk-thru' mode?
|
||
|
if (m_CameraMode == MODE_WALK_THROUGH) {
|
||
|
if (m_WalkThruObj != NULL) {
|
||
|
|
||
|
if (::GetAsyncKeyState (VK_ESCAPE) < 0 || ::GetAsyncKeyState (VK_F6) < 0) {
|
||
|
::Get_Mouse_Mgr ()->Set_Mouse_Mode (MouseMgrClass::MODE_OBJECT_MANIPULATE);
|
||
|
} else {
|
||
|
|
||
|
//
|
||
|
// Check for the VIS-Update keypress
|
||
|
//
|
||
|
static DWORD last_vis_gen = 0;
|
||
|
static DWORD last_static_anim_toggle = 0;
|
||
|
DWORD current_ticks = ::GetTickCount ();
|
||
|
if ((::GetAsyncKeyState (VK_RETURN) < 0) && (current_ticks - last_vis_gen) > 1000) {
|
||
|
Vector3 sample_point = m_WalkThruObj->Get_Transform ().Get_Translation () + Vector3 (0, 0, 1);
|
||
|
::Get_Scene_Editor ()->Record_Vis_Info (m_pCamera->Get_Transform (), sample_point);
|
||
|
last_vis_gen = current_ticks;
|
||
|
} else if (::GetAsyncKeyState (VK_F3) < 0) {
|
||
|
bool points_visible = ::Get_Scene_Editor ()->Are_Manual_Vis_Points_Visible ();
|
||
|
::Get_Scene_Editor ()->Show_Manual_Vis_Points (!points_visible);
|
||
|
} else if ( (::GetAsyncKeyState (VK_CONTROL) < 0) &&
|
||
|
(::GetAsyncKeyState (VK_SHIFT) < 0) &&
|
||
|
(::GetAsyncKeyState ('T') < 0))
|
||
|
{
|
||
|
//
|
||
|
// Toggle the static anims... (if necessary)
|
||
|
//
|
||
|
if ((current_ticks - last_static_anim_toggle) > 250) {
|
||
|
((CMainFrame *)::AfxGetMainWnd ())->Toggle_Static_Anims ();
|
||
|
last_static_anim_toggle = current_ticks;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Allow the game object and physic object to think
|
||
|
//
|
||
|
m_WalkThruObj->Generate_Control ();
|
||
|
m_WalkThruObj->Think ();
|
||
|
PhysClass *phys_obj = m_WalkThruObj->Peek_Physical_Object ();
|
||
|
if (phys_obj != NULL) {
|
||
|
phys_obj->Timestep (TimeManager::Get_Frame_Seconds ());
|
||
|
}
|
||
|
m_WalkThruObj->Post_Think ();
|
||
|
|
||
|
CCameraClass *game_camera = CombatManager::Get_Camera ();
|
||
|
if (game_camera != NULL) {
|
||
|
|
||
|
//
|
||
|
// Update the game camera
|
||
|
//
|
||
|
Input::Update ();
|
||
|
CombatManager::Handle_Input ();
|
||
|
CombatManager::Update_Star ();
|
||
|
|
||
|
Matrix3D tm = m_WalkThruObj->Get_Transform();
|
||
|
game_camera->Update ();
|
||
|
|
||
|
//
|
||
|
// Copy the game camera's transform
|
||
|
//
|
||
|
Matrix3D camera_tm = game_camera->Get_Transform ();
|
||
|
m_pCamera->Set_Transform (camera_tm);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (m_bAutoLevel) {
|
||
|
Auto_Level ();
|
||
|
}
|
||
|
|
||
|
if (m_CameraMode == MODE_FLYTO) {
|
||
|
Update_Fly_To ();
|
||
|
}
|
||
|
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Update_Camera_Animation
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Update_Camera_Animation (void)
|
||
|
{
|
||
|
//
|
||
|
// TODO - move the camera depending on the animation mode
|
||
|
//
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
//**************************************************************************************************************//
|
||
|
//
|
||
|
// Start of static methods
|
||
|
//
|
||
|
//**************************************************************************************************************//
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Update_Camera_MOVE_ZOOM
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Update_Camera_MOVE_ZOOM
|
||
|
(
|
||
|
CameraClass & camera,
|
||
|
float deltax,
|
||
|
float deltay
|
||
|
)
|
||
|
{
|
||
|
// Get the camera's current position
|
||
|
Vector3 position = camera.Get_Position ();
|
||
|
|
||
|
// Get the current direction the camera is looking at
|
||
|
Matrix3D matrix = camera.Get_Transform ();
|
||
|
Vector3 orientation = matrix.Get_Z_Vector ();
|
||
|
|
||
|
float scale_factor = (position.Z > MIN_MOVE_SCALE) ? position.Z : MIN_MOVE_SCALE;
|
||
|
|
||
|
// Scale the position along the direction vector
|
||
|
position = position - (deltay * orientation * scale_factor);
|
||
|
|
||
|
// Set the camera's new position
|
||
|
::Get_Camera_Mgr ()->Set_Position (position);
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Update_Camera_MOVE_PLANE
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Update_Camera_MOVE_PLANE
|
||
|
(
|
||
|
CameraClass & camera,
|
||
|
float deltax,
|
||
|
float deltay
|
||
|
)
|
||
|
{
|
||
|
// Get the camera's current position
|
||
|
Vector3 position = camera.Get_Position ();
|
||
|
|
||
|
// Get the vector the camera is 'sliding' up and down on
|
||
|
Matrix3D matrix = camera.Get_Transform ();
|
||
|
Vector3 orientation = matrix.Get_Y_Vector ();
|
||
|
|
||
|
float scale_factor = (position.Z > MIN_MOVE_SCALE) ? position.Z : MIN_MOVE_SCALE;
|
||
|
|
||
|
// Scale the position along the direction vector
|
||
|
position = position + (deltay * orientation * scale_factor);
|
||
|
|
||
|
// Scale the position along the 'left/right' vector
|
||
|
orientation = matrix.Get_X_Vector ();
|
||
|
position = position - (deltax * orientation * scale_factor);
|
||
|
|
||
|
// Set the camera's new position
|
||
|
::Get_Camera_Mgr ()->Set_Position (position);
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Update_Camera_FLY_THROUGH
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Update_Camera_FLY_THROUGH
|
||
|
(
|
||
|
CameraClass & camera,
|
||
|
float deltax,
|
||
|
float deltay
|
||
|
)
|
||
|
{
|
||
|
//
|
||
|
// TODO - update the camera
|
||
|
//
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Update_Camera_WALK_THROUGH
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Update_Camera_WALK_THROUGH
|
||
|
(
|
||
|
CameraClass & camera,
|
||
|
float deltax,
|
||
|
float deltay
|
||
|
)
|
||
|
{
|
||
|
//
|
||
|
// TODO - update the camera
|
||
|
//
|
||
|
|
||
|
//Matrix3D transform = camera.Get_Transform ();
|
||
|
//transform.Rotate_X (deltay*3.0F);
|
||
|
_XRot += deltay * 2.0F;
|
||
|
//_YRot += deltax * 3.0F;
|
||
|
//camera.Set_Transform (transform);
|
||
|
|
||
|
// Get the camera's current transformation matrix
|
||
|
//CamaraCharPhys *pcharacter = ::Get_Camera_Mgr ()->Get_Walkthru_Character ();
|
||
|
if (0) {//pcharacter != NULL) {
|
||
|
|
||
|
/*Matrix3D transform = pcharacter->Get_Transform ();
|
||
|
transform.Rotate_Z (deltax * 2.0F);
|
||
|
pcharacter->Set_Transform (transform);*/
|
||
|
}
|
||
|
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Update_Camera_ROTATE_FREE
|
||
|
//
|
||
|
void
|
||
|
CameraMgr::Update_Camera_ROTATE_FREE
|
||
|
(
|
||
|
CameraClass & camera,
|
||
|
float deltax,
|
||
|
float deltay
|
||
|
)
|
||
|
{
|
||
|
// Rotate the camera's transformation matrix based
|
||
|
// on the deltas
|
||
|
Matrix3D matrix = camera.Get_Transform ();
|
||
|
//matrix.Rotate_X (deltay);
|
||
|
//matrix.Rotate_Y (deltax);
|
||
|
|
||
|
// Restrict the rotation to the current axis
|
||
|
switch (::Get_Current_Document ()->Get_Axis_Restriction ()) {
|
||
|
|
||
|
case CLevelEditDoc::RESTRICT_X:
|
||
|
{
|
||
|
matrix.Rotate_X (deltay);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CLevelEditDoc::RESTRICT_Y:
|
||
|
{
|
||
|
matrix.Rotate_Y (deltax);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CLevelEditDoc::RESTRICT_Z:
|
||
|
{
|
||
|
matrix.Rotate_Z (deltay);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
{
|
||
|
matrix.Rotate_X (deltay);
|
||
|
matrix.Rotate_Y (deltax);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Set the camera's new rotation
|
||
|
::Get_Camera_Mgr ()->Set_Transform (matrix);
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Update_Camera_ROTATE_X
|
||
|
//
|
||
|
void
|
||
|
CameraMgr::Update_Camera_ROTATE_X
|
||
|
(
|
||
|
CameraClass & camera,
|
||
|
float deltax,
|
||
|
float deltay
|
||
|
)
|
||
|
{
|
||
|
// Rotate the camera's transformation matrix based
|
||
|
// on the x delta
|
||
|
Matrix3D matrix = camera.Get_Transform ();
|
||
|
matrix.Rotate_X (deltay);
|
||
|
|
||
|
// Set the camera's new rotation
|
||
|
::Get_Camera_Mgr ()->Set_Transform (matrix);
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Update_Camera_ROTATE_Y
|
||
|
//
|
||
|
void
|
||
|
CameraMgr::Update_Camera_ROTATE_Y
|
||
|
(
|
||
|
CameraClass &camera,
|
||
|
float deltax,
|
||
|
float deltay
|
||
|
)
|
||
|
{
|
||
|
// Rotate the camera's transformation matrix based
|
||
|
// on the y delta
|
||
|
Matrix3D matrix = camera.Get_Transform ();
|
||
|
matrix.Rotate_Y (deltax);
|
||
|
|
||
|
// Set the camera's new rotation
|
||
|
::Get_Camera_Mgr ()->Set_Transform (matrix);
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Update_Camera_ROTATE_Z
|
||
|
//
|
||
|
void
|
||
|
CameraMgr::Update_Camera_ROTATE_Z
|
||
|
(
|
||
|
CameraClass & camera,
|
||
|
float deltax,
|
||
|
float deltay
|
||
|
)
|
||
|
{
|
||
|
// Rotate the camera's transformation matrix based
|
||
|
// on the x and y deltas, but restrict the rotation
|
||
|
// to Z
|
||
|
Matrix3D matrix = camera.Get_Transform ();
|
||
|
Matrix3D temp_matrix = matrix;
|
||
|
temp_matrix.Rotate_X (deltay);
|
||
|
temp_matrix.Rotate_Y (deltax);
|
||
|
|
||
|
/*Matrix3D new_matrix (1);
|
||
|
new_matrix.Set_Translation (matrix.Get_Translation ());
|
||
|
new_matrix.Rotate_X (matrix.Get_X_Rotation ());
|
||
|
new_matrix.Rotate_Y (matrix.Get_Y_Rotation ());
|
||
|
new_matrix.Rotate_Z (temp_matrix.Get_Z_Rotation ());*/
|
||
|
|
||
|
Matrix3D new_matrix = matrix;
|
||
|
new_matrix.Rotate_Z (deltax+deltay);
|
||
|
//new_matrix.Rotate_Z (deltay);
|
||
|
|
||
|
// Set the camera's new rotation
|
||
|
::Get_Camera_Mgr ()->Set_Transform (matrix);
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Update_Camera_FLY_TO
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Update_Camera_FLY_TO
|
||
|
(
|
||
|
CameraClass &camera,
|
||
|
float /*deltax*/,
|
||
|
float /*deltay*/
|
||
|
)
|
||
|
{
|
||
|
::Get_Camera_Mgr ()->Update_Fly_To ();
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Update_Camera_ORBIT
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Update_Camera_ORBIT
|
||
|
(
|
||
|
CameraClass &camera,
|
||
|
float /*deltax*/,
|
||
|
float /*deltay*/
|
||
|
)
|
||
|
{
|
||
|
//
|
||
|
// TODO - update the camera
|
||
|
//
|
||
|
|
||
|
MouseMgrClass *pmouse_mgr = ::Get_Mouse_Mgr ();
|
||
|
|
||
|
CPoint point = pmouse_mgr->Get_Mouse_Point ();
|
||
|
CPoint last_point = pmouse_mgr->Get_Last_Mouse_Point ();
|
||
|
|
||
|
Vector3 viewpos;
|
||
|
Vector3 last_viewpos;
|
||
|
camera.Device_To_View_Space (Vector2 (last_point.x, last_point.y), &last_viewpos);
|
||
|
camera.Device_To_View_Space (Vector2 (point.x, point.y), &viewpos);
|
||
|
|
||
|
// Rotate the camara like a trackball
|
||
|
Quaternion rotation = ::Trackball (last_viewpos.X, last_viewpos.Y, viewpos.X, viewpos.Y, 0.4F);
|
||
|
|
||
|
// Rotate this item about its z axis
|
||
|
if (::Get_Selection_Mgr ().Get_Count () > 0) {
|
||
|
|
||
|
//SphereClass bounding_sphere = ::Get_Selection_Mgr ().Get_Bounding_Sphere ();
|
||
|
//bounding_sphere.Center;
|
||
|
|
||
|
Matrix3D matrix = camera.Get_Transform ();
|
||
|
Matrix3D matrix_inv;
|
||
|
matrix.Get_Orthogonal_Inverse (matrix_inv);
|
||
|
|
||
|
Vector3 vector_to_object = matrix_inv * ::Get_Selection_Mgr ().Get_Center ();//bounding_sphere.Center;
|
||
|
matrix.Translate (vector_to_object);
|
||
|
|
||
|
Matrix3D::Multiply (matrix, ::Build_Matrix3D (rotation), &matrix);
|
||
|
|
||
|
matrix.Translate (-vector_to_object);
|
||
|
|
||
|
::Get_Camera_Mgr ()->Set_Transform (matrix);
|
||
|
}
|
||
|
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Set_Camera_Pos
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Set_Camera_Pos (CAMERA_POS position)
|
||
|
{
|
||
|
SphereClass sp = ::Get_Selection_Mgr ().Get_Bounding_Sphere ();
|
||
|
if (Get_Selection_Mgr ().Get_Count () == 0) {
|
||
|
sp.Center = Vector3 (0, 0, 0);
|
||
|
sp.Radius = 100.00F;
|
||
|
}
|
||
|
|
||
|
float distance = sp.Radius * 3.00F;
|
||
|
distance = (distance < 1.0F) ? 1.0F : distance;
|
||
|
distance = (distance > 400.0F) ? 400.0F : distance;
|
||
|
|
||
|
Matrix3D transform (1);
|
||
|
|
||
|
switch (position)
|
||
|
{
|
||
|
case CAMERA_FRONT:
|
||
|
{
|
||
|
transform.Look_At (sp.Center + Vector3 (distance, 0.00F, 0.00F), sp.Center, 0);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CAMERA_BACK:
|
||
|
{
|
||
|
transform.Look_At (sp.Center + Vector3 (-distance, 0.00F, 0.00F), sp.Center, 0);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CAMERA_LEFT:
|
||
|
{
|
||
|
transform.Look_At (sp.Center + Vector3 (0.00F, -distance, 0.00F), sp.Center, 0);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CAMERA_RIGHT:
|
||
|
{
|
||
|
transform.Look_At (sp.Center + Vector3 (0.00F, distance, 0.00F), sp.Center, 0);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CAMERA_TOP:
|
||
|
{
|
||
|
transform.Look_At (sp.Center + Vector3 (0.00F, 0.00F, distance), sp.Center, 3.1415926535F);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CAMERA_BOTTOM:
|
||
|
{
|
||
|
transform.Look_At (sp.Center + Vector3 (0.00F, 0.00F, -distance), sp.Center, 3.1415926535F);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Move the camera back to get a good view of the object
|
||
|
Set_Transform (transform);
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Goto_Node
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Goto_Node (NodeClass *node)
|
||
|
{
|
||
|
RenderObjClass *render_obj = node->Peek_Render_Obj ();
|
||
|
if (render_obj != NULL) {
|
||
|
|
||
|
//
|
||
|
// Get the node's position
|
||
|
//
|
||
|
SphereClass sphere = render_obj->Get_Bounding_Sphere ();
|
||
|
Matrix3D tm = render_obj->Get_Transform ();
|
||
|
tm.Set_Translation (Vector3 (0, 0, 0));
|
||
|
|
||
|
//
|
||
|
// Calculate an appropriate viewing distance
|
||
|
//
|
||
|
float distance = sphere.Radius * 4;
|
||
|
distance = (distance < 1.0F) ? 1.0F : distance;
|
||
|
distance = (distance > 100.0F) ? 100.0F : distance;
|
||
|
|
||
|
Matrix3D transform (1);
|
||
|
//transform.Look_At (sphere.Center + Vector3 (distance, distance, distance), sphere.Center, 0);
|
||
|
Vector3 camera_loc = (sphere.Center + Vector3 (-distance, 0, distance));
|
||
|
transform.Look_At (camera_loc, sphere.Center, 0);
|
||
|
//tranform.Set_Translation (sphere.Center);
|
||
|
//render_obj->
|
||
|
|
||
|
//
|
||
|
// Move the camera back to get a good view of the object
|
||
|
//
|
||
|
Set_Transform (transform);
|
||
|
|
||
|
// Ensure the window is updated
|
||
|
::Refresh_Main_View ();
|
||
|
}
|
||
|
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Goto_Group
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Goto_Group (GroupMgrClass *group)
|
||
|
{
|
||
|
// State OK?
|
||
|
if (group != NULL) {
|
||
|
|
||
|
// Get the node's position
|
||
|
SphereClass sp = group->Get_Bounding_Sphere ();
|
||
|
|
||
|
float distance = sp.Radius;
|
||
|
distance = (distance < 1.0F) ? 1.0F : distance;
|
||
|
distance = (distance > 400.0F) ? 400.0F : distance;
|
||
|
|
||
|
Matrix3D transform (1);
|
||
|
transform.Look_At (sp.Center + Vector3 (distance, distance, distance), sp.Center, 0);
|
||
|
|
||
|
// Move the camera back to get a good view of the object
|
||
|
Set_Transform (transform);
|
||
|
|
||
|
// Ensure the window is updated
|
||
|
::Refresh_Main_View ();
|
||
|
}
|
||
|
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Set_Transform
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Set_Transform (const Matrix3D &transform)
|
||
|
{
|
||
|
if (m_pCamera != NULL) {
|
||
|
|
||
|
// Set the camera's new location and orientation
|
||
|
m_pCamera->Set_Transform (transform);
|
||
|
|
||
|
// Update the the UI to reflect this new position
|
||
|
((CMainFrame *)::AfxGetMainWnd ())->Update_Camera_Location (transform.Get_Translation ());
|
||
|
Set_Modified (true);
|
||
|
|
||
|
// If the camera settings dialog is visible, update its contents
|
||
|
/*FormToolbarClass &toolbar = ((CMainFrame *)::AfxGetMainWnd ())->Get_Camera_Toolbar ();
|
||
|
if (::IsWindow (toolbar) && toolbar.IsVisible ()) {
|
||
|
CameraSettingsFormClass *pform = (CameraSettingsFormClass *)toolbar.Get_Form ();
|
||
|
if (pform != NULL) {
|
||
|
pform->Update_Controls ();
|
||
|
}
|
||
|
}*/
|
||
|
}
|
||
|
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Set_Position
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Set_Position (const Vector3 &position)
|
||
|
{
|
||
|
if (m_pCamera != NULL) {
|
||
|
|
||
|
// Set the camera's new location and orientation
|
||
|
m_pCamera->Set_Position (position);
|
||
|
|
||
|
// Update the the UI to reflect this new position
|
||
|
((CMainFrame *)::AfxGetMainWnd ())->Update_Camera_Location (position);
|
||
|
Set_Modified (true);
|
||
|
|
||
|
// If the camera settings dialog is visible, update its contents
|
||
|
/*FormToolbarClass &toolbar = ((CMainFrame *)::AfxGetMainWnd ())->Get_Camera_Toolbar ();
|
||
|
if (::IsWindow (toolbar) && toolbar.IsVisible ()) {
|
||
|
CameraSettingsFormClass *pform = (CameraSettingsFormClass *)toolbar.Get_Form ();
|
||
|
if (pform != NULL) {
|
||
|
pform->Update_Controls ();
|
||
|
}
|
||
|
}*/
|
||
|
}
|
||
|
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Fly_To_Transform
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Fly_To_Transform (const Matrix3D &transform)
|
||
|
{
|
||
|
m_FlyToStartTransform = m_pCamera->Get_Transform ();
|
||
|
m_FlyToEndTransform = transform;
|
||
|
|
||
|
Vector3 start_point = m_FlyToStartTransform.Get_Translation ();
|
||
|
Vector3 end_point = m_FlyToEndTransform.Get_Translation ();
|
||
|
|
||
|
Vector3 delta = end_point - start_point;
|
||
|
float len = delta.Length () / 2;
|
||
|
Vector3 middle_point = start_point + Vector3 (delta.X / 2, delta.Y / 2, delta.Z / 2 + len);
|
||
|
|
||
|
// Remove all keys from the spline
|
||
|
while (m_FlyToSpline.Key_Count () > 0) {
|
||
|
m_FlyToSpline.Remove_Key (0);
|
||
|
}
|
||
|
|
||
|
Vector3 looking_start = -20.0F * m_FlyToStartTransform.Get_Z_Vector ();
|
||
|
int index = m_FlyToSpline.Add_Key (start_point, 0);
|
||
|
m_FlyToSpline.Set_Tangents (index, looking_start, looking_start);
|
||
|
|
||
|
Vector3 looking_end = -20.0F * m_FlyToEndTransform.Get_Z_Vector ();
|
||
|
index = m_FlyToSpline.Add_Key (end_point, 1);
|
||
|
m_FlyToSpline.Set_Tangents (index, looking_end, looking_end);
|
||
|
|
||
|
m_FlyToStartTime = ::GetTickCount ();
|
||
|
Set_Camera_Mode (MODE_FLYTO);
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Update_Fly_To
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void
|
||
|
CameraMgr::Update_Fly_To (void)
|
||
|
{
|
||
|
const DWORD FLY_TICKS = 5000;
|
||
|
float fly_ticks = (float)FLY_TICKS;
|
||
|
|
||
|
if (::GetAsyncKeyState (VK_CONTROL) < 0) {
|
||
|
fly_ticks = fly_ticks / m_SpeedModifier;
|
||
|
}
|
||
|
|
||
|
DWORD current_time = ::GetTickCount ();
|
||
|
float spline_time = float(current_time - m_FlyToStartTime) / fly_ticks;
|
||
|
spline_time = min (1.0F, spline_time);
|
||
|
|
||
|
if (m_FlyToStartTime + ((DWORD)fly_ticks) < current_time) {
|
||
|
m_pCamera->Set_Transform (m_FlyToEndTransform);
|
||
|
Set_Camera_Mode (MODE_MOVE_PLANE);
|
||
|
} else {
|
||
|
Vector3 position (0,0,0);
|
||
|
Vector3 next_position (0,0,0);
|
||
|
m_FlyToSpline.Evaluate (spline_time, &position);
|
||
|
m_FlyToSpline.Evaluate (spline_time + 0.05F, &next_position);
|
||
|
|
||
|
Matrix3D rot_90 (1);
|
||
|
rot_90.Rotate_Z ((float)DEG_TO_RAD (90));
|
||
|
|
||
|
Vector3 x_axis = next_position - position;
|
||
|
x_axis.Normalize ();
|
||
|
|
||
|
Vector3 y_axis = rot_90 * x_axis;
|
||
|
y_axis.Normalize ();
|
||
|
|
||
|
Vector3 z_axis;
|
||
|
Vector3::Cross_Product (x_axis, y_axis, &z_axis);
|
||
|
Matrix3D orientation (x_axis, y_axis, z_axis, position);
|
||
|
|
||
|
Matrix3D world_to_cam (Vector3 (0, -1, 0), Vector3 (0, 0, 1), Vector3 (-1, 0, 0), Vector3 (0, 0, 0));
|
||
|
Matrix3D camera_tm = orientation * world_to_cam;
|
||
|
|
||
|
if (camera_tm.Is_Orthogonal () == false) {
|
||
|
TRACE ("Matrix not orthogonal!\r\n");
|
||
|
camera_tm.Re_Orthogonalize();
|
||
|
}
|
||
|
|
||
|
Set_Transform (camera_tm);
|
||
|
}
|
||
|
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Get_Character_TM
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
Matrix3D
|
||
|
CameraMgr::Get_Character_TM (void)
|
||
|
{
|
||
|
Matrix3D tm (1);
|
||
|
|
||
|
if (m_WalkThruObj != NULL) {
|
||
|
tm = m_WalkThruObj->Get_Transform ();
|
||
|
} else {
|
||
|
tm = m_pCamera->Get_Transform ();
|
||
|
}
|
||
|
|
||
|
return tm;
|
||
|
}
|