Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
1206 lines
28 KiB
C++
1206 lines
28 KiB
C++
//===========================================================================//
|
|
// File: CameraShip.cpp
|
|
//---------------------------------------------------------------------------//
|
|
// Date Who Modification //
|
|
// -------- --- ---------------------------------------------------------- //
|
|
// 09/09/98 JSE Inital base class based off of Shadowrun/Adept
|
|
//---------------------------------------------------------------------------//
|
|
// Copyright (C) 1998, Fasa Interactive //
|
|
// All Rights reserved worldwide //
|
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
|
//===========================================================================//
|
|
|
|
|
|
#include "MW4Headers.hpp"
|
|
|
|
#include "CameraShip.hpp"
|
|
#include "MWObject.hpp"
|
|
//#include "CombatAI.hpp"
|
|
#include "MWGUIManager.hpp"
|
|
#include "MWVideoRenderer.hpp"
|
|
#include "VehicleInterface.hpp"
|
|
#include "Mech.hpp"
|
|
#include "aiutils.hpp"
|
|
|
|
#include <Adept\EntityManager.hpp>
|
|
#include <Adept\DamageObject.hpp>
|
|
#include <Adept\Effect.hpp>
|
|
#include <Adept\Map.hpp>
|
|
#include <Adept\VideoRenderer.hpp>
|
|
#include <Adept\CameraComponent.hpp>
|
|
#include <Adept\Player.hpp>
|
|
#include <Adept\CollisionGrid.hpp>
|
|
|
|
CameraShipManager *CameraShipManager::Instance = NULL;
|
|
|
|
//#############################################################################
|
|
//################## CameraShip::ExecutionStateEngine ########################
|
|
//#############################################################################
|
|
|
|
const StateEngine::StateEntry
|
|
CameraShip::ExecutionStateEngine::StateEntries[]=
|
|
{
|
|
STATE_ENTRY(CameraShip__ExecutionStateEngine, CameraMotion)
|
|
};
|
|
|
|
CameraShip::ExecutionStateEngine::ClassData*
|
|
CameraShip::ExecutionStateEngine::DefaultData = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
CameraShip::ExecutionStateEngine::InitializeClass()
|
|
{
|
|
|
|
|
|
|
|
Check_Object(StateEngine::DefaultData);
|
|
Verify(!DefaultData);
|
|
|
|
DefaultData =
|
|
new ClassData(
|
|
CameraShip__ExecutionStateEngineClassID,
|
|
"CameraShip::ExecutionStateEngine",
|
|
BaseClass::DefaultData,
|
|
ELEMENTS(StateEntries), StateEntries,
|
|
(Entity::ExecutionStateEngine::Factory)Make,
|
|
(Entity::ExecutionStateEngine::FactoryRequest::Factory)
|
|
&FactoryRequest::ConstructFactoryRequest
|
|
);
|
|
Register_Object(DefaultData);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
CameraShip::ExecutionStateEngine::TerminateClass()
|
|
{
|
|
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
CameraShip::ExecutionStateEngine*
|
|
CameraShip::ExecutionStateEngine::Make(
|
|
CameraShip *entity,
|
|
FactoryRequest *request
|
|
)
|
|
{
|
|
Check_Object(entity);
|
|
Check_Object(request);
|
|
CameraShip::ExecutionStateEngine *engine;
|
|
gos_PushCurrentHeap(Heap);
|
|
engine = new CameraShip::ExecutionStateEngine(DefaultData, entity, request);
|
|
gos_PopCurrentHeap();
|
|
return engine;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
CameraShip::ExecutionStateEngine::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|
|
|
|
//#############################################################################
|
|
//############################### CameraShipManager
|
|
//#############################################################################
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShipManager::TurnOnCameras()
|
|
{
|
|
|
|
Verify(!cinemaStarted);
|
|
|
|
{
|
|
|
|
|
|
CameraComponent *cam_comp = VideoRenderer::Instance->GetSceneCamera();
|
|
Check_Object(cam_comp);
|
|
|
|
cam_comp->GetPerspective(
|
|
nearClip,
|
|
farClip,
|
|
horFOV,
|
|
aspectRatio
|
|
);
|
|
|
|
ToggleHud(false);
|
|
|
|
Stuff::ChainIteratorOf<CameraShip*> iterator(&camerasInWorld);
|
|
CameraShip *camera;
|
|
while ((camera = iterator.GetCurrent()) != NULL)
|
|
{
|
|
camera->TurnOn();
|
|
iterator.ReadAndNext();
|
|
}
|
|
|
|
cinemaStarted = true;
|
|
}
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShipManager::TurnOffCameras()
|
|
{
|
|
|
|
if (cinemaStarted)
|
|
{
|
|
|
|
cinemaStarted = false;
|
|
|
|
Stuff::ChainIteratorOf<CameraShip*> iterator(&camerasInWorld);
|
|
CameraShip *camera;
|
|
while ((camera = iterator.GetCurrent()) != NULL)
|
|
{
|
|
camera->TurnOff();
|
|
iterator.ReadAndNext();
|
|
}
|
|
activeCamera.Remove();
|
|
|
|
MWVideoRenderer *vid_rend = Cast_Object(MWVideoRenderer *, VideoRenderer::Instance);
|
|
Stuff::RGBColor color;
|
|
color = RGBColor(0.0f, 0.0f, 0.0f);
|
|
vid_rend->SetFadeLevel(0.0f, color);
|
|
|
|
ToggleHud(true);
|
|
ToggleInternal(true);
|
|
if (Player::GetInstance()->playerInterface)
|
|
{
|
|
VehicleInterface *v_interface = Cast_Object(VehicleInterface *, Player::GetInstance()->playerInterface);
|
|
v_interface->RestorePreferredCameraPosition();
|
|
v_interface->SetCameraViewLevel(v_interface->GetCameraViewLevel());
|
|
v_interface->SetCameraMode(v_interface->cameraView);
|
|
}
|
|
CameraComponent *cam_comp = VideoRenderer::Instance->GetSceneCamera();
|
|
Check_Object(cam_comp);
|
|
|
|
cam_comp->SetPerspective(
|
|
nearClip,
|
|
farClip,
|
|
horFOV,
|
|
aspectRatio
|
|
);
|
|
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CameraShipManager::ToggleHud(bool active)
|
|
{
|
|
|
|
// turn on
|
|
if (active)
|
|
{
|
|
if (!hudOn) // if hud off
|
|
{
|
|
hudOn = true;
|
|
|
|
MWVideoRenderer *vid_rend = Cast_Object(MWVideoRenderer *, VideoRenderer::Instance);
|
|
vid_rend->TurnOffCinemaScope();
|
|
}
|
|
if(MWGUIManager::GetInstance())
|
|
{
|
|
MWGUIManager::GetInstance()->Show();
|
|
}
|
|
}
|
|
else // turn off
|
|
{
|
|
if (hudOn) // if hud on
|
|
{
|
|
hudOn = false;
|
|
|
|
MWVideoRenderer *vid_rend = Cast_Object(MWVideoRenderer *, VideoRenderer::Instance);
|
|
|
|
vid_rend->TurnOnCinemaScope();
|
|
vid_rend->SetCinemaScopeWidthRatio(2.35f);
|
|
}
|
|
if(MWGUIManager::GetInstance())
|
|
{
|
|
MWGUIManager::GetInstance()->Hide();
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CameraShipManager::ToggleInternal(bool active)
|
|
{
|
|
|
|
if (active)
|
|
{
|
|
internalCamera = true;
|
|
|
|
MWVideoRenderer *vid_rend = Cast_Object(MWVideoRenderer *, VideoRenderer::Instance);
|
|
CameraComponent *cam_comp = VideoRenderer::Instance->GetSceneCamera();
|
|
Check_Object(cam_comp);
|
|
|
|
cam_comp->SetPerspective(
|
|
nearClip,
|
|
farClip,
|
|
horFOV,
|
|
aspectRatio
|
|
);
|
|
|
|
|
|
Stuff::RGBColor color;
|
|
color = RGBColor(0.0f, 0.0f, 0.0f);
|
|
vid_rend->SetFadeLevel(0.0f, color);
|
|
|
|
if (Player::GetInstance()->playerInterface)
|
|
{
|
|
VehicleInterface *v_interface = Cast_Object(VehicleInterface *, Player::GetInstance()->playerInterface);
|
|
v_interface->SetCameraMode(VehicleInterface::InMechCameraView);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
internalCamera = false;
|
|
|
|
if (Player::GetInstance()->playerInterface)
|
|
{
|
|
VehicleInterface *v_interface = Cast_Object(VehicleInterface *, Player::GetInstance()->playerInterface);
|
|
v_interface->SetCameraMode(VehicleInterface::ExternalCameraAttachedView);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CameraShipManager::InterruptCinema()
|
|
{
|
|
if (cinemaStarted)
|
|
{
|
|
cinemaStarted = false;
|
|
|
|
|
|
ToggleHud(true);
|
|
|
|
MWVideoRenderer *vid_rend = Cast_Object(MWVideoRenderer *, VideoRenderer::Instance);
|
|
Stuff::RGBColor color;
|
|
color = RGBColor(0.0f, 0.0f, 0.0f);
|
|
vid_rend->SetFadeLevel(0.0f, color);
|
|
|
|
activeCamera.Remove();
|
|
|
|
CameraComponent *cam_comp = VideoRenderer::Instance->GetSceneCamera();
|
|
if (cam_comp)
|
|
{
|
|
Check_Object(cam_comp);
|
|
|
|
cam_comp->SetPerspective(
|
|
nearClip,
|
|
farClip,
|
|
horFOV,
|
|
aspectRatio
|
|
);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
|
|
void CameraShipManager::SetInternalCamera(bool show_hud)
|
|
{
|
|
CameraShip *last_camera = activeCamera.GetCurrent();
|
|
if (last_camera != NULL)
|
|
{
|
|
last_camera->ClearActive();
|
|
}
|
|
|
|
activeCamera.Remove();
|
|
|
|
|
|
ToggleInternal(true);
|
|
|
|
if (show_hud)
|
|
{
|
|
ToggleHud(true);
|
|
}
|
|
else
|
|
{
|
|
ToggleHud(false);
|
|
}
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShipManager::SetActiveCamera(CameraShip *camera)
|
|
{
|
|
|
|
|
|
ToggleHud(false);
|
|
ToggleInternal(false);
|
|
|
|
|
|
CameraShip *last_camera = activeCamera.GetCurrent();
|
|
if (last_camera != NULL)
|
|
{
|
|
last_camera->ClearActive();
|
|
}
|
|
|
|
activeCamera.Remove();
|
|
activeCamera.Add(camera);
|
|
|
|
camera->SetActive();
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
CameraShip *CameraShipManager::GetActiveCamera(void)
|
|
{
|
|
return activeCamera.GetCurrent();
|
|
}
|
|
|
|
|
|
//#############################################################################
|
|
//############################### CameraShip
|
|
//#############################################################################
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
CameraShip::ClassData*
|
|
CameraShip::DefaultData = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
CameraShip::InitializeClass()
|
|
{
|
|
CameraShipManager::Instance = new CameraShipManager();
|
|
Register_Object(CameraShipManager::Instance);
|
|
|
|
|
|
Check_Object(ExecutionStateEngine::DefaultData);
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
CameraShipClassID,
|
|
"MechWarrior4::CameraShip",
|
|
BaseClass::DefaultData,
|
|
NULL, NULL,
|
|
(Entity::Factory)Make,
|
|
(Entity::CreateMessage::Factory)CreateMessage::ConstructCreateMessage,
|
|
ExecutionStateEngine::DefaultData,
|
|
(Entity::GameModel::Factory)GameModel::ConstructGameModel,
|
|
NULL,
|
|
(Entity::GameModel::ReadAndVerifier)GameModel::ReadAndVerify,
|
|
(Entity::GameModel::ModelWrite)GameModel::WriteToText,
|
|
(Entity::GameModel::ModelSave)GameModel::SaveGameModel
|
|
);
|
|
Register_Object(DefaultData);
|
|
|
|
INDIRECT_STATE_ATTRIBUTE(
|
|
CameraShip,
|
|
ExecutionState,
|
|
executionState,
|
|
CameraShip__ExecutionStateEngine
|
|
);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
CameraShip::TerminateClass()
|
|
{
|
|
Unregister_Object(CameraShipManager::Instance);
|
|
delete CameraShipManager::Instance;
|
|
CameraShipManager::Instance = NULL;
|
|
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
CameraShip*
|
|
CameraShip::Make(
|
|
CreateMessage *message,
|
|
ReplicatorID *base_id
|
|
)
|
|
{
|
|
Check_Object(message);
|
|
gos_PushCurrentHeap(Heap);
|
|
CameraShip *new_entity =
|
|
new CameraShip(DefaultData, message, base_id, NULL);
|
|
gos_PopCurrentHeap();
|
|
Check_Object(new_entity);
|
|
|
|
CameraShipManager::Instance->AddCamera(new_entity);
|
|
|
|
return new_entity;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
CameraShip::CameraShip(
|
|
ClassData *class_data,
|
|
CreateMessage *message,
|
|
ReplicatorID *base_id,
|
|
ElementRenderer::Element *element
|
|
):
|
|
Entity(class_data, message, base_id, element),
|
|
m_ShakeDistance(0),
|
|
m_ShakeSource(-2)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(message);
|
|
|
|
|
|
|
|
|
|
cameraMovement = FollowInitialPositionMovementType;
|
|
targetMovement = FollowInitialPositionMovementType;
|
|
|
|
cameraFollowObject = NULL;
|
|
targetFollowObject = NULL;
|
|
|
|
cameraPath = NULL;
|
|
targetPath = NULL;
|
|
|
|
cameraOffsetLocal = true;
|
|
targetOffsetLocal = true;
|
|
|
|
cameraOffset.Init(Point3D::Identity, Point3D::Identity, 0.0f);
|
|
targetOffset.Init(Point3D::Identity, Point3D::Identity, 0.0f);
|
|
|
|
|
|
Point3D current_position;
|
|
|
|
|
|
|
|
|
|
current_position = GetElement()->GetNewLocalToParent();
|
|
cameraPosition.Init(current_position, current_position, 0.0f);
|
|
targetPosition.Init(current_position, current_position, 0.0f);
|
|
|
|
overridePitchFlag = false;
|
|
overrideYawFlag = false;
|
|
overrideRollFlag = false;
|
|
|
|
cameraPitch.Init(0.0f, 0.0f, 0.0f);
|
|
cameraYaw.Init(0.0f, 0.0f, 0.0f);
|
|
cameraRoll.Init(0.0f, 0.0f, 0.0f);
|
|
|
|
cameraFOV.Init(0.0f, 0.0f, 0.0f);
|
|
fadeLevel.Init(0.0f, 0.0f, 0.0f);
|
|
|
|
fadeState = FadeBlackType;
|
|
|
|
cameraCurrentWayPoint = 0;
|
|
targetCurrentWayPoint = 0;
|
|
cameraPathSpeed = 0.0f;
|
|
targetPathSpeed = 0.0f;
|
|
|
|
cameraWaypointAnimation.Init(Point3D::Identity, Point3D::Identity, 0.0f);
|
|
targetWaypointAnimation.Init(Point3D::Identity, Point3D::Identity, 0.0f);
|
|
|
|
|
|
activeCamera = false;
|
|
|
|
currentTargetPosition = Point3D::Identity;
|
|
|
|
UsePostCollision();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
CameraShip::~CameraShip()
|
|
{
|
|
CameraShipManager::Instance->InterruptCinema();
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void
|
|
CameraShip::PostCollisionExecute(Time till)
|
|
{
|
|
Check_Object(this);
|
|
POSTCOLLISION_LOGIC("CameraShip");
|
|
|
|
Scalar time_slice = GetTimeSlice(till);
|
|
|
|
cameraOffset.UpdateTime(time_slice);
|
|
targetOffset.UpdateTime(time_slice);
|
|
cameraPitch.UpdateTime(time_slice);
|
|
cameraYaw.UpdateTime(time_slice);
|
|
cameraRoll.UpdateTime(time_slice);
|
|
cameraFOV.UpdateTime(time_slice);
|
|
fadeLevel.UpdateTime(time_slice);
|
|
cameraPosition.UpdateTime(time_slice);
|
|
targetPosition.UpdateTime(time_slice);
|
|
cameraWaypointAnimation.UpdateTime(time_slice);
|
|
targetWaypointAnimation.UpdateTime(time_slice);
|
|
|
|
|
|
// position the target
|
|
Point3D camera_position = Point3D::Identity;
|
|
YawPitchRoll camera_rotation = YawPitchRoll::Identity;
|
|
|
|
switch(cameraMovement)
|
|
{
|
|
case FollowInitialPositionMovementType:
|
|
// stay where we are. This is the initial position
|
|
camera_position = cameraPosition.GetCurrentValue();
|
|
break;
|
|
|
|
case FollowObjectMovementType:
|
|
{
|
|
Check_Object(cameraFollowObject);
|
|
Point3D offset = cameraOffset.GetCurrentValue();
|
|
|
|
LinearMatrix4D camera_object_mat = cameraFollowObject->GetLocalToWorld();
|
|
if (cameraOffsetLocal)
|
|
{
|
|
// take into account rotation
|
|
camera_position.Multiply(offset, camera_object_mat);
|
|
}
|
|
else
|
|
{
|
|
// leave rotation out of it
|
|
Point3D world_point;
|
|
world_point = camera_object_mat;
|
|
camera_position.Add(offset, world_point);
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case FollowPathMovementType:
|
|
{
|
|
|
|
// set the position..
|
|
|
|
|
|
|
|
|
|
Point3D offset = cameraOffset.GetCurrentValue();
|
|
camera_position.Add(offset, cameraWaypointAnimation.GetCurrentValue());
|
|
|
|
|
|
if (cameraWaypointAnimation.AnimDone())
|
|
{
|
|
// go to the next waypoint if there is one...
|
|
|
|
++cameraCurrentWayPoint;
|
|
|
|
if (cameraCurrentWayPoint < cameraPath->pathPoints.size())
|
|
{
|
|
Scalar time_to_next_waypoint = 0.0f;
|
|
|
|
Point3D to, from;
|
|
to = cameraPath->pathPoints[cameraCurrentWayPoint];
|
|
from = cameraPath->pathPoints[cameraCurrentWayPoint-1];
|
|
|
|
|
|
Vector3D length_vector;
|
|
length_vector.Subtract(to, from);
|
|
|
|
if (!Small_Enough(length_vector) && !Small_Enough(cameraPathSpeed))
|
|
{
|
|
Scalar length = length_vector.GetLength();
|
|
time_to_next_waypoint = length / cameraPathSpeed;
|
|
}
|
|
|
|
cameraWaypointAnimation.Init(from, to, time_to_next_waypoint);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case FollowPositionMovemntType:
|
|
// stay where we are. The call made set this position and now we just sit
|
|
camera_position = cameraPosition.GetCurrentValue();
|
|
break;
|
|
}
|
|
|
|
// position the camera
|
|
Point3D target_position = Point3D::Identity;
|
|
|
|
switch(targetMovement)
|
|
{
|
|
case FollowInitialPositionMovementType:
|
|
break;
|
|
case FollowObjectMovementType:
|
|
{
|
|
Check_Object(targetFollowObject);
|
|
Point3D offset = targetOffset.GetCurrentValue();
|
|
|
|
LinearMatrix4D target_object_mat = targetFollowObject->GetLocalToWorld();
|
|
|
|
if (targetOffsetLocal)
|
|
{
|
|
// take into account rotation
|
|
target_position.Multiply(offset, target_object_mat);
|
|
}
|
|
else
|
|
{
|
|
// leave rotation out of it
|
|
Point3D world_point;
|
|
world_point = target_object_mat;
|
|
target_position.Add(offset, world_point);
|
|
}
|
|
}
|
|
break;
|
|
case FollowPathMovementType:
|
|
{
|
|
// set the position..
|
|
|
|
|
|
Point3D offset = targetOffset.GetCurrentValue();
|
|
|
|
|
|
target_position.Add(offset, targetWaypointAnimation.GetCurrentValue());
|
|
|
|
if (targetWaypointAnimation.AnimDone())
|
|
{
|
|
// go to the next waypoint if there is one...
|
|
|
|
++targetCurrentWayPoint;
|
|
|
|
if (targetCurrentWayPoint < targetPath->pathPoints.size())
|
|
{
|
|
Scalar time_to_next_waypoint = 0.0f;
|
|
|
|
Point3D to, from;
|
|
to = targetPath->pathPoints[targetCurrentWayPoint];
|
|
from = targetPath->pathPoints[targetCurrentWayPoint-1];
|
|
|
|
|
|
Vector3D length_vector;
|
|
length_vector.Subtract(to, from);
|
|
|
|
if (!Small_Enough(length_vector) && !Small_Enough(targetPathSpeed))
|
|
{
|
|
Scalar length = length_vector.GetLength();
|
|
time_to_next_waypoint = length / targetPathSpeed;
|
|
}
|
|
|
|
targetWaypointAnimation.Init(from, to, time_to_next_waypoint);
|
|
}
|
|
|
|
}
|
|
}
|
|
break;
|
|
case FollowPositionMovemntType:
|
|
target_position = targetPosition.GetCurrentValue();
|
|
break;
|
|
}
|
|
|
|
|
|
Stuff::Line3D line;
|
|
line.m_length = 100.0f;
|
|
line.m_direction = Vector3D::Down;
|
|
line.m_origin = camera_position;
|
|
line.m_origin.y += 50.0f;
|
|
Stuff::Normal3D normal;
|
|
Entity::CollisionQuery query(&line,&normal,Entity::CanBeWalkedOnFlag,NULL);
|
|
Check_Object(CollisionGrid::Instance);
|
|
if (CollisionGrid::Instance->ProjectLine(&query) == Adept::Map::GetInstance())
|
|
{
|
|
Stuff::Point3D hit_spot;
|
|
line.FindEnd(&hit_spot);
|
|
|
|
if (camera_position.y < hit_spot.y + 1.0f)
|
|
{
|
|
camera_position.y = hit_spot.y + 1.0f;
|
|
}
|
|
}
|
|
|
|
// point the camera
|
|
|
|
if (targetMovement != FollowInitialPositionMovementType)
|
|
{
|
|
if (target_position == camera_position)
|
|
{
|
|
camera_rotation = GetLocalToWorld();
|
|
}
|
|
else
|
|
{
|
|
Stuff::Vector3D vec_to_target;
|
|
vec_to_target.Subtract(target_position, camera_position);
|
|
Stuff::YawPitchRange ypr(vec_to_target);
|
|
|
|
camera_rotation.yaw = ypr.yaw;
|
|
camera_rotation.pitch = ypr.pitch;
|
|
camera_rotation.roll = 0.0f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
camera_rotation = GetLocalToWorld();
|
|
}
|
|
|
|
currentTargetPosition = target_position;
|
|
|
|
if (overridePitchFlag)
|
|
{
|
|
camera_rotation.pitch = cameraPitch.GetCurrentValue();
|
|
}
|
|
|
|
if (overrideYawFlag)
|
|
{
|
|
camera_rotation.yaw = cameraYaw.GetCurrentValue();
|
|
}
|
|
|
|
if (overrideRollFlag)
|
|
{
|
|
camera_rotation.roll = cameraRoll.GetCurrentValue();
|
|
}
|
|
|
|
UpdateFootShaking(camera_rotation);
|
|
|
|
//set the camera position
|
|
|
|
LinearMatrix4D new_position(true);
|
|
new_position.BuildRotation(camera_rotation);
|
|
new_position.BuildTranslation(camera_position);
|
|
|
|
|
|
SetNewLocalToParent(new_position);
|
|
SyncMatrices(true);
|
|
|
|
|
|
|
|
if (activeCamera)
|
|
{
|
|
CameraComponent *cam_comp = VideoRenderer::Instance->GetSceneCamera();
|
|
Check_Object(cam_comp);
|
|
|
|
cam_comp->SetPerspective(
|
|
CameraShipManager::Instance->nearClip,
|
|
CameraShipManager::Instance->farClip,
|
|
cameraFOV.GetCurrentValue(),
|
|
CameraShipManager::Instance->aspectRatio
|
|
);
|
|
|
|
|
|
MWVideoRenderer *vid_rend = Cast_Object(MWVideoRenderer *, VideoRenderer::Instance);
|
|
|
|
|
|
Stuff::RGBColor color;
|
|
|
|
if (fadeState == FadeBlackType)
|
|
{
|
|
color = RGBColor(0.0f, 0.0f, 0.0f);
|
|
}
|
|
else
|
|
{
|
|
color = RGBColor(1.0f, 1.0f, 1.0f);
|
|
}
|
|
|
|
vid_rend->SetFadeLevel(fadeLevel.GetCurrentValue(), color);
|
|
|
|
|
|
}
|
|
|
|
lastParameterization = till;
|
|
initialLocalToParent = GetLocalToParent();
|
|
|
|
BaseClass::PostCollisionExecute(till);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::TurnOn(void)
|
|
{
|
|
Check_Object(this);
|
|
|
|
executionState->RequestState(ExecutionStateEngine::AlwaysExecuteState);
|
|
entityElement->SetNeverCullMode();
|
|
|
|
cameraFOV.Init(CameraShipManager::Instance->horFOV, CameraShipManager::Instance->horFOV, 0.0f);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::TurnOff(void)
|
|
{
|
|
Check_Object(this);
|
|
|
|
executionState->RequestState(ExecutionStateEngine::NeverExecuteState);
|
|
entityElement->SetAlwaysCullMode();
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::CameraFollowObject(Entity *entity)
|
|
{
|
|
Check_Object(this);
|
|
|
|
cameraMovement = FollowObjectMovementType;
|
|
cameraFollowObject = entity;
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::CameraFollowPath(float speed_mps, Path *path)
|
|
{
|
|
Check_Object(this);
|
|
|
|
cameraMovement = FollowPathMovementType;
|
|
|
|
cameraPath = path;
|
|
cameraCurrentWayPoint = 0;
|
|
cameraPathSpeed = speed_mps;
|
|
|
|
|
|
int size = path->pathPoints.size();
|
|
Verify (size>0);
|
|
|
|
Point3D to, from;
|
|
|
|
from = path->pathPoints[0];
|
|
|
|
if (size < 2)
|
|
to = path->pathPoints[0];
|
|
else
|
|
to = path->pathPoints[1];
|
|
|
|
Scalar time_to_next_waypoint = 0.0f;
|
|
|
|
Vector3D length_vector;
|
|
length_vector.Subtract(to, from);
|
|
|
|
if (!Small_Enough(length_vector) && !Small_Enough(speed_mps))
|
|
{
|
|
Scalar length = length_vector.GetLength();
|
|
time_to_next_waypoint = length / speed_mps;
|
|
}
|
|
|
|
cameraCurrentWayPoint = 1;
|
|
cameraWaypointAnimation.Init(from, to, time_to_next_waypoint);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::CameraPosition(float x, float y, float z, float time)
|
|
{
|
|
Check_Object(this);
|
|
|
|
cameraMovement = FollowPositionMovemntType;
|
|
|
|
Point3D current_position;
|
|
current_position = GetLocalToWorld();
|
|
|
|
cameraPosition.Init(current_position, Point3D(x,y,z), time);
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::CameraDetach()
|
|
{
|
|
Check_Object(this);
|
|
|
|
cameraMovement = FollowPositionMovemntType;
|
|
|
|
Stuff::Point3D local_pos;
|
|
local_pos = GetLocalToWorld();
|
|
cameraPosition.Init(local_pos, local_pos, 0.0f);
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::CameraOffset(float x, float y, float z, float time, bool local)
|
|
{
|
|
Check_Object(this);
|
|
|
|
cameraOffset.Init(cameraOffset.GetCurrentValue(), Point3D(x,y,z), time);
|
|
cameraOffsetLocal = local;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::OverrideCameraPitch(float degrees, float time)
|
|
{
|
|
Check_Object(this);
|
|
overridePitchFlag = true;
|
|
YawPitchRoll camera_rotation;
|
|
camera_rotation = GetLocalToWorld();
|
|
cameraPitch.Init(camera_rotation.pitch, degrees, time);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::OverrideCameraRoll(float degrees, float time)
|
|
{
|
|
Check_Object(this);
|
|
overrideRollFlag = true;
|
|
YawPitchRoll camera_rotation;
|
|
camera_rotation = GetLocalToWorld();
|
|
cameraRoll.Init(camera_rotation.roll, degrees, time);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::OverrideCameraYaw(float degrees, float time)
|
|
{
|
|
Check_Object(this);
|
|
overrideYawFlag = true;
|
|
YawPitchRoll camera_rotation;
|
|
camera_rotation = GetLocalToWorld();
|
|
cameraYaw.Init(camera_rotation.yaw, degrees, time);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::ResetCameraOverrides(void)
|
|
{
|
|
Check_Object(this);
|
|
overrideRollFlag = false;
|
|
overrideYawFlag = false;
|
|
overridePitchFlag = false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::TargetFollowObject(Entity *entity)
|
|
{
|
|
Check_Object(this);
|
|
|
|
targetMovement = FollowObjectMovementType;
|
|
targetFollowObject = entity;
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::TargetFollowPath(float speed_mps, Path *path)
|
|
{
|
|
Check_Object(this);
|
|
|
|
targetMovement = FollowPathMovementType;
|
|
|
|
targetPath = path;
|
|
targetCurrentWayPoint = 0;
|
|
targetPathSpeed = speed_mps;
|
|
|
|
int size = path->pathPoints.size();
|
|
Verify (size>0);
|
|
|
|
Point3D to, from;
|
|
|
|
from = path->pathPoints[0];
|
|
|
|
if (size < 2)
|
|
to = path->pathPoints[0];
|
|
else
|
|
to = path->pathPoints[1];
|
|
|
|
Scalar time_to_next_waypoint = 0.0f;
|
|
|
|
Vector3D length_vector;
|
|
length_vector.Subtract(to, from);
|
|
|
|
if (!Small_Enough(length_vector) && !Small_Enough(speed_mps))
|
|
{
|
|
Scalar length = length_vector.GetLength();
|
|
time_to_next_waypoint = length / speed_mps;
|
|
}
|
|
|
|
targetCurrentWayPoint = 1;
|
|
|
|
targetWaypointAnimation.Init(from, to, time_to_next_waypoint);
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::TargetPosition(float x, float y, float z, float time)
|
|
{
|
|
Check_Object(this);
|
|
|
|
targetMovement = FollowPositionMovemntType;
|
|
|
|
Point3D current_position;
|
|
current_position = currentTargetPosition;
|
|
|
|
targetPosition.Init(current_position, Point3D(x,y,z), time);
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::TargetDetach()
|
|
{
|
|
Check_Object(this);
|
|
|
|
|
|
targetMovement = FollowPositionMovemntType;
|
|
|
|
targetPosition.Init(currentTargetPosition, currentTargetPosition, 0.0f);
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::TargetOffset(float x, float y, float z, float time, bool local)
|
|
{
|
|
Check_Object(this);
|
|
targetOffset.Init(targetOffset.GetCurrentValue(), Point3D(x,y,z), time);
|
|
targetOffsetLocal = local;
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::SetCameraFOV(float degrees, float time)
|
|
{
|
|
Check_Object(this);
|
|
|
|
cameraFOV.Init(cameraFOV.GetCurrentValue(), degrees, time);
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::FadeToBlack(float time)
|
|
{
|
|
Check_Object(this);
|
|
fadeState = FadeBlackType;
|
|
fadeLevel.Init(fadeLevel.GetCurrentValue(), 1.0f, time);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::FadeToWhite(float time)
|
|
{
|
|
Check_Object(this);
|
|
fadeState = FadeWhiteType;
|
|
fadeLevel.Init(fadeLevel.GetCurrentValue(), 1.0f, time);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::FadeFromBlack(float time)
|
|
{
|
|
Check_Object(this);
|
|
fadeState = FadeBlackType;
|
|
fadeLevel.Init(fadeLevel.GetCurrentValue(), 0.0f, time);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void CameraShip::FadeFromWhite(float time)
|
|
{
|
|
Check_Object(this);
|
|
fadeState = FadeWhiteType;
|
|
fadeLevel.Init(fadeLevel.GetCurrentValue(), 0.0f, time);
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
CameraShip::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
CameraShip::SetFootShakeParams(Adept::ObjectID id, int meters)
|
|
{
|
|
m_ShakeSource = id;
|
|
m_ShakeDistance = meters;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
CameraShip::UpdateFootShaking(Stuff::YawPitchRoll& camera_rotation)
|
|
{
|
|
if ((m_ShakeSource < 0) ||
|
|
(m_ShakeDistance <= 0) ||
|
|
(Adept::NameTable::GetInstance() == 0))
|
|
{
|
|
return;
|
|
}
|
|
|
|
Adept::Entity* entity = Adept::NameTable::GetInstance()->FindData(m_ShakeSource);
|
|
if ((entity == 0) ||
|
|
(entity->IsDestroyed() == true) ||
|
|
(entity->IsDerivedFrom(Mech::DefaultData) == false))
|
|
{
|
|
return;
|
|
}
|
|
|
|
Mech* mech = Cast_Object(Mech*,entity);
|
|
|
|
Stuff::Scalar time_delta((Stuff::Scalar)gos_GetElapsedTime() - mech->GetLastFootFallTime());
|
|
const Stuff::Scalar min_time_delta(0.4f);
|
|
|
|
Stuff::Scalar distance = GetApproximateLength((Stuff::Point3D)GetLocalToWorld(),
|
|
(Stuff::Point3D)mech->GetLocalToWorld());
|
|
|
|
if ((time_delta > min_time_delta) ||
|
|
(distance > m_ShakeDistance * 2))
|
|
{
|
|
return;
|
|
}
|
|
|
|
Stuff::Scalar magnitude(1 - (time_delta / min_time_delta));
|
|
magnitude *= (m_ShakeDistance / distance);
|
|
magnitude *= 0.005f;
|
|
|
|
camera_rotation.yaw += (Stuff::Random::GetFraction() - 0.5f) * magnitude;
|
|
camera_rotation.pitch += (Stuff::Random::GetFraction() - 0.5f) * magnitude;
|
|
camera_rotation.roll += (Stuff::Random::GetFraction() - 0.5f) * magnitude;
|
|
}
|