SPEC-7531 Change Code/CryEngine to Code/Legacy (#1634)
* git mv Code\CryEngine Code\Legacy * redirecting CMakeLists.txt * fixing uic warning * Some more CryEngine mentions * validation scripts Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#include "CrySystem_precompiled.h"
|
||||
#include "DebugCamera.h"
|
||||
#include "ISystem.h"
|
||||
#include "Cry_Camera.h"
|
||||
#include "IViewSystem.h"
|
||||
|
||||
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
|
||||
#include <AzFramework/Input/Devices/Gamepad/InputDeviceGamepad.h>
|
||||
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
|
||||
|
||||
using namespace AzFramework;
|
||||
|
||||
namespace LegacyViewSystem
|
||||
{
|
||||
const float g_moveScaleIncrement = 0.1f;
|
||||
const float g_moveScaleMin = 0.01f;
|
||||
const float g_moveScaleMax = 10.0f;
|
||||
const float g_mouseMoveScale = 0.1f;
|
||||
const float g_gamepadRotationSpeed = 5.0f;
|
||||
const float g_mouseMaxRotationSpeed = 270.0f;
|
||||
const float g_moveSpeed = 10.0f;
|
||||
const float g_maxPitch = 85.0f;
|
||||
const float g_boostMultiplier = 10.0f;
|
||||
const float g_minRotationSpeed = 15.0f;
|
||||
const float g_maxRotationSpeed = 70.0f;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
DebugCamera::DebugCamera()
|
||||
: m_mouseMoveMode(0)
|
||||
, m_isYInverted(0)
|
||||
, m_cameraMode(DebugCamera::ModeOff)
|
||||
, m_cameraYawInput(0.0f)
|
||||
, m_cameraPitchInput(0.0f)
|
||||
, m_cameraYaw(0.0f)
|
||||
, m_cameraPitch(0.0f)
|
||||
, m_moveInput(ZERO)
|
||||
, m_moveScale(1.0f)
|
||||
, m_oldMoveScale(1.0f)
|
||||
, m_position(ZERO)
|
||||
, m_view(IDENTITY)
|
||||
{
|
||||
InputChannelEventListener::Connect();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
DebugCamera::~DebugCamera()
|
||||
{
|
||||
InputChannelEventListener::Disconnect();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void DebugCamera::OnEnable()
|
||||
{
|
||||
m_position = gEnv->pSystem->GetViewCamera().GetPosition();
|
||||
m_moveInput = Vec3_Zero;
|
||||
|
||||
Ang3 cameraAngles = Ang3(gEnv->pSystem->GetViewCamera().GetMatrix());
|
||||
m_cameraYaw = RAD2DEG(cameraAngles.z);
|
||||
m_cameraPitch = RAD2DEG(cameraAngles.x);
|
||||
m_view = Matrix33(Ang3(DEG2RAD(m_cameraPitch), 0.0f, DEG2RAD(m_cameraYaw)));
|
||||
|
||||
m_cameraYawInput = 0.0f;
|
||||
m_cameraPitchInput = 0.0f;
|
||||
|
||||
m_mouseMoveMode = 0;
|
||||
m_cameraMode = DebugCamera::ModeFree;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void DebugCamera::OnDisable()
|
||||
{
|
||||
m_mouseMoveMode = 0;
|
||||
m_cameraMode = DebugCamera::ModeOff;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void DebugCamera::OnInvertY()
|
||||
{
|
||||
m_isYInverted = !m_isYInverted;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void DebugCamera::OnNextMode()
|
||||
{
|
||||
if (m_cameraMode == DebugCamera::ModeFree)
|
||||
{
|
||||
m_cameraMode = DebugCamera::ModeFixed;
|
||||
}
|
||||
// ...
|
||||
else if (m_cameraMode == DebugCamera::ModeFixed)
|
||||
{
|
||||
// this is the last mode, go to disabled.
|
||||
OnDisable();
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void DebugCamera::Update()
|
||||
{
|
||||
if (m_cameraMode == DebugCamera::ModeOff)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float rotationSpeed = clamp_tpl(m_moveScale, g_minRotationSpeed, g_maxRotationSpeed);
|
||||
UpdateYaw(m_cameraYawInput * rotationSpeed * gEnv->pTimer->GetFrameTime());
|
||||
UpdatePitch(m_cameraPitchInput * rotationSpeed * gEnv->pTimer->GetFrameTime());
|
||||
|
||||
m_view = Matrix33(Ang3(DEG2RAD(m_cameraPitch), 0.0f, DEG2RAD(m_cameraYaw)));
|
||||
UpdatePosition(m_moveInput);
|
||||
|
||||
// update the listener of the active view
|
||||
if (IView* view = gEnv->pSystem->GetIViewSystem()->GetActiveView())
|
||||
{
|
||||
view->UpdateAudioListener(Matrix34(m_view, m_position));
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void DebugCamera::PostUpdate()
|
||||
{
|
||||
if (m_cameraMode == DebugCamera::ModeOff)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CCamera& camera = gEnv->pSystem->GetViewCamera();
|
||||
camera.SetMatrix(Matrix34(m_view, m_position));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
bool DebugCamera::OnInputChannelEventFiltered(const InputChannel& inputChannel)
|
||||
{
|
||||
if (!IsEnabled() || m_cameraMode == DebugCamera::ModeFixed || gEnv->pConsole->IsOpened())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const InputDeviceId& deviceId = inputChannel.GetInputDevice().GetInputDeviceId();
|
||||
const InputChannelId& channelId = inputChannel.GetInputChannelId();
|
||||
const float eventValue = inputChannel.GetValue();
|
||||
if (InputDeviceKeyboard::IsKeyboardDevice(deviceId))
|
||||
{
|
||||
if (channelId == InputDeviceKeyboard::Key::AlphanumericW)
|
||||
{
|
||||
m_moveInput.y = eventValue;
|
||||
}
|
||||
else if (channelId == InputDeviceKeyboard::Key::AlphanumericS)
|
||||
{
|
||||
m_moveInput.y = -eventValue;
|
||||
}
|
||||
else if (channelId == InputDeviceKeyboard::Key::AlphanumericA)
|
||||
{
|
||||
m_moveInput.x = -eventValue;
|
||||
}
|
||||
else if (channelId == InputDeviceKeyboard::Key::AlphanumericD)
|
||||
{
|
||||
m_moveInput.x = eventValue;
|
||||
}
|
||||
else if (channelId == InputDeviceKeyboard::Key::ModifierShiftL)
|
||||
{
|
||||
if (inputChannel.IsStateEnded())
|
||||
{
|
||||
m_moveScale = m_oldMoveScale;
|
||||
}
|
||||
else if (inputChannel.IsStateBegan())
|
||||
{
|
||||
m_oldMoveScale = m_moveScale;
|
||||
m_moveScale = clamp_tpl(m_moveScale * g_boostMultiplier, g_moveScaleMin, g_moveScaleMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (InputDeviceMouse::IsMouseDevice(deviceId))
|
||||
{
|
||||
if (channelId == InputDeviceMouse::Movement::Z)
|
||||
{
|
||||
if (inputChannel.GetValue() > 0)
|
||||
{
|
||||
m_moveScale = clamp_tpl(m_moveScale + g_moveScaleIncrement, g_moveScaleMin, g_moveScaleMax);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_moveScale = clamp_tpl(m_moveScale - g_moveScaleIncrement, g_moveScaleMin, g_moveScaleMax);
|
||||
}
|
||||
}
|
||||
else if (channelId == InputDeviceMouse::Movement::X)
|
||||
{
|
||||
//KC: If both left and right mouse buttons are pressed then use
|
||||
//the mouse movement for horizontal movement.
|
||||
if (2 != m_mouseMoveMode)
|
||||
{
|
||||
UpdateYaw(fsgnf(-eventValue) * clamp_tpl(fabs_tpl(eventValue) * m_moveScale, 0.0f, g_mouseMaxRotationSpeed) * gEnv->pTimer->GetFrameTime());
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdatePosition(Vec3(eventValue * g_mouseMoveScale, 0.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
else if (channelId == InputDeviceMouse::Movement::Y)
|
||||
{
|
||||
//KC: If both left and right mouse buttons are pressed then use
|
||||
//the mouse movement for vertical movement.
|
||||
if (2 != m_mouseMoveMode)
|
||||
{
|
||||
UpdatePitch(fsgnf(-eventValue) * clamp_tpl(fabs_tpl(eventValue) * m_moveScale, 0.0f, g_mouseMaxRotationSpeed) * gEnv->pTimer->GetFrameTime());
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdatePosition(Vec3(0.0f, 0.0f, -eventValue * g_mouseMoveScale));
|
||||
}
|
||||
}
|
||||
else if (channelId == InputDeviceMouse::Button::Left)
|
||||
{
|
||||
if (inputChannel.IsStateEnded())
|
||||
{
|
||||
m_mouseMoveMode = clamp_tpl(m_mouseMoveMode - 1, 0, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mouseMoveMode = clamp_tpl(m_mouseMoveMode + 1, 0, 2);
|
||||
}
|
||||
}
|
||||
else if (channelId == InputDeviceMouse::Button::Right)
|
||||
{
|
||||
if (inputChannel.IsStateEnded())
|
||||
{
|
||||
m_mouseMoveMode = clamp_tpl(m_mouseMoveMode - 1, 0, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mouseMoveMode = clamp_tpl(m_mouseMoveMode + 1, 0, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (InputDeviceGamepad::IsGamepadDevice(deviceId))
|
||||
{
|
||||
if (channelId == InputDeviceGamepad::Button::DU)
|
||||
{
|
||||
m_moveScale = clamp_tpl(m_moveScale + g_moveScaleIncrement, g_moveScaleMin, g_moveScaleMax);
|
||||
}
|
||||
else if (channelId == InputDeviceGamepad::Button::DD)
|
||||
{
|
||||
m_moveScale = clamp_tpl(m_moveScale - g_moveScaleIncrement, g_moveScaleMin, g_moveScaleMax);
|
||||
}
|
||||
else if (channelId == InputDeviceGamepad::Trigger::L2)
|
||||
{
|
||||
m_moveInput.z = -eventValue;
|
||||
}
|
||||
else if (channelId == InputDeviceGamepad::Trigger::R2)
|
||||
{
|
||||
m_moveInput.z = eventValue;
|
||||
}
|
||||
else if (channelId == InputDeviceGamepad::ThumbStickAxis1D::LX)
|
||||
{
|
||||
m_moveInput.x = eventValue;
|
||||
}
|
||||
else if (channelId == InputDeviceGamepad::ThumbStickAxis1D::LY)
|
||||
{
|
||||
m_moveInput.y = eventValue;
|
||||
}
|
||||
else if (channelId == InputDeviceGamepad::ThumbStickAxis1D::RX)
|
||||
{
|
||||
m_cameraYawInput = -eventValue * g_gamepadRotationSpeed;
|
||||
}
|
||||
else if (channelId == InputDeviceGamepad::ThumbStickAxis1D::RY)
|
||||
{
|
||||
m_cameraPitchInput = eventValue * g_gamepadRotationSpeed;
|
||||
}
|
||||
//KC: Use the shoulder buttons to temporarily boost or reduce the scale.
|
||||
else if (channelId == InputDeviceGamepad::Button::L1)
|
||||
{
|
||||
if (inputChannel.IsStateEnded())
|
||||
{
|
||||
m_moveScale = m_oldMoveScale;
|
||||
}
|
||||
else if (inputChannel.IsStateBegan())
|
||||
{
|
||||
m_oldMoveScale = m_moveScale;
|
||||
m_moveScale = clamp_tpl(m_moveScale / g_boostMultiplier, g_moveScaleMin, g_moveScaleMax);
|
||||
}
|
||||
}
|
||||
else if (channelId == InputDeviceGamepad::Button::R1)
|
||||
{
|
||||
if (inputChannel.IsStateEnded())
|
||||
{
|
||||
m_moveScale = m_oldMoveScale;
|
||||
}
|
||||
else if (inputChannel.IsStateBegan())
|
||||
{
|
||||
m_oldMoveScale = m_moveScale;
|
||||
m_moveScale = clamp_tpl(m_moveScale * g_boostMultiplier, g_moveScaleMin, g_moveScaleMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void DebugCamera::UpdatePitch(float amount)
|
||||
{
|
||||
if (m_isYInverted)
|
||||
{
|
||||
amount = -amount;
|
||||
}
|
||||
|
||||
m_cameraPitch += amount;
|
||||
m_cameraPitch = clamp_tpl(m_cameraPitch, -g_maxPitch, g_maxPitch);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void DebugCamera::UpdateYaw(float amount)
|
||||
{
|
||||
m_cameraYaw += amount;
|
||||
if (m_cameraYaw < 0.0f)
|
||||
{
|
||||
m_cameraYaw += 360.0f;
|
||||
}
|
||||
else if (m_cameraYaw >= 360.0f)
|
||||
{
|
||||
m_cameraYaw -= 360.0f;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void DebugCamera::UpdatePosition(const Vec3& amount)
|
||||
{
|
||||
Vec3 diff = amount * g_moveSpeed * m_moveScale * gEnv->pTimer->GetFrameTime();
|
||||
MovePosition(diff);
|
||||
}
|
||||
|
||||
void DebugCamera::MovePosition(const Vec3& offset)
|
||||
{
|
||||
m_position += m_view.GetColumn0() * offset.x;
|
||||
m_position += m_view.GetColumn1() * offset.y;
|
||||
m_position += m_view.GetColumn2() * offset.z;
|
||||
}
|
||||
|
||||
} // namespace LegacyViewSystem
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzFramework/Input/Events/InputChannelEventListener.h>
|
||||
|
||||
namespace LegacyViewSystem
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class DebugCamera
|
||||
: public AzFramework::InputChannelEventListener
|
||||
{
|
||||
public:
|
||||
enum Mode
|
||||
{
|
||||
ModeOff, // no debug cam
|
||||
ModeFree, // free-fly
|
||||
ModeFixed, // fixed cam, control goes back to game
|
||||
};
|
||||
|
||||
DebugCamera();
|
||||
~DebugCamera() override;
|
||||
|
||||
void Update();
|
||||
void PostUpdate();
|
||||
bool IsEnabled();
|
||||
bool IsFixed();
|
||||
bool IsFree();
|
||||
|
||||
// AzFramework::InputChannelEventListener
|
||||
bool OnInputChannelEventFiltered(const AzFramework::InputChannel& inputChannel) override;
|
||||
|
||||
void OnEnable();
|
||||
void OnDisable();
|
||||
void OnInvertY();
|
||||
void OnNextMode();
|
||||
void UpdatePitch(float amount);
|
||||
void UpdateYaw(float amount);
|
||||
void UpdatePosition(const Vec3& amount);
|
||||
void MovePosition(const Vec3& offset);
|
||||
|
||||
protected:
|
||||
int m_mouseMoveMode;
|
||||
int m_isYInverted;
|
||||
int m_cameraMode;
|
||||
float m_cameraYawInput;
|
||||
float m_cameraPitchInput;
|
||||
float m_cameraYaw;
|
||||
float m_cameraPitch;
|
||||
Vec3 m_moveInput;
|
||||
|
||||
float m_moveScale;
|
||||
float m_oldMoveScale;
|
||||
Vec3 m_position;
|
||||
Matrix33 m_view;
|
||||
};
|
||||
|
||||
|
||||
inline bool DebugCamera::IsEnabled()
|
||||
{
|
||||
return m_cameraMode != DebugCamera::ModeOff;
|
||||
}
|
||||
|
||||
inline bool DebugCamera::IsFixed()
|
||||
{
|
||||
return m_cameraMode == DebugCamera::ModeFixed;
|
||||
}
|
||||
|
||||
inline bool DebugCamera::IsFree()
|
||||
{
|
||||
return m_cameraMode == DebugCamera::ModeFree;
|
||||
}
|
||||
|
||||
} // namespace LegacyViewSystem
|
||||
@@ -0,0 +1,635 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "CrySystem_precompiled.h"
|
||||
|
||||
#include <Cry_Camera.h>
|
||||
#include <HMDBus.h>
|
||||
#include "View.h"
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <IStereoRenderer.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <Random.h>
|
||||
#include <MathConversion.h>
|
||||
|
||||
namespace LegacyViewSystem
|
||||
{
|
||||
|
||||
static ICVar* pCamShakeMult = 0;
|
||||
static ICVar* pHmdReferencePoint = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CView::CView(ISystem* pSystem)
|
||||
: m_pSystem(pSystem)
|
||||
, m_linkedTo(0)
|
||||
, m_frameAdditiveAngles(0.0f, 0.0f, 0.0f)
|
||||
, m_scale(1.0f)
|
||||
, m_zoomedScale(1.0f)
|
||||
{
|
||||
if (!pCamShakeMult)
|
||||
{
|
||||
pCamShakeMult = gEnv->pConsole->GetCVar("c_shakeMult");
|
||||
}
|
||||
if (!pHmdReferencePoint)
|
||||
{
|
||||
pHmdReferencePoint = gEnv->pConsole->GetCVar("hmd_reference_point");
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CView::~CView()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void CView::Release()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CView::Update(float frameTime, bool isActive)
|
||||
{
|
||||
//FIXME:some cameras may need to be updated always
|
||||
if (!isActive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_azEntity)
|
||||
{
|
||||
m_viewParams.SaveLast();
|
||||
|
||||
CCamera* pSysCam = &m_pSystem->GetViewCamera();
|
||||
|
||||
//process screen shaking
|
||||
ProcessShaking(frameTime);
|
||||
|
||||
//FIXME:to let the updateView implementation use the correct shakeVector
|
||||
m_viewParams.currentShakeShift = m_viewParams.rotation * m_viewParams.currentShakeShift;
|
||||
|
||||
m_viewParams.frameTime = frameTime;
|
||||
//update view position/rotation
|
||||
if (m_azEntity != nullptr)
|
||||
{
|
||||
auto entityTransform = m_azEntity->GetTransform();
|
||||
if (entityTransform != nullptr)
|
||||
{
|
||||
AZ::Transform transform = entityTransform->GetWorldTM();
|
||||
m_viewParams.position = AZVec3ToLYVec3(transform.GetTranslation());
|
||||
m_viewParams.rotation = AZQuaternionToLYQuaternion(transform.GetRotation());
|
||||
}
|
||||
}
|
||||
|
||||
ApplyFrameAdditiveAngles(m_viewParams.rotation);
|
||||
|
||||
const float fNearZ = gEnv->pSystem->GetIViewSystem()->GetDefaultZNear();
|
||||
|
||||
//see if the view have to use a custom near clipping plane
|
||||
const float nearPlane = (m_viewParams.nearplane >= CAMERA_MIN_NEAR) ? (m_viewParams.nearplane) : fNearZ;
|
||||
const float farPlane = (m_viewParams.farplane > 0.f) ? m_viewParams.farplane : DEFAULT_FAR;
|
||||
float fov = (m_viewParams.fov < 0.001f) ? DEFAULT_FOV : m_viewParams.fov;
|
||||
|
||||
m_camera.SetFrustum(pSysCam->GetViewSurfaceX(), pSysCam->GetViewSurfaceZ(), fov, nearPlane, farPlane, pSysCam->GetPixelAspectRatio());
|
||||
|
||||
//apply shake & set the view matrix
|
||||
m_viewParams.rotation *= m_viewParams.currentShakeQuat;
|
||||
m_viewParams.rotation.NormalizeSafe();
|
||||
m_viewParams.position += m_viewParams.currentShakeShift;
|
||||
|
||||
// Blending between cameras needs to happen after Camera space rendering calculations have been applied
|
||||
// so that the m_viewParams.position is in World Space again
|
||||
m_viewParams.UpdateBlending(frameTime);
|
||||
|
||||
// [VR] specific
|
||||
// Add HMD's pose tracking on top of current camera pose
|
||||
// Each game-title can decide whether to keep this functionality here or (most likely)
|
||||
// move it somewhere else.
|
||||
|
||||
Quat q = m_viewParams.rotation;
|
||||
Vec3 pos = m_viewParams.position;
|
||||
Vec3 p = Vec3(ZERO);
|
||||
|
||||
Matrix34 viewMtx(q);
|
||||
viewMtx.SetTranslation(pos + p);
|
||||
m_camera.SetMatrix(viewMtx);
|
||||
|
||||
m_camera.SetEntityRotation(m_viewParams.rotation);
|
||||
m_camera.SetEntityPos(pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_linkedTo = AZ::EntityId(0);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void CView::ApplyFrameAdditiveAngles(Quat& cameraOrientation)
|
||||
{
|
||||
if ((m_frameAdditiveAngles.x != 0.f) || (m_frameAdditiveAngles.y != 0.f) || (m_frameAdditiveAngles.z != 0.f))
|
||||
{
|
||||
Ang3 cameraAngles(cameraOrientation);
|
||||
cameraAngles += m_frameAdditiveAngles;
|
||||
|
||||
cameraOrientation.SetRotationXYZ(cameraAngles);
|
||||
|
||||
m_frameAdditiveAngles.Set(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CView::SetViewShake(Ang3 shakeAngle, Vec3 shakeShift, float duration, float frequency, float randomness, int shakeID, bool bFlipVec, bool bUpdateOnly, bool bGroundOnly)
|
||||
{
|
||||
SShakeParams params;
|
||||
params.shakeAngle = shakeAngle;
|
||||
params.shakeShift = shakeShift;
|
||||
params.frequency = frequency;
|
||||
params.randomness = randomness;
|
||||
params.shakeID = shakeID;
|
||||
params.bFlipVec = bFlipVec;
|
||||
params.bUpdateOnly = bUpdateOnly;
|
||||
params.bGroundOnly = bGroundOnly;
|
||||
params.fadeInDuration = 0; //
|
||||
params.fadeOutDuration = duration; // originally it was faded out from start. that is why the values are set this way here, to preserve compatibility.
|
||||
params.sustainDuration = 0; //
|
||||
|
||||
SetViewShakeEx(params);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CView::SetViewShakeEx(const SShakeParams& params)
|
||||
{
|
||||
float shakeMult = GetScale();
|
||||
if (shakeMult < 0.001f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int shakes(m_shakes.size());
|
||||
SShake* pSetShake(NULL);
|
||||
|
||||
for (int i = 0; i < shakes; ++i)
|
||||
{
|
||||
SShake* pShake = &m_shakes[i];
|
||||
if (pShake->ID == params.shakeID)
|
||||
{
|
||||
pSetShake = pShake;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pSetShake)
|
||||
{
|
||||
m_shakes.push_back(SShake(params.shakeID));
|
||||
pSetShake = &m_shakes.back();
|
||||
}
|
||||
|
||||
if (pSetShake)
|
||||
{
|
||||
// this can be set dynamically
|
||||
pSetShake->frequency = max(0.00001f, params.frequency);
|
||||
|
||||
// the following are set on a 'new' shake as well
|
||||
if (params.bUpdateOnly == false)
|
||||
{
|
||||
pSetShake->amount = params.shakeAngle * shakeMult;
|
||||
pSetShake->amountVector = params.shakeShift * shakeMult;
|
||||
pSetShake->randomness = params.randomness;
|
||||
pSetShake->doFlip = params.bFlipVec;
|
||||
pSetShake->groundOnly = params.bGroundOnly;
|
||||
pSetShake->isSmooth = params.isSmooth;
|
||||
pSetShake->permanent = params.bPermanent;
|
||||
pSetShake->fadeInDuration = params.fadeInDuration;
|
||||
pSetShake->sustainDuration = params.sustainDuration;
|
||||
pSetShake->fadeOutDuration = params.fadeOutDuration;
|
||||
pSetShake->timeDone = 0;
|
||||
pSetShake->updating = true;
|
||||
pSetShake->interrupted = false;
|
||||
pSetShake->goalShake = Quat(ZERO);
|
||||
pSetShake->goalShakeSpeed = Quat(ZERO);
|
||||
pSetShake->goalShakeVector = Vec3(ZERO);
|
||||
pSetShake->goalShakeVectorSpeed = Vec3(ZERO);
|
||||
pSetShake->nextShake = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CView::SetScale(const float scale)
|
||||
{
|
||||
CRY_ASSERT_MESSAGE(scale == 1.0f || m_scale == 1.0f, "Attempting to CView::SetScale but has already been set!");
|
||||
m_scale = scale;
|
||||
}
|
||||
|
||||
void CView::SetZoomedScale(const float scale)
|
||||
{
|
||||
CRY_ASSERT_MESSAGE(scale == 1.0f || m_zoomedScale == 1.0f, "Attempting to CView::SetZoomedScale but has already been set!");
|
||||
m_zoomedScale = scale;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
const float CView::GetScale()
|
||||
{
|
||||
float shakeMult(pCamShakeMult->GetFVal());
|
||||
return m_scale * shakeMult * m_zoomedScale;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CView::ProcessShaking(float frameTime)
|
||||
{
|
||||
m_viewParams.currentShakeQuat.SetIdentity();
|
||||
m_viewParams.currentShakeShift.zero();
|
||||
m_viewParams.shakingRatio = 0;
|
||||
m_viewParams.groundOnly = false;
|
||||
|
||||
int shakes(m_shakes.size());
|
||||
for (int i = 0; i < shakes; ++i)
|
||||
{
|
||||
ProcessShake(&m_shakes[i], frameTime);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CView::ProcessShake(SShake* pShake, float frameTime)
|
||||
{
|
||||
if (!pShake->updating)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pShake->timeDone += frameTime;
|
||||
|
||||
if (pShake->isSmooth)
|
||||
{
|
||||
ProcessShakeSmooth(pShake, frameTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessShakeNormal(pShake, frameTime);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CView::ProcessShakeNormal(SShake* pShake, float frameTime)
|
||||
{
|
||||
float endSustain = pShake->fadeInDuration + pShake->sustainDuration;
|
||||
float totalDuration = endSustain + pShake->fadeOutDuration;
|
||||
|
||||
bool finalDamping = (!pShake->permanent && pShake->timeDone > totalDuration) || (pShake->interrupted && pShake->ratio < 0.05f);
|
||||
|
||||
if (finalDamping)
|
||||
{
|
||||
ProcessShakeNormal_FinalDamping(pShake, frameTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessShakeNormal_CalcRatio(pShake, frameTime, endSustain);
|
||||
ProcessShakeNormal_DoShaking(pShake, frameTime);
|
||||
|
||||
//for the global shaking ratio keep the biggest
|
||||
if (pShake->groundOnly)
|
||||
{
|
||||
m_viewParams.groundOnly = true;
|
||||
}
|
||||
m_viewParams.shakingRatio = max(m_viewParams.shakingRatio, pShake->ratio);
|
||||
m_viewParams.currentShakeQuat *= pShake->shakeQuat;
|
||||
m_viewParams.currentShakeShift += pShake->shakeVector;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CView::ProcessShakeSmooth(SShake* pShake, float frameTime)
|
||||
{
|
||||
assert(pShake->timeDone >= 0);
|
||||
|
||||
float endTimeFadeIn = pShake->fadeInDuration;
|
||||
float endTimeSustain = pShake->sustainDuration + endTimeFadeIn;
|
||||
float totalTime = endTimeSustain + pShake->fadeOutDuration;
|
||||
|
||||
if (pShake->interrupted && endTimeFadeIn <= pShake->timeDone && pShake->timeDone < endTimeSustain)
|
||||
{
|
||||
pShake->timeDone = endTimeSustain;
|
||||
}
|
||||
|
||||
float damping = 1.f;
|
||||
if (pShake->timeDone < endTimeFadeIn)
|
||||
{
|
||||
damping = pShake->timeDone / endTimeFadeIn;
|
||||
}
|
||||
else if (endTimeSustain < pShake->timeDone && pShake->timeDone < totalTime)
|
||||
{
|
||||
damping = (totalTime - pShake->timeDone) / (totalTime - endTimeSustain);
|
||||
}
|
||||
else if (totalTime <= pShake->timeDone)
|
||||
{
|
||||
pShake->shakeQuat.SetIdentity();
|
||||
pShake->shakeVector.zero();
|
||||
pShake->ratio = 0.0f;
|
||||
pShake->nextShake = 0.0f;
|
||||
pShake->flip = false;
|
||||
pShake->updating = false;
|
||||
return;
|
||||
}
|
||||
|
||||
ProcessShakeSmooth_DoShaking(pShake, frameTime);
|
||||
|
||||
if (pShake->groundOnly)
|
||||
{
|
||||
m_viewParams.groundOnly = true;
|
||||
}
|
||||
pShake->ratio = (3.f - 2.f * damping) * damping * damping; // smooth ration change
|
||||
m_viewParams.shakingRatio = max(m_viewParams.shakingRatio, pShake->ratio);
|
||||
m_viewParams.currentShakeQuat *= Quat::CreateSlerp(IDENTITY, pShake->shakeQuat, pShake->ratio);
|
||||
m_viewParams.currentShakeShift += Vec3::CreateLerp(ZERO, pShake->shakeVector, pShake->ratio);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CView::GetRandomQuat(Quat& quat, SShake* pShake)
|
||||
{
|
||||
quat.SetRotationXYZ(pShake->amount);
|
||||
float randomAmt(pShake->randomness);
|
||||
float len(fabs(pShake->amount.x) + fabs(pShake->amount.y) + fabs(pShake->amount.z));
|
||||
len /= 3.f;
|
||||
float r = len * randomAmt;
|
||||
quat *= Quat::CreateRotationXYZ(Ang3(cry_random(-r, r), cry_random(-r, r), cry_random(-r, r)));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CView::GetRandomVector(Vec3& vec, SShake* pShake)
|
||||
{
|
||||
vec = pShake->amountVector;
|
||||
float randomAmt(pShake->randomness);
|
||||
float len = fabs(pShake->amountVector.x) + fabs(pShake->amountVector.y) + fabs(pShake->amountVector.z);
|
||||
len /= 3.f;
|
||||
float r = len * randomAmt;
|
||||
vec += Vec3(cry_random(-r, r), cry_random(-r, r), cry_random(-r, r));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CView::CubeInterpolateQuat(float t, SShake* pShake)
|
||||
{
|
||||
Quat p0 = pShake->startShake;
|
||||
Quat p1 = pShake->goalShake;
|
||||
Quat v0 = pShake->startShakeSpeed * 0.5f;
|
||||
Quat v1 = pShake->goalShakeSpeed * 0.5f;
|
||||
|
||||
pShake->shakeQuat = (((p0 * 2.f + p1 * -2.f + v0 + v1) * t
|
||||
+ (p0 * -3.f + p1 * 3.f + v0 * -2.f - v1)) * t
|
||||
+ (v0)) * t
|
||||
+ p0;
|
||||
|
||||
pShake->shakeQuat.Normalize();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CView::CubeInterpolateVector(float t, SShake* pShake)
|
||||
{
|
||||
Vec3 p0 = pShake->startShakeVector;
|
||||
Vec3 p1 = pShake->goalShakeVector;
|
||||
Vec3 v0 = pShake->startShakeVectorSpeed * 0.8f;
|
||||
Vec3 v1 = pShake->goalShakeVectorSpeed * 0.8f;
|
||||
|
||||
pShake->shakeVector = (((p0 * 2.f + p1 * -2.f + v0 + v1) * t
|
||||
+ (p0 * -3.f + p1 * 3.f + v0 * -2.f - v1)) * t
|
||||
+ (v0)) * t
|
||||
+ p0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CView::ProcessShakeSmooth_DoShaking(SShake* pShake, float frameTime)
|
||||
{
|
||||
if (pShake->nextShake <= 0.0f)
|
||||
{
|
||||
pShake->nextShake = pShake->frequency;
|
||||
|
||||
pShake->startShake = pShake->goalShake;
|
||||
pShake->startShakeSpeed = pShake->goalShakeSpeed;
|
||||
pShake->startShakeVector = pShake->goalShakeVector;
|
||||
pShake->startShakeVectorSpeed = pShake->goalShakeVectorSpeed;
|
||||
|
||||
GetRandomQuat(pShake->goalShake, pShake);
|
||||
GetRandomQuat(pShake->goalShakeSpeed, pShake);
|
||||
GetRandomVector(pShake->goalShakeVector, pShake);
|
||||
GetRandomVector(pShake->goalShakeVectorSpeed, pShake);
|
||||
|
||||
if (pShake->flip)
|
||||
{
|
||||
pShake->goalShake.Invert();
|
||||
pShake->goalShakeSpeed.Invert();
|
||||
pShake->goalShakeVector = -pShake->goalShakeVector;
|
||||
pShake->goalShakeVectorSpeed = -pShake->goalShakeVectorSpeed;
|
||||
}
|
||||
|
||||
if (pShake->doFlip)
|
||||
{
|
||||
pShake->flip = !pShake->flip;
|
||||
}
|
||||
}
|
||||
|
||||
pShake->nextShake -= frameTime;
|
||||
|
||||
float t = (pShake->frequency - pShake->nextShake) / pShake->frequency;
|
||||
CubeInterpolateQuat(t, pShake);
|
||||
CubeInterpolateVector(t, pShake);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CView::ProcessShakeNormal_FinalDamping(SShake* pShake, float frameTime)
|
||||
{
|
||||
pShake->shakeQuat = Quat::CreateSlerp(pShake->shakeQuat, IDENTITY, frameTime * 5.0f);
|
||||
m_viewParams.currentShakeQuat *= pShake->shakeQuat;
|
||||
|
||||
pShake->shakeVector = Vec3::CreateLerp(pShake->shakeVector, ZERO, frameTime * 5.0f);
|
||||
m_viewParams.currentShakeShift += pShake->shakeVector;
|
||||
|
||||
float svlen2(pShake->shakeVector.len2());
|
||||
bool quatIsIdentity(Quat::IsEquivalent(IDENTITY, pShake->shakeQuat, 0.0001f));
|
||||
|
||||
if (quatIsIdentity && svlen2 < 0.01f)
|
||||
{
|
||||
pShake->shakeQuat.SetIdentity();
|
||||
pShake->shakeVector.zero();
|
||||
|
||||
pShake->ratio = 0.0f;
|
||||
pShake->nextShake = 0.0f;
|
||||
pShake->flip = false;
|
||||
|
||||
pShake->updating = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// "ratio" is the amplitude of the shaking
|
||||
void CView::ProcessShakeNormal_CalcRatio(SShake* pShake, float frameTime, float endSustain)
|
||||
{
|
||||
const float FADEOUT_TIME_WHEN_INTERRUPTED = 0.5f;
|
||||
|
||||
if (pShake->interrupted)
|
||||
{
|
||||
pShake->ratio = max(0.f, pShake->ratio - (frameTime / FADEOUT_TIME_WHEN_INTERRUPTED)); // fadeout after interrupted
|
||||
}
|
||||
else
|
||||
if (pShake->timeDone >= endSustain && pShake->fadeOutDuration > 0)
|
||||
{
|
||||
float timeFading = pShake->timeDone - endSustain;
|
||||
pShake->ratio = clamp_tpl(1.f - timeFading / pShake->fadeOutDuration, 0.f, 1.f); // fadeOut
|
||||
}
|
||||
else
|
||||
if (pShake->timeDone >= pShake->fadeInDuration)
|
||||
{
|
||||
pShake->ratio = 1.f; // sustain
|
||||
}
|
||||
else
|
||||
{
|
||||
pShake->ratio = min(1.f, pShake->timeDone / pShake->fadeInDuration); // fadeIn
|
||||
}
|
||||
|
||||
if (pShake->permanent && pShake->timeDone >= pShake->fadeInDuration && !pShake->interrupted)
|
||||
{
|
||||
pShake->ratio = 1.f; // permanent standing
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CView::ProcessShakeNormal_DoShaking(SShake* pShake, float frameTime)
|
||||
{
|
||||
float t;
|
||||
if (pShake->nextShake <= 0.0f)
|
||||
{
|
||||
//angular
|
||||
pShake->goalShake.SetRotationXYZ(pShake->amount);
|
||||
if (pShake->flip)
|
||||
{
|
||||
pShake->goalShake.Invert();
|
||||
}
|
||||
|
||||
//translational
|
||||
pShake->goalShakeVector = pShake->amountVector;
|
||||
if (pShake->flip)
|
||||
{
|
||||
pShake->goalShakeVector = -pShake->goalShakeVector;
|
||||
}
|
||||
|
||||
if (pShake->doFlip)
|
||||
{
|
||||
pShake->flip = !pShake->flip;
|
||||
}
|
||||
|
||||
//randomize it a little
|
||||
float randomAmt(pShake->randomness);
|
||||
float len(fabs(pShake->amount.x) + fabs(pShake->amount.y) + fabs(pShake->amount.z));
|
||||
len /= 3.0f;
|
||||
float r = len * randomAmt;
|
||||
pShake->goalShake *= Quat::CreateRotationXYZ(Ang3(cry_random(-r, r), cry_random(-r, r), cry_random(-r, r)));
|
||||
|
||||
//translational randomization
|
||||
len = fabs(pShake->amountVector.x) + fabs(pShake->amountVector.y) + fabs(pShake->amountVector.z);
|
||||
len /= 3.0f;
|
||||
r = len * randomAmt;
|
||||
pShake->goalShakeVector += Vec3(cry_random(-r, r), cry_random(-r, r), cry_random(-r, r));
|
||||
|
||||
//damp & bounce it in a non linear fashion
|
||||
t = 1.0f - (pShake->ratio * pShake->ratio);
|
||||
pShake->goalShake = Quat::CreateSlerp(pShake->goalShake, IDENTITY, t);
|
||||
pShake->goalShakeVector = Vec3::CreateLerp(pShake->goalShakeVector, ZERO, t);
|
||||
|
||||
pShake->nextShake = pShake->frequency;
|
||||
}
|
||||
|
||||
pShake->nextShake = max(0.0f, pShake->nextShake - frameTime);
|
||||
|
||||
t = min(1.0f, frameTime * (1.0f / pShake->frequency));
|
||||
pShake->shakeQuat = Quat::CreateSlerp(pShake->shakeQuat, pShake->goalShake, t);
|
||||
pShake->shakeQuat.Normalize();
|
||||
pShake->shakeVector = Vec3::CreateLerp(pShake->shakeVector, pShake->goalShakeVector, t);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CView::StopShake(int shakeID)
|
||||
{
|
||||
uint32 num = m_shakes.size();
|
||||
for (uint32 i = 0; i < num; ++i)
|
||||
{
|
||||
if (m_shakes[i].ID == shakeID && m_shakes[i].updating)
|
||||
{
|
||||
m_shakes[i].interrupted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CView::ResetShaking()
|
||||
{
|
||||
// disable shakes
|
||||
std::vector<SShake>::iterator iter = m_shakes.begin();
|
||||
std::vector<SShake>::iterator iterEnd = m_shakes.end();
|
||||
while (iter != iterEnd)
|
||||
{
|
||||
SShake& shake = *iter;
|
||||
shake.updating = false;
|
||||
shake.timeDone = 0;
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CView::LinkTo(AZ::Entity* follow)
|
||||
{
|
||||
CRY_ASSERT(follow);
|
||||
m_azEntity = follow;
|
||||
m_linkedTo = follow->GetId();
|
||||
m_viewParams.targetPos = Vec3();// This should be quickly overwritten by the camera's acutal position from its matrix
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CView::Unlink()
|
||||
{
|
||||
m_azEntity = nullptr;
|
||||
m_linkedTo.SetInvalid();
|
||||
m_viewParams.targetPos = Vec3();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CView::SetFrameAdditiveCameraAngles(const Ang3& addFrameAngles)
|
||||
{
|
||||
m_frameAdditiveAngles = addFrameAngles;
|
||||
}
|
||||
|
||||
void CView::GetMemoryUsage(ICrySizer* s) const
|
||||
{
|
||||
s->AddObject(this, sizeof(*this));
|
||||
s->AddObject(m_shakes);
|
||||
}
|
||||
|
||||
void CView::Serialize(TSerialize ser)
|
||||
{
|
||||
if (ser.IsReading())
|
||||
{
|
||||
ResetShaking();
|
||||
}
|
||||
}
|
||||
|
||||
void CView::PostSerialize()
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CView::UpdateAudioListener([[maybe_unused]] Matrix34 const& rMatrix)
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CView::SetActive([[maybe_unused]] bool const bActive)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace LegacyViewSystem
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// Description : View System interfaces.
|
||||
|
||||
# pragma once
|
||||
|
||||
#include "IViewSystem.h"
|
||||
#include <Cry_Camera.h>
|
||||
|
||||
class CGameObject;
|
||||
|
||||
namespace LegacyViewSystem
|
||||
{
|
||||
|
||||
class CView
|
||||
: public IView
|
||||
{
|
||||
public:
|
||||
|
||||
CView(ISystem* pSystem);
|
||||
virtual ~CView();
|
||||
|
||||
//shaking
|
||||
struct SShake
|
||||
{
|
||||
bool updating;
|
||||
bool flip;
|
||||
bool doFlip;
|
||||
bool groundOnly;
|
||||
bool permanent;
|
||||
bool interrupted; // when forcefully stopped
|
||||
bool isSmooth;
|
||||
|
||||
int ID;
|
||||
|
||||
float nextShake;
|
||||
float timeDone;
|
||||
float sustainDuration;
|
||||
float fadeInDuration;
|
||||
float fadeOutDuration;
|
||||
|
||||
float frequency;
|
||||
float ratio;
|
||||
|
||||
float randomness;
|
||||
|
||||
Quat startShake;
|
||||
Quat startShakeSpeed;
|
||||
Vec3 startShakeVector;
|
||||
Vec3 startShakeVectorSpeed;
|
||||
|
||||
Quat goalShake;
|
||||
Quat goalShakeSpeed;
|
||||
Vec3 goalShakeVector;
|
||||
Vec3 goalShakeVectorSpeed;
|
||||
|
||||
Ang3 amount;
|
||||
Vec3 amountVector;
|
||||
|
||||
Quat shakeQuat;
|
||||
Vec3 shakeVector;
|
||||
|
||||
SShake(int shakeID)
|
||||
{
|
||||
memset(this, 0, sizeof(SShake));
|
||||
|
||||
startShake.SetIdentity();
|
||||
startShakeSpeed.SetIdentity();
|
||||
goalShake.SetIdentity();
|
||||
shakeQuat.SetIdentity();
|
||||
|
||||
randomness = 0.5f;
|
||||
|
||||
ID = shakeID;
|
||||
}
|
||||
|
||||
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const { /*nothing*/}
|
||||
};
|
||||
|
||||
|
||||
// IView
|
||||
virtual void Release();
|
||||
virtual void Update(float frameTime, bool isActive);
|
||||
virtual void ProcessShaking(float frameTime);
|
||||
virtual void ProcessShake(SShake* pShake, float frameTime);
|
||||
virtual void ResetShaking();
|
||||
virtual void ResetBlending() { m_viewParams.ResetBlending(); }
|
||||
virtual void LinkTo(AZ::Entity* follow);
|
||||
virtual void Unlink();
|
||||
virtual AZ::EntityId GetLinkedId() {return m_linkedTo; };
|
||||
virtual void SetCurrentParams(SViewParams& params) { m_viewParams = params; };
|
||||
virtual const SViewParams* GetCurrentParams() {return &m_viewParams; }
|
||||
virtual void SetViewShake(Ang3 shakeAngle, Vec3 shakeShift, float duration, float frequency, float randomness, int shakeID, bool bFlipVec = true, bool bUpdateOnly = false, bool bGroundOnly = false);
|
||||
virtual void SetViewShakeEx(const SShakeParams& params);
|
||||
virtual void StopShake(int shakeID);
|
||||
virtual void SetFrameAdditiveCameraAngles(const Ang3& addFrameAngles);
|
||||
virtual void SetScale(const float scale);
|
||||
virtual void SetZoomedScale(const float scale);
|
||||
virtual void SetActive(const bool bActive);
|
||||
// ~IView
|
||||
|
||||
void Serialize(TSerialize ser) override;
|
||||
void PostSerialize() override;
|
||||
CCamera& GetCamera() override { return m_camera; }
|
||||
const CCamera& GetCamera() const override { return m_camera; }
|
||||
void UpdateAudioListener(const Matrix34& rMatrix) override;
|
||||
|
||||
void GetMemoryUsage(ICrySizer* s) const;
|
||||
|
||||
protected:
|
||||
|
||||
void ProcessShakeNormal(SShake* pShake, float frameTime);
|
||||
void ProcessShakeNormal_FinalDamping(SShake* pShake, float frameTime);
|
||||
void ProcessShakeNormal_CalcRatio(SShake* pShake, float frameTime, float endSustain);
|
||||
void ProcessShakeNormal_DoShaking(SShake* pShake, float frameTime);
|
||||
|
||||
void ProcessShakeSmooth(SShake* pShake, float frameTime);
|
||||
void ProcessShakeSmooth_DoShaking(SShake* pShake, float frameTime);
|
||||
|
||||
void ApplyFrameAdditiveAngles(Quat& cameraOrientation);
|
||||
|
||||
const float GetScale();
|
||||
|
||||
private:
|
||||
|
||||
void GetRandomQuat(Quat& quat, SShake* pShake);
|
||||
void GetRandomVector(Vec3& vec3, SShake* pShake);
|
||||
void CubeInterpolateQuat(float t, SShake* pShake);
|
||||
void CubeInterpolateVector(float t, SShake* pShake);
|
||||
|
||||
protected:
|
||||
|
||||
bool m_active;
|
||||
AZ::EntityId m_linkedTo;
|
||||
AZ::Entity* m_azEntity = nullptr;
|
||||
|
||||
SViewParams m_viewParams;
|
||||
CCamera m_camera;
|
||||
|
||||
ISystem* m_pSystem;
|
||||
|
||||
std::vector<SShake> m_shakes;
|
||||
|
||||
Ang3 m_frameAdditiveAngles; // Used mainly for cinematics, where the game can slightly override camera orientation
|
||||
|
||||
float m_scale;
|
||||
float m_zoomedScale;
|
||||
};
|
||||
|
||||
} // namespace LegacyViewSystem
|
||||
@@ -0,0 +1,684 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "CrySystem_precompiled.h"
|
||||
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
|
||||
#include <Cry_Camera.h>
|
||||
#include <ILevelSystem.h>
|
||||
#include "ViewSystem.h"
|
||||
#include "PNoise3.h"
|
||||
#include "DebugCamera.h"
|
||||
#include <MathConversion.h>
|
||||
|
||||
#include <AzCore/Casting/lossy_cast.h>
|
||||
|
||||
#define VS_CALL_LISTENERS(func) \
|
||||
{ \
|
||||
size_t count = m_listeners.size(); \
|
||||
if (count > 0) \
|
||||
{ \
|
||||
const size_t memSize = count * sizeof(IViewSystemListener*); \
|
||||
PREFAST_SUPPRESS_WARNING(6255) IViewSystemListener * *pArray = (IViewSystemListener**) alloca(memSize); \
|
||||
memcpy(pArray, &*m_listeners.begin(), memSize); \
|
||||
while (count--) \
|
||||
{ \
|
||||
(*pArray)->func; ++pArray; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
namespace LegacyViewSystem
|
||||
{
|
||||
|
||||
void ToggleDebugCamera([[maybe_unused]] IConsoleCmdArgs* pArgs)
|
||||
{
|
||||
#if !defined(_RELEASE)
|
||||
if (!gEnv->IsDedicated())
|
||||
{
|
||||
DebugCamera* debugCamera = CViewSystem::s_debugCamera;
|
||||
if (debugCamera)
|
||||
{
|
||||
if (!debugCamera->IsEnabled())
|
||||
{
|
||||
debugCamera->OnEnable();
|
||||
}
|
||||
else
|
||||
{
|
||||
debugCamera->OnNextMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ToggleDebugCameraInvertY([[maybe_unused]] IConsoleCmdArgs* pArgs)
|
||||
{
|
||||
#if !defined(_RELEASE)
|
||||
if (!gEnv->IsDedicated())
|
||||
{
|
||||
DebugCamera* debugCamera = CViewSystem::s_debugCamera;
|
||||
if (debugCamera)
|
||||
{
|
||||
debugCamera->OnInvertY();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void DebugCameraMove([[maybe_unused]] IConsoleCmdArgs* pArgs)
|
||||
{
|
||||
#if !defined(_RELEASE)
|
||||
if (!gEnv->IsDedicated())
|
||||
{
|
||||
if (pArgs->GetArgCount() != 4)
|
||||
{
|
||||
CryLogAlways("debugCameraMove requires 3 args, not %d.", pArgs->GetArgCount() - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
DebugCamera* debugCamera = CViewSystem::s_debugCamera;
|
||||
if (debugCamera && debugCamera->IsFree())
|
||||
{
|
||||
Vec3::value_type x = azlossy_cast<float>(atof(pArgs->GetArg(1)));
|
||||
Vec3::value_type y = azlossy_cast<float>(atof(pArgs->GetArg(2)));
|
||||
Vec3::value_type z = azlossy_cast<float>(atof(pArgs->GetArg(3)));
|
||||
Vec3 newPos(x, y, z);
|
||||
debugCamera->MovePosition(newPos);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
DebugCamera* CViewSystem::s_debugCamera = nullptr;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CViewSystem::CViewSystem(ISystem* pSystem)
|
||||
: m_pSystem(pSystem)
|
||||
, m_activeViewId(0)
|
||||
, m_nextViewIdToAssign(1000)
|
||||
, m_preSequenceViewId(0)
|
||||
, m_cutsceneViewId(0)
|
||||
, m_cutsceneCount(0)
|
||||
, m_bOverridenCameraRotation(false)
|
||||
, m_bActiveViewFromSequence(false)
|
||||
, m_fBlendInPosSpeed(0.0f)
|
||||
, m_fBlendInRotSpeed(0.0f)
|
||||
, m_bPerformBlendOut(false)
|
||||
, m_useDeferredViewSystemUpdate(false)
|
||||
, m_bControlsAudioListeners(true)
|
||||
{
|
||||
#if !defined(_RELEASE) && !defined(DEDICATED_SERVER)
|
||||
if (!s_debugCamera)
|
||||
{
|
||||
s_debugCamera = new DebugCamera;
|
||||
}
|
||||
|
||||
REGISTER_COMMAND("debugCameraToggle", ToggleDebugCamera, VF_DEV_ONLY, "Toggle the debug camera.\n");
|
||||
REGISTER_COMMAND("debugCameraInvertY", ToggleDebugCameraInvertY, VF_DEV_ONLY, "Toggle debug camera Y-axis inversion.\n");
|
||||
REGISTER_COMMAND("debugCameraMove", DebugCameraMove, VF_DEV_ONLY, "Move the debug camera the specified distance (x y z).\n");
|
||||
gEnv->pConsole->CreateKeyBind("ctrl_keyboard_key_punctuation_backslash", "debugCameraToggle");
|
||||
gEnv->pConsole->CreateKeyBind("alt_keyboard_key_punctuation_backslash", "debugCameraInvertY");
|
||||
#endif
|
||||
|
||||
REGISTER_CVAR2("cl_camera_noise", &m_fCameraNoise, -1, 0,
|
||||
"Adds hand-held like camera noise to the camera view. \n The higher the value, the higher the noise.\n A value <= 0 disables it.");
|
||||
REGISTER_CVAR2("cl_camera_noise_freq", &m_fCameraNoiseFrequency, 2.5326173f, 0,
|
||||
"Defines camera noise frequency for the camera view. \n The higher the value, the higher the noise.");
|
||||
|
||||
REGISTER_CVAR2("cl_ViewSystemDebug", &m_nViewSystemDebug, 0, VF_CHEAT,
|
||||
"Sets Debug information of the ViewSystem.");
|
||||
|
||||
REGISTER_CVAR2("cl_DefaultNearPlane", &m_fDefaultCameraNearZ, DEFAULT_NEAR, VF_CHEAT,
|
||||
"The default camera near plane. ");
|
||||
|
||||
//Register as level system listener
|
||||
if (m_pSystem->GetILevelSystem())
|
||||
{
|
||||
m_pSystem->GetILevelSystem()->AddListener(this);
|
||||
}
|
||||
|
||||
Camera::CameraSystemRequestBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
CViewSystem::~CViewSystem()
|
||||
{
|
||||
Camera::CameraSystemRequestBus::Handler::BusDisconnect();
|
||||
|
||||
ClearAllViews();
|
||||
|
||||
IConsole* pConsole = gEnv->pConsole;
|
||||
CRY_ASSERT(pConsole);
|
||||
pConsole->UnregisterVariable("cl_camera_noise", true);
|
||||
pConsole->UnregisterVariable("cl_camera_noise_freq", true);
|
||||
pConsole->UnregisterVariable("cl_ViewSystemDebug", true);
|
||||
pConsole->UnregisterVariable("cl_DefaultNearPlane", true);
|
||||
|
||||
//Remove as level system listener
|
||||
if (m_pSystem->GetILevelSystem())
|
||||
{
|
||||
m_pSystem->GetILevelSystem()->RemoveListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CViewSystem::Update(float frameTime)
|
||||
{
|
||||
FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
|
||||
|
||||
if (gEnv->IsDedicated())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_debugCamera)
|
||||
{
|
||||
s_debugCamera->Update();
|
||||
}
|
||||
|
||||
CView* const pActiveView = static_cast<CView*>(GetActiveView());
|
||||
|
||||
TViewMap::const_iterator Iter(m_views.begin());
|
||||
TViewMap::const_iterator const IterEnd(m_views.end());
|
||||
|
||||
for (; Iter != IterEnd; ++Iter)
|
||||
{
|
||||
IView* const pView = Iter->second;
|
||||
|
||||
bool const bIsActive = (pView == pActiveView);
|
||||
|
||||
pView->Update(frameTime, bIsActive);
|
||||
|
||||
if (bIsActive)
|
||||
{
|
||||
CCamera& rCamera = pView->GetCamera();
|
||||
if (!s_debugCamera || !s_debugCamera->IsEnabled())
|
||||
{
|
||||
pView->UpdateAudioListener(rCamera.GetMatrix());
|
||||
}
|
||||
|
||||
if (const SViewParams* currentParams = pView->GetCurrentParams())
|
||||
{
|
||||
SViewParams copyCurrentParams = *currentParams;
|
||||
rCamera.SetJustActivated(copyCurrentParams.justActivated);
|
||||
|
||||
copyCurrentParams.justActivated = false;
|
||||
pView->SetCurrentParams(copyCurrentParams);
|
||||
}
|
||||
|
||||
if (m_bOverridenCameraRotation)
|
||||
{
|
||||
// When camera rotation is overridden.
|
||||
Vec3 pos = rCamera.GetMatrix().GetTranslation();
|
||||
Matrix34 camTM(m_overridenCameraRotation);
|
||||
camTM.SetTranslation(pos);
|
||||
rCamera.SetMatrix(camTM);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal setting of the camera
|
||||
|
||||
if (m_fCameraNoise > 0)
|
||||
{
|
||||
Matrix33 m = Matrix33(rCamera.GetMatrix());
|
||||
m.OrthonormalizeFast();
|
||||
Ang3 aAng1 = Ang3::GetAnglesXYZ(m);
|
||||
//Ang3 aAng2 = RAD2DEG(aAng1);
|
||||
|
||||
Matrix34 camTM = rCamera.GetMatrix();
|
||||
Vec3 pos = camTM.GetTranslation();
|
||||
camTM.SetIdentity();
|
||||
|
||||
const float fScale = 0.1f;
|
||||
CPNoise3* pNoise = m_pSystem->GetNoiseGen();
|
||||
float fRes = pNoise->Noise1D(gEnv->pTimer->GetCurrTime() * m_fCameraNoiseFrequency);
|
||||
aAng1.x += fRes * m_fCameraNoise * fScale;
|
||||
pos.z -= fRes * m_fCameraNoise * fScale;
|
||||
fRes = pNoise->Noise1D(17 + gEnv->pTimer->GetCurrTime() * m_fCameraNoiseFrequency);
|
||||
aAng1.y -= fRes * m_fCameraNoise * fScale;
|
||||
|
||||
//aAng1.z+=fRes*0.025f; // left / right movement should be much less visible
|
||||
|
||||
camTM.SetRotationXYZ(aAng1);
|
||||
camTM.SetTranslation(pos);
|
||||
rCamera.SetMatrix(camTM);
|
||||
}
|
||||
}
|
||||
|
||||
m_pSystem->SetViewCamera(rCamera);
|
||||
}
|
||||
}
|
||||
|
||||
if (s_debugCamera)
|
||||
{
|
||||
s_debugCamera->PostUpdate();
|
||||
}
|
||||
|
||||
// Display debug info on screen
|
||||
if (m_nViewSystemDebug)
|
||||
{
|
||||
DebugDraw();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
IView* CViewSystem::CreateView()
|
||||
{
|
||||
CView* newView = new CView(m_pSystem);
|
||||
|
||||
if (newView)
|
||||
{
|
||||
AddView(newView);
|
||||
}
|
||||
|
||||
return newView;
|
||||
}
|
||||
|
||||
unsigned int CViewSystem::AddView(IView* pView)
|
||||
{
|
||||
assert(pView);
|
||||
|
||||
m_views.insert(TViewMap::value_type(m_nextViewIdToAssign, pView));
|
||||
return m_nextViewIdToAssign++;
|
||||
}
|
||||
|
||||
void CViewSystem::RemoveView(IView* pView)
|
||||
{
|
||||
RemoveViewById(GetViewId(pView));
|
||||
}
|
||||
|
||||
void CViewSystem::RemoveView(unsigned int viewId)
|
||||
{
|
||||
RemoveViewById(viewId);
|
||||
}
|
||||
|
||||
void CViewSystem::RemoveViewById(unsigned int viewId)
|
||||
{
|
||||
TViewMap::iterator iter = m_views.find(viewId);
|
||||
|
||||
if (iter != m_views.end())
|
||||
{
|
||||
if (viewId == m_activeViewId)
|
||||
{
|
||||
m_activeViewId = 0;
|
||||
}
|
||||
if (viewId == m_preSequenceViewId)
|
||||
{
|
||||
m_preSequenceViewId = 0;
|
||||
}
|
||||
SAFE_RELEASE(iter->second);
|
||||
m_views.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CViewSystem::SetActiveView(IView* pView)
|
||||
{
|
||||
if (pView != NULL)
|
||||
{
|
||||
IView* const pPrevView = GetView(m_activeViewId);
|
||||
|
||||
if (pPrevView != pView)
|
||||
{
|
||||
if (pPrevView != NULL)
|
||||
{
|
||||
pPrevView->SetActive(false);
|
||||
}
|
||||
|
||||
pView->SetActive(true);
|
||||
m_activeViewId = GetViewId(pView);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_activeViewId = ~0;
|
||||
}
|
||||
|
||||
m_bActiveViewFromSequence = false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CViewSystem::SetActiveView(unsigned int viewId)
|
||||
{
|
||||
IView* const pPrevView = GetView(m_activeViewId);
|
||||
|
||||
if (pPrevView != NULL)
|
||||
{
|
||||
pPrevView->SetActive(false);
|
||||
}
|
||||
|
||||
IView* const pView = GetView(viewId);
|
||||
|
||||
if (pView != NULL)
|
||||
{
|
||||
pView->SetActive(true);
|
||||
m_activeViewId = viewId;
|
||||
m_bActiveViewFromSequence = false;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
IView* CViewSystem::GetView(unsigned int viewId)
|
||||
{
|
||||
TViewMap::iterator it = m_views.find(viewId);
|
||||
|
||||
if (it != m_views.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
IView* CViewSystem::GetActiveView()
|
||||
{
|
||||
return GetView(m_activeViewId);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
unsigned int CViewSystem::GetViewId(IView* pView)
|
||||
{
|
||||
for (TViewMap::iterator it = m_views.begin(); it != m_views.end(); ++it)
|
||||
{
|
||||
IView* tView = it->second;
|
||||
|
||||
if (tView == pView)
|
||||
{
|
||||
return it->first;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
unsigned int CViewSystem::GetActiveViewId()
|
||||
{
|
||||
// cutscene can override the games id of the active view
|
||||
if (m_cutsceneCount && m_cutsceneViewId)
|
||||
{
|
||||
return m_cutsceneViewId;
|
||||
}
|
||||
return m_activeViewId;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
IView* CViewSystem::GetViewByEntityId(const AZ::EntityId& id, bool forceCreate)
|
||||
{
|
||||
for (TViewMap::iterator it = m_views.begin(); it != m_views.end(); ++it)
|
||||
{
|
||||
IView* tView = it->second;
|
||||
|
||||
if (tView && tView->GetLinkedId() == id)
|
||||
{
|
||||
return tView;
|
||||
}
|
||||
}
|
||||
|
||||
if (forceCreate)
|
||||
{
|
||||
// Component Camera
|
||||
AZ::Entity* entity = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationBus::Events::FindEntity, id);
|
||||
if (entity)
|
||||
{
|
||||
if (IView* pNew = CreateView())
|
||||
{
|
||||
pNew->LinkTo(entity);
|
||||
return pNew;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CViewSystem::SetActiveCamera(const SCameraParams& params)
|
||||
{
|
||||
IView* pView = NULL;
|
||||
|
||||
if (params.cameraEntityId.IsValid())
|
||||
{
|
||||
pView = GetViewByEntityId(params.cameraEntityId, true);
|
||||
if (pView)
|
||||
{
|
||||
SViewParams viewParams = *pView->GetCurrentParams();
|
||||
viewParams.fov = params.fov;
|
||||
viewParams.nearplane = params.nearZ;
|
||||
|
||||
if (m_bActiveViewFromSequence == false && m_preSequenceViewId == 0)
|
||||
{
|
||||
m_preSequenceViewId = m_activeViewId;
|
||||
IView* pPrevView = GetView(m_activeViewId);
|
||||
if (pPrevView && m_fBlendInPosSpeed > 0.0f && m_fBlendInRotSpeed > 0.0f)
|
||||
{
|
||||
viewParams.blendPosSpeed = m_fBlendInPosSpeed;
|
||||
viewParams.blendRotSpeed = m_fBlendInRotSpeed;
|
||||
viewParams.BlendFrom(*pPrevView->GetCurrentParams());
|
||||
}
|
||||
}
|
||||
|
||||
if (m_activeViewId != GetViewId(pView) && params.justActivated)
|
||||
{
|
||||
viewParams.justActivated = true;
|
||||
}
|
||||
|
||||
pView->SetCurrentParams(viewParams);
|
||||
// make this one the active view
|
||||
SetActiveView(pView);
|
||||
m_bActiveViewFromSequence = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_preSequenceViewId != 0)
|
||||
{
|
||||
// Restore m_preSequenceViewId view
|
||||
|
||||
IView* pActiveView = GetView(m_activeViewId);
|
||||
IView* pNewView = GetView(m_preSequenceViewId);
|
||||
if (pActiveView && pNewView && m_bPerformBlendOut)
|
||||
{
|
||||
SViewParams activeViewParams = *pActiveView->GetCurrentParams();
|
||||
SViewParams newViewParams = *pNewView->GetCurrentParams();
|
||||
newViewParams.BlendFrom(activeViewParams);
|
||||
newViewParams.blendPosSpeed = activeViewParams.blendPosSpeed;
|
||||
newViewParams.blendRotSpeed = activeViewParams.blendRotSpeed;
|
||||
|
||||
if (m_activeViewId != m_preSequenceViewId && params.justActivated)
|
||||
{
|
||||
newViewParams.justActivated = true;
|
||||
}
|
||||
|
||||
pNewView->SetCurrentParams(newViewParams);
|
||||
SetActiveView(m_preSequenceViewId);
|
||||
}
|
||||
else if (pActiveView && m_activeViewId != m_preSequenceViewId && params.justActivated)
|
||||
{
|
||||
SViewParams activeViewParams = *pActiveView->GetCurrentParams();
|
||||
activeViewParams.justActivated = true;
|
||||
|
||||
if (pNewView)
|
||||
{
|
||||
pNewView->SetCurrentParams(activeViewParams);
|
||||
SetActiveView(m_preSequenceViewId);
|
||||
}
|
||||
}
|
||||
|
||||
m_preSequenceViewId = 0;
|
||||
m_bActiveViewFromSequence = false;
|
||||
}
|
||||
}
|
||||
m_cutsceneViewId = GetViewId(pView);
|
||||
|
||||
VS_CALL_LISTENERS(OnCameraChange(params));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CViewSystem::BeginCutScene(IAnimSequence* pSeq, [[maybe_unused]] unsigned long dwFlags, bool bResetFX)
|
||||
{
|
||||
m_cutsceneCount++;
|
||||
|
||||
VS_CALL_LISTENERS(OnBeginCutScene(pSeq, bResetFX));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void CViewSystem::EndCutScene(IAnimSequence* pSeq, [[maybe_unused]] unsigned long dwFlags)
|
||||
{
|
||||
m_cutsceneCount -= (m_cutsceneCount > 0);
|
||||
|
||||
ClearCutsceneViews();
|
||||
|
||||
VS_CALL_LISTENERS(OnEndCutScene(pSeq));
|
||||
}
|
||||
|
||||
void CViewSystem::SendGlobalEvent([[maybe_unused]] const char* pszEvent)
|
||||
{
|
||||
// TODO: broadcast to script system
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CViewSystem::SetOverrideCameraRotation(bool bOverride, Quat rotation)
|
||||
{
|
||||
m_bOverridenCameraRotation = bOverride;
|
||||
m_overridenCameraRotation = rotation;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CViewSystem::UpdateSoundListeners()
|
||||
{
|
||||
assert(gEnv->IsEditor() && !gEnv->IsEditorGameMode());
|
||||
|
||||
// In Editor we may want to control global listeners outside of the game view.
|
||||
if (m_bControlsAudioListeners)
|
||||
{
|
||||
IView* const pActiveView = static_cast<IView*>(GetActiveView());
|
||||
TViewMap::const_iterator Iter(m_views.begin());
|
||||
TViewMap::const_iterator const IterEnd(m_views.end());
|
||||
|
||||
for (; Iter != IterEnd; ++Iter)
|
||||
{
|
||||
IView* const pView = Iter->second;
|
||||
bool const bIsActive = (pView == pActiveView);
|
||||
CCamera const& rCamera = bIsActive ? gEnv->pSystem->GetViewCamera() : pView->GetCamera();
|
||||
pView->UpdateAudioListener(rCamera.GetMatrix());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
void CViewSystem::OnLoadingStart([[maybe_unused]] const char* levelName)
|
||||
{
|
||||
//If the level is being restarted (IsSerializingFile() == 1)
|
||||
//views should not be cleared, because the main view (player one) won't be recreated in this case
|
||||
//Views will only be cleared when loading a new map, or loading a saved game (IsSerizlizingFile() == 2)
|
||||
bool shouldClearViews = gEnv->pSystem ? (gEnv->pSystem->IsSerializingFile() != 1) : false;
|
||||
|
||||
if (shouldClearViews)
|
||||
{
|
||||
ClearAllViews();
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
void CViewSystem::OnUnloadComplete([[maybe_unused]] const char* levelName)
|
||||
{
|
||||
bool shouldClearViews = gEnv->pSystem ? (gEnv->pSystem->IsSerializingFile() != 1) : false;
|
||||
|
||||
if (shouldClearViews)
|
||||
{
|
||||
ClearAllViews();
|
||||
}
|
||||
|
||||
assert(m_listeners.empty());
|
||||
stl::free_container(m_listeners);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
void CViewSystem::ClearCutsceneViews()
|
||||
{
|
||||
//First switch to previous camera if available
|
||||
//In practice, the camera should be already restored before reaching this point, but just in case.
|
||||
if (m_preSequenceViewId != 0)
|
||||
{
|
||||
SCameraParams camParams;
|
||||
camParams.cameraEntityId.SetInvalid(); //Setting to invalid will try to switch to previous camera
|
||||
camParams.fov = 60.0f;
|
||||
camParams.nearZ = DEFAULT_NEAR;
|
||||
camParams.justActivated = true;
|
||||
SetActiveCamera(camParams);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
void CViewSystem::ClearAllViews()
|
||||
{
|
||||
TViewMap::iterator end = m_views.end();
|
||||
for (TViewMap::iterator it = m_views.begin(); it != end; ++it)
|
||||
{
|
||||
SAFE_RELEASE(it->second);
|
||||
}
|
||||
stl::free_container(m_views);
|
||||
m_preSequenceViewId = 0;
|
||||
m_activeViewId = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CViewSystem::DebugDraw()
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CViewSystem::GetMemoryUsage(ICrySizer* s) const
|
||||
{
|
||||
SIZER_SUBCOMPONENT_NAME(s, "ViewSystem");
|
||||
s->Add(*this);
|
||||
s->AddContainer(m_views);
|
||||
}
|
||||
|
||||
void CViewSystem::Serialize(TSerialize ser)
|
||||
{
|
||||
TViewMap::iterator iter = m_views.begin();
|
||||
TViewMap::iterator iterEnd = m_views.end();
|
||||
while (iter != iterEnd)
|
||||
{
|
||||
iter->second->Serialize(ser);
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
void CViewSystem::PostSerialize()
|
||||
{
|
||||
TViewMap::iterator iter = m_views.begin();
|
||||
TViewMap::iterator iterEnd = m_views.end();
|
||||
while (iter != iterEnd)
|
||||
{
|
||||
iter->second->PostSerialize();
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
void CViewSystem::SetControlAudioListeners(bool bActive)
|
||||
{
|
||||
m_bControlsAudioListeners = bActive;
|
||||
|
||||
TViewMap::const_iterator Iter(m_views.begin());
|
||||
TViewMap::const_iterator const IterEnd(m_views.end());
|
||||
|
||||
for (; Iter != IterEnd; ++Iter)
|
||||
{
|
||||
Iter->second->SetActive(bActive);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LegacyViewSystem
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// Description : View System interfaces.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "View.h"
|
||||
#include "IMovieSystem.h"
|
||||
#include <ILevelSystem.h>
|
||||
#include <AzFramework/Components/CameraBus.h>
|
||||
|
||||
namespace LegacyViewSystem
|
||||
{
|
||||
|
||||
class DebugCamera;
|
||||
|
||||
class CViewSystem
|
||||
: public IViewSystem
|
||||
, public IMovieUser
|
||||
, public ILevelSystemListener
|
||||
, public Camera::CameraSystemRequestBus::Handler
|
||||
{
|
||||
private:
|
||||
|
||||
typedef std::map<unsigned int, IView*> TViewMap;
|
||||
typedef std::vector<unsigned int> TViewIdVector;
|
||||
|
||||
public:
|
||||
|
||||
//IViewSystem
|
||||
virtual IView* CreateView();
|
||||
virtual unsigned int AddView(IView* pView) override;
|
||||
virtual void RemoveView(IView* pView);
|
||||
virtual void RemoveView(unsigned int viewId);
|
||||
|
||||
virtual void SetActiveView(IView* pView);
|
||||
virtual void SetActiveView(unsigned int viewId);
|
||||
|
||||
//CameraSystemRequestBus
|
||||
AZ::EntityId GetActiveCamera() override { return m_activeViewId ? GetActiveView()->GetLinkedId() : AZ::EntityId(); }
|
||||
|
||||
//utility functions
|
||||
virtual IView* GetView(unsigned int viewId);
|
||||
virtual IView* GetActiveView();
|
||||
|
||||
virtual unsigned int GetViewId(IView* pView);
|
||||
virtual unsigned int GetActiveViewId();
|
||||
|
||||
virtual void Serialize(TSerialize ser);
|
||||
virtual void PostSerialize();
|
||||
|
||||
virtual IView* GetViewByEntityId(const AZ::EntityId& id, bool forceCreate);
|
||||
|
||||
virtual float GetDefaultZNear() { return m_fDefaultCameraNearZ; };
|
||||
virtual void SetBlendParams(float fBlendPosSpeed, float fBlendRotSpeed, bool performBlendOut) { m_fBlendInPosSpeed = fBlendPosSpeed; m_fBlendInRotSpeed = fBlendRotSpeed; m_bPerformBlendOut = performBlendOut; };
|
||||
virtual void SetOverrideCameraRotation(bool bOverride, Quat rotation);
|
||||
virtual bool IsPlayingCutScene() const
|
||||
{
|
||||
return m_cutsceneCount > 0;
|
||||
}
|
||||
virtual void UpdateSoundListeners();
|
||||
|
||||
virtual void SetDeferredViewSystemUpdate(bool const bDeferred){ m_useDeferredViewSystemUpdate = bDeferred; }
|
||||
virtual bool UseDeferredViewSystemUpdate() const { return m_useDeferredViewSystemUpdate; }
|
||||
virtual void SetControlAudioListeners(bool const bActive);
|
||||
//~IViewSystem
|
||||
|
||||
//IMovieUser
|
||||
virtual void SetActiveCamera(const SCameraParams& Params);
|
||||
virtual void BeginCutScene(IAnimSequence* pSeq, unsigned long dwFlags, bool bResetFX);
|
||||
virtual void EndCutScene(IAnimSequence* pSeq, unsigned long dwFlags);
|
||||
virtual void SendGlobalEvent(const char* pszEvent);
|
||||
//~IMovieUser
|
||||
|
||||
// ILevelSystemListener
|
||||
virtual void OnLevelNotFound([[maybe_unused]] const char* levelName) {};
|
||||
virtual void OnLoadingStart([[maybe_unused]] const char* levelName);
|
||||
virtual void OnLoadingComplete([[maybe_unused]] const char* levelName){};
|
||||
virtual void OnLoadingError([[maybe_unused]] const char* levelName, [[maybe_unused]] const char* error){};
|
||||
virtual void OnLoadingProgress([[maybe_unused]] const char* levelName, [[maybe_unused]] int progressAmount){};
|
||||
virtual void OnUnloadComplete([[maybe_unused]] const char* levelName);
|
||||
//~ILevelSystemListener
|
||||
|
||||
CViewSystem(ISystem* pSystem);
|
||||
~CViewSystem();
|
||||
|
||||
void Release() override { delete this; };
|
||||
void Update(float frameTime) override;
|
||||
|
||||
virtual void ForceUpdate(float elapsed) { Update(elapsed); }
|
||||
|
||||
//void RegisterViewClass(const char *name, IView *(*func)());
|
||||
|
||||
bool AddListener(IViewSystemListener* pListener)
|
||||
{
|
||||
return stl::push_back_unique(m_listeners, pListener);
|
||||
}
|
||||
|
||||
bool RemoveListener(IViewSystemListener* pListener)
|
||||
{
|
||||
return stl::find_and_erase(m_listeners, pListener);
|
||||
}
|
||||
|
||||
void GetMemoryUsage(ICrySizer* s) const;
|
||||
|
||||
void ClearAllViews();
|
||||
|
||||
private:
|
||||
|
||||
void RemoveViewById(unsigned int viewId);
|
||||
void ClearCutsceneViews();
|
||||
void DebugDraw();
|
||||
|
||||
ISystem* m_pSystem;
|
||||
|
||||
//TViewClassMap m_viewClasses;
|
||||
TViewMap m_views;
|
||||
|
||||
// Listeners
|
||||
std::vector<IViewSystemListener*> m_listeners;
|
||||
|
||||
unsigned int m_activeViewId;
|
||||
unsigned int m_nextViewIdToAssign; // next id which will be assigned
|
||||
unsigned int m_preSequenceViewId; // viewId before a movie cam dropped in
|
||||
|
||||
unsigned int m_cutsceneViewId;
|
||||
unsigned int m_cutsceneCount;
|
||||
|
||||
bool m_bActiveViewFromSequence;
|
||||
|
||||
bool m_bOverridenCameraRotation;
|
||||
Quat m_overridenCameraRotation;
|
||||
float m_fCameraNoise;
|
||||
float m_fCameraNoiseFrequency;
|
||||
|
||||
float m_fDefaultCameraNearZ;
|
||||
float m_fBlendInPosSpeed;
|
||||
float m_fBlendInRotSpeed;
|
||||
bool m_bPerformBlendOut;
|
||||
int m_nViewSystemDebug;
|
||||
|
||||
bool m_useDeferredViewSystemUpdate;
|
||||
bool m_bControlsAudioListeners;
|
||||
|
||||
public:
|
||||
static DebugCamera* s_debugCamera;
|
||||
};
|
||||
|
||||
} // namespace LegacyViewSystem
|
||||
Reference in New Issue
Block a user