diff --git a/Code/Game/DanBiasGame/DanBiasGame.vcxproj b/Code/Game/DanBiasGame/DanBiasGame.vcxproj index abb0d4c3..cd56f8cf 100644 --- a/Code/Game/DanBiasGame/DanBiasGame.vcxproj +++ b/Code/Game/DanBiasGame/DanBiasGame.vcxproj @@ -197,6 +197,7 @@ + @@ -214,6 +215,7 @@ + diff --git a/Code/Game/DanBiasGame/GameClientState/Camera_FPS.cpp b/Code/Game/DanBiasGame/GameClientState/Camera_FPS.cpp new file mode 100644 index 00000000..f4d46f69 --- /dev/null +++ b/Code/Game/DanBiasGame/GameClientState/Camera_FPS.cpp @@ -0,0 +1,181 @@ +#include "Camera_FPS.h" + +using namespace ::Oyster::Math3D; + +Camera_FPS::Camera_FPS() +{ // this->head is default set to identity uniformprojection at origo + this->pitchUp = 0.0f; + this->headOffset = + this->body.translation = + this->body.angularAxis = Float3( 0.0f ); + this->body.direction = Float3x3::identity; +} + +Camera_FPS::~Camera_FPS() {} + +Camera_FPS & Camera_FPS::operator = ( const Camera_FPS &camera ) +{ + this->head = camera.head; + this->pitchUp = camera.pitchUp; + this->headOffset = camera.headOffset; + this->body.translation = camera.body.translation; + this->body.angularAxis = camera.body.angularAxis; + this->body.direction = camera.body.direction; + return *this; +} + +void Camera_FPS::SetHeadOffset( const Float3 &translation ) +{ + this->head.Move( translation - this->headOffset ); + this->headOffset = translation; +} + +void Camera_FPS::SetPosition( const Float3 &translation ) +{ + this->head.Move( translation - this->body.translation ); + this->body.translation = translation; +} + +void Camera_FPS::SetAngular( const Float3 &axis ) +{ + this->head.SetAngular( axis ); + this->pitchUp = 0.0f; + this->body.angularAxis = axis; +} + +void Camera_FPS::SetProjection( const Float4x4 &matrix ) +{ + this->head.SetProjection( matrix ); +} + +void Camera_FPS::SetOrthographicProjection( Float width, Float height, Float nearClip, Float farClip ) +{ + this->head.SetOrthographicProjection( width, height, nearClip, farClip ); +} + +void Camera_FPS::SetPerspectiveProjection( Float verticalFoV, Float aspectRatio, Float nearClip, Float farClip ) +{ + this->head.SetPerspectiveProjection( verticalFoV, aspectRatio, nearClip, farClip ); +} + +void Camera_FPS::UpdateOrientation() +{ + RotationMatrix( Rotation(this->body.angularAxis), this->body.direction ); + + Float4x4 orientation = Float4x4( Float4(this->body.direction.v[0], 0.0f), + Float4(this->body.direction.v[1], 0.0f), + Float4(this->body.direction.v[2], 0.0f), + Float4(this->body.translation, 1.0f) ); + + this->head.SetPosition( (orientation * Float4(this->headOffset, 1.0f)).xyz ); +} + +void Camera_FPS::SnapUpToNormal( const Float3 &normal ) +{ + SnapAngularAxis( this->body.angularAxis, this->body.direction.v[1], normal, this->body.angularAxis ); + this->head.SetAngular( this->body.angularAxis + this->pitchUp * Float3::standard_unit_x ); +} + +void Camera_FPS::Move( const Float3 &deltaPosition ) +{ + this->head.Move( deltaPosition ); + this->body.translation += deltaPosition; +} + +void Camera_FPS::Rotate( const Float3 &deltaAngularAxis ) +{ + this->head.Rotate( deltaAngularAxis ); + this->body.angularAxis += deltaAngularAxis; +} + +void Camera_FPS::MoveForward( Float distance ) +{ + this->MoveBackward( -distance ); +} + +void Camera_FPS::MoveBackward( Float distance ) +{ + this->Move( distance * this->body.direction.v[2] ); +} + +void Camera_FPS::StrafeRight( Float distance ) +{ + this->Move( distance * this->body.direction.v[0] ); +} + +void Camera_FPS::StrafeLeft( Float distance ) +{ + this->StrafeRight( -distance ); +} + +void Camera_FPS::PitchUp( Float radian ) +{ + this->pitchUp += radian; + this->head.SetAngular( this->body.angularAxis + this->pitchUp * this->body.direction.v[0] ); +} + +void Camera_FPS::PitchDown( Float radian ) +{ + this->PitchDown( -radian ); +} + +void Camera_FPS::YawRight( Float radian ) +{ + this->YawLeft( -radian ); +} + +void Camera_FPS::YawLeft( Float radian ) +{ + this->body.angularAxis += radian * this->body.direction.v[1]; + this->head.SetAngular( this->body.angularAxis + this->pitchUp * this->body.direction.v[0] ); +} + +const Float3 & Camera_FPS::GetHeadOffset() const +{ + return this->headOffset; +} + +const Float3 & Camera_FPS::GetPosition() const +{ + return this->body.translation; +} + +Float4x4 & Camera_FPS::GetViewMatrix( Float4x4 &targetMem ) const +{ + return this->head.GetViewMatrix( targetMem ); +} + +const Float4x4 & Camera_FPS::GetProjectionMatrix() const +{ + return this->head.GetProjectionMatrix(); +} + +Float4x4 & Camera_FPS::GetViewsProjMatrix( Float4x4 &targetMem ) const +{ + return this->head.GetViewsProjMatrix( targetMem ); +} + +Float3 Camera_FPS::GetNormalOf( const Float3 &axis ) const +{ + return this->head.GetNormalOf( axis ); +} + +Float3 Camera_FPS::GetRight() const +{ + return this->body.direction.v[0]; +} + +Float3 Camera_FPS::GetUp() const +{ + return this->body.direction.v[1]; +} + +Float3 Camera_FPS::GetLook() const +{ + return this->head.GetNormalOf( -Float3::standard_unit_z ); +} + +Float3 Camera_FPS::GetForward() const +{ + return -this->body.direction.v[2]; +} \ No newline at end of file diff --git a/Code/Game/DanBiasGame/GameClientState/Camera_FPS.h b/Code/Game/DanBiasGame/GameClientState/Camera_FPS.h new file mode 100644 index 00000000..1a464d7b --- /dev/null +++ b/Code/Game/DanBiasGame/GameClientState/Camera_FPS.h @@ -0,0 +1,61 @@ +#ifndef CAMERA_FPS_H +#define CAMERA_FPS_H + +#include "OysterMath.h" +#include "Camera_Basic.h" + +class Camera_FPS +{ +public: + Camera_FPS(); + virtual ~Camera_FPS(); + + Camera_FPS & operator = ( const Camera_FPS &camera ); + + void SetHeadOffset( const ::Oyster::Math::Float3 &translation ); + void SetPosition( const ::Oyster::Math::Float3 &translation ); + void SetAngular( const ::Oyster::Math::Float3 &axis ); + void SetProjection( const ::Oyster::Math::Float4x4 &matrix ); + void SetOrthographicProjection( ::Oyster::Math::Float width, ::Oyster::Math::Float height, ::Oyster::Math::Float nearClip, ::Oyster::Math::Float farClip ); + void SetPerspectiveProjection( ::Oyster::Math::Float verticalFoV, ::Oyster::Math::Float aspectRatio, ::Oyster::Math::Float nearClip, ::Oyster::Math::Float farClip ); + + void UpdateOrientation(); + + void SnapUpToNormal( const ::Oyster::Math::Float3 &normal ); + + void Move( const ::Oyster::Math::Float3 &deltaPosition ); + void Rotate( const ::Oyster::Math::Float3 &deltaAngularAxis ); + + void MoveForward( ::Oyster::Math::Float distance ); + void MoveBackward( ::Oyster::Math::Float distance ); + void StrafeRight( ::Oyster::Math::Float distance ); + void StrafeLeft( ::Oyster::Math::Float distance ); + + void PitchUp( ::Oyster::Math::Float radian ); + void PitchDown( ::Oyster::Math::Float radian ); + void YawRight( ::Oyster::Math::Float radian ); + void YawLeft( ::Oyster::Math::Float radian ); + + const ::Oyster::Math::Float3 & GetHeadOffset() const; + const ::Oyster::Math::Float3 & GetPosition() const; + ::Oyster::Math::Float4x4 & GetViewMatrix( Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const; + const ::Oyster::Math::Float4x4 & GetProjectionMatrix() const; + ::Oyster::Math::Float4x4 & GetViewsProjMatrix( Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const; + ::Oyster::Math::Float3 GetNormalOf( const ::Oyster::Math::Float3 &axis ) const; + ::Oyster::Math::Float3 GetRight() const; + ::Oyster::Math::Float3 GetUp() const; + ::Oyster::Math::Float3 GetLook() const; + ::Oyster::Math::Float3 GetForward() const; + +private: + Camera_Basic head; + ::Oyster::Math::Float pitchUp; + ::Oyster::Math::Float3 headOffset; + struct + { + ::Oyster::Math::Float3 translation, angularAxis; + ::Oyster::Math::Float3x3 direction; + } body; +}; + +#endif \ No newline at end of file