Merge pull request #108 from SHADE-DP/SP3-141-Camera-System
Sp3 141 camera system Added camera directors. Use Transform Component's position and rotation for camera if entity has transform component. Added a function to update editor camera
This commit is contained in:
commit
845c833915
|
@ -1,7 +1,9 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHCameraComponent.h"
|
||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||
|
||||
#include "SHCameraSystem.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -22,33 +24,69 @@ namespace SHADE
|
|||
void SHCameraComponent::SetYaw(float yaw) noexcept
|
||||
{
|
||||
this->yaw = yaw;
|
||||
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
|
||||
{
|
||||
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
|
||||
SHVec3 rotation = transform->GetWorldRotation();
|
||||
transform->SetWorldRotation(SHVec3{rotation.x,yaw, rotation.z});
|
||||
}
|
||||
dirtyView = true;
|
||||
}
|
||||
|
||||
void SHCameraComponent::SetPitch(float pitch) noexcept
|
||||
{
|
||||
this->pitch = pitch;
|
||||
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
|
||||
{
|
||||
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
|
||||
SHVec3 rotation = transform->GetWorldRotation();
|
||||
transform->SetWorldRotation(SHVec3{ pitch,rotation.y, rotation.z });
|
||||
}
|
||||
dirtyView = true;
|
||||
}
|
||||
|
||||
void SHCameraComponent::SetRoll(float roll) noexcept
|
||||
{
|
||||
this->roll = roll;
|
||||
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
|
||||
{
|
||||
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
|
||||
SHVec3 rotation = transform->GetWorldRotation();
|
||||
transform->SetWorldRotation(SHVec3{ rotation.x,rotation.y, roll});
|
||||
}
|
||||
dirtyView = true;
|
||||
}
|
||||
void SHCameraComponent::SetPositionX(float x) noexcept
|
||||
{
|
||||
position.x = x;
|
||||
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
|
||||
{
|
||||
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
|
||||
SHVec3 position = transform->GetWorldPosition();
|
||||
transform->SetWorldRotation(SHVec3{ x,position.y, position.z});
|
||||
}
|
||||
dirtyView = true;
|
||||
}
|
||||
void SHCameraComponent::SetPositionY(float y) noexcept
|
||||
{
|
||||
position.y = y;
|
||||
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
|
||||
{
|
||||
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
|
||||
SHVec3 position = transform->GetWorldPosition();
|
||||
transform->SetWorldRotation(SHVec3{ position.x,y, position.z });
|
||||
}
|
||||
dirtyView = true;
|
||||
}
|
||||
void SHCameraComponent::SetPositionZ(float z) noexcept
|
||||
{
|
||||
position.z = z;
|
||||
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
|
||||
{
|
||||
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
|
||||
SHVec3 position = transform->GetWorldPosition();
|
||||
transform->SetWorldRotation(SHVec3{ position.x,position.y, z });
|
||||
}
|
||||
dirtyView = true;
|
||||
}
|
||||
void SHCameraComponent::SetPosition(float x,float y, float z) noexcept
|
||||
|
@ -56,11 +94,23 @@ namespace SHADE
|
|||
position.x = x;
|
||||
position.y = y;
|
||||
position.z = z;
|
||||
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
|
||||
{
|
||||
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
|
||||
SHVec3 position = transform->GetWorldPosition();
|
||||
transform->SetWorldRotation(SHVec3{ x,y, z });
|
||||
}
|
||||
dirtyView = true;
|
||||
}
|
||||
void SHCameraComponent::SetPosition(SHVec3& pos) noexcept
|
||||
{
|
||||
this->position = pos;
|
||||
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
|
||||
{
|
||||
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
|
||||
SHVec3 position = transform->GetWorldPosition();
|
||||
transform->SetWorldRotation(pos);
|
||||
}
|
||||
dirtyView = true;
|
||||
}
|
||||
|
||||
|
@ -128,4 +178,12 @@ namespace SHADE
|
|||
return projMatrix;
|
||||
}
|
||||
|
||||
void SHCameraComponent::SetMainCamera(size_t directorCameraIndex) noexcept
|
||||
{
|
||||
auto system = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||
system->GetDirector(directorCameraIndex)->SetMainCamera(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -70,6 +70,8 @@ namespace SHADE
|
|||
const SHMatrix& GetViewMatrix() const noexcept;
|
||||
const SHMatrix& GetProjMatrix() const noexcept;
|
||||
|
||||
void SetMainCamera(size_t cameraDirectorIndex = 0) noexcept;
|
||||
|
||||
|
||||
float movementSpeed;
|
||||
SHVec3 turnSpeed;
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHCameraDirector.h"
|
||||
#include "SHCameraComponent.h"
|
||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||
#include "ECS_Base/SHECSMacros.h"
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include "Tools/SHLog.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
SHCameraDirector::SHCameraDirector()
|
||||
:mainCameraEID(MAX_EID), transitionCameraEID(MAX_EID)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SHMatrix SHCameraDirector::GetViewMatrix() const noexcept
|
||||
{
|
||||
return viewMatrix;
|
||||
}
|
||||
SHMatrix SHCameraDirector::GetProjMatrix() const noexcept
|
||||
{
|
||||
return projMatrix;
|
||||
}
|
||||
SHMatrix SHCameraDirector::GetVPMatrix() const noexcept
|
||||
{
|
||||
return projMatrix * viewMatrix;
|
||||
}
|
||||
|
||||
void SHCameraDirector::UpdateMatrix() noexcept
|
||||
{
|
||||
if (mainCameraEID == MAX_EID)
|
||||
{
|
||||
auto& dense = SHComponentManager::GetDense<SHCameraComponent>();
|
||||
if (dense.size() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
mainCameraEID = dense[0].GetEID();
|
||||
}
|
||||
SHCameraComponent* camComponent = SHComponentManager::GetComponent_s<SHCameraComponent>(mainCameraEID);
|
||||
if (!camComponent)
|
||||
{
|
||||
SHLOG_WARNING("Camera Director warning: Entity does not have a camera");
|
||||
}
|
||||
else
|
||||
{
|
||||
viewMatrix = camComponent->GetViewMatrix();
|
||||
projMatrix = camComponent->GetProjMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
void SHCameraDirector::SetMainCamera(SHCameraComponent& camera) noexcept
|
||||
{
|
||||
if (SHEntityManager::IsValidEID(camera.GetEID()) == false)
|
||||
{
|
||||
SHLOG_WARNING("Camera Director Warning: Attempting to set an invalid entity as main camera.")
|
||||
return;
|
||||
}
|
||||
mainCameraEID = camera.GetEID();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#pragma once
|
||||
|
||||
#include "SH_API.h"
|
||||
#include "ECS_Base/Entity/SHEntity.h"
|
||||
#include "Math/SHMatrix.h"
|
||||
#include "Resource/SHHandle.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHCameraComponent;
|
||||
|
||||
|
||||
|
||||
class SH_API SHCameraDirector
|
||||
{
|
||||
public:
|
||||
SHCameraDirector();
|
||||
~SHCameraDirector() = default;
|
||||
|
||||
|
||||
EntityID mainCameraEID;
|
||||
EntityID transitionCameraEID;
|
||||
|
||||
SHMatrix GetViewMatrix() const noexcept;
|
||||
SHMatrix GetProjMatrix() const noexcept;
|
||||
SHMatrix GetVPMatrix() const noexcept;
|
||||
void UpdateMatrix() noexcept;
|
||||
void SetMainCamera(SHCameraComponent& cam) noexcept;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
protected:
|
||||
SHMatrix viewMatrix;
|
||||
SHMatrix projMatrix;
|
||||
|
||||
};
|
||||
|
||||
typedef Handle<SHCameraDirector> DirectorHandle;
|
||||
|
||||
}
|
|
@ -3,12 +3,63 @@
|
|||
#include "Math/SHMathHelpers.h"
|
||||
#include "Input/SHInputManager.h"
|
||||
#include "Math/Vector/SHVec2.h"
|
||||
|
||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
void SHCameraSystem::UpdateEditorCamera(double dt) noexcept
|
||||
{
|
||||
|
||||
auto& camera = editorCamera;
|
||||
SHVec3 view, right, UP;
|
||||
GetCameraAxis(camera, view, right, UP);
|
||||
|
||||
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::A))
|
||||
{
|
||||
camera.position -= right * dt * camera.movementSpeed;
|
||||
camera.dirtyView = true;
|
||||
}
|
||||
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::D))
|
||||
{
|
||||
camera.position += right * dt * camera.movementSpeed;
|
||||
camera.dirtyView = true;
|
||||
}
|
||||
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::W))
|
||||
{
|
||||
camera.position += view * dt * camera.movementSpeed;
|
||||
camera.dirtyView = true;
|
||||
}
|
||||
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::S))
|
||||
{
|
||||
camera.position -= view * dt * camera.movementSpeed;
|
||||
camera.dirtyView = true;
|
||||
}
|
||||
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::Q))
|
||||
{
|
||||
camera.position += UP * dt * camera.movementSpeed;
|
||||
camera.dirtyView = true;
|
||||
}
|
||||
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::E))
|
||||
{
|
||||
camera.position -= UP * dt * camera.movementSpeed;
|
||||
camera.dirtyView = true;
|
||||
}
|
||||
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::RMB))
|
||||
{
|
||||
double mouseX, mouseY;
|
||||
SHInputManager::GetMouseVelocity(&mouseX, &mouseY);
|
||||
|
||||
//std::cout << camera.yaw << std::endl;
|
||||
|
||||
camera.pitch -= mouseY * dt * camera.turnSpeed.x;
|
||||
camera.yaw -= mouseX * dt * camera.turnSpeed.y;
|
||||
camera.dirtyView = true;
|
||||
}
|
||||
|
||||
UpdateCameraComponent(editorCamera);
|
||||
}
|
||||
void SHCameraSystem::EditorCameraUpdate::Execute(double dt) noexcept
|
||||
{
|
||||
SHCameraSystem* system = static_cast<SHCameraSystem*>(GetSystem());
|
||||
|
@ -83,10 +134,25 @@ namespace SHADE
|
|||
|
||||
void SHCameraSystem::UpdateCameraComponent(SHCameraComponent& camera) noexcept
|
||||
{
|
||||
if (SHComponentManager::HasComponent<SHTransformComponent>(camera.GetEID()) == true)
|
||||
{
|
||||
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(camera.GetEID());
|
||||
SHVec3 rotation = transform->GetWorldRotation();
|
||||
camera.pitch = rotation.x;
|
||||
camera.yaw = rotation.y;
|
||||
camera.roll = rotation.z;
|
||||
camera.position = transform->GetWorldPosition();
|
||||
}
|
||||
|
||||
|
||||
if (camera.dirtyView)
|
||||
{
|
||||
|
||||
SHVec3 view, right, UP;
|
||||
|
||||
|
||||
ClampCameraRotation(camera);
|
||||
|
||||
GetCameraAxis(camera, view, right, UP);
|
||||
|
||||
camera.viewMatrix = SHMatrix::Identity;
|
||||
|
@ -168,5 +234,55 @@ namespace SHADE
|
|||
upVec = SHVec3::Cross(forward, right);
|
||||
}
|
||||
|
||||
void SHCameraSystem::CameraSystemUpdate::Execute(double dt) noexcept
|
||||
{
|
||||
SHCameraSystem* system = static_cast<SHCameraSystem*>(GetSystem());
|
||||
auto& dense = SHComponentManager::GetDense<SHCameraComponent>();
|
||||
for (auto& cam : dense)
|
||||
{
|
||||
system->UpdateCameraComponent(cam);
|
||||
}
|
||||
for (auto& handle : system->directorHandleList)
|
||||
{
|
||||
handle->UpdateMatrix();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
DirectorHandle SHCameraSystem::CreateDirector() noexcept
|
||||
{
|
||||
auto handle = directorLibrary.Create();
|
||||
directorHandleList.emplace_back(handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
DirectorHandle SHCameraSystem::GetDirector(size_t index) noexcept
|
||||
{
|
||||
if (index < directorHandleList.size())
|
||||
{
|
||||
return directorHandleList[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
return CreateDirector();
|
||||
}
|
||||
}
|
||||
void SHCameraSystem::ClampCameraRotation(SHCameraComponent& camera) noexcept
|
||||
{
|
||||
|
||||
|
||||
|
||||
if (camera.pitch > 85)
|
||||
camera.SetPitch(85);
|
||||
if (camera.pitch < -85)
|
||||
camera.SetPitch(-85);
|
||||
if (camera.roll > 85)
|
||||
camera.SetRoll(85);
|
||||
if (camera.roll < -85)
|
||||
camera.SetRoll(-85);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
#include "ECS_Base/System/SHSystem.h"
|
||||
#include "SHCameraComponent.h"
|
||||
#include "ECS_Base/System/SHSystemRoutine.h"
|
||||
#include "Resource/SHResourceLibrary.h"
|
||||
#include "SHCameraDirector.h"
|
||||
#include "SH_API.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SH_API SHCameraSystem final : public SHSystem
|
||||
|
@ -14,8 +15,9 @@ namespace SHADE
|
|||
//A camera component that represents editor camera.
|
||||
//This is not tied to any entity. Hence this EID should not be used.
|
||||
SHCameraComponent editorCamera;
|
||||
|
||||
|
||||
SHResourceLibrary<SHCameraDirector> directorLibrary;
|
||||
std::vector<DirectorHandle> directorHandleList;
|
||||
|
||||
public:
|
||||
SHCameraSystem(void) = default;
|
||||
|
@ -34,13 +36,26 @@ namespace SHADE
|
|||
};
|
||||
friend class EditorCameraUpdate;
|
||||
|
||||
SHCameraComponent* GetEditorCamera (void) noexcept;
|
||||
class SH_API CameraSystemUpdate final: public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
CameraSystemUpdate() : SHSystemRoutine("Camera System Update", false) {};
|
||||
virtual void Execute(double dt)noexcept override final;
|
||||
};
|
||||
friend class CameraSystemUpdate;
|
||||
|
||||
|
||||
SHCameraComponent* GetEditorCamera (void) noexcept;
|
||||
void GetCameraAxis(SHCameraComponent const& camera, SHVec3& forward, SHVec3& right, SHVec3& up) const noexcept;
|
||||
DirectorHandle CreateDirector() noexcept;
|
||||
DirectorHandle GetDirector(size_t index) noexcept;
|
||||
void ClampCameraRotation(SHCameraComponent& camera) noexcept;
|
||||
void UpdateEditorCamera(double dt) noexcept;
|
||||
protected:
|
||||
|
||||
void UpdateCameraComponent(SHCameraComponent& camera) noexcept;
|
||||
|
||||
void GetCameraAxis(SHCameraComponent const& camera, SHVec3& forward, SHVec3& right, SHVec3& up) const noexcept;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue