mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
136 lines
3.0 KiB
C++
136 lines
3.0 KiB
C++
|
#include "stdafx.h"
|
||
|
#include "RenderViewCamera.h"
|
||
|
|
||
|
namespace Assets
|
||
|
{
|
||
|
RenderViewCamera::RenderViewCamera()
|
||
|
: _Theta(0), _Phi(0), _Radius(0), _Up(1), _Target(0, 0, 0), _ViewMatrix(), _ProjectionMatrix(), _MatrixDirty(true)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
RenderViewCamera::RenderViewCamera(float Theta, float Phi, float Radius, RenderViewCameraUpAxis UpAxis)
|
||
|
: _Theta(Theta), _Phi(Phi), _Radius(Radius), _Up(1), _Target(0, 0, 0), _ViewMatrix(), _ProjectionMatrix(), _MatrixDirty(true)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void RenderViewCamera::Rotate(float Theta, float Phi)
|
||
|
{
|
||
|
this->_MatrixDirty = true;
|
||
|
|
||
|
if (_Up > 0.f)
|
||
|
_Theta += Theta;
|
||
|
else
|
||
|
_Theta -= Theta;
|
||
|
|
||
|
_Phi += Phi;
|
||
|
|
||
|
if (_Phi > (float)MathHelper::PI2)
|
||
|
_Phi -= (float)MathHelper::PI2;
|
||
|
else if (_Phi < -(float)MathHelper::PI2)
|
||
|
_Phi += (float)MathHelper::PI2;
|
||
|
|
||
|
if ((_Phi > 0 && _Phi < (float)MathHelper::PI) || (_Phi < -(float)MathHelper::PI && _Phi > -(float)MathHelper::PI2))
|
||
|
_Up = 1.f;
|
||
|
else
|
||
|
_Up = -1.f;
|
||
|
}
|
||
|
|
||
|
void RenderViewCamera::Zoom(float Distance)
|
||
|
{
|
||
|
this->_MatrixDirty = true;
|
||
|
|
||
|
_Radius -= Distance;
|
||
|
|
||
|
if (_Radius <= 0.f)
|
||
|
{
|
||
|
_Radius = 30.f;
|
||
|
auto Look = (_Target - this->GetCameraPosition()).GetNormalized();
|
||
|
_Target = (_Target + (Look * 30.f));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void RenderViewCamera::Pan(float X, float Y)
|
||
|
{
|
||
|
this->_MatrixDirty = true;
|
||
|
|
||
|
auto Look = (_Target - this->GetCameraPosition()).GetNormalized();
|
||
|
auto WorldUp = Vector3(0, _Up, 0);
|
||
|
|
||
|
auto Right = Look.Cross(WorldUp);
|
||
|
auto Up = Look.Cross(Right);
|
||
|
|
||
|
_Target = (_Target + ((Right * X) + (Up * Y)));
|
||
|
}
|
||
|
|
||
|
void RenderViewCamera::Reset(float Theta, float Phi, float Radius)
|
||
|
{
|
||
|
_Theta = Theta;
|
||
|
_Phi = Phi;
|
||
|
_Radius = Radius;
|
||
|
_Up = 1;
|
||
|
_Target = { 0, 0, 0 };
|
||
|
_ViewMatrix = {};
|
||
|
_ProjectionMatrix = {};
|
||
|
_MatrixDirty = true;
|
||
|
}
|
||
|
|
||
|
void RenderViewCamera::SetUpAxis(RenderViewCameraUpAxis UpAxis)
|
||
|
{
|
||
|
switch (UpAxis)
|
||
|
{
|
||
|
case RenderViewCameraUpAxis::Y:
|
||
|
_ModelMatrix = Matrix();
|
||
|
break;
|
||
|
case RenderViewCameraUpAxis::Z:
|
||
|
_ModelMatrix = Matrix::CreateFromQuaternion(Quaternion::FromEulerAngles(-90, 0, 0));
|
||
|
break;
|
||
|
}
|
||
|
_MatrixDirty = true;
|
||
|
}
|
||
|
|
||
|
void RenderViewCamera::UpdateProjectionMatrix(float Fov, float ClientWidth, float ClientHeight, float NearClip, float FarClip)
|
||
|
{
|
||
|
this->_ProjectionMatrix = Matrix::CreatePerspectiveFov(Fov, ClientWidth / ClientHeight, NearClip, FarClip);
|
||
|
}
|
||
|
|
||
|
Vector3 RenderViewCamera::GetCameraPosition() const
|
||
|
{
|
||
|
return (this->_Target + this->ToCartesian());
|
||
|
}
|
||
|
|
||
|
Matrix& RenderViewCamera::GetProjectionMatrix()
|
||
|
{
|
||
|
return this->_ProjectionMatrix;
|
||
|
}
|
||
|
|
||
|
Matrix& RenderViewCamera::GetViewMatrix()
|
||
|
{
|
||
|
if (this->_MatrixDirty)
|
||
|
{
|
||
|
this->UpdateViewMatrix();
|
||
|
this->_MatrixDirty = false;
|
||
|
}
|
||
|
|
||
|
return this->_ViewMatrix;
|
||
|
}
|
||
|
|
||
|
Matrix& RenderViewCamera::GetModelMatrix()
|
||
|
{
|
||
|
return this->_ModelMatrix;
|
||
|
}
|
||
|
|
||
|
void RenderViewCamera::UpdateViewMatrix()
|
||
|
{
|
||
|
this->_ViewMatrix = Matrix::CreateLookAt(GetCameraPosition(), this->_Target, Vector3(0.f, this->_Up, 0.f));
|
||
|
}
|
||
|
|
||
|
Vector3 RenderViewCamera::ToCartesian() const
|
||
|
{
|
||
|
return Vector3(
|
||
|
_Radius * sinf(_Phi) * sinf(_Theta),
|
||
|
_Radius * cosf(_Phi),
|
||
|
_Radius * sinf(_Phi) * cosf(_Theta)
|
||
|
);
|
||
|
}
|
||
|
}
|