diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 24f0a214..a4fef1fa 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -108,13 +108,10 @@ namespace Sandbox SHComponentManager::CreateComponentSparseSet(); SHComponentManager::CreateComponentSparseSet(); SHComponentManager::CreateComponentSparseSet(); - SHComponentManager::CreateComponentSparseSet(); + //SHComponentManager::CreateComponentSparseSet(); SHAssetManager::Load(); - auto id = SHFamilyID::GetID(); - auto id2 = SHFamilyID::GetID(); - auto id3 = SHFamilyID::GetID(); SHSystemManager::RegisterRoutine(); diff --git a/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp b/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp new file mode 100644 index 00000000..9cb221ff --- /dev/null +++ b/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp @@ -0,0 +1,68 @@ +#include "SHpch.h" +#include "SHCameraArmComponent.h" + + + +namespace SHADE +{ + + SHCameraArmComponent::SHCameraArmComponent() + :pitch(0.0f), yaw(0.0f), armLength(1.0f),offset(), dirty(true), lookAtCameraOrigin(true) + { + + } + + + SHVec3 const& SHCameraArmComponent::GetOffset() const noexcept + { + return offset; + } + + float SHCameraArmComponent::GetPitch() const noexcept + { + return pitch; + } + + float SHCameraArmComponent::GetYaw() const noexcept + { + return yaw; + } + + float SHCameraArmComponent::GetArmLength() const noexcept + { + return armLength; + } + + void SHCameraArmComponent::SetPitch(float pitch) noexcept + { + this->pitch = pitch; + dirty = true; + } + + void SHCameraArmComponent::SetYaw(float yaw) noexcept + { + this->yaw = yaw; + dirty = true; + } + + void SHCameraArmComponent::SetArmLength(float length) noexcept + { + this->armLength = length; + dirty = true; + } + +}//namespace SHADE + + +RTTR_REGISTRATION +{ + using namespace SHADE; + using namespace rttr; + + registration::class_("Camera Arm Component") + .property("Arm Pitch", &SHCameraArmComponent::GetPitch, &SHCameraArmComponent::SetPitch) + .property("Arm Yaw", &SHCameraArmComponent::GetYaw, &SHCameraArmComponent::SetYaw) + .property("Arm Length", &SHCameraArmComponent::GetArmLength, &SHCameraArmComponent::SetArmLength) + .property("Look At Camera Origin", &SHCameraArmComponent::lookAtCameraOrigin); + +} \ No newline at end of file diff --git a/SHADE_Engine/src/Camera/SHCameraArmComponent.h b/SHADE_Engine/src/Camera/SHCameraArmComponent.h new file mode 100644 index 00000000..2b81a808 --- /dev/null +++ b/SHADE_Engine/src/Camera/SHCameraArmComponent.h @@ -0,0 +1,44 @@ +#pragma once + + +#include +#include "ECS_Base/Components/SHComponent.h" +#include "Math/SHMatrix.h" +#include "SH_API.h" + +namespace SHADE +{ + class SH_API SHCameraArmComponent final: public SHComponent + { + private: + float pitch; + float yaw; + float armLength; + + bool dirty; + SHVec3 offset; + + public: + friend class SHCameraSystem; + SHCameraArmComponent(); + virtual ~SHCameraArmComponent() = default; + + bool lookAtCameraOrigin; + //Getters + //SHMatrix const& GetMatrix() const noexcept; + SHVec3 const& GetOffset() const noexcept; + float GetPitch() const noexcept; + float GetYaw() const noexcept; + float GetArmLength() const noexcept; + + //Setters + void SetPitch(float pitch) noexcept; + void SetYaw(float yaw) noexcept; + void SetArmLength(float length) noexcept; + + protected: + + + }; + +}//namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Camera/SHCameraComponent.cpp b/SHADE_Engine/src/Camera/SHCameraComponent.cpp index 31afe2ac..ac451df5 100644 --- a/SHADE_Engine/src/Camera/SHCameraComponent.cpp +++ b/SHADE_Engine/src/Camera/SHCameraComponent.cpp @@ -13,7 +13,7 @@ namespace SHADE , width(1920.0f), height(1080.0f), zNear(0.01f), zFar(10000.0f), fov(90.0f), movementSpeed(1.0f), turnSpeed(0.5f) , perspProj(true), dirtyView(true), dirtyProj(true) , viewMatrix(), projMatrix() - , position() + , position(), offset() { ComponentFamily::GetID(); } diff --git a/SHADE_Engine/src/Camera/SHCameraComponent.h b/SHADE_Engine/src/Camera/SHCameraComponent.h index f5e08af4..b778b8fa 100644 --- a/SHADE_Engine/src/Camera/SHCameraComponent.h +++ b/SHADE_Engine/src/Camera/SHCameraComponent.h @@ -33,7 +33,7 @@ namespace SHADE SHVec3 position; bool perspProj; - + SHVec3 offset; @@ -41,7 +41,7 @@ namespace SHADE friend class SHCameraSystem; SHCameraComponent(); - ~SHCameraComponent(); + virtual ~SHCameraComponent(); //Getters and setters. diff --git a/SHADE_Engine/src/Camera/SHCameraDirector.cpp b/SHADE_Engine/src/Camera/SHCameraDirector.cpp index 559897c0..98341098 100644 --- a/SHADE_Engine/src/Camera/SHCameraDirector.cpp +++ b/SHADE_Engine/src/Camera/SHCameraDirector.cpp @@ -1,6 +1,7 @@ #include "SHpch.h" #include "SHCameraDirector.h" #include "SHCameraComponent.h" +#include "SHCameraArmComponent.h" #include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/SHECSMacros.h" #include "ECS_Base/Managers/SHEntityManager.h" @@ -48,6 +49,7 @@ namespace SHADE viewMatrix = camComponent->GetViewMatrix(); projMatrix = camComponent->GetProjMatrix(); } + } void SHCameraDirector::SetMainCamera(SHCameraComponent& camera) noexcept diff --git a/SHADE_Engine/src/Camera/SHCameraDirector.h b/SHADE_Engine/src/Camera/SHCameraDirector.h index 5d09788b..6d5404c5 100644 --- a/SHADE_Engine/src/Camera/SHCameraDirector.h +++ b/SHADE_Engine/src/Camera/SHCameraDirector.h @@ -21,6 +21,7 @@ namespace SHADE EntityID mainCameraEID; EntityID transitionCameraEID; + SHMatrix GetViewMatrix() const noexcept; SHMatrix GetProjMatrix() const noexcept; @@ -35,7 +36,7 @@ namespace SHADE protected: SHMatrix viewMatrix; SHMatrix projMatrix; - + }; typedef Handle DirectorHandle; diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.cpp b/SHADE_Engine/src/Camera/SHCameraSystem.cpp index 609805f8..d5bd414d 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.cpp +++ b/SHADE_Engine/src/Camera/SHCameraSystem.cpp @@ -1,10 +1,12 @@ #include "SHpch.h" #include "SHCameraSystem.h" +#include "SHCameraArmComponent.h" #include "Math/SHMathHelpers.h" #include "Input/SHInputManager.h" #include "Math/Vector/SHVec2.h" #include "ECS_Base/Managers/SHComponentManager.h" #include "Math/Transform/SHTransformComponent.h" +#include namespace SHADE @@ -59,6 +61,7 @@ namespace SHADE } UpdateCameraComponent(editorCamera); + } void SHCameraSystem::EditorCameraUpdate::Execute(double dt) noexcept { @@ -112,6 +115,8 @@ namespace SHADE //std::cout << "Camera position: " << camera.position.x << " " << camera.position.y << std::endl; system->UpdateCameraComponent(system->editorCamera); + + system->DecomposeViewMatrix(camera.viewMatrix, camera.pitch, camera.yaw, camera.roll, camera.position); } void SHCameraSystem::Init(void) @@ -121,6 +126,9 @@ namespace SHADE editorCamera.SetYaw(0.0f); editorCamera.SetRoll(0.0f); editorCamera.movementSpeed = 2.0f; + + SHComponentManager::CreateComponentSparseSet(); + SHComponentManager::CreateComponentSparseSet(); } @@ -134,6 +142,26 @@ namespace SHADE return &editorCamera; } + void SHCameraSystem::UpdatePivotArmComponent(SHCameraArmComponent& pivot) noexcept + { + if (pivot.dirty) + { + + SHVec3 offset{ 0.0f,0.0f, pivot.GetArmLength() }; + offset = SHVec3::RotateX(offset, -(SHMath::DegreesToRadians(pivot.GetPitch()))); + offset = SHVec3::RotateY(offset, (SHMath::DegreesToRadians(pivot.GetYaw()))); + + + //pivot.rtMatrix = SHMatrix::RotateX(SHMath::DegreesToRadians(pivot.GetPitch())) + // * SHMatrix::RotateY(SHMath::DegreesToRadians(pivot.GetYaw())) + // * SHMatrix::Translate(SHVec3(0.0f , 0.0f, pivot.GetArmLength())); + + pivot.offset = offset; + // pivot.rtMatrix = SHMatrix::Inverse(pivot.rtMatrix); + } + } + + void SHCameraSystem::UpdateCameraComponent(SHCameraComponent& camera) noexcept { if (SHComponentManager::HasComponent(camera.GetEID()) == true && &camera != &editorCamera) @@ -151,6 +179,15 @@ namespace SHADE if (camera.dirtyView) { + camera.offset = SHVec3{ 0.0f }; + if (SHComponentManager::HasComponent(camera.GetEID())) + { + auto arm = SHComponentManager::GetComponent(camera.GetEID()); + camera.offset = arm->GetOffset(); + if(arm->lookAtCameraOrigin) + CameraLookAt(camera, camera.position); + } + SHVec3 view, right, UP; @@ -171,9 +208,12 @@ namespace SHADE camera.viewMatrix(2, 1) = view[1]; camera.viewMatrix(2, 2) = view[2]; - camera.viewMatrix(0, 3) = -right.Dot(camera.position); - camera.viewMatrix(1, 3) = -UP.Dot(camera.position); - camera.viewMatrix(2, 3) = -view.Dot(camera.position); + camera.viewMatrix(0, 3) = -right.Dot(camera.position + camera.offset); + camera.viewMatrix(1, 3) = -UP.Dot(camera.position + camera.offset); + camera.viewMatrix(2, 3) = -view.Dot(camera.position + camera.offset); + + + camera.dirtyView = false; } @@ -221,6 +261,8 @@ namespace SHADE SHVec3 up = { 0.0f,1.0f,0.0f }; + + target = SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch)); target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw)); target += camera.position; @@ -241,6 +283,13 @@ namespace SHADE { SHCameraSystem* system = static_cast(GetSystem()); auto& dense = SHComponentManager::GetDense(); + auto& pivotDense = SHComponentManager::GetDense(); + + for (auto& pivot : pivotDense) + { + system->UpdatePivotArmComponent(pivot); + } + for (auto& cam : dense) { system->UpdateCameraComponent(cam); @@ -274,18 +323,115 @@ namespace SHADE } void SHCameraSystem::ClampCameraRotation(SHCameraComponent& camera) noexcept { + constexpr float clampVal = 85.0f; + if (camera.pitch > clampVal) + camera.SetPitch(clampVal); + if (camera.pitch < -clampVal) + camera.SetPitch(-clampVal); + if (camera.roll > clampVal) + camera.SetRoll(clampVal); + if (camera.roll < -clampVal) + camera.SetRoll(-clampVal); - 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); + while (camera.yaw > 360) + camera.yaw -= 360; + while (camera.yaw < -360) + camera.yaw += 360; } + void SHCameraSystem::SetMainCamera(EntityID eid, size_t directorIndex) noexcept + { + if (SHComponentManager::HasComponent(eid) && directorIndex < directorHandleList.size()) + directorHandleList[directorIndex]->SetMainCamera(*SHComponentManager::GetComponent(eid)); + else + { + SHLOG_WARNING("Set Main Camera warning: Entity does not have camera component or director does not exist.") + } + } + + void SHCameraSystem::DecomposeViewMatrix(SHMatrix const& viewMatrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept + { + + float initPitch = pitch; + SHVec3 initPos = pos; + SHVec3 translate3, scale; + SHQuaternion quat; + + //SHMatrix viewInverse = viewMatrix; + + viewMatrix.Decompose(translate3, quat, scale); + yaw = 180+ SHMath::RadiansToDegrees(quat.ToEuler().y); + pitch = -SHMath::RadiansToDegrees(quat.ToEuler().x); + + SHVec4 dotPos{ -viewMatrix(0,3),-viewMatrix(1,3), -viewMatrix(2,3), 1.0f }; + SHMatrix mtx = viewMatrix; + mtx(0, 3) = 0.0f; + mtx(1, 3) = 0.0f; + mtx(2, 3) = 0.0f; + mtx.Transpose(); + mtx = SHMatrix::Inverse(mtx); + SHVec4 translate = mtx* dotPos; + + pos.x = translate.x; + pos.y = translate.y; + pos.z = translate.z; + + } + void SHCameraSystem::SetCameraViewMatrix(SHCameraComponent& camera, SHMatrix const& viewMatrix) noexcept + { + DecomposeViewMatrix(viewMatrix, camera.pitch, camera.yaw, camera.roll, camera.position); + camera.dirtyView = true; + } + + void SHCameraSystem::CameraLookAt(SHCameraComponent& camera, SHVec3 target) noexcept + { + + if (camera.position == target) + { + //lets off set it abit so the view is nt fked + target.z -= 0.0001f; + } + SHVec3 forward, right, upVec; + + SHVec3 up = { 0.0f,1.0f,0.0f }; + + + ////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll)); + + //target = SHVec3::Normalise(target); + + SHVec3::RotateZ(up, camera.roll); + up = SHVec3::Normalise(up); + + + forward = target - (camera.position + camera.offset); forward = SHVec3::Normalise(forward); + right = SHVec3::Cross(forward, up); right = SHVec3::Normalise(right); + upVec = SHVec3::Cross(forward, right); + + + SHMatrix viewMtx; + viewMtx = SHMatrix::Identity; + viewMtx(0, 0) = right[0]; + viewMtx(0, 1) = right[1]; + viewMtx(0, 2) = right[2]; + + viewMtx(1, 0) = upVec[0]; + viewMtx(1, 1) = upVec[1]; + viewMtx(1, 2) = upVec[2]; + + viewMtx(2, 0) = forward[0]; + viewMtx(2, 1) = forward[1]; + viewMtx(2, 2) = forward[2]; + + viewMtx(0, 3) = -right.Dot(camera.position + camera.offset); + viewMtx(1, 3) = -upVec.Dot(camera.position + camera.offset); + viewMtx(2, 3) = -forward.Dot(camera.position + camera.offset); + + + SetCameraViewMatrix(camera, viewMtx); + } + } diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.h b/SHADE_Engine/src/Camera/SHCameraSystem.h index 68071160..98fd442f 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.h +++ b/SHADE_Engine/src/Camera/SHCameraSystem.h @@ -9,6 +9,9 @@ namespace SHADE { + + class SHCameraArmComponent; + class SH_API SHCameraSystem final : public SHSystem { private: @@ -19,6 +22,11 @@ namespace SHADE SHResourceLibrary directorLibrary; std::vector directorHandleList; + + void UpdateCameraComponent(SHCameraComponent& camera) noexcept; + void UpdatePivotArmComponent(SHCameraArmComponent& pivot) noexcept; + + public: SHCameraSystem(void) = default; virtual ~SHCameraSystem(void) = default; @@ -39,7 +47,7 @@ namespace SHADE class SH_API CameraSystemUpdate final: public SHSystemRoutine { public: - CameraSystemUpdate() : SHSystemRoutine("Camera System Update", false) {}; + CameraSystemUpdate() : SHSystemRoutine("Camera System Update", true) {}; virtual void Execute(double dt)noexcept override final; }; friend class CameraSystemUpdate; @@ -51,12 +59,10 @@ namespace SHADE DirectorHandle GetDirector(size_t index) noexcept; void ClampCameraRotation(SHCameraComponent& camera) noexcept; void UpdateEditorCamera(double dt) noexcept; - protected: - - void UpdateCameraComponent(SHCameraComponent& camera) noexcept; - - - + void SetMainCamera(EntityID eid, size_t directorIndex) noexcept; + void DecomposeViewMatrix(SHMatrix const& matrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept; + void SetCameraViewMatrix(SHCameraComponent& camera, SHMatrix const& viewMatrix) noexcept; + void CameraLookAt(SHCameraComponent& camera, SHVec3 target) noexcept; }; diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index c4a86785..2fecae25 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -17,6 +17,7 @@ #include "Physics/Components/SHRigidBodyComponent.h" #include "Physics/Components/SHColliderComponent.h" #include "Camera/SHCameraComponent.h" +#include "Camera/SHCameraArmComponent.h" #include "SHEditorComponentView.h" namespace SHADE @@ -126,6 +127,9 @@ namespace SHADE if (auto cameraComponent = SHComponentManager::GetComponent_s(eid)) { DrawComponent(cameraComponent); + }if (auto cameraArmComponent = SHComponentManager::GetComponent_s(eid)) + { + DrawComponent(cameraArmComponent); } ImGui::Separator(); // Render Scripts @@ -136,6 +140,7 @@ namespace SHADE { DrawAddComponentButton(eid); DrawAddComponentButton(eid); + DrawAddComponentButton(eid); DrawAddComponentButton(eid); // Components that require Transforms