From 357b36a9b085cf08c0caf5b190081f48f329525d Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 27 Sep 2022 16:24:08 +0800 Subject: [PATCH 01/61] Added RigidBody Component --- SHADE_Engine/src/Math/SHMathHelpers.hpp | 2 +- .../Math/Transform/SHTransformComponent.cpp | 37 -- .../src/Math/Transform/SHTransformComponent.h | 8 +- .../Components/SHRigidBodyComponent.cpp | 499 ++++++++++++++++++ .../Physics/Components/SHRigidBodyComponent.h | 147 ++++++ SHADE_Engine/src/SHpch.h | 1 + SHADE_Engine/src/Tools/SHException.h | 17 +- 7 files changed, 662 insertions(+), 49 deletions(-) create mode 100644 SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp create mode 100644 SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h diff --git a/SHADE_Engine/src/Math/SHMathHelpers.hpp b/SHADE_Engine/src/Math/SHMathHelpers.hpp index 0e5fc5fa..d95bcfa2 100644 --- a/SHADE_Engine/src/Math/SHMathHelpers.hpp +++ b/SHADE_Engine/src/Math/SHMathHelpers.hpp @@ -120,7 +120,7 @@ namespace SHADE bool SHMath::CompareFloat(T lhs, T rhs, T absTolerance, T relTolerance) { const T RTOL = relTolerance * Max(std::fabs(lhs), std::fabs(rhs)); - return std::fabs(lhs - rhs) <= MAX(absTolerance, RTOL); + return std::fabs(lhs - rhs) <= Max(absTolerance, RTOL); } } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp b/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp index cdc5105f..fd950628 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp @@ -24,43 +24,6 @@ namespace SHADE , dirty { true } {} - SHTransformComponent::SHTransformComponent(const SHTransformComponent& rhs) noexcept - : SHComponent {} - , dirty { true } - , local { rhs.local } - , world { rhs.world } - {} - - SHTransformComponent::SHTransformComponent(SHTransformComponent&& rhs) noexcept - : SHComponent {} - , dirty { true } - , local { std::move(rhs.local) } - , world { std::move(rhs.world) } - {} - - /*-----------------------------------------------------------------------------------*/ - /* Operator Overload Definitions */ - /*-----------------------------------------------------------------------------------*/ - - SHTransformComponent& SHTransformComponent::operator=(const SHTransformComponent& rhs) noexcept - { - dirty = true; - local = rhs.local; - world = rhs.world; - - return *this; - } - - SHTransformComponent& SHTransformComponent::operator=(SHTransformComponent&& rhs) noexcept - { - dirty = true; - local = std::move(rhs.local); - world = std::move(rhs.world); - - return *this; - } - - /*-----------------------------------------------------------------------------------*/ /* Getter Function Definitions */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Math/Transform/SHTransformComponent.h b/SHADE_Engine/src/Math/Transform/SHTransformComponent.h index 7f7dd473..50377b3a 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformComponent.h +++ b/SHADE_Engine/src/Math/Transform/SHTransformComponent.h @@ -40,15 +40,15 @@ namespace SHADE ~SHTransformComponent () override = default; SHTransformComponent () noexcept; - SHTransformComponent (const SHTransformComponent& rhs) noexcept; - SHTransformComponent (SHTransformComponent&& rhs) noexcept; + SHTransformComponent (const SHTransformComponent& rhs) noexcept = default; + SHTransformComponent (SHTransformComponent&& rhs) noexcept = default; /*---------------------------------------------------------------------------------*/ /* Operator Overloads */ /*---------------------------------------------------------------------------------*/ - SHTransformComponent& operator=(const SHTransformComponent& rhs) noexcept; - SHTransformComponent& operator=(SHTransformComponent&& rhs) noexcept; + SHTransformComponent& operator=(const SHTransformComponent& rhs) noexcept = default; + SHTransformComponent& operator=(SHTransformComponent&& rhs) noexcept = default; /*---------------------------------------------------------------------------------*/ /* Getter Functions */ diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp new file mode 100644 index 00000000..2de6e52a --- /dev/null +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp @@ -0,0 +1,499 @@ +/**************************************************************************************** + * \file SHRigidBodyComponent.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for a Rigidbody Component. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHRigidBodyComponent.h" + +// Project Headers +#include "Tools/SHUtilities.h" +#include "Math/SHMathHelpers.h" +#include "Math/SHQuaternion.h" + +/*-------------------------------------------------------------------------------------*/ +/* Local Function Definitions */ +/*-------------------------------------------------------------------------------------*/ + + + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHRigidBodyComponent::SHRigidBodyComponent() noexcept + : rigidBody { nullptr } + , type { Type::DYNAMIC } + , mass { 1.0f } + , drag { 0.01f } + , angularDrag { 0.01f } + , flags { 0 } + { + // Set default flags: Gravity & Sleeping enabled + flags |= 1U << 0; + flags |= 1U << 1; + + // TODO(Diren): Send an update command to the physics system + } + + SHRigidBodyComponent::~SHRigidBodyComponent() + { + rigidBody = nullptr; + } + + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + bool SHRigidBodyComponent::IsGravityEnabled() const noexcept + { + const bool GRAVITY = flags & (1U << 0); + if (rigidBody) + { + SHASSERT(rigidBody->isGravityEnabled() == GRAVITY, "ReactPhysics and SHADE body enable gravity do not match!") + } + + return GRAVITY; + } + + bool SHRigidBodyComponent::IsSleepingEnabled() const noexcept + { + const bool SLEEP = flags & (1U << 1); + if (rigidBody) + { + SHASSERT(rigidBody->isAllowedToSleep() == SLEEP, "ReactPhysics and SHADE body enable sleep do not match!") + } + + return SLEEP; + } + + SHRigidBodyComponent::Type SHRigidBodyComponent::GetType() const noexcept + { + if (rigidBody) + { + SHASSERT + ( + SHUtilities::ConvertEnum(rigidBody->getType()) == SHUtilities::ConvertEnum(type), + "ReactPhysics and SHADE body types do not match!" + ) + } + + return type; + } + + float SHRigidBodyComponent::GetMass() const noexcept + { + if (rigidBody) + { + SHASSERT(rigidBody->getMass() == mass, "ReactPhysics and SHADE body masses do not match!") + } + + return mass; + } + + float SHRigidBodyComponent::GetDrag() const noexcept + { + if (rigidBody) + { + SHASSERT + ( + SHMath::CompareFloat(rigidBody->getLinearDamping(), drag), + "ReactPhysics and SADE body drag coefficients do not match!" + ) + } + + return drag; + } + + float SHRigidBodyComponent::GetAngularDrag() const noexcept + { + if (rigidBody) + { + SHASSERT + ( + SHMath::CompareFloat(rigidBody->getAngularDamping(), angularDrag), + "ReactPhysics and SADE body drag coefficients do not match!" + ) + } + + return angularDrag; + } + + bool SHRigidBodyComponent::GetFreezePositionX() const noexcept + { + const bool FREEZE_X_POS = flags & (1U << 2); + if (rigidBody) + { + const bool RP3D_FREEZE_X_POS = fabs(rigidBody->getLinearLockAxisFactor().x) > 0.0f; + SHASSERT(RP3D_FREEZE_X_POS == FREEZE_X_POS, "ReactPhysics and SHADE body x-axis position lock do not match!") + } + + return FREEZE_X_POS; + } + + bool SHRigidBodyComponent::GetFreezePositionY() const noexcept + { + const bool FREEZE_Y_POS = flags & (1U << 3); + if (rigidBody) + { + const bool RP3D_FREEZE_Y_POS = fabs(rigidBody->getLinearLockAxisFactor().y) > 0.0f; + SHASSERT(RP3D_FREEZE_Y_POS == FREEZE_Y_POS, "ReactPhysics and SHADE body y-axis position lock do not match!") + } + + return FREEZE_Y_POS; + } + + bool SHRigidBodyComponent::GetFreezePositionZ() const noexcept + { + const bool FREEZE_Z_POS = flags & (1U << 4); + if (rigidBody) + { + const bool RP3D_FREEZE_Z_POS = fabs(rigidBody->getLinearLockAxisFactor().z) > 0.0f; + SHASSERT(RP3D_FREEZE_Z_POS == FREEZE_Z_POS, "ReactPhysics and SHADE body z-axis position lock do not match!") + } + + return FREEZE_Z_POS; + } + + bool SHRigidBodyComponent::GetFreezeRotationX() const noexcept + { + const bool FREEZE_X_ROT = flags & (1U << 5); + if (rigidBody) + { + const bool RP3D_FREEZE_Y_ROT = fabs(rigidBody->getAngularLockAxisFactor().x) > 0.0f; + SHASSERT(RP3D_FREEZE_Y_ROT == FREEZE_X_ROT, "ReactPhysics and SHADE body x-axis rotation lock do not match!") + } + + return FREEZE_X_ROT; + } + + bool SHRigidBodyComponent::GetFreezeRotationY() const noexcept + { + const bool FREEZE_Y_ROT = flags & (1U << 6); + if (rigidBody) + { + const bool RP3D_FREEZE_Y_ROT = fabs(rigidBody->getAngularLockAxisFactor().y) > 0.0f; + SHASSERT(RP3D_FREEZE_Y_ROT == FREEZE_Y_ROT, "ReactPhysics and SHADE body y-axis rotation lock do not match!") + } + + return FREEZE_Y_ROT; + } + + bool SHRigidBodyComponent::GetFreezeRotationZ() const noexcept + { + const bool FREEZE_Z_ROT = flags & (1U << 7); + if (rigidBody) + { + const bool RP3D_FREEZE_Z_ROT = fabs(rigidBody->getAngularLockAxisFactor().z) > 0.0f; + SHASSERT(RP3D_FREEZE_Z_ROT == FREEZE_Z_ROT, "ReactPhysics and SHADE body z-axis rotation lock do not match!") + } + + return FREEZE_Z_ROT; + } + + SHVec3 SHRigidBodyComponent::GetForce() const noexcept + { + SHVec3 result; + + if (rigidBody) + { + const auto RP3D_RESULT = rigidBody->getForce(); + result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z }; + } + + return result; + } + + SHVec3 SHRigidBodyComponent::GetTorque() const noexcept + { + SHVec3 result; + + if (rigidBody) + { + const auto RP3D_RESULT = rigidBody->getTorque(); + result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z }; + } + + return result; + } + + SHVec3 SHRigidBodyComponent::GetLinearVelocity() const noexcept + { + SHVec3 result; + + if (rigidBody) + { + const auto RP3D_RESULT = rigidBody->getLinearVelocity(); + result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z }; + } + + return result; + } + + SHVec3 SHRigidBodyComponent::GetAngularVelocity() const noexcept + { + SHVec3 result; + + if (rigidBody) + { + const auto RP3D_RESULT = rigidBody->getAngularVelocity(); + result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z }; + } + + return result; + } + + SHVec3 SHRigidBodyComponent::GetPosition() const noexcept + { + SHVec3 result; + + if (rigidBody) + { + const auto RP3D_RESULT = rigidBody->getTransform().getPosition(); + result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z }; + } + + return result; + } + + SHQuaternion SHRigidBodyComponent::GetOrientation() const noexcept + { + SHQuaternion result; + + if (rigidBody) + { + const auto RP3D_RESULT = rigidBody->getTransform().getOrientation(); + result = SHQuaternion{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z, RP3D_RESULT.w }; + } + + return result; + } + + /*-----------------------------------------------------------------------------------*/ + /* Setter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHRigidBodyComponent::SetType(Type newType) noexcept + { + if (type == newType) + return; + + type = newType; + if (rigidBody) + rigidBody->setType(static_cast(newType)); + } + + void SHRigidBodyComponent::SetMass(float newMass) noexcept + { + mass = newMass; + if (rigidBody) + rigidBody->setMass(newMass); + } + + void SHRigidBodyComponent::SetDrag(float newDrag) noexcept + { + drag = newDrag; + if (rigidBody) + rigidBody->setLinearDamping(newDrag); + } + + void SHRigidBodyComponent::SetAngularDrag(float newAngularDrag) noexcept + { + angularDrag = newAngularDrag; + if (rigidBody) + rigidBody->setAngularDamping(newAngularDrag); + } + + void SHRigidBodyComponent::SetGravityEnabled(bool enableGravity) noexcept + { + SetFlag(enableGravity, 0); + if (rigidBody) + rigidBody->enableGravity(enableGravity); + } + + void SHRigidBodyComponent::SetSleepingEnabled(bool enableSleeping) noexcept + { + SetFlag(enableSleeping, 1); + if (rigidBody) + rigidBody->setIsAllowedToSleep(enableSleeping); + } + + void SHRigidBodyComponent::SetFreezePositionX(bool freezePositionX) noexcept + { + SetFlag(freezePositionX, 2); + SetRP3DLinearConstraints(); + } + + void SHRigidBodyComponent::SetFreezePositionY(bool freezePositionY) noexcept + { + SetFlag(freezePositionY, 3); + SetRP3DLinearConstraints(); + } + + void SHRigidBodyComponent::SetFreezePositionZ(bool freezePositionZ) noexcept + { + SetFlag(freezePositionZ, 4); + SetRP3DLinearConstraints(); + } + + void SHRigidBodyComponent::SetFreezeRotationX(bool freezeRotationX) noexcept + { + SetFlag(freezeRotationX, 5); + SetRP3DAngularConstraints(); + } + + void SHRigidBodyComponent::SetFreezeRotationY(bool freezeRotationY) noexcept + { + SetFlag(freezeRotationY, 6); + SetRP3DAngularConstraints(); + } + + void SHRigidBodyComponent::SetFreezeRotationZ(bool freezeRotationZ) noexcept + { + SetFlag(freezeRotationZ, 7); + SetRP3DAngularConstraints(); + } + + void SHRigidBodyComponent::SetLinearVelocity(const SHVec3& newLinearVelocity) const noexcept + { + if (rigidBody) + { + const rp3d::Vector3 NEW_V { newLinearVelocity.x, newLinearVelocity.y, newLinearVelocity.z }; + rigidBody->setLinearVelocity(NEW_V); + } + } + + void SHRigidBodyComponent::SetAngularVelocity(const SHVec3& newAngularVelocity) const noexcept + { + if (rigidBody) + { + const rp3d::Vector3 NEW_V { newAngularVelocity.x, newAngularVelocity.y, newAngularVelocity.z }; + rigidBody->setAngularVelocity(NEW_V); + } + } + + /*-----------------------------------------------------------------------------------*/ + /* Public Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHRigidBodyComponent::AddForce(const SHVec3& force) const noexcept + { + if (rigidBody) + { + const rp3d::Vector3 F { force.x, force.y, force.z }; + rigidBody->applyWorldForceAtCenterOfMass(F); + } + } + + void SHRigidBodyComponent::AddForceAtLocalPos(const SHVec3& force, const SHVec3& localPos) const noexcept + { + if (rigidBody) + { + const rp3d::Vector3 F{ force.x, force.y, force.z }; + const rp3d::Vector3 P{ localPos.x, localPos.y, localPos.z }; + rigidBody->applyWorldForceAtLocalPosition(F, P); + } + } + + void SHRigidBodyComponent::AddForceAtWorldPos(const SHVec3& force, const SHVec3& worldPos) const noexcept + { + if (rigidBody) + { + const rp3d::Vector3 F{ force.x, force.y, force.z }; + const rp3d::Vector3 P{ worldPos.x, worldPos.y, worldPos.z }; + rigidBody->applyWorldForceAtWorldPosition(F, P); + } + } + + void SHRigidBodyComponent::AddRelativeForce(const SHVec3& relativeForce) const noexcept + { + if (rigidBody) + { + const rp3d::Vector3 F{ relativeForce.x, relativeForce.y, relativeForce.z }; + rigidBody->applyLocalForceAtCenterOfMass(F); + } + } + + void SHRigidBodyComponent::AddRelativeForceAtLocalPos(const SHVec3& relativeForce, const SHVec3& localPos) const noexcept + { + if (rigidBody) + { + const rp3d::Vector3 F{ relativeForce.x, relativeForce.y, relativeForce.z }; + const rp3d::Vector3 P{ localPos.x, localPos.y, localPos.z }; + rigidBody->applyLocalForceAtLocalPosition(F, P); + } + } + + void SHRigidBodyComponent::AddRelativeForceAtWorldPos(const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept + { + if (rigidBody) + { + const rp3d::Vector3 F{ relativeForce.x, relativeForce.y, relativeForce.z }; + const rp3d::Vector3 P{ worldPos.x, worldPos.y, worldPos.z }; + rigidBody->applyLocalForceAtWorldPosition(F, P); + } + } + + void SHRigidBodyComponent::AddTorque(const SHVec3& torque) const noexcept + { + if (rigidBody) + { + const rp3d::Vector3 T{ torque.x, torque.y, torque.z }; + rigidBody->applyWorldTorque(T); + } + } + + void SHRigidBodyComponent::AddRelativeTorque(const SHVec3& relativeTorque) const noexcept + { + if (rigidBody) + { + const rp3d::Vector3 T{ relativeTorque.x, relativeTorque.y, relativeTorque.z }; + rigidBody->applyLocalTorque(T); + } + } + + /*-----------------------------------------------------------------------------------*/ + /* Private Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHRigidBodyComponent::SetFlag(bool flagState, int flagPos) + { + flagState ? flags |= (1U << flagPos) : flags &= ~(1U << flagPos); + } + + void SHRigidBodyComponent::SetRP3DLinearConstraints() const + { + const rp3d::Vector3 CONSTRAINTS + { + flags & 1U << 2 ? 1.0f : 0.0f, + flags & 1U << 3 ? 1.0f : 0.0f, + flags & 1U << 4 ? 1.0f : 0.0f + }; + + if (rigidBody) + rigidBody->setLinearLockAxisFactor(CONSTRAINTS); + } + + void SHRigidBodyComponent::SetRP3DAngularConstraints() const + { + const rp3d::Vector3 CONSTRAINTS + { + flags & 1U << 5 ? 1.0f : 0.0f, + flags & 1U << 6 ? 1.0f : 0.0f, + flags & 1U << 7 ? 1.0f : 0.0f + }; + + if (rigidBody) + rigidBody->setAngularLockAxisFactor(CONSTRAINTS); + } + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h new file mode 100644 index 00000000..69338b1e --- /dev/null +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h @@ -0,0 +1,147 @@ +/**************************************************************************************** + * \file SHRigidBodyComponent.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for a Rigidbody Component. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include + +// Project Headers +#include "Math/Vector/SHVec3.h" +#include "Math/SHMatrix.h" +#include "ECS_Base/Components/SHComponent.h" + +namespace SHADE +{ + class SH_API SHRigidBodyComponent : public SHComponent + { + public: + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + + enum class Type + { + STATIC + , KINEMATIC + , DYNAMIC + + , COUNT + }; + + // TODO(Diren): Collision Types + + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHRigidBodyComponent () noexcept; + SHRigidBodyComponent (const SHRigidBodyComponent& rhs) noexcept = default; + SHRigidBodyComponent (SHRigidBodyComponent&& rhs) noexcept = default; + ~SHRigidBodyComponent () override; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + SHRigidBodyComponent& operator=(const SHRigidBodyComponent& rhs) noexcept = default; + SHRigidBodyComponent& operator=(SHRigidBodyComponent&& rhs) noexcept = default; + + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] bool IsGravityEnabled () const noexcept; + [[nodiscard]] bool IsSleepingEnabled () const noexcept; + + [[nodiscard]] Type GetType () const noexcept; + [[nodiscard]] float GetMass () const noexcept; + [[nodiscard]] float GetDrag () const noexcept; + [[nodiscard]] float GetAngularDrag () const noexcept; + + [[nodiscard]] bool GetFreezePositionX () const noexcept; + [[nodiscard]] bool GetFreezePositionY () const noexcept; + [[nodiscard]] bool GetFreezePositionZ () const noexcept; + + [[nodiscard]] bool GetFreezeRotationX () const noexcept; + [[nodiscard]] bool GetFreezeRotationY () const noexcept; + [[nodiscard]] bool GetFreezeRotationZ () const noexcept; + + [[nodiscard]] SHVec3 GetForce () const noexcept; + [[nodiscard]] SHVec3 GetTorque () const noexcept; + [[nodiscard]] SHVec3 GetLinearVelocity () const noexcept; + [[nodiscard]] SHVec3 GetAngularVelocity () const noexcept; + [[nodiscard]] SHVec3 GetPosition () const noexcept; + [[nodiscard]] SHQuaternion GetOrientation () const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Setter Functions */ + /*---------------------------------------------------------------------------------*/ + + void SetType (Type newType) noexcept; + void SetMass (float newMass) noexcept; + void SetDrag (float newDrag) noexcept; + void SetAngularDrag (float newAngularDrag) noexcept; + + void SetGravityEnabled (bool enableGravity) noexcept; + void SetSleepingEnabled (bool enableSleeping) noexcept; + void SetFreezePositionX (bool freezePositionX) noexcept; + void SetFreezePositionY (bool freezePositionY) noexcept; + void SetFreezePositionZ (bool freezePositionZ) noexcept; + void SetFreezeRotationX (bool freezeRotationX) noexcept; + void SetFreezeRotationY (bool freezeRotationY) noexcept; + void SetFreezeRotationZ (bool freezeRotationZ) noexcept; + + void SetLinearVelocity (const SHVec3& newLinearVelocity) const noexcept; + void SetAngularVelocity (const SHVec3& newAngularVelocity) const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + void AddForce (const SHVec3& force) const noexcept; + void AddForceAtLocalPos (const SHVec3& force, const SHVec3& localPos) const noexcept; + void AddForceAtWorldPos (const SHVec3& force, const SHVec3& worldPos) const noexcept; + + void AddRelativeForce (const SHVec3& relativeForce) const noexcept; + void AddRelativeForceAtLocalPos (const SHVec3& relativeForce, const SHVec3& localPos) const noexcept; + void AddRelativeForceAtWorldPos (const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept; + + void AddTorque (const SHVec3& torque) const noexcept; + void AddRelativeTorque (const SHVec3& relativeTorque) const noexcept; + + private: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + rp3d::RigidBody* rigidBody; + + Type type; + + float mass; + float drag; + float angularDrag; + + SHMatrix inertiaTensor; + + // rX rY rZ pX pY pZ slp g + uint8_t flags; + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + void SetFlag (bool flagState, int flagPos); + void SetRP3DLinearConstraints () const ; + void SetRP3DAngularConstraints () const ; + + + }; +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/SHpch.h b/SHADE_Engine/src/SHpch.h index 8b2f11f3..7e308829 100644 --- a/SHADE_Engine/src/SHpch.h +++ b/SHADE_Engine/src/SHpch.h @@ -38,3 +38,4 @@ #include "Common/SHCommonTypes.h" #include "Tools/SHLogger.h" +#include "Tools/SHException.h" diff --git a/SHADE_Engine/src/Tools/SHException.h b/SHADE_Engine/src/Tools/SHException.h index 251217eb..2e0b82a9 100644 --- a/SHADE_Engine/src/Tools/SHException.h +++ b/SHADE_Engine/src/Tools/SHException.h @@ -75,10 +75,13 @@ namespace SHADE }; } -#define SHASSERT(cond, msg) \ - if (!(cond)) \ - { \ - SHLOGV_CRITICAL(msg) \ - std::abort(); \ - } - +#ifdef _DEBUG + #define SHASSERT(cond, msg) \ + if (!(cond)) \ + { \ + SHLOGV_CRITICAL(msg) \ + std::abort(); \ + } +#else + #define SHASSERT(cond, msg) { } +#endif From a08b12381457c3f26910926f1ab1ab471fdf05e4 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Wed, 28 Sep 2022 13:34:35 +0800 Subject: [PATCH 02/61] Added reactphysics to SHADE_Application premake file --- SHADE_Application/premake5.lua | 3 +- .../src/Application/SBApplication.cpp | 31 +++++++++++++------ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/SHADE_Application/premake5.lua b/SHADE_Application/premake5.lua index b34b06fa..27910231 100644 --- a/SHADE_Application/premake5.lua +++ b/SHADE_Application/premake5.lua @@ -35,7 +35,8 @@ project "SHADE_Application" "%{IncludeDir.VMA}/include", "%{IncludeDir.VULKAN}/Source/SPIRV-Reflect", "%{IncludeDir.RTTR}/include", - "%{IncludeDir.tinyddsloader}" + "%{IncludeDir.tinyddsloader}", + "%{IncludeDir.reactphysics3d}\\include" } externalwarnings "Off" diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 20aa3b5a..82ca0f1c 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -17,16 +17,25 @@ #define SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN 1 #include -#include "Scripting/SHScriptEngine.h" + #include "Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.h" + +// Managers #include "ECS_Base/Managers/SHEntityManager.h" -#include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Scene/SHSceneManager.h" -#include "Math/Transform/SHTransformSystem.h" + +// Systems #include "Input/SHInputManagerSystem.h" +#include "Scripting/SHScriptEngine.h" +#include "Physics/SHPhysicsSystem.h" +#include "Math/Transform/SHTransformSystem.h" + +// Components +#include "Graphics/MiddleEnd/Interface/SHRenderable.h" +#include "Math/Transform/SHTransformComponent.h" #include "Scenes/SBTestScene.h" -#include "Math/Transform/SHTransformComponent.h" + #include "Assets/SHAssetManager.h" @@ -51,31 +60,33 @@ namespace Sandbox // Create Systems SHADE::SHSystemManager::CreateSystem(); SHADE::SHSystemManager::CreateSystem(); - // TODO(Diren): Create Physics System here + SHADE::SHSystemManager::CreateSystem(); SHADE::SHSystemManager::CreateSystem(); SHADE::SHGraphicsSystem* graphicsSystem = static_cast(SHADE::SHSystemManager::GetSystem()); SHADE::SHSystemManager::CreateSystem(); // Create Routines + SHADE::SHSystemManager::RegisterRoutine(); + SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHSystemManager::RegisterRoutine(); - // TODO(Diren): Register Physics System & Routines here + SHADE::SHSystemManager::RegisterRoutine(); + SHADE::SHSystemManager::RegisterRoutine(); + SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHSystemManager::RegisterRoutine(); - SHADE::SHComponentManager::CreateComponentSparseSet(); SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHSystemManager::RegisterRoutine(); - SHADE::SHComponentManager::CreateComponentSparseSet(); SHADE::SHComponentManager::CreateComponentSparseSet(); - - SHADE::SHSystemManager::RegisterRoutine(); + SHADE::SHComponentManager::CreateComponentSparseSet(); + SHADE::SHComponentManager::CreateComponentSparseSet(); //TODO: REMOVE AFTER PRESENTATION SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf"); From 097b1be3f7e23924fc5f562cf0ee802491aca171 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Wed, 28 Sep 2022 16:15:36 +0800 Subject: [PATCH 03/61] Added Physics System --- .../src/Application/SBApplication.cpp | 1 - .../ECS_Base/System/SHFixedSystemRoutine.h | 16 +- .../Components/SHRigidBodyComponent.cpp | 15 + .../Physics/Components/SHRigidBodyComponent.h | 10 +- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 446 ++++++++++++++++++ SHADE_Engine/src/Physics/SHPhysicsSystem.h | 237 ++++++++++ 6 files changed, 712 insertions(+), 13 deletions(-) create mode 100644 SHADE_Engine/src/Physics/SHPhysicsSystem.cpp create mode 100644 SHADE_Engine/src/Physics/SHPhysicsSystem.h diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 82ca0f1c..fdc933b9 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -86,7 +86,6 @@ namespace Sandbox SHADE::SHComponentManager::CreateComponentSparseSet(); SHADE::SHComponentManager::CreateComponentSparseSet(); - SHADE::SHComponentManager::CreateComponentSparseSet(); //TODO: REMOVE AFTER PRESENTATION SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf"); diff --git a/SHADE_Engine/src/ECS_Base/System/SHFixedSystemRoutine.h b/SHADE_Engine/src/ECS_Base/System/SHFixedSystemRoutine.h index d9a2b510..d54d9441 100644 --- a/SHADE_Engine/src/ECS_Base/System/SHFixedSystemRoutine.h +++ b/SHADE_Engine/src/ECS_Base/System/SHFixedSystemRoutine.h @@ -8,23 +8,19 @@ namespace SHADE { class SHFixedSystemRoutine: public SHSystemRoutine { - private: - double accumulatedTime; - double fixedTimeStep; - protected: - SHFixedSystemRoutine(double timeStep = DEFAULT_FIXED_STEP, std::string routineName = "Default Fixed Routine Name", bool editorPause = false) + double accumulatedTime; + double fixedTimeStep; + + SHFixedSystemRoutine(double timeStep = DEFAULT_FIXED_STEP, std::string routineName = "Default Fixed Routine Name", bool editorPause = false) :SHSystemRoutine(routineName, editorPause), accumulatedTime(0.0), fixedTimeStep(timeStep){} - - public: ~SHFixedSystemRoutine() = default; - virtual void Execute(double dt) noexcept; - - virtual void FixedExecute(double dt) noexcept {}; + virtual void Execute(double dt) noexcept override; + virtual void FixedExecute(double dt) noexcept {} }; diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp index 2de6e52a..e3989d6e 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp @@ -465,6 +465,21 @@ namespace SHADE /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ + void SHRigidBodyComponent::SyncRP3DAndSHADE() + { + rigidBody->setType(static_cast(type)); + + rigidBody->setMass(mass); + rigidBody->setLinearDamping(drag); + rigidBody->setAngularDamping(angularDrag); + + rigidBody->enableGravity(flags & (1U << 0)); + rigidBody->setIsAllowedToSleep(flags & (1U << 1)); + SetRP3DLinearConstraints(); + SetRP3DAngularConstraints(); + } + + void SHRigidBodyComponent::SetFlag(bool flagState, int flagPos) { flagState ? flags |= (1U << flagPos) : flags &= ~(1U << flagPos); diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h index 69338b1e..668ab6bd 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h @@ -21,6 +21,13 @@ namespace SHADE { class SH_API SHRigidBodyComponent : public SHComponent { + private: + /*---------------------------------------------------------------------------------*/ + /* Friends */ + /*---------------------------------------------------------------------------------*/ + + friend class SHPhysicsSystem; + public: /*---------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -128,8 +135,6 @@ namespace SHADE float mass; float drag; float angularDrag; - - SHMatrix inertiaTensor; // rX rY rZ pX pY pZ slp g uint8_t flags; @@ -138,6 +143,7 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ + void SyncRP3DAndSHADE (); void SetFlag (bool flagState, int flagPos); void SetRP3DLinearConstraints () const ; void SetRP3DAngularConstraints () const ; diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp new file mode 100644 index 00000000..537c2c70 --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -0,0 +1,446 @@ +/**************************************************************************************** + * \file SHPhysicsSystem.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for the Physics System + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHPhysicsSystem.h" + +// Project Headers +#include "Math/Transform/SHTransformComponent.h" +#include "Scene/SHSceneManager.h" +#include "ECS_Base/Managers/SHComponentManager.h" +#include "ECS_Base/Managers/SHEntityManager.h" +#include "Graphics/MiddleEnd/Interface/SHRenderable.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHPhysicsSystem::PhysicsPreUpdate::PhysicsPreUpdate() + : SHSystemRoutine { "Physics PreUpdate", true } + {} + + SHPhysicsSystem::PhysicsFixedUpdate::PhysicsFixedUpdate() + : SHFixedSystemRoutine { DEFAULT_FIXED_STEP, "Physics FixedUpdate", true } + {} + + SHPhysicsSystem::PhysicsPostUpdate::PhysicsPostUpdate() + : SHSystemRoutine { "Physics PostUpdate", true } + {} + + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + bool SHPhysicsSystem::IsSleepingEnabled() const noexcept + { + if (world) + return world->isSleepingEnabled(); + + SHLOGV_WARNING("No physics world has been initialised!") + return false; + } + + //double SHPhysicsSystem::GetFixedUpdate() const noexcept + //{ + // return fixedUpdate; + //} + + SHVec3 SHPhysicsSystem::GetWorldGravity() const noexcept + { + SHVec3 result; + + if (world) + { + const auto RP3D_GRAVITY = world->getGravity(); + result.x = RP3D_GRAVITY.x; + result.y = RP3D_GRAVITY.y; + result.z = RP3D_GRAVITY.z; + } + else + { + SHLOGV_WARNING("No physics world has been initialised!") + } + + return result; + } + + uint16_t SHPhysicsSystem::GetNumberVelocityIterations() const noexcept + { + if (world) + return world->getNbIterationsVelocitySolver(); + + SHLOGV_WARNING("No physics world has been initialised!") + return 0; + } + + uint16_t SHPhysicsSystem::GetNumberPositionIterations() const noexcept + { + if (world) + return world->getNbIterationsPositionSolver(); + + SHLOGV_WARNING("No physics world has been initialised!") + return 0; + } + + /*-----------------------------------------------------------------------------------*/ + /* Setter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + //void SHPhysicsSystem::SetFixedUpdate(double fixedUpdateRate) noexcept + //{ + // fixedUpdate = fixedUpdateRate; + // SHLOG_INFO("Setting Physics update rate to {}", 1.0 / fixedUpdate) + //} + + void SHPhysicsSystem::SetWorldGravity(const SHVec3& gravity) const noexcept + { + if (world) + { + const rp3d::Vector3 G { gravity.x, gravity.y, gravity.z }; + world->setGravity(G); + } + else + { + SHLOGV_WARNING("No physics world has been initialised!") + } + } + + void SHPhysicsSystem::SetNumberVelocityIterations(uint16_t numVelIterations) const noexcept + { + if (world) + { + world->setNbIterationsVelocitySolver(numVelIterations); + } + else + { + SHLOGV_WARNING("No physics world has been initialised!") + } + } + + void SHPhysicsSystem::SetNumberPositionIterations(uint16_t numPosIterations) const noexcept + { + if (world) + { + world->setNbIterationsPositionSolver(numPosIterations); + } + else + { + SHLOGV_WARNING("No physics world has been initialised!") + } + } + + void SHPhysicsSystem::SetSleepingEnabled(bool enableSleeping) const noexcept + { + if (world) + { + world->enableSleeping(enableSleeping); + } + else + { + SHLOGV_WARNING("No physics world has been initialised!") + } + } + + void SHPhysicsSystem::SetWorldSettings(const WorldSettings& settings) const noexcept + { + if (world) + { + const rp3d::Vector3 G { settings.gravity.x, settings.gravity.y, settings.gravity.z }; + world->setGravity(G); + world->setNbIterationsVelocitySolver(settings.numVelocitySolverIterations); + world->setNbIterationsPositionSolver(settings.numPositionSolverIterations); + world->enableSleeping(settings.sleepingEnabled); + } + else + { + SHLOGV_WARNING("No physics world has been initialised!") + } + } + + /*-----------------------------------------------------------------------------------*/ + /* Public Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHPhysicsSystem::Init() + { + using namespace rp3d; + + // Create a physics world with the default settings + PhysicsWorld::WorldSettings settings; + settings.gravity = Vector3{ 0, -9.81, 0 }; + settings.isSleepingEnabled = true; + settings.defaultVelocitySolverNbIterations = 8; + settings.defaultPositionSolverNbIterations = 3; + + world = factory.createPhysicsWorld(settings); + + // Create component sparse sets + SHADE::SHComponentManager::CreateComponentSparseSet(); + } + + void SHPhysicsSystem::Exit() + { + factory.destroyPhysicsWorld(world); + } + + void SHPhysicsSystem::AddRigidBodyComponent(EntityID id) noexcept + { + const UpdateCommand NEW_CMD + { + .component = UpdateComponent::RIGID_BODY, + .type = UpdateType::ADD, + .entityID = id + }; + + updateQueue.push(NEW_CMD); + } + + void SHPhysicsSystem::AddColliderComponent(EntityID id) noexcept + { + const UpdateCommand NEW_CMD + { + .component = UpdateComponent::COLLIDER, + .type = UpdateType::ADD, + .entityID = id + }; + + updateQueue.push(NEW_CMD); + } + + void SHPhysicsSystem::RemoveRigidBodyComponent(EntityID id) noexcept + { + const UpdateCommand NEW_CMD + { + .component = UpdateComponent::RIGID_BODY, + .type = UpdateType::REMOVE, + .entityID = id + }; + + updateQueue.push(NEW_CMD); + } + + void SHPhysicsSystem::RemoveColliderComponent(EntityID id) noexcept + { + const UpdateCommand NEW_CMD + { + .component = UpdateComponent::COLLIDER, + .type = UpdateType::REMOVE, + .entityID = id + }; + + updateQueue.push(NEW_CMD); + } + + void SHPhysicsSystem::PhysicsPreUpdate::Execute([[maybe_unused]]double dt) noexcept + { + auto* system = reinterpret_cast(GetSystem()); + system->ClearUpdateQueue(); + + // Sync active states: if node or component is not active, set rp3d to inactive + static const auto SYNC_ACTIVE = [](SHSceneNode* node) + { + const EntityID ENTITY_ID = node->GetEntityID(); + + // Check if has rigid body + auto const* rigidBodyComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + if(rigidBodyComponent) + { + const bool RP3D_ACTIVE = rigidBodyComponent->rigidBody->isActive(); + const bool SHADE_ACTIVE = node->IsActive() && rigidBodyComponent->isActive; + + if (RP3D_ACTIVE != SHADE_ACTIVE) + rigidBodyComponent->rigidBody->setIsActive(SHADE_ACTIVE); + } + else // Check for a collider + { + + } + }; + + const auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + sceneGraph.Traverse(SYNC_ACTIVE); + } + + //void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept + //{ + // // I had to override this anyway due to needing to calculate the + // // interpolation factor right after the fixed update was done + + // auto* system = reinterpret_cast(GetSystem()); + // fixedTimeStep = 1.0 / system->fixedUpdate; + + // accumulatedTime += dt; + // int counter = 0; + + // while (accumulatedTime > fixedTimeStep) + // { + // FixedExecute(fixedTimeStep); + + // accumulatedTime -= fixedTimeStep; + // ++counter; + // } + + // stats.numSteps = counter; + + // system->interpolationFactor = accumulatedTime / fixedTimeStep; + //} + + void SHPhysicsSystem::PhysicsFixedUpdate::FixedExecute(double dt) noexcept + { + auto* system = reinterpret_cast(GetSystem()); + system->world->update(static_cast(dt)); + + system->fixedDT = fixedTimeStep; + system->accumulatedTime = accumulatedTime; + } + + void SHPhysicsSystem::PhysicsPostUpdate::Execute(double dt) noexcept + { + // Interpolate transforms for rendering + const auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + sceneGraph.Traverse([](SHSceneNode* node) + { + const EntityID ENTITY_ID = node->GetEntityID(); + + // Check if has rigid body + if (auto* rb = SHComponentManager::GetComponent_s(ENTITY_ID); rb) + { + // TODO(Diren): Interpolate transforms for rendering + if (node->IsActive() && rb->isActive) + { + // Get SHADE transform + auto* transformComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + SHASSERT(transformComponent != nullptr, "Transform Component missing from Entity " + std::to_string(ENTITY_ID)) + + const auto& RP3D_POS = rb->GetPosition(); + const SHVec3 SHADE_POS{ RP3D_POS.x, RP3D_POS.y, RP3D_POS.z }; + + const auto& SHADE_ROT = rb->GetOrientation().ToEuler(); + + transformComponent->SetWorldPosition(SHADE_POS); + transformComponent->SetWorldRotation(SHADE_ROT); + } + else // Check for a collider + { + + } + } + }); + + // TODO(Diren): Handle trigger messages for scripting + } + + /*-----------------------------------------------------------------------------------*/ + /* Private Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHPhysicsSystem::ClearUpdateQueue() noexcept + { + while (!updateQueue.empty()) + { + const auto& CMD = updateQueue.front(); + switch (CMD.type) + { + case UpdateType::ADD: + { + switch (CMD.component) + { + case UpdateComponent::RIGID_BODY: AddRigidBody(CMD.entityID); break; + //case UpdateComponent::COLLIDER: AddCollider(CMD.entityID); break; + default: break; + } + } + case UpdateType::REMOVE: + { + switch (CMD.component) + { + case UpdateComponent::RIGID_BODY: RemoveRigidBody(CMD.entityID); break; + //case UpdateComponent::COLLIDER: RemoveCollider(CMD.entityID); break; + default: break; + } + } + default: break; + } + + updateQueue.pop(); + } + } + + + void SHPhysicsSystem::AddRigidBody(EntityID entityID) const noexcept + { + #ifdef _DEBUG + SHLOG_INFO("Adding a Rigidbody to the Physics World.") + #endif + + // Rigid Bodies need a transform. + auto const* transformComponent = SHComponentManager::GetComponent_s(entityID); + if (!transformComponent) + { + // NOTE: This should already be handled by the editor. + + SHLOG_INFO("Automatically adding a transform to Entity {}", entityID) + SHComponentManager::AddComponent(entityID); + transformComponent = SHComponentManager::GetComponent(entityID); + } + + const SHVec3& SHADE_WORLD_POSITION = transformComponent->GetWorldPosition(); + const rp3d::Vector3 RP3D_POSITION { SHADE_WORLD_POSITION.x, SHADE_WORLD_POSITION.y, SHADE_WORLD_POSITION.z }; + + const SHVec3& SHADE_WORLD_ROTATION = transformComponent->GetWorldRotation(); + const rp3d::Quaternion RP3D_ORIENTATION = rp3d::Quaternion::fromEulerAngles(SHADE_WORLD_ROTATION.x, SHADE_WORLD_ROTATION.y, SHADE_WORLD_ROTATION.z); + + const rp3d::Transform RP3D_TF { RP3D_POSITION, RP3D_ORIENTATION }; + + auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); + if (!rigidBodyComponent) + { + // NOTE: This should already be handled by the editor. + + SHLOG_INFO("Automatically adding a rigidbody to Entity {}", entityID) + SHComponentManager::AddComponent(entityID); + rigidBodyComponent = SHComponentManager::GetComponent(entityID); + } + + rigidBodyComponent->rigidBody = world->createRigidBody(RP3D_TF); + rigidBodyComponent->SyncRP3DAndSHADE(); + + // Reassign collider + //if (collider) + //{ + // collider. + //} + } + + void SHPhysicsSystem::RemoveRigidBody(EntityID entityID) const noexcept + { + #ifdef _DEBUG + SHLOG_INFO("Removing a Rigidbody from the Physics World.") + #endif + + auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); + if (rigidBodyComponent == nullptr) + { + SHLOG_ERROR("Entity {} does not have a rigidbody component to remove!", entityID) + return; + } + + // If a collider exists, remake the colliders with a collision body + + world->destroyRigidBody(rigidBodyComponent->rigidBody); + rigidBodyComponent->rigidBody = nullptr; // this should be redundant + } + + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h new file mode 100644 index 00000000..dac6836a --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -0,0 +1,237 @@ +/**************************************************************************************** + * \file SHPhysicsSystem.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for the Physics System + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include +#include + +#include + +// Project Headers +#include "Math/SHQuaternion.h" +#include "Components/SHRigidBodyComponent.h" + +#include "Scene/SHSceneGraph.h" +#include "ECS_Base/System/SHSystemRoutine.h" +#include "ECS_Base/System/SHFixedSystemRoutine.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SH_API SHPhysicsSystem : public SHSystem + { + public: + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + + struct WorldSettings + { + SHVec3 gravity; + uint16_t numVelocitySolverIterations; + uint16_t numPositionSolverIterations; + bool sleepingEnabled; + }; + + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHPhysicsSystem () = default; + ~SHPhysicsSystem () override = default; + + SHPhysicsSystem (const SHPhysicsSystem&) = delete; + SHPhysicsSystem (SHPhysicsSystem&&) = delete; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + SHPhysicsSystem& operator= (const SHPhysicsSystem&) = delete; + SHPhysicsSystem& operator= (SHPhysicsSystem&&) = delete; + + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] bool IsSleepingEnabled () const noexcept; + + //[[nodiscard]] double GetFixedUpdate () const noexcept; + [[nodiscard]] SHVec3 GetWorldGravity () const noexcept; + [[nodiscard]] uint16_t GetNumberVelocityIterations () const noexcept; + [[nodiscard]] uint16_t GetNumberPositionIterations () const noexcept; + + + /*---------------------------------------------------------------------------------*/ + /* Setter Functions */ + /*---------------------------------------------------------------------------------*/ + + //void SetFixedUpdate (double fixedUpdateRate) noexcept; + void SetWorldGravity (const SHVec3& gravity) const noexcept; + void SetNumberVelocityIterations (uint16_t numVelIterations) const noexcept; + void SetNumberPositionIterations (uint16_t numPosIterations) const noexcept; + void SetSleepingEnabled (bool enableSleeping) const noexcept; + + void SetWorldSettings (const WorldSettings& settings) const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + void Init () override; + void Exit () override; + + void AddRigidBodyComponent (EntityID id) noexcept; + void AddColliderComponent (EntityID id) noexcept; + void RemoveRigidBodyComponent (EntityID id) noexcept; + void RemoveColliderComponent (EntityID id) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* System Routines */ + /*---------------------------------------------------------------------------------*/ + + class SH_API PhysicsPreUpdate : public SHSystemRoutine + { + public: + /*-------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*-------------------------------------------------------------------------------*/ + + PhysicsPreUpdate(); + ~PhysicsPreUpdate() = default; + + PhysicsPreUpdate(const PhysicsPreUpdate&) = delete; + PhysicsPreUpdate(PhysicsPreUpdate&&) = delete; + + /*-------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-------------------------------------------------------------------------------*/ + + PhysicsPreUpdate& operator= (const PhysicsPreUpdate&) = delete; + PhysicsPreUpdate& operator= (PhysicsPreUpdate&&) = delete; + + /*-------------------------------------------------------------------------------*/ + /* Function Members */ + /*-------------------------------------------------------------------------------*/ + + void Execute(double dt) noexcept override; + }; + + class SH_API PhysicsFixedUpdate : public SHFixedSystemRoutine + { + public: + /*-------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*-------------------------------------------------------------------------------*/ + + PhysicsFixedUpdate(); + ~PhysicsFixedUpdate() = default; + + PhysicsFixedUpdate(const PhysicsFixedUpdate&) = delete; + PhysicsFixedUpdate(PhysicsFixedUpdate&&) = delete; + + /*-------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-------------------------------------------------------------------------------*/ + + PhysicsFixedUpdate& operator= (const PhysicsFixedUpdate&) = delete; + PhysicsFixedUpdate& operator= (PhysicsFixedUpdate&&) = delete; + + /*-------------------------------------------------------------------------------*/ + /* Function Members */ + /*-------------------------------------------------------------------------------*/ + + //void Execute (double dt) noexcept override; + void FixedExecute (double dt) noexcept override; + }; + + class SH_API PhysicsPostUpdate : public SHSystemRoutine + { + public: + /*-------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*-------------------------------------------------------------------------------*/ + + PhysicsPostUpdate(); + ~PhysicsPostUpdate() = default; + + PhysicsPostUpdate(const PhysicsPostUpdate&) = delete; + PhysicsPostUpdate(PhysicsPostUpdate&&) = delete; + + /*-------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-------------------------------------------------------------------------------*/ + + PhysicsPostUpdate& operator= (const PhysicsPostUpdate&) = delete; + PhysicsPostUpdate& operator= (PhysicsPostUpdate&&) = delete; + + /*-------------------------------------------------------------------------------*/ + /* Function Members */ + /*-------------------------------------------------------------------------------*/ + + void Execute(double dt) noexcept override; + }; + + + private: + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + + enum class UpdateComponent { RIGID_BODY, COLLIDER }; + enum class UpdateType { ADD, REMOVE }; + + struct UpdateCommand + { + UpdateComponent component; + UpdateType type; + EntityID entityID; + }; + + struct CachedTransform + { + SHVec3 position; + SHQuaternion orientation; + }; + + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + //double interpolationFactor; + //double fixedUpdate; + + double accumulatedTime; + double fixedDT; + + rp3d::PhysicsCommon factory; + rp3d::PhysicsWorld* world; + + std::queue updateQueue; + std::unordered_map prevTransforms; // used for interpolation + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + void ClearUpdateQueue () noexcept; + + void AddRigidBody (EntityID entityID) const noexcept; + void AddCollider (EntityID entityID) const noexcept; + void RemoveRigidBody (EntityID entityID) const noexcept; + void RemoveCollider (EntityID entityID) const noexcept; + }; + + +} // namespace SHADE \ No newline at end of file From 561f2b091f231582896f94c6aca6f74fd3ddcdd4 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Wed, 28 Sep 2022 21:09:27 +0800 Subject: [PATCH 04/61] Added PhysicsObject to handle interface between components and physics system --- .../Components/SHRigidBodyComponent.cpp | 206 +++++++------- .../Physics/Components/SHRigidBodyComponent.h | 21 +- SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 112 ++++++++ SHADE_Engine/src/Physics/SHPhysicsObject.h | 82 ++++++ SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 252 ++++++++---------- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 103 +++---- 6 files changed, 446 insertions(+), 330 deletions(-) create mode 100644 SHADE_Engine/src/Physics/SHPhysicsObject.cpp create mode 100644 SHADE_Engine/src/Physics/SHPhysicsObject.h diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp index e3989d6e..16863dbd 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp @@ -18,12 +18,6 @@ #include "Math/SHMathHelpers.h" #include "Math/SHQuaternion.h" -/*-------------------------------------------------------------------------------------*/ -/* Local Function Definitions */ -/*-------------------------------------------------------------------------------------*/ - - - namespace SHADE { /*-----------------------------------------------------------------------------------*/ @@ -31,8 +25,7 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHRigidBodyComponent::SHRigidBodyComponent() noexcept - : rigidBody { nullptr } - , type { Type::DYNAMIC } + : type { Type::DYNAMIC } , mass { 1.0f } , drag { 0.01f } , angularDrag { 0.01f } @@ -41,13 +34,11 @@ namespace SHADE // Set default flags: Gravity & Sleeping enabled flags |= 1U << 0; flags |= 1U << 1; - - // TODO(Diren): Send an update command to the physics system } SHRigidBodyComponent::~SHRigidBodyComponent() { - rigidBody = nullptr; + } /*-----------------------------------------------------------------------------------*/ @@ -57,9 +48,10 @@ namespace SHADE bool SHRigidBodyComponent::IsGravityEnabled() const noexcept { const bool GRAVITY = flags & (1U << 0); - if (rigidBody) + if (rp3dBody) { - SHASSERT(rigidBody->isGravityEnabled() == GRAVITY, "ReactPhysics and SHADE body enable gravity do not match!") + + SHASSERT(reinterpret_cast(rp3dBody)->isGravityEnabled() == GRAVITY, "ReactPhysics and SHADE body enable gravity do not match!") } return GRAVITY; @@ -68,21 +60,26 @@ namespace SHADE bool SHRigidBodyComponent::IsSleepingEnabled() const noexcept { const bool SLEEP = flags & (1U << 1); - if (rigidBody) + if (rp3dBody) { - SHASSERT(rigidBody->isAllowedToSleep() == SLEEP, "ReactPhysics and SHADE body enable sleep do not match!") + SHASSERT(reinterpret_cast(rp3dBody)->isAllowedToSleep() == SLEEP, "ReactPhysics and SHADE body enable sleep do not match!") } return SLEEP; } + bool SHRigidBodyComponent::IsInterpolating() const noexcept + { + return interpolate; + } + SHRigidBodyComponent::Type SHRigidBodyComponent::GetType() const noexcept { - if (rigidBody) + if (rp3dBody) { SHASSERT ( - SHUtilities::ConvertEnum(rigidBody->getType()) == SHUtilities::ConvertEnum(type), + SHUtilities::ConvertEnum(reinterpret_cast(rp3dBody)->getType()) == SHUtilities::ConvertEnum(type), "ReactPhysics and SHADE body types do not match!" ) } @@ -92,9 +89,9 @@ namespace SHADE float SHRigidBodyComponent::GetMass() const noexcept { - if (rigidBody) + if (rp3dBody) { - SHASSERT(rigidBody->getMass() == mass, "ReactPhysics and SHADE body masses do not match!") + SHASSERT(reinterpret_cast(rp3dBody)->getMass() == mass, "ReactPhysics and SHADE body masses do not match!") } return mass; @@ -102,11 +99,11 @@ namespace SHADE float SHRigidBodyComponent::GetDrag() const noexcept { - if (rigidBody) + if (rp3dBody) { SHASSERT ( - SHMath::CompareFloat(rigidBody->getLinearDamping(), drag), + SHMath::CompareFloat(reinterpret_cast(rp3dBody)->getLinearDamping(), drag), "ReactPhysics and SADE body drag coefficients do not match!" ) } @@ -116,11 +113,11 @@ namespace SHADE float SHRigidBodyComponent::GetAngularDrag() const noexcept { - if (rigidBody) + if (rp3dBody) { SHASSERT ( - SHMath::CompareFloat(rigidBody->getAngularDamping(), angularDrag), + SHMath::CompareFloat(reinterpret_cast(rp3dBody)->getAngularDamping(), angularDrag), "ReactPhysics and SADE body drag coefficients do not match!" ) } @@ -131,9 +128,9 @@ namespace SHADE bool SHRigidBodyComponent::GetFreezePositionX() const noexcept { const bool FREEZE_X_POS = flags & (1U << 2); - if (rigidBody) + if (rp3dBody) { - const bool RP3D_FREEZE_X_POS = fabs(rigidBody->getLinearLockAxisFactor().x) > 0.0f; + const bool RP3D_FREEZE_X_POS = fabs(reinterpret_cast(rp3dBody)->getLinearLockAxisFactor().x) > 0.0f; SHASSERT(RP3D_FREEZE_X_POS == FREEZE_X_POS, "ReactPhysics and SHADE body x-axis position lock do not match!") } @@ -143,9 +140,9 @@ namespace SHADE bool SHRigidBodyComponent::GetFreezePositionY() const noexcept { const bool FREEZE_Y_POS = flags & (1U << 3); - if (rigidBody) + if (rp3dBody) { - const bool RP3D_FREEZE_Y_POS = fabs(rigidBody->getLinearLockAxisFactor().y) > 0.0f; + const bool RP3D_FREEZE_Y_POS = fabs(reinterpret_cast(rp3dBody)->getLinearLockAxisFactor().y) > 0.0f; SHASSERT(RP3D_FREEZE_Y_POS == FREEZE_Y_POS, "ReactPhysics and SHADE body y-axis position lock do not match!") } @@ -155,9 +152,9 @@ namespace SHADE bool SHRigidBodyComponent::GetFreezePositionZ() const noexcept { const bool FREEZE_Z_POS = flags & (1U << 4); - if (rigidBody) + if (rp3dBody) { - const bool RP3D_FREEZE_Z_POS = fabs(rigidBody->getLinearLockAxisFactor().z) > 0.0f; + const bool RP3D_FREEZE_Z_POS = fabs(reinterpret_cast(rp3dBody)->getLinearLockAxisFactor().z) > 0.0f; SHASSERT(RP3D_FREEZE_Z_POS == FREEZE_Z_POS, "ReactPhysics and SHADE body z-axis position lock do not match!") } @@ -167,9 +164,9 @@ namespace SHADE bool SHRigidBodyComponent::GetFreezeRotationX() const noexcept { const bool FREEZE_X_ROT = flags & (1U << 5); - if (rigidBody) + if (rp3dBody) { - const bool RP3D_FREEZE_Y_ROT = fabs(rigidBody->getAngularLockAxisFactor().x) > 0.0f; + const bool RP3D_FREEZE_Y_ROT = fabs(reinterpret_cast(rp3dBody)->getAngularLockAxisFactor().x) > 0.0f; SHASSERT(RP3D_FREEZE_Y_ROT == FREEZE_X_ROT, "ReactPhysics and SHADE body x-axis rotation lock do not match!") } @@ -179,9 +176,9 @@ namespace SHADE bool SHRigidBodyComponent::GetFreezeRotationY() const noexcept { const bool FREEZE_Y_ROT = flags & (1U << 6); - if (rigidBody) + if (rp3dBody) { - const bool RP3D_FREEZE_Y_ROT = fabs(rigidBody->getAngularLockAxisFactor().y) > 0.0f; + const bool RP3D_FREEZE_Y_ROT = fabs(reinterpret_cast(rp3dBody)->getAngularLockAxisFactor().y) > 0.0f; SHASSERT(RP3D_FREEZE_Y_ROT == FREEZE_Y_ROT, "ReactPhysics and SHADE body y-axis rotation lock do not match!") } @@ -191,9 +188,9 @@ namespace SHADE bool SHRigidBodyComponent::GetFreezeRotationZ() const noexcept { const bool FREEZE_Z_ROT = flags & (1U << 7); - if (rigidBody) + if (rp3dBody) { - const bool RP3D_FREEZE_Z_ROT = fabs(rigidBody->getAngularLockAxisFactor().z) > 0.0f; + const bool RP3D_FREEZE_Z_ROT = fabs(reinterpret_cast(rp3dBody)->getAngularLockAxisFactor().z) > 0.0f; SHASSERT(RP3D_FREEZE_Z_ROT == FREEZE_Z_ROT, "ReactPhysics and SHADE body z-axis rotation lock do not match!") } @@ -204,9 +201,9 @@ namespace SHADE { SHVec3 result; - if (rigidBody) + if (rp3dBody) { - const auto RP3D_RESULT = rigidBody->getForce(); + const auto& RP3D_RESULT = reinterpret_cast(rp3dBody)->getForce(); result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z }; } @@ -217,9 +214,9 @@ namespace SHADE { SHVec3 result; - if (rigidBody) + if (rp3dBody) { - const auto RP3D_RESULT = rigidBody->getTorque(); + const auto& RP3D_RESULT = reinterpret_cast(rp3dBody)->getTorque(); result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z }; } @@ -230,9 +227,9 @@ namespace SHADE { SHVec3 result; - if (rigidBody) + if (rp3dBody) { - const auto RP3D_RESULT = rigidBody->getLinearVelocity(); + const auto& RP3D_RESULT = reinterpret_cast(rp3dBody)->getLinearVelocity(); result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z }; } @@ -243,41 +240,15 @@ namespace SHADE { SHVec3 result; - if (rigidBody) + if (rp3dBody) { - const auto RP3D_RESULT = rigidBody->getAngularVelocity(); + const auto& RP3D_RESULT = reinterpret_cast(rp3dBody)->getAngularVelocity(); result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z }; } return result; } - SHVec3 SHRigidBodyComponent::GetPosition() const noexcept - { - SHVec3 result; - - if (rigidBody) - { - const auto RP3D_RESULT = rigidBody->getTransform().getPosition(); - result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z }; - } - - return result; - } - - SHQuaternion SHRigidBodyComponent::GetOrientation() const noexcept - { - SHQuaternion result; - - if (rigidBody) - { - const auto RP3D_RESULT = rigidBody->getTransform().getOrientation(); - result = SHQuaternion{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z, RP3D_RESULT.w }; - } - - return result; - } - /*-----------------------------------------------------------------------------------*/ /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -288,43 +259,43 @@ namespace SHADE return; type = newType; - if (rigidBody) - rigidBody->setType(static_cast(newType)); + if (rp3dBody) + reinterpret_cast(rp3dBody)->setType(static_cast(newType)); } void SHRigidBodyComponent::SetMass(float newMass) noexcept { mass = newMass; - if (rigidBody) - rigidBody->setMass(newMass); + if (rp3dBody) + reinterpret_cast(rp3dBody)->setMass(newMass); } void SHRigidBodyComponent::SetDrag(float newDrag) noexcept { drag = newDrag; - if (rigidBody) - rigidBody->setLinearDamping(newDrag); + if (rp3dBody) + reinterpret_cast(rp3dBody)->setLinearDamping(newDrag); } void SHRigidBodyComponent::SetAngularDrag(float newAngularDrag) noexcept { angularDrag = newAngularDrag; - if (rigidBody) - rigidBody->setAngularDamping(newAngularDrag); + if (rp3dBody) + reinterpret_cast(rp3dBody)->setAngularDamping(newAngularDrag); } void SHRigidBodyComponent::SetGravityEnabled(bool enableGravity) noexcept { SetFlag(enableGravity, 0); - if (rigidBody) - rigidBody->enableGravity(enableGravity); + if (rp3dBody) + reinterpret_cast(rp3dBody)->enableGravity(enableGravity); } void SHRigidBodyComponent::SetSleepingEnabled(bool enableSleeping) noexcept { SetFlag(enableSleeping, 1); - if (rigidBody) - rigidBody->setIsAllowedToSleep(enableSleeping); + if (rp3dBody) + reinterpret_cast(rp3dBody)->setIsAllowedToSleep(enableSleeping); } void SHRigidBodyComponent::SetFreezePositionX(bool freezePositionX) noexcept @@ -363,21 +334,26 @@ namespace SHADE SetRP3DAngularConstraints(); } + void SHRigidBodyComponent::SetInterpolate(bool allowInterpolation) noexcept + { + interpolate = allowInterpolation; + } + void SHRigidBodyComponent::SetLinearVelocity(const SHVec3& newLinearVelocity) const noexcept { - if (rigidBody) + if (rp3dBody) { const rp3d::Vector3 NEW_V { newLinearVelocity.x, newLinearVelocity.y, newLinearVelocity.z }; - rigidBody->setLinearVelocity(NEW_V); + reinterpret_cast(rp3dBody)->setLinearVelocity(NEW_V); } } void SHRigidBodyComponent::SetAngularVelocity(const SHVec3& newAngularVelocity) const noexcept { - if (rigidBody) + if (rp3dBody) { const rp3d::Vector3 NEW_V { newAngularVelocity.x, newAngularVelocity.y, newAngularVelocity.z }; - rigidBody->setAngularVelocity(NEW_V); + reinterpret_cast(rp3dBody)->setAngularVelocity(NEW_V); } } @@ -385,79 +361,97 @@ namespace SHADE /* Public Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ + void SHRigidBodyComponent::OnCreate() + { + componentFlags |= 1U << 0; // dirty + componentFlags |= 1U << 1; // rb dirty + componentFlags |= 1U << 2; // has rb + + Synchronise(); + } + + void SHRigidBodyComponent::OnDestroy() + { + componentFlags |= 1U << 0; // dirty + componentFlags |= 1U << 1; // rb dirty + componentFlags &= ~(1U << 2); // no rb + + Synchronise(); + } + void SHRigidBodyComponent::AddForce(const SHVec3& force) const noexcept { - if (rigidBody) + if (rp3dBody) { const rp3d::Vector3 F { force.x, force.y, force.z }; - rigidBody->applyWorldForceAtCenterOfMass(F); + reinterpret_cast(rp3dBody)->applyWorldForceAtCenterOfMass(F); } } void SHRigidBodyComponent::AddForceAtLocalPos(const SHVec3& force, const SHVec3& localPos) const noexcept { - if (rigidBody) + if (rp3dBody) { const rp3d::Vector3 F{ force.x, force.y, force.z }; const rp3d::Vector3 P{ localPos.x, localPos.y, localPos.z }; - rigidBody->applyWorldForceAtLocalPosition(F, P); + reinterpret_cast(rp3dBody)->applyWorldForceAtLocalPosition(F, P); } } void SHRigidBodyComponent::AddForceAtWorldPos(const SHVec3& force, const SHVec3& worldPos) const noexcept { - if (rigidBody) + if (rp3dBody) { const rp3d::Vector3 F{ force.x, force.y, force.z }; const rp3d::Vector3 P{ worldPos.x, worldPos.y, worldPos.z }; - rigidBody->applyWorldForceAtWorldPosition(F, P); + reinterpret_cast(rp3dBody)->applyWorldForceAtWorldPosition(F, P); } } void SHRigidBodyComponent::AddRelativeForce(const SHVec3& relativeForce) const noexcept { - if (rigidBody) + if (rp3dBody) { const rp3d::Vector3 F{ relativeForce.x, relativeForce.y, relativeForce.z }; - rigidBody->applyLocalForceAtCenterOfMass(F); + reinterpret_cast(rp3dBody)->applyLocalForceAtCenterOfMass(F); } } void SHRigidBodyComponent::AddRelativeForceAtLocalPos(const SHVec3& relativeForce, const SHVec3& localPos) const noexcept { - if (rigidBody) + if (rp3dBody) { const rp3d::Vector3 F{ relativeForce.x, relativeForce.y, relativeForce.z }; const rp3d::Vector3 P{ localPos.x, localPos.y, localPos.z }; - rigidBody->applyLocalForceAtLocalPosition(F, P); + reinterpret_cast(rp3dBody)->applyLocalForceAtLocalPosition(F, P); } } void SHRigidBodyComponent::AddRelativeForceAtWorldPos(const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept { - if (rigidBody) + if (rp3dBody) { const rp3d::Vector3 F{ relativeForce.x, relativeForce.y, relativeForce.z }; const rp3d::Vector3 P{ worldPos.x, worldPos.y, worldPos.z }; - rigidBody->applyLocalForceAtWorldPosition(F, P); + reinterpret_cast(rp3dBody)->applyLocalForceAtWorldPosition(F, P); } } void SHRigidBodyComponent::AddTorque(const SHVec3& torque) const noexcept { - if (rigidBody) + if (rp3dBody) { const rp3d::Vector3 T{ torque.x, torque.y, torque.z }; - rigidBody->applyWorldTorque(T); + reinterpret_cast(rp3dBody)->applyWorldTorque(T); } } void SHRigidBodyComponent::AddRelativeTorque(const SHVec3& relativeTorque) const noexcept { - if (rigidBody) + if (rp3dBody) { const rp3d::Vector3 T{ relativeTorque.x, relativeTorque.y, relativeTorque.z }; - rigidBody->applyLocalTorque(T); + reinterpret_cast(rp3dBody)->applyLocalTorque(T); } } @@ -467,6 +461,8 @@ namespace SHADE void SHRigidBodyComponent::SyncRP3DAndSHADE() { + auto* rigidBody = reinterpret_cast(rp3dBody); + rigidBody->setType(static_cast(type)); rigidBody->setMass(mass); @@ -494,8 +490,8 @@ namespace SHADE flags & 1U << 4 ? 1.0f : 0.0f }; - if (rigidBody) - rigidBody->setLinearLockAxisFactor(CONSTRAINTS); + if (rp3dBody) + reinterpret_cast(rp3dBody)->setLinearLockAxisFactor(CONSTRAINTS); } void SHRigidBodyComponent::SetRP3DAngularConstraints() const @@ -507,8 +503,8 @@ namespace SHADE flags & 1U << 7 ? 1.0f : 0.0f }; - if (rigidBody) - rigidBody->setAngularLockAxisFactor(CONSTRAINTS); + if (rp3dBody) + reinterpret_cast(rp3dBody)->setAngularLockAxisFactor(CONSTRAINTS); } } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h index 668ab6bd..439fa3db 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h @@ -10,16 +10,17 @@ #pragma once -#include - // Project Headers -#include "Math/Vector/SHVec3.h" -#include "Math/SHMatrix.h" #include "ECS_Base/Components/SHComponent.h" +#include "Physics/SHPhysicsObject.h" namespace SHADE { - class SH_API SHRigidBodyComponent : public SHComponent + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SH_API SHRigidBodyComponent : public SHComponent, public SHPhysicsObject { private: /*---------------------------------------------------------------------------------*/ @@ -66,6 +67,7 @@ namespace SHADE [[nodiscard]] bool IsGravityEnabled () const noexcept; [[nodiscard]] bool IsSleepingEnabled () const noexcept; + [[nodiscard]] bool IsInterpolating () const noexcept; [[nodiscard]] Type GetType () const noexcept; [[nodiscard]] float GetMass () const noexcept; @@ -84,8 +86,6 @@ namespace SHADE [[nodiscard]] SHVec3 GetTorque () const noexcept; [[nodiscard]] SHVec3 GetLinearVelocity () const noexcept; [[nodiscard]] SHVec3 GetAngularVelocity () const noexcept; - [[nodiscard]] SHVec3 GetPosition () const noexcept; - [[nodiscard]] SHQuaternion GetOrientation () const noexcept; /*---------------------------------------------------------------------------------*/ /* Setter Functions */ @@ -104,6 +104,7 @@ namespace SHADE void SetFreezeRotationX (bool freezeRotationX) noexcept; void SetFreezeRotationY (bool freezeRotationY) noexcept; void SetFreezeRotationZ (bool freezeRotationZ) noexcept; + void SetInterpolate (bool allowInterpolation) noexcept; void SetLinearVelocity (const SHVec3& newLinearVelocity) const noexcept; void SetAngularVelocity (const SHVec3& newAngularVelocity) const noexcept; @@ -112,6 +113,9 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ + void OnCreate () override; + void OnDestroy () override; + void AddForce (const SHVec3& force) const noexcept; void AddForceAtLocalPos (const SHVec3& force, const SHVec3& localPos) const noexcept; void AddForceAtWorldPos (const SHVec3& force, const SHVec3& worldPos) const noexcept; @@ -127,8 +131,6 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ - - rp3d::RigidBody* rigidBody; Type type; @@ -138,6 +140,7 @@ namespace SHADE // rX rY rZ pX pY pZ slp g uint8_t flags; + bool interpolate; /*---------------------------------------------------------------------------------*/ /* Function Members */ diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp new file mode 100644 index 00000000..4f0616f8 --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -0,0 +1,112 @@ +/**************************************************************************************** + * \file SHPhysicsObject.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for a Physics Object. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHPhysicsObject.h" + +// Project Headers +#include "ECS_Base/Managers/SHSystemManager.h" +#include "SHPhysicsSystem.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHPhysicsObject::SHPhysicsObject() noexcept + : entityID { MAX_EID } + , componentFlags { 0 } + , rp3dBody { nullptr } + {} + + SHPhysicsObject::~SHPhysicsObject() noexcept + { + rp3dBody = nullptr; + } + + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHVec3 SHPhysicsObject::GetPosition() const noexcept + { + SHVec3 result; + + if (rp3dBody) + { + const auto& RP3D_RESULT = rp3dBody->getTransform().getPosition(); + result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z }; + } + + return result; + } + + SHQuaternion SHPhysicsObject::GetOrientation() const noexcept + { + SHQuaternion result; + + if (rp3dBody) + { + const auto& RP3D_RESULT = rp3dBody->getTransform().getOrientation(); + result = SHQuaternion{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z, RP3D_RESULT.w }; + } + + return result; + } + + SHVec3 SHPhysicsObject::GetRotation() const noexcept + { + SHVec3 result; + + if (rp3dBody) + { + const auto& RP3D_RESULT = rp3dBody->getTransform().getOrientation(); + result = SHQuaternion{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z, RP3D_RESULT.w }.ToEuler(); + } + + return result; + } + + /*-----------------------------------------------------------------------------------*/ + /* Public Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHPhysicsObject::Synchronise() const + { + if (const bool IS_DIRTY = componentFlags & 1U << 0; IS_DIRTY) + { + auto* physicsSystem = SHSystemManager::GetSystem(); + + const bool IS_RIGIDBODY_DIRTY = componentFlags & 1U << 1; + const bool IS_COLLIDER_DIRTY = componentFlags & 1U << 3; + + if (IS_RIGIDBODY_DIRTY) + { + static constexpr auto COMP_ENUM = SHPhysicsSystem::UpdateComponent::RIGID_BODY; + + const bool HAS_RIGIDBODY = componentFlags & 1U << 2; + HAS_RIGIDBODY ? physicsSystem->AddComponent(COMP_ENUM, entityID) : physicsSystem->RemoveComponent(COMP_ENUM, entityID); + } + + if (IS_COLLIDER_DIRTY) + { + static constexpr auto COMP_ENUM = SHPhysicsSystem::UpdateComponent::COLLIDER; + + const bool HAS_COLLIDER = componentFlags & 1U << 2; + HAS_COLLIDER ? physicsSystem->AddComponent(COMP_ENUM, entityID) : physicsSystem->RemoveComponent(COMP_ENUM, entityID); + } + } + } + + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.h b/SHADE_Engine/src/Physics/SHPhysicsObject.h new file mode 100644 index 00000000..20449f2d --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.h @@ -0,0 +1,82 @@ +/**************************************************************************************** + * \file SHPhysicsObject.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for a Physics Object. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include + +// Project Headers +#include "Math/Vector/SHVec3.h" +#include "Math/SHQuaternion.h" +#include "ECS_Base/Entity/SHEntity.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SH_API SHPhysicsObject + { + protected: + /*---------------------------------------------------------------------------------*/ + /* Friends */ + /*---------------------------------------------------------------------------------*/ + + friend class SHPhysicsSystem; + + public: + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHPhysicsObject () noexcept; + SHPhysicsObject (const SHPhysicsObject& rhs) noexcept = default; + SHPhysicsObject (SHPhysicsObject&& rhs) noexcept = default; + ~SHPhysicsObject () noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + SHPhysicsObject& operator=(const SHPhysicsObject& rhs) noexcept = default; + SHPhysicsObject& operator=(SHPhysicsObject&& rhs) noexcept = default; + + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] SHVec3 GetPosition () const noexcept; + [[nodiscard]] SHQuaternion GetOrientation () const noexcept; + [[nodiscard]] SHVec3 GetRotation () const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + /** + * @brief Checks for updates in the component states and tells the physics system to + * make any necessary additions / removals to rp3d side to sync with the SHADE + * component. + */ + void Synchronise() const; + + protected: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + EntityID entityID; + uint8_t componentFlags; // 0 0 0 c cDirty rb rbDirty dirty + rp3d::CollisionBody* rp3dBody; // Can be either a collision body or a rigid body + rp3d::Transform prevTransform; // Cached transform for interpolation + + }; +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 537c2c70..d27469ad 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -14,11 +14,10 @@ #include "SHPhysicsSystem.h" // Project Headers -#include "Math/Transform/SHTransformComponent.h" -#include "Scene/SHSceneManager.h" #include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/Managers/SHEntityManager.h" -#include "Graphics/MiddleEnd/Interface/SHRenderable.h" +#include "Scene/SHSceneManager.h" +#include "Math/Transform/SHTransformComponent.h" namespace SHADE { @@ -26,6 +25,12 @@ namespace SHADE /* Constructors & Destructor Definitions */ /*-----------------------------------------------------------------------------------*/ + SHPhysicsSystem::SHPhysicsSystem() + : accumulatedTime { 0.0 } + , fixedDT { 1.0 / 60.0 } + , world { nullptr } + {} + SHPhysicsSystem::PhysicsPreUpdate::PhysicsPreUpdate() : SHSystemRoutine { "Physics PreUpdate", true } {} @@ -51,11 +56,6 @@ namespace SHADE return false; } - //double SHPhysicsSystem::GetFixedUpdate() const noexcept - //{ - // return fixedUpdate; - //} - SHVec3 SHPhysicsSystem::GetWorldGravity() const noexcept { SHVec3 result; @@ -97,12 +97,6 @@ namespace SHADE /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ - //void SHPhysicsSystem::SetFixedUpdate(double fixedUpdateRate) noexcept - //{ - // fixedUpdate = fixedUpdateRate; - // SHLOG_INFO("Setting Physics update rate to {}", 1.0 / fixedUpdate) - //} - void SHPhysicsSystem::SetWorldGravity(const SHVec3& gravity) const noexcept { if (world) @@ -178,7 +172,7 @@ namespace SHADE // Create a physics world with the default settings PhysicsWorld::WorldSettings settings; - settings.gravity = Vector3{ 0, -9.81, 0 }; + settings.gravity = Vector3{ 0.0f, -9.81f, 0.0f }; settings.isSleepingEnabled = true; settings.defaultVelocitySolverNbIterations = 8; settings.defaultPositionSolverNbIterations = 3; @@ -194,108 +188,14 @@ namespace SHADE factory.destroyPhysicsWorld(world); } - void SHPhysicsSystem::AddRigidBodyComponent(EntityID id) noexcept - { - const UpdateCommand NEW_CMD - { - .component = UpdateComponent::RIGID_BODY, - .type = UpdateType::ADD, - .entityID = id - }; - - updateQueue.push(NEW_CMD); - } - - void SHPhysicsSystem::AddColliderComponent(EntityID id) noexcept - { - const UpdateCommand NEW_CMD - { - .component = UpdateComponent::COLLIDER, - .type = UpdateType::ADD, - .entityID = id - }; - - updateQueue.push(NEW_CMD); - } - - void SHPhysicsSystem::RemoveRigidBodyComponent(EntityID id) noexcept - { - const UpdateCommand NEW_CMD - { - .component = UpdateComponent::RIGID_BODY, - .type = UpdateType::REMOVE, - .entityID = id - }; - - updateQueue.push(NEW_CMD); - } - - void SHPhysicsSystem::RemoveColliderComponent(EntityID id) noexcept - { - const UpdateCommand NEW_CMD - { - .component = UpdateComponent::COLLIDER, - .type = UpdateType::REMOVE, - .entityID = id - }; - - updateQueue.push(NEW_CMD); - } - void SHPhysicsSystem::PhysicsPreUpdate::Execute([[maybe_unused]]double dt) noexcept { auto* system = reinterpret_cast(GetSystem()); + system->ClearUpdateQueue(); - - // Sync active states: if node or component is not active, set rp3d to inactive - static const auto SYNC_ACTIVE = [](SHSceneNode* node) - { - const EntityID ENTITY_ID = node->GetEntityID(); - - // Check if has rigid body - auto const* rigidBodyComponent = SHComponentManager::GetComponent_s(ENTITY_ID); - if(rigidBodyComponent) - { - const bool RP3D_ACTIVE = rigidBodyComponent->rigidBody->isActive(); - const bool SHADE_ACTIVE = node->IsActive() && rigidBodyComponent->isActive; - - if (RP3D_ACTIVE != SHADE_ACTIVE) - rigidBodyComponent->rigidBody->setIsActive(SHADE_ACTIVE); - } - else // Check for a collider - { - - } - }; - - const auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); - sceneGraph.Traverse(SYNC_ACTIVE); + system->SyncActiveStates(SHSceneManager::GetCurrentSceneGraph()); } - //void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept - //{ - // // I had to override this anyway due to needing to calculate the - // // interpolation factor right after the fixed update was done - - // auto* system = reinterpret_cast(GetSystem()); - // fixedTimeStep = 1.0 / system->fixedUpdate; - - // accumulatedTime += dt; - // int counter = 0; - - // while (accumulatedTime > fixedTimeStep) - // { - // FixedExecute(fixedTimeStep); - - // accumulatedTime -= fixedTimeStep; - // ++counter; - // } - - // stats.numSteps = counter; - - // system->interpolationFactor = accumulatedTime / fixedTimeStep; - //} - void SHPhysicsSystem::PhysicsFixedUpdate::FixedExecute(double dt) noexcept { auto* system = reinterpret_cast(GetSystem()); @@ -309,38 +209,25 @@ namespace SHADE { // Interpolate transforms for rendering const auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); - sceneGraph.Traverse([](SHSceneNode* node) - { - const EntityID ENTITY_ID = node->GetEntityID(); - - // Check if has rigid body - if (auto* rb = SHComponentManager::GetComponent_s(ENTITY_ID); rb) - { - // TODO(Diren): Interpolate transforms for rendering - if (node->IsActive() && rb->isActive) - { - // Get SHADE transform - auto* transformComponent = SHComponentManager::GetComponent_s(ENTITY_ID); - SHASSERT(transformComponent != nullptr, "Transform Component missing from Entity " + std::to_string(ENTITY_ID)) - - const auto& RP3D_POS = rb->GetPosition(); - const SHVec3 SHADE_POS{ RP3D_POS.x, RP3D_POS.y, RP3D_POS.z }; - - const auto& SHADE_ROT = rb->GetOrientation().ToEuler(); - - transformComponent->SetWorldPosition(SHADE_POS); - transformComponent->SetWorldRotation(SHADE_ROT); - } - else // Check for a collider - { - - } - } - }); // TODO(Diren): Handle trigger messages for scripting } + /*-----------------------------------------------------------------------------------*/ + /* Protected Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHPhysicsSystem::AddComponent(UpdateComponent comp, EntityID entityID) noexcept + { + updateQueue.push({ comp, UpdateType::ADD, entityID }); + } + + + void SHPhysicsSystem::RemoveComponent(UpdateComponent comp, EntityID entityID) noexcept + { + updateQueue.push({ comp, UpdateType::REMOVE, entityID }); + } + /*-----------------------------------------------------------------------------------*/ /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -377,6 +264,85 @@ namespace SHADE } } + void SHPhysicsSystem::SyncActiveStates(const SHSceneGraph& sceneGraph) const noexcept + { + // Sync active states: if node or component is not active, set rp3d to inactive + static constexpr auto SYNC_ACTIVE = [](SHSceneNode* node) + { + const EntityID ENTITY_ID = node->GetEntityID(); + + // Check if has rigid body + auto const* rigidBodyComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + if(rigidBodyComponent) + { + const bool RP3D_ACTIVE = rigidBodyComponent->rp3dBody->isActive(); + const bool SHADE_ACTIVE = node->IsActive() && rigidBodyComponent->isActive; + + if (RP3D_ACTIVE != SHADE_ACTIVE) + rigidBodyComponent->rp3dBody->setIsActive(SHADE_ACTIVE); + } + else // Check for a collider + { + + } + }; + + sceneGraph.Traverse(SYNC_ACTIVE); + } + + void SHPhysicsSystem::SyncTransforms(const SHSceneGraph& sceneGraph) const noexcept + { + const rp3d::decimal INTERPOLATION_FACTOR = static_cast(accumulatedTime / fixedDT); + + static const auto SYNC_TRANSFORMS = [&](SHSceneNode* node) + { + const EntityID ENTITY_ID = node->GetEntityID(); + + // Check if has rigid body + if (auto* rb = SHComponentManager::GetComponent_s(ENTITY_ID); rb) + { + if (node->IsActive() && rb->isActive) + { + // Get SHADE transform + auto* transformComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + SHASSERT(transformComponent != nullptr, "Transform Component missing from Entity " + std::to_string(ENTITY_ID)) + + SHVec3 shadePos, shadeRot; + + if (rb->interpolate) + { + const rp3d::Transform CURRENT_TRANSFORM = rb->rp3dBody->getTransform(); + const rp3d::Transform INTERPOLATED_TRANSFORM = rp3d::Transform::interpolateTransforms(rb->prevTransform, CURRENT_TRANSFORM, INTERPOLATION_FACTOR); + + const auto& RP3D_POS = INTERPOLATED_TRANSFORM.getPosition(); + shadePos = SHVec3{ RP3D_POS.x, RP3D_POS.y, RP3D_POS.z }; + + const auto& RP3D_ORT = INTERPOLATED_TRANSFORM.getOrientation(); + shadeRot = SHQuaternion{ RP3D_ORT.x, RP3D_ORT.y, RP3D_ORT.z, RP3D_ORT.w }.ToEuler(); + + rb->prevTransform = CURRENT_TRANSFORM; + } + else + { + + const auto& RP3D_POS = rb->GetPosition(); + shadePos = SHVec3{ RP3D_POS.x, RP3D_POS.y, RP3D_POS.z }; + shadeRot = rb->GetOrientation().ToEuler(); + } + + transformComponent->SetWorldPosition(shadePos); + transformComponent->SetWorldRotation(shadeRot); + } + else // Check for a collider + { + + } + } + }; + + sceneGraph.Traverse(SYNC_TRANSFORMS); + } + void SHPhysicsSystem::AddRigidBody(EntityID entityID) const noexcept { @@ -413,7 +379,8 @@ namespace SHADE rigidBodyComponent = SHComponentManager::GetComponent(entityID); } - rigidBodyComponent->rigidBody = world->createRigidBody(RP3D_TF); + rigidBodyComponent->rp3dBody = world->createRigidBody(RP3D_TF); + rigidBodyComponent->prevTransform = RP3D_TF; rigidBodyComponent->SyncRP3DAndSHADE(); // Reassign collider @@ -438,9 +405,8 @@ namespace SHADE // If a collider exists, remake the colliders with a collision body - world->destroyRigidBody(rigidBodyComponent->rigidBody); - rigidBodyComponent->rigidBody = nullptr; // this should be redundant + world->destroyRigidBody(reinterpret_cast(rigidBodyComponent->rp3dBody)); + rigidBodyComponent->rp3dBody = nullptr; // this should be redundant } - } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index dac6836a..273eb54d 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -11,14 +11,12 @@ #pragma once #include -#include #include // Project Headers #include "Math/SHQuaternion.h" #include "Components/SHRigidBodyComponent.h" - #include "Scene/SHSceneGraph.h" #include "ECS_Base/System/SHSystemRoutine.h" #include "ECS_Base/System/SHFixedSystemRoutine.h" @@ -31,6 +29,13 @@ namespace SHADE class SH_API SHPhysicsSystem : public SHSystem { + protected: + /*---------------------------------------------------------------------------------*/ + /* Friends */ + /*---------------------------------------------------------------------------------*/ + + friend class SHPhysicsObject; + public: /*---------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -48,18 +53,7 @@ namespace SHADE /* Constructors & Destructor */ /*---------------------------------------------------------------------------------*/ - SHPhysicsSystem () = default; - ~SHPhysicsSystem () override = default; - - SHPhysicsSystem (const SHPhysicsSystem&) = delete; - SHPhysicsSystem (SHPhysicsSystem&&) = delete; - - /*---------------------------------------------------------------------------------*/ - /* Operator Overloads */ - /*---------------------------------------------------------------------------------*/ - - SHPhysicsSystem& operator= (const SHPhysicsSystem&) = delete; - SHPhysicsSystem& operator= (SHPhysicsSystem&&) = delete; + SHPhysicsSystem(); /*---------------------------------------------------------------------------------*/ /* Getter Functions */ @@ -67,7 +61,6 @@ namespace SHADE [[nodiscard]] bool IsSleepingEnabled () const noexcept; - //[[nodiscard]] double GetFixedUpdate () const noexcept; [[nodiscard]] SHVec3 GetWorldGravity () const noexcept; [[nodiscard]] uint16_t GetNumberVelocityIterations () const noexcept; [[nodiscard]] uint16_t GetNumberPositionIterations () const noexcept; @@ -92,11 +85,6 @@ namespace SHADE void Init () override; void Exit () override; - void AddRigidBodyComponent (EntityID id) noexcept; - void AddColliderComponent (EntityID id) noexcept; - void RemoveRigidBodyComponent (EntityID id) noexcept; - void RemoveColliderComponent (EntityID id) noexcept; - /*---------------------------------------------------------------------------------*/ /* System Routines */ /*---------------------------------------------------------------------------------*/ @@ -109,17 +97,6 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ PhysicsPreUpdate(); - ~PhysicsPreUpdate() = default; - - PhysicsPreUpdate(const PhysicsPreUpdate&) = delete; - PhysicsPreUpdate(PhysicsPreUpdate&&) = delete; - - /*-------------------------------------------------------------------------------*/ - /* Operator Overloads */ - /*-------------------------------------------------------------------------------*/ - - PhysicsPreUpdate& operator= (const PhysicsPreUpdate&) = delete; - PhysicsPreUpdate& operator= (PhysicsPreUpdate&&) = delete; /*-------------------------------------------------------------------------------*/ /* Function Members */ @@ -136,17 +113,6 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ PhysicsFixedUpdate(); - ~PhysicsFixedUpdate() = default; - - PhysicsFixedUpdate(const PhysicsFixedUpdate&) = delete; - PhysicsFixedUpdate(PhysicsFixedUpdate&&) = delete; - - /*-------------------------------------------------------------------------------*/ - /* Operator Overloads */ - /*-------------------------------------------------------------------------------*/ - - PhysicsFixedUpdate& operator= (const PhysicsFixedUpdate&) = delete; - PhysicsFixedUpdate& operator= (PhysicsFixedUpdate&&) = delete; /*-------------------------------------------------------------------------------*/ /* Function Members */ @@ -164,17 +130,6 @@ namespace SHADE /*-------------------------------------------------------------------------------*/ PhysicsPostUpdate(); - ~PhysicsPostUpdate() = default; - - PhysicsPostUpdate(const PhysicsPostUpdate&) = delete; - PhysicsPostUpdate(PhysicsPostUpdate&&) = delete; - - /*-------------------------------------------------------------------------------*/ - /* Operator Overloads */ - /*-------------------------------------------------------------------------------*/ - - PhysicsPostUpdate& operator= (const PhysicsPostUpdate&) = delete; - PhysicsPostUpdate& operator= (PhysicsPostUpdate&&) = delete; /*-------------------------------------------------------------------------------*/ /* Function Members */ @@ -183,8 +138,7 @@ namespace SHADE void Execute(double dt) noexcept override; }; - - private: + protected: /*---------------------------------------------------------------------------------*/ /* Type Definitions */ /*---------------------------------------------------------------------------------*/ @@ -199,38 +153,41 @@ namespace SHADE EntityID entityID; }; - struct CachedTransform - { - SHVec3 position; - SHQuaternion orientation; - }; + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + void AddComponent (UpdateComponent comp, EntityID entityID) noexcept; + void RemoveComponent (UpdateComponent comp, EntityID entityID) noexcept; + + private: /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ - //double interpolationFactor; - //double fixedUpdate; + // TODO(Diren): Store interpFactor & fixedUpdate for modifiable fixedDT - double accumulatedTime; - double fixedDT; + double accumulatedTime; + double fixedDT; - rp3d::PhysicsCommon factory; - rp3d::PhysicsWorld* world; + rp3d::PhysicsCommon factory; + rp3d::PhysicsWorld* world; - std::queue updateQueue; - std::unordered_map prevTransforms; // used for interpolation + std::queue updateQueue; /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ - void ClearUpdateQueue () noexcept; + void ClearUpdateQueue () noexcept; + void SyncActiveStates (const SHSceneGraph& sceneGraph) const noexcept; + void SyncTransforms (const SHSceneGraph& sceneGraph) const noexcept; + // TODO(Diren): Trigger handling - void AddRigidBody (EntityID entityID) const noexcept; - void AddCollider (EntityID entityID) const noexcept; - void RemoveRigidBody (EntityID entityID) const noexcept; - void RemoveCollider (EntityID entityID) const noexcept; + void AddRigidBody (EntityID entityID) const noexcept; + void AddCollider (EntityID entityID) const noexcept; + void RemoveRigidBody (EntityID entityID) const noexcept; + void RemoveCollider (EntityID entityID) const noexcept; }; From 4f56a32a9bbe26b258b5e5b16d4bc122f6e51ce9 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sat, 1 Oct 2022 15:26:08 +0800 Subject: [PATCH 05/61] Added physics system (untested) --- .../src/Application/SBApplication.cpp | 2 +- SHADE_Application/src/Scenes/SBTestScene.cpp | 88 ++-- .../src/Math/Geometry/SHBoundingBox.cpp | 2 +- .../src/Math/Geometry/SHBoundingBox.h | 14 +- SHADE_Engine/src/Math/Geometry/SHShape.h | 4 +- .../Math/Transform/SHTransformComponent.cpp | 6 +- .../src/Math/Transform/SHTransformComponent.h | 1 + .../Components/SHColliderComponent.cpp | 98 ++++ .../Physics/Components/SHColliderComponent.h | 94 ++++ .../Components/SHRigidBodyComponent.cpp | 461 +++++++---------- .../Physics/Components/SHRigidBodyComponent.h | 111 +++-- SHADE_Engine/src/Physics/SHCollider.cpp | 215 ++++++++ SHADE_Engine/src/Physics/SHCollider.h | 108 ++++ SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 36 +- SHADE_Engine/src/Physics/SHPhysicsObject.h | 37 +- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 470 ++++++++++++------ SHADE_Engine/src/Physics/SHPhysicsSystem.h | 86 ++-- 17 files changed, 1193 insertions(+), 640 deletions(-) create mode 100644 SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp create mode 100644 SHADE_Engine/src/Physics/Components/SHColliderComponent.h create mode 100644 SHADE_Engine/src/Physics/SHCollider.cpp create mode 100644 SHADE_Engine/src/Physics/SHCollider.h diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 57e14d71..acad9e14 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -90,7 +90,7 @@ namespace Sandbox SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHSystemManager::RegisterRoutine(); - //SHADE::SHComponentManager::CreateComponentSparseSet(); + SHADE::SHComponentManager::CreateComponentSparseSet(); SHADE::SHComponentManager::CreateComponentSparseSet(); SHADE::SHComponentManager::CreateComponentSparseSet(); diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 664497df..556ff3ac 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -18,9 +18,9 @@ using namespace SHADE; namespace Sandbox { - void SBTestScene::WindowFocusFunc([[maybe_unused]]void* window, int focused) + void SBTestScene::WindowFocusFunc([[maybe_unused]] void* window, int focused) { - if(focused) + if (focused) { } else @@ -44,15 +44,15 @@ namespace Sandbox { if (mesh.meshName == "Cube.012") { - handles.push_back(graphicsSystem->AddMesh( - mesh.header.vertexCount, - mesh.vertexPosition.data(), - mesh.texCoords.data(), - mesh.vertexTangent.data(), - mesh.vertexNormal.data(), - mesh.header.indexCount, - mesh.indices.data() - )); + handles.push_back(graphicsSystem->AddMesh( + mesh.header.vertexCount, + mesh.vertexPosition.data(), + mesh.texCoords.data(), + mesh.vertexTangent.data(), + mesh.vertexNormal.data(), + mesh.header.indexCount, + mesh.indices.data() + )); } } graphicsSystem->BuildMeshBuffers(); @@ -62,8 +62,8 @@ namespace Sandbox std::vector> texHandles; for (const auto& tex : textures) { - auto texture = graphicsSystem->Add(tex); - texHandles.push_back(texture); + auto texture = graphicsSystem->Add(tex); + texHandles.push_back(texture); } graphicsSystem->BuildTextures(); @@ -79,14 +79,14 @@ namespace Sandbox constexpr int NUM_ROWS = 100; constexpr int NUM_COLS = 100; static const SHVec3 TEST_OBJ_SPACING = { 0.05f, 0.05f, 0.05f }; - static const SHVec3 TEST_OBJ_START_POS = { - (NUM_COLS / 2 * TEST_OBJ_SPACING.x ) + 1.0f, -2.0f, -1.0f }; + static const SHVec3 TEST_OBJ_START_POS = { -(NUM_COLS / 2 * TEST_OBJ_SPACING.x) + 1.0f, -2.0f, -1.0f }; for (int y = 0; y < NUM_ROWS; ++y) - for (int x = 0; x < NUM_COLS; ++x) - { - auto entity = SHEntityManager::CreateEntity(); + for (int x = 0; x < NUM_COLS; ++x) + { + auto entity = SHEntityManager::CreateEntity(); auto& renderable = *SHComponentManager::GetComponent_s(entity); - auto& transform = *SHComponentManager::GetComponent_s(entity); + auto& transform = *SHComponentManager::GetComponent_s(entity); renderable.Mesh = handles.front(); renderable.SetMaterial(customMat); @@ -95,17 +95,17 @@ namespace Sandbox renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 0.0f, 0.0f, 1.0f)); //Set initial positions - transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ - x * TEST_OBJ_SPACING.x, - y * TEST_OBJ_SPACING.y, - 0.0f - }); + transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ + x * TEST_OBJ_SPACING.x, + y * TEST_OBJ_SPACING.y, + 0.0f + }); //transform.SetWorldPosition({-1.0f, -1.0f, -1.0f}); //transform.SetWorldRotation(3.14159265f * 1.5f, -3.14159265f / 2.0f, 0.0f); transform.SetLocalScale(TEST_OBJ_SCALE); stressTestObjects.emplace_back(entity); - } + } auto raccoonSpin = SHEntityManager::CreateEntity(); auto& renderable = *SHComponentManager::GetComponent_s(raccoonSpin); @@ -117,8 +117,8 @@ namespace Sandbox renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); renderable.GetModifiableMaterial()->SetProperty("data.textureIndex", 1); - transform.SetWorldPosition ({-3.0f, -1.0f, -1.0f}); - transform.SetLocalScale({5.0f, 5.0f, 5.0f}); + transform.SetWorldPosition({ -3.0f, -1.0f, -1.0f }); + transform.SetLocalScale({ 5.0f, 5.0f, 5.0f }); //auto entity = SHEntityManager::CreateEntity(); //auto& renderable = *SHComponentManager::GetComponent_s(entity); @@ -137,21 +137,21 @@ namespace Sandbox //testObjRenderable.SetMaterial(matInst); SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); - scriptEngine->AddScript(raccoonSpin, "RaccoonSpin"); + scriptEngine->AddScript(raccoonSpin, "RaccoonSpin"); - auto raccoonShowcase = SHEntityManager::CreateEntity(); - auto& renderableShowcase = *SHComponentManager::GetComponent_s(raccoonShowcase); - auto& transformShowcase = *SHComponentManager::GetComponent_s(raccoonShowcase); + auto raccoonShowcase = SHEntityManager::CreateEntity(); + auto& renderableShowcase = *SHComponentManager::GetComponent_s(raccoonShowcase); + auto& transformShowcase = *SHComponentManager::GetComponent_s(raccoonShowcase); - renderableShowcase.Mesh = handles.front(); - renderableShowcase.SetMaterial(customMat); - renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); - renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); - renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 1); + renderableShowcase.Mesh = handles.front(); + renderableShowcase.SetMaterial(customMat); + renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); + renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); + renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 1); - transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f }); - transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f }); - scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase"); + transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f }); + transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f }); + scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase"); } void SBTestScene::Update(float dt) @@ -163,19 +163,19 @@ namespace Sandbox //transform.SetWorldPosition({1.0f, 1.0f, -1.0f}); //transform.SetWorldRotation(0.0f, 0.0f + rotation, 0.0f); //rotation += dt * 0.2f; - + // Destroy entity if space is pressed if (GetKeyState(VK_SPACE) & 0x8000) { rotation = 0.0f; - SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); - scriptEngine->RemoveAllScripts(testObj); + SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); + scriptEngine->RemoveAllScripts(testObj); } } void SBTestScene::Render() { - + } void SBTestScene::Unload() @@ -186,8 +186,4 @@ namespace Sandbox { //SHSerialization::SerializeScene("resources/scenes/Scene01.SHADE"); } - } - - - diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp index 44f01a4b..3abcc315 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp @@ -21,7 +21,7 @@ namespace SHADE /* Constructors & Destructor Definitions */ /*-----------------------------------------------------------------------------------*/ - SHBoundingBox::SHBoundingBox(const SHVec3& c, SHVec3& hE) noexcept + SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept : SHShape {} , center { c } , halfExtents { hE } diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h index b60c6c29..5041df63 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h @@ -27,15 +27,15 @@ namespace SHADE /* Constructors & Destructor */ /*---------------------------------------------------------------------------------*/ - SHBoundingBox (const SHVec3& center, SHVec3& halfExtents) noexcept; - SHBoundingBox (const SHVec3* vertices, size_t numVertices) noexcept; - SHBoundingBox (const SHBoundingBox* boxes, size_t numBoxes) noexcept; + SHBoundingBox (const SHVec3& center, const SHVec3& halfExtents) noexcept; + SHBoundingBox (const SHVec3* vertices, size_t numVertices) noexcept; + SHBoundingBox (const SHBoundingBox* boxes, size_t numBoxes) noexcept; - SHBoundingBox (const SHBoundingBox& rhs) noexcept; - SHBoundingBox (SHBoundingBox&& rhs) noexcept; + SHBoundingBox (const SHBoundingBox& rhs) noexcept; + SHBoundingBox (SHBoundingBox&& rhs) noexcept; - SHBoundingBox& operator= (const SHBoundingBox& rhs) noexcept; - SHBoundingBox& operator= (SHBoundingBox&& rhs) noexcept; + SHBoundingBox& operator= (const SHBoundingBox& rhs) noexcept; + SHBoundingBox& operator= (SHBoundingBox&& rhs) noexcept; /*---------------------------------------------------------------------------------*/ /* Getter Functions */ diff --git a/SHADE_Engine/src/Math/Geometry/SHShape.h b/SHADE_Engine/src/Math/Geometry/SHShape.h index 84b7bbe7..e33ca583 100644 --- a/SHADE_Engine/src/Math/Geometry/SHShape.h +++ b/SHADE_Engine/src/Math/Geometry/SHShape.h @@ -30,7 +30,9 @@ namespace SHADE enum class Type { BOUNDING_BOX - , RAY + , SPHERE + , CAPSULE + , CONVEX_HULL , TRIANGLE , COUNT diff --git a/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp b/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp index 15cd698b..949cfa67 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp @@ -152,7 +152,7 @@ RTTR_REGISTRATION using namespace rttr; registration::class_("Transform Component") - .property("Translate", &SHTransformComponent::GetLocalPosition, &SHTransformComponent::SetLocalPosition) - .property("Rotate", &SHTransformComponent::GetLocalRotation, select_overload(&SHTransformComponent::SetLocalRotation)) - .property("Scale", &SHTransformComponent::GetLocalScale, &SHTransformComponent::SetLocalScale); + .property("Translate" , &SHTransformComponent::GetLocalPosition , &SHTransformComponent::SetLocalPosition ) + .property("Rotate" , &SHTransformComponent::GetLocalRotation , select_overload(&SHTransformComponent::SetLocalRotation) ) + .property("Scale" , &SHTransformComponent::GetLocalScale , &SHTransformComponent::SetLocalScale ); } \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Transform/SHTransformComponent.h b/SHADE_Engine/src/Math/Transform/SHTransformComponent.h index a87b1921..ad355694 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformComponent.h +++ b/SHADE_Engine/src/Math/Transform/SHTransformComponent.h @@ -13,6 +13,7 @@ #include #include + // Project Headers #include "SH_API.h" #include "ECS_Base/Components/SHComponent.h" diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp new file mode 100644 index 00000000..3e1c7aa6 --- /dev/null +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp @@ -0,0 +1,98 @@ +/**************************************************************************************** + * \file SHColliderComponent.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for a Collider Component. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHColliderComponent.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + bool SHColliderComponent::HasChanged() const noexcept + { + return dirty; + } + + const SHVec3& SHColliderComponent::GetPosition() const noexcept + { + return position; + } + + const SHQuaternion& SHColliderComponent::GetOrientation() const noexcept + { + return orientation; + } + + SHVec3 SHColliderComponent::GetRotation() const noexcept + { + return orientation.ToEuler(); + } + + const SHColliderComponent::Colliders& SHColliderComponent::GetColliders() const noexcept + { + return colliders; + } + + SHCollider& SHColliderComponent::GetCollider(int index) noexcept + { + if (index < 0 || static_cast(index) >= colliders.size()) + throw std::invalid_argument("Out-of-range access!"); + + return colliders[index].first; + } + + /*-----------------------------------------------------------------------------------*/ + /* Public Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHColliderComponent::OnCreate() + { + + } + + void SHColliderComponent::OnDestroy() + { + + } + + void SHColliderComponent::AddBoundingBox() noexcept + { + const auto BOX_PAIR = std::make_pair(SHCollider{SHCollider::Type::BOX}, true); + colliders.emplace_back(BOX_PAIR); + } + + void SHColliderComponent::AddSphere() noexcept + { + + } + + void SHColliderComponent::RemoveCollider(int index) noexcept + { + if (index < 0 || static_cast(index) >= colliders.size()) + throw std::invalid_argument("Out-of-range access!"); + + int idx = 0; + auto it = colliders.begin(); + for (; it != colliders.end(); ++it) + { + if (idx == index) + break; + + ++idx; + } + + it = colliders.erase(it); + } + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.h b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h new file mode 100644 index 00000000..aeb3b9e6 --- /dev/null +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h @@ -0,0 +1,94 @@ +/**************************************************************************************** + * \file SHColliderComponent.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for a Collider Component. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +// Project Headers +#include "ECS_Base/Components/SHComponent.h" +#include "Physics/SHCollider.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SH_API SHColliderComponent : public SHComponent + { + private: + /*---------------------------------------------------------------------------------*/ + /* Friends */ + /*---------------------------------------------------------------------------------*/ + + friend class SHPhysicsSystem; + + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + + using ColliderDirtyPair = std::pair; + using Colliders = std::vector; + + public: + + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHColliderComponent () noexcept = default; + SHColliderComponent (const SHColliderComponent& rhs) noexcept = default; + SHColliderComponent (SHColliderComponent&& rhs) noexcept = default; + ~SHColliderComponent () override = default; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + SHColliderComponent& operator=(const SHColliderComponent& rhs) noexcept = default; + SHColliderComponent& operator=(SHColliderComponent&& rhs) noexcept = default; + + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] bool HasChanged () const noexcept; + + [[nodiscard]] const SHVec3& GetPosition () const noexcept; + [[nodiscard]] const SHQuaternion& GetOrientation () const noexcept; + [[nodiscard]] SHVec3 GetRotation () const noexcept; + + [[nodiscard]] const Colliders& GetColliders () const noexcept; + [[nodiscard]] SHCollider& GetCollider (int index) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + void OnCreate () override; + void OnDestroy () override; + + void AddBoundingBox () noexcept; + void AddSphere () noexcept; + + void RemoveCollider (int index) noexcept; + + private: + + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + bool dirty; + SHVec3 position; + SHQuaternion orientation; + Colliders colliders; + + }; +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp index 16863dbd..04cb00dd 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp @@ -14,9 +14,8 @@ #include "SHRigidBodyComponent.h" // Project Headers -#include "Tools/SHUtilities.h" -#include "Math/SHMathHelpers.h" -#include "Math/SHQuaternion.h" +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Physics/SHPhysicsSystem.h" namespace SHADE { @@ -26,46 +25,32 @@ namespace SHADE SHRigidBodyComponent::SHRigidBodyComponent() noexcept : type { Type::DYNAMIC } + , flags { 0 } + , dirtyFlags { 0 } + , interpolate { true } + , system { nullptr } , mass { 1.0f } , drag { 0.01f } , angularDrag { 0.01f } - , flags { 0 } + { // Set default flags: Gravity & Sleeping enabled flags |= 1U << 0; flags |= 1U << 1; } - SHRigidBodyComponent::~SHRigidBodyComponent() - { - - } - /*-----------------------------------------------------------------------------------*/ /* Getter Function Definitions */ /*-----------------------------------------------------------------------------------*/ bool SHRigidBodyComponent::IsGravityEnabled() const noexcept { - const bool GRAVITY = flags & (1U << 0); - if (rp3dBody) - { - - SHASSERT(reinterpret_cast(rp3dBody)->isGravityEnabled() == GRAVITY, "ReactPhysics and SHADE body enable gravity do not match!") - } - - return GRAVITY; + return flags & (1U << 0); } - bool SHRigidBodyComponent::IsSleepingEnabled() const noexcept + bool SHRigidBodyComponent::IsAllowedToSleep() const noexcept { - const bool SLEEP = flags & (1U << 1); - if (rp3dBody) - { - SHASSERT(reinterpret_cast(rp3dBody)->isAllowedToSleep() == SLEEP, "ReactPhysics and SHADE body enable sleep do not match!") - } - - return SLEEP; + return flags & (1U << 1); } bool SHRigidBodyComponent::IsInterpolating() const noexcept @@ -75,178 +60,87 @@ namespace SHADE SHRigidBodyComponent::Type SHRigidBodyComponent::GetType() const noexcept { - if (rp3dBody) - { - SHASSERT - ( - SHUtilities::ConvertEnum(reinterpret_cast(rp3dBody)->getType()) == SHUtilities::ConvertEnum(type), - "ReactPhysics and SHADE body types do not match!" - ) - } - return type; } float SHRigidBodyComponent::GetMass() const noexcept { - if (rp3dBody) - { - SHASSERT(reinterpret_cast(rp3dBody)->getMass() == mass, "ReactPhysics and SHADE body masses do not match!") - } - return mass; } float SHRigidBodyComponent::GetDrag() const noexcept { - if (rp3dBody) - { - SHASSERT - ( - SHMath::CompareFloat(reinterpret_cast(rp3dBody)->getLinearDamping(), drag), - "ReactPhysics and SADE body drag coefficients do not match!" - ) - } - return drag; } float SHRigidBodyComponent::GetAngularDrag() const noexcept { - if (rp3dBody) - { - SHASSERT - ( - SHMath::CompareFloat(reinterpret_cast(rp3dBody)->getAngularDamping(), angularDrag), - "ReactPhysics and SADE body drag coefficients do not match!" - ) - } - return angularDrag; } bool SHRigidBodyComponent::GetFreezePositionX() const noexcept { - const bool FREEZE_X_POS = flags & (1U << 2); - if (rp3dBody) - { - const bool RP3D_FREEZE_X_POS = fabs(reinterpret_cast(rp3dBody)->getLinearLockAxisFactor().x) > 0.0f; - SHASSERT(RP3D_FREEZE_X_POS == FREEZE_X_POS, "ReactPhysics and SHADE body x-axis position lock do not match!") - } - - return FREEZE_X_POS; + return flags & (1U << 2); } bool SHRigidBodyComponent::GetFreezePositionY() const noexcept { - const bool FREEZE_Y_POS = flags & (1U << 3); - if (rp3dBody) - { - const bool RP3D_FREEZE_Y_POS = fabs(reinterpret_cast(rp3dBody)->getLinearLockAxisFactor().y) > 0.0f; - SHASSERT(RP3D_FREEZE_Y_POS == FREEZE_Y_POS, "ReactPhysics and SHADE body y-axis position lock do not match!") - } - - return FREEZE_Y_POS; + return flags & (1U << 3); } bool SHRigidBodyComponent::GetFreezePositionZ() const noexcept { - const bool FREEZE_Z_POS = flags & (1U << 4); - if (rp3dBody) - { - const bool RP3D_FREEZE_Z_POS = fabs(reinterpret_cast(rp3dBody)->getLinearLockAxisFactor().z) > 0.0f; - SHASSERT(RP3D_FREEZE_Z_POS == FREEZE_Z_POS, "ReactPhysics and SHADE body z-axis position lock do not match!") - } - - return FREEZE_Z_POS; + return flags & (1U << 4); } bool SHRigidBodyComponent::GetFreezeRotationX() const noexcept { - const bool FREEZE_X_ROT = flags & (1U << 5); - if (rp3dBody) - { - const bool RP3D_FREEZE_Y_ROT = fabs(reinterpret_cast(rp3dBody)->getAngularLockAxisFactor().x) > 0.0f; - SHASSERT(RP3D_FREEZE_Y_ROT == FREEZE_X_ROT, "ReactPhysics and SHADE body x-axis rotation lock do not match!") - } - - return FREEZE_X_ROT; + return flags & (1U << 5); } bool SHRigidBodyComponent::GetFreezeRotationY() const noexcept { - const bool FREEZE_Y_ROT = flags & (1U << 6); - if (rp3dBody) - { - const bool RP3D_FREEZE_Y_ROT = fabs(reinterpret_cast(rp3dBody)->getAngularLockAxisFactor().y) > 0.0f; - SHASSERT(RP3D_FREEZE_Y_ROT == FREEZE_Y_ROT, "ReactPhysics and SHADE body y-axis rotation lock do not match!") - } - - return FREEZE_Y_ROT; + return flags & (1U << 6); } bool SHRigidBodyComponent::GetFreezeRotationZ() const noexcept { - const bool FREEZE_Z_ROT = flags & (1U << 7); - if (rp3dBody) - { - const bool RP3D_FREEZE_Z_ROT = fabs(reinterpret_cast(rp3dBody)->getAngularLockAxisFactor().z) > 0.0f; - SHASSERT(RP3D_FREEZE_Z_ROT == FREEZE_Z_ROT, "ReactPhysics and SHADE body z-axis rotation lock do not match!") - } - - return FREEZE_Z_ROT; + return flags & (1U << 7); } - SHVec3 SHRigidBodyComponent::GetForce() const noexcept + const SHVec3& SHRigidBodyComponent::GetForce() const noexcept { - SHVec3 result; - - if (rp3dBody) - { - const auto& RP3D_RESULT = reinterpret_cast(rp3dBody)->getForce(); - result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z }; - } - - return result; + return force; } - SHVec3 SHRigidBodyComponent::GetTorque() const noexcept + const SHVec3& SHRigidBodyComponent::GetTorque() const noexcept { - SHVec3 result; - - if (rp3dBody) - { - const auto& RP3D_RESULT = reinterpret_cast(rp3dBody)->getTorque(); - result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z }; - } - - return result; + return torque; } - SHVec3 SHRigidBodyComponent::GetLinearVelocity() const noexcept + const SHVec3& SHRigidBodyComponent::GetLinearVelocity() const noexcept { - SHVec3 result; - - if (rp3dBody) - { - const auto& RP3D_RESULT = reinterpret_cast(rp3dBody)->getLinearVelocity(); - result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z }; - } - - return result; + return linearVelocity; } - SHVec3 SHRigidBodyComponent::GetAngularVelocity() const noexcept + const SHVec3& SHRigidBodyComponent::GetAngularVelocity() const noexcept { - SHVec3 result; + return angularVelocity; + } - if (rp3dBody) - { - const auto& RP3D_RESULT = reinterpret_cast(rp3dBody)->getAngularVelocity(); - result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z }; - } + const SHVec3& SHRigidBodyComponent::GetPosition() const noexcept + { + return position; + } - return result; + const SHQuaternion& SHRigidBodyComponent::GetOrientation() const noexcept + { + return orientation; + } + + SHVec3 SHRigidBodyComponent::GetRotation() const noexcept + { + return orientation.ToEuler(); } /*-----------------------------------------------------------------------------------*/ @@ -258,80 +152,72 @@ namespace SHADE if (type == newType) return; + dirtyFlags |= 1U << 4; type = newType; - if (rp3dBody) - reinterpret_cast(rp3dBody)->setType(static_cast(newType)); - } - - void SHRigidBodyComponent::SetMass(float newMass) noexcept - { - mass = newMass; - if (rp3dBody) - reinterpret_cast(rp3dBody)->setMass(newMass); - } - - void SHRigidBodyComponent::SetDrag(float newDrag) noexcept - { - drag = newDrag; - if (rp3dBody) - reinterpret_cast(rp3dBody)->setLinearDamping(newDrag); - } - - void SHRigidBodyComponent::SetAngularDrag(float newAngularDrag) noexcept - { - angularDrag = newAngularDrag; - if (rp3dBody) - reinterpret_cast(rp3dBody)->setAngularDamping(newAngularDrag); } void SHRigidBodyComponent::SetGravityEnabled(bool enableGravity) noexcept { - SetFlag(enableGravity, 0); - if (rp3dBody) - reinterpret_cast(rp3dBody)->enableGravity(enableGravity); + constexpr int FLAG_POS = 0; + + dirtyFlags |= 1U << FLAG_POS; + enableGravity ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); } - void SHRigidBodyComponent::SetSleepingEnabled(bool enableSleeping) noexcept + void SHRigidBodyComponent::SetIsAllowedToSleep(bool isAllowedToSleep) noexcept { - SetFlag(enableSleeping, 1); - if (rp3dBody) - reinterpret_cast(rp3dBody)->setIsAllowedToSleep(enableSleeping); + constexpr int FLAG_POS = 1; + + dirtyFlags |= 1U << 1; + isAllowedToSleep ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); } void SHRigidBodyComponent::SetFreezePositionX(bool freezePositionX) noexcept { - SetFlag(freezePositionX, 2); - SetRP3DLinearConstraints(); + constexpr int FLAG_POS = 2; + + dirtyFlags |= 1U << 2; + freezePositionX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); } void SHRigidBodyComponent::SetFreezePositionY(bool freezePositionY) noexcept { - SetFlag(freezePositionY, 3); - SetRP3DLinearConstraints(); + constexpr int FLAG_POS = 3; + + dirtyFlags |= 1U << 2; + freezePositionY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); } void SHRigidBodyComponent::SetFreezePositionZ(bool freezePositionZ) noexcept { - SetFlag(freezePositionZ, 4); - SetRP3DLinearConstraints(); + constexpr int FLAG_POS = 4; + + dirtyFlags |= 1U << 2; + freezePositionZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); } void SHRigidBodyComponent::SetFreezeRotationX(bool freezeRotationX) noexcept { - SetFlag(freezeRotationX, 5); - SetRP3DAngularConstraints(); + constexpr int FLAG_POS = 5; + + dirtyFlags |= 1U << 3; + freezeRotationX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); } void SHRigidBodyComponent::SetFreezeRotationY(bool freezeRotationY) noexcept { - SetFlag(freezeRotationY, 6); - SetRP3DAngularConstraints(); + constexpr int FLAG_POS = 6; + + dirtyFlags |= 1U << 3; + freezeRotationY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); } void SHRigidBodyComponent::SetFreezeRotationZ(bool freezeRotationZ) noexcept { - SetFlag(freezeRotationZ, 7); - SetRP3DAngularConstraints(); + constexpr int FLAG_POS = 7; + + dirtyFlags |= 1U << 3; + freezeRotationZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); } void SHRigidBodyComponent::SetInterpolate(bool allowInterpolation) noexcept @@ -339,22 +225,34 @@ namespace SHADE interpolate = allowInterpolation; } - void SHRigidBodyComponent::SetLinearVelocity(const SHVec3& newLinearVelocity) const noexcept + void SHRigidBodyComponent::SetMass(float newMass) noexcept { - if (rp3dBody) - { - const rp3d::Vector3 NEW_V { newLinearVelocity.x, newLinearVelocity.y, newLinearVelocity.z }; - reinterpret_cast(rp3dBody)->setLinearVelocity(NEW_V); - } + dirtyFlags |= 1U << 5; + mass = newMass; } - void SHRigidBodyComponent::SetAngularVelocity(const SHVec3& newAngularVelocity) const noexcept + void SHRigidBodyComponent::SetDrag(float newDrag) noexcept { - if (rp3dBody) - { - const rp3d::Vector3 NEW_V { newAngularVelocity.x, newAngularVelocity.y, newAngularVelocity.z }; - reinterpret_cast(rp3dBody)->setAngularVelocity(NEW_V); - } + dirtyFlags |= 1U << 6; + drag = newDrag; + } + + void SHRigidBodyComponent::SetAngularDrag(float newAngularDrag) noexcept + { + dirtyFlags |= 1U << 7; + angularDrag = newAngularDrag; + } + + void SHRigidBodyComponent::SetLinearVelocity(const SHVec3& newLinearVelocity) noexcept + { + dirtyFlags |= 1U << 8; + linearVelocity = newLinearVelocity; + } + + void SHRigidBodyComponent::SetAngularVelocity(const SHVec3& newAngularVelocity) noexcept + { + dirtyFlags |= 1U << 9; + angularVelocity = newAngularVelocity; } /*-----------------------------------------------------------------------------------*/ @@ -363,148 +261,143 @@ namespace SHADE void SHRigidBodyComponent::OnCreate() { - componentFlags |= 1U << 0; // dirty - componentFlags |= 1U << 1; // rb dirty - componentFlags |= 1U << 2; // has rb + system = SHSystemManager::GetSystem(); + if (!system) + { + SHLOG_ERROR("Physics system does not exist, Rigid Body Component not added!") + return; + } - Synchronise(); + // Notify Physics System + system->AddRigidBody(GetEID()); } void SHRigidBodyComponent::OnDestroy() { - componentFlags |= 1U << 0; // dirty - componentFlags |= 1U << 1; // rb dirty - componentFlags &= ~(1U << 2); // no rb + // Notify Physics System + if (!system) + { + SHLOG_ERROR("Physics system does not exist, unable to remove Rigid Body Component!") + return; + } - Synchronise(); + system->RemoveRigidBody(GetEID()); } void SHRigidBodyComponent::AddForce(const SHVec3& force) const noexcept { - if (rp3dBody) + if (!system) { - const rp3d::Vector3 F { force.x, force.y, force.z }; - reinterpret_cast(rp3dBody)->applyWorldForceAtCenterOfMass(F); + SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!") + return; } + + // Notify Physics Systems + system->AddForce(GetEID(), force); } void SHRigidBodyComponent::AddForceAtLocalPos(const SHVec3& force, const SHVec3& localPos) const noexcept { - if (rp3dBody) + if (!system) { - const rp3d::Vector3 F{ force.x, force.y, force.z }; - const rp3d::Vector3 P{ localPos.x, localPos.y, localPos.z }; - reinterpret_cast(rp3dBody)->applyWorldForceAtLocalPosition(F, P); + SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!") + return; } + + // Notify Physics Systems + system->AddForceAtLocalPos(GetEID(), force, localPos); } void SHRigidBodyComponent::AddForceAtWorldPos(const SHVec3& force, const SHVec3& worldPos) const noexcept { - if (rp3dBody) + if (!system) { - const rp3d::Vector3 F{ force.x, force.y, force.z }; - const rp3d::Vector3 P{ worldPos.x, worldPos.y, worldPos.z }; - reinterpret_cast(rp3dBody)->applyWorldForceAtWorldPosition(F, P); + SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!") + return; } + + // Notify Physics Systems + system->AddForceAtWorldPos(GetEID(), force, worldPos); } void SHRigidBodyComponent::AddRelativeForce(const SHVec3& relativeForce) const noexcept { - if (rp3dBody) + if (!system) { - const rp3d::Vector3 F{ relativeForce.x, relativeForce.y, relativeForce.z }; - reinterpret_cast(rp3dBody)->applyLocalForceAtCenterOfMass(F); + SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!") + return; } + + // Notify Physics Systems + system->AddRelativeForce(GetEID(), force); } void SHRigidBodyComponent::AddRelativeForceAtLocalPos(const SHVec3& relativeForce, const SHVec3& localPos) const noexcept { - if (rp3dBody) + if (!system) { - const rp3d::Vector3 F{ relativeForce.x, relativeForce.y, relativeForce.z }; - const rp3d::Vector3 P{ localPos.x, localPos.y, localPos.z }; - reinterpret_cast(rp3dBody)->applyLocalForceAtLocalPosition(F, P); + SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!") + return; } + + // Notify Physics Systems + system->AddRelativeForceAtLocalPos(GetEID(), force, localPos); } void SHRigidBodyComponent::AddRelativeForceAtWorldPos(const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept { - if (rp3dBody) + if (!system) { - const rp3d::Vector3 F{ relativeForce.x, relativeForce.y, relativeForce.z }; - const rp3d::Vector3 P{ worldPos.x, worldPos.y, worldPos.z }; - reinterpret_cast(rp3dBody)->applyLocalForceAtWorldPosition(F, P); + SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!") + return; } + + // Notify Physics Systems + system->AddRelativeForceAtWorldPos(GetEID(), force, worldPos); } void SHRigidBodyComponent::AddTorque(const SHVec3& torque) const noexcept { - if (rp3dBody) + if (!system) { - const rp3d::Vector3 T{ torque.x, torque.y, torque.z }; - reinterpret_cast(rp3dBody)->applyWorldTorque(T); + SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!") + return; } + + // Notify Physics Systems + system->AddTorque(GetEID(), torque); } void SHRigidBodyComponent::AddRelativeTorque(const SHVec3& relativeTorque) const noexcept { - if (rp3dBody) + if (!system) { - const rp3d::Vector3 T{ relativeTorque.x, relativeTorque.y, relativeTorque.z }; - reinterpret_cast(rp3dBody)->applyLocalTorque(T); + SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!") + return; } + + // Notify Physics Systems + system->AddRelativeTorque(GetEID(), relativeTorque); } - /*-----------------------------------------------------------------------------------*/ - /* Private Function Member Definitions */ - /*-----------------------------------------------------------------------------------*/ +} // namespace SHADE - void SHRigidBodyComponent::SyncRP3DAndSHADE() - { - auto* rigidBody = reinterpret_cast(rp3dBody); +RTTR_REGISTRATION +{ + using namespace SHADE; + using namespace rttr; - rigidBody->setType(static_cast(type)); - - rigidBody->setMass(mass); - rigidBody->setLinearDamping(drag); - rigidBody->setAngularDamping(angularDrag); - - rigidBody->enableGravity(flags & (1U << 0)); - rigidBody->setIsAllowedToSleep(flags & (1U << 1)); - SetRP3DLinearConstraints(); - SetRP3DAngularConstraints(); - } - - - void SHRigidBodyComponent::SetFlag(bool flagState, int flagPos) - { - flagState ? flags |= (1U << flagPos) : flags &= ~(1U << flagPos); - } - - void SHRigidBodyComponent::SetRP3DLinearConstraints() const - { - const rp3d::Vector3 CONSTRAINTS - { - flags & 1U << 2 ? 1.0f : 0.0f, - flags & 1U << 3 ? 1.0f : 0.0f, - flags & 1U << 4 ? 1.0f : 0.0f - }; - - if (rp3dBody) - reinterpret_cast(rp3dBody)->setLinearLockAxisFactor(CONSTRAINTS); - } - - void SHRigidBodyComponent::SetRP3DAngularConstraints() const - { - const rp3d::Vector3 CONSTRAINTS - { - flags & 1U << 5 ? 1.0f : 0.0f, - flags & 1U << 6 ? 1.0f : 0.0f, - flags & 1U << 7 ? 1.0f : 0.0f - }; - - if (rp3dBody) - reinterpret_cast(rp3dBody)->setAngularLockAxisFactor(CONSTRAINTS); - } - -} // namespace SHADE \ No newline at end of file + registration::class_("RigidBody Component") + .property("Type" , &SHRigidBodyComponent::GetType , &SHRigidBodyComponent::SetType ) + .property("Mass" , &SHRigidBodyComponent::GetMass , &SHRigidBodyComponent::SetMass ) + .property("Drag" , &SHRigidBodyComponent::GetDrag , &SHRigidBodyComponent::SetDrag ) + .property("Angular Drag" , &SHRigidBodyComponent::GetAngularDrag , &SHRigidBodyComponent::SetAngularDrag ) + .property("Use Gravity" , &SHRigidBodyComponent::IsGravityEnabled , &SHRigidBodyComponent::SetGravityEnabled ) + .property("Interpolate" , &SHRigidBodyComponent::IsInterpolating , &SHRigidBodyComponent::SetInterpolate ) + .property("Freeze Position X" , &SHRigidBodyComponent::GetFreezePositionX , &SHRigidBodyComponent::SetFreezePositionX ) + .property("Freeze Position Y" , &SHRigidBodyComponent::GetFreezePositionY , &SHRigidBodyComponent::SetFreezePositionY ) + .property("Freeze Position Z" , &SHRigidBodyComponent::GetFreezePositionZ , &SHRigidBodyComponent::SetFreezePositionZ ) + .property("Freeze Rotation X" , &SHRigidBodyComponent::GetFreezeRotationX , &SHRigidBodyComponent::SetFreezeRotationX ) + .property("Freeze Rotation Y" , &SHRigidBodyComponent::GetFreezeRotationY , &SHRigidBodyComponent::SetFreezeRotationY ) + .property("Freeze Rotation Z" , &SHRigidBodyComponent::GetFreezeRotationZ , &SHRigidBodyComponent::SetFreezeRotationZ ); +} \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h index 439fa3db..0793b2ff 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h @@ -10,6 +10,8 @@ #pragma once +#include + // Project Headers #include "ECS_Base/Components/SHComponent.h" #include "Physics/SHPhysicsObject.h" @@ -20,7 +22,7 @@ namespace SHADE /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ - class SH_API SHRigidBodyComponent : public SHComponent, public SHPhysicsObject + class SH_API SHRigidBodyComponent : public SHComponent { private: /*---------------------------------------------------------------------------------*/ @@ -43,8 +45,6 @@ namespace SHADE , COUNT }; - // TODO(Diren): Collision Types - /*---------------------------------------------------------------------------------*/ /* Constructors & Destructor */ /*---------------------------------------------------------------------------------*/ @@ -52,7 +52,7 @@ namespace SHADE SHRigidBodyComponent () noexcept; SHRigidBodyComponent (const SHRigidBodyComponent& rhs) noexcept = default; SHRigidBodyComponent (SHRigidBodyComponent&& rhs) noexcept = default; - ~SHRigidBodyComponent () override; + ~SHRigidBodyComponent () override = default; /*---------------------------------------------------------------------------------*/ /* Operator Overloads */ @@ -65,56 +65,61 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] bool IsGravityEnabled () const noexcept; - [[nodiscard]] bool IsSleepingEnabled () const noexcept; - [[nodiscard]] bool IsInterpolating () const noexcept; + [[nodiscard]] bool IsGravityEnabled () const noexcept; + [[nodiscard]] bool IsAllowedToSleep () const noexcept; + [[nodiscard]] bool IsInterpolating () const noexcept; - [[nodiscard]] Type GetType () const noexcept; - [[nodiscard]] float GetMass () const noexcept; - [[nodiscard]] float GetDrag () const noexcept; - [[nodiscard]] float GetAngularDrag () const noexcept; + [[nodiscard]] Type GetType () const noexcept; + [[nodiscard]] float GetMass () const noexcept; + [[nodiscard]] float GetDrag () const noexcept; + [[nodiscard]] float GetAngularDrag () const noexcept; - [[nodiscard]] bool GetFreezePositionX () const noexcept; - [[nodiscard]] bool GetFreezePositionY () const noexcept; - [[nodiscard]] bool GetFreezePositionZ () const noexcept; + [[nodiscard]] bool GetFreezePositionX () const noexcept; + [[nodiscard]] bool GetFreezePositionY () const noexcept; + [[nodiscard]] bool GetFreezePositionZ () const noexcept; - [[nodiscard]] bool GetFreezeRotationX () const noexcept; - [[nodiscard]] bool GetFreezeRotationY () const noexcept; - [[nodiscard]] bool GetFreezeRotationZ () const noexcept; + [[nodiscard]] bool GetFreezeRotationX () const noexcept; + [[nodiscard]] bool GetFreezeRotationY () const noexcept; + [[nodiscard]] bool GetFreezeRotationZ () const noexcept; - [[nodiscard]] SHVec3 GetForce () const noexcept; - [[nodiscard]] SHVec3 GetTorque () const noexcept; - [[nodiscard]] SHVec3 GetLinearVelocity () const noexcept; - [[nodiscard]] SHVec3 GetAngularVelocity () const noexcept; + [[nodiscard]] const SHVec3& GetForce () const noexcept; + [[nodiscard]] const SHVec3& GetTorque () const noexcept; + [[nodiscard]] const SHVec3& GetLinearVelocity () const noexcept; + [[nodiscard]] const SHVec3& GetAngularVelocity () const noexcept; + + [[nodiscard]] const SHVec3& GetPosition () const noexcept; + [[nodiscard]] const SHQuaternion& GetOrientation () const noexcept; + [[nodiscard]] SHVec3 GetRotation () const noexcept; /*---------------------------------------------------------------------------------*/ /* Setter Functions */ /*---------------------------------------------------------------------------------*/ - void SetType (Type newType) noexcept; - void SetMass (float newMass) noexcept; - void SetDrag (float newDrag) noexcept; - void SetAngularDrag (float newAngularDrag) noexcept; + void SetType (Type newType) noexcept; - void SetGravityEnabled (bool enableGravity) noexcept; - void SetSleepingEnabled (bool enableSleeping) noexcept; - void SetFreezePositionX (bool freezePositionX) noexcept; - void SetFreezePositionY (bool freezePositionY) noexcept; - void SetFreezePositionZ (bool freezePositionZ) noexcept; - void SetFreezeRotationX (bool freezeRotationX) noexcept; - void SetFreezeRotationY (bool freezeRotationY) noexcept; - void SetFreezeRotationZ (bool freezeRotationZ) noexcept; - void SetInterpolate (bool allowInterpolation) noexcept; + void SetGravityEnabled (bool enableGravity) noexcept; + void SetIsAllowedToSleep(bool isAllowedToSleep) noexcept; + void SetFreezePositionX (bool freezePositionX) noexcept; + void SetFreezePositionY (bool freezePositionY) noexcept; + void SetFreezePositionZ (bool freezePositionZ) noexcept; + void SetFreezeRotationX (bool freezeRotationX) noexcept; + void SetFreezeRotationY (bool freezeRotationY) noexcept; + void SetFreezeRotationZ (bool freezeRotationZ) noexcept; + void SetInterpolate (bool allowInterpolation) noexcept; - void SetLinearVelocity (const SHVec3& newLinearVelocity) const noexcept; - void SetAngularVelocity (const SHVec3& newAngularVelocity) const noexcept; + void SetMass (float newMass) noexcept; + void SetDrag (float newDrag) noexcept; + void SetAngularDrag (float newAngularDrag) noexcept; + + void SetLinearVelocity (const SHVec3& newLinearVelocity) noexcept; + void SetAngularVelocity (const SHVec3& newAngularVelocity) noexcept; /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ - void OnCreate () override; - void OnDestroy () override; + void OnCreate () override; + void OnDestroy () override; void AddForce (const SHVec3& force) const noexcept; void AddForceAtLocalPos (const SHVec3& force, const SHVec3& localPos) const noexcept; @@ -134,23 +139,33 @@ namespace SHADE Type type; + // rX rY rZ pX pY pZ slp g + uint8_t flags; + // 0 0 0 0 0 0 aV lV aD d m t ag lc slp g + uint16_t dirtyFlags; + bool interpolate; + + SHPhysicsSystem* system; + float mass; float drag; float angularDrag; - - // rX rY rZ pX pY pZ slp g - uint8_t flags; - bool interpolate; + + SHVec3 force; + SHVec3 linearVelocity; + + SHVec3 torque; + SHVec3 angularVelocity; + + // TODO(Diren): Once quaternions have replaced euler angles in transforms, store it for the rigidbody. + + SHVec3 position; + SHQuaternion orientation; /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ - void SyncRP3DAndSHADE (); - void SetFlag (bool flagState, int flagPos); - void SetRP3DLinearConstraints () const ; - void SetRP3DAngularConstraints () const ; - - + RTTR_ENABLE() }; } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHCollider.cpp b/SHADE_Engine/src/Physics/SHCollider.cpp new file mode 100644 index 00000000..724db19c --- /dev/null +++ b/SHADE_Engine/src/Physics/SHCollider.cpp @@ -0,0 +1,215 @@ +/**************************************************************************************** + * \file SHCollider.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for a Collider. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHCollider.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHCollider::SHCollider(Type colliderType) + : type { colliderType } + , isTrigger { false } + , dirty { true } + , shape { nullptr } + { + CreateShape(); + } + + SHCollider::SHCollider(const SHCollider& rhs) noexcept + : type { rhs.type} + , isTrigger { rhs.isTrigger } + , dirty { true } + , shape { nullptr } + { + CreateShape(); + + // TODO(Diren): Copy transform data over + } + + SHCollider::SHCollider(SHCollider&& rhs) noexcept + : type { rhs.type} + , isTrigger { rhs.isTrigger } + , dirty { true } + , shape { nullptr } + { + CreateShape(); + + // TODO(Diren): Copy transform data over + } + + SHCollider::~SHCollider() noexcept + { + delete shape; + } + + /*-----------------------------------------------------------------------------------*/ + /* Operator Overload Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHCollider& SHCollider::operator=(const SHCollider& rhs) noexcept + { + type = rhs.type; + isTrigger = rhs.isTrigger; + dirty = true; + + CreateShape(); + + // TODO(Diren): Copy transform data over + + return *this; + } + + SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept + { + type = rhs.type; + isTrigger = rhs.isTrigger; + dirty = true; + + CreateShape(); + + // TODO(Diren): Copy transform data over + + return *this; + } + + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + bool SHCollider::HasChanged() const noexcept + { + return dirty; + } + + bool SHCollider::IsTrigger() const noexcept + { + return isTrigger; + } + + SHCollider::Type SHCollider::GetType() const noexcept + { + return type; + } + + SHShape* SHCollider::GetShape() const noexcept + { + return shape; + } + + float SHCollider::GetFriction() const noexcept + { + // TODO(Diren): Fix after implementing materials + return 0.0f; + } + + float SHCollider::GetBounciness() const noexcept + { + // TODO(Diren): Fix after implementing materials + return 0.0f; + } + float SHCollider::GetDensity() const noexcept + { + // TODO(Diren): Fix after implementing materials + return 0.0f; + } + + SHVec3 SHCollider::GetPosition() const noexcept + { + // TODO(Diren): Fix after linking transform data + return SHVec3::Zero; + } + + const SHVec3& SHCollider::GetPositionOffset() const noexcept + { + return positionOffset; + } + + SHQuaternion SHCollider::GetOrientation() const noexcept + { + // TODO(Diren): Fix after linking transform data + return SHQuaternion::Identity; + } + + /*-----------------------------------------------------------------------------------*/ + /* Setter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHCollider::SetType(Type newType) noexcept + { + if (type == newType) + return; + + dirty = true; + + type = newType; + CreateShape(); + } + + void SHCollider::SetIsTrigger(bool trigger) noexcept + { + dirty = true; + isTrigger = trigger; + } + + void SHCollider::SetFriction(float friction) noexcept + { + dirty = true; + } + + void SHCollider::SetBounciness(float bounciness) noexcept + { + dirty = true; + } + + void SHCollider::SetDensity(float density) noexcept + { + dirty = true; + } + + void SHCollider::SetPositionOffset(const SHVec3& posOffset) noexcept + { + dirty = true; + positionOffset = posOffset; + } + + /*-----------------------------------------------------------------------------------*/ + /* Private Member Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHCollider::CreateShape() + { + // Remove current shape + delete shape; + + switch (type) + { + case Type::BOX: CreateBoundingBox(); break; + case Type::SPHERE: CreateSphere(); break; + default: break; + } + } + + void SHCollider::CreateBoundingBox() + { + shape = new SHBoundingBox{ SHVec3::Zero, SHVec3::One }; + } + + void SHCollider::CreateSphere() + { + + } + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHCollider.h b/SHADE_Engine/src/Physics/SHCollider.h new file mode 100644 index 00000000..fce4a5b2 --- /dev/null +++ b/SHADE_Engine/src/Physics/SHCollider.h @@ -0,0 +1,108 @@ +/**************************************************************************************** + * \file SHCollider.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for a Collider. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +// Project Headers +#include "Math/Geometry/SHBoundingBox.h" +#include "Math/SHQuaternion.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SH_API SHCollider + { + public: + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + + enum class Type + { + BOX + , SPHERE + , CAPSULE + , CONVEX_HULL + , CONVEX_MESH + }; + + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHCollider (Type colliderType); + + SHCollider (const SHCollider& rhs) noexcept; + SHCollider (SHCollider&& rhs) noexcept; + ~SHCollider () noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + SHCollider& operator=(const SHCollider& rhs) noexcept; + SHCollider& operator=(SHCollider&& rhs) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] bool HasChanged () const noexcept; + + [[nodiscard]] bool IsTrigger () const noexcept; + + [[nodiscard]] Type GetType () const noexcept; + [[nodiscard]] SHShape* GetShape () const noexcept; + + [[nodiscard]] float GetFriction () const noexcept; + [[nodiscard]] float GetBounciness () const noexcept; + [[nodiscard]] float GetDensity () const noexcept; + + [[nodiscard]] SHVec3 GetPosition () const noexcept; + [[nodiscard]] const SHVec3& GetPositionOffset () const noexcept; + [[nodiscard]] SHQuaternion GetOrientation () const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Setter Functions */ + /*---------------------------------------------------------------------------------*/ + + void SetType (Type newType) noexcept; + + void SetIsTrigger (bool isTrigger) noexcept; + void SetFriction (float friction) noexcept; + void SetBounciness (float bounciness) noexcept; + void SetDensity (float density) noexcept; + + void SetPositionOffset (const SHVec3& positionOffset) noexcept; + + private: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + Type type; + bool isTrigger; + bool dirty; + SHShape* shape; + SHVec3 positionOffset; + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + void CreateShape (); + void CreateBoundingBox (); + void CreateSphere (); + }; + +} // namespace SHADE diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index 4f0616f8..325d860f 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -24,9 +24,10 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHPhysicsObject::SHPhysicsObject() noexcept - : entityID { MAX_EID } - , componentFlags { 0 } - , rp3dBody { nullptr } + : entityID { MAX_EID } + , isRigidBody { false } + , hasColliders{ false } + , rp3dBody { nullptr } {} SHPhysicsObject::~SHPhysicsObject() noexcept @@ -81,32 +82,11 @@ namespace SHADE /* Public Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHPhysicsObject::Synchronise() const - { - if (const bool IS_DIRTY = componentFlags & 1U << 0; IS_DIRTY) - { - auto* physicsSystem = SHSystemManager::GetSystem(); - const bool IS_RIGIDBODY_DIRTY = componentFlags & 1U << 1; - const bool IS_COLLIDER_DIRTY = componentFlags & 1U << 3; - - if (IS_RIGIDBODY_DIRTY) - { - static constexpr auto COMP_ENUM = SHPhysicsSystem::UpdateComponent::RIGID_BODY; - - const bool HAS_RIGIDBODY = componentFlags & 1U << 2; - HAS_RIGIDBODY ? physicsSystem->AddComponent(COMP_ENUM, entityID) : physicsSystem->RemoveComponent(COMP_ENUM, entityID); - } - - if (IS_COLLIDER_DIRTY) - { - static constexpr auto COMP_ENUM = SHPhysicsSystem::UpdateComponent::COLLIDER; - - const bool HAS_COLLIDER = componentFlags & 1U << 2; - HAS_COLLIDER ? physicsSystem->AddComponent(COMP_ENUM, entityID) : physicsSystem->RemoveComponent(COMP_ENUM, entityID); - } - } - } + /*-----------------------------------------------------------------------------------*/ + /* Private Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.h b/SHADE_Engine/src/Physics/SHPhysicsObject.h index 20449f2d..e0f0f38f 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.h @@ -25,22 +25,24 @@ namespace SHADE class SH_API SHPhysicsObject { - protected: + private: /*---------------------------------------------------------------------------------*/ /* Friends */ /*---------------------------------------------------------------------------------*/ friend class SHPhysicsSystem; + friend class SHRigidBodyComponent; + friend class SHColliderComponent; public: /*---------------------------------------------------------------------------------*/ /* Constructors & Destructor */ /*---------------------------------------------------------------------------------*/ - SHPhysicsObject () noexcept; - SHPhysicsObject (const SHPhysicsObject& rhs) noexcept = default; - SHPhysicsObject (SHPhysicsObject&& rhs) noexcept = default; - ~SHPhysicsObject () noexcept; + SHPhysicsObject () noexcept; + SHPhysicsObject (const SHPhysicsObject& rhs) noexcept = default; + SHPhysicsObject (SHPhysicsObject&& rhs) noexcept = default; + virtual ~SHPhysicsObject () noexcept; /*---------------------------------------------------------------------------------*/ /* Operator Overloads */ @@ -53,30 +55,31 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] SHVec3 GetPosition () const noexcept; - [[nodiscard]] SHQuaternion GetOrientation () const noexcept; - [[nodiscard]] SHVec3 GetRotation () const noexcept; + [[nodiscard]] virtual SHVec3 GetPosition () const noexcept; + [[nodiscard]] virtual SHQuaternion GetOrientation () const noexcept; + [[nodiscard]] virtual SHVec3 GetRotation () const noexcept; /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ - /** - * @brief Checks for updates in the component states and tells the physics system to - * make any necessary additions / removals to rp3d side to sync with the SHADE - * component. - */ - void Synchronise() const; - - protected: + private: /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ EntityID entityID; - uint8_t componentFlags; // 0 0 0 c cDirty rb rbDirty dirty + bool isRigidBody; + bool hasColliders; + rp3d::CollisionBody* rp3dBody; // Can be either a collision body or a rigid body rp3d::Transform prevTransform; // Cached transform for interpolation + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + + }; } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index df69ad04..9be8a5ef 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -26,9 +26,9 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHPhysicsSystem::SHPhysicsSystem() - : accumulatedTime { 0.0 } - , fixedDT { 1.0 / 60.0 } - , world { nullptr } + : interpolationFactor { 0.0 } + , fixedDT { 1.0 / 60.0 } + , world { nullptr } {} SHPhysicsSystem::PhysicsPreUpdate::PhysicsPreUpdate() @@ -36,17 +36,22 @@ namespace SHADE {} SHPhysicsSystem::PhysicsFixedUpdate::PhysicsFixedUpdate() - : SHFixedSystemRoutine { DEFAULT_FIXED_STEP, "Physics FixedUpdate", true } + : SHFixedSystemRoutine { DEFAULT_FIXED_STEP, "Physics FixedUpdate", false } {} SHPhysicsSystem::PhysicsPostUpdate::PhysicsPostUpdate() - : SHSystemRoutine { "Physics PostUpdate", true } + : SHSystemRoutine { "Physics PostUpdate", false } {} /*-----------------------------------------------------------------------------------*/ /* Getter Function Definitions */ /*-----------------------------------------------------------------------------------*/ + double SHPhysicsSystem::GetFixedDT() const noexcept + { + return fixedDT; + } + bool SHPhysicsSystem::IsSleepingEnabled() const noexcept { if (world) @@ -97,6 +102,11 @@ namespace SHADE /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ + void SHPhysicsSystem::SetFixedDT(double fixedUpdateRate) noexcept + { + fixedDT = fixedUpdateRate; + } + void SHPhysicsSystem::SetWorldGravity(const SHVec3& gravity) const noexcept { if (world) @@ -185,228 +195,362 @@ namespace SHADE factory.destroyPhysicsWorld(world); } - void SHPhysicsSystem::PhysicsPreUpdate::Execute([[maybe_unused]]double dt) noexcept + void SHPhysicsSystem::AddRigidBody(EntityID entityID) noexcept + { + #ifdef _DEBUG + SHLOG_INFO("Adding a Rigidbody to the Physics World.") + #endif + + // Check if entity is already a physics object + auto* physicsObject = GetPhysicsObject(entityID); + if (!physicsObject) + physicsObject = &(map.emplace(entityID, SHPhysicsObject{}).first->second); + + // Get entity transform + auto const* SHADE_TF = SHComponentManager::GetComponent_s(entityID); + + // Possibly redundant + if (!SHADE_TF) + { + SHComponentManager::AddComponent(entityID); + SHADE_TF = SHComponentManager::GetComponent(entityID); + } + + const SHVec3& SHADE_POS = SHADE_TF->GetWorldPosition(); + const SHVec3& SHADE_ROT = SHADE_TF->GetWorldRotation(); + + const rp3d::Vector3 RP3D_POS { SHADE_POS.x, SHADE_POS.y, SHADE_POS.z }; + const rp3d::Quaternion RP3D_ROT = rp3d::Quaternion::fromEulerAngles( SHADE_ROT.x, SHADE_ROT.y, SHADE_ROT.z ); + + physicsObject->rp3dBody = world->createRigidBody(rp3d::Transform{ RP3D_POS, RP3D_ROT }); + physicsObject->isRigidBody = true; + } + + void SHPhysicsSystem::AddCollider(EntityID entityID) noexcept + { + #ifdef _DEBUG + SHLOG_INFO("Adding a Collider to the Physics World.") + #endif + } + + void SHPhysicsSystem::RemoveRigidBody(EntityID entityID) noexcept + { + #ifdef _DEBUG + SHLOG_INFO("Removing a Rigidbody from the Physics World.") + #endif + + } + + void SHPhysicsSystem::RemoveCollider(EntityID entityID) noexcept + { + #ifdef _DEBUG + SHLOG_INFO("Removing a Collider from the Physics World.") + #endif + } + + void SHPhysicsSystem::AddForce(EntityID entityID, const SHVec3& force) const noexcept + { + + } + + void SHPhysicsSystem::AddForceAtLocalPos(EntityID entityID, const SHVec3& force, const SHVec3& localPos) const noexcept + { + + } + + void SHPhysicsSystem::AddForceAtWorldPos(EntityID entityID, const SHVec3& force, const SHVec3& worldPos) const noexcept + { + + } + + void SHPhysicsSystem::AddRelativeForce(EntityID entityID, const SHVec3& relativeForce) const noexcept + { + + } + + void SHPhysicsSystem::AddRelativeForceAtLocalPos(EntityID entityID, const SHVec3& relativeForce, const SHVec3& localPos) const noexcept + { + + } + + void SHPhysicsSystem::AddRelativeForceAtWorldPos(EntityID entityID, const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept + { + + } + + void SHPhysicsSystem::AddTorque(EntityID entityID, const SHVec3& torque) const noexcept + { + + } + + void SHPhysicsSystem::AddRelativeTorque(EntityID entityID, const SHVec3& relativeTorque) const noexcept + { + + } + + void SHPhysicsSystem::PhysicsPreUpdate::Execute(double) noexcept { auto* system = reinterpret_cast(GetSystem()); - system->ClearUpdateQueue(); - //system->SyncActiveStates(SHSceneManager::GetCurrentSceneGraph()); + // Update bodies and colliders if component is dirty + const auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + system->SyncComponents(sceneGraph); } - void SHPhysicsSystem::PhysicsFixedUpdate::FixedExecute(double dt) noexcept + void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept { auto* system = reinterpret_cast(GetSystem()); - system->world->update(static_cast(dt)); + fixedTimeStep = 1.0 / system->fixedDT; + accumulatedTime += dt; - system->fixedDT = fixedTimeStep; - system->accumulatedTime = accumulatedTime; + int count = 0; + while (accumulatedTime > fixedTimeStep) + { + system->world->update(static_cast(fixedTimeStep)); + + accumulatedTime -= fixedTimeStep; + ++count; + } + + stats.numSteps = count; + + system->interpolationFactor = accumulatedTime / fixedTimeStep; } - void SHPhysicsSystem::PhysicsPostUpdate::Execute(double dt) noexcept + void SHPhysicsSystem::PhysicsPostUpdate::Execute(double) noexcept { auto* system = reinterpret_cast(GetSystem()); // Interpolate transforms for rendering const auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); - //system->SyncTransforms(sceneGraph); + system->SyncTransforms(sceneGraph); // TODO(Diren): Handle trigger messages for scripting } - /*-----------------------------------------------------------------------------------*/ - /* Protected Function Member Definitions */ - /*-----------------------------------------------------------------------------------*/ - - void SHPhysicsSystem::AddComponent(UpdateComponent comp, EntityID entityID) noexcept - { - updateQueue.push({ comp, UpdateType::ADD, entityID }); - } - - - void SHPhysicsSystem::RemoveComponent(UpdateComponent comp, EntityID entityID) noexcept - { - updateQueue.push({ comp, UpdateType::REMOVE, entityID }); - } - /*-----------------------------------------------------------------------------------*/ /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHPhysicsSystem::ClearUpdateQueue() noexcept + SHPhysicsObject* SHPhysicsSystem::GetPhysicsObject(EntityID entityID) noexcept { - while (!updateQueue.empty()) + const auto it = map.find(entityID); + if (it == map.end()) { - const auto& CMD = updateQueue.front(); - switch (CMD.type) - { - case UpdateType::ADD: - { - switch (CMD.component) - { - case UpdateComponent::RIGID_BODY: AddRigidBody(CMD.entityID); break; - //case UpdateComponent::COLLIDER: AddCollider(CMD.entityID); break; - default: break; - } - } - case UpdateType::REMOVE: - { - switch (CMD.component) - { - case UpdateComponent::RIGID_BODY: RemoveRigidBody(CMD.entityID); break; - //case UpdateComponent::COLLIDER: RemoveCollider(CMD.entityID); break; - default: break; - } - } - default: break; - } - - updateQueue.pop(); + SHLOG_ERROR("Entity {} is not in the physics system!", entityID) + return nullptr; } + + return &(it->second); } - void SHPhysicsSystem::SyncActiveStates(const SHSceneGraph& sceneGraph) const noexcept + void SHPhysicsSystem::SyncComponents(const SHSceneGraph& sceneGraph) noexcept { - // Sync active states: if node or component is not active, set rp3d to inactive - static constexpr auto SYNC_ACTIVE = [](SHSceneNode* node) + static const auto SYNC_COMPONENTS = [&](SHSceneNode* node) { const EntityID ENTITY_ID = node->GetEntityID(); - // Check if has rigid body - auto const* rigidBodyComponent = SHComponentManager::GetComponent_s(ENTITY_ID); - if(rigidBodyComponent) - { - const bool RP3D_ACTIVE = rigidBodyComponent->rp3dBody->isActive(); - const bool SHADE_ACTIVE = node->IsActive() && rigidBodyComponent->isActive; + // Get physics object + auto const* physicsObject = GetPhysicsObject(ENTITY_ID); + if (!physicsObject) + return; - if (RP3D_ACTIVE != SHADE_ACTIVE) - rigidBodyComponent->rp3dBody->setIsActive(SHADE_ACTIVE); - } - else // Check for a collider + const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive(); + const bool NODE_ACTIVE = node->IsActive(); + + // Sync rigid body + if (physicsObject->isRigidBody) { + auto* rbComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + if (rbComponent->dirtyFlags > 0) + { + SyncRB(physicsObject, rbComponent); + rbComponent->dirtyFlags = 0; + } + + + // Sync active states + const bool SHADE_ACTIVE = NODE_ACTIVE && rbComponent->isActive; + if (SHADE_ACTIVE != RP3D_ACTIVE) + physicsObject->rp3dBody->setIsActive(SHADE_ACTIVE); + } + + // Sync colliders + if (physicsObject->hasColliders) + { + auto const* colliderComponent = SHComponentManager::GetComponent_s(ENTITY_ID); } + + // Sync transforms + auto const* tfComponent = SHComponentManager::GetComponent(ENTITY_ID); + if (tfComponent->HasChanged()) + { + const SHVec3& SHADE_POS = tfComponent->GetWorldPosition(); + const SHVec3& SHADE_ROT = tfComponent->GetWorldRotation(); + + const rp3d::Vector3 RP3D_POS { SHADE_POS.x, SHADE_POS.y, SHADE_POS.z }; + const rp3d::Quaternion RP3D_ROT = rp3d::Quaternion::fromEulerAngles(SHADE_ROT.x, SHADE_ROT.y, SHADE_ROT.z); + + physicsObject->rp3dBody->setTransform(rp3d::Transform{ RP3D_POS, RP3D_ROT }); + } }; - sceneGraph.Traverse(SYNC_ACTIVE); + sceneGraph.Traverse(SYNC_COMPONENTS); } - void SHPhysicsSystem::SyncTransforms(const SHSceneGraph& sceneGraph) const noexcept + void SHPhysicsSystem::SyncTransforms(const SHSceneGraph& sceneGraph) noexcept { - const rp3d::decimal INTERPOLATION_FACTOR = static_cast(accumulatedTime / fixedDT); - static const auto SYNC_TRANSFORMS = [&](SHSceneNode* node) { const EntityID ENTITY_ID = node->GetEntityID(); - // Check if has rigid body - if (auto* rb = SHComponentManager::GetComponent_s(ENTITY_ID); rb) + // Get physics object + auto* physicsObject = GetPhysicsObject(ENTITY_ID); + if (!physicsObject) + return; + + auto* tfComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + + rp3d::Vector3 rp3dPos; + rp3d::Quaternion rp3dRot; + + const rp3d::Transform CURRENT_TF = physicsObject->rp3dBody->getTransform(); + + // Check if transform should be interpolated + auto const* rbComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + if (rbComponent && rbComponent->IsInterpolating()) { - if (node->IsActive() && rb->isActive) - { - // Get SHADE transform - auto* transformComponent = SHComponentManager::GetComponent_s(ENTITY_ID); - SHASSERT(transformComponent != nullptr, "Transform Component missing from Entity " + std::to_string(ENTITY_ID)) + const rp3d::Transform PREV_TF = physicsObject->prevTransform; + const rp3d::Transform INTERPOLATED_TF = rp3d::Transform::interpolateTransforms(PREV_TF, CURRENT_TF, static_cast(interpolationFactor)); - SHVec3 shadePos, shadeRot; - - if (rb->interpolate) - { - const rp3d::Transform CURRENT_TRANSFORM = rb->rp3dBody->getTransform(); - const rp3d::Transform INTERPOLATED_TRANSFORM = rp3d::Transform::interpolateTransforms(rb->prevTransform, CURRENT_TRANSFORM, INTERPOLATION_FACTOR); - - const auto& RP3D_POS = INTERPOLATED_TRANSFORM.getPosition(); - shadePos = SHVec3{ RP3D_POS.x, RP3D_POS.y, RP3D_POS.z }; - - const auto& RP3D_ORT = INTERPOLATED_TRANSFORM.getOrientation(); - shadeRot = SHQuaternion{ RP3D_ORT.x, RP3D_ORT.y, RP3D_ORT.z, RP3D_ORT.w }.ToEuler(); - - rb->prevTransform = CURRENT_TRANSFORM; - } - else - { - - const auto& RP3D_POS = rb->GetPosition(); - shadePos = SHVec3{ RP3D_POS.x, RP3D_POS.y, RP3D_POS.z }; - shadeRot = rb->GetOrientation().ToEuler(); - } - - transformComponent->SetWorldPosition(shadePos); - transformComponent->SetWorldRotation(shadeRot); - } - else // Check for a collider - { - - } + + rp3dPos = INTERPOLATED_TF.getPosition(); + rp3dRot = INTERPOLATED_TF.getOrientation(); } + else + { + rp3dPos = CURRENT_TF.getPosition(); + rp3dRot = CURRENT_TF.getOrientation(); + } + + // Convert RP3D Transform to SHADE + const SHVec3 SHADE_POS = SHVec3{ rp3dPos.x, rp3dPos.y, rp3dPos.z }; + const SHVec3 SHADE_ROT = SHQuaternion{ rp3dRot.x, rp3dRot.y, rp3dRot.z, rp3dRot.w }.ToEuler(); + + tfComponent->SetWorldPosition(SHADE_POS); + tfComponent->SetWorldRotation(SHADE_ROT); + + // Cache transforms + physicsObject->prevTransform = CURRENT_TF; }; sceneGraph.Traverse(SYNC_TRANSFORMS); } - - void SHPhysicsSystem::AddRigidBody(EntityID entityID) const noexcept + void SHPhysicsSystem::SyncRB(SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept { - #ifdef _DEBUG - SHLOG_INFO("Adding a Rigidbody to the Physics World.") - #endif + auto* rigidBody = reinterpret_cast(physicsObject->rp3dBody); - // Rigid Bodies need a transform. - auto const* transformComponent = SHComponentManager::GetComponent_s(entityID); - if (!transformComponent) + const uint16_t RB_FLAGS = comp->dirtyFlags; + const size_t NUM_FLAGS = sizeof(RB_FLAGS) * 8U; + for (size_t i = 0; i < NUM_FLAGS; ++i) { - // NOTE: This should already be handled by the editor. + // Check if current dirty flag has been set to true + if (RB_FLAGS & 1U << i) + { + switch (i) + { + case 0: // Gravity + { + rigidBody->enableGravity(comp->IsGravityEnabled()); + break; + } + case 1: // Sleeping + { + rigidBody->setIsAllowedToSleep(comp->IsAllowedToSleep()); + break; + } + case 2: // Linear Constraints + { + SetRP3DLinearConstraints(rigidBody, comp->flags); + break; + } + case 3: // Angular Constraints + { + SetRP3DAngularConstraints(rigidBody, comp->flags); + break; + } + case 4: // Type + { + rigidBody->setType(static_cast(comp->GetType())); + break; + } + case 5: // Mass + { + rigidBody->setMass(comp->GetMass()); + break; + } + case 6: // Drag + { + rigidBody->setLinearDamping(comp->GetDrag()); + break; + } + case 7: // Angular Drag + { + rigidBody->setAngularDamping(comp->GetAngularDrag()); + break; + } + case 8: // Linear Velocity + { + const SHVec3& SHADE_VEL = comp->GetLinearVelocity(); + rp3d::Vector3 RP3D_VEL { SHADE_VEL.x, SHADE_VEL.y, SHADE_VEL.z }; - SHLOG_INFO("Automatically adding a transform to Entity {}", entityID) - SHComponentManager::AddComponent(entityID); - transformComponent = SHComponentManager::GetComponent(entityID); + rigidBody->setLinearVelocity(RP3D_VEL); + break; + } + case 9: // Angular Velocity + { + const SHVec3& SHADE_VEL = comp->GetAngularVelocity(); + rp3d::Vector3 RP3D_VEL { SHADE_VEL.x, SHADE_VEL.y, SHADE_VEL.z }; + + rigidBody->setAngularVelocity(RP3D_VEL); + break; + } + default: break; + } + } } - - const SHVec3& SHADE_WORLD_POSITION = transformComponent->GetWorldPosition(); - const rp3d::Vector3 RP3D_POSITION { SHADE_WORLD_POSITION.x, SHADE_WORLD_POSITION.y, SHADE_WORLD_POSITION.z }; - - const SHVec3& SHADE_WORLD_ROTATION = transformComponent->GetWorldRotation(); - const rp3d::Quaternion RP3D_ORIENTATION = rp3d::Quaternion::fromEulerAngles(SHADE_WORLD_ROTATION.x, SHADE_WORLD_ROTATION.y, SHADE_WORLD_ROTATION.z); - - const rp3d::Transform RP3D_TF { RP3D_POSITION, RP3D_ORIENTATION }; - - auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); - if (!rigidBodyComponent) - { - // NOTE: This should already be handled by the editor. - - SHLOG_INFO("Automatically adding a rigidbody to Entity {}", entityID) - SHComponentManager::AddComponent(entityID); - rigidBodyComponent = SHComponentManager::GetComponent(entityID); - } - - rigidBodyComponent->rp3dBody = world->createRigidBody(RP3D_TF); - rigidBodyComponent->prevTransform = RP3D_TF; - rigidBodyComponent->SyncRP3DAndSHADE(); - - // Reassign collider - //if (collider) - //{ - // collider. - //} } - void SHPhysicsSystem::RemoveRigidBody(EntityID entityID) const noexcept + void SHPhysicsSystem::SetRP3DLinearConstraints(rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept { - #ifdef _DEBUG - SHLOG_INFO("Removing a Rigidbody from the Physics World.") - #endif - - auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); - if (rigidBodyComponent == nullptr) + const rp3d::Vector3 CONSTRAINTS { - SHLOG_ERROR("Entity {} does not have a rigidbody component to remove!", entityID) - return; - } + rbFlags & 1U << 2 ? 1.0f : 0.0f, + rbFlags & 1U << 3 ? 1.0f : 0.0f, + rbFlags & 1U << 4 ? 1.0f : 0.0f + }; - // If a collider exists, remake the colliders with a collision body + + rp3dRigidBody->setLinearLockAxisFactor(CONSTRAINTS); + } - world->destroyRigidBody(reinterpret_cast(rigidBodyComponent->rp3dBody)); - rigidBodyComponent->rp3dBody = nullptr; // this should be redundant + void SHPhysicsSystem::SetRP3DAngularConstraints(rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept + { + const rp3d::Vector3 CONSTRAINTS + { + rbFlags & 1U << 5 ? 1.0f : 0.0f, + rbFlags & 1U << 6 ? 1.0f : 0.0f, + rbFlags & 1U << 7 ? 1.0f : 0.0f + }; + + rp3dRigidBody->setAngularLockAxisFactor(CONSTRAINTS); + } + + void SHPhysicsSystem::SyncColliders(SHPhysicsObject const* physicsObject, const SHColliderComponent* comp) noexcept + { + } } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index 273eb54d..af615f35 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -11,16 +11,20 @@ #pragma once #include +#include #include // Project Headers -#include "Math/SHQuaternion.h" +#include "SHPhysicsObject.h" #include "Components/SHRigidBodyComponent.h" +#include "Components/SHColliderComponent.h" + #include "Scene/SHSceneGraph.h" #include "ECS_Base/System/SHSystemRoutine.h" #include "ECS_Base/System/SHFixedSystemRoutine.h" + namespace SHADE { /*-----------------------------------------------------------------------------------*/ @@ -29,13 +33,6 @@ namespace SHADE class SH_API SHPhysicsSystem : public SHSystem { - protected: - /*---------------------------------------------------------------------------------*/ - /* Friends */ - /*---------------------------------------------------------------------------------*/ - - friend class SHPhysicsObject; - public: /*---------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -59,6 +56,8 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ + [[nodiscard]] double GetFixedDT () const noexcept; + [[nodiscard]] bool IsSleepingEnabled () const noexcept; [[nodiscard]] SHVec3 GetWorldGravity () const noexcept; @@ -70,7 +69,7 @@ namespace SHADE /* Setter Functions */ /*---------------------------------------------------------------------------------*/ - //void SetFixedUpdate (double fixedUpdateRate) noexcept; + void SetFixedDT (double fixedUpdateRate) noexcept; void SetWorldGravity (const SHVec3& gravity) const noexcept; void SetNumberVelocityIterations (uint16_t numVelIterations) const noexcept; void SetNumberPositionIterations (uint16_t numPosIterations) const noexcept; @@ -82,13 +81,32 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - void Init () override; - void Exit () override; + void Init () override; + void Exit () override; + + void AddRigidBody (EntityID entityID) noexcept; + void AddCollider (EntityID entityID) noexcept; + void RemoveRigidBody (EntityID entityID) noexcept; + void RemoveCollider (EntityID entityID) noexcept; + + void AddForce (EntityID entityID, const SHVec3& force) const noexcept; + void AddForceAtLocalPos (EntityID entityID, const SHVec3& force, const SHVec3& localPos) const noexcept; + void AddForceAtWorldPos (EntityID entityID, const SHVec3& force, const SHVec3& worldPos) const noexcept; + + void AddRelativeForce (EntityID entityID, const SHVec3& relativeForce) const noexcept; + void AddRelativeForceAtLocalPos (EntityID entityID, const SHVec3& relativeForce, const SHVec3& localPos) const noexcept; + void AddRelativeForceAtWorldPos (EntityID entityID, const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept; + + void AddTorque (EntityID entityID, const SHVec3& torque) const noexcept; + void AddRelativeTorque (EntityID entityID, const SHVec3& relativeTorque) const noexcept; /*---------------------------------------------------------------------------------*/ /* System Routines */ /*---------------------------------------------------------------------------------*/ + /** + * @brief Synchronises RP3D with SHADE + */ class SH_API PhysicsPreUpdate : public SHSystemRoutine { public: @@ -118,8 +136,7 @@ namespace SHADE /* Function Members */ /*-------------------------------------------------------------------------------*/ - //void Execute (double dt) noexcept override; - void FixedExecute (double dt) noexcept override; + void Execute (double dt) noexcept override; }; class SH_API PhysicsPostUpdate : public SHSystemRoutine @@ -138,56 +155,43 @@ namespace SHADE void Execute(double dt) noexcept override; }; - protected: + private: /*---------------------------------------------------------------------------------*/ /* Type Definitions */ /*---------------------------------------------------------------------------------*/ - enum class UpdateComponent { RIGID_BODY, COLLIDER }; - enum class UpdateType { ADD, REMOVE }; + using EntityObjectMap = std::unordered_map; - struct UpdateCommand - { - UpdateComponent component; - UpdateType type; - EntityID entityID; - }; - - /*---------------------------------------------------------------------------------*/ - /* Function Members */ - /*---------------------------------------------------------------------------------*/ - - void AddComponent (UpdateComponent comp, EntityID entityID) noexcept; - void RemoveComponent (UpdateComponent comp, EntityID entityID) noexcept; - - private: /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ - // TODO(Diren): Store interpFactor & fixedUpdate for modifiable fixedDT + // TODO(Diren): Store interpFactor - double accumulatedTime; + double interpolationFactor; double fixedDT; rp3d::PhysicsCommon factory; rp3d::PhysicsWorld* world; - std::queue updateQueue; + EntityObjectMap map; + + /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ + SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; - void ClearUpdateQueue () noexcept; - void SyncActiveStates (const SHSceneGraph& sceneGraph) const noexcept; - void SyncTransforms (const SHSceneGraph& sceneGraph) const noexcept; + void SyncComponents (const SHSceneGraph& sceneGraph) noexcept; + void SyncTransforms (const SHSceneGraph& sceneGraph) noexcept; // TODO(Diren): Trigger handling - void AddRigidBody (EntityID entityID) const noexcept; - void AddCollider (EntityID entityID) const noexcept; - void RemoveRigidBody (EntityID entityID) const noexcept; - void RemoveCollider (EntityID entityID) const noexcept; + static void SyncRB (SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept; + static void SetRP3DLinearConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept; + static void SetRP3DAngularConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept; + + static void SyncColliders (SHPhysicsObject const* physicsObject, const SHColliderComponent* comp) noexcept; }; From b657ad88846b228ec14149278bfb12fc90383bea Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sat, 1 Oct 2022 16:33:16 +0800 Subject: [PATCH 06/61] Handled resizing for the render graph resource (not tested) --- .../Graphics/Devices/SHVkLogicalDevice.cpp | 2 + .../src/Graphics/Images/SHVkImage.cpp | 74 ++++++---- SHADE_Engine/src/Graphics/Images/SHVkImage.h | 5 +- .../src/Graphics/Images/SHVkImageView.cpp | 136 ++++++++++-------- .../src/Graphics/Images/SHVkImageView.h | 5 + .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 19 ++- .../MiddleEnd/Interface/SHGraphicsSystem.h | 2 + .../Graphics/RenderGraph/SHRenderGraph.cpp | 9 ++ .../src/Graphics/RenderGraph/SHRenderGraph.h | 1 + .../RenderGraph/SHRenderGraphResource.cpp | 56 +++++++- .../RenderGraph/SHRenderGraphResource.h | 16 +++ 11 files changed, 220 insertions(+), 105 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index 3fa797bf..766a27c6 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -195,6 +195,8 @@ namespace SHADE vk::PhysicalDeviceDescriptorIndexingFeatures descIndexingFeature{}; descIndexingFeature.descriptorBindingVariableDescriptorCount = true; + descIndexingFeature.shaderSampledImageArrayNonUniformIndexing = true; + descIndexingFeature.runtimeDescriptorArray = true; // Prepare to create the device vk::DeviceCreateInfo deviceCreateInfo diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp b/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp index b6f20af4..ed539a6c 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp +++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp @@ -79,6 +79,41 @@ namespace SHADE vmaUnmapMemory(*vmaAllocator, stagingAlloc); } + void SHVkImage::CreateFramebufferImage(void) noexcept + { + vk::ImageCreateInfo imageCreateInfo{}; + imageCreateInfo.imageType = vk::ImageType::e2D; + imageCreateInfo.extent.width = width; + imageCreateInfo.extent.height = height; + imageCreateInfo.extent.depth = depth; + imageCreateInfo.mipLevels = mipLevelCount; + imageCreateInfo.arrayLayers = layerCount; + imageCreateInfo.format = imageFormat; + imageCreateInfo.tiling = vk::ImageTiling::eOptimal; + imageCreateInfo.initialLayout = vk::ImageLayout::eUndefined; + imageCreateInfo.usage = usageFlags; + imageCreateInfo.sharingMode = vk::SharingMode::eExclusive; + imageCreateInfo.samples = vk::SampleCountFlagBits::e1; + imageCreateInfo.flags = createFlags; + + + // Prepare allocation parameters for call to create images later + VmaAllocationCreateInfo allocCreateInfo{}; + allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; + allocCreateInfo.flags = {}; // TODO: Make sure the vk::MemoryPropertyFlags returned from vmaGetAllocationMemoryProperties has the device local bit set + + VmaAllocationInfo allocInfo{}; + + VkImage tempImage; + auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo); + vkImage = tempImage; + + if (result != VK_SUCCESS) + SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. "); + else + SHVulkanDebugUtil::ReportVkSuccess("Successfully created image. "); + } + SHVkImage::SHVkImage( VmaAllocator const* allocator, SHImageCreateParams const& imageDetails, @@ -196,37 +231,7 @@ namespace SHADE , createFlags {create} , vmaAllocator {allocator} { - vk::ImageCreateInfo imageCreateInfo{}; - imageCreateInfo.imageType = vk::ImageType::e2D; - imageCreateInfo.extent.width = width; - imageCreateInfo.extent.height = height; - imageCreateInfo.extent.depth = depth; - imageCreateInfo.mipLevels = mipLevelCount; - imageCreateInfo.arrayLayers = layerCount; - imageCreateInfo.format = imageFormat; - imageCreateInfo.tiling = vk::ImageTiling::eOptimal; - imageCreateInfo.initialLayout = vk::ImageLayout::eUndefined; - imageCreateInfo.usage = usageFlags; - imageCreateInfo.sharingMode = vk::SharingMode::eExclusive; - imageCreateInfo.samples = vk::SampleCountFlagBits::e1; - imageCreateInfo.flags = createFlags; - - - // Prepare allocation parameters for call to create images later - VmaAllocationCreateInfo allocCreateInfo{}; - allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; - allocCreateInfo.flags = {}; // TODO: Make sure the vk::MemoryPropertyFlags returned from vmaGetAllocationMemoryProperties has the device local bit set - - VmaAllocationInfo allocInfo{}; - - VkImage tempImage; - auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo); - vkImage = tempImage; - - if (result != VK_SUCCESS) - SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. "); - else - SHVulkanDebugUtil::ReportVkSuccess("Successfully created image. "); + CreateFramebufferImage(); } Handle SHVkImage::CreateImageView(Handle const& inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) const noexcept @@ -288,6 +293,13 @@ namespace SHADE barrier.subresourceRange.layerCount = layerCount; } + void SHVkImage::HandleResizeFramebufferImage(void) noexcept + { + vmaDestroyImage(*vmaAllocator, vkImage, alloc); + + CreateFramebufferImage(); + } + void SHVkImage::LinkWithExteriorImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t layers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept { vkImage = inVkImage; diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.h b/SHADE_Engine/src/Graphics/Images/SHVkImage.h index 39e695a5..b23d7bd4 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImage.h +++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.h @@ -108,7 +108,7 @@ namespace SHADE /* PRIVATE MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ void PrepStagingBuffer(const void* data, uint32_t srcSize) noexcept; - + void CreateFramebufferImage (void) noexcept; public: /*-----------------------------------------------------------------------*/ @@ -137,7 +137,8 @@ namespace SHADE Handle CreateImageView (Handle const& inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) const noexcept; void TransferToDeviceResource (Handle cmdBufferHdl) noexcept; void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept; - + void HandleResizeFramebufferImage(void) noexcept; + /*-----------------------------------------------------------------------*/ /* GETTERS AND SETTERS */ /*-----------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImageView.cpp b/SHADE_Engine/src/Graphics/Images/SHVkImageView.cpp index 9d12d7cd..44b5718c 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImageView.cpp +++ b/SHADE_Engine/src/Graphics/Images/SHVkImageView.cpp @@ -6,6 +6,67 @@ namespace SHADE { + + void SHVkImageView::Create(void) noexcept + { + auto parentImageCreateFlags = parentImage->GetImageeCreateFlags(); + + // 2D array image type means parent image must be 2D array compatible + if (imageViewDetails.viewType == vk::ImageViewType::e2DArray) + { + if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::e2DArrayCompatible)) + { + SHLOG_ERROR("Failed to create image view. Parent image not 2D array compatible. "); + return; + } + } + + // Check if its possible for the image view to have different format than parent image + if (imageViewDetails.format != parentImage->GetImageFormat()) + { + if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::eMutableFormat)) + { + SHLOG_ERROR("Failed to create image view. Format for image view not same as image but image not initialized with mutable format bit. "); + return; + } + } + + + vk::ImageViewCreateInfo viewCreateInfo + { + .pNext = nullptr, // Can be used to override with a VkImageViewUsageCreateInfo to override usage. See Vulkan spec page 877 for more information + .image = parentImage->GetVkImage(), + .viewType = imageViewDetails.viewType, + .format = imageViewDetails.format, + .components + { + .r = vk::ComponentSwizzle::eR, + .g = vk::ComponentSwizzle::eG, + .b = vk::ComponentSwizzle::eB, + .a = vk::ComponentSwizzle::eA, + }, + .subresourceRange + { + .aspectMask = imageViewDetails.imageAspectFlags, + .baseMipLevel = imageViewDetails.baseMipLevel, + .levelCount = imageViewDetails.mipLevelCount, + .baseArrayLayer = imageViewDetails.baseArrayLayer, + .layerCount = imageViewDetails.layerCount, + }, + }; + + if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createImageView(&viewCreateInfo, nullptr, &vkImageView); result != vk::Result::eSuccess) + { + SHVulkanDebugUtil::ReportVkError(result, "Failed to create image view! "); + return; + } + else + { + SHVulkanDebugUtil::ReportVkSuccess("Successfully created image view. "); + } + + } + /***************************************************************************/ /*! @@ -18,70 +79,12 @@ namespace SHADE */ /***************************************************************************/ SHVkImageView::SHVkImageView(Handle const& inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) noexcept - : parentImage{ } + : parentImage{ parent } , vkImageView{} - , imageViewDetails{} + , imageViewDetails{createParams} , logicalDeviceHdl {inLogicalDeviceHdl} { - auto parentImageCreateFlags = parent->GetImageeCreateFlags(); - - // 2D array image type means parent image must be 2D array compatible - if (createParams.viewType == vk::ImageViewType::e2DArray) - { - if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::e2DArrayCompatible)) - { - SHLOG_ERROR("Failed to create image view. Parent image not 2D array compatible. "); - return; - } - } - - // Check if its possible for the image view to have different format than parent image - if (createParams.format != parent->GetImageFormat()) - { - if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::eMutableFormat)) - { - SHLOG_ERROR("Failed to create image view. Format for image view not same as image but image not initialized with mutable format bit. "); - return; - } - } - - - vk::ImageViewCreateInfo viewCreateInfo - { - .pNext = nullptr, // Can be used to override with a VkImageViewUsageCreateInfo to override usage. See Vulkan spec page 877 for more information - .image = parent->GetVkImage(), - .viewType = createParams.viewType, - .format = createParams.format, - .components - { - .r = vk::ComponentSwizzle::eR, - .g = vk::ComponentSwizzle::eG, - .b = vk::ComponentSwizzle::eB, - .a = vk::ComponentSwizzle::eA, - }, - .subresourceRange - { - .aspectMask = createParams.imageAspectFlags, - .baseMipLevel = createParams.baseMipLevel, - .levelCount = createParams.mipLevelCount, - .baseArrayLayer = createParams.baseArrayLayer, - .layerCount = createParams.layerCount, - }, - }; - - if (auto result = inLogicalDeviceHdl->GetVkLogicalDevice().createImageView(&viewCreateInfo, nullptr, &vkImageView); result != vk::Result::eSuccess) - { - SHVulkanDebugUtil::ReportVkError(result, "Failed to create image view! "); - return; - } - else - { - SHVulkanDebugUtil::ReportVkSuccess("Successfully created image view. "); - } - - // After success, THEN assign variables - parentImage = parent; - imageViewDetails = createParams; + Create(); } SHVkImageView::SHVkImageView(SHVkImageView&& rhs) noexcept @@ -94,6 +97,17 @@ namespace SHADE } + void SHVkImageView::ViewNewImage(Handle const& parent, SHImageViewDetails const& createParams) noexcept + { + imageViewDetails = createParams; + parentImage = parent; + + if (vkImageView) + logicalDeviceHdl->GetVkLogicalDevice().destroyImageView(vkImageView, nullptr); + + Create(); + } + Handle const& SHVkImageView::GetParentImage(void) const noexcept { return parentImage; diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImageView.h b/SHADE_Engine/src/Graphics/Images/SHVkImageView.h index afa357ef..ae23d7a7 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImageView.h +++ b/SHADE_Engine/src/Graphics/Images/SHVkImageView.h @@ -25,12 +25,17 @@ namespace SHADE //! Logical Device needed for creation and destruction Handle logicalDeviceHdl; + //! Create new image view + void Create (void) noexcept; + public: SHVkImageView(Handle const& inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) noexcept; ~SHVkImageView(void) noexcept; SHVkImageView(SHVkImageView&& rhs) noexcept; SHVkImageView& operator=(SHVkImageView&& rhs) noexcept; + void ViewNewImage (Handle const& parent, SHImageViewDetails const& createParams) noexcept; + /*-----------------------------------------------------------------------*/ /* GETTERS AND SETTERS */ /*-----------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 40e24979..e4207c20 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -341,10 +341,7 @@ namespace SHADE { device->WaitIdle(); - // Resize the swapchain - swapchain->Resize(surface, windowDims.first, windowDims.second); - - renderContext.HandleResize(); + HandleResize(); } const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame(); @@ -387,10 +384,8 @@ namespace SHADE // If swapchain is incompatible/outdated if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR) { - auto windowDims = window->GetWindowSize(); - swapchain->Resize(surface, windowDims.first, windowDims.second); - renderContext.HandleResize(); + HandleResize(); } } @@ -509,6 +504,16 @@ namespace SHADE ); } + void SHGraphicsSystem::HandleResize(void) noexcept + { + auto windowDims = window->GetWindowSize(); + + // Resize the swapchain + swapchain->Resize(surface, windowDims.first, windowDims.second); + + renderContext.HandleResize(); + } + void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept { window = wind; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 84dc39cd..10df44a5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -246,6 +246,8 @@ namespace SHADE /***************************************************************************/ void BuildTextures(); + void HandleResize(void) noexcept; + /*-----------------------------------------------------------------------------*/ /* Setters */ /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 828a83f1..27a1d604 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -480,6 +480,15 @@ namespace SHADE } } + void SHRenderGraph::HandleResize(void) noexcept + { + // resize resources + for (auto& [name, resource]: graphResources) + resource->HandleResize(); + + + } + Handle SHRenderGraph::GetNode(std::string const& nodeName) const noexcept { if (nodeIndexing.contains(nodeName)) diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 8b5b2212..83aeeb2c 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -80,6 +80,7 @@ namespace SHADE void Generate (void) noexcept; void Execute (uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept; void FinaliseBatch(uint32_t frameIndex, Handle descPool); + void HandleResize (void) noexcept; /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index eb873b16..72dd557f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -2,9 +2,11 @@ #include "SHRenderGraphResource.h" #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Swapchain/SHVkSwapchain.h" +#include "Graphics/Images/SHVkImageView.h" namespace SHADE { + /***************************************************************************/ /*! @@ -42,7 +44,9 @@ namespace SHADE */ /***************************************************************************/ SHRenderGraphResource::SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageCreateFlagBits createFlags) noexcept - : resourceType{ type } + : logicalDevice {logicalDevice} + , swapchain{ swapchain } + , resourceType{ type } , resourceFormat{ format } , images{} , imageViews{} @@ -52,10 +56,10 @@ namespace SHADE , resourceName{ name } { // If the resource type is an arbitrary image and not swapchain image - if (type != SH_ATT_DESC_TYPE::COLOR_PRESENT) + if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT) { - vk::ImageAspectFlags imageAspectFlags; - vk::ImageUsageFlags usage = {}; + imageAspectFlags = vk::ImageAspectFlags{}; + usage = {}; // Check the resource type and set image usage flags and image aspect flags accordingly switch (resourceType) @@ -189,4 +193,48 @@ namespace SHADE } + void SHRenderGraphResource::HandleResize(void) noexcept + { + if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT) + { + // prepare image view details + SHImageViewDetails viewDetails + { + .viewType = vk::ImageViewType::e2D, + .format = images[0]->GetImageFormat(), + .imageAspectFlags = imageAspectFlags, + .baseMipLevel = 0, + .mipLevelCount = mipLevels, + .baseArrayLayer = 0, + .layerCount = 1, + }; + + for (uint32_t i = 0; i < images.size(); ++i) + { + images[i]->HandleResizeFramebufferImage(); + imageViews[i]->ViewNewImage(images[i], viewDetails); + } + } + else + { + // Prepare image view details + SHImageViewDetails viewDetails + { + .viewType = vk::ImageViewType::e2D, + .format = swapchain->GetSurfaceFormatKHR().format, + .imageAspectFlags = vk::ImageAspectFlagBits::eColor, + .baseMipLevel = 0, + .mipLevelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1, + }; + + for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i) + { + images[i] = swapchain->GetSwapchainImage(i); + imageViews[i]->ViewNewImage(images[i], viewDetails); + } + } + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h index fcb16601..741acdc0 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h @@ -20,6 +20,12 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ + // for creation/recreation + Handle logicalDevice; + + // for creation/recreation + Handle swapchain; + //! Name of the resource std::string resourceName; @@ -47,6 +53,14 @@ namespace SHADE //! Number of mipmap levels uint8_t mipLevels; + + //! image aspect flags + vk::ImageAspectFlags imageAspectFlags; + + //! usage flags + vk::ImageUsageFlags usage = {}; + + public: /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ @@ -56,6 +70,8 @@ namespace SHADE SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept; ~SHRenderGraphResource(void) noexcept; + void HandleResize (void) noexcept; + friend class SHRenderGraphNode; friend class SHRenderGraph; }; From 374f1a961dc3a2e6ad4ef28be6aa7581a74439b6 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sat, 1 Oct 2022 16:50:50 +0800 Subject: [PATCH 07/61] Integrated rigidbodies into physics system --- SHADE_Application/src/Scenes/SBTestScene.cpp | 122 ++++++++------- .../Components/SHRigidBodyComponent.cpp | 3 + SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 38 ++++- SHADE_Engine/src/Physics/SHPhysicsObject.h | 12 +- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 148 +++++++++--------- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 5 +- 6 files changed, 180 insertions(+), 148 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 556ff3ac..ce52be95 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -10,6 +10,7 @@ #include "Scripting/SHScriptEngine.h" #include "Math/Transform/SHTransformComponent.h" #include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" +#include "Physics/Components/SHRigidBodyComponent.h" #include "Assets/SHAssetManager.h" @@ -75,83 +76,86 @@ namespace Sandbox customMat->SetProperty("data.alpha", 0.1f); // Create Stress Test Objects - static const SHVec3 TEST_OBJ_SCALE = { 0.05f, 0.05f, 0.05f }; - constexpr int NUM_ROWS = 100; - constexpr int NUM_COLS = 100; - static const SHVec3 TEST_OBJ_SPACING = { 0.05f, 0.05f, 0.05f }; - static const SHVec3 TEST_OBJ_START_POS = { -(NUM_COLS / 2 * TEST_OBJ_SPACING.x) + 1.0f, -2.0f, -1.0f }; + //static const SHVec3 TEST_OBJ_SCALE = { 0.05f, 0.05f, 0.05f }; + //constexpr int NUM_ROWS = 100; + //constexpr int NUM_COLS = 100; + //static const SHVec3 TEST_OBJ_SPACING = { 0.05f, 0.05f, 0.05f }; + //static const SHVec3 TEST_OBJ_START_POS = { -(NUM_COLS / 2 * TEST_OBJ_SPACING.x) + 1.0f, -2.0f, -1.0f }; - for (int y = 0; y < NUM_ROWS; ++y) - for (int x = 0; x < NUM_COLS; ++x) - { - auto entity = SHEntityManager::CreateEntity(); - auto& renderable = *SHComponentManager::GetComponent_s(entity); - auto& transform = *SHComponentManager::GetComponent_s(entity); + //for (int y = 0; y < NUM_ROWS; ++y) + // for (int x = 0; x < NUM_COLS; ++x) + // { + // auto entity = SHEntityManager::CreateEntity(); + // auto& renderable = *SHComponentManager::GetComponent_s(entity); + // auto& transform = *SHComponentManager::GetComponent_s(entity); - renderable.Mesh = handles.front(); - renderable.SetMaterial(customMat); + // //renderable.Mesh = handles.front(); + // renderable.Mesh = CUBE_MESH; + // renderable.SetMaterial(customMat); - if (y == 50) - renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 0.0f, 0.0f, 1.0f)); + // if (y == 50) + // renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 0.0f, 0.0f, 1.0f)); - //Set initial positions - transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ - x * TEST_OBJ_SPACING.x, - y * TEST_OBJ_SPACING.y, - 0.0f - }); - //transform.SetWorldPosition({-1.0f, -1.0f, -1.0f}); - //transform.SetWorldRotation(3.14159265f * 1.5f, -3.14159265f / 2.0f, 0.0f); - transform.SetLocalScale(TEST_OBJ_SCALE); + // //Set initial positions + // transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ + // x * TEST_OBJ_SPACING.x, + // y * TEST_OBJ_SPACING.y, + // 0.0f + // }); + // //transform.SetWorldPosition({-1.0f, -1.0f, -1.0f}); + // //transform.SetWorldRotation(3.14159265f * 1.5f, -3.14159265f / 2.0f, 0.0f); + // transform.SetLocalScale(TEST_OBJ_SCALE); - stressTestObjects.emplace_back(entity); - } + // stressTestObjects.emplace_back(entity); + // } - auto raccoonSpin = SHEntityManager::CreateEntity(); - auto& renderable = *SHComponentManager::GetComponent_s(raccoonSpin); - auto& transform = *SHComponentManager::GetComponent_s(raccoonSpin); + //auto raccoonSpin = SHEntityManager::CreateEntity(); + //auto& renderable = *SHComponentManager::GetComponent_s(raccoonSpin); + //auto& transform = *SHComponentManager::GetComponent_s(raccoonSpin); - renderable.Mesh = handles.front(); - renderable.SetMaterial(customMat); - renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); - renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); - renderable.GetModifiableMaterial()->SetProperty("data.textureIndex", 1); - - transform.SetWorldPosition({ -3.0f, -1.0f, -1.0f }); - transform.SetLocalScale({ 5.0f, 5.0f, 5.0f }); - - //auto entity = SHEntityManager::CreateEntity(); - //auto& renderable = *SHComponentManager::GetComponent_s(entity); - //auto& transform = *SHComponentManager::GetComponent_s(entity); - - //renderable.Mesh = handles.back(); + //renderable.Mesh = handles.front(); //renderable.SetMaterial(customMat); + //renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); + //renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); + //renderable.GetModifiableMaterial()->SetProperty("data.textureIndex", 1); - //transform.SetLocalScale(TEST_OBJ_SCALE); - //transform.SetWorldPosition({-1.0f, -1.0f, -1.0f}); + //transform.SetWorldPosition({ -3.0f, -1.0f, -1.0f }); + //transform.SetLocalScale({ 5.0f, 5.0f, 5.0f }); + + auto entity = SHEntityManager::CreateEntity(); + auto& renderable = *SHComponentManager::GetComponent_s(entity); + auto& transform = *SHComponentManager::GetComponent_s(entity); + auto& rb = *SHComponentManager::GetComponent_s(entity); + + renderable.Mesh = CUBE_MESH; + renderable.SetMaterial(customMat); + + transform.SetLocalScale(SHVec3::One * 0.25f); + transform.SetWorldPosition({0.0f, 2.0f, -1.0f}); // Create blank entity with a script //testObj = SHADE::SHEntityManager::CreateEntity(); - //auto& testObjRenderable = *SHComponentManager::GetComponent_s(testObj); + //auto& testObjRenderable = *SHComponentManager::GetComponent(testObj); //testObjRenderable.Mesh = CUBE_MESH; //testObjRenderable.SetMaterial(matInst); - SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); - scriptEngine->AddScript(raccoonSpin, "RaccoonSpin"); - auto raccoonShowcase = SHEntityManager::CreateEntity(); - auto& renderableShowcase = *SHComponentManager::GetComponent_s(raccoonShowcase); - auto& transformShowcase = *SHComponentManager::GetComponent_s(raccoonShowcase); + //SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); + //scriptEngine->AddScript(raccoonSpin, "RaccoonSpin"); - renderableShowcase.Mesh = handles.front(); - renderableShowcase.SetMaterial(customMat); - renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); - renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); - renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 1); + //auto raccoonShowcase = SHEntityManager::CreateEntity(); + //auto& renderableShowcase = *SHComponentManager::GetComponent_s(raccoonShowcase); + //auto& transformShowcase = *SHComponentManager::GetComponent_s(raccoonShowcase); - transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f }); - transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f }); - scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase"); + //renderableShowcase.Mesh = handles.front(); + //renderableShowcase.SetMaterial(customMat); + //renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); + //renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); + //renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 1); + + //transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f }); + //transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f }); + //scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase"); } void SBTestScene::Update(float dt) diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp index 04cb00dd..e2cd1e4b 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp @@ -37,6 +37,9 @@ namespace SHADE // Set default flags: Gravity & Sleeping enabled flags |= 1U << 0; flags |= 1U << 1; + + // Set all dirty flags to true + dirtyFlags = 1023; } /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index 325d860f..f489624d 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -79,14 +79,40 @@ namespace SHADE } /*-----------------------------------------------------------------------------------*/ - /* Public Function Member Definitions */ + /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ + void SHPhysicsObject::SetPosition(const SHVec3& position) const noexcept + { + const rp3d::Vector3 RP3D_POS { position.x, position.y, position.z }; - /*-----------------------------------------------------------------------------------*/ - /* Private Function Member Definitions */ - /*-----------------------------------------------------------------------------------*/ + rp3d::Transform rp3dTF; + rp3dTF.setPosition(RP3D_POS); + rp3dTF.setOrientation(rp3dBody->getTransform().getOrientation()); + + rp3dBody->setTransform(rp3dTF); + } + + void SHPhysicsObject::SetOrientation(const SHQuaternion& orientation) const noexcept + { + const rp3d::Quaternion RP3D_ORIENTATION { orientation.x, orientation.y, orientation.z, orientation.w }; + + rp3d::Transform rp3dTF; + rp3dTF.setPosition(rp3dBody->getTransform().getPosition()); + rp3dTF.setOrientation(RP3D_ORIENTATION); + + rp3dBody->setTransform(rp3dTF); + } + + void SHPhysicsObject::SetRotation(const SHVec3& rotation) const noexcept + { + const rp3d::Quaternion RP3D_ORIENTATION = rp3d::Quaternion::fromEulerAngles( rotation.x, rotation.y, rotation.z ); + + rp3d::Transform rp3dTF; + rp3dTF.setPosition(rp3dBody->getTransform().getPosition()); + rp3dTF.setOrientation(RP3D_ORIENTATION); + + rp3dBody->setTransform(rp3dTF); + } - - } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.h b/SHADE_Engine/src/Physics/SHPhysicsObject.h index e0f0f38f..cd9be57b 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.h @@ -55,14 +55,18 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] virtual SHVec3 GetPosition () const noexcept; - [[nodiscard]] virtual SHQuaternion GetOrientation () const noexcept; - [[nodiscard]] virtual SHVec3 GetRotation () const noexcept; + [[nodiscard]] SHVec3 GetPosition () const noexcept; + [[nodiscard]] SHQuaternion GetOrientation () const noexcept; + [[nodiscard]] SHVec3 GetRotation () const noexcept; /*---------------------------------------------------------------------------------*/ - /* Function Members */ + /* Setter Functions */ /*---------------------------------------------------------------------------------*/ + void SetPosition (const SHVec3& position) const noexcept; + void SetOrientation (const SHQuaternion& orientation) const noexcept; + void SetRotation (const SHVec3& rotation) const noexcept; + private: /*---------------------------------------------------------------------------------*/ /* Data Members */ diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 9be8a5ef..59d915f9 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -27,7 +27,7 @@ namespace SHADE SHPhysicsSystem::SHPhysicsSystem() : interpolationFactor { 0.0 } - , fixedDT { 1.0 / 60.0 } + , fixedDT { 60.0 } , world { nullptr } {} @@ -204,7 +204,11 @@ namespace SHADE // Check if entity is already a physics object auto* physicsObject = GetPhysicsObject(entityID); if (!physicsObject) + { physicsObject = &(map.emplace(entityID, SHPhysicsObject{}).first->second); + physicsObject->entityID = entityID; + } + // Get entity transform auto const* SHADE_TF = SHComponentManager::GetComponent_s(entityID); @@ -292,9 +296,23 @@ namespace SHADE { auto* system = reinterpret_cast(GetSystem()); + // Get dense arrays + auto& rbDense = SHComponentManager::GetDense(); + auto& cDense = SHComponentManager::GetDense(); + // Update bodies and colliders if component is dirty - const auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); - system->SyncComponents(sceneGraph); + system->SyncRigidBodyComponents(rbDense); + + // Sync transforms + for (auto& physicsObject : system->map | std::views::values) + { + const auto* TF = SHComponentManager::GetComponent(physicsObject.entityID); + if (TF->HasChanged()) + { + physicsObject.SetPosition(TF->GetWorldPosition()); + physicsObject.SetRotation(TF->GetWorldRotation()); + } + } } void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept @@ -322,8 +340,7 @@ namespace SHADE auto* system = reinterpret_cast(GetSystem()); // Interpolate transforms for rendering - const auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); - system->SyncTransforms(sceneGraph); + system->SyncTransforms(); // TODO(Diren): Handle trigger messages for scripting } @@ -344,89 +361,67 @@ namespace SHADE return &(it->second); } - void SHPhysicsSystem::SyncComponents(const SHSceneGraph& sceneGraph) noexcept + void SHPhysicsSystem::SyncRigidBodyComponents(std::vector& denseArray) noexcept { - static const auto SYNC_COMPONENTS = [&](SHSceneNode* node) + if (denseArray.empty()) + return; + + for (auto& comp : denseArray) { - const EntityID ENTITY_ID = node->GetEntityID(); + const EntityID ENTITY_ID = comp.GetEID(); - // Get physics object + // Get physicsObject auto const* physicsObject = GetPhysicsObject(ENTITY_ID); - if (!physicsObject) - return; - const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive(); - const bool NODE_ACTIVE = node->IsActive(); + const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive(); + // TODO(Diren): Check if active in hierarchy + const bool COMPONENT_ACTIVE = comp.isActive; - // Sync rigid body - if (physicsObject->isRigidBody) + if (RP3D_ACTIVE != COMPONENT_ACTIVE) + physicsObject->rp3dBody->setIsActive(COMPONENT_ACTIVE); + + if (!COMPONENT_ACTIVE) + continue; + + if (comp.dirtyFlags > 0) { - auto* rbComponent = SHComponentManager::GetComponent_s(ENTITY_ID); - if (rbComponent->dirtyFlags > 0) - { - SyncRB(physicsObject, rbComponent); - rbComponent->dirtyFlags = 0; - } - - - // Sync active states - const bool SHADE_ACTIVE = NODE_ACTIVE && rbComponent->isActive; - if (SHADE_ACTIVE != RP3D_ACTIVE) - physicsObject->rp3dBody->setIsActive(SHADE_ACTIVE); + SyncRB(physicsObject, &comp); + comp.dirtyFlags = 0; } - - // Sync colliders - if (physicsObject->hasColliders) - { - auto const* colliderComponent = SHComponentManager::GetComponent_s(ENTITY_ID); - - } - - // Sync transforms - auto const* tfComponent = SHComponentManager::GetComponent(ENTITY_ID); - if (tfComponent->HasChanged()) - { - const SHVec3& SHADE_POS = tfComponent->GetWorldPosition(); - const SHVec3& SHADE_ROT = tfComponent->GetWorldRotation(); - - const rp3d::Vector3 RP3D_POS { SHADE_POS.x, SHADE_POS.y, SHADE_POS.z }; - const rp3d::Quaternion RP3D_ROT = rp3d::Quaternion::fromEulerAngles(SHADE_ROT.x, SHADE_ROT.y, SHADE_ROT.z); - - physicsObject->rp3dBody->setTransform(rp3d::Transform{ RP3D_POS, RP3D_ROT }); - } - }; - - sceneGraph.Traverse(SYNC_COMPONENTS); + } } - void SHPhysicsSystem::SyncTransforms(const SHSceneGraph& sceneGraph) noexcept + void SHPhysicsSystem::SyncTransforms() noexcept { - static const auto SYNC_TRANSFORMS = [&](SHSceneNode* node) + for (auto& pair : map) { - const EntityID ENTITY_ID = node->GetEntityID(); - - // Get physics object - auto* physicsObject = GetPhysicsObject(ENTITY_ID); - if (!physicsObject) - return; - - auto* tfComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + const EntityID ENTITY_ID = pair.first; + SHPhysicsObject& physicsObject = pair.second; rp3d::Vector3 rp3dPos; rp3d::Quaternion rp3dRot; - const rp3d::Transform CURRENT_TF = physicsObject->rp3dBody->getTransform(); + const rp3d::Transform CURRENT_TF = physicsObject.rp3dBody->getTransform(); // Check if transform should be interpolated - auto const* rbComponent = SHComponentManager::GetComponent_s(ENTITY_ID); - if (rbComponent && rbComponent->IsInterpolating()) + + if (physicsObject.isRigidBody) { - const rp3d::Transform PREV_TF = physicsObject->prevTransform; - const rp3d::Transform INTERPOLATED_TF = rp3d::Transform::interpolateTransforms(PREV_TF, CURRENT_TF, static_cast(interpolationFactor)); + auto const* rbComponent = SHComponentManager::GetComponent(ENTITY_ID); + if (rbComponent->IsInterpolating()) + { + const rp3d::Transform PREV_TF = physicsObject.prevTransform; + const rp3d::Transform INTERPOLATED_TF = rp3d::Transform::interpolateTransforms(PREV_TF, CURRENT_TF, static_cast(interpolationFactor)); - rp3dPos = INTERPOLATED_TF.getPosition(); - rp3dRot = INTERPOLATED_TF.getOrientation(); + rp3dPos = INTERPOLATED_TF.getPosition(); + rp3dRot = INTERPOLATED_TF.getOrientation(); + } + else + { + rp3dPos = CURRENT_TF.getPosition(); + rp3dRot = CURRENT_TF.getOrientation(); + } } else { @@ -438,14 +433,13 @@ namespace SHADE const SHVec3 SHADE_POS = SHVec3{ rp3dPos.x, rp3dPos.y, rp3dPos.z }; const SHVec3 SHADE_ROT = SHQuaternion{ rp3dRot.x, rp3dRot.y, rp3dRot.z, rp3dRot.w }.ToEuler(); + auto* tfComponent = SHComponentManager::GetComponent(ENTITY_ID); tfComponent->SetWorldPosition(SHADE_POS); tfComponent->SetWorldRotation(SHADE_ROT); // Cache transforms - physicsObject->prevTransform = CURRENT_TF; - }; - - sceneGraph.Traverse(SYNC_TRANSFORMS); + physicsObject.prevTransform = CURRENT_TF; + } } void SHPhysicsSystem::SyncRB(SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept @@ -527,9 +521,9 @@ namespace SHADE { const rp3d::Vector3 CONSTRAINTS { - rbFlags & 1U << 2 ? 1.0f : 0.0f, - rbFlags & 1U << 3 ? 1.0f : 0.0f, - rbFlags & 1U << 4 ? 1.0f : 0.0f + rbFlags & 1U << 2 ? 0.0f : 1.0f, + rbFlags & 1U << 3 ? 0.0f : 1.0f, + rbFlags & 1U << 4 ? 0.0f : 1.0f }; @@ -540,9 +534,9 @@ namespace SHADE { const rp3d::Vector3 CONSTRAINTS { - rbFlags & 1U << 5 ? 1.0f : 0.0f, - rbFlags & 1U << 6 ? 1.0f : 0.0f, - rbFlags & 1U << 7 ? 1.0f : 0.0f + rbFlags & 1U << 5 ? 0.0f : 1.0f, + rbFlags & 1U << 6 ? 0.0f : 1.0f, + rbFlags & 1U << 7 ? 0.0f : 1.0f }; rp3dRigidBody->setAngularLockAxisFactor(CONSTRAINTS); diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index af615f35..dbf0a597 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -183,8 +183,9 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; - void SyncComponents (const SHSceneGraph& sceneGraph) noexcept; - void SyncTransforms (const SHSceneGraph& sceneGraph) noexcept; + void SyncRigidBodyComponents (std::vector& denseArray) noexcept; + void SyncColliderComponents (std::vector& denseArray) noexcept; + void SyncTransforms () noexcept; // TODO(Diren): Trigger handling static void SyncRB (SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept; From b3d15b6a39ef9c9b97da4790d81d3a20049cf50d Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sat, 1 Oct 2022 20:34:23 +0800 Subject: [PATCH 08/61] Added WIP UndoRedoStack --- SHADE_Managed/src/Editor/Editor.cxx | 2 +- SHADE_Managed/src/Editor/UndoRedoStack .cxx | 49 +++++++++++++++++++++ SHADE_Managed/src/Editor/UndoRedoStack.hxx | 48 ++++++++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 SHADE_Managed/src/Editor/UndoRedoStack .cxx create mode 100644 SHADE_Managed/src/Editor/UndoRedoStack.hxx diff --git a/SHADE_Managed/src/Editor/Editor.cxx b/SHADE_Managed/src/Editor/Editor.cxx index 629c9e65..73d52d14 100644 --- a/SHADE_Managed/src/Editor/Editor.cxx +++ b/SHADE_Managed/src/Editor/Editor.cxx @@ -3,7 +3,7 @@ \author Tng Kah Wei, kahwei.tng, 390009620 \par email: kahwei.tng\@digipen.edu \date Sep 27, 2022 -\brief Contains the definition of the functions for the ScriptStore managed +\brief Contains the definition of the functions for the Editor managed static class. Note: This file is written in C++17/CLI. diff --git a/SHADE_Managed/src/Editor/UndoRedoStack .cxx b/SHADE_Managed/src/Editor/UndoRedoStack .cxx new file mode 100644 index 00000000..e3fdc2f0 --- /dev/null +++ b/SHADE_Managed/src/Editor/UndoRedoStack .cxx @@ -0,0 +1,49 @@ +/************************************************************************************//*! +\file UndoRedoStack.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 29, 2022 +\brief Contains the definition of the functions for the UndoRedoStack managed + class. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "UndoRedoStack.hxx" +// External Dependencies +#include "Editor/SHEditorUI.h" +// Project Headers + +namespace SHADE +{ + void UndoRedoStack::Add(Command command) + { + // Erase any other actions ahead of the current action + if (latestActionIndex < commandStack->Count - 1) + { + commandStack->RemoveRange(latestActionIndex + 1, commandStack->Count - latestActionIndex); + } + + // Add the command + commandStack->Add(command); + + // Increment latest command + ++latestActionIndex; + } + + void UndoRedoStack::Undo() + { + + } + + void UndoRedoStack::Redo() + { + + } +} diff --git a/SHADE_Managed/src/Editor/UndoRedoStack.hxx b/SHADE_Managed/src/Editor/UndoRedoStack.hxx new file mode 100644 index 00000000..2db3cacb --- /dev/null +++ b/SHADE_Managed/src/Editor/UndoRedoStack.hxx @@ -0,0 +1,48 @@ +/************************************************************************************//*! +\file UndoRedoStack.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 29, 2022 +\brief Contains the definition of the managed UndoRedoStack class. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +namespace SHADE +{ + /// + /// Class that is able to store a stack of actions that can be done and redone. + /// + private ref class UndoRedoStack sealed + { + public: + /*-----------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------*/ + value struct Command + { + public: + System::Action^ UndoAction; + System::Action^ RedoAction; + }; + + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + void Add(Command command); + void Undo(); + void Redo(); + + private: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + int latestActionIndex = -1; + System::Collections::Generic::List^ commandStack = gcnew System::Collections::Generic::List(); + }; +} From c5efefcf4f3f4140f4226eebbdd01f6b9f830c7e Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Sat, 1 Oct 2022 21:18:54 +0800 Subject: [PATCH 09/61] Editor warning fixes --- .../src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp | 2 +- SHADE_Engine/src/Editor/IconsMaterialDesign.h | 2 +- SHADE_Engine/src/Editor/SHEditorWidgets.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp index f787d4db..25cd5a6a 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp @@ -114,7 +114,7 @@ namespace SHADE auto* entity = SHEntityManager::GetEntityByID(currentNode->GetEntityID()); //Draw Node - bool isNodeOpen = ImGui::TreeNodeEx((void*)eid, nodeFlags, "%u: %s", EntityHandleGenerator::GetIndex(eid), entity->name.c_str()); + bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast(entity), nodeFlags, "%u: %s", EntityHandleGenerator::GetIndex(eid), entity->name.c_str()); const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); //Check For Begin Drag diff --git a/SHADE_Engine/src/Editor/IconsMaterialDesign.h b/SHADE_Engine/src/Editor/IconsMaterialDesign.h index 68373237..3f15892b 100644 --- a/SHADE_Engine/src/Editor/IconsMaterialDesign.h +++ b/SHADE_Engine/src/Editor/IconsMaterialDesign.h @@ -843,7 +843,7 @@ #define ICON_MD_FLIP_TO_FRONT "\xee\xa2\x83" // U+e883 #define ICON_MD_FLOOD "\xee\xaf\xa6" // U+ebe6 #define ICON_MD_FLOURESCENT "\xee\xb0\xb1" // U+ec31 -#define ICON_MD_FLOURESCENT "\xef\x80\x8d" // U+f00d +#define ICON_MD_FLOURESCENT2 "\xef\x80\x8d" // U+f00d #define ICON_MD_FLUORESCENT "\xee\xb0\xb1" // U+ec31 #define ICON_MD_FLUTTER_DASH "\xee\x80\x8b" // U+e00b #define ICON_MD_FMD_BAD "\xef\x80\x8e" // U+f00e diff --git a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp index 88cea814..8d2adcc6 100644 --- a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp +++ b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp @@ -327,7 +327,7 @@ namespace SHADE ImGui::PushID(fieldLabel.c_str()); ImGui::Text(fieldLabel.c_str()); ImGui::SameLine(); - if (edited = ImGui::Combo("##Combo", &selected, list.data(), list.size())) + if (edited = ImGui::Combo("##Combo", &selected, list.data(), static_cast(list.size()))) { SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), selected, set)), false); } From 1a725c24e26d0feb7a3d7cb726ab93cd61755291 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sat, 1 Oct 2022 21:25:22 +0800 Subject: [PATCH 10/61] Stored renderpass attachement information in SHVkRenderpass --- .../RenderGraph/SHRenderGraphNode.cpp | 5 ++ .../Graphics/RenderGraph/SHRenderGraphNode.h | 1 + .../Graphics/Renderpass/SHVkRenderpass.cpp | 57 ++++++++++++------- .../src/Graphics/Renderpass/SHVkRenderpass.h | 8 ++- 4 files changed, 50 insertions(+), 21 deletions(-) diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index b981225a..551e90fc 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -56,6 +56,11 @@ namespace SHADE } } + void SHRenderGraphNode::HandleResize(void) noexcept + { + + } + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 59b20271..c713f402 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -81,6 +81,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ void CreateRenderpass(void) noexcept; void CreateFramebuffer(void) noexcept; + void HandleResize (void) noexcept; public: /*-----------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp index 29de5954..349c507e 100644 --- a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp +++ b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp @@ -30,7 +30,10 @@ namespace SHADE SHVkRenderpass::SHVkRenderpass(Handle const& inLogicalDeviceHdl, std::span const vkDescriptions, std::vector const& subpasses) noexcept : logicalDeviceHdl {inLogicalDeviceHdl} , numAttDescs {static_cast(vkDescriptions.size())} + , vkSubpassDescriptions{} + , vkSubpassDeps{} , clearColors{} + , vkAttachmentDescriptions{} { for (uint32_t i = 0; i < vkDescriptions.size(); ++i) { @@ -42,7 +45,6 @@ namespace SHADE vk::RenderPassCreateInfo renderPassCreateInfo{}; - std::vector subpassDeps; // For validating the depth ref auto isValidDepthRef = [&](vk::AttachmentReference const& depthRef) -> bool @@ -50,13 +52,16 @@ namespace SHADE return !(depthRef.attachment == static_cast (-1) && depthRef.layout == vk::ImageLayout::eUndefined); }; + for (uint32_t i = 0; i < vkDescriptions.size(); ++i) + vkAttachmentDescriptions[i] = vkDescriptions[i]; + uint32_t subpassIndex = 0; if (!subpasses.empty()) { for (auto& subpass : subpasses) { - subpassDescriptions.emplace_back(); - auto& spDesc = subpassDescriptions.back(); + vkSubpassDescriptions.emplace_back(); + auto& spDesc = vkSubpassDescriptions.back(); spDesc.pColorAttachments = subpass.colorRefs.data(); spDesc.colorAttachmentCount = static_cast(subpass.colorRefs.size()); @@ -88,18 +93,18 @@ namespace SHADE }; // Push a new dependency - subpassDeps.push_back(dependency); + vkSubpassDeps.push_back(dependency); ++subpassIndex; } // Renderpass create info for render pass creation - renderPassCreateInfo.attachmentCount = static_cast(vkDescriptions.size()); - renderPassCreateInfo.pAttachments = vkDescriptions.data(); - renderPassCreateInfo.subpassCount = static_cast(subpassDescriptions.size()); - renderPassCreateInfo.pSubpasses = subpassDescriptions.data(); - renderPassCreateInfo.dependencyCount = static_cast(subpassDeps.size()); - renderPassCreateInfo.pDependencies = subpassDeps.data(); + renderPassCreateInfo.attachmentCount = static_cast(vkAttachmentDescriptions.size()); + renderPassCreateInfo.pAttachments = vkAttachmentDescriptions.data(); + renderPassCreateInfo.subpassCount = static_cast(vkSubpassDescriptions.size()); + renderPassCreateInfo.pSubpasses = vkSubpassDescriptions.data(); + renderPassCreateInfo.dependencyCount = static_cast(vkSubpassDeps.size()); + renderPassCreateInfo.pDependencies = vkSubpassDeps.data(); } // No subpasses passed in, create a default one. @@ -172,6 +177,8 @@ namespace SHADE : logicalDeviceHdl{ inLogicalDeviceHdl } , numAttDescs{ static_cast(vkDescriptions.size()) } , clearColors{} + , vkSubpassDescriptions{ } + , vkSubpassDeps{ } { for (uint32_t i = 0; i < vkDescriptions.size(); ++i) { @@ -181,18 +188,24 @@ namespace SHADE clearColors[i].color = { {{0.0f, 0.0f, 0.0f, 1.0f}} }; } - subpassDescriptions.resize (spDescs.size()); - for (uint32_t i = 0; i < subpassDescriptions.size(); ++i) - { - subpassDescriptions[i] = spDescs[i]; - } + vkAttachmentDescriptions.resize(vkDescriptions.size()); + for (uint32_t i = 0; i < vkDescriptions.size(); ++i) + vkAttachmentDescriptions[i] = vkDescriptions[i]; + + vkSubpassDescriptions.resize (spDescs.size()); + for (uint32_t i = 0; i < vkSubpassDescriptions.size(); ++i) + vkSubpassDescriptions[i] = spDescs[i]; + + vkSubpassDeps.resize(spDeps.size()); + for (uint32_t i = 0; i < vkSubpassDeps.size(); ++i) + vkSubpassDeps[i] = spDeps[i]; vk::RenderPassCreateInfo renderPassCreateInfo{}; renderPassCreateInfo.attachmentCount = static_cast(vkDescriptions.size()); renderPassCreateInfo.pAttachments = vkDescriptions.data(); - renderPassCreateInfo.subpassCount = static_cast(subpassDescriptions.size()); - renderPassCreateInfo.pSubpasses = subpassDescriptions.data(); + renderPassCreateInfo.subpassCount = static_cast(vkSubpassDescriptions.size()); + renderPassCreateInfo.pSubpasses = vkSubpassDescriptions.data(); renderPassCreateInfo.dependencyCount = static_cast(spDeps.size()); renderPassCreateInfo.pDependencies = spDeps.data(); @@ -210,8 +223,10 @@ namespace SHADE SHVkRenderpass::SHVkRenderpass(SHVkRenderpass&& rhs) noexcept : vkRenderpass {rhs.vkRenderpass} , logicalDeviceHdl {rhs.logicalDeviceHdl} - , subpassDescriptions {std::move (rhs.subpassDescriptions)} - , clearColors {std::move (rhs.clearColors)} + , vkSubpassDescriptions{ std::move(rhs.vkSubpassDescriptions) } + , vkSubpassDeps{ std::move(rhs.vkSubpassDeps) } + , clearColors{ std::move(rhs.clearColors) } + , vkAttachmentDescriptions{ std::move(rhs.vkAttachmentDescriptions) } { rhs.vkRenderpass = VK_NULL_HANDLE; } @@ -224,8 +239,10 @@ namespace SHADE vkRenderpass = rhs.vkRenderpass; logicalDeviceHdl = rhs.logicalDeviceHdl; - subpassDescriptions = std::move(rhs.subpassDescriptions); + vkSubpassDescriptions = std::move(rhs.vkSubpassDescriptions); + vkSubpassDeps = std::move(rhs.vkSubpassDeps); clearColors = std::move(rhs.clearColors); + vkAttachmentDescriptions = std::move(rhs.vkAttachmentDescriptions); rhs.vkRenderpass = VK_NULL_HANDLE; diff --git a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h index b0ae7445..a2799eb7 100644 --- a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h +++ b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h @@ -29,7 +29,13 @@ namespace SHADE Handle logicalDeviceHdl; //! Container of subpass information used to construct subpasses - std::vector subpassDescriptions; + std::vector vkSubpassDescriptions; + + //! Container of subpass dependencies used to create renderpass + std::vector vkSubpassDeps; + + //! Attachment descriptions + std::vector vkAttachmentDescriptions; //! Clear colors for the color and depth std::array clearColors; From 8a3a08986bd0faa54c01431850c9d5e2404b1eb3 Mon Sep 17 00:00:00 2001 From: Glence Date: Sat, 1 Oct 2022 21:29:40 +0800 Subject: [PATCH 11/61] fix audiosystem warnings --- SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp | 4 ++-- SHADE_Engine/src/AudioSystem/SHAudioSystem.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp index 2482fe8e..c3c7ef03 100644 --- a/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp +++ b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp @@ -90,7 +90,7 @@ namespace SHADE //PlayEventOnce("event:/SFX/Dawn/Dawn_Attack"); } - void SHADE::SHAudioSystem::Run(float dt) + void SHADE::SHAudioSystem::Run(double dt) { static_cast(dt); //if (GetKeyState(VK_SPACE) & 0x8000) @@ -417,7 +417,7 @@ namespace SHADE int instanceCount = 0; event.second->getInstanceCount(&instanceCount); std::vector instances(instanceCount); - event.second->getInstanceList(instances.data(), instances.size(), &instanceCount); + event.second->getInstanceList(instances.data(), static_cast(instances.size()), &instanceCount); for (auto const& instance : instances) { instance->setPaused(pause); diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSystem.h b/SHADE_Engine/src/AudioSystem/SHAudioSystem.h index 04fad1f0..f19fcc3b 100644 --- a/SHADE_Engine/src/AudioSystem/SHAudioSystem.h +++ b/SHADE_Engine/src/AudioSystem/SHAudioSystem.h @@ -50,7 +50,7 @@ namespace SHADE ~SHAudioSystem(); void Init(); - void Run(float dt); + void Run(double dt); class SH_API AudioRoutine final : public SHSystemRoutine { public: From f717b61c88743cc9471b99425b0a2b2601f392df Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sat, 1 Oct 2022 22:56:15 +0800 Subject: [PATCH 12/61] Added undo and redo support for script changes in the inspector --- SHADE_Engine/src/Editor/Command/SHCommand.hpp | 22 +++++- .../src/Editor/Command/SHCommandManager.cpp | 5 ++ .../src/Editor/Command/SHCommandManager.h | 4 +- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 22 ++++++ SHADE_Engine/src/Scripting/SHScriptEngine.h | 13 ++- SHADE_Managed/premake5.lua | 3 +- SHADE_Managed/src/Editor/Editor.cxx | 79 ++++++++++++++----- SHADE_Managed/src/Editor/Editor.hxx | 29 +++++-- .../{UndoRedoStack .cxx => UndoRedoStack.cxx} | 30 +++++-- SHADE_Managed/src/Editor/UndoRedoStack.hxx | 41 ++++++++-- 10 files changed, 204 insertions(+), 44 deletions(-) rename SHADE_Managed/src/Editor/{UndoRedoStack .cxx => UndoRedoStack.cxx} (56%) diff --git a/SHADE_Engine/src/Editor/Command/SHCommand.hpp b/SHADE_Engine/src/Editor/Command/SHCommand.hpp index ae8834e9..7a526506 100644 --- a/SHADE_Engine/src/Editor/Command/SHCommand.hpp +++ b/SHADE_Engine/src/Editor/Command/SHCommand.hpp @@ -5,9 +5,13 @@ //#==============================================================# #include +#include "SH_API.h" +#include "Scripting/SHScriptEngine.h" +#include "ECS_Base/Managers/SHSystemManager.h" + namespace SHADE { - class SHBaseCommand + class SH_API SHBaseCommand { public: virtual ~SHBaseCommand() = default; @@ -48,4 +52,20 @@ namespace SHADE T newValue; SetterFunction set; }; + + class SH_API SHCLICommand : SHBaseCommand + { + public: + SHCLICommand() = default; + void Execute() override + { + SHScriptEngine* scriptEngine = static_cast(SHSystemManager::GetSystem()); + scriptEngine->RedoScriptInspectorChanges(); + } + void Undo() override + { + SHScriptEngine* scriptEngine = static_cast(SHSystemManager::GetSystem()); + scriptEngine->UndoScriptInspectorChanges(); + } + }; }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/Command/SHCommandManager.cpp b/SHADE_Engine/src/Editor/Command/SHCommandManager.cpp index 67d6c2ee..ee2d316d 100644 --- a/SHADE_Engine/src/Editor/Command/SHCommandManager.cpp +++ b/SHADE_Engine/src/Editor/Command/SHCommandManager.cpp @@ -27,6 +27,11 @@ namespace SHADE } } + void SHCommandManager::RegisterCommand(CommandPtr commandPtr) + { + undoStack.push(commandPtr); + } + void SHCommandManager::UndoCommand() { if (undoStack.empty()) diff --git a/SHADE_Engine/src/Editor/Command/SHCommandManager.h b/SHADE_Engine/src/Editor/Command/SHCommandManager.h index 3ea42740..9152c3cb 100644 --- a/SHADE_Engine/src/Editor/Command/SHCommandManager.h +++ b/SHADE_Engine/src/Editor/Command/SHCommandManager.h @@ -9,10 +9,11 @@ //|| SHADE Includes || //#==============================================================# #include "SHCommand.hpp" +#include "SH_API.h" namespace SHADE { - class SHCommandManager + class SH_API SHCommandManager { public: //#==============================================================# @@ -22,6 +23,7 @@ namespace SHADE using CommandStack = std::stack; static void PerformCommand(CommandPtr commandPtr, bool const& overrideValue = false); + static void RegisterCommand(CommandPtr commandPtr); static void UndoCommand(); static void RedoCommand(); static std::size_t GetUndoStackSize(); diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index d65eaf64..65f445a6 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -153,6 +153,16 @@ namespace SHADE csEditorRenderScripts(entity); } + void SHScriptEngine::UndoScriptInspectorChanges() const + { + csEditorUndo(); + } + + void SHScriptEngine::RedoScriptInspectorChanges() const + { + csEditorRedo(); + } + /*-----------------------------------------------------------------------------------*/ /* Static Utility Functions */ /*-----------------------------------------------------------------------------------*/ @@ -400,6 +410,18 @@ namespace SHADE DEFAULT_CSHARP_NAMESPACE + ".Editor", "RenderScriptsInInspector" ); + csEditorUndo = dotNet.GetFunctionPtr + ( + DEFAULT_CSHARP_LIB_NAME, + DEFAULT_CSHARP_NAMESPACE + ".Editor", + "Undo" + ); + csEditorRedo = dotNet.GetFunctionPtr + ( + DEFAULT_CSHARP_LIB_NAME, + DEFAULT_CSHARP_NAMESPACE + ".Editor", + "Redo" + ); } void SHScriptEngine::registerEvents() diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.h b/SHADE_Engine/src/Scripting/SHScriptEngine.h index 710421e8..0d2c0c96 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.h +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.h @@ -171,6 +171,14 @@ namespace SHADE /// /// The Entity to render the Scripts of. void RenderScriptsInInspector(EntityID entity) const; + /// + /// Performs an undo for script inspector changes if it exists. + /// + void UndoScriptInspectorChanges() const; + /// + /// Performs a redo for script inspector changes if it exists. + /// + void RedoScriptInspectorChanges() const; /*-----------------------------------------------------------------------------*/ /* Static Utility Functions */ @@ -243,9 +251,8 @@ namespace SHADE CsScriptSerialiseYamlFuncPtr csScriptDeserialiseYaml = nullptr; // - Editor CsScriptEditorFuncPtr csEditorRenderScripts = nullptr; - // Delegates - /*ECS::EntityEvent::Delegate onEntityCreate; - ECS::EntityEvent::Delegate onEntityDestroy;*/ + CsFuncPtr csEditorUndo = nullptr; + CsFuncPtr csEditorRedo = nullptr; /*-----------------------------------------------------------------------------*/ /* Event Handler Functions */ diff --git a/SHADE_Managed/premake5.lua b/SHADE_Managed/premake5.lua index 9724c296..c2f47aa2 100644 --- a/SHADE_Managed/premake5.lua +++ b/SHADE_Managed/premake5.lua @@ -30,7 +30,8 @@ project "SHADE_Managed" "%{IncludeDir.imguizmo}", "%{IncludeDir.imnodes}", "%{IncludeDir.yamlcpp}", - "%{IncludeDir.RTTR}/include", + "%{IncludeDir.RTTR}/include", + "%{IncludeDir.dotnet}\\include", "%{wks.location}/SHADE_Engine/src" } diff --git a/SHADE_Managed/src/Editor/Editor.cxx b/SHADE_Managed/src/Editor/Editor.cxx index 73d52d14..735f8c2c 100644 --- a/SHADE_Managed/src/Editor/Editor.cxx +++ b/SHADE_Managed/src/Editor/Editor.cxx @@ -16,6 +16,8 @@ of DigiPen Institute of Technology is prohibited. #include "SHpch.h" // Primary Header #include "Editor/Editor.hxx" +// STL Includes +#include // External Dependencies #include "Editor/SHEditorUI.h" // Project Headers @@ -25,6 +27,8 @@ of DigiPen Institute of Technology is prohibited. #include "Utility/Debug.hxx" #include "Serialisation/ReflectionUtilities.hxx" #include "Editor/IconsMaterialDesign.h" +#include "Editor/Command/SHCommandManager.h" +#include "Editor/Command/SHCommand.hpp" // Using Directives using namespace System; @@ -48,9 +52,11 @@ using namespace System::Collections::Generic; (field->FieldType == MANAGED_TYPE::typeid) \ { \ NATIVE_TYPE val = safe_cast(field->GetValue(object)); \ + NATIVE_TYPE oldVal = val; \ if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \ { \ field->SetValue(object, val); \ + registerUndoAction(object, field, val, oldVal); \ } \ } \ /// @@ -69,9 +75,11 @@ using namespace System::Collections::Generic; (field->FieldType == MANAGED_TYPE::typeid) \ { \ NATIVE_TYPE val = Convert::ToNative(safe_cast(field->GetValue(object))); \ + NATIVE_TYPE oldVal = val; \ if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \ { \ field->SetValue(object, Convert::ToCLI(val)); \ + registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal)); \ } \ } \ @@ -105,26 +113,43 @@ namespace SHADE SAFE_NATIVE_CALL_END_N("SHADE_Managed.Editor.RenderScriptsInInspector") } - void Editor::RenderScriptAddButton(Entity entity) - { - // Get list of Scripts - auto scriptTypes = ScriptStore::GetAvailableScriptList(); + void Editor::RenderScriptAddButton(Entity entity) + { + // Get list of Scripts + auto scriptTypes = ScriptStore::GetAvailableScriptList(); - // Define pop up - if (SHEditorUI::BeginMenu("Add Script", ICON_MD_LIBRARY_ADD)) - { - for each (Type ^ type in scriptTypes) - { - if (SHEditorUI::Selectable(Convert::ToNative(type->Name))) - { - // Add the script - ScriptStore::AddScriptViaName(entity, type->Name); - } - } + // Define pop up + if (SHEditorUI::BeginMenu("Add Script", ICON_MD_LIBRARY_ADD)) + { + for each (Type ^ type in scriptTypes) + { + if (SHEditorUI::Selectable(Convert::ToNative(type->Name))) + { + // Add the script + ScriptStore::AddScriptViaName(entity, type->Name); + } + } - SHEditorUI::EndMenu(); - } - } + SHEditorUI::EndMenu(); + } + } + + /*---------------------------------------------------------------------------------*/ + /* UndoRedoStack Functions */ + /*---------------------------------------------------------------------------------*/ + void Editor::Undo() + { + SAFE_NATIVE_CALL_BEGIN + actionStack.Undo(); + SAFE_NATIVE_CALL_END_N("SHADE_Managed.Editor.Undo") + } + + void Editor::Redo() + { + SAFE_NATIVE_CALL_BEGIN + actionStack.Redo(); + SAFE_NATIVE_CALL_END_N("SHADE_Managed.Editor.Redo") + } /*---------------------------------------------------------------------------------*/ /* Helper Functions */ @@ -192,9 +217,11 @@ namespace SHADE } int val = safe_cast(field->GetValue(object)); + int oldVal = val; if (SHEditorUI::InputEnumCombo(Convert::ToNative(field->Name), val, nativeEnumNames)) { field->SetValue(object, val); + registerUndoAction(object, field, val, oldVal); } } else if RENDER_FIELD_CASTED(Vector2, SHVec2, InputVec2) @@ -210,9 +237,11 @@ namespace SHADE // Actual Field std::string val = Convert::ToNative(stringVal); + std::string oldVal = val; if (SHEditorUI::InputTextField(Convert::ToNative(field->Name), val)) { field->SetValue(object, Convert::ToCLI(val)); + registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal)); } } } @@ -231,4 +260,18 @@ namespace SHADE } } + void Editor::registerUndoAction(System::Object^ object, System::Reflection::FieldInfo^ field, System::Object^ newData, System::Object^ oldData) + { + // Create command and add it into the undo stack + UndoRedoStack::Command cmd; + cmd.Field = field; + cmd.Object = object; + cmd.NewData = newData; + cmd.OldData = oldData; + actionStack.Add(cmd); + + // Inform the C++ Undo-Redo stack + SHCommandManager::RegisterCommand(std::reinterpret_pointer_cast(std::make_shared())); + } + } diff --git a/SHADE_Managed/src/Editor/Editor.hxx b/SHADE_Managed/src/Editor/Editor.hxx index 188da660..c4800645 100644 --- a/SHADE_Managed/src/Editor/Editor.hxx +++ b/SHADE_Managed/src/Editor/Editor.hxx @@ -16,6 +16,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "Engine/Entity.hxx" #include "Scripts/Script.hxx" +#include "UndoRedoStack.hxx" namespace SHADE { @@ -36,15 +37,26 @@ namespace SHADE /// rendering code. /// /// The Entity to render the Scripts of. - static void RenderScriptsInInspector(Entity entity); - /// - /// Renders a dropdown button that allows for the addition of PlushieScripts - /// onto the specified Entity. - /// - /// The Entity to add PlushieScripts to. - static void RenderScriptAddButton(Entity entity); + static void RenderScriptsInInspector(Entity entity); + /// + /// Renders a dropdown button that allows for the addition of PlushieScripts + /// onto the specified Entity. + /// + /// The Entity to add PlushieScripts to. + static void RenderScriptAddButton(Entity entity); + + /*-----------------------------------------------------------------------------*/ + /* UndoRedoStack Functions */ + /*-----------------------------------------------------------------------------*/ + static void Undo(); + static void Redo(); + + private: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + static UndoRedoStack actionStack; - private: /*-----------------------------------------------------------------------------*/ /* Helper Functions */ /*-----------------------------------------------------------------------------*/ @@ -73,5 +85,6 @@ namespace SHADE /// The Entity to render the Scripts of. /// The Script to render the inspector for. static void renderScriptContextMenu(Entity entity, Script^ script); + static void registerUndoAction(System::Object^ object, System::Reflection::FieldInfo^ field, System::Object^ newData, System::Object^ oldData); }; } diff --git a/SHADE_Managed/src/Editor/UndoRedoStack .cxx b/SHADE_Managed/src/Editor/UndoRedoStack.cxx similarity index 56% rename from SHADE_Managed/src/Editor/UndoRedoStack .cxx rename to SHADE_Managed/src/Editor/UndoRedoStack.cxx index e3fdc2f0..7a3b1930 100644 --- a/SHADE_Managed/src/Editor/UndoRedoStack .cxx +++ b/SHADE_Managed/src/Editor/UndoRedoStack.cxx @@ -22,28 +22,48 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { + bool UndoRedoStack::UndoActionPresent::get() + { + return commandStack->Count > 0 && latestActionIndex >= 0; + } + + bool UndoRedoStack::RedoActionPresent::get() + { + return latestActionIndex >= 0 && latestActionIndex < commandStack->Count - 1; + } + void UndoRedoStack::Add(Command command) { // Erase any other actions ahead of the current action - if (latestActionIndex < commandStack->Count - 1) + if (latestActionIndex >= 0 && latestActionIndex < commandStack->Count - 1) { - commandStack->RemoveRange(latestActionIndex + 1, commandStack->Count - latestActionIndex); + commandStack->RemoveRange(latestActionIndex, commandStack->Count - latestActionIndex); } // Add the command commandStack->Add(command); - // Increment latest command - ++latestActionIndex; + // Set the latest command + latestActionIndex = commandStack->Count - 1; } - void UndoRedoStack::Undo() + void UndoRedoStack::Undo() { + if (!UndoActionPresent) + return; + Command cmd = commandStack[latestActionIndex]; + cmd.Field->SetValue(cmd.Object, cmd.OldData); + --latestActionIndex; } void UndoRedoStack::Redo() { + if (!RedoActionPresent) + return; + Command cmd = commandStack[latestActionIndex]; + cmd.Field->SetValue(cmd.Object, cmd.NewData); + ++latestActionIndex; } } diff --git a/SHADE_Managed/src/Editor/UndoRedoStack.hxx b/SHADE_Managed/src/Editor/UndoRedoStack.hxx index 2db3cacb..4c525228 100644 --- a/SHADE_Managed/src/Editor/UndoRedoStack.hxx +++ b/SHADE_Managed/src/Editor/UndoRedoStack.hxx @@ -24,25 +24,52 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------*/ + /// + /// Command for the stack that represents a data modification. + /// value struct Command { public: - System::Action^ UndoAction; - System::Action^ RedoAction; - }; + System::Object^ Object; + System::Reflection::FieldInfo^ Field; + System::Object^ NewData; + System::Object^ OldData; + }; + + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// True if there is an undoable action in the stack. + /// + property bool UndoActionPresent { bool get(); } + /// + /// True if there is a redoable action in the stack. + /// + property bool RedoActionPresent { bool get(); } /*-----------------------------------------------------------------------------*/ /* Usage Functions */ - /*-----------------------------------------------------------------------------*/ - void Add(Command command); + /*-----------------------------------------------------------------------------*/ + /// + /// Adds a command onto the stack. + /// + /// + void Add(Command command); + /// + /// Undos the last added command if it exists. + /// void Undo(); - void Redo(); + /// + /// Redoes the last undo-ed command if it exists. + /// + void Redo(); private: /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ int latestActionIndex = -1; - System::Collections::Generic::List^ commandStack = gcnew System::Collections::Generic::List(); + System::Collections::Generic::List^ commandStack = gcnew System::Collections::Generic::List(); }; } From 15c39d7028f9eeea135a3af45f8a8d214df227b0 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sat, 1 Oct 2022 22:58:19 +0800 Subject: [PATCH 13/61] Removed mixed tabs and spaces --- SHADE_Engine/src/Scripting/SHScriptEngine.h | 12 +++++------ SHADE_Managed/src/Editor/UndoRedoStack.cxx | 24 ++++++++++----------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.h b/SHADE_Engine/src/Scripting/SHScriptEngine.h index 0d2c0c96..239d6b90 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.h +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.h @@ -175,10 +175,10 @@ namespace SHADE /// Performs an undo for script inspector changes if it exists. /// void UndoScriptInspectorChanges() const; - /// - /// Performs a redo for script inspector changes if it exists. - /// - void RedoScriptInspectorChanges() const; + /// + /// Performs a redo for script inspector changes if it exists. + /// + void RedoScriptInspectorChanges() const; /*-----------------------------------------------------------------------------*/ /* Static Utility Functions */ @@ -251,8 +251,8 @@ namespace SHADE CsScriptSerialiseYamlFuncPtr csScriptDeserialiseYaml = nullptr; // - Editor CsScriptEditorFuncPtr csEditorRenderScripts = nullptr; - CsFuncPtr csEditorUndo = nullptr; - CsFuncPtr csEditorRedo = nullptr; + CsFuncPtr csEditorUndo = nullptr; + CsFuncPtr csEditorRedo = nullptr; /*-----------------------------------------------------------------------------*/ /* Event Handler Functions */ diff --git a/SHADE_Managed/src/Editor/UndoRedoStack.cxx b/SHADE_Managed/src/Editor/UndoRedoStack.cxx index 7a3b1930..08e289cc 100644 --- a/SHADE_Managed/src/Editor/UndoRedoStack.cxx +++ b/SHADE_Managed/src/Editor/UndoRedoStack.cxx @@ -22,15 +22,15 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { - bool UndoRedoStack::UndoActionPresent::get() - { - return commandStack->Count > 0 && latestActionIndex >= 0; - } + bool UndoRedoStack::UndoActionPresent::get() + { + return commandStack->Count > 0 && latestActionIndex >= 0; + } - bool UndoRedoStack::RedoActionPresent::get() - { + bool UndoRedoStack::RedoActionPresent::get() + { return latestActionIndex >= 0 && latestActionIndex < commandStack->Count - 1; - } + } void UndoRedoStack::Add(Command command) { @@ -47,7 +47,7 @@ namespace SHADE latestActionIndex = commandStack->Count - 1; } - void UndoRedoStack::Undo() + void UndoRedoStack::Undo() { if (!UndoActionPresent) return; @@ -60,10 +60,10 @@ namespace SHADE void UndoRedoStack::Redo() { if (!RedoActionPresent) - return; + return; - Command cmd = commandStack[latestActionIndex]; - cmd.Field->SetValue(cmd.Object, cmd.NewData); - ++latestActionIndex; + Command cmd = commandStack[latestActionIndex]; + cmd.Field->SetValue(cmd.Object, cmd.NewData); + ++latestActionIndex; } } From 1a14e5241b1fa12325aa45e4f4f6ce4f222dee9d Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sat, 1 Oct 2022 23:14:42 +0800 Subject: [PATCH 14/61] Added names for SHGraphicsSystem Routines --- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 29 +++++++++++++++++++ .../MiddleEnd/Interface/SHGraphicsSystem.h | 4 +++ 2 files changed, 33 insertions(+) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index e4207c20..8e3c599b 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -518,21 +518,50 @@ namespace SHADE { window = wind; } + + /*-----------------------------------------------------------------------------------*/ + /* System Routine Functions - BeginRoutine */ + /*-----------------------------------------------------------------------------------*/ + SHGraphicsSystem::BeginRoutine::BeginRoutine() + : SHSystemRoutine("Graphics System Frame Set Up", false) + {} void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept { reinterpret_cast(system)->BeginRender(); } + + /*-----------------------------------------------------------------------------------*/ + /* System Routine Functions - RenderRoutine */ + /*-----------------------------------------------------------------------------------*/ + SHGraphicsSystem::RenderRoutine::RenderRoutine() + : SHSystemRoutine("Graphics System Render", false) + {} void SHGraphicsSystem::RenderRoutine::Execute(double dt) noexcept { reinterpret_cast(system)->Run(dt); } + /*-----------------------------------------------------------------------------------*/ + /* System Routine Functions - EndRoutine */ + /*-----------------------------------------------------------------------------------*/ + SHGraphicsSystem::EndRoutine::EndRoutine() + : SHSystemRoutine("Graphics System Frame Clean Up", false) + {} + void SHGraphicsSystem::EndRoutine::Execute(double) noexcept { reinterpret_cast(system)->EndRender(); } + + /*-----------------------------------------------------------------------------------*/ + /* System Routine Functions - BatcherDispatcherRoutine */ + /*-----------------------------------------------------------------------------------*/ + SHGraphicsSystem::BatcherDispatcherRoutine::BatcherDispatcherRoutine() + : SHSystemRoutine("Graphics System Batcher Dispatcher", false) + {} + void SHGraphicsSystem::BatcherDispatcherRoutine::Execute(double) noexcept { auto& renderables = SHComponentManager::GetDense(); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 10df44a5..3a392ac5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -69,21 +69,25 @@ namespace SHADE class SH_API BeginRoutine final : public SHSystemRoutine { public: + BeginRoutine(); virtual void Execute(double dt) noexcept override final; }; class SH_API RenderRoutine final : public SHSystemRoutine { public: + RenderRoutine(); virtual void Execute(double dt) noexcept override final; }; class SH_API EndRoutine final : public SHSystemRoutine { public: + EndRoutine(); virtual void Execute(double dt) noexcept override final; }; class SH_API BatcherDispatcherRoutine final : public SHSystemRoutine { public: + BatcherDispatcherRoutine(); virtual void Execute(double dt) noexcept override final; }; From 8e60d4b771d19a2c09e867d6a7bf909d3ad495ad Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sat, 1 Oct 2022 23:42:54 +0800 Subject: [PATCH 15/61] Changed asserts to SHLOG related functions --- SHADE_Engine/src/Filesystem/SHFileSystem.cpp | 33 ++++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/SHADE_Engine/src/Filesystem/SHFileSystem.cpp b/SHADE_Engine/src/Filesystem/SHFileSystem.cpp index 16175578..bd34ed71 100644 --- a/SHADE_Engine/src/Filesystem/SHFileSystem.cpp +++ b/SHADE_Engine/src/Filesystem/SHFileSystem.cpp @@ -2,7 +2,6 @@ #include "SHFileSystem.h" #include "fileapi.h" #include -#include #include namespace SHADE @@ -27,8 +26,11 @@ namespace SHADE } auto const count = static_cast(folders[here]->subFolders.size()); - - assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n"); + + if (count >= FOLDER_MAX_COUNT) + { + SHLOG_ERROR("Max subfolder reached: {}\n", name); + } auto const location = static_cast(count); @@ -37,7 +39,10 @@ namespace SHADE return location; } - assert(folders.contains(here), "Folder creation location does not exist/invalid\n"); + if (!folders.contains(here)) + { + SHLOG_ERROR("Folder creation location does not exist/invalid: {}\n", here); + } auto const count = static_cast(folders[here]->subFolders.size()); @@ -45,7 +50,11 @@ namespace SHADE location <<= FOLDER_BIT_ALLOCATE; location |= count; - assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n"); + if (count >= FOLDER_MAX_COUNT) + { + SHLOG_ERROR("Max subfolder reached: {}\n", name); + } + CreateFolder(folders[0]->path, here, location, name); return location; @@ -53,7 +62,10 @@ namespace SHADE bool SHFileSystem::DeleteFolder(FolderPointer location) noexcept { - assert(folders.contains(location->id), "Delete target does not exist/invalid.\n"); + if (!folders.contains(location->id)) + { + SHLOG_ERROR("Delete target does not exist/invalid: {}\n", location->name); + } for (auto const& subFolder : folders[location->id]->subFolders) { @@ -116,10 +128,11 @@ namespace SHADE FolderPointer SHFileSystem::CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept { - assert( - CreateDirectoryA(path.c_str(), nullptr), - "Failed to create folder\n" - ); + + if (!CreateDirectoryA(path.c_str(), nullptr)) + { + SHLOG_ERROR("Failed to create folder: {}\n", path); + } folders[location] = std::make_unique(location, name); folders[location]->path = path; From 77653ebde5940ac0707adad35162349ad43e5450 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Sat, 1 Oct 2022 23:56:45 +0800 Subject: [PATCH 16/61] add window isMinimized --- SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp | 6 ++++++ SHADE_Engine/src/Graphics/Windowing/SHWindow.h | 11 +++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp b/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp index 4d8dae72..a4569c75 100644 --- a/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp +++ b/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp @@ -378,6 +378,12 @@ namespace SHADE { wndData.width = static_cast(size.cx); wndData.height = static_cast(size.cy); + + if (type == SIZE_MINIMIZED) + { + wndData.isMinimised = true; + } + for (auto const& entry : windowResizeCallbacks) { entry.second(static_cast(wndData.width), static_cast(wndData.height)); diff --git a/SHADE_Engine/src/Graphics/Windowing/SHWindow.h b/SHADE_Engine/src/Graphics/Windowing/SHWindow.h index 1e08dcb0..8f15bb60 100644 --- a/SHADE_Engine/src/Graphics/Windowing/SHWindow.h +++ b/SHADE_Engine/src/Graphics/Windowing/SHWindow.h @@ -18,7 +18,7 @@ namespace SHADE }; struct WindowData - { + { unsigned x = 0; unsigned y = 0; @@ -42,7 +42,7 @@ namespace SHADE bool closable = true; bool minimizable = true; - + bool maximizable = true; //bool canFullscreen = true; @@ -56,11 +56,13 @@ namespace SHADE bool shadowEnabled = true; bool isVisible = true; - + bool isFullscreen = false; bool modal = false; + bool isMinimised = false; + std::wstring title = L"SHADE ENGINE"; std::wstring name = L"SHADEEngineApp"; @@ -103,7 +105,7 @@ namespace SHADE void SetMousePosition(unsigned x, unsigned y); //unsigned GetBGColor(); - + void SetBGColor(unsigned color); void Minimize(); @@ -163,6 +165,7 @@ namespace SHADE void OnSize(UINT msg, UINT type, SIZE size); void OnPosChange(LPWINDOWPOS pos); void OnPaint(HDC hdc, LPPAINTSTRUCT paint); + bool IsMinimized() const { return wndData.isMinimised; } }; static SHWindowMap windowMap; static SHWindow* windowBeingCreated = nullptr; From e2b86545bb8482c95d2f90f457e1a6d253bfbb14 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sat, 1 Oct 2022 23:57:08 +0800 Subject: [PATCH 17/61] Window resize working --- SHADE_Application/src/Scenes/SBTestScene.cpp | 4 +- .../Graphics/Framebuffer/SHVkFramebuffer.cpp | 45 +++++++++++++++++++ .../Graphics/Framebuffer/SHVkFramebuffer.h | 2 + .../src/Graphics/Images/SHVkImage.cpp | 5 ++- SHADE_Engine/src/Graphics/Images/SHVkImage.h | 2 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 18 +++++++- .../MiddleEnd/Interface/SHGraphicsSystem.h | 2 + .../MiddleEnd/Interface/SHViewport.cpp | 12 +++++ .../Graphics/MiddleEnd/Interface/SHViewport.h | 6 +++ .../Graphics/RenderGraph/SHRenderGraph.cpp | 14 +++--- .../src/Graphics/RenderGraph/SHRenderGraph.h | 2 +- .../RenderGraph/SHRenderGraphNode.cpp | 23 ++++++++++ .../RenderGraph/SHRenderGraphResource.cpp | 9 +++- .../RenderGraph/SHRenderGraphResource.h | 2 +- .../Graphics/Renderpass/SHVkRenderpass.cpp | 27 +++++++++++ .../src/Graphics/Renderpass/SHVkRenderpass.h | 2 + 16 files changed, 158 insertions(+), 17 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 6daa3645..5eee8cac 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -76,8 +76,8 @@ namespace Sandbox // Create Stress Test Objects static const SHVec3 TEST_OBJ_SCALE = { 0.05f, 0.05f, 0.05f }; - constexpr int NUM_ROWS = 100; - constexpr int NUM_COLS = 100; + constexpr int NUM_ROWS = 10; + constexpr int NUM_COLS = 10; static const SHVec3 TEST_OBJ_SPACING = { 0.05f, 0.05f, 0.05f }; static const SHVec3 TEST_OBJ_START_POS = { - (NUM_COLS / 2 * TEST_OBJ_SPACING.x ) + 1.0f, -2.0f, -1.0f }; diff --git a/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.cpp b/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.cpp index 1386134f..76e627d3 100644 --- a/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.cpp +++ b/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.cpp @@ -98,6 +98,51 @@ namespace SHADE return *this; } + void SHVkFramebuffer::HandleResize(Handle const& renderpassHdl, std::vector> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept + { + width = inWidth; + height = inHeight; + + for (auto& attachment : attachments) + { + // Not sure if its an error to pass in diff dimension images. + if (attachment->GetParentImage()->GetWidth() != (*attachments.begin())->GetParentImage()->GetWidth() || attachment->GetParentImage()->GetHeight() != (*attachments.begin())->GetParentImage()->GetHeight()) + { + SHLOG_ERROR("Dimensions of images not same as each other. Cannot create framebuffer."); + return; + } + } + + std::vector vkAttachments(attachments.size()); + + uint32_t i = 0; + for(auto const& attachment : attachments) + { + vkAttachments[i] = attachment->GetImageView(); + ++i; + } + + vk::FramebufferCreateInfo createInfo + { + .renderPass = renderpassHdl->GetVkRenderpass(), + .attachmentCount = static_cast(vkAttachments.size()), + .pAttachments = vkAttachments.data(), + .width = width, + .height = height, + .layers = 1 // TODO: Find out why this is 1 + }; + + if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createFramebuffer(&createInfo, nullptr, &vkFramebuffer); result != vk::Result::eSuccess) + { + SHVulkanDebugUtil::ReportVkError(result, "Failed to create framebuffer. "); + return; + } + else + { + SHVulkanDebugUtil::ReportVkSuccess("Successfully created framebuffer. "); + } + } + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.h b/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.h index fa9161e8..47bfcf99 100644 --- a/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.h +++ b/SHADE_Engine/src/Graphics/Framebuffer/SHVkFramebuffer.h @@ -37,6 +37,8 @@ namespace SHADE SHVkFramebuffer(SHVkFramebuffer&& rhs) noexcept; SHVkFramebuffer& operator=(SHVkFramebuffer&& rhs) noexcept; + void HandleResize (Handle const& renderpassHdl, std::vector> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept; + /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp b/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp index ed539a6c..00cc31bf 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp +++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp @@ -293,10 +293,13 @@ namespace SHADE barrier.subresourceRange.layerCount = layerCount; } - void SHVkImage::HandleResizeFramebufferImage(void) noexcept + void SHVkImage::HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept { vmaDestroyImage(*vmaAllocator, vkImage, alloc); + width = newWidth; + height = newHeight; + CreateFramebufferImage(); } diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.h b/SHADE_Engine/src/Graphics/Images/SHVkImage.h index b23d7bd4..51b71b26 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImage.h +++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.h @@ -137,7 +137,7 @@ namespace SHADE Handle CreateImageView (Handle const& inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) const noexcept; void TransferToDeviceResource (Handle cmdBufferHdl) noexcept; void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept; - void HandleResizeFramebufferImage(void) noexcept; + void HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept; /*-----------------------------------------------------------------------*/ /* GETTERS AND SETTERS */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index e4207c20..979f8d40 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -67,6 +67,9 @@ namespace SHADE // Register callback to notify render context upon a window resize window->RegisterWindowSizeCallback([&]([[maybe_unused]] uint32_t width, [[maybe_unused]] uint32_t height) { + if (width == 0 || height == 0) + return; + renderContext.SetIsResized(true); }); @@ -116,8 +119,8 @@ namespace SHADE screenCamera = resourceManager.Create(); screenCamera->SetLookAt(SHVec3(0.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 1.0f), SHVec3(0.0f, 1.0f, 0.0f)); screenCamera->SetOrthographic(static_cast(windowDims.first), static_cast(windowDims.second), 0.01f, 100.0f); + worldCamera = resourceManager.Create(); - //worldCamera->SetLookAt(SHVec3(1.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 2.0f), SHVec3(0.0f, 1.0f, 0.0f)); worldCamera->SetLookAt(SHVec3(0.0f, 0.0f, 0.0f), SHVec3(0.0f, 0.0f, -2.0f), SHVec3(0.0f, 1.0f, 0.0f)); worldCamera->SetPerspective(90.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 100.0f); @@ -125,7 +128,7 @@ namespace SHADE defaultViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast(window->GetWindowSize().first), static_cast(window->GetWindowSize().second), 0.0f, 1.0f)); // Get render graph from default viewport world renderer - auto worldRenderGraph = resourceManager.Create(); + worldRenderGraph = resourceManager.Create(); std::vector> renderContextCmdPools{swapchain->GetNumImages()}; for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i) @@ -249,6 +252,10 @@ namespace SHADE // Begin recording the command buffer currentCmdBuffer->BeginRecording(); + uint32_t w = viewports[vpIndex]->GetWidth(); + uint32_t h = viewports[vpIndex]->GetHeight(); + currentCmdBuffer->SetViewportScissor (static_cast(w), static_cast(h), w, h); + currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout()); // Bind all the buffers required for meshes @@ -512,6 +519,13 @@ namespace SHADE swapchain->Resize(surface, windowDims.first, windowDims.second); renderContext.HandleResize(); + + worldRenderGraph->HandleResize(windowDims.first, windowDims.second); + + defaultViewport->SetWidth(windowDims.first); + defaultViewport->SetHeight(windowDims.second); + + worldCamera->SetPerspective(90.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 100.0f); } void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 10df44a5..1dddaeb1 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -316,5 +316,7 @@ namespace SHADE // Temp Materials Handle defaultMaterial; + + Handle worldRenderGraph; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp index 25c5bca2..d6eea3d7 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp @@ -73,4 +73,16 @@ namespace SHADE iter->Free(); renderers.erase(iter); } + + void SHViewport::SetWidth(uint32_t w) noexcept + { + viewport.width = w; + } + + void SHViewport::SetHeight(uint32_t h) noexcept + { + viewport.height = h; + + } + } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h index d97d62ce..ce992f77 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h @@ -62,6 +62,12 @@ namespace SHADE Handle AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle renderGraph); void RemoveRenderer(Handle renderer); + /*-----------------------------------------------------------------------------*/ + /* Setters */ + /*-----------------------------------------------------------------------------*/ + void SetWidth(uint32_t w) noexcept; + void SetHeight (uint32_t h) noexcept; + /*-----------------------------------------------------------------------------*/ /* Getters */ /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 27a1d604..cad6a78e 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -46,7 +46,7 @@ namespace SHADE if (w == static_cast(-1) && h == static_cast(-1)) { w = swapchainHdl->GetSwapchainImage(0)->GetWidth(); - w = swapchainHdl->GetSwapchainImage(0)->GetHeight(); + h = swapchainHdl->GetSwapchainImage(0)->GetHeight(); format = swapchainHdl->GetSurfaceFormatKHR().format; } @@ -465,9 +465,6 @@ namespace SHADE // better way to manage these void SHRenderGraph::Execute(uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept { - // TODO: DON'T HARDCODE THIS - cmdBuffer->SetViewportScissor(1920.0f, 1080.0f, 1920, 1080); - for (auto& node : nodes) node->Execute(cmdBuffer, descPool, frameIndex); } @@ -480,13 +477,16 @@ namespace SHADE } } - void SHRenderGraph::HandleResize(void) noexcept + void SHRenderGraph::HandleResize(uint32_t newWidth, uint32_t newHeight) noexcept { // resize resources for (auto& [name, resource]: graphResources) - resource->HandleResize(); - + resource->HandleResize(newWidth, newHeight); + for (auto& node : nodes) + { + node->HandleResize(); + } } Handle SHRenderGraph::GetNode(std::string const& nodeName) const noexcept diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 83aeeb2c..a3140a4f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -80,7 +80,7 @@ namespace SHADE void Generate (void) noexcept; void Execute (uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept; void FinaliseBatch(uint32_t frameIndex, Handle descPool); - void HandleResize (void) noexcept; + void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept; /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 551e90fc..05232af3 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -3,6 +3,7 @@ #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Images/SHVkImageView.h" #include "Graphics/Swapchain/SHVkSwapchain.h" +#include "Graphics/Framebuffer/SHVkFramebuffer.h" #include "SHRenderGraphResource.h" #include "SHSubpass.h" @@ -58,7 +59,29 @@ namespace SHADE void SHRenderGraphNode::HandleResize(void) noexcept { + renderpass->HandleResize(); + for (uint32_t i = 0; i < framebuffers.size(); ++i) + { + std::vector> imageViews(attResources.size()); + uint32_t fbWidth = std::numeric_limits::max(); + uint32_t fbHeight = std::numeric_limits::max(); + + for (uint32_t j = 0; j < attResources.size(); ++j) + { + uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) ? i : 0; + imageViews[j] = attResources[j]->imageViews[imageViewIndex]; + + // We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's + if (fbWidth > attResources[j]->width) + fbWidth = attResources[j]->width; + if (fbHeight > attResources[j]->height) + fbHeight = attResources[j]->height; + } + + + framebuffers[i]->HandleResize(renderpass, imageViews, fbWidth, fbHeight); + } } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index 72dd557f..cc881867 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -146,6 +146,7 @@ namespace SHADE , width{ rhs.width } , height{ rhs.height } , mipLevels{ rhs.mipLevels } + , imageAspectFlags{ rhs.imageAspectFlags } { } @@ -176,6 +177,7 @@ namespace SHADE width = rhs.width; height = rhs.height; mipLevels = rhs.mipLevels; + imageAspectFlags = rhs.imageAspectFlags; return *this; } @@ -193,8 +195,11 @@ namespace SHADE } - void SHRenderGraphResource::HandleResize(void) noexcept + void SHRenderGraphResource::HandleResize(uint32_t newWidth, uint32_t newHeight) noexcept { + width = newWidth; + height = newHeight; + if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT) { // prepare image view details @@ -211,7 +216,7 @@ namespace SHADE for (uint32_t i = 0; i < images.size(); ++i) { - images[i]->HandleResizeFramebufferImage(); + images[i]->HandleResizeFramebufferImage(width, height); imageViews[i]->ViewNewImage(images[i], viewDetails); } } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h index 741acdc0..ebb699d8 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h @@ -70,7 +70,7 @@ namespace SHADE SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept; ~SHRenderGraphResource(void) noexcept; - void HandleResize (void) noexcept; + void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept; friend class SHRenderGraphNode; friend class SHRenderGraph; diff --git a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp index 349c507e..fee23f13 100644 --- a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp +++ b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp @@ -227,6 +227,7 @@ namespace SHADE , vkSubpassDeps{ std::move(rhs.vkSubpassDeps) } , clearColors{ std::move(rhs.clearColors) } , vkAttachmentDescriptions{ std::move(rhs.vkAttachmentDescriptions) } + , numAttDescs{rhs.numAttDescs} { rhs.vkRenderpass = VK_NULL_HANDLE; } @@ -243,6 +244,7 @@ namespace SHADE vkSubpassDeps = std::move(rhs.vkSubpassDeps); clearColors = std::move(rhs.clearColors); vkAttachmentDescriptions = std::move(rhs.vkAttachmentDescriptions); + numAttDescs = std::move(rhs.numAttDescs); rhs.vkRenderpass = VK_NULL_HANDLE; @@ -255,6 +257,31 @@ namespace SHADE } + void SHVkRenderpass::HandleResize(void) noexcept + { + logicalDeviceHdl->GetVkLogicalDevice().destroyRenderPass(vkRenderpass, nullptr); + + vk::RenderPassCreateInfo renderPassCreateInfo{}; + + renderPassCreateInfo.attachmentCount = static_cast(vkAttachmentDescriptions.size()); + renderPassCreateInfo.pAttachments = vkAttachmentDescriptions.data(); + renderPassCreateInfo.subpassCount = static_cast(vkSubpassDescriptions.size()); + renderPassCreateInfo.pSubpasses = vkSubpassDescriptions.data(); + renderPassCreateInfo.dependencyCount = static_cast(vkSubpassDeps.size()); + renderPassCreateInfo.pDependencies = vkSubpassDeps.data(); + + + if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createRenderPass(&renderPassCreateInfo, nullptr, &vkRenderpass); result != vk::Result::eSuccess) + { + SHVulkanDebugUtil::ReportVkError(result, "Failed to create Renderpass. "); + } + else + { + SHVulkanDebugUtil::ReportVkSuccess("Successfully created Renderpass. "); + } + + } + vk::RenderPass SHVkRenderpass::GetVkRenderpass(void) const noexcept { return vkRenderpass; diff --git a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h index a2799eb7..70a04bbf 100644 --- a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h +++ b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.h @@ -55,6 +55,8 @@ namespace SHADE SHVkRenderpass(SHVkRenderpass&& rhs) noexcept; SHVkRenderpass& operator=(SHVkRenderpass&& rhs) noexcept; + void HandleResize (void) noexcept; + /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ From 61e353164bc3fe9aed6f1df550d2c5743054104e Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sat, 1 Oct 2022 23:57:26 +0800 Subject: [PATCH 18/61] Fixed all asset related warnings --- .../src/Assets/Asset Types/SHTextureAsset.h | 6 +++-- .../src/Assets/Libraries/SHMeshLoader.cpp | 4 +-- .../src/Assets/Libraries/SHTextureLoader.cpp | 8 +++--- SHADE_Engine/src/Assets/SHAssetManager.cpp | 26 ++++++++++--------- .../src/Assets/SHAssetMetaHandler.cpp | 2 +- .../MiddleEnd/Textures/SHTextureLibrary.h | 2 +- 6 files changed, 26 insertions(+), 22 deletions(-) diff --git a/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h index 634d9a9a..07cebea9 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h @@ -17,7 +17,8 @@ namespace SHADE SHTexture::PixelChannel const * pixelData; SHTextureAsset() - : numBytes{ 0 }, + : compiled{ false }, + numBytes{ 0 }, width{ 0 }, height{ 0 }, format{ SHTexture::TextureFormat::eUndefined }, @@ -25,7 +26,8 @@ namespace SHADE {} SHTextureAsset(SHTextureAsset const& rhs) - : numBytes{ rhs.numBytes }, + : compiled{ false }, + numBytes{ rhs.numBytes }, width{ rhs.width }, height{ rhs.height }, format{ rhs.format }, diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp index b77d429d..3a5fb9ec 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp @@ -91,8 +91,8 @@ namespace SHADE } } - result.header.vertexCount = result.vertexPosition.size(); - result.header.indexCount = result.indices.size(); + result.header.vertexCount = static_cast(result.vertexPosition.size()); + result.header.indexCount = static_cast(result.indices.size()); result.header.meshName = mesh.mName.C_Str(); return result; diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp index 1047cdc6..47501d42 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp @@ -83,10 +83,10 @@ namespace SHADE std::vector mipOff(file.GetMipCount()); - for (auto i{0}; i < file.GetMipCount(); ++i) + for (size_t i{0}; i < file.GetMipCount(); ++i) { - mipOff[i] = totalBytes; - totalBytes += file.GetImageData(i, 0)->m_memSlicePitch; + mipOff[i] = static_cast(totalBytes); + totalBytes += file.GetImageData(static_cast(i), 0)->m_memSlicePitch; } SHTexture::PixelChannel* pixel = new SHTexture::PixelChannel[totalBytes]; @@ -94,7 +94,7 @@ namespace SHADE //pixel = std::move(reinterpret_cast(file.GetDDSData())); asset.compiled = false; - asset.numBytes = totalBytes; + asset.numBytes = static_cast(totalBytes); asset.width = file.GetWidth(); asset.height = file.GetHeight(); asset.format = ddsLoaderToVkFormat(file.GetFormat(), true); diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 989cd2ad..430b8c79 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -72,12 +72,13 @@ namespace SHADE AssetType type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string().c_str()); std::string folder; - switch (type) - { - default: - //TODO:ASSERT UNSUPPORTED FILE TYPE - return std::filesystem::path(); - } + //TODO Implement asset type generation + //switch (type) + //{ + //default: + // //TODO:ASSERT UNSUPPORTED FILE TYPE + // return std::filesystem::path(); + //} return std::filesystem::path(ASSET_ROOT + folder + path.filename().string()); } @@ -108,12 +109,13 @@ namespace SHADE meta.type = type; std::string folder; - switch (type) - { - default: - folder = ""; - break; - } + //TODO implement folder choosing + //switch (type) + //{ + //default: + // folder = ""; + // break; + //} AssetPath path{ ASSET_ROOT + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) }; SHAssetMetaHandler::WriteMetaData(meta); diff --git a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp index 35d167d2..6554a3e4 100644 --- a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp +++ b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp @@ -122,7 +122,7 @@ namespace SHADE break; default: - void; + break; } metaFile.close(); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h index 660d93eb..c2eb85ec 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h @@ -37,7 +37,7 @@ namespace SHADE class SHVkDescriptorSetLayout; class SHVkDescriptorSetGroup; class SHVkSampler; - class SHTextureAsset; + struct SHTextureAsset; /*---------------------------------------------------------------------------------*/ /* Type Definitions */ From 40bcea133d1089c2e060afdeda20d1b977901b0e Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sun, 2 Oct 2022 00:09:38 +0800 Subject: [PATCH 19/61] Changed texture index to 0 for both racoons --- SHADE_Application/src/Scenes/SBTestScene.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index ffecdf95..3b277e6c 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -118,7 +118,7 @@ namespace Sandbox renderable.SetMaterial(customMat); renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); - renderable.GetModifiableMaterial()->SetProperty("data.textureIndex", 1); + renderable.GetModifiableMaterial()->SetProperty("data.textureIndex", 0); transform.SetWorldPosition({ -3.0f, -1.0f, -1.0f }); transform.SetLocalScale({ 5.0f, 5.0f, 5.0f }); @@ -159,7 +159,7 @@ namespace Sandbox renderableShowcase.SetMaterial(customMat); renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); - renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 1); + renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 0); transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f }); transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f }); From 64d1c2ab2e0e07e27fd9bb129029dd1a23553b6d Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 2 Oct 2022 00:47:26 +0800 Subject: [PATCH 20/61] Minimize is now working --- SHADE_Engine/premake5.lua | 6 ++--- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 25 +++++++++++++++++++ .../MiddleEnd/PerFrame/SHRenderContext.cpp | 5 ++++ .../MiddleEnd/PerFrame/SHRenderContext.h | 1 + .../src/Graphics/Windowing/SHWindow.cpp | 2 ++ .../src/Graphics/Windowing/SHWindow.h | 2 +- SHADE_Managed/premake5.lua | 5 ++++ 7 files changed, 42 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/premake5.lua b/SHADE_Engine/premake5.lua index f11ccf79..d90d69e3 100644 --- a/SHADE_Engine/premake5.lua +++ b/SHADE_Engine/premake5.lua @@ -156,8 +156,8 @@ project "SHADE_Engine" links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"} excludes { - "%{prj.location}/src/Editor/**.cpp", - "%{prj.location}/src/Editor/**.h", - "%{prj.location}/src/Editor/**.hpp", +-- "%{prj.location}/src/Editor/**.cpp", +-- "%{prj.location}/src/Editor/**.h", +-- "%{prj.location}/src/Editor/**.hpp", } links{"fmodstudio_vc.lib", "fmod_vc.lib"} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 7aad2206..5751e7b0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -213,6 +213,15 @@ namespace SHADE /***************************************************************************/ void SHGraphicsSystem::Run(double) noexcept { + if (window->IsMinimized()) + return; + + if (renderContext.GetResized()) + { + return; + } + + // Frame data for the current frame auto const& frameData = renderContext.GetCurrentFrameData(); uint32_t frameIndex = renderContext.GetCurrentFrame(); @@ -335,6 +344,9 @@ namespace SHADE /***************************************************************************/ void SHGraphicsSystem::BeginRender() { + if (window->IsMinimized()) + return; + // Finalise all batches for (auto vp : viewports) for (auto renderer : vp->GetRenderers()) @@ -381,6 +393,16 @@ namespace SHADE /***************************************************************************/ void SHGraphicsSystem::EndRender() { + if (window->IsMinimized()) + return; + + if (renderContext.GetResized()) + { + return; + } + + + const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame(); auto& currFrameData = renderContext.GetCurrentFrameData(); @@ -513,6 +535,9 @@ namespace SHADE void SHGraphicsSystem::HandleResize(void) noexcept { + if (window->IsMinimized()) + return; + auto windowDims = window->GetWindowSize(); // Resize the swapchain diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp index f31653a8..4953447b 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp @@ -197,6 +197,11 @@ namespace SHADE return currentFrame; } + bool SHRenderContext::GetResized(void) noexcept + { + return isResized; + } + bool SHRenderContext::GetResizeAndReset(void) noexcept { bool b = isResized; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.h b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.h index 04cea4e4..afdbef2d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.h @@ -56,6 +56,7 @@ namespace SHADE SHPerFrameData& GetCurrentFrameData(void) noexcept; SHPerFrameData& GetFrameData (uint32_t index) noexcept; uint32_t GetCurrentFrame (void) const noexcept; + bool GetResized(void) noexcept; bool GetResizeAndReset (void) noexcept; }; diff --git a/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp b/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp index a4569c75..2477b111 100644 --- a/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp +++ b/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp @@ -383,6 +383,8 @@ namespace SHADE { wndData.isMinimised = true; } + else + wndData.isMinimised = false; for (auto const& entry : windowResizeCallbacks) { diff --git a/SHADE_Engine/src/Graphics/Windowing/SHWindow.h b/SHADE_Engine/src/Graphics/Windowing/SHWindow.h index 8f15bb60..9dcaedd9 100644 --- a/SHADE_Engine/src/Graphics/Windowing/SHWindow.h +++ b/SHADE_Engine/src/Graphics/Windowing/SHWindow.h @@ -125,6 +125,7 @@ namespace SHADE CALLBACKID RegisterWindowSizeCallback(WindowResizeCallbackFn); void UnregisterWindowSizeCallback(CALLBACKID const& callbackid); + bool IsMinimized() const { return wndData.isMinimised; } protected: static LRESULT CALLBACK WndProcStatic(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); @@ -165,7 +166,6 @@ namespace SHADE void OnSize(UINT msg, UINT type, SIZE size); void OnPosChange(LPWINDOWPOS pos); void OnPaint(HDC hdc, LPPAINTSTRUCT paint); - bool IsMinimized() const { return wndData.isMinimised; } }; static SHWindowMap windowMap; static SHWindow* windowBeingCreated = nullptr; diff --git a/SHADE_Managed/premake5.lua b/SHADE_Managed/premake5.lua index a7b20144..d9a47975 100644 --- a/SHADE_Managed/premake5.lua +++ b/SHADE_Managed/premake5.lua @@ -79,3 +79,8 @@ project "SHADE_Managed" optimize "On" defines{"_RELEASE"} links{"librttr_core.lib"} + + filter "configurations:Publish" + optimize "On" + defines{"_RELEASE"} + links{"librttr_core.lib"} From 201ce17a407dd61a0bedc2eb3b24d183c6f39625 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sun, 2 Oct 2022 00:56:12 +0800 Subject: [PATCH 21/61] Fixed validation errors when closing the app --- SHADE_Application/src/Application/SBApplication.cpp | 3 +++ .../src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp | 7 ++++++- .../src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 8abc341b..d0bf544d 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -136,6 +136,9 @@ namespace Sandbox SHADE::SHSystemManager::RunRoutines(false, 0.016f); } + + // Finish all graphics jobs first + graphicsSystem->AwaitGraphicsExecution(); } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 5751e7b0..fc02b994 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -552,12 +552,17 @@ namespace SHADE worldCamera->SetPerspective(90.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 100.0f); } + + void SHGraphicsSystem::AwaitGraphicsExecution() + { + device->WaitIdle(); + } void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept { window = wind; } - + /*-----------------------------------------------------------------------------------*/ /* System Routine Functions - BeginRoutine */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index a835b1bb..6ecb13f0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -251,6 +251,7 @@ namespace SHADE void BuildTextures(); void HandleResize(void) noexcept; + void AwaitGraphicsExecution(); /*-----------------------------------------------------------------------------*/ /* Setters */ From 9e8b4414d10e1fd7fb2cd89524f35301db6752c5 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Sun, 2 Oct 2022 01:00:07 +0800 Subject: [PATCH 22/61] add window close callback --- .../src/Graphics/Windowing/SHWindow.cpp | 21 +++++++++++++++++++ .../src/Graphics/Windowing/SHWindow.h | 6 ++++++ 2 files changed, 27 insertions(+) diff --git a/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp b/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp index 2477b111..1688d348 100644 --- a/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp +++ b/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp @@ -272,6 +272,17 @@ namespace SHADE windowResizeCallbacks.erase(callbackid); } + SHWindow::CALLBACKID SHWindow::RegisterWindowCloseCallback(WindowResizeCallbackFn windowCloseCallback) + { + windowCloseCallbacks.try_emplace(windowResizeCallbackCount, windowCloseCallback); + return windowCloseCallbackCount++; + } + + void SHWindow::UnregisterWindowCloseCallback(CALLBACKID const& callbackid) + { + windowCloseCallbacks.erase(callbackid); + } + LRESULT SHWindow::WndProcStatic(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { auto window = windowMap.GetWindow(hwnd); @@ -307,6 +318,8 @@ namespace SHADE case WM_CREATE: OnCreate(hwnd, reinterpret_cast(wparam)); break; + case WM_CLOSE: + case WM_DESTROY: OnDestroy(); return 0; @@ -365,6 +378,14 @@ namespace SHADE } + void SHADE::SHWindow::OnClose() + { + for (const auto& callbackFn : windowCloseCallbacks | std::views::values) + { + callbackFn(); + } + } + void SHWindow::OnDestroy() { this->Destroy(); diff --git a/SHADE_Engine/src/Graphics/Windowing/SHWindow.h b/SHADE_Engine/src/Graphics/Windowing/SHWindow.h index 9dcaedd9..b1c1067d 100644 --- a/SHADE_Engine/src/Graphics/Windowing/SHWindow.h +++ b/SHADE_Engine/src/Graphics/Windowing/SHWindow.h @@ -75,6 +75,7 @@ namespace SHADE public: using SHVec2 = std::pair; typedef std::function WindowResizeCallbackFn; + typedef std::function WindowCloseCallbackFn; typedef uint16_t CALLBACKID; SHWindow(); @@ -125,6 +126,8 @@ namespace SHADE CALLBACKID RegisterWindowSizeCallback(WindowResizeCallbackFn); void UnregisterWindowSizeCallback(CALLBACKID const& callbackid); + CALLBACKID RegisterWindowCloseCallback(WindowResizeCallbackFn); + void UnregisterWindowCloseCallback(CALLBACKID const& callbackid); bool IsMinimized() const { return wndData.isMinimised; } protected: @@ -157,10 +160,13 @@ namespace SHADE HFONT font; std::unordered_map windowResizeCallbacks; + std::unordered_map windowCloseCallbacks; CALLBACKID windowResizeCallbackCount{}; + CALLBACKID windowCloseCallbackCount{}; //TODO: Shift to events abstraction void OnCreate(HWND hwnd, LPCREATESTRUCT create_struct); + void OnClose(); void OnDestroy(); //void OnFileDrop(HDROP drop); void OnSize(UINT msg, UINT type, SIZE size); From 9fabb7d672b95c75997fbb77d727c6dc39bf869a Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 2 Oct 2022 01:13:04 +0800 Subject: [PATCH 23/61] Window can close properly (with the exception of scene graph dtor crash) --- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 13 +++++++++---- .../Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp | 10 ++++++++++ .../Graphics/MiddleEnd/PerFrame/SHRenderContext.h | 7 +++++-- SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp | 3 ++- SHADE_Engine/src/Graphics/Windowing/SHWindow.h | 2 +- 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index fc02b994..8aec5a83 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -73,6 +73,11 @@ namespace SHADE renderContext.SetIsResized(true); }); + window->RegisterWindowCloseCallback([&](void) + { + renderContext.SetWindowIsDead(true); + } + ); // Create graphics queue graphicsQueue = device->GetQueue(SH_Q_FAM::GRAPHICS, 0); transferQueue = device->GetQueue(SH_Q_FAM::TRANSFER, 0); @@ -213,7 +218,7 @@ namespace SHADE /***************************************************************************/ void SHGraphicsSystem::Run(double) noexcept { - if (window->IsMinimized()) + if (window->IsMinimized() || renderContext.GetWindowIsDead()) return; if (renderContext.GetResized()) @@ -344,7 +349,7 @@ namespace SHADE /***************************************************************************/ void SHGraphicsSystem::BeginRender() { - if (window->IsMinimized()) + if (window->IsMinimized() || renderContext.GetWindowIsDead()) return; // Finalise all batches @@ -393,7 +398,7 @@ namespace SHADE /***************************************************************************/ void SHGraphicsSystem::EndRender() { - if (window->IsMinimized()) + if (window->IsMinimized() || renderContext.GetWindowIsDead()) return; if (renderContext.GetResized()) @@ -535,7 +540,7 @@ namespace SHADE void SHGraphicsSystem::HandleResize(void) noexcept { - if (window->IsMinimized()) + if (window->IsMinimized() || renderContext.GetWindowIsDead()) return; auto windowDims = window->GetWindowSize(); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp index 4953447b..0ac7013a 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp @@ -168,6 +168,11 @@ namespace SHADE isResized = resized; } + void SHRenderContext::SetWindowIsDead(bool dead) noexcept + { + windowIsDead = dead; + } + /***************************************************************************/ /*! @@ -209,4 +214,9 @@ namespace SHADE return b; } + bool SHRenderContext::GetWindowIsDead(void) const noexcept + { + return windowIsDead; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.h b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.h index afdbef2d..bf186922 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.h @@ -36,6 +36,7 @@ namespace SHADE uint32_t currentFrame; bool isResized{ false }; + bool windowIsDead {false}; public: SHRenderContext(void) noexcept; @@ -51,13 +52,15 @@ namespace SHADE bool WaitForFence (void) noexcept; void ResetFence (void) noexcept; - void SetIsResized (bool resized) noexcept; + void SetIsResized (bool resized) noexcept; + void SetWindowIsDead (bool dead) noexcept; SHPerFrameData& GetCurrentFrameData(void) noexcept; SHPerFrameData& GetFrameData (uint32_t index) noexcept; uint32_t GetCurrentFrame (void) const noexcept; - bool GetResized(void) noexcept; + bool GetResized (void) noexcept; bool GetResizeAndReset (void) noexcept; + bool GetWindowIsDead (void) const noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp b/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp index 1688d348..f4ae3d7e 100644 --- a/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp +++ b/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp @@ -272,7 +272,7 @@ namespace SHADE windowResizeCallbacks.erase(callbackid); } - SHWindow::CALLBACKID SHWindow::RegisterWindowCloseCallback(WindowResizeCallbackFn windowCloseCallback) + SHWindow::CALLBACKID SHWindow::RegisterWindowCloseCallback(WindowCloseCallbackFn windowCloseCallback) { windowCloseCallbacks.try_emplace(windowResizeCallbackCount, windowCloseCallback); return windowCloseCallbackCount++; @@ -388,6 +388,7 @@ namespace SHADE void SHWindow::OnDestroy() { + OnClose(); this->Destroy(); } diff --git a/SHADE_Engine/src/Graphics/Windowing/SHWindow.h b/SHADE_Engine/src/Graphics/Windowing/SHWindow.h index b1c1067d..0a180285 100644 --- a/SHADE_Engine/src/Graphics/Windowing/SHWindow.h +++ b/SHADE_Engine/src/Graphics/Windowing/SHWindow.h @@ -126,7 +126,7 @@ namespace SHADE CALLBACKID RegisterWindowSizeCallback(WindowResizeCallbackFn); void UnregisterWindowSizeCallback(CALLBACKID const& callbackid); - CALLBACKID RegisterWindowCloseCallback(WindowResizeCallbackFn); + CALLBACKID RegisterWindowCloseCallback(WindowCloseCallbackFn); void UnregisterWindowCloseCallback(CALLBACKID const& callbackid); bool IsMinimized() const { return wndData.isMinimised; } From cfa07e9b3b201238063fc5fb26e13793bb3e7a7e Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sun, 2 Oct 2022 01:58:24 +0800 Subject: [PATCH 24/61] Temp fix for SceneGraph crash --- SHADE_Engine/src/Scene/SHSceneGraph.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.cpp b/SHADE_Engine/src/Scene/SHSceneGraph.cpp index da2dcffd..3fe85809 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.cpp +++ b/SHADE_Engine/src/Scene/SHSceneGraph.cpp @@ -90,10 +90,15 @@ namespace SHADE #endif // Go through the map and release all the nodes - for (auto* node : entityNodeMap | std::views::values) - ReleaseNode(node); + for (auto*& node : entityNodeMap | std::views::values) + { + delete node; + node = nullptr; + } - delete root; + entityNodeMap.clear(); + + //delete root; #ifdef _DEBUG SHLOG_INFO("Scene Graph Destroyed Successfully!") From e5df98aaa6341429bac49436278370308dfb64a4 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sun, 2 Oct 2022 01:59:56 +0800 Subject: [PATCH 25/61] Added missing move assignment and extra check for command buffer destructor --- .../src/Graphics/Commands/SHVkCommandBuffer.cpp | 2 +- .../src/Graphics/Commands/SHVkCommandPool.cpp | 2 -- .../src/Graphics/Devices/SHVkLogicalDevice.cpp | 16 ++++++++++++++++ .../src/Graphics/Devices/SHVkLogicalDevice.h | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp index eb65598c..9ebbd227 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp @@ -24,7 +24,7 @@ namespace SHADE /***************************************************************************/ SHVkCommandBuffer::~SHVkCommandBuffer(void) noexcept { - if (vkCommandBuffer) + if (vkCommandBuffer && parentPool) parentPool->GetLogicalDevice()->GetVkLogicalDevice().freeCommandBuffers(parentPool->GetVkCommandPool(), commandBufferCount, &vkCommandBuffer); } diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandPool.cpp b/SHADE_Engine/src/Graphics/Commands/SHVkCommandPool.cpp index 881ee998..e1470898 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandPool.cpp +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandPool.cpp @@ -102,8 +102,6 @@ namespace SHADE logicalDeviceHdl = rhs.logicalDeviceHdl; transient = rhs.transient; - static_cast&>(*this) = static_cast&>(rhs); - rhs.vkCommandPool = VK_NULL_HANDLE; return *this; diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index 766a27c6..3f8aa239 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -251,6 +251,22 @@ namespace SHADE vkLogicalDevice.destroy(nullptr); } + SHVkLogicalDevice& SHVkLogicalDevice::operator=(SHVkLogicalDevice&& rhs) noexcept + { + if (this == &rhs) + return *this; + + vkLogicalDevice = std::move (rhs.vkLogicalDevice); + queueFamilyIndices = std::move (rhs.queueFamilyIndices); + vmaAllocator = rhs.vmaAllocator; + nonDedicatedBestIndex = 0; + parentPhysicalDeviceHdl = rhs.parentPhysicalDeviceHdl; + + rhs.vkLogicalDevice = VK_NULL_HANDLE; + + return *this; + } + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index 1272f68f..5c400e02 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -115,7 +115,7 @@ namespace SHADE ~SHVkLogicalDevice (void) noexcept; SHVkLogicalDevice& operator= (SHVkLogicalDevice const& rhs) noexcept = default; - SHVkLogicalDevice& operator= (SHVkLogicalDevice&& rhs) noexcept = default; + SHVkLogicalDevice& operator= (SHVkLogicalDevice&& rhs) noexcept; /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER VARIABLES */ From 4771fbfb762f413a9b35934c3861c60b135d9c71 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 2 Oct 2022 02:28:50 +0800 Subject: [PATCH 26/61] WIP --- .../src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp | 2 ++ .../src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h | 1 - .../src/Graphics/MiddleEnd/Interface/SHRenderer.cpp | 8 ++++++++ .../src/Graphics/MiddleEnd/Interface/SHRenderer.h | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 8aec5a83..14768108 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -325,6 +325,8 @@ namespace SHADE void SHGraphicsSystem::Exit(void) { + //worldRenderer-> + graphicsCmdPool.Free(); renderContext.Destroy(); graphicsQueue.Free(); swapchain.Free(); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 6ecb13f0..c89e6ebc 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -286,7 +286,6 @@ namespace SHADE Handle transferQueue; Handle descPool; Handle graphicsCmdPool; - Handle transferCmdPool; Handle transferCmdBuffer; Handle graphicsTexCmdBuffer; SHRenderContext renderContext; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index 84ac3ee2..14af56ee 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -49,6 +49,14 @@ namespace SHADE cameraDescriptorSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA); } + SHRenderer::~SHRenderer(void) + { + //for (auto& cmdBuffer : commandBuffers) + //{ + // cmdBuffer.Free(); + //} + } + /*-----------------------------------------------------------------------------------*/ /* Camera Registration */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h index 5e72da85..0feea840 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h @@ -65,6 +65,7 @@ namespace SHADE /* Constructor/Destructors */ /*-----------------------------------------------------------------------------*/ SHRenderer(Handle logicalDevice, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle viewport, Handle renderGraph); + ~SHRenderer(void); /*-----------------------------------------------------------------------------*/ /* Camera Registration */ From 45514ac77e2fb599f7e2bc940b6fbf819a1c5f2f Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sun, 2 Oct 2022 03:06:13 +0800 Subject: [PATCH 27/61] Fixed warnings and errors --- .../src/Graphics/Devices/SHVkLogicalDevice.cpp | 2 +- .../src/Graphics/MiddleEnd/Batching/SHBatch.cpp | 4 ++-- .../src/Graphics/MiddleEnd/Interface/SHCamera.h | 2 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 17 ++++------------- .../Graphics/MiddleEnd/Interface/SHMaterial.h | 2 +- .../Graphics/MiddleEnd/Interface/SHViewport.cpp | 4 ++-- .../Graphics/MiddleEnd/Interface/SHViewport.h | 4 ++-- .../MiddleEnd/Meshes/SHPrimitiveGenerator.cpp | 8 ++++---- .../MiddleEnd/Textures/SHTextureLibrary.cpp | 2 +- SHADE_Engine/src/Resource/ResourceLibrary.cpp | 4 ++-- SHADE_Engine/src/Resource/ResourceLibrary.h | 2 +- 11 files changed, 21 insertions(+), 30 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index 3f8aa239..4f4f94a4 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -92,7 +92,7 @@ namespace SHADE //uint32_t minBuffer if (alignmentSize > 0) { - alignedSize = (alignedSize + alignmentSize - 1) & ~(alignmentSize - 1); + alignedSize = (alignedSize + static_cast(alignmentSize) - 1) & ~(alignmentSize - 1); } return alignedSize; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index b1cd2cd3..181c1f22 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -249,7 +249,7 @@ namespace SHADE if (!EMPTY_MAT_PROPS) { singleMatPropSize = SHADER_INFO->GetBytesRequired(); - singleMatPropAlignedSize = device->PadSSBOSize(singleMatPropSize); + singleMatPropAlignedSize = device->PadSSBOSize(static_cast(singleMatPropSize)); matPropTotalBytes = numTotalElements * singleMatPropAlignedSize; if (matPropsDataSize < matPropTotalBytes) { @@ -386,7 +386,7 @@ namespace SHADE SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, bufferList, - 0, matPropsDataSize + 0, static_cast(matPropsDataSize) ); matPropsDescSet[frameIndex]->UpdateDescriptorSetBuffer ( diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.h index c54f29ed..3a945109 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.h @@ -69,7 +69,7 @@ namespace SHADE SHMatrix inverseViewMatrix; SHMatrix inverseProjMatrix; SHMatrix inverseVpMatrix; - bool isDirty; + bool isDirty = true; /*-----------------------------------------------------------------------------*/ /* Helper Functions */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 14768108..6957aa93 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -266,8 +266,8 @@ namespace SHADE // Begin recording the command buffer currentCmdBuffer->BeginRecording(); - uint32_t w = viewports[vpIndex]->GetWidth(); - uint32_t h = viewports[vpIndex]->GetHeight(); + uint32_t w = static_cast(viewports[vpIndex]->GetWidth()); + uint32_t h = static_cast(viewports[vpIndex]->GetHeight()); currentCmdBuffer->SetViewportScissor (static_cast(w), static_cast(h), w, h); currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout()); @@ -325,15 +325,6 @@ namespace SHADE void SHGraphicsSystem::Exit(void) { - //worldRenderer-> - graphicsCmdPool.Free(); - renderContext.Destroy(); - graphicsQueue.Free(); - swapchain.Free(); - surface.Free(); - device.Free(); - - SHVkInstance::Destroy(); } /*---------------------------------------------------------------------------------*/ @@ -554,8 +545,8 @@ namespace SHADE worldRenderGraph->HandleResize(windowDims.first, windowDims.second); - defaultViewport->SetWidth(windowDims.first); - defaultViewport->SetHeight(windowDims.second); + defaultViewport->SetWidth(static_cast(windowDims.first)); + defaultViewport->SetHeight(static_cast(windowDims.second)); worldCamera->SetPerspective(90.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 100.0f); } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h index 692d857f..348efb07 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h @@ -63,7 +63,7 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ Handle pipeline; std::unique_ptr propMemory; - Byte propMemorySize; + Byte propMemorySize = 0; /*-----------------------------------------------------------------------------*/ /* Helper Functions */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp index d6eea3d7..dc534a49 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp @@ -74,12 +74,12 @@ namespace SHADE renderers.erase(iter); } - void SHViewport::SetWidth(uint32_t w) noexcept + void SHViewport::SetWidth(float w) noexcept { viewport.width = w; } - void SHViewport::SetHeight(uint32_t h) noexcept + void SHViewport::SetHeight(float h) noexcept { viewport.height = h; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h index ce992f77..221dbe7e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h @@ -65,8 +65,8 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Setters */ /*-----------------------------------------------------------------------------*/ - void SetWidth(uint32_t w) noexcept; - void SetHeight (uint32_t h) noexcept; + void SetWidth(float w) noexcept; + void SetHeight (float h) noexcept; /*-----------------------------------------------------------------------------*/ /* Getters */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.cpp index 2080265b..be181beb 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.cpp @@ -196,12 +196,12 @@ namespace SHADE static SHMeshData meshData = Cube(); return meshLibrary.AddMesh ( - meshData.VertexPositions.size(), + static_cast(meshData.VertexPositions.size()), meshData.VertexPositions.data(), meshData.VertexTexCoords.data(), meshData.VertexTangents.data(), meshData.VertexNormals.data(), - meshData.Indices.size(), + static_cast(meshData.Indices.size()), meshData.Indices.data() ); } @@ -211,12 +211,12 @@ namespace SHADE static SHMeshData meshData = Cube(); return gfxSystem.AddMesh ( - meshData.VertexPositions.size(), + static_cast(meshData.VertexPositions.size()), meshData.VertexPositions.data(), meshData.VertexTexCoords.data(), meshData.VertexTangents.data(), meshData.VertexNormals.data(), - meshData.Indices.size(), + static_cast(meshData.Indices.size()), meshData.Indices.data() ); } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp index 6a7439e5..5c315ff6 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp @@ -149,7 +149,7 @@ namespace SHADE { texOrder.emplace_back(job.TextureHandle); combinedImageSamplers.emplace_back(std::make_tuple(job.TextureHandle->ImageView, job.Sampler, vk::ImageLayout::eShaderReadOnlyOptimal)); - job.TextureHandle->TextureArrayIndex = texOrder.size() - 1; + job.TextureHandle->TextureArrayIndex = static_cast(texOrder.size()) - 1U; } addJobs.clear(); diff --git a/SHADE_Engine/src/Resource/ResourceLibrary.cpp b/SHADE_Engine/src/Resource/ResourceLibrary.cpp index 5a3ad9fe..b215b591 100644 --- a/SHADE_Engine/src/Resource/ResourceLibrary.cpp +++ b/SHADE_Engine/src/Resource/ResourceLibrary.cpp @@ -8,9 +8,9 @@ namespace SHADE ResourceManager::~ResourceManager() { // Delete all resources libraries - for (const auto& deleter : deleters) + for (auto iter = deleters.rbegin(); iter != deleters.rend(); ++iter) { - deleter(); + (*iter)(); } deleters.clear(); } diff --git a/SHADE_Engine/src/Resource/ResourceLibrary.h b/SHADE_Engine/src/Resource/ResourceLibrary.h index 4588b9fe..a5bf0a67 100644 --- a/SHADE_Engine/src/Resource/ResourceLibrary.h +++ b/SHADE_Engine/src/Resource/ResourceLibrary.h @@ -118,7 +118,7 @@ namespace SHADE /// Handle to the resource object. /// Read-only reference to the resource object. template - const T& Get(Handle handle) const; + const T& Get(Handle handle) const; private: /*-----------------------------------------------------------------------------*/ From 0dba60f9f11aaf5c1553b8f175b3e734b2b31aab Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 2 Oct 2022 03:09:09 +0800 Subject: [PATCH 28/61] Small fix --- .../src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp index e50e717f..e842df47 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp @@ -208,7 +208,7 @@ namespace SHADE BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding); // to index a set - uint32_t setIndex = setIndexing[bsHash]; + uint32_t setIndex = setIndexing[set]; // to index a write for a binding uint32_t writeInfoIndex = updater.writeHashMap[bsHash]; @@ -233,7 +233,7 @@ namespace SHADE BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding); // to index a set - uint32_t setIndex = setIndexing[bsHash]; + uint32_t setIndex = setIndexing[set]; // to index a write for a binding uint32_t writeInfoIndex = updater.writeHashMap[bsHash]; From db0b61d16f4ee77754ca9a57db0913df88797e14 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Sun, 2 Oct 2022 10:56:13 +0800 Subject: [PATCH 29/61] Reflect RB Enumeration Add RB to inspector view --- .../Inspector/SHEditorInspector.cpp | 21 ++++++++++++------- .../Components/SHRigidBodyComponent.cpp | 7 +++++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index 35836dc2..3d00ac4b 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -18,6 +18,8 @@ #include "ECS_Base/Managers/SHSystemManager.h" #include "AudioSystem/SHAudioSystem.h" +#include "Physics/Components/SHRigidBodyComponent.h" +#include "Physics/Components/SHColliderComponent.h" namespace SHADE { @@ -70,23 +72,28 @@ namespace SHADE { DrawComponent(renderableComponent); } - if(auto testComponent = SHComponentManager::GetComponent_s(eid)) + if(auto colliderComponent = SHComponentManager::GetComponent_s(eid)) { - DrawComponent(testComponent); + DrawComponent(colliderComponent); } + if(auto rigidbodyComponent = SHComponentManager::GetComponent_s(eid)) + { + DrawComponent(rigidbodyComponent); + } + ImGui::Separator(); + // Render Scripts + SHScriptEngine* scriptEngine = static_cast(SHSystemManager::GetSystem()); + scriptEngine->RenderScriptsInInspector(eid); ImGui::Separator(); if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data())) { DrawAddComponentButton(eid); DrawAddComponentButton(eid); - DrawAddComponentButton(eid); + DrawAddComponentButton(eid); + DrawAddComponentButton(eid); ImGui::EndMenu(); } - // Render Scripts - SHScriptEngine* scriptEngine = static_cast(SHSystemManager::GetSystem()); - scriptEngine->RenderScriptsInInspector(eid); - } ImGui::End(); } diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp index e2cd1e4b..5f961de4 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp @@ -390,6 +390,13 @@ RTTR_REGISTRATION using namespace SHADE; using namespace rttr; + registration::enumeration("RigidBody Type") + ( + value("Static", SHRigidBodyComponent::Type::STATIC), + value("Dynamic", SHRigidBodyComponent::Type::DYNAMIC), + value("Kinematic", SHRigidBodyComponent::Type::KINEMATIC) + ); + registration::class_("RigidBody Component") .property("Type" , &SHRigidBodyComponent::GetType , &SHRigidBodyComponent::SetType ) .property("Mass" , &SHRigidBodyComponent::GetMass , &SHRigidBodyComponent::SetMass ) From 7c4a9ca004ad951d9bd0c81a0075d296e6754373 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 10 Oct 2022 18:07:21 +0800 Subject: [PATCH 30/61] Added conversions for shade math to reactphysics math --- SHADE_Engine/src/Math/SHQuaternion.cpp | 18 ++++++ SHADE_Engine/src/Math/SHQuaternion.h | 23 +++++-- SHADE_Engine/src/Math/Vector/SHVec2.cpp | 9 +++ SHADE_Engine/src/Math/Vector/SHVec2.h | 16 ++++- SHADE_Engine/src/Math/Vector/SHVec3.cpp | 14 +++++ SHADE_Engine/src/Math/Vector/SHVec3.h | 59 ++++++++++-------- SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 23 ++----- SHADE_Engine/src/Physics/SHPhysicsObject.h | 3 - SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 64 ++++---------------- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 14 ++--- SHADE_Managed/premake5.lua | 3 +- 11 files changed, 133 insertions(+), 113 deletions(-) diff --git a/SHADE_Engine/src/Math/SHQuaternion.cpp b/SHADE_Engine/src/Math/SHQuaternion.cpp index a6428d30..8463a7c2 100644 --- a/SHADE_Engine/src/Math/SHQuaternion.cpp +++ b/SHADE_Engine/src/Math/SHQuaternion.cpp @@ -67,6 +67,19 @@ namespace SHADE XMStoreFloat4(this, XMQuaternionRotationMatrix(M)); } + SHQuaternion::SHQuaternion(const reactphysics3d::Vector3& rp3dEuler) noexcept + : XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) + { + const SHVec3& SHADE_VEC{ rp3dEuler }; + + const XMVECTOR V = XMLoadFloat3(&SHADE_VEC); + XMStoreFloat4(this, XMQuaternionRotationRollPitchYawFromVector(V)); + } + + SHQuaternion::SHQuaternion(const reactphysics3d::Quaternion& rp3dQuat) noexcept + : XMFLOAT4( rp3dQuat.x, rp3dQuat.y, rp3dQuat.z, rp3dQuat.w ) + {} + /*-----------------------------------------------------------------------------------*/ /* Operator Overload Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -176,6 +189,11 @@ namespace SHADE return XMQuaternionNotEqual(Q1, Q2); } + SHQuaternion::operator reactphysics3d::Quaternion() const noexcept + { + return reactphysics3d::Quaternion{ x, y, z, w }; + } + SHQuaternion operator*(float lhs, const SHQuaternion& rhs) noexcept { return rhs * lhs; diff --git a/SHADE_Engine/src/Math/SHQuaternion.h b/SHADE_Engine/src/Math/SHQuaternion.h index 61b55ef9..01452cef 100644 --- a/SHADE_Engine/src/Math/SHQuaternion.h +++ b/SHADE_Engine/src/Math/SHQuaternion.h @@ -11,6 +11,8 @@ #pragma once #include +#include + #include // Project Headers @@ -46,12 +48,17 @@ namespace SHADE SHQuaternion (const SHQuaternion& rhs) = default; SHQuaternion (SHQuaternion&& rhs) = default; - SHQuaternion () noexcept; - SHQuaternion (float x, float y, float z, float w) noexcept; - SHQuaternion (float yaw, float pitch, float roll) noexcept; - SHQuaternion (const SHVec3& eulerAngles) noexcept; - SHQuaternion (const SHVec3& axis, float angleInRad) noexcept; - SHQuaternion (const SHMatrix& rotationMatrix) noexcept; + SHQuaternion () noexcept; + SHQuaternion (float x, float y, float z, float w) noexcept; + SHQuaternion (float yaw, float pitch, float roll) noexcept; + SHQuaternion (const SHVec3& eulerAngles) noexcept; + SHQuaternion (const SHVec3& axis, float angleInRad) noexcept; + SHQuaternion (const SHMatrix& rotationMatrix) noexcept; + + // Conversion from other math types + + SHQuaternion (const reactphysics3d::Vector3& rp3dEuler) noexcept; + SHQuaternion (const reactphysics3d::Quaternion& rp3dQuat) noexcept; /*---------------------------------------------------------------------------------*/ /* Operator Overloads */ @@ -76,6 +83,10 @@ namespace SHADE [[nodiscard]] bool operator== (const SHQuaternion& rhs) const noexcept; [[nodiscard]] bool operator!= (const SHQuaternion& rhs) const noexcept; + // Conversion to other math types used by SHADE + + operator reactphysics3d::Quaternion () const noexcept; + /*---------------------------------------------------------------------------------*/ /* Getter Functions */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Math/Vector/SHVec2.cpp b/SHADE_Engine/src/Math/Vector/SHVec2.cpp index 545492cb..c417a1b2 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec2.cpp +++ b/SHADE_Engine/src/Math/Vector/SHVec2.cpp @@ -46,6 +46,10 @@ namespace SHADE : XMFLOAT2( _x, _y ) {} + SHVec2::SHVec2(const reactphysics3d::Vector2& rp3dVec2) noexcept + : XMFLOAT2( rp3dVec2.x, rp3dVec2.y ) + {} + /*-----------------------------------------------------------------------------------*/ /* Operator Overload Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -213,6 +217,11 @@ namespace SHADE } } + SHVec2::operator reactphysics3d::Vector2() const noexcept + { + return reactphysics3d::Vector2{ x, y }; + } + SHVec2 operator* (float lhs, const SHVec2& rhs) noexcept { SHVec2 result; diff --git a/SHADE_Engine/src/Math/Vector/SHVec2.h b/SHADE_Engine/src/Math/Vector/SHVec2.h index 17642126..5f2f50e2 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec2.h +++ b/SHADE_Engine/src/Math/Vector/SHVec2.h @@ -11,6 +11,8 @@ #pragma once #include +#include + #include #include @@ -52,9 +54,13 @@ namespace SHADE SHVec2 (SHVec2&& rhs) = default; ~SHVec2 () = default; - SHVec2 () noexcept; - SHVec2 (float n) noexcept; - SHVec2 (float x, float y) noexcept; + SHVec2 () noexcept; + SHVec2 (float n) noexcept; + SHVec2 (float x, float y) noexcept; + + // Conversion from other math types to SHADE + + SHVec2 (const reactphysics3d::Vector2& rp3dVec2) noexcept; /*---------------------------------------------------------------------------------*/ /* Operator Overloads */ @@ -86,6 +92,10 @@ namespace SHADE [[nodiscard]] float operator[] (int index) const; [[nodiscard]] float operator[] (size_t index) const; + // Conversion to other math types used by SHADE + + operator reactphysics3d::Vector2 () const noexcept; + /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Math/Vector/SHVec3.cpp b/SHADE_Engine/src/Math/Vector/SHVec3.cpp index 1bcb47b3..2d86276b 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec3.cpp +++ b/SHADE_Engine/src/Math/Vector/SHVec3.cpp @@ -51,6 +51,10 @@ namespace SHADE : XMFLOAT3( _x, _y, _z ) {} + SHVec3::SHVec3(const reactphysics3d::Vector3& rp3dVec3) noexcept + : XMFLOAT3( rp3dVec3.x, rp3dVec3.y, rp3dVec3.z ) + {} + /*-----------------------------------------------------------------------------------*/ /* Operator Overload Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -223,6 +227,16 @@ namespace SHADE } } + SHVec3::operator reactphysics3d::Vector3() const noexcept + { + return reactphysics3d::Vector3{ x, y , z }; + } + + SHVec3::operator reactphysics3d::Quaternion() const noexcept + { + return reactphysics3d::Quaternion::fromEulerAngles(x, y, z); + } + SHVec3 operator* (float lhs, const SHVec3& rhs) noexcept { SHVec3 result; diff --git a/SHADE_Engine/src/Math/Vector/SHVec3.h b/SHADE_Engine/src/Math/Vector/SHVec3.h index cc0e043e..03a3578f 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec3.h +++ b/SHADE_Engine/src/Math/Vector/SHVec3.h @@ -11,6 +11,9 @@ #pragma once #include +#include +#include + #include #include @@ -57,40 +60,48 @@ namespace SHADE SHVec3 (SHVec3&& rhs) = default; ~SHVec3 () = default; - SHVec3 () noexcept; - SHVec3 (float n) noexcept; - SHVec3 (float x, float y, float z) noexcept; + SHVec3 () noexcept; + SHVec3 (float n) noexcept; + SHVec3 (float x, float y, float z) noexcept; + + // Conversion from other math types to SHADE + + SHVec3 (const reactphysics3d::Vector3& rp3dVec3) noexcept; /*---------------------------------------------------------------------------------*/ /* Operator Overloads */ /*---------------------------------------------------------------------------------*/ - SHVec3& operator= (const SHVec3& rhs) = default; - SHVec3& operator= (SHVec3&& rhs) = default; + SHVec3& operator= (const SHVec3& rhs) = default; + SHVec3& operator= (SHVec3&& rhs) = default; - SHVec3& operator+= (const SHVec3& rhs) noexcept; - SHVec3& operator-= (const SHVec3& rhs) noexcept; - SHVec3& operator*= (const SHVec3& rhs) noexcept; - SHVec3& operator*= (float rhs) noexcept; - SHVec3& operator/= (const SHVec3& rhs) noexcept; - SHVec3& operator/= (float rhs) noexcept; + SHVec3& operator+= (const SHVec3& rhs) noexcept; + SHVec3& operator-= (const SHVec3& rhs) noexcept; + SHVec3& operator*= (const SHVec3& rhs) noexcept; + SHVec3& operator*= (float rhs) noexcept; + SHVec3& operator/= (const SHVec3& rhs) noexcept; + SHVec3& operator/= (float rhs) noexcept; - [[nodiscard]] SHVec3 operator+ (const SHVec3& rhs) const noexcept; - [[nodiscard]] SHVec3 operator- (const SHVec3& rhs) const noexcept; - [[nodiscard]] SHVec3 operator- () const noexcept; - [[nodiscard]] SHVec3 operator* (const SHVec3& rhs) const noexcept; - [[nodiscard]] SHVec3 operator* (float rhs) const noexcept; - [[nodiscard]] SHVec3 operator/ (const SHVec3& rhs) const noexcept; - [[nodiscard]] SHVec3 operator/ (float rhs) const noexcept; + [[nodiscard]] SHVec3 operator+ (const SHVec3& rhs) const noexcept; + [[nodiscard]] SHVec3 operator- (const SHVec3& rhs) const noexcept; + [[nodiscard]] SHVec3 operator- () const noexcept; + [[nodiscard]] SHVec3 operator* (const SHVec3& rhs) const noexcept; + [[nodiscard]] SHVec3 operator* (float rhs) const noexcept; + [[nodiscard]] SHVec3 operator/ (const SHVec3& rhs) const noexcept; + [[nodiscard]] SHVec3 operator/ (float rhs) const noexcept; - [[nodiscard]] bool operator== (const SHVec3& rhs) const noexcept; - [[nodiscard]] bool operator!= (const SHVec3& rhs) const noexcept; + [[nodiscard]] bool operator== (const SHVec3& rhs) const noexcept; + [[nodiscard]] bool operator!= (const SHVec3& rhs) const noexcept; - [[nodiscard]] float& operator[] (int index); - [[nodiscard]] float& operator[] (size_t index); - [[nodiscard]] float operator[] (int index) const; - [[nodiscard]] float operator[] (size_t index) const; + [[nodiscard]] float& operator[] (int index); + [[nodiscard]] float& operator[] (size_t index); + [[nodiscard]] float operator[] (int index) const; + [[nodiscard]] float operator[] (size_t index) const; + // Conversion to other math types used by SHADE + + operator reactphysics3d::Vector3 () const noexcept; + operator reactphysics3d::Quaternion () const noexcept; /*---------------------------------------------------------------------------------*/ /* Function Members */ diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index 844803b1..1188ae40 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -44,10 +44,7 @@ namespace SHADE SHVec3 result; if (rp3dBody) - { - const auto& RP3D_RESULT = rp3dBody->getTransform().getPosition(); - result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z }; - } + result = SHVec3{ rp3dBody->getTransform().getPosition() }; return result; } @@ -57,10 +54,7 @@ namespace SHADE SHQuaternion result; if (rp3dBody) - { - const auto& RP3D_RESULT = rp3dBody->getTransform().getOrientation(); - result = SHQuaternion{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z, RP3D_RESULT.w }; - } + result = SHQuaternion{ rp3dBody->getTransform().getOrientation() }; return result; } @@ -70,10 +64,7 @@ namespace SHADE SHVec3 result; if (rp3dBody) - { - const auto& RP3D_RESULT = rp3dBody->getTransform().getOrientation(); - result = SHQuaternion{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z, RP3D_RESULT.w }.ToEuler(); - } + result = SHQuaternion{ rp3dBody->getTransform().getOrientation() }.ToEuler(); return result; } @@ -84,10 +75,8 @@ namespace SHADE void SHPhysicsObject::SetPosition(const SHVec3& position) noexcept { - const rp3d::Vector3 RP3D_POS { position.x, position.y, position.z }; - rp3d::Transform rp3dTF; - rp3dTF.setPosition(RP3D_POS); + rp3dTF.setPosition(position); rp3dTF.setOrientation(rp3dBody->getTransform().getOrientation()); rp3dBody->setTransform(rp3dTF); @@ -96,11 +85,9 @@ namespace SHADE void SHPhysicsObject::SetOrientation(const SHQuaternion& orientation) noexcept { - const rp3d::Quaternion RP3D_ORIENTATION { orientation.x, orientation.y, orientation.z, orientation.w }; - rp3d::Transform rp3dTF; rp3dTF.setPosition(rp3dBody->getTransform().getPosition()); - rp3dTF.setOrientation(RP3D_ORIENTATION); + rp3dTF.setOrientation(orientation); rp3dBody->setTransform(rp3dTF); prevTransform = rp3dTF; diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.h b/SHADE_Engine/src/Physics/SHPhysicsObject.h index cdff2f5b..6002d697 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.h @@ -82,8 +82,5 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ - - - }; } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index f3a4c276..1fb8232e 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -68,10 +68,7 @@ namespace SHADE if (world) { - const auto RP3D_GRAVITY = world->getGravity(); - result.x = RP3D_GRAVITY.x; - result.y = RP3D_GRAVITY.y; - result.z = RP3D_GRAVITY.z; + result = world->getGravity(); } else { @@ -112,8 +109,7 @@ namespace SHADE { if (world) { - const rp3d::Vector3 G { gravity.x, gravity.y, gravity.z }; - world->setGravity(G); + world->setGravity(gravity); } else { @@ -161,8 +157,7 @@ namespace SHADE { if (world) { - const rp3d::Vector3 G { settings.gravity.x, settings.gravity.y, settings.gravity.z }; - world->setGravity(G); + world->setGravity(settings.gravity); world->setNbIterationsVelocitySolver(settings.numVelocitySolverIterations); world->setNbIterationsPositionSolver(settings.numPositionSolverIterations); world->enableSleeping(settings.sleepingEnabled); @@ -225,13 +220,7 @@ namespace SHADE SHADE_TF = SHComponentManager::GetComponent(entityID); } - const SHVec3& SHADE_POS = SHADE_TF->GetWorldPosition(); - const SHVec3& SHADE_ROT = SHADE_TF->GetWorldRotation(); - - const rp3d::Vector3 RP3D_POS { SHADE_POS.x, SHADE_POS.y, SHADE_POS.z }; - const rp3d::Quaternion RP3D_ROT = rp3d::Quaternion::fromEulerAngles( SHADE_ROT.x, SHADE_ROT.y, SHADE_ROT.z ); - - const rp3d::Transform RP3D_TF { RP3D_POS, RP3D_ROT }; + const rp3d::Transform RP3D_TF { SHADE_TF->GetWorldPosition(), SHADE_TF->GetWorldRotation() }; // If collider already exists if (physicsObject->hasColliders) @@ -251,10 +240,7 @@ namespace SHADE case SHCollider::Type::BOX: { SHBoundingBox* box = reinterpret_cast(collider.GetShape()); - const SHVec3& SHADE_EXTENTS = box->GetHalfExtents(); - - rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z }; - rp3d::BoxShape* newBox = factory.createBoxShape(RP3D_EXTENTS); + rp3d::BoxShape* newBox = factory.createBoxShape(box->GetHalfExtents()); // TODO(Diren): Handle offsets physicsObject->rp3dBody->addCollider(newBox, RP3D_TF); @@ -296,13 +282,7 @@ namespace SHADE SHADE_TF = SHComponentManager::GetComponent(entityID); } - const SHVec3& SHADE_POS = SHADE_TF->GetWorldPosition(); - const SHVec3& SHADE_ROT = SHADE_TF->GetWorldRotation(); - - const rp3d::Vector3 RP3D_POS { SHADE_POS.x, SHADE_POS.y, SHADE_POS.z }; - const rp3d::Quaternion RP3D_ROT = rp3d::Quaternion::fromEulerAngles( SHADE_ROT.x, SHADE_ROT.y, SHADE_ROT.z ); - - const rp3d::Transform RP3D_TF { RP3D_POS, RP3D_ROT }; + const rp3d::Transform RP3D_TF { SHADE_TF->GetWorldPosition(), SHADE_TF->GetWorldRotation() }; // No rb if (!physicsObject->isRigidBody) @@ -316,10 +296,7 @@ namespace SHADE case SHCollider::Type::BOX: { SHBoundingBox* box = reinterpret_cast(collider.GetShape()); - const SHVec3& SHADE_EXTENTS = box->GetHalfExtents(); - - rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z }; - rp3d::BoxShape* newBox = factory.createBoxShape(RP3D_EXTENTS); + rp3d::BoxShape* newBox = factory.createBoxShape(box->GetHalfExtents()); // TODO(Diren): Handle offsets physicsObject->rp3dBody->addCollider(newBox, RP3D_TF); @@ -401,10 +378,7 @@ namespace SHADE case SHShape::Type::BOUNDING_BOX: { auto* box = reinterpret_cast(shape); - const SHVec3& SHADE_EXTENTS = box->GetHalfExtents(); - - rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z }; - rp3d::BoxShape* newBox = factory.createBoxShape(RP3D_EXTENTS); + rp3d::BoxShape* newBox = factory.createBoxShape(box->GetHalfExtents()); // TODO(Diren): Handle offsets @@ -593,12 +567,9 @@ namespace SHADE } // Convert RP3D Transform to SHADE - const SHVec3 SHADE_POS = SHVec3{ rp3dPos.x, rp3dPos.y, rp3dPos.z }; - const SHVec3 SHADE_ROT = SHQuaternion{ rp3dRot.x, rp3dRot.y, rp3dRot.z, rp3dRot.w }.ToEuler(); - auto* tfComponent = SHComponentManager::GetComponent(ENTITY_ID); - tfComponent->SetWorldPosition(SHADE_POS); - tfComponent->SetWorldRotation(SHADE_ROT); + tfComponent->SetWorldPosition(rp3dPos); + tfComponent->SetWorldRotation(SHQuaternion{ rp3dRot }.ToEuler()); // Cache transforms physicsObject.prevTransform = CURRENT_TF; @@ -660,18 +631,12 @@ namespace SHADE } case 8: // Linear Velocity { - const SHVec3& SHADE_VEL = comp->GetLinearVelocity(); - rp3d::Vector3 RP3D_VEL { SHADE_VEL.x, SHADE_VEL.y, SHADE_VEL.z }; - - rigidBody->setLinearVelocity(RP3D_VEL); + rigidBody->setLinearVelocity(comp->GetLinearVelocity()); break; } case 9: // Angular Velocity { - const SHVec3& SHADE_VEL = comp->GetAngularVelocity(); - rp3d::Vector3 RP3D_VEL { SHADE_VEL.x, SHADE_VEL.y, SHADE_VEL.z }; - - rigidBody->setAngularVelocity(RP3D_VEL); + rigidBody->setAngularVelocity(comp->GetAngularVelocity()); break; } default: break; @@ -718,12 +683,9 @@ namespace SHADE case SHCollider::Type::BOX: { SHBoundingBox* box = reinterpret_cast(collider.GetShape()); - const SHVec3& SHADE_EXTENTS = box->GetHalfExtents(); - - rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z }; auto* rp3dBoxShape = reinterpret_cast(physicsObject->rp3dBody->getCollider(index)->getCollisionShape()); - rp3dBoxShape->setHalfExtents(RP3D_EXTENTS); + rp3dBoxShape->setHalfExtents(box->GetHalfExtents()); if (rp3dBoxShape) { diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index 4eaf4a89..92a4730d 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -185,18 +185,18 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ - SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; + SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; - void SyncRigidBodyComponents (std::vector& denseArray) noexcept; - void SyncColliderComponents (std::vector& denseArray) noexcept; - void SyncTransforms () noexcept; + void SyncRigidBodyComponents (std::vector& denseArray) noexcept; + void SyncColliderComponents (std::vector& denseArray) noexcept; + void SyncTransforms () noexcept; // TODO(Diren): Trigger handling static void SyncRigidBody (SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept; - static void SetRP3DLinearConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept; - static void SetRP3DAngularConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept; + static void SetRP3DLinearConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept; + static void SetRP3DAngularConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept; - static void SyncCollider (SHPhysicsObject const* physicsObject, SHColliderComponent* comp) noexcept; + static void SyncCollider (SHPhysicsObject const* physicsObject, SHColliderComponent* comp) noexcept; }; diff --git a/SHADE_Managed/premake5.lua b/SHADE_Managed/premake5.lua index 052be24a..6d37122c 100644 --- a/SHADE_Managed/premake5.lua +++ b/SHADE_Managed/premake5.lua @@ -30,8 +30,9 @@ project "SHADE_Managed" "%{IncludeDir.imguizmo}", "%{IncludeDir.imnodes}", "%{IncludeDir.yamlcpp}", - "%{IncludeDir.RTTR}/include", + "%{IncludeDir.RTTR}/include", "%{IncludeDir.dotnet}\\include", + "%{IncludeDir.reactphysics3d}\\include", "%{wks.location}/SHADE_Engine/src" } From 46a082b62efab28def786201e204ac07b2c5492b Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 10 Oct 2022 21:13:14 +0800 Subject: [PATCH 31/61] Moved rigidbody creation into physics object --- .../src/Math/Geometry/SHBoundingBox.cpp | 14 +-- SHADE_Engine/src/Math/Geometry/SHShape.h | 2 +- SHADE_Engine/src/Math/SHQuaternion.cpp | 5 ++ SHADE_Engine/src/Math/SHQuaternion.h | 1 + SHADE_Engine/src/Math/Vector/SHVec3.cpp | 5 ++ SHADE_Engine/src/Math/Vector/SHVec3.h | 9 +- .../Physics/Components/SHColliderComponent.h | 6 ++ .../Components/SHRigidBodyComponent.cpp | 6 +- .../Physics/Components/SHRigidBodyComponent.h | 9 +- SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 85 ++++++++++++++++-- SHADE_Engine/src/Physics/SHPhysicsObject.h | 37 +++++--- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 90 +++++++++---------- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 14 ++- 13 files changed, 198 insertions(+), 85 deletions(-) diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp index 3abcc315..9068fe42 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp @@ -26,13 +26,13 @@ namespace SHADE , center { c } , halfExtents { hE } { - type = Type::BOUNDING_BOX; + type = Type::BOX; } SHBoundingBox::SHBoundingBox(const SHVec3* vertices, size_t numVertices) noexcept : SHShape {} { - type = Type::BOUNDING_BOX; + type = Type::BOX; if (vertices == nullptr || numVertices < 2) { @@ -63,7 +63,7 @@ namespace SHADE SHBoundingBox::SHBoundingBox(const SHBoundingBox* boxes, size_t numBoxes) noexcept : SHShape {} { - type = Type::BOUNDING_BOX; + type = Type::BOX; if (boxes == nullptr || numBoxes == 0) { @@ -83,7 +83,7 @@ namespace SHADE , center { rhs.center } , halfExtents { rhs.halfExtents } { - type = Type::BOUNDING_BOX; + type = Type::BOX; } SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept @@ -91,12 +91,12 @@ namespace SHADE , center { rhs.center } , halfExtents { rhs.halfExtents } { - type = Type::BOUNDING_BOX; + type = Type::BOX; } SHBoundingBox& SHBoundingBox::operator=(const SHBoundingBox& rhs) noexcept { - if (rhs.type != Type::BOUNDING_BOX) + if (rhs.type != Type::BOX) { SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!") } @@ -111,7 +111,7 @@ namespace SHADE SHBoundingBox& SHBoundingBox::operator=(SHBoundingBox&& rhs) noexcept { - if (rhs.type != Type::BOUNDING_BOX) + if (rhs.type != Type::BOX) { SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!") } diff --git a/SHADE_Engine/src/Math/Geometry/SHShape.h b/SHADE_Engine/src/Math/Geometry/SHShape.h index e33ca583..8efece09 100644 --- a/SHADE_Engine/src/Math/Geometry/SHShape.h +++ b/SHADE_Engine/src/Math/Geometry/SHShape.h @@ -29,7 +29,7 @@ namespace SHADE enum class Type { - BOUNDING_BOX + BOX , SPHERE , CAPSULE , CONVEX_HULL diff --git a/SHADE_Engine/src/Math/SHQuaternion.cpp b/SHADE_Engine/src/Math/SHQuaternion.cpp index 8463a7c2..33c568a5 100644 --- a/SHADE_Engine/src/Math/SHQuaternion.cpp +++ b/SHADE_Engine/src/Math/SHQuaternion.cpp @@ -194,6 +194,11 @@ namespace SHADE return reactphysics3d::Quaternion{ x, y, z, w }; } + SHQuaternion::operator reactphysics3d::Vector3() const noexcept + { + return reactphysics3d::Vector3{ ToEuler() }; + } + SHQuaternion operator*(float lhs, const SHQuaternion& rhs) noexcept { return rhs * lhs; diff --git a/SHADE_Engine/src/Math/SHQuaternion.h b/SHADE_Engine/src/Math/SHQuaternion.h index 01452cef..c94907b5 100644 --- a/SHADE_Engine/src/Math/SHQuaternion.h +++ b/SHADE_Engine/src/Math/SHQuaternion.h @@ -86,6 +86,7 @@ namespace SHADE // Conversion to other math types used by SHADE operator reactphysics3d::Quaternion () const noexcept; + operator reactphysics3d::Vector3 () const noexcept; /*---------------------------------------------------------------------------------*/ /* Getter Functions */ diff --git a/SHADE_Engine/src/Math/Vector/SHVec3.cpp b/SHADE_Engine/src/Math/Vector/SHVec3.cpp index 2d86276b..8ec91fb8 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec3.cpp +++ b/SHADE_Engine/src/Math/Vector/SHVec3.cpp @@ -14,6 +14,7 @@ #include "SHVec3.h" // Project Headers #include "Math/SHMatrix.h" +#include "Math/SHQuaternion.h" #include "Tools/SHLogger.h" using namespace DirectX; @@ -55,6 +56,10 @@ namespace SHADE : XMFLOAT3( rp3dVec3.x, rp3dVec3.y, rp3dVec3.z ) {} + SHVec3::SHVec3(const reactphysics3d::Quaternion& rp3dVec3) noexcept + : XMFLOAT3( SHQuaternion{rp3dVec3}.ToEuler() ) + {} + /*-----------------------------------------------------------------------------------*/ /* Operator Overload Definitions */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Math/Vector/SHVec3.h b/SHADE_Engine/src/Math/Vector/SHVec3.h index 03a3578f..7badf6cd 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec3.h +++ b/SHADE_Engine/src/Math/Vector/SHVec3.h @@ -60,13 +60,14 @@ namespace SHADE SHVec3 (SHVec3&& rhs) = default; ~SHVec3 () = default; - SHVec3 () noexcept; - SHVec3 (float n) noexcept; - SHVec3 (float x, float y, float z) noexcept; + SHVec3 () noexcept; + SHVec3 (float n) noexcept; + SHVec3 (float x, float y, float z) noexcept; // Conversion from other math types to SHADE - SHVec3 (const reactphysics3d::Vector3& rp3dVec3) noexcept; + SHVec3 (const reactphysics3d::Vector3& rp3dVec3) noexcept; + SHVec3 (const reactphysics3d::Quaternion& rp3dVec3) noexcept; /*---------------------------------------------------------------------------------*/ /* Operator Overloads */ diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.h b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h index cb9696d9..fd4bcb9a 100644 --- a/SHADE_Engine/src/Physics/Components/SHColliderComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h @@ -16,6 +16,11 @@ #include "ECS_Base/Components/SHComponent.h" #include "Physics/SHCollider.h" +//namespace SHADE +//{ +// class SHPhysicsSystem; +//} + namespace SHADE { /*-----------------------------------------------------------------------------------*/ @@ -30,6 +35,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ friend class SHPhysicsSystem; + friend class SHPhysicsObject; /*---------------------------------------------------------------------------------*/ /* Type Definitions */ diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp index 5f961de4..e5938717 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp @@ -392,9 +392,9 @@ RTTR_REGISTRATION registration::enumeration("RigidBody Type") ( - value("Static", SHRigidBodyComponent::Type::STATIC), - value("Dynamic", SHRigidBodyComponent::Type::DYNAMIC), - value("Kinematic", SHRigidBodyComponent::Type::KINEMATIC) + value("Static", SHRigidBodyComponent::Type::STATIC), + value("Kinematic", SHRigidBodyComponent::Type::KINEMATIC), + value("Dynamic", SHRigidBodyComponent::Type::DYNAMIC) ); registration::class_("RigidBody Component") diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h index 0793b2ff..285df810 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h @@ -14,7 +14,13 @@ // Project Headers #include "ECS_Base/Components/SHComponent.h" -#include "Physics/SHPhysicsObject.h" +#include "Math/Vector/SHVec3.h" +#include "Math/SHQuaternion.h" + +//namespace SHADE +//{ +// class SHPhysicsSystem; +//} namespace SHADE { @@ -30,6 +36,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ friend class SHPhysicsSystem; + friend class SHPhysicsObject; public: /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index 1188ae40..a007c5fe 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -15,7 +15,8 @@ // Project Headers #include "ECS_Base/Managers/SHSystemManager.h" -#include "SHPhysicsSystem.h" +#include "ECS_Base/Managers/SHComponentManager.h" + namespace SHADE { @@ -23,16 +24,20 @@ namespace SHADE /* Constructors & Destructor Definitions */ /*-----------------------------------------------------------------------------------*/ - SHPhysicsObject::SHPhysicsObject() noexcept - : entityID { MAX_EID } + SHPhysicsObject::SHPhysicsObject(EntityID eid, rp3d::PhysicsCommon* physicsFactory, rp3d::PhysicsWorld* physicsWorld) noexcept + : entityID { eid } , isRigidBody { false } , hasColliders{ false } + , factory { physicsFactory } + , world { physicsWorld } , rp3dBody { nullptr } {} SHPhysicsObject::~SHPhysicsObject() noexcept { - rp3dBody = nullptr; + factory = nullptr; + world = nullptr; + rp3dBody = nullptr; } /*-----------------------------------------------------------------------------------*/ @@ -75,6 +80,12 @@ namespace SHADE void SHPhysicsObject::SetPosition(const SHVec3& position) noexcept { + if (!rp3dBody) + { + SHLOG_ERROR("Cannot set position of a non-existent physics body for Entity {}", entityID) + return; + } + rp3d::Transform rp3dTF; rp3dTF.setPosition(position); rp3dTF.setOrientation(rp3dBody->getTransform().getOrientation()); @@ -85,6 +96,12 @@ namespace SHADE void SHPhysicsObject::SetOrientation(const SHQuaternion& orientation) noexcept { + if (!rp3dBody) + { + SHLOG_ERROR("Cannot set orientation of a non-existent physics body for Entity {}", entityID) + return; + } + rp3d::Transform rp3dTF; rp3dTF.setPosition(rp3dBody->getTransform().getPosition()); rp3dTF.setOrientation(orientation); @@ -95,14 +112,70 @@ namespace SHADE void SHPhysicsObject::SetRotation(const SHVec3& rotation) noexcept { - const rp3d::Quaternion RP3D_ORIENTATION = rp3d::Quaternion::fromEulerAngles( rotation.x, rotation.y, rotation.z ); + if (!rp3dBody) + { + SHLOG_ERROR("Cannot set rotation of a non-existent physics body for Entity {}", entityID) + return; + } rp3d::Transform rp3dTF; rp3dTF.setPosition(rp3dBody->getTransform().getPosition()); - rp3dTF.setOrientation(RP3D_ORIENTATION); + rp3dTF.setOrientation(rotation); rp3dBody->setTransform(rp3dTF); prevTransform = rp3dTF; } + /*-----------------------------------------------------------------------------------*/ + /* Public Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHPhysicsObject::CreateRigidBody(const SHTransformComponent* tf, SHRigidBodyComponent* rb, SHColliderComponent* c) + { + // If collider already exists + if (hasColliders) + world->destroyCollisionBody(rp3dBody); + + rp3dBody = world->createRigidBody(rp3d::Transform{ tf->GetWorldPosition(), tf->GetWorldRotation() }); + isRigidBody = true; + + rb->position = tf->GetWorldPosition(); + rb->orientation = tf->GetWorldRotation(); + } + + void SHPhysicsObject::DestroyRigidBody() noexcept + { + + } + + void SHPhysicsObject::CreateCollisionBody(const SHTransformComponent* tf, SHColliderComponent* c) + { + + } + + void SHPhysicsObject::DestroyCollisionBody() noexcept + { + + } + + int SHPhysicsObject::AddCollider(SHCollider* collider) + { + return 0; + } + + void SHPhysicsObject::RemoveCollider(int index) noexcept + { + + } + + void SHPhysicsObject::SyncRigidBody() noexcept + { + + } + + void SHPhysicsObject::SyncColliders() noexcept + { + + } + } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.h b/SHADE_Engine/src/Physics/SHPhysicsObject.h index 6002d697..c6ecd250 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.h @@ -13,9 +13,9 @@ #include // Project Headers -#include "Math/Vector/SHVec3.h" -#include "Math/SHQuaternion.h" -#include "ECS_Base/Entity/SHEntity.h" +#include "Math/Transform/SHTransformComponent.h" +#include "Components/SHRigidBodyComponent.h" +#include "Components/SHColliderComponent.h" namespace SHADE { @@ -31,15 +31,13 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ friend class SHPhysicsSystem; - friend class SHRigidBodyComponent; - friend class SHColliderComponent; public: /*---------------------------------------------------------------------------------*/ /* Constructors & Destructor */ /*---------------------------------------------------------------------------------*/ - SHPhysicsObject () noexcept; + SHPhysicsObject (EntityID eid, rp3d::PhysicsCommon* physicsFactory, rp3d::PhysicsWorld* physicsWorld) noexcept; SHPhysicsObject (const SHPhysicsObject& rhs) noexcept = default; SHPhysicsObject (SHPhysicsObject&& rhs) noexcept = default; virtual ~SHPhysicsObject () noexcept; @@ -63,9 +61,24 @@ namespace SHADE /* Setter Functions */ /*---------------------------------------------------------------------------------*/ - void SetPosition (const SHVec3& position) noexcept; - void SetOrientation (const SHQuaternion& orientation) noexcept; - void SetRotation (const SHVec3& rotation) noexcept; + void SetPosition (const SHVec3& position) noexcept; + void SetOrientation (const SHQuaternion& orientation) noexcept; + void SetRotation (const SHVec3& rotation) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + void CreateRigidBody (const SHTransformComponent* tf, SHRigidBodyComponent* rb, SHColliderComponent* c); + void DestroyRigidBody () noexcept; + + void CreateCollisionBody (const SHTransformComponent* tf, SHColliderComponent* c); + int AddCollider (SHCollider* collider); + void RemoveCollider (int index) noexcept; + void DestroyCollisionBody () noexcept; + + void SyncRigidBody () noexcept; + void SyncColliders () noexcept; private: /*---------------------------------------------------------------------------------*/ @@ -76,11 +89,9 @@ namespace SHADE bool isRigidBody; bool hasColliders; + rp3d::PhysicsCommon* factory; + rp3d::PhysicsWorld* world; rp3d::CollisionBody* rp3dBody; // Can be either a collision body or a rigid body rp3d::Transform prevTransform; // Cached transform for interpolation - - /*---------------------------------------------------------------------------------*/ - /* Function Members */ - /*---------------------------------------------------------------------------------*/ }; } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 1fb8232e..38c7e19c 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -204,32 +204,18 @@ namespace SHADE // Check if entity is already a physics object auto* physicsObject = GetPhysicsObject(entityID); + if (!physicsObject) - { - physicsObject = &(map.emplace(entityID, SHPhysicsObject{}).first->second); - physicsObject->entityID = entityID; - } + physicsObject = CreatePhysicsObject(entityID); - // Get entity transform - auto const* SHADE_TF = SHComponentManager::GetComponent_s(entityID); + // Get components transform + auto* transformComponent = EnsureTransform(entityID); + auto* rigidBodyComponent = SHComponentManager::GetComponent(entityID); - // Possibly redundant - if (!SHADE_TF) - { - SHComponentManager::AddComponent(entityID); - SHADE_TF = SHComponentManager::GetComponent(entityID); - } - - const rp3d::Transform RP3D_TF { SHADE_TF->GetWorldPosition(), SHADE_TF->GetWorldRotation() }; - - // If collider already exists - if (physicsObject->hasColliders) - world->destroyCollisionBody(physicsObject->rp3dBody); - - physicsObject->rp3dBody = world->createRigidBody(RP3D_TF); - physicsObject->isRigidBody = true; + physicsObject->CreateRigidBody(transformComponent, rigidBodyComponent, nullptr); // Recreate colliders + const rp3d::Transform RP3D_TF { transformComponent->GetWorldPosition(), transformComponent->GetWorldRotation() }; if (physicsObject->hasColliders) { const auto& COLLIDERS = SHComponentManager::GetComponent(entityID)->GetColliders(); @@ -267,22 +253,11 @@ namespace SHADE // Check if entity is already a physics object auto* physicsObject = GetPhysicsObject(entityID); if (!physicsObject) - { - physicsObject = &(map.emplace(entityID, SHPhysicsObject{}).first->second); - physicsObject->entityID = entityID; - } + physicsObject = CreatePhysicsObject(entityID); // Get entity transform - auto const* SHADE_TF = SHComponentManager::GetComponent_s(entityID); - - // Possibly redundant - if (!SHADE_TF) - { - SHComponentManager::AddComponent(entityID); - SHADE_TF = SHComponentManager::GetComponent(entityID); - } - - const rp3d::Transform RP3D_TF { SHADE_TF->GetWorldPosition(), SHADE_TF->GetWorldRotation() }; + auto const* TF = EnsureTransform(entityID); + const rp3d::Transform RP3D_TF { TF->GetWorldPosition(), TF->GetWorldRotation() }; // No rb if (!physicsObject->isRigidBody) @@ -375,7 +350,7 @@ namespace SHADE switch (shape->GetType()) { - case SHShape::Type::BOUNDING_BOX: + case SHShape::Type::BOX: { auto* box = reinterpret_cast(shape); rp3d::BoxShape* newBox = factory.createBoxShape(box->GetHalfExtents()); @@ -457,6 +432,12 @@ namespace SHADE /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ + SHPhysicsObject* SHPhysicsSystem::CreatePhysicsObject(EntityID entityID) noexcept + { + auto* newPhysicsObject = &map.emplace(entityID, SHPhysicsObject{entityID, &factory, world}).first->second; + return newPhysicsObject; + } + SHPhysicsObject* SHPhysicsSystem::GetPhysicsObject(EntityID entityID) noexcept { const auto it = map.find(entityID); @@ -469,6 +450,14 @@ namespace SHADE return &(it->second); } + void SHPhysicsSystem::SyncActiveStates(SHPhysicsObject* physicsObject, bool componentActive) noexcept + { + const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive(); + if (RP3D_ACTIVE != componentActive) + physicsObject->rp3dBody->setIsActive(componentActive); + } + + void SHPhysicsSystem::SyncRigidBodyComponents(std::vector& denseArray) noexcept { if (denseArray.empty()) @@ -479,14 +468,11 @@ namespace SHADE const EntityID ENTITY_ID = comp.GetEID(); // Get physicsObject - auto const* physicsObject = GetPhysicsObject(ENTITY_ID); + auto* physicsObject = GetPhysicsObject(ENTITY_ID); - const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive(); // TODO(Diren): Check if active in hierarchy const bool COMPONENT_ACTIVE = comp.isActive; - - if (RP3D_ACTIVE != COMPONENT_ACTIVE) - physicsObject->rp3dBody->setIsActive(COMPONENT_ACTIVE); + SyncActiveStates(physicsObject, COMPONENT_ACTIVE); if (!COMPONENT_ACTIVE) continue; @@ -509,14 +495,11 @@ namespace SHADE const EntityID ENTITY_ID = comp.GetEID(); // Get physicsObject - auto const* physicsObject = GetPhysicsObject(ENTITY_ID); + auto* physicsObject = GetPhysicsObject(ENTITY_ID); - const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive(); // TODO(Diren): Check if active in hierarchy const bool COMPONENT_ACTIVE = comp.isActive; - - if (RP3D_ACTIVE != COMPONENT_ACTIVE) - physicsObject->rp3dBody->setIsActive(COMPONENT_ACTIVE); + SyncActiveStates(physicsObject, COMPONENT_ACTIVE); if (!COMPONENT_ACTIVE) continue; @@ -706,4 +689,19 @@ namespace SHADE } } + SHTransformComponent* SHPhysicsSystem::EnsureTransform(EntityID entityID) + { + auto* tf = SHComponentManager::GetComponent_s(entityID); + + // Possibly redundant + if (!tf) + { + SHComponentManager::AddComponent(entityID); + tf = SHComponentManager::GetComponent(entityID); + } + + return tf; + } + + } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index 92a4730d..b5ab36bc 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -19,6 +19,7 @@ #include "SHPhysicsObject.h" #include "Components/SHRigidBodyComponent.h" #include "Components/SHColliderComponent.h" +#include "Math/Transform/SHTransformComponent.h" #include "Scene/SHSceneGraph.h" #include "ECS_Base/System/SHSystemRoutine.h" @@ -185,11 +186,13 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ - SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; + SHPhysicsObject* CreatePhysicsObject (EntityID entityID) noexcept; + SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; - void SyncRigidBodyComponents (std::vector& denseArray) noexcept; - void SyncColliderComponents (std::vector& denseArray) noexcept; - void SyncTransforms () noexcept; + void SyncActiveStates (SHPhysicsObject* physicsObject, bool componentActive) noexcept; + void SyncRigidBodyComponents (std::vector& denseArray) noexcept; + void SyncColliderComponents (std::vector& denseArray) noexcept; + void SyncTransforms () noexcept; // TODO(Diren): Trigger handling static void SyncRigidBody (SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept; @@ -197,6 +200,9 @@ namespace SHADE static void SetRP3DAngularConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept; static void SyncCollider (SHPhysicsObject const* physicsObject, SHColliderComponent* comp) noexcept; + + // TODO(Diren): Remove when responsibility shifted to editor + SHTransformComponent* EnsureTransform (EntityID entityID); }; From e68ef89c00f9411501ed92682becde42ac7fe193 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 10 Oct 2022 21:21:20 +0800 Subject: [PATCH 32/61] synced rigidbodies through physics object --- .../Physics/Components/SHRigidBodyComponent.h | 3 + SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 109 ++++++++++++++++-- SHADE_Engine/src/Physics/SHPhysicsObject.h | 12 +- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 6 +- 4 files changed, 107 insertions(+), 23 deletions(-) diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h index 285df810..8b62b7ff 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h @@ -144,6 +144,9 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ + static constexpr size_t NUM_FLAGS = 8; + static constexpr size_t NUM_DIRTY_FLAGS = 16; + Type type; // rX rY rZ pX pY pZ slp g diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index a007c5fe..bbe8c726 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -143,37 +143,122 @@ namespace SHADE rb->orientation = tf->GetWorldRotation(); } - void SHPhysicsObject::DestroyRigidBody() noexcept - { - - } - void SHPhysicsObject::CreateCollisionBody(const SHTransformComponent* tf, SHColliderComponent* c) { } - void SHPhysicsObject::DestroyCollisionBody() noexcept - { - - } - int SHPhysicsObject::AddCollider(SHCollider* collider) { return 0; } + void SHPhysicsObject::DestroyRigidBody() noexcept + { + + } + + void SHPhysicsObject::DestroyCollisionBody() noexcept + { + + } + void SHPhysicsObject::RemoveCollider(int index) noexcept { } - void SHPhysicsObject::SyncRigidBody() noexcept + void SHPhysicsObject::SyncRigidBody(SHRigidBodyComponent* rb) const noexcept { + SHASSERT(rp3dBody != nullptr, "ReactPhysics body does not exist!") + + if (rb->dirtyFlags == 0) + return; + + auto* rigidBody = reinterpret_cast(rp3dBody); + + const uint16_t RB_FLAGS = rb->dirtyFlags; + for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i) + { + // Check if current dirty flag has been set to true + if (RB_FLAGS & 1U << i) + { + switch (i) + { + case 0: // Gravity + { + rigidBody->enableGravity(rb->IsGravityEnabled()); + break; + } + case 1: // Sleeping + { + rigidBody->setIsAllowedToSleep(rb->IsAllowedToSleep()); + break; + } + case 2: // Linear Constraints + { + const rp3d::Vector3 CONSTRAINTS + { + rb->flags & 1U << 2 ? 0.0f : 1.0f, + rb->flags & 1U << 3 ? 0.0f : 1.0f, + rb->flags & 1U << 4 ? 0.0f : 1.0f + }; + + rigidBody->setLinearLockAxisFactor(CONSTRAINTS); + break; + } + case 3: // Angular Constraints + { + const rp3d::Vector3 CONSTRAINTS + { + rb->flags & 1U << 5 ? 0.0f : 1.0f, + rb->flags & 1U << 6 ? 0.0f : 1.0f, + rb->flags & 1U << 7 ? 0.0f : 1.0f + }; + + rigidBody->setAngularLockAxisFactor(CONSTRAINTS); + break; + } + case 4: // Type + { + rigidBody->setType(static_cast(rb->GetType())); + break; + } + case 5: // Mass + { + rigidBody->setMass(rb->GetMass()); + break; + } + case 6: // Drag + { + rigidBody->setLinearDamping(rb->GetDrag()); + break; + } + case 7: // Angular Drag + { + rigidBody->setAngularDamping(rb->GetAngularDrag()); + break; + } + case 8: // Linear Velocity + { + rigidBody->setLinearVelocity(rb->GetLinearVelocity()); + break; + } + case 9: // Angular Velocity + { + rigidBody->setAngularVelocity(rb->GetAngularVelocity()); + break; + } + default: break; + } + } + } + + rb->dirtyFlags = 0; } - void SHPhysicsObject::SyncColliders() noexcept + void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept { } diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.h b/SHADE_Engine/src/Physics/SHPhysicsObject.h index c6ecd250..8562a0a1 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.h @@ -70,15 +70,15 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ void CreateRigidBody (const SHTransformComponent* tf, SHRigidBodyComponent* rb, SHColliderComponent* c); - void DestroyRigidBody () noexcept; - void CreateCollisionBody (const SHTransformComponent* tf, SHColliderComponent* c); int AddCollider (SHCollider* collider); - void RemoveCollider (int index) noexcept; - void DestroyCollisionBody () noexcept; - void SyncRigidBody () noexcept; - void SyncColliders () noexcept; + void DestroyRigidBody () noexcept; + void RemoveCollider (int index) noexcept; + void DestroyCollisionBody () noexcept; + + void SyncRigidBody (SHRigidBodyComponent* rb) const noexcept; + void SyncColliders (SHColliderComponent* c) const noexcept; private: /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 38c7e19c..b922cdd7 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -477,11 +477,7 @@ namespace SHADE if (!COMPONENT_ACTIVE) continue; - if (comp.dirtyFlags > 0) - { - SyncRigidBody(physicsObject, &comp); - comp.dirtyFlags = 0; - } + physicsObject->SyncRigidBody(&comp); } } From ff9b504bc5224089726983f7098b19bfd8b226fb Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 11 Oct 2022 01:26:12 +0800 Subject: [PATCH 33/61] Moved collider interface into physics object. Added support for removing rigidbodies --- SHADE_Application/src/Scenes/SBTestScene.cpp | 3 +- .../Components/SHColliderComponent.cpp | 16 +- .../Physics/Components/SHColliderComponent.h | 2 +- SHADE_Engine/src/Physics/SHCollider.cpp | 106 +++---- SHADE_Engine/src/Physics/SHCollider.h | 22 +- SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 108 ++++++- SHADE_Engine/src/Physics/SHPhysicsObject.h | 4 +- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 287 ++++-------------- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 13 +- 9 files changed, 227 insertions(+), 334 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 3b277e6c..36c69386 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -104,8 +104,7 @@ namespace Sandbox transform.SetWorldRotation(SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber()); transform.SetWorldScale(TEST_OBJ_SCALE); - auto* box = collider.AddBoundingBox(); - box->SetHalfExtents(transform.GetWorldScale() * 0.5f); + collider.AddBoundingBox(SHVec3::One * 0.5f, SHVec3::Zero); stressTestObjects.emplace_back(entity); } diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp index 73e7ccbd..ada90eaa 100644 --- a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp @@ -24,7 +24,8 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHColliderComponent::SHColliderComponent() noexcept - : system { nullptr } + : system { nullptr } + , colliders {} {} /*-----------------------------------------------------------------------------------*/ @@ -87,12 +88,17 @@ namespace SHADE system->RemoveCollider(GetEID()); } - SHBoundingBox* SHColliderComponent::AddBoundingBox() noexcept + SHBoundingBox* SHColliderComponent::AddBoundingBox(const SHVec3& halfExtents, const SHVec3& posOffset) noexcept { const auto TYPE = SHCollider::Type::BOX; - const auto BOX_PAIR = std::make_pair(SHCollider{TYPE}, true); - auto& collider = colliders.emplace_back(BOX_PAIR).first; + auto boxPair = std::make_pair(SHCollider{TYPE}, true); + auto& collider = colliders.emplace_back(boxPair).first; + + const auto* tf = SHComponentManager::GetComponent(GetEID()); + + collider.SetPositionOffset(posOffset); + collider.SetAsBoundingBox(tf->GetWorldScale() * halfExtents); if (!system) { @@ -101,7 +107,7 @@ namespace SHADE } // Notify Physics System - system->AddCollisionShape(GetEID(), collider.GetShape()); + system->AddCollisionShape(GetEID(), &collider); return reinterpret_cast(collider.GetShape()); } diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.h b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h index fd4bcb9a..db4cd612 100644 --- a/SHADE_Engine/src/Physics/Components/SHColliderComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h @@ -82,7 +82,7 @@ namespace SHADE void OnCreate () override; void OnDestroy () override; - SHBoundingBox* AddBoundingBox () noexcept; + SHBoundingBox* AddBoundingBox (const SHVec3& halfExtents = SHVec3::One, const SHVec3& posOffset = SHVec3::Zero) noexcept; void RemoveCollider (int index); diff --git a/SHADE_Engine/src/Physics/SHCollider.cpp b/SHADE_Engine/src/Physics/SHCollider.cpp index 724db19c..5a3a6ac2 100644 --- a/SHADE_Engine/src/Physics/SHCollider.cpp +++ b/SHADE_Engine/src/Physics/SHCollider.cpp @@ -29,25 +29,23 @@ namespace SHADE } SHCollider::SHCollider(const SHCollider& rhs) noexcept - : type { rhs.type} - , isTrigger { rhs.isTrigger } - , dirty { true } - , shape { nullptr } + : type { rhs.type} + , isTrigger { rhs.isTrigger } + , dirty { true } + , shape { nullptr } + , positionOffset { rhs.positionOffset } { CreateShape(); - - // TODO(Diren): Copy transform data over } SHCollider::SHCollider(SHCollider&& rhs) noexcept - : type { rhs.type} - , isTrigger { rhs.isTrigger } - , dirty { true } - , shape { nullptr } + : type { rhs.type} + , isTrigger { rhs.isTrigger } + , dirty { true } + , shape { nullptr } + , positionOffset { rhs.positionOffset } { CreateShape(); - - // TODO(Diren): Copy transform data over } SHCollider::~SHCollider() noexcept @@ -61,27 +59,26 @@ namespace SHADE SHCollider& SHCollider::operator=(const SHCollider& rhs) noexcept { - type = rhs.type; - isTrigger = rhs.isTrigger; - dirty = true; + if (this == &rhs) + return *this; + + type = rhs.type; + isTrigger = rhs.isTrigger; + dirty = true; + positionOffset = rhs.positionOffset; CreateShape(); - - // TODO(Diren): Copy transform data over - return *this; } SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept { - type = rhs.type; - isTrigger = rhs.isTrigger; - dirty = true; + type = rhs.type; + isTrigger = rhs.isTrigger; + dirty = true; + positionOffset = rhs.positionOffset; CreateShape(); - - // TODO(Diren): Copy transform data over - return *this; } @@ -104,11 +101,6 @@ namespace SHADE return type; } - SHShape* SHCollider::GetShape() const noexcept - { - return shape; - } - float SHCollider::GetFriction() const noexcept { // TODO(Diren): Fix after implementing materials @@ -126,38 +118,41 @@ namespace SHADE return 0.0f; } - SHVec3 SHCollider::GetPosition() const noexcept - { - // TODO(Diren): Fix after linking transform data - return SHVec3::Zero; - } - const SHVec3& SHCollider::GetPositionOffset() const noexcept { return positionOffset; } - SHQuaternion SHCollider::GetOrientation() const noexcept + SHShape* SHCollider::GetShape() noexcept { - // TODO(Diren): Fix after linking transform data - return SHQuaternion::Identity; + dirty = true; + return shape; } /*-----------------------------------------------------------------------------------*/ /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHCollider::SetType(Type newType) noexcept + void SHCollider::SetAsBoundingBox(const SHVec3& halfExtents) { - if (type == newType) - return; - dirty = true; + type = Type::BOX; - type = newType; - CreateShape(); + delete shape; + shape = new SHBoundingBox{ positionOffset, halfExtents }; } + void SHCollider::SetAsBoundingSphere(float radius) + { + dirty = true; + type = Type::SPHERE; + + // TODO(Diren): Add Sphere + delete shape; + } + + + void SHCollider::SetIsTrigger(bool trigger) noexcept { dirty = true; @@ -191,25 +186,22 @@ namespace SHADE void SHCollider::CreateShape() { - // Remove current shape delete shape; switch (type) { - case Type::BOX: CreateBoundingBox(); break; - case Type::SPHERE: CreateSphere(); break; + case Type::BOX: + { + SetAsBoundingBox(SHVec3::One); + break; + } + case Type::SPHERE: + { + SetAsBoundingSphere(1.0f); + break; + } default: break; } } - void SHCollider::CreateBoundingBox() - { - shape = new SHBoundingBox{ SHVec3::Zero, SHVec3::One }; - } - - void SHCollider::CreateSphere() - { - - } - } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHCollider.h b/SHADE_Engine/src/Physics/SHCollider.h index fce4a5b2..b53ce58a 100644 --- a/SHADE_Engine/src/Physics/SHCollider.h +++ b/SHADE_Engine/src/Physics/SHCollider.h @@ -32,8 +32,6 @@ namespace SHADE BOX , SPHERE , CAPSULE - , CONVEX_HULL - , CONVEX_MESH }; /*---------------------------------------------------------------------------------*/ @@ -62,28 +60,28 @@ namespace SHADE [[nodiscard]] bool IsTrigger () const noexcept; [[nodiscard]] Type GetType () const noexcept; - [[nodiscard]] SHShape* GetShape () const noexcept; [[nodiscard]] float GetFriction () const noexcept; [[nodiscard]] float GetBounciness () const noexcept; [[nodiscard]] float GetDensity () const noexcept; - [[nodiscard]] SHVec3 GetPosition () const noexcept; [[nodiscard]] const SHVec3& GetPositionOffset () const noexcept; - [[nodiscard]] SHQuaternion GetOrientation () const noexcept; + + [[nodiscard]] SHShape* GetShape () noexcept; /*---------------------------------------------------------------------------------*/ /* Setter Functions */ /*---------------------------------------------------------------------------------*/ - void SetType (Type newType) noexcept; + void SetAsBoundingBox (const SHVec3& halfExtents); + void SetAsBoundingSphere (float radius); - void SetIsTrigger (bool isTrigger) noexcept; - void SetFriction (float friction) noexcept; - void SetBounciness (float bounciness) noexcept; - void SetDensity (float density) noexcept; + void SetIsTrigger (bool isTrigger) noexcept; + void SetFriction (float friction) noexcept; + void SetBounciness (float bounciness) noexcept; + void SetDensity (float density) noexcept; - void SetPositionOffset (const SHVec3& positionOffset) noexcept; + void SetPositionOffset (const SHVec3& positionOffset) noexcept; private: /*---------------------------------------------------------------------------------*/ @@ -101,8 +99,6 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ void CreateShape (); - void CreateBoundingBox (); - void CreateSphere (); }; } // namespace SHADE diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index bbe8c726..eaecc9c0 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -132,7 +132,7 @@ namespace SHADE void SHPhysicsObject::CreateRigidBody(const SHTransformComponent* tf, SHRigidBodyComponent* rb, SHColliderComponent* c) { - // If collider already exists + // If collider already exists, recreate the collision body as a rigid body if (hasColliders) world->destroyCollisionBody(rp3dBody); @@ -141,31 +141,91 @@ namespace SHADE rb->position = tf->GetWorldPosition(); rb->orientation = tf->GetWorldRotation(); + + if (hasColliders) + { + c->position = tf->GetWorldPosition(); + c->orientation = tf->GetWorldRotation(); + // Get array of colliders and add them back into the rigidbody + for (auto& collider : c->colliders | std::views::keys) + AddCollider(&collider); + } } void SHPhysicsObject::CreateCollisionBody(const SHTransformComponent* tf, SHColliderComponent* c) { - + if (rp3dBody == nullptr) + rp3dBody = world->createCollisionBody(rp3d::Transform{ tf->GetWorldPosition(), tf->GetWorldRotation() }); + + hasColliders = true; + + c->position = tf->GetWorldPosition(); + c->orientation = tf->GetWorldRotation(); + + for (auto& collider : c->colliders | std::views::keys) + AddCollider(&collider); } int SHPhysicsObject::AddCollider(SHCollider* collider) { - return 0; + switch (collider->GetType()) + { + case SHCollider::Type::BOX: + { + const auto* box = reinterpret_cast(collider->GetShape()); + rp3d::BoxShape* newBox = factory->createBoxShape(box->GetHalfExtents()); + + // TODO(Diren): Handle offsets + rp3dBody->addCollider(newBox, rp3d::Transform{ collider->GetPositionOffset(), SHQuaternion::Identity }); + break; + } + case SHCollider::Type::SPHERE: + { + break; + } + // TODO(Diren): Add more collider shapes + default: break; + } + + return static_cast(rp3dBody->getNbColliders()) - 1; } - void SHPhysicsObject::DestroyRigidBody() noexcept + void SHPhysicsObject::DestroyRigidBody(SHColliderComponent* c) noexcept { - + world->destroyRigidBody(reinterpret_cast(rp3dBody)); + + if (hasColliders) + { + // Preserve colliders as a collision body + rp3dBody = world->createCollisionBody(rp3d::Transform{ c->position, c->orientation }); + for (auto& collider : c->colliders | std::views::keys) + AddCollider(&collider); + } + + isRigidBody = false; } void SHPhysicsObject::DestroyCollisionBody() noexcept { - + // Remove all colliders + for (uint32_t i = 0; i < rp3dBody->getNbColliders(); ++i) + { + auto* collider = rp3dBody->getCollider(i); + rp3dBody->removeCollider(collider); + } } - void SHPhysicsObject::RemoveCollider(int index) noexcept + void SHPhysicsObject::RemoveCollider(int index) { - + const int NUM_COLLIDERS = static_cast(rp3dBody->getNbColliders()); + if (NUM_COLLIDERS == 0) + return; + + if (index < 0 || index >= NUM_COLLIDERS) + throw std::invalid_argument("Index out of range!"); + + auto* collider = rp3dBody->getCollider(index); + rp3dBody->removeCollider(collider); } void SHPhysicsObject::SyncRigidBody(SHRigidBodyComponent* rb) const noexcept @@ -260,7 +320,37 @@ namespace SHADE void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept { - + int index = 0; + for (auto& [collider, dirty] : c->colliders) + { + if (!dirty) + continue; + + // Update offsets + auto* rp3dCollider = rp3dBody->getCollider(index); + rp3dCollider->setLocalToBodyTransform(rp3d::Transform(collider.GetPositionOffset(), SHQuaternion::Identity)); + + switch (collider.GetType()) + { + case SHCollider::Type::BOX: + { + const auto* box = reinterpret_cast(collider.GetShape()); + + auto* rp3dBoxShape = reinterpret_cast(rp3dCollider->getCollisionShape()); + rp3dBoxShape->setHalfExtents(box->GetHalfExtents()); + + break; + } + case SHCollider::Type::SPHERE: + { + break; + } + default: break; + } + + dirty = false; + ++index; + } } } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.h b/SHADE_Engine/src/Physics/SHPhysicsObject.h index 8562a0a1..39a85421 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.h @@ -73,8 +73,8 @@ namespace SHADE void CreateCollisionBody (const SHTransformComponent* tf, SHColliderComponent* c); int AddCollider (SHCollider* collider); - void DestroyRigidBody () noexcept; - void RemoveCollider (int index) noexcept; + void DestroyRigidBody (SHColliderComponent* c) noexcept; + void RemoveCollider (int index); void DestroyCollisionBody () noexcept; void SyncRigidBody (SHRigidBodyComponent* rb) const noexcept; diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index b922cdd7..c5a7aa57 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -202,46 +202,14 @@ namespace SHADE SHLOG_INFO("Adding a Rigidbody to the Physics World.") #endif - // Check if entity is already a physics object - auto* physicsObject = GetPhysicsObject(entityID); + auto* physicsObject = CreatePhysicsObject(entityID); - if (!physicsObject) - physicsObject = CreatePhysicsObject(entityID); - - // Get components transform - auto* transformComponent = EnsureTransform(entityID); - auto* rigidBodyComponent = SHComponentManager::GetComponent(entityID); - - physicsObject->CreateRigidBody(transformComponent, rigidBodyComponent, nullptr); - - // Recreate colliders - const rp3d::Transform RP3D_TF { transformComponent->GetWorldPosition(), transformComponent->GetWorldRotation() }; - if (physicsObject->hasColliders) - { - const auto& COLLIDERS = SHComponentManager::GetComponent(entityID)->GetColliders(); - for (const auto& collider : COLLIDERS | std::views::keys) - { - switch (collider.GetType()) - { - case SHCollider::Type::BOX: - { - SHBoundingBox* box = reinterpret_cast(collider.GetShape()); - rp3d::BoxShape* newBox = factory.createBoxShape(box->GetHalfExtents()); - - // TODO(Diren): Handle offsets - physicsObject->rp3dBody->addCollider(newBox, RP3D_TF); - break; - } - case SHCollider::Type::SPHERE: - { - break; - } - // TODO(Diren): Add more collider shapes - default: break; - } - } - } - + physicsObject->CreateRigidBody + ( + EnsureTransform(entityID), + SHComponentManager::GetComponent(entityID), + SHComponentManager::GetComponent_s(entityID) + ); } void SHPhysicsSystem::AddCollider(EntityID entityID) noexcept @@ -250,43 +218,13 @@ namespace SHADE SHLOG_INFO("Adding a Collider to the Physics World.") #endif - // Check if entity is already a physics object - auto* physicsObject = GetPhysicsObject(entityID); - if (!physicsObject) - physicsObject = CreatePhysicsObject(entityID); + auto* physicsObject = CreatePhysicsObject(entityID); - // Get entity transform - auto const* TF = EnsureTransform(entityID); - const rp3d::Transform RP3D_TF { TF->GetWorldPosition(), TF->GetWorldRotation() }; - - // No rb - if (!physicsObject->isRigidBody) - physicsObject->rp3dBody = world->createCollisionBody(RP3D_TF); - - const auto& COLLIDERS = SHComponentManager::GetComponent(entityID)->GetColliders(); - for (const auto& collider : COLLIDERS | std::views::keys) - { - switch (collider.GetType()) - { - case SHCollider::Type::BOX: - { - SHBoundingBox* box = reinterpret_cast(collider.GetShape()); - rp3d::BoxShape* newBox = factory.createBoxShape(box->GetHalfExtents()); - - // TODO(Diren): Handle offsets - physicsObject->rp3dBody->addCollider(newBox, RP3D_TF); - break; - } - case SHCollider::Type::SPHERE: - { - break; - } - // TODO(Diren): Add more collider shapes - default: break; - } - } - - physicsObject->hasColliders = true; + physicsObject->CreateCollisionBody + ( + EnsureTransform(entityID), + SHComponentManager::GetComponent(entityID) + ); } void SHPhysicsSystem::RemoveRigidBody(EntityID entityID) noexcept @@ -295,6 +233,13 @@ namespace SHADE SHLOG_INFO("Removing a Rigidbody from the Physics World.") #endif + auto* physicsObject = GetPhysicsObject(entityID); + SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!") + + physicsObject->DestroyRigidBody(SHComponentManager::GetComponent_s(entityID)); + + if (physicsObject->rp3dBody == nullptr) + DestroyPhysicsObject(entityID); } void SHPhysicsSystem::RemoveCollider(EntityID entityID) noexcept @@ -344,30 +289,10 @@ namespace SHADE } - void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHShape* shape) + void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollider* collider) { auto* physicsObject = GetPhysicsObject(entityID); - - switch (shape->GetType()) - { - case SHShape::Type::BOX: - { - auto* box = reinterpret_cast(shape); - rp3d::BoxShape* newBox = factory.createBoxShape(box->GetHalfExtents()); - - // TODO(Diren): Handle offsets - - rp3d::Transform tf = rp3d::Transform::identity(); - physicsObject->rp3dBody->addCollider(newBox, tf); - break; - } - case SHShape::Type::SPHERE: - { - break; - } - // TODO(Diren): Add more collider shapes - default: break; - } + physicsObject->AddCollider(collider); } void SHPhysicsSystem::RemoveCollisionShape(EntityID entityID, int index) @@ -424,6 +349,7 @@ namespace SHADE if (system->worldUpdated) { system->SyncTransforms(); + // TODO(Diren): Handle trigger messages for scripting } } @@ -434,8 +360,14 @@ namespace SHADE SHPhysicsObject* SHPhysicsSystem::CreatePhysicsObject(EntityID entityID) noexcept { - auto* newPhysicsObject = &map.emplace(entityID, SHPhysicsObject{entityID, &factory, world}).first->second; - return newPhysicsObject; + const auto it = map.find(entityID); + if (it == map.end()) + { + auto* newPhysicsObject = &map.emplace(entityID, SHPhysicsObject{entityID, &factory, world}).first->second; + return newPhysicsObject; + } + + return &(it->second); } SHPhysicsObject* SHPhysicsSystem::GetPhysicsObject(EntityID entityID) noexcept @@ -450,6 +382,11 @@ namespace SHADE return &(it->second); } + void SHPhysicsSystem::DestroyPhysicsObject(EntityID entityID) noexcept + { + map.erase(entityID); + } + void SHPhysicsSystem::SyncActiveStates(SHPhysicsObject* physicsObject, bool componentActive) noexcept { const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive(); @@ -500,17 +437,14 @@ namespace SHADE if (!COMPONENT_ACTIVE) continue; - SyncCollider(physicsObject, &comp); + physicsObject->SyncColliders(&comp); } } void SHPhysicsSystem::SyncTransforms() noexcept { - for (auto& pair : map) + for (auto& [entityID, physicsObject] : map) { - const EntityID ENTITY_ID = pair.first; - SHPhysicsObject& physicsObject = pair.second; - rp3d::Vector3 rp3dPos; rp3d::Quaternion rp3dRot; @@ -520,7 +454,7 @@ namespace SHADE if (physicsObject.isRigidBody) { - auto const* rbComponent = SHComponentManager::GetComponent(ENTITY_ID); + auto* rbComponent = SHComponentManager::GetComponent(entityID); if (rbComponent->GetType() == SHRigidBodyComponent::Type::STATIC) continue; @@ -538,6 +472,16 @@ namespace SHADE rp3dPos = CURRENT_TF.getPosition(); rp3dRot = CURRENT_TF.getOrientation(); } + + rbComponent->position = CURRENT_TF.getPosition(); + rbComponent->orientation = CURRENT_TF.getOrientation(); + + if (physicsObject.hasColliders) + { + auto* colliderComponent = SHComponentManager::GetComponent(entityID); + colliderComponent->position = CURRENT_TF.getPosition(); + colliderComponent->orientation = CURRENT_TF.getOrientation(); + } } else { @@ -546,145 +490,16 @@ namespace SHADE } // Convert RP3D Transform to SHADE - auto* tfComponent = SHComponentManager::GetComponent(ENTITY_ID); + auto* tfComponent = SHComponentManager::GetComponent(entityID); tfComponent->SetWorldPosition(rp3dPos); tfComponent->SetWorldRotation(SHQuaternion{ rp3dRot }.ToEuler()); + // Cache transforms physicsObject.prevTransform = CURRENT_TF; } } - void SHPhysicsSystem::SyncRigidBody(SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept - { - auto* rigidBody = reinterpret_cast(physicsObject->rp3dBody); - - const uint16_t RB_FLAGS = comp->dirtyFlags; - const size_t NUM_FLAGS = sizeof(RB_FLAGS) * 8U; - for (size_t i = 0; i < NUM_FLAGS; ++i) - { - // Check if current dirty flag has been set to true - if (RB_FLAGS & 1U << i) - { - switch (i) - { - case 0: // Gravity - { - rigidBody->enableGravity(comp->IsGravityEnabled()); - break; - } - case 1: // Sleeping - { - rigidBody->setIsAllowedToSleep(comp->IsAllowedToSleep()); - break; - } - case 2: // Linear Constraints - { - SetRP3DLinearConstraints(rigidBody, comp->flags); - break; - } - case 3: // Angular Constraints - { - SetRP3DAngularConstraints(rigidBody, comp->flags); - break; - } - case 4: // Type - { - rigidBody->setType(static_cast(comp->GetType())); - break; - } - case 5: // Mass - { - rigidBody->setMass(comp->GetMass()); - break; - } - case 6: // Drag - { - rigidBody->setLinearDamping(comp->GetDrag()); - break; - } - case 7: // Angular Drag - { - rigidBody->setAngularDamping(comp->GetAngularDrag()); - break; - } - case 8: // Linear Velocity - { - rigidBody->setLinearVelocity(comp->GetLinearVelocity()); - break; - } - case 9: // Angular Velocity - { - rigidBody->setAngularVelocity(comp->GetAngularVelocity()); - break; - } - default: break; - } - } - } - } - - void SHPhysicsSystem::SetRP3DLinearConstraints(rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept - { - const rp3d::Vector3 CONSTRAINTS - { - rbFlags & 1U << 2 ? 0.0f : 1.0f, - rbFlags & 1U << 3 ? 0.0f : 1.0f, - rbFlags & 1U << 4 ? 0.0f : 1.0f - }; - - - rp3dRigidBody->setLinearLockAxisFactor(CONSTRAINTS); - } - - void SHPhysicsSystem::SetRP3DAngularConstraints(rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept - { - const rp3d::Vector3 CONSTRAINTS - { - rbFlags & 1U << 5 ? 0.0f : 1.0f, - rbFlags & 1U << 6 ? 0.0f : 1.0f, - rbFlags & 1U << 7 ? 0.0f : 1.0f - }; - - rp3dRigidBody->setAngularLockAxisFactor(CONSTRAINTS); - } - - void SHPhysicsSystem::SyncCollider(SHPhysicsObject const* physicsObject, SHColliderComponent* comp) noexcept - { - int index = 0; - for (auto& [collider, dirty] : comp->colliders) - { - if (!dirty) - continue; - - switch (collider.GetType()) - { - case SHCollider::Type::BOX: - { - SHBoundingBox* box = reinterpret_cast(collider.GetShape()); - - auto* rp3dBoxShape = reinterpret_cast(physicsObject->rp3dBody->getCollider(index)->getCollisionShape()); - rp3dBoxShape->setHalfExtents(box->GetHalfExtents()); - - if (rp3dBoxShape) - { - SHLOG_INFO("Updating box things") - } - - break; - } - case SHCollider::Type::SPHERE: - { - break; - } - default: break; - } - - dirty = false; - ++index; - } - } - SHTransformComponent* SHPhysicsSystem::EnsureTransform(EntityID entityID) { auto* tf = SHComponentManager::GetComponent_s(entityID); diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index b5ab36bc..bc6a1ba2 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -82,8 +82,8 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - void Init () override; - void Exit () override; + void Init () override; + void Exit () override; void AddRigidBody (EntityID entityID) noexcept; void AddCollider (EntityID entityID) noexcept; @@ -101,7 +101,7 @@ namespace SHADE void AddTorque (EntityID entityID, const SHVec3& torque) const noexcept; void AddRelativeTorque (EntityID entityID, const SHVec3& relativeTorque) const noexcept; - void AddCollisionShape (EntityID entityID, SHShape* shape); + void AddCollisionShape (EntityID entityID, SHCollider* collider); void RemoveCollisionShape (EntityID entityID, int index); /*---------------------------------------------------------------------------------*/ @@ -188,6 +188,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ SHPhysicsObject* CreatePhysicsObject (EntityID entityID) noexcept; SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; + void DestroyPhysicsObject (EntityID entityID) noexcept; void SyncActiveStates (SHPhysicsObject* physicsObject, bool componentActive) noexcept; void SyncRigidBodyComponents (std::vector& denseArray) noexcept; @@ -195,12 +196,6 @@ namespace SHADE void SyncTransforms () noexcept; // TODO(Diren): Trigger handling - static void SyncRigidBody (SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept; - static void SetRP3DLinearConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept; - static void SetRP3DAngularConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept; - - static void SyncCollider (SHPhysicsObject const* physicsObject, SHColliderComponent* comp) noexcept; - // TODO(Diren): Remove when responsibility shifted to editor SHTransformComponent* EnsureTransform (EntityID entityID); }; From 2fa71f0fd973db9494ce1ef7a91f29c1d675aedc Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Wed, 12 Oct 2022 19:12:34 +0800 Subject: [PATCH 34/61] Added Ray --- .../src/Math/Geometry/SHBoundingBox.cpp | 5 ++ .../src/Math/Geometry/SHBoundingBox.h | 3 +- SHADE_Engine/src/Math/Geometry/SHShape.h | 7 ++- SHADE_Engine/src/Math/SHMatrix.cpp | 33 ++++++++++ SHADE_Engine/src/Math/SHMatrix.h | 20 ++++++- SHADE_Engine/src/Math/SHRay.cpp | 60 +++++++++++++++++++ SHADE_Engine/src/Math/SHRay.h | 54 +++++++++++++++++ 7 files changed, 177 insertions(+), 5 deletions(-) create mode 100644 SHADE_Engine/src/Math/SHRay.cpp create mode 100644 SHADE_Engine/src/Math/SHRay.h diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp index 3abcc315..72b46819 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp @@ -201,6 +201,11 @@ namespace SHADE return true; } + bool SHBoundingBox::Raycast(const SHVec3& SHRay, float& distance) noexcept + { + return false; + } + bool SHBoundingBox::Contains(const SHBoundingBox& rhs) const noexcept { const SHVec3 V = SHVec3::Abs(rhs.center - center); diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h index a89c5965..2ad5f1ed 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h @@ -64,7 +64,8 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] bool TestPoint (const SHVec3& point) noexcept override; + [[nodiscard]] bool TestPoint (const SHVec3& point) noexcept override; + [[nodiscard]] bool Raycast (const SHVec3& SHRay, float& distance) noexcept override; [[nodiscard]] bool Contains (const SHBoundingBox& rhs) const noexcept; [[nodiscard]] float Volume () const noexcept; diff --git a/SHADE_Engine/src/Math/Geometry/SHShape.h b/SHADE_Engine/src/Math/Geometry/SHShape.h index e33ca583..204d4e0c 100644 --- a/SHADE_Engine/src/Math/Geometry/SHShape.h +++ b/SHADE_Engine/src/Math/Geometry/SHShape.h @@ -11,8 +11,10 @@ #pragma once // Project Headers -#include "Math/Transform/SHTransform.h" #include "SH_API.h" +#include "Math/Transform/SHTransform.h" +#include "Math/SHRay.h" + namespace SHADE { @@ -69,7 +71,8 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] virtual bool TestPoint (const SHVec3& point) noexcept = 0; + [[nodiscard]] virtual bool TestPoint (const SHVec3& point) noexcept = 0; + [[nodiscard]] virtual bool Raycast (const SHVec3& SHRay, float& distance) noexcept = 0; protected: /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Math/SHMatrix.cpp b/SHADE_Engine/src/Math/SHMatrix.cpp index 94c17914..571fa4e0 100644 --- a/SHADE_Engine/src/Math/SHMatrix.cpp +++ b/SHADE_Engine/src/Math/SHMatrix.cpp @@ -334,6 +334,39 @@ namespace SHADE return ss.str(); } + bool SHMatrix::Decompose(SHVec3& translation, SHVec3& rotation, SHVec3& scale) const noexcept + { + XMVECTOR s, r, t; + const XMMATRIX M = XMLoadFloat4x4(this); + + if (!XMMatrixDecompose(&s, &r, &t, M)) + return false; + + SHQuaternion orientation; + + XMStoreFloat3(&scale, s); + XMStoreFloat4(&orientation, r); + XMStoreFloat3(&translation, t); + + rotation = orientation.ToEuler(); + + return true; + } + + bool SHMatrix::Decompose(SHVec3& translation, SHQuaternion& orientation, SHVec3& scale) const noexcept + { + XMVECTOR s, r, t; + const XMMATRIX M = XMLoadFloat4x4(this); + + if (!XMMatrixDecompose(&s, &r, &t, M)) + return false; + + XMStoreFloat3(&scale, s); + XMStoreFloat4(&orientation, r); + XMStoreFloat3(&translation, t); + + return true; + } /*-----------------------------------------------------------------------------------*/ /* Static Function Member Definitions */ diff --git a/SHADE_Engine/src/Math/SHMatrix.h b/SHADE_Engine/src/Math/SHMatrix.h index 3666fbe6..7a662478 100644 --- a/SHADE_Engine/src/Math/SHMatrix.h +++ b/SHADE_Engine/src/Math/SHMatrix.h @@ -16,7 +16,6 @@ // Project Headers #include "SH_API.h" #include "Vector/SHVec4.h" -#include "SH_API.h" namespace SHADE { @@ -25,7 +24,6 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ class SHVec2; class SHVec3; - class SHVec4; class SHQuaternion; /*-----------------------------------------------------------------------------------*/ @@ -109,6 +107,24 @@ namespace SHADE [[nodiscard]] float Determinant () const noexcept; [[nodiscard]] std::string ToString () const noexcept; + /** + * @brief Decomposes a transformation matrix into translation, euler angles and scale. + * @param[out] scale The scaling factor of the matrix. + * @param[out] rotation The euler angles of the matrix. + * @param[out] translation The translation of the matrix. + * @return True if decomposition was successful. + */ + bool Decompose (SHVec3& translation, SHVec3& rotation, SHVec3& scale) const noexcept; + + /** + * @brief Decomposes a transformation matrix into translation, orientation and scale. + * @param[out] scale The scaling factor of the matrix. + * @param[out] orientation The orientation of the matrix. + * @param[out] translation The translation of the matrix. + * @return True if decomposition was successful. + */ + bool Decompose (SHVec3& translation, SHQuaternion& orientation, SHVec3& scale) const noexcept; + /*---------------------------------------------------------------------------------*/ /* Static Function Members */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Math/SHRay.cpp b/SHADE_Engine/src/Math/SHRay.cpp new file mode 100644 index 00000000..87f12b81 --- /dev/null +++ b/SHADE_Engine/src/Math/SHRay.cpp @@ -0,0 +1,60 @@ +/**************************************************************************************** + * \file SHRay.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for a Ray. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHRay.h" + +using namespace DirectX; + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHRay::SHRay() noexcept + : direction { 0.0f, 0.0f, 1.0f } + {} + + SHRay::SHRay(const SHVec3& pos, const SHVec3& dir) noexcept + : position { pos } + , direction { dir } + {} + + /*-----------------------------------------------------------------------------------*/ + /* Operator Overload Definitions */ + /*-----------------------------------------------------------------------------------*/ + + bool SHRay::operator==(const SHRay& rhs) noexcept + { + const XMVECTOR LHS_POS = XMLoadFloat3(&position); + const XMVECTOR RHS_POS = XMLoadFloat3(&rhs.position); + + const XMVECTOR LHS_DIR = XMLoadFloat3(&direction); + const XMVECTOR RHS_DIR = XMLoadFloat3(&rhs.direction); + + return XMVector3Equal(LHS_POS, RHS_POS) && XMVector3NotEqual(LHS_DIR, RHS_DIR); + } + + bool SHRay::operator!=(const SHRay& rhs) noexcept + { + const XMVECTOR LHS_POS = XMLoadFloat3(&position); + const XMVECTOR RHS_POS = XMLoadFloat3(&rhs.position); + + const XMVECTOR LHS_DIR = XMLoadFloat3(&direction); + const XMVECTOR RHS_DIR = XMLoadFloat3(&rhs.direction); + + return XMVector3NotEqual(LHS_POS, RHS_POS) || XMVector3NotEqual(LHS_DIR, RHS_DIR); + } + + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/SHRay.h b/SHADE_Engine/src/Math/SHRay.h new file mode 100644 index 00000000..29d55b16 --- /dev/null +++ b/SHADE_Engine/src/Math/SHRay.h @@ -0,0 +1,54 @@ +/**************************************************************************************** + * \file SHRay.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for a Ray. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include + +// Project Headers +#include "SH_API.h" +#include "Vector/SHVec3.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + struct SH_API SHRay + { + public: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + SHVec3 position; + SHVec3 direction; + + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHRay() noexcept; + SHRay(const SHVec3& pos, const SHVec3& dir) noexcept; + SHRay(const SHRay& rhs) noexcept = default; + SHRay(SHRay&& rhs) noexcept = default; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + SHRay& operator= (const SHRay& rhs) noexcept = default; + SHRay& operator= (SHRay&& rhs) noexcept = default; + + [[nodiscard]] bool operator==(const SHRay& rhs) noexcept; + [[nodiscard]] bool operator!=(const SHRay& rhs) noexcept; + }; +} // namespace SHADE \ No newline at end of file From d95dbd5ce6a420f42ddb4458a9f8b6228399d07d Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Wed, 12 Oct 2022 21:59:34 +0800 Subject: [PATCH 35/61] Reworked Bounding Boxes --- .../src/Math/Geometry/SHBoundingBox.cpp | 196 +++++++----------- .../src/Math/Geometry/SHBoundingBox.h | 62 +++--- SHADE_Engine/src/Math/Geometry/SHShape.h | 4 +- SHADE_Engine/src/Math/Vector/SHVec2.cpp | 110 +++------- SHADE_Engine/src/Math/Vector/SHVec2.h | 9 +- SHADE_Engine/src/Math/Vector/SHVec3.cpp | 128 ++++-------- SHADE_Engine/src/Math/Vector/SHVec3.h | 3 + SHADE_Engine/src/Math/Vector/SHVec4.cpp | 144 ++++--------- SHADE_Engine/src/Math/Vector/SHVec4.h | 7 +- 9 files changed, 242 insertions(+), 421 deletions(-) diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp index 72b46819..11a14eed 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp @@ -14,6 +14,9 @@ #include "SHBoundingBox.h" // Project Headers #include "Math/SHMathHelpers.h" +#include "Math/SHRay.h" + +using namespace DirectX; namespace SHADE { @@ -21,89 +24,56 @@ namespace SHADE /* Constructors & Destructor Definitions */ /*-----------------------------------------------------------------------------------*/ + SHBoundingBox::SHBoundingBox() noexcept + { + type = Type::BOUNDING_BOX; + } + SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept - : SHShape {} - , center { c } - , halfExtents { hE } - { - type = Type::BOUNDING_BOX; - } - - SHBoundingBox::SHBoundingBox(const SHVec3* vertices, size_t numVertices) noexcept - : SHShape {} { type = Type::BOUNDING_BOX; - if (vertices == nullptr || numVertices < 2) - { - SHLOG_ERROR("Insufficient number of vertices passed into bounding box constructor!") - return; - } - - SHVec3 min { std::numeric_limits::max() }; - SHVec3 max { std::numeric_limits::min() }; - - for (size_t i = 0; i < numVertices; ++i) - { - const SHVec3& v = vertices[i]; - - min.x = SHMath::Min(min.x, v.x); - min.y = SHMath::Min(min.y, v.y); - min.z = SHMath::Min(min.z, v.z); - - max.x = SHMath::Max(max.x, v.x); - max.y = SHMath::Max(max.y, v.y); - max.z = SHMath::Max(max.z, v.z); - } - - center = SHVec3::Lerp(min, max, 0.5f); - halfExtents = SHVec3::Abs((max - min) * 0.5f); + Center = c; + Extents = hE; } - SHBoundingBox::SHBoundingBox(const SHBoundingBox* boxes, size_t numBoxes) noexcept - : SHShape {} - { - type = Type::BOUNDING_BOX; - - if (boxes == nullptr || numBoxes == 0) - { - SHLOG_ERROR("Insufficient number of boxes passed into bounding box constructor!") - return; - } - - center = boxes->center; - halfExtents = boxes->halfExtents; - - for (size_t i = 1; i < numBoxes; ++i) - *this = Combine(*this, boxes[i]); - } SHBoundingBox::SHBoundingBox(const SHBoundingBox& rhs) noexcept - : SHShape {} - , center { rhs.center } - , halfExtents { rhs.halfExtents } { + if (this == &rhs) + return; + type = Type::BOUNDING_BOX; + + Center = rhs.Center; + Extents = rhs.Extents; } SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept - : SHShape {} - , center { rhs.center } - , halfExtents { rhs.halfExtents } { type = Type::BOUNDING_BOX; + + Center = rhs.Center; + Extents = rhs.Extents; } + /*-----------------------------------------------------------------------------------*/ + /* Operator Overload Definitions */ + /*-----------------------------------------------------------------------------------*/ + SHBoundingBox& SHBoundingBox::operator=(const SHBoundingBox& rhs) noexcept { + if (this == &rhs) + return *this; + if (rhs.type != Type::BOUNDING_BOX) { SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!") } else { - center = rhs.center; - halfExtents = rhs.halfExtents; + Center = rhs.Center; + Extents = rhs.Extents; } return *this; @@ -117,8 +87,8 @@ namespace SHADE } else { - center = rhs.center; - halfExtents = rhs.halfExtents; + Center = rhs.Center; + Extents = rhs.Extents; } return *this; @@ -130,22 +100,22 @@ namespace SHADE const SHVec3& SHBoundingBox::GetCenter() const noexcept { - return center; + return Center; } const SHVec3& SHBoundingBox::GetHalfExtents() const noexcept { - return halfExtents; + return Extents; } SHVec3 SHBoundingBox::GetMin() const noexcept { - return center - halfExtents; + return SHVec3{ Center.x - Extents.x, Center.y - Extents.y, Center.z - Extents.z }; } SHVec3 SHBoundingBox::GetMax() const noexcept { - return center + halfExtents; + return SHVec3{ Center.x + Extents.x, Center.y + Extents.y, Center.z + Extents.z }; } /*-----------------------------------------------------------------------------------*/ @@ -154,36 +124,42 @@ namespace SHADE void SHBoundingBox::SetCenter(const SHVec3& newCenter) noexcept { - center = newCenter; + Center = newCenter; } void SHBoundingBox::SetHalfExtents(const SHVec3& newHalfExtents) noexcept { - halfExtents = newHalfExtents; + Extents = newHalfExtents; } void SHBoundingBox::SetMin(const SHVec3& min) noexcept { - const SHVec3 MAX = center + halfExtents; + const SHVec3 MAX = GetMax(); - center = SHVec3::Lerp(min, MAX, 0.5f); - halfExtents = SHVec3::Abs((MAX - min) * 0.5f); + Center = SHVec3::Lerp(min, MAX, 0.5f); + Extents = SHVec3::Abs((MAX - min) * 0.5f); } void SHBoundingBox::SetMax(const SHVec3& max) noexcept { - const SHVec3 MIN = center - halfExtents; + const SHVec3 MIN = GetMin(); - center = SHVec3::Lerp(MIN, max, 0.5f); - halfExtents = SHVec3::Abs((max - MIN) * 0.5f); + Center = SHVec3::Lerp(MIN, max, 0.5f); + Extents = SHVec3::Abs((max - MIN) * 0.5f); } void SHBoundingBox::SetMinMax(const SHVec3& min, const SHVec3& max) noexcept { - center = SHVec3::Lerp(min, max, 0.5f); - halfExtents = SHVec3::Abs((max - min) * 0.5f); + Center = SHVec3::Lerp(min, max, 0.5f); + Extents = SHVec3::Abs((max - min) * 0.5f); } + std::vector SHBoundingBox::GetVertices() const noexcept + { + std::vector vertices{ 8 }; + GetCorners(vertices.data()); + return vertices; + } /*-----------------------------------------------------------------------------------*/ /* Public Function Member Definitions */ @@ -191,43 +167,29 @@ namespace SHADE bool SHBoundingBox::TestPoint(const SHVec3& point) noexcept { - const SHVec3 V = SHVec3::Abs(point - center); - for (size_t i = 0; i < SHVec3::SIZE; ++i) - { - if (V[i] > halfExtents[i]) - return false; - } - - return true; + return BoundingBox::Contains(point); } - bool SHBoundingBox::Raycast(const SHVec3& SHRay, float& distance) noexcept + bool SHBoundingBox::Raycast(const SHRay& ray, float& distance) noexcept { - return false; + return BoundingBox::Intersects(ray.position, ray.direction, distance); } bool SHBoundingBox::Contains(const SHBoundingBox& rhs) const noexcept { - const SHVec3 V = SHVec3::Abs(rhs.center - center); - for (size_t i = 0; i < SHVec3::SIZE; ++i) - { - if (V[i] > rhs.halfExtents[i]) - return false; - } - - return true; + return BoundingBox::Contains(rhs); } float SHBoundingBox::Volume() const noexcept { - return 8.0f * (halfExtents.x * halfExtents.y * halfExtents.z); + return 8.0f * (Extents.x * Extents.y * Extents.z); } float SHBoundingBox::SurfaceArea() const noexcept { - return 8.0f * ((halfExtents.x * halfExtents.y) - + (halfExtents.x * halfExtents.z) - + (halfExtents.y * halfExtents.z)); + return 8.0f * ((Extents.x * Extents.y) + + (Extents.x * Extents.z) + + (Extents.y * Extents.z)); } /*-----------------------------------------------------------------------------------*/ @@ -236,37 +198,31 @@ namespace SHADE SHBoundingBox SHBoundingBox::Combine(const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept { - if (lhs.Contains(rhs)) - return lhs; - - if (rhs.Contains(lhs)) - return rhs; - - const SHVec3 LHS_MIN = lhs.GetMin(); - const SHVec3 LHS_MAX = lhs.GetMax(); - const SHVec3 RHS_MIN = rhs.GetMin(); - const SHVec3 RHS_MAX = rhs.GetMax(); - - SHVec3 min = SHVec3::Min({ LHS_MIN, RHS_MIN }); - SHVec3 max = SHVec3::Max({ LHS_MAX, RHS_MAX }); - - SHBoundingBox result{ lhs }; - result.SetMinMax(min, max); + SHBoundingBox result; + CreateMerged(result, lhs, rhs); return result; } bool SHBoundingBox::Intersect(const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept { - const SHVec3 V = SHVec3::Abs(lhs.center - rhs.center); - const SHVec3 D = lhs.halfExtents + rhs.halfExtents; + return lhs.Intersects(rhs); + } - for (size_t i = 0; i < SHVec3::SIZE; ++i) - { - if (V[i] > D[i]) - return false; - } + SHBoundingBox SHBoundingBox::BuildFromBoxes(const SHBoundingBox* boxes, size_t numBoxes) noexcept + { + SHBoundingBox result; - return true; + for (size_t i = 1; i < numBoxes; ++i) + CreateMerged(result, boxes[i - 1], boxes[i]); + + return result; + } + + SHBoundingBox SHBoundingBox::BuildFromVertices(const SHVec3* vertices, size_t numVertices, size_t stride) noexcept + { + SHBoundingBox result; + CreateFromPoints(result, numVertices, vertices, stride); + return result; } } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h index 2ad5f1ed..5c38e1b8 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h @@ -22,32 +22,43 @@ namespace SHADE /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ - // TODO(Diren): Use DirectX BoundingBox instead of custom - class SH_API SHBoundingBox : public SHShape + class SH_API SHBoundingBox : public SHShape, + private DirectX::BoundingBox { public: + /*---------------------------------------------------------------------------------*/ + /* Static Data Members */ + /*---------------------------------------------------------------------------------*/ + + static constexpr size_t NUM_VERTICES = 8; + /*---------------------------------------------------------------------------------*/ /* Constructors & Destructor */ /*---------------------------------------------------------------------------------*/ - SHBoundingBox (const SHVec3& center, const SHVec3& halfExtents) noexcept; - SHBoundingBox (const SHVec3* vertices, size_t numVertices) noexcept; - SHBoundingBox (const SHBoundingBox* boxes, size_t numBoxes) noexcept; + ~SHBoundingBox () noexcept = default; - SHBoundingBox (const SHBoundingBox& rhs) noexcept; - SHBoundingBox (SHBoundingBox&& rhs) noexcept; + SHBoundingBox () noexcept; + SHBoundingBox (const SHVec3& center, const SHVec3& halfExtents) noexcept; + SHBoundingBox (const SHBoundingBox& rhs) noexcept; + SHBoundingBox (SHBoundingBox&& rhs) noexcept; - SHBoundingBox& operator= (const SHBoundingBox& rhs) noexcept; - SHBoundingBox& operator= (SHBoundingBox&& rhs) noexcept; + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + SHBoundingBox& operator= (const SHBoundingBox& rhs) noexcept; + SHBoundingBox& operator= (SHBoundingBox&& rhs) noexcept; /*---------------------------------------------------------------------------------*/ /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] const SHVec3& GetCenter () const noexcept; - [[nodiscard]] const SHVec3& GetHalfExtents () const noexcept; - [[nodiscard]] SHVec3 GetMin () const noexcept; - [[nodiscard]] SHVec3 GetMax () const noexcept; + [[nodiscard]] const SHVec3& GetCenter () const noexcept; + [[nodsicard]] const SHVec3& GetHalfExtents() const noexcept; + [[nodiscard]] SHVec3 GetMin () const noexcept; + [[nodiscard]] SHVec3 GetMax () const noexcept; + [[nodiscard]] std::vector GetVertices () const noexcept; /*---------------------------------------------------------------------------------*/ /* Setter Functions */ @@ -59,32 +70,25 @@ namespace SHADE void SetMax (const SHVec3& max) noexcept; void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept; - /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] bool TestPoint (const SHVec3& point) noexcept override; - [[nodiscard]] bool Raycast (const SHVec3& SHRay, float& distance) noexcept override; + [[nodiscard]] bool TestPoint (const SHVec3& point) noexcept override; + [[nodiscard]] bool Raycast (const SHRay& ray, float& distance) noexcept override; - [[nodiscard]] bool Contains (const SHBoundingBox& rhs) const noexcept; - [[nodiscard]] float Volume () const noexcept; - [[nodiscard]] float SurfaceArea () const noexcept; + [[nodiscard]] bool Contains (const SHBoundingBox& rhs) const noexcept; + [[nodiscard]] float Volume () const noexcept; + [[nodiscard]] float SurfaceArea () const noexcept; /*---------------------------------------------------------------------------------*/ /* Static Function Members */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] static SHBoundingBox Combine (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept; - [[nodiscard]] static bool Intersect (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept; - - private: - /*---------------------------------------------------------------------------------*/ - /* Data Members */ - /*---------------------------------------------------------------------------------*/ - - SHVec3 center; - SHVec3 halfExtents; + [[nodiscard]] static SHBoundingBox Combine (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept; + [[nodiscard]] static bool Intersect (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept; + [[nodiscard]] static SHBoundingBox BuildFromBoxes (const SHBoundingBox* boxes, size_t numBoxes) noexcept; + [[nodiscard]] static SHBoundingBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept; }; diff --git a/SHADE_Engine/src/Math/Geometry/SHShape.h b/SHADE_Engine/src/Math/Geometry/SHShape.h index 204d4e0c..69578cb3 100644 --- a/SHADE_Engine/src/Math/Geometry/SHShape.h +++ b/SHADE_Engine/src/Math/Geometry/SHShape.h @@ -71,8 +71,8 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] virtual bool TestPoint (const SHVec3& point) noexcept = 0; - [[nodiscard]] virtual bool Raycast (const SHVec3& SHRay, float& distance) noexcept = 0; + [[nodiscard]] virtual bool TestPoint (const SHVec3& point) noexcept = 0; + [[nodiscard]] virtual bool Raycast (const SHRay& ray, float& distance) noexcept = 0; protected: /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Math/Vector/SHVec2.cpp b/SHADE_Engine/src/Math/Vector/SHVec2.cpp index 545492cb..a71ad0ea 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec2.cpp +++ b/SHADE_Engine/src/Math/Vector/SHVec2.cpp @@ -38,6 +38,10 @@ namespace SHADE : XMFLOAT2( 0.0f, 0.0f ) {} + SHVec2::SHVec2(const XMFLOAT2& xmfloat2) noexcept + : XMFLOAT2 ( xmfloat2.x, xmfloat2.y ) + {} + SHVec2::SHVec2(float n) noexcept : XMFLOAT2( n, n ) {} @@ -50,6 +54,11 @@ namespace SHADE /* Operator Overload Definitions */ /*-----------------------------------------------------------------------------------*/ + SHVec2::operator XMVECTOR() const noexcept + { + return XMLoadFloat2(this); + } + SHVec2& SHVec2::operator+=(const SHVec2& rhs) noexcept { return *this = *this + rhs; @@ -83,22 +92,16 @@ namespace SHADE SHVec2 SHVec2::operator+(const SHVec2& rhs) const noexcept { SHVec2 result; - - const XMVECTOR V1 = XMLoadFloat2(this); - const XMVECTOR V2 = XMLoadFloat2(&rhs); - XMStoreFloat2(&result, XMVectorAdd(V1, V2)); + XMStoreFloat2(&result, XMVectorAdd(*this, rhs)); return result; } SHVec2 SHVec2::operator-(const SHVec2& rhs) const noexcept { SHVec2 result; - - const XMVECTOR V1 = XMLoadFloat2(this); - const XMVECTOR V2 = XMLoadFloat2(&rhs); - XMStoreFloat2(&result, XMVectorSubtract(V1, V2)); + XMStoreFloat2(&result, XMVectorSubtract(*this, rhs)); return result; } @@ -110,59 +113,43 @@ namespace SHADE SHVec2 SHVec2::operator*(const SHVec2& rhs) const noexcept { SHVec2 result; - - const XMVECTOR V1 = XMLoadFloat2(this); - const XMVECTOR V2 = XMLoadFloat2(&rhs); - XMStoreFloat2(&result, XMVectorMultiply(V1, V2)); + XMStoreFloat2(&result, XMVectorMultiply(*this, rhs)); return result; } SHVec2 SHVec2::operator*(float rhs) const noexcept { SHVec2 result; - - const XMVECTOR V = XMLoadFloat2(this); - XMStoreFloat2(&result, XMVectorScale(V, rhs)); + XMStoreFloat2(&result, XMVectorScale(*this, rhs)); return result; } SHVec2 SHVec2::operator/(const SHVec2& rhs) const noexcept { SHVec2 result; - - const XMVECTOR V1 = XMLoadFloat2(this); - const XMVECTOR V2 = XMLoadFloat2(&rhs); - XMStoreFloat2(&result, XMVectorDivide(V1, V2)); + XMStoreFloat2(&result, XMVectorDivide(*this, rhs)); return result; } SHVec2 SHVec2::operator/(float rhs) const noexcept { SHVec2 result; - - const XMVECTOR V = XMLoadFloat2(this); - XMStoreFloat2(&result, XMVectorScale(V, 1.0f / rhs)); + XMStoreFloat2(&result, XMVectorScale(*this, 1.0f / rhs)); return result; } bool SHVec2::operator==(const SHVec2& rhs) const noexcept { - const XMVECTOR V1 = XMLoadFloat2(this); - const XMVECTOR V2 = XMLoadFloat2(&rhs); - - return XMVector2Equal(V1, V2); + return XMVector2Equal(*this, rhs); } bool SHVec2::operator!=(const SHVec2& rhs) const noexcept { - const XMVECTOR V1 = XMLoadFloat2(this); - const XMVECTOR V2 = XMLoadFloat2(&rhs); - - return XMVector2NotEqual(V1, V2); + return XMVector2NotEqual(*this, rhs); } float& SHVec2::operator[](int index) @@ -216,10 +203,8 @@ namespace SHADE SHVec2 operator* (float lhs, const SHVec2& rhs) noexcept { SHVec2 result; - - const XMVECTOR V = XMLoadFloat2(&rhs); - XMStoreFloat2(&result, XMVectorScale(V, lhs)); + XMStoreFloat2(&result, XMVectorScale(rhs, lhs)); return result; } @@ -229,16 +214,12 @@ namespace SHADE float SHVec2::Length() const noexcept { - const XMVECTOR V = XMLoadFloat2(this); - - return XMVectorGetX(XMVector2Length(V)); + return XMVectorGetX(XMVector2Length(*this)); } float SHVec2::LengthSquared() const noexcept { - const XMVECTOR V = XMLoadFloat2(this); - - return XMVectorGetX(XMVector2LengthSq(V)); + return XMVectorGetX(XMVector2LengthSq(*this)); } std::string SHVec2::ToString() const noexcept @@ -251,20 +232,14 @@ namespace SHADE float SHVec2::Dot(const SHVec2& rhs) const noexcept { - const XMVECTOR V1 = XMLoadFloat2(this); - const XMVECTOR V2 = XMLoadFloat2(&rhs); - - return XMVectorGetX(XMVector2Dot(V1, V2)); + return XMVectorGetX(XMVector2Dot(*this, rhs)); } SHVec2 SHVec2::Cross(const SHVec2& rhs) const noexcept { SHVec2 result; - const XMVECTOR V1 = XMLoadFloat2(this); - const XMVECTOR V2 = XMLoadFloat2(&rhs); - - XMStoreFloat2(&result, XMVector2Cross(V1, V2)); + XMStoreFloat2(&result, XMVector2Cross(*this, rhs)); return result; } @@ -276,9 +251,7 @@ namespace SHADE { SHVec2 result; - const XMVECTOR V = XMLoadFloat2(&vec2); - - XMStoreFloat2(&result, XMVector2Normalize(V)); + XMStoreFloat2(&result, XMVector2Normalize(vec2)); return result; } @@ -297,10 +270,10 @@ namespace SHADE SHVec2 result; - XMVECTOR min = XMLoadFloat2(&(*vec2s.begin())); + XMVECTOR min = *vec2s.begin(); for (auto it = vec2s.begin() + 1; it != vec2s.end(); ++it) { - const XMVECTOR tmp = XMLoadFloat2(&(*it)); + const XMVECTOR tmp = *it; min = XMVectorMin(min, tmp); } @@ -318,10 +291,10 @@ namespace SHADE SHVec2 result; - XMVECTOR max = XMLoadFloat2(&(*vec2s.begin())); + XMVECTOR max = *vec2s.begin(); for (auto it = vec2s.begin() + 1; it != vec2s.end(); ++it) { - const XMVECTOR tmp = XMLoadFloat2(&(*it)); + const XMVECTOR tmp = *it; max = XMVectorMax(max, tmp); } @@ -333,11 +306,7 @@ namespace SHADE { SHVec2 result; - const XMVECTOR V = XMLoadFloat2(&v); - const XMVECTOR MIN = XMLoadFloat2(&vMin); - const XMVECTOR MAX = XMLoadFloat2(&vMax); - - XMStoreFloat2(&result, XMVectorClamp(V, MIN, MAX)); + XMStoreFloat2(&result, XMVectorClamp(v, vMin, vMax)); return result; } @@ -345,10 +314,7 @@ namespace SHADE { SHVec2 result; - const XMVECTOR V1 = XMLoadFloat2(&a); - const XMVECTOR V2 = XMLoadFloat2(&b); - - XMStoreFloat2(&result, XMVectorLerp(V1, V2, t)); + XMStoreFloat2(&result, XMVectorLerp(a, b, t)); return result; } @@ -369,10 +335,7 @@ namespace SHADE float SHVec2::Angle(const SHVec2& lhs, const SHVec2& rhs) noexcept { - const XMVECTOR V1 = XMLoadFloat2(&lhs); - const XMVECTOR V2 = XMLoadFloat2(&rhs); - - return XMVectorGetX(XMVector2AngleBetweenVectors(V1, V2)); + return XMVectorGetX(XMVector2AngleBetweenVectors(lhs, rhs)); } float SHVec2::Dot(const SHVec2& lhs, const SHVec2& rhs) noexcept @@ -384,11 +347,10 @@ namespace SHADE { SHVec2 result; - const XMVECTOR U = XMLoadFloat2(&u); const float V_DOT_U = Dot(v, u); const float U_LENSQ = u.LengthSquared(); - XMStoreFloat2(&result, XMVectorScale(U, V_DOT_U / U_LENSQ)); + XMStoreFloat2(&result, XMVectorScale(u, V_DOT_U / U_LENSQ)); return result; } @@ -396,10 +358,8 @@ namespace SHADE { SHVec2 result; - const XMVECTOR V = XMLoadFloat2(&v); - const XMVECTOR N = XMLoadFloat2(&normal); - XMStoreFloat2(&result, XMVector2Reflect(V, N)); + XMStoreFloat2(&result, XMVector2Reflect(v, normal)); return result; } @@ -407,10 +367,9 @@ namespace SHADE { SHVec2 result; - const XMVECTOR V = XMLoadFloat2(&v); const XMMATRIX R = XMMatrixRotationZ(angleInRad); - XMStoreFloat2(&result, XMVector2Transform(V, R)); + XMStoreFloat2(&result, XMVector2Transform(v, R)); return result; } @@ -418,10 +377,9 @@ namespace SHADE { SHVec2 result; - const XMVECTOR V = XMLoadFloat2(&v); const XMMATRIX TF = XMLoadFloat4x4(&transformMtx); - XMStoreFloat2(&result, XMVector2TransformCoord(V, TF)); + XMStoreFloat2(&result, XMVector2TransformCoord(v, TF)); return result; } diff --git a/SHADE_Engine/src/Math/Vector/SHVec2.h b/SHADE_Engine/src/Math/Vector/SHVec2.h index 17642126..7fed19b4 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec2.h +++ b/SHADE_Engine/src/Math/Vector/SHVec2.h @@ -52,9 +52,10 @@ namespace SHADE SHVec2 (SHVec2&& rhs) = default; ~SHVec2 () = default; - SHVec2 () noexcept; - SHVec2 (float n) noexcept; - SHVec2 (float x, float y) noexcept; + SHVec2 () noexcept; + SHVec2 (const XMFLOAT2& xmfloat2) noexcept; + SHVec2 (float n) noexcept; + SHVec2 (float x, float y) noexcept; /*---------------------------------------------------------------------------------*/ /* Operator Overloads */ @@ -63,6 +64,8 @@ namespace SHADE SHVec2& operator= (const SHVec2& rhs) = default; SHVec2& operator= (SHVec2&& rhs) = default; + operator DirectX::XMVECTOR () const noexcept; + SHVec2& operator+= (const SHVec2& rhs) noexcept; SHVec2& operator-= (const SHVec2& rhs) noexcept; SHVec2& operator*= (const SHVec2& rhs) noexcept; diff --git a/SHADE_Engine/src/Math/Vector/SHVec3.cpp b/SHADE_Engine/src/Math/Vector/SHVec3.cpp index 1bcb47b3..45fe4f61 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec3.cpp +++ b/SHADE_Engine/src/Math/Vector/SHVec3.cpp @@ -43,6 +43,10 @@ namespace SHADE : XMFLOAT3( 0.0f, 0.0f, 0.0f ) {} + SHVec3::SHVec3(const XMFLOAT3& xmfloat3) noexcept + : XMFLOAT3 ( xmfloat3.x, xmfloat3.y, xmfloat3.z ) + {} + SHVec3::SHVec3(float n) noexcept : XMFLOAT3( n, n, n ) {} @@ -55,6 +59,12 @@ namespace SHADE /* Operator Overload Definitions */ /*-----------------------------------------------------------------------------------*/ + SHVec3::operator XMVECTOR() const noexcept + { + return XMLoadFloat3(this); + } + + SHVec3& SHVec3::operator+=(const SHVec3& rhs) noexcept { return *this = *this + rhs; @@ -88,22 +98,16 @@ namespace SHADE SHVec3 SHVec3::operator+(const SHVec3& rhs) const noexcept { SHVec3 result; - - const XMVECTOR V1 = XMLoadFloat3(this); - const XMVECTOR V2 = XMLoadFloat3(&rhs); - XMStoreFloat3(&result, XMVectorAdd(V1, V2)); + XMStoreFloat3(&result, XMVectorAdd(*this, rhs)); return result; } SHVec3 SHVec3::operator-(const SHVec3& rhs) const noexcept { SHVec3 result; - - const XMVECTOR V1 = XMLoadFloat3(this); - const XMVECTOR V2 = XMLoadFloat3(&rhs); - XMStoreFloat3(&result, XMVectorSubtract(V1, V2)); + XMStoreFloat3(&result, XMVectorSubtract(*this, rhs)); return result; } @@ -116,59 +120,43 @@ namespace SHADE SHVec3 SHVec3::operator*(const SHVec3& rhs) const noexcept { SHVec3 result; - - const XMVECTOR V1 = XMLoadFloat3(this); - const XMVECTOR V2 = XMLoadFloat3(&rhs); - XMStoreFloat3(&result, XMVectorMultiply(V1, V2)); + XMStoreFloat3(&result, XMVectorMultiply(*this, rhs)); return result; } SHVec3 SHVec3::operator*(float rhs) const noexcept { SHVec3 result; - - const XMVECTOR V = XMLoadFloat3(this); - XMStoreFloat3(&result, XMVectorScale(V, rhs)); + XMStoreFloat3(&result, XMVectorScale(*this, rhs)); return result; } SHVec3 SHVec3::operator/(const SHVec3& rhs) const noexcept { SHVec3 result; - - const XMVECTOR V1 = XMLoadFloat3(this); - const XMVECTOR V2 = XMLoadFloat3(&rhs); - XMStoreFloat3(&result, XMVectorDivide(V1, V2)); + XMStoreFloat3(&result, XMVectorDivide(*this, rhs)); return result; } SHVec3 SHVec3::operator/(float rhs) const noexcept { SHVec3 result; - - const XMVECTOR V = XMLoadFloat3(this); - XMStoreFloat3(&result, XMVectorScale(V, 1.0f / rhs)); + XMStoreFloat3(&result, XMVectorScale(*this, 1.0f / rhs)); return result; } bool SHVec3::operator==(const SHVec3& rhs) const noexcept { - const XMVECTOR V1 = XMLoadFloat3(this); - const XMVECTOR V2 = XMLoadFloat3(&rhs); - - return XMVector3Equal(V1, V2); + return XMVector3Equal(*this, rhs); } bool SHVec3::operator!=(const SHVec3& rhs) const noexcept { - const XMVECTOR V1 = XMLoadFloat3(this); - const XMVECTOR V2 = XMLoadFloat3(&rhs); - - return XMVector3NotEqual(V1, V2); + return XMVector3NotEqual(*this, rhs); } float& SHVec3::operator[](int index) @@ -226,10 +214,8 @@ namespace SHADE SHVec3 operator* (float lhs, const SHVec3& rhs) noexcept { SHVec3 result; - - const XMVECTOR V = XMLoadFloat3(&rhs); - XMStoreFloat3(&result, XMVectorScale(V, lhs)); + XMStoreFloat3(&result, XMVectorScale(rhs, lhs)); return result; } @@ -239,16 +225,12 @@ namespace SHADE float SHVec3::Length() const noexcept { - const XMVECTOR V = XMLoadFloat3(this); - - return XMVectorGetX(XMVector3Length(V)); + return XMVectorGetX(XMVector3Length(*this)); } float SHVec3::LengthSquared() const noexcept { - const XMVECTOR V = XMLoadFloat3(this); - - return XMVectorGetX(XMVector3LengthSq(V)); + return XMVectorGetX(XMVector3LengthSq(*this)); } std::string SHVec3::ToString() const noexcept @@ -261,20 +243,14 @@ namespace SHADE float SHVec3::Dot(const SHVec3& rhs) const noexcept { - const XMVECTOR V1 = XMLoadFloat3(this); - const XMVECTOR V2 = XMLoadFloat3(&rhs); - - return XMVectorGetX(XMVector3Dot(V1, V2)); + return XMVectorGetX(XMVector3Dot(*this, rhs)); } SHVec3 SHVec3::Cross(const SHVec3& rhs) const noexcept { SHVec3 result; - const XMVECTOR V1 = XMLoadFloat3(this); - const XMVECTOR V2 = XMLoadFloat3(&rhs); - - XMStoreFloat3(&result, XMVector3Cross(V1, V2)); + XMStoreFloat3(&result, XMVector3Cross(*this, rhs)); return result; } @@ -286,9 +262,7 @@ namespace SHADE { SHVec3 result; - const XMVECTOR V = XMLoadFloat3(&v); - - XMStoreFloat3(&result, XMVector3Normalize(V)); + XMStoreFloat3(&result, XMVector3Normalize(v)); return result; } @@ -307,10 +281,10 @@ namespace SHADE SHVec3 result; - XMVECTOR min = XMLoadFloat3(&(*vs.begin())); + XMVECTOR min = *vs.begin(); for (auto it = vs.begin() + 1; it != vs.end(); ++it) { - const XMVECTOR tmp = XMLoadFloat3(&(*it)); + const XMVECTOR tmp = *it; min = XMVectorMin(min, tmp); } @@ -328,10 +302,10 @@ namespace SHADE SHVec3 result; - XMVECTOR max = XMLoadFloat3(&(*vs.begin())); + XMVECTOR max = *vs.begin(); for (auto it = vs.begin() + 1; it != vs.end(); ++it) { - const XMVECTOR tmp = XMLoadFloat3(&(*it)); + const XMVECTOR tmp = *it; max = XMVectorMax(max, tmp); } @@ -343,11 +317,7 @@ namespace SHADE { SHVec3 result; - const XMVECTOR V = XMLoadFloat3(&v); - const XMVECTOR MIN = XMLoadFloat3(&vMin); - const XMVECTOR MAX = XMLoadFloat3(&vMax); - - XMStoreFloat3(&result, XMVectorClamp(V, MIN, MAX)); + XMStoreFloat3(&result, XMVectorClamp(v, vMin, vMax)); return result; } @@ -355,10 +325,7 @@ namespace SHADE { SHVec3 result; - const XMVECTOR V1 = XMLoadFloat3(&a); - const XMVECTOR V2 = XMLoadFloat3(&b); - - XMStoreFloat3(&result, XMVectorLerp(V1, V2, t)); + XMStoreFloat3(&result, XMVectorLerp(a, b, t)); return result; } @@ -382,7 +349,7 @@ namespace SHADE const XMVECTOR V1 = XMLoadFloat3(&lhs); const XMVECTOR V2 = XMLoadFloat3(&rhs); - return XMVectorGetX(XMVector3AngleBetweenVectors(V1, V2)); + return XMVectorGetX(XMVector3AngleBetweenVectors(lhs, rhs)); } float SHVec3::Dot(const SHVec3& lhs, const SHVec3& rhs) noexcept @@ -399,22 +366,18 @@ namespace SHADE { SHVec3 result; - const XMVECTOR U = XMLoadFloat3(&u); const float V_DOT_U = Dot(v, u); const float U_LENSQ = u.LengthSquared(); - XMStoreFloat3(&result, XMVectorScale(U, V_DOT_U / U_LENSQ)); + XMStoreFloat3(&result, XMVectorScale(u, V_DOT_U / U_LENSQ)); return result; } SHVec3 SHVec3::Reflect(const SHVec3& v, const SHVec3& normal) noexcept { SHVec3 result; - - const XMVECTOR V = XMLoadFloat3(&v); - const XMVECTOR N = XMLoadFloat3(&normal); - XMStoreFloat3(&result, XMVector3Reflect(V, N)); + XMStoreFloat3(&result, XMVector3Reflect(v, normal)); return result; } @@ -422,12 +385,9 @@ namespace SHADE { SHVec3 result; - const XMVECTOR V = XMLoadFloat3(&v); + const XMVECTOR Q = XMQuaternionRotationAxis(axis, angleInRad); - const XMVECTOR AXIS = XMLoadFloat3(&axis); - const XMVECTOR Q = XMQuaternionRotationAxis(AXIS, angleInRad); - - XMStoreFloat3(&result, XMVector3Rotate(V, Q)); + XMStoreFloat3(&result, XMVector3Rotate(v, Q)); return result; } @@ -435,10 +395,9 @@ namespace SHADE { SHVec3 result; - const XMVECTOR V = XMLoadFloat3(&v); - const XMMATRIX R = XMMatrixRotationX(angleInRad); + const XMMATRIX R = XMMatrixRotationX(angleInRad); - XMStoreFloat3(&result, XMVector3TransformCoord(V, R)); + XMStoreFloat3(&result, XMVector3TransformCoord(v, R)); return result; } @@ -446,10 +405,9 @@ namespace SHADE { SHVec3 result; - const XMVECTOR V = XMLoadFloat3(&v); - const XMMATRIX R = XMMatrixRotationY(angleInRad); + const XMMATRIX R = XMMatrixRotationY(angleInRad); - XMStoreFloat3(&result, XMVector3TransformCoord(V, R)); + XMStoreFloat3(&result, XMVector3TransformCoord(v, R)); return result; } @@ -457,10 +415,9 @@ namespace SHADE { SHVec3 result; - const XMVECTOR V = XMLoadFloat3(&v); - const XMMATRIX R = XMMatrixRotationZ(angleInRad); + const XMMATRIX R = XMMatrixRotationZ(angleInRad); - XMStoreFloat3(&result, XMVector3TransformCoord(V, R)); + XMStoreFloat3(&result, XMVector3TransformCoord(v, R)); return result; } @@ -468,10 +425,9 @@ namespace SHADE { SHVec3 result; - const XMVECTOR V = XMLoadFloat3(&v); const XMMATRIX TF = XMLoadFloat4x4(&transformMtx); - XMStoreFloat3(&result, XMVector3TransformCoord(V, TF)); + XMStoreFloat3(&result, XMVector3TransformCoord(v, TF)); return result; } } \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Vector/SHVec3.h b/SHADE_Engine/src/Math/Vector/SHVec3.h index cc0e043e..fb9d0d4a 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec3.h +++ b/SHADE_Engine/src/Math/Vector/SHVec3.h @@ -58,6 +58,7 @@ namespace SHADE ~SHVec3 () = default; SHVec3 () noexcept; + SHVec3 (const XMFLOAT3& xmfloat3) noexcept; SHVec3 (float n) noexcept; SHVec3 (float x, float y, float z) noexcept; @@ -68,6 +69,8 @@ namespace SHADE SHVec3& operator= (const SHVec3& rhs) = default; SHVec3& operator= (SHVec3&& rhs) = default; + operator DirectX::XMVECTOR () const noexcept; + SHVec3& operator+= (const SHVec3& rhs) noexcept; SHVec3& operator-= (const SHVec3& rhs) noexcept; SHVec3& operator*= (const SHVec3& rhs) noexcept; diff --git a/SHADE_Engine/src/Math/Vector/SHVec4.cpp b/SHADE_Engine/src/Math/Vector/SHVec4.cpp index d1c87865..bcf2ef97 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec4.cpp +++ b/SHADE_Engine/src/Math/Vector/SHVec4.cpp @@ -38,6 +38,10 @@ namespace SHADE : XMFLOAT4( 0.0f, 0.0f, 0.0f, 0.0f ) {} + SHVec4::SHVec4(const XMFLOAT4& xmfloat4) noexcept + : XMFLOAT4( xmfloat4.x, xmfloat4.y, xmfloat4.z, xmfloat4.w ) + {} + SHVec4::SHVec4(float _x, float _y, float _z, float _w) noexcept : XMFLOAT4( _x, _y, _z, _w ) {} @@ -46,6 +50,11 @@ namespace SHADE /* Operator Overload Definitions */ /*-----------------------------------------------------------------------------------*/ + SHVec4::operator XMVECTOR() const noexcept + { + return XMLoadFloat4(this); + } + SHVec4& SHVec4::operator+=(const SHVec4& rhs) noexcept { return *this = *this + rhs; @@ -79,22 +88,16 @@ namespace SHADE SHVec4 SHVec4::operator+(const SHVec4& rhs) const noexcept { SHVec4 result; - - const XMVECTOR V1 = XMLoadFloat4(this); - const XMVECTOR V2 = XMLoadFloat4(&rhs); - XMStoreFloat4(&result, XMVectorAdd(V1, V2)); + XMStoreFloat4(&result, XMVectorAdd(*this, rhs)); return result; } SHVec4 SHVec4::operator-(const SHVec4& rhs) const noexcept { SHVec4 result; - - const XMVECTOR V1 = XMLoadFloat4(this); - const XMVECTOR V2 = XMLoadFloat4(&rhs); - XMStoreFloat4(&result, XMVectorSubtract(V1, V2)); + XMStoreFloat4(&result, XMVectorSubtract(*this, rhs)); return result; } @@ -106,59 +109,43 @@ namespace SHADE SHVec4 SHVec4::operator*(const SHVec4& rhs) const noexcept { SHVec4 result; - - const XMVECTOR V1 = XMLoadFloat4(this); - const XMVECTOR V2 = XMLoadFloat4(&rhs); - XMStoreFloat4(&result, XMVectorMultiply(V1, V2)); + XMStoreFloat4(&result, XMVectorMultiply(*this, rhs)); return result; } SHVec4 SHVec4::operator*(float rhs) const noexcept { SHVec4 result; - - const XMVECTOR V = XMLoadFloat4(this); - XMStoreFloat4(&result, XMVectorScale(V, rhs)); + XMStoreFloat4(&result, XMVectorScale(*this, rhs)); return result; } SHVec4 SHVec4::operator/(const SHVec4& rhs) const noexcept { SHVec4 result; - - const XMVECTOR V1 = XMLoadFloat4(this); - const XMVECTOR V2 = XMLoadFloat4(&rhs); - XMStoreFloat4(&result, XMVectorDivide(V1, V2)); + XMStoreFloat4(&result, XMVectorDivide(*this, rhs)); return result; } SHVec4 SHVec4::operator/(float rhs) const noexcept { SHVec4 result; - - const XMVECTOR V = XMLoadFloat4(this); - XMStoreFloat4(&result, XMVectorScale(V, 1.0f / rhs)); + XMStoreFloat4(&result, XMVectorScale(*this, 1.0f / rhs)); return result; } bool SHVec4::operator==(const SHVec4& rhs) const noexcept { - const XMVECTOR V1 = XMLoadFloat4(this); - const XMVECTOR V2 = XMLoadFloat4(&rhs); - - return XMVector4Equal(V1, V2); + return XMVector4Equal(*this, rhs); } bool SHVec4::operator!=(const SHVec4& rhs) const noexcept { - const XMVECTOR V1 = XMLoadFloat4(this); - const XMVECTOR V2 = XMLoadFloat4(&rhs); - - return XMVector4NotEqual(V1, V2); + return XMVector4NotEqual(*this, rhs); } float& SHVec4::operator[](int index) @@ -220,10 +207,8 @@ namespace SHADE SHVec4 operator* (float lhs, const SHVec4& rhs) noexcept { SHVec4 result; - - const XMVECTOR V = XMLoadFloat4(&rhs); - XMStoreFloat4(&result, XMVectorScale(V, lhs)); + XMStoreFloat4(&result, XMVectorScale(rhs, lhs)); return result; } @@ -233,30 +218,22 @@ namespace SHADE float SHVec4::Length() const noexcept { - const XMVECTOR V = XMLoadFloat4(this); - - return XMVectorGetX(XMVector4Length(V)); + return XMVectorGetX(XMVector4Length(*this)); } float SHVec4::Length3D() const noexcept { - const XMVECTOR V = XMLoadFloat4(this); - - return XMVectorGetX(XMVector3Length(V)); + return XMVectorGetX(XMVector3Length(*this)); } float SHVec4::LengthSquared() const noexcept { - const XMVECTOR V = XMLoadFloat4(this); - - return XMVectorGetX(XMVector4LengthSq(V)); + return XMVectorGetX(XMVector4LengthSq(*this)); } float SHVec4::LengthSquared3D() const noexcept { - const XMVECTOR V = XMLoadFloat4(this); - - return XMVectorGetX(XMVector3LengthSq(V)); + return XMVectorGetX(XMVector3LengthSq(*this)); } std::string SHVec4::ToString() const noexcept @@ -269,28 +246,19 @@ namespace SHADE float SHVec4::Dot(const SHVec4& rhs) const noexcept { - const XMVECTOR V1 = XMLoadFloat4(this); - const XMVECTOR V2 = XMLoadFloat4(&rhs); - - return XMVectorGetX(XMVector4Dot(V1, V2)); + return XMVectorGetX(XMVector4Dot(*this, rhs)); } float SHVec4::Dot3D(const SHVec4& rhs) const noexcept { - const XMVECTOR V1 = XMLoadFloat4(this); - const XMVECTOR V2 = XMLoadFloat4(&rhs); - - return XMVectorGetX(XMVector3Dot(V1, V2)); + return XMVectorGetX(XMVector3Dot(*this, rhs)); } SHVec4 SHVec4::Cross3D(const SHVec4& rhs) const noexcept { SHVec4 result; - const XMVECTOR V1 = XMLoadFloat4(this); - const XMVECTOR V2 = XMLoadFloat4(&rhs); - - XMStoreFloat4(&result, XMVector3Cross(V1, V2)); + XMStoreFloat4(&result, XMVector3Cross(*this, rhs)); result.w = 1.0f; return result; } @@ -299,11 +267,7 @@ namespace SHADE { SHVec4 result; - const XMVECTOR V3 = XMLoadFloat4(this); - const XMVECTOR V1 = XMLoadFloat4(&v1); - const XMVECTOR V2 = XMLoadFloat4(&v2); - - XMStoreFloat4(&result, XMVector4Cross(V3, V1, V2)); + XMStoreFloat4(&result, XMVector4Cross(*this, v1, v2)); return result; } @@ -315,9 +279,7 @@ namespace SHADE { SHVec4 result; - const XMVECTOR V = XMLoadFloat4(&v); - - XMStoreFloat4(&result, XMVector4Normalize(V)); + XMStoreFloat4(&result, XMVector4Normalize(v)); return result; } @@ -325,9 +287,7 @@ namespace SHADE { SHVec4 result; - const XMVECTOR V = XMLoadFloat4(&v); - - XMStoreFloat4(&result, XMVector3Normalize(V)); + XMStoreFloat4(&result, XMVector3Normalize(v)); result.w = 1.0f; return result; } @@ -347,10 +307,10 @@ namespace SHADE SHVec4 result; - XMVECTOR min = XMLoadFloat4(&(*vs.begin())); + XMVECTOR min = *vs.begin(); for (auto it = vs.begin() + 1; it != vs.end(); ++it) { - const XMVECTOR tmp = XMLoadFloat4(&(*it)); + const XMVECTOR tmp = *it; min = XMVectorMin(min, tmp); } @@ -368,10 +328,10 @@ namespace SHADE SHVec4 result; - XMVECTOR max = XMLoadFloat4(&(*vs.begin())); + XMVECTOR max = *vs.begin(); for (auto it = vs.begin() + 1; it != vs.end(); ++it) { - const XMVECTOR tmp = XMLoadFloat4(&(*it)); + const XMVECTOR tmp = *it; max = XMVectorMax(max, tmp); } @@ -383,11 +343,7 @@ namespace SHADE { SHVec4 result; - const XMVECTOR V = XMLoadFloat4(&v); - const XMVECTOR MIN = XMLoadFloat4(&vMin); - const XMVECTOR MAX = XMLoadFloat4(&vMax); - - XMStoreFloat4(&result, XMVectorClamp(V, MIN, MAX)); + XMStoreFloat4(&result, XMVectorClamp(v, vMin, vMax)); return result; } @@ -395,10 +351,7 @@ namespace SHADE { SHVec4 result; - const XMVECTOR V1 = XMLoadFloat4(&a); - const XMVECTOR V2 = XMLoadFloat4(&b); - - XMStoreFloat4(&result, XMVectorLerp(V1, V2, t)); + XMStoreFloat4(&result, XMVectorLerp(a, b, t)); return result; } @@ -429,18 +382,12 @@ namespace SHADE float SHVec4::Angle(const SHVec4& lhs, const SHVec4& rhs) noexcept { - const XMVECTOR V1 = XMLoadFloat4(&lhs); - const XMVECTOR V2 = XMLoadFloat4(&rhs); - - return XMVectorGetX(XMVector4AngleBetweenVectors(V1, V2)); + return XMVectorGetX(XMVector4AngleBetweenVectors(lhs,rhs)); } float SHVec4::Angle3D(const SHVec4& lhs, const SHVec4& rhs) noexcept { - const XMVECTOR V1 = XMLoadFloat4(&lhs); - const XMVECTOR V2 = XMLoadFloat4(&rhs); - - return XMVectorGetX(XMVector3AngleBetweenVectors(V1, V2)); + return XMVectorGetX(XMVector3AngleBetweenVectors(lhs,rhs)); } float SHVec4::Dot(const SHVec4& lhs, const SHVec4& rhs) noexcept @@ -467,11 +414,10 @@ namespace SHADE { SHVec4 result; - const XMVECTOR U = XMLoadFloat4(&u); const float V_DOT_U = Dot(v, u); const float U_LENSQ = u.LengthSquared(); - XMStoreFloat4(&result, XMVectorScale(U, V_DOT_U / U_LENSQ)); + XMStoreFloat4(&result, XMVectorScale(u, V_DOT_U / U_LENSQ)); return result; } @@ -479,11 +425,10 @@ namespace SHADE { SHVec4 result; - const XMVECTOR U = XMLoadFloat4(&u); const float V_DOT_U = Dot3D(v, u); const float U_LENSQ = u.LengthSquared3D(); - XMStoreFloat4(&result, XMVectorScale(U, V_DOT_U / U_LENSQ)); + XMStoreFloat4(&result, XMVectorScale(u, V_DOT_U / U_LENSQ)); result.w = 1.0f; return result; } @@ -491,11 +436,8 @@ namespace SHADE SHVec4 SHVec4::Reflect(const SHVec4& v, const SHVec4& normal) noexcept { SHVec4 result; - - const XMVECTOR V = XMLoadFloat4(&v); - const XMVECTOR N = XMLoadFloat4(&normal); - XMStoreFloat4(&result, XMVector4Reflect(V, N)); + XMStoreFloat4(&result, XMVector4Reflect(v, normal)); result.w = 1.0f; return result; } @@ -503,11 +445,8 @@ namespace SHADE SHVec4 SHVec4::Reflect3D(const SHVec4& v, const SHVec4& normal) noexcept { SHVec4 result; - - const XMVECTOR V = XMLoadFloat4(&v); - const XMVECTOR N = XMLoadFloat4(&normal); - XMStoreFloat4(&result, XMVector3Reflect(V, N)); + XMStoreFloat4(&result, XMVector3Reflect(v, normal)); result.w = 1.0f; return result; } @@ -516,10 +455,9 @@ namespace SHADE { SHVec4 result; - const XMVECTOR V = XMLoadFloat4(&v); const XMMATRIX TF = XMLoadFloat4x4(&transformMtx); - XMStoreFloat4(&result, XMVector3TransformCoord(V, TF)); + XMStoreFloat4(&result, XMVector3TransformCoord(v, TF)); return result; } } \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Vector/SHVec4.h b/SHADE_Engine/src/Math/Vector/SHVec4.h index 59038065..911a714e 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec4.h +++ b/SHADE_Engine/src/Math/Vector/SHVec4.h @@ -52,8 +52,9 @@ namespace SHADE SHVec4 (SHVec4&& rhs) = default; ~SHVec4 () = default; - SHVec4 () noexcept; - SHVec4 (float x, float y, float z, float w) noexcept; + SHVec4 () noexcept; + SHVec4 (const XMFLOAT4& xmfloat4) noexcept; + SHVec4 (float x, float y, float z, float w) noexcept; /*---------------------------------------------------------------------------------*/ /* Operator Overloads */ @@ -62,6 +63,8 @@ namespace SHADE SHVec4& operator= (const SHVec4& rhs) = default; SHVec4& operator= (SHVec4&& rhs) = default; + operator DirectX::XMVECTOR () const noexcept; + SHVec4& operator+= (const SHVec4& rhs) noexcept; SHVec4& operator-= (const SHVec4& rhs) noexcept; SHVec4& operator*= (const SHVec4& rhs) noexcept; From 381217a1b870b90b3d8f2b80e4ebaf9a20e2a5f9 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 13 Oct 2022 03:03:21 +0800 Subject: [PATCH 36/61] Added Colour --- SHADE_Engine/src/Math/SHColour.cpp | 297 ++++++++++++++++++++++++ SHADE_Engine/src/Math/SHColour.h | 166 +++++++++++++ SHADE_Engine/src/Math/Vector/SHVec3.cpp | 1 + 3 files changed, 464 insertions(+) create mode 100644 SHADE_Engine/src/Math/SHColour.cpp create mode 100644 SHADE_Engine/src/Math/SHColour.h diff --git a/SHADE_Engine/src/Math/SHColour.cpp b/SHADE_Engine/src/Math/SHColour.cpp new file mode 100644 index 00000000..8aae2cb3 --- /dev/null +++ b/SHADE_Engine/src/Math/SHColour.cpp @@ -0,0 +1,297 @@ +/**************************************************************************************** + * \file SHColour.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for a Colour. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + + +#include + +// Primary Header +#include "SHColour.h" +// Project Headers +#include "SHMathHelpers.h" + +using namespace DirectX; + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Static Data Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + const SHColour SHColour::BEIGE = DirectX::Colors::Beige; + const SHColour SHColour::BLACK = DirectX::Colors::Black; + const SHColour SHColour::BLUE = DirectX::Colors::Blue; + const SHColour SHColour::BROWN = DirectX::Colors::Brown; + const SHColour SHColour::CHOCOLATE = DirectX::Colors::Chocolate; + const SHColour SHColour::CORAL = DirectX::Colors::Coral; + const SHColour SHColour::CRIMSON = DirectX::Colors::Crimson; + const SHColour SHColour::CYAN = DirectX::Colors::Cyan; + const SHColour SHColour::DARKBLUE = DirectX::Colors::DarkBlue; + const SHColour SHColour::DARKGRAY = DirectX::Colors::DarkGray; + const SHColour SHColour::DARKGREEN = DirectX::Colors::DarkGreen; + const SHColour SHColour::DARKMAGENTA = DirectX::Colors::DarkMagenta; + const SHColour SHColour::DARKORANGE = DirectX::Colors::DarkOrange; + const SHColour SHColour::DARKRED = DirectX::Colors::DarkRed; + const SHColour SHColour::DEEPPINK = DirectX::Colors::DeepPink; + const SHColour SHColour::FORESTGREEN = DirectX::Colors::ForestGreen; + const SHColour SHColour::FUCHSIA = DirectX::Colors::Fuchsia; + const SHColour SHColour::GOLD = DirectX::Colors::Gold; + const SHColour SHColour::GRAY = DirectX::Colors::Gray; + const SHColour SHColour::GREEN = DirectX::Colors::Green; + const SHColour SHColour::HOTPINK = DirectX::Colors::HotPink; + const SHColour SHColour::INDIGO = DirectX::Colors::Indigo; + const SHColour SHColour::LAVENDER = DirectX::Colors::Lavender; + const SHColour SHColour::LIGHTBLUE = DirectX::Colors::LightBlue; + const SHColour SHColour::LIGHTGRAY = DirectX::Colors::LightGray; + const SHColour SHColour::LIGHTGREEN = DirectX::Colors::LightGreen; + const SHColour SHColour::LIGHTPINK = DirectX::Colors::LightPink; + const SHColour SHColour::LIGHTYELLOW = DirectX::Colors::LightYellow; + const SHColour SHColour::LIME = DirectX::Colors::Lime; + const SHColour SHColour::LIMEGREEN = DirectX::Colors::LimeGreen; + const SHColour SHColour::MAGENTA = DirectX::Colors::Magenta; + const SHColour SHColour::MAROON = DirectX::Colors::Maroon; + const SHColour SHColour::MEDIUMBLUE = DirectX::Colors::MediumBlue; + const SHColour SHColour::MEDIUMPURPLE = DirectX::Colors::MediumPurple; + const SHColour SHColour::NAVY = DirectX::Colors::Navy; + const SHColour SHColour::OLIVE = DirectX::Colors::Olive; + const SHColour SHColour::ORANGE = DirectX::Colors::Orange; + const SHColour SHColour::ORCHID = DirectX::Colors::Orchid; + const SHColour SHColour::PINK = DirectX::Colors::Pink; + const SHColour SHColour::PURPLE = DirectX::Colors::Purple; + const SHColour SHColour::RED = DirectX::Colors::Red; + const SHColour SHColour::ROYALBLUE = DirectX::Colors::RoyalBlue; + const SHColour SHColour::SALMON = DirectX::Colors::Salmon; + const SHColour SHColour::SANDYBROWN = DirectX::Colors::SandyBrown; + const SHColour SHColour::SILVER = DirectX::Colors::Silver; + const SHColour SHColour::SKYBLUE = DirectX::Colors::SkyBlue; + const SHColour SHColour::SLATEGRAY = DirectX::Colors::SlateGray; + const SHColour SHColour::SNOW = DirectX::Colors::Snow; + const SHColour SHColour::STEELBLUE = DirectX::Colors::SteelBlue; + const SHColour SHColour::TAN = DirectX::Colors::Tan; + const SHColour SHColour::TEAL = DirectX::Colors::Teal; + const SHColour SHColour::TURQUOISE = DirectX::Colors::Turquoise; + const SHColour SHColour::VIOLET = DirectX::Colors::Violet; + const SHColour SHColour::WHITE = DirectX::Colors::White; + const SHColour SHColour::YELLOW = DirectX::Colors::Yellow; + + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHColour::SHColour() noexcept + : SHVec4 { 0.0f, 0.0f, 0.0f, 1.0f } + {} + + SHColour::SHColour(float r, float g, float b) noexcept + : SHVec4 { r, g, b, 1.0f } + {} + + SHColour::SHColour(float r, float g, float b, float a) noexcept + : SHVec4 { r, g, b, a } + {} + + SHColour::SHColour(uint8_t r, uint8_t g, uint8_t b) noexcept + : SHVec4 + { + static_cast(r) / 255.0f, + static_cast(g) / 255.0f, + static_cast(b) / 255.0f, + 1.0f + } + {} + + SHColour::SHColour(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept + : SHVec4 + { + static_cast(r) / 255.0f, + static_cast(g) / 255.0f, + static_cast(b) / 255.0f, + static_cast(a) / 255.0f + } + {} + + SHColour::SHColour(const DirectX::XMFLOAT3& colour) noexcept + : SHVec4 { colour.x, colour.y, colour.z, 1.0f } + {} + + SHColour::SHColour(const DirectX::XMVECTORF32& colour) noexcept + : SHVec4 + { + XMVectorGetX(colour), + XMVectorGetY(colour), + XMVectorGetZ(colour), + XMVectorGetW(colour) + } + {} + + /*-----------------------------------------------------------------------------------*/ + /* Operator Overload Definitions */ + /*-----------------------------------------------------------------------------------*/ + + bool SHColour::operator==(const SHColour& rhs) const noexcept + { + return XMColorEqual(*this, rhs); + } + + bool SHColour::operator!=(const SHColour& rhs) const noexcept + { + return XMColorNotEqual(*this, rhs); + } + + /*-----------------------------------------------------------------------------------*/ + /* Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHColourHSV SHColour::ToHSV() noexcept + { + SHColourHSV hsv; + + const float MIN = SHMath::Min({ x, y, z }); + const float MAX = SHMath::Max({ x, y, z }); + + hsv.v = MAX; + + const float DELTA = MAX - MIN; + hsv.s = (MAX != 0.0f) ? DELTA / MAX : 0.0f; + + static const float SIN_60 = sin(SHMath::DegreesToRadians(60.0f)); + + if (DELTA == 0.0f) + hsv.h = 0.0f; + else if (x == MAX) + hsv.h = (y - z) / DELTA; + else if (y == MAX) + hsv.h = 2.0f + (z - x) / DELTA; + else + hsv.h = 4.0f + (x - y) / DELTA; + + hsv.h *= 60; + if (hsv.h < 0.0f) + hsv.h += 360.f; + + return hsv; + } + + void SHColour::Negate() noexcept + { + XMStoreFloat4(this, XMColorNegative(*this)); + } + + void SHColour::Saturate() noexcept + { + XMStoreFloat4(this, XMVectorSaturate(*this)); + } + + void SHColour::AdjustSaturation(float saturation) noexcept + { + XMStoreFloat4(this, XMColorAdjustSaturation(*this, saturation)); + } + + void SHColour::AdjustContrast(float contrast) noexcept + { + XMStoreFloat4(this, XMColorAdjustContrast(*this, contrast)); + } + + /*-----------------------------------------------------------------------------------*/ + /* Static Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHColour SHColour::Modulate(const SHColour& lhs, const SHColour& rhs) noexcept + { + SHColour result; + XMStoreFloat4(&result, XMColorModulate(lhs, rhs)); + return result; + } + + SHColour SHColour::FromHSV(float hue, float saturation, float value) + { + if (hue < 0.0f || saturation < 0.0f || value < 0.0f) + throw std::invalid_argument("One or more of the hsv values are invalid!"); + + SHColour colour; + + if (saturation == 0.0f) + { + colour.x = colour.y = colour.z = value; + } + else + { + hue /= 60.0f; + + const int SECTOR = static_cast(hue); + + const float F = hue - static_cast(SECTOR); + const float P = value * (1.0f - saturation); + const float Q = value * (1.0f - saturation * F); + const float T = value * (1.0f - saturation * (1.0f - F)); + + switch (SECTOR) + { + case 0: + { + colour.x = value; + colour.y = T; + colour.z = P; + + break; + } + case 1: + { + colour.x = Q; + colour.y = value; + colour.z = P; + + break; + } + case 2: + { + colour.x = P; + colour.y = value; + colour.z = T; + + break; + } + case 3: + { + colour.x = P; + colour.y = Q; + colour.z = value; + + break; + } + case 4: + { + colour.x = T; + colour.y = P; + colour.z = value; + + break; + } + default: + { + colour.x = value; + colour.y = P; + colour.z = Q; + + break; + } + } + } + + return colour; + } + + SHColour SHColour::FromHSV(const SHColourHSV& hsv) + { + return FromHSV(hsv.h, hsv.s, hsv.v); + } + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/SHColour.h b/SHADE_Engine/src/Math/SHColour.h new file mode 100644 index 00000000..bd2bc9e7 --- /dev/null +++ b/SHADE_Engine/src/Math/SHColour.h @@ -0,0 +1,166 @@ +/**************************************************************************************** + * \file SHColour.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for a Colour. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include + +// Project Headers +#include "SH_API.h" +#include "Vector/SHVec3.h" +#include "Vector/SHVec4.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*-----------------------------------------------------------------------------------*/ + + class SHColour; + + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + struct SH_API SHColourHSV + { + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + float h = 0.0f; + float s = 0.0f; + float v = 0.0f; + }; + + class SH_API SHColour : private SHVec4 + { + public: + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHColour () noexcept; + SHColour (float r, float g, float b) noexcept; + SHColour (float r, float g, float b, float a) noexcept; + SHColour (uint8_t r, uint8_t g, uint8_t b) noexcept; + SHColour (uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept; + + SHColour (const SHVec3& colour) noexcept; + SHColour (const DirectX::XMFLOAT3& colour) noexcept; + SHColour (const DirectX::XMVECTORF32& colour) noexcept; + + SHColour (const SHColour&) = default; + SHColour (SHColour&&) = default; + + ~SHColour () = default; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + SHColour& operator= (const SHColour&) = default; + SHColour& operator= (SHColour&&) = default; + + bool operator== (const SHColour& rhs) const noexcept; + bool operator!= (const SHColour& rhs) const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] inline float& r() noexcept { return x; } + [[nodiscard]] inline float& g() noexcept { return y; } + [[nodiscard]] inline float& b() noexcept { return z; } + [[nodiscard]] inline float& a() noexcept { return w; } + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + SHColourHSV ToHSV () noexcept; + + void Negate () noexcept; + void Saturate () noexcept; + + void AdjustSaturation (float saturation) noexcept; + void AdjustContrast (float contrast) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Static Function Members */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] static SHColour Modulate (const SHColour& lhs, const SHColour& rhs) noexcept; + [[nodiscard]] static SHColour FromHSV (float hue, float saturation, float value); + [[nodiscard]] static SHColour FromHSV (const SHColourHSV& hsv); + + /*---------------------------------------------------------------------------------*/ + /* Static Data Members */ + /*---------------------------------------------------------------------------------*/ + + static const SHColour BEIGE ; + static const SHColour BLACK ; + static const SHColour BLUE ; + static const SHColour BROWN ; + static const SHColour CHOCOLATE ; + static const SHColour CORAL ; + static const SHColour CRIMSON ; + static const SHColour CYAN ; + static const SHColour DARKBLUE ; + static const SHColour DARKGRAY ; + static const SHColour DARKGREEN ; + static const SHColour DARKMAGENTA ; + static const SHColour DARKORANGE ; + static const SHColour DARKRED ; + static const SHColour DEEPPINK ; + static const SHColour FORESTGREEN ; + static const SHColour FUCHSIA ; + static const SHColour GOLD ; + static const SHColour GRAY ; + static const SHColour GREEN ; + static const SHColour HOTPINK ; + static const SHColour INDIGO ; + static const SHColour LAVENDER ; + static const SHColour LIGHTBLUE ; + static const SHColour LIGHTGRAY ; + static const SHColour LIGHTGREEN ; + static const SHColour LIGHTPINK ; + static const SHColour LIGHTYELLOW ; + static const SHColour LIME ; + static const SHColour LIMEGREEN ; + static const SHColour MAGENTA ; + static const SHColour MAROON ; + static const SHColour MEDIUMBLUE ; + static const SHColour MEDIUMPURPLE; + static const SHColour NAVY ; + static const SHColour OLIVE ; + static const SHColour ORANGE ; + static const SHColour ORCHID ; + static const SHColour PINK ; + static const SHColour PURPLE ; + static const SHColour RED ; + static const SHColour ROYALBLUE ; + static const SHColour SALMON ; + static const SHColour SANDYBROWN ; + static const SHColour SILVER ; + static const SHColour SKYBLUE ; + static const SHColour SLATEGRAY ; + static const SHColour SNOW ; + static const SHColour STEELBLUE ; + static const SHColour TAN ; + static const SHColour TEAL ; + static const SHColour TURQUOISE ; + static const SHColour VIOLET ; + static const SHColour WHITE ; + static const SHColour YELLOW; + }; + + +} // namespace SHADE diff --git a/SHADE_Engine/src/Math/Vector/SHVec3.cpp b/SHADE_Engine/src/Math/Vector/SHVec3.cpp index 45fe4f61..c248ebce 100644 --- a/SHADE_Engine/src/Math/Vector/SHVec3.cpp +++ b/SHADE_Engine/src/Math/Vector/SHVec3.cpp @@ -23,6 +23,7 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ /* Static Data Member Definitions */ /*-----------------------------------------------------------------------------------*/ + SHVec3 const SHVec3::Zero { 0.0f, 0.0f, 0.0f }; SHVec3 const SHVec3::One { 1.0f, 1.0f, 1.0f }; SHVec3 const SHVec3::Left { -1.0f, 0.0f, 0.0f }; From 0a3d211f027507ab99f6498c55bb479b739e0177 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Thu, 13 Oct 2022 16:57:08 +0800 Subject: [PATCH 37/61] Added a render target to store entity ID Pipelines created from pipeline library now checks if the resources pointed to by a subpass requires blending and adds a blend state accordingly. Fragment shader writes to this new render target for testing (works) --- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 14 ++++----- .../MiddleEnd/Pipeline/SHPipelineLibrary.cpp | 27 ++++++++++++++++++ .../src/Graphics/Pipeline/SHPipelineState.h | 17 ++--------- .../RenderGraph/SHRenderGraphNode.cpp | 9 ++++++ .../Graphics/RenderGraph/SHRenderGraphNode.h | 1 + .../RenderGraph/SHRenderGraphResource.cpp | 5 ++++ .../RenderGraph/SHRenderGraphResource.h | 2 ++ .../src/Graphics/RenderGraph/SHSubpass.cpp | 13 +++++++++ .../src/Graphics/RenderGraph/SHSubpass.h | 3 +- SHADE_Engine/src/Graphics/SHVkUtil.cpp | 19 ++++++++++++ SHADE_Engine/src/Graphics/SHVkUtil.h | 1 + TempShaderFolder/TestCubeFs.glsl | 3 +- TempShaderFolder/TestCubeFs.spv | Bin 1984 -> 2100 bytes 13 files changed, 88 insertions(+), 26 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 6957aa93..09579f02 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -143,26 +143,22 @@ namespace SHADE // Initialize world render graph worldRenderGraph->Init(device, swapchain); + worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second); worldRenderGraph->AddResource("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); + worldRenderGraph->AddResource("Entity ID", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR32Uint); + //worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); //worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); //worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); //worldRenderGraph->AddResource("Scene", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eB8G8R8A8Unorm); - worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second); - auto node = worldRenderGraph->AddNode("G-Buffer", { /*"Composite", "Position", */"Depth Buffer", "Present" }, {}); // no predecessors + auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Present"}, {}); // no predecessors //First subpass to write to G-Buffer auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write"); - //gBufferWriteSubpass->AddColorOutput("Scene"); gBufferWriteSubpass->AddColorOutput("Present"); + gBufferWriteSubpass->AddColorOutput("Entity ID"); gBufferWriteSubpass->AddDepthOutput ("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL); - //writeSubpass->AddColorOutput("Normals"); - // //Second subpass to read from G-Buffer - //auto compositeSubpass = node->AddSubpass("G-Buffer Composite"); - //compositeSubpass->AddColorOutput("Present"); // TODO: This should be "Composite" and then composite will write to swapchain image "Present" - //compositeSubpass->AddInput("Normals"); - //compositeSubpass->AddInput("Position"); // TODO: Use macro to add this node when SH_EDITOR is enabled auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {"G-Buffer"}); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp index 10b42a9e..682b549c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp @@ -2,6 +2,8 @@ #include "SHPipelineLibrary.h" #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/RenderGraph/SHSubpass.h" +#include "Graphics/SHVkUtil.h" namespace SHADE { @@ -20,6 +22,31 @@ namespace SHADE // Create the pipeline and configure the default vertex input state auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass); newPipeline->GetPipelineState().SetVertexInputState(SHGraphicsGlobalData::GetDefaultViState()); + + SHColorBlendState colorBlendState{}; + colorBlendState.logic_op_enable = VK_FALSE; + colorBlendState.logic_op = vk::LogicOp::eCopy; + + auto const& subpassColorReferences = subpass->GetColorAttachmentReferences(); + colorBlendState.attachments.reserve(subpassColorReferences.size()); + + for (auto& att : subpassColorReferences) + { + colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState + { + .blendEnable = SHVkUtil::IsBlendCompatible (subpass->GetFormatFromAttachmentReference(att.attachment)) ? true : false, + .srcColorBlendFactor = vk::BlendFactor::eSrcAlpha, + .dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha, + .colorBlendOp = vk::BlendOp::eAdd, + .srcAlphaBlendFactor = vk::BlendFactor::eOne, + .dstAlphaBlendFactor = vk::BlendFactor::eZero, + .alphaBlendOp = vk::BlendOp::eAdd, + .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA, + } + ); + } + + newPipeline->GetPipelineState().SetColorBlenState(colorBlendState); // Actually construct the pipeline newPipeline->ConstructPipeline(); diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h index 2769d6cc..4c8d679a 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h @@ -137,22 +137,9 @@ namespace SHADE { VkBool32 logic_op_enable{ VK_FALSE }; - vk::LogicOp logic_op{ VK_LOGIC_OP_COPY }; + vk::LogicOp logic_op{ vk::LogicOp::eCopy }; - std::vector attachments = - { - vk::PipelineColorBlendAttachmentState - { - .blendEnable = true, - .srcColorBlendFactor = vk::BlendFactor::eSrcAlpha, - .dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha, - .colorBlendOp = vk::BlendOp::eAdd, - .srcAlphaBlendFactor = vk::BlendFactor::eOne, - .dstAlphaBlendFactor = vk::BlendFactor::eZero, - .alphaBlendOp = vk::BlendOp::eAdd, - .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA, - } - }; + std::vector attachments{}; }; // TODO: Specialization constants diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 05232af3..ea09dd47 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -261,6 +261,7 @@ namespace SHADE return {}; } + Handle pipeline = pipelineLibrary.GetDrawPipline(vsFsPair); if (!pipeline) { @@ -301,4 +302,12 @@ namespace SHADE return subpasses[subpassIndexing.at(subpassName.data())]; } + Handle SHRenderGraphNode::GetResource(uint32_t resourceIndex) const noexcept + { + if (resourceIndex < attResources.size()) + return attResources[resourceIndex]; + else + return {}; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index c713f402..28527a92 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -105,6 +105,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ Handle GetRenderpass(void) const noexcept; Handle GetSubpass(std::string_view subpassName) const noexcept; + Handle GetResource (uint32_t resourceIndex) const noexcept; friend class SHRenderGraph; }; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index cc881867..6da6593e 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -242,4 +242,9 @@ namespace SHADE } } + vk::Format SHRenderGraphResource::GetResourceFormat(void) const noexcept + { + return resourceFormat; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h index ebb699d8..d4782226 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h @@ -72,6 +72,8 @@ namespace SHADE void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept; + vk::Format GetResourceFormat (void) const noexcept; + friend class SHRenderGraphNode; friend class SHRenderGraph; }; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index 007502dd..abd3a7be 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -2,6 +2,8 @@ #include "SHSubpass.h" #include "Graphics/MiddleEnd/Batching/SHSuperBatch.h" #include "Graphics/Devices/SHVkLogicalDevice.h" +#include "SHRenderGraphNode.h" +#include "SHRenderGraphResource.h" namespace SHADE { @@ -207,4 +209,15 @@ namespace SHADE { return superBatch; } + + std::vector const& SHSubpass::GetColorAttachmentReferences(void) const noexcept + { + return colorReferences; + } + + vk::Format SHSubpass::GetFormatFromAttachmentReference(uint32_t attachmentReference) const noexcept + { + return parentNode->GetResource(attachmentReference)->GetResourceFormat(); + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h index b8b8717f..aba282b9 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h @@ -86,7 +86,8 @@ namespace SHADE Handle const& GetParentNode(void) const noexcept; SHSubPassIndex GetIndex() const noexcept; Handle GetSuperBatch(void) const noexcept; - + std::vector const& GetColorAttachmentReferences (void) const noexcept; + vk::Format GetFormatFromAttachmentReference (uint32_t attachmentReference) const noexcept; friend class SHRenderGraphNode; friend class SHRenderGraph; diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.cpp b/SHADE_Engine/src/Graphics/SHVkUtil.cpp index e4f9f37e..2d0e7cf2 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.cpp +++ b/SHADE_Engine/src/Graphics/SHVkUtil.cpp @@ -23,6 +23,25 @@ namespace SHADE IsDepthOnlyFormat(format); } + bool SHVkUtil::IsBlendCompatible(vk::Format format) noexcept + { + // TODO: Update with all formats + switch (format) + { + case vk::Format::eR32Sint: + case vk::Format::eR32G32Sint: + case vk::Format::eR32G32B32Sint: + case vk::Format::eR32G32B32A32Sint: + return false; + case vk::Format::eR32Sfloat: + case vk::Format::eR32G32Sfloat: + case vk::Format::eR32G32B32Sfloat: + case vk::Format::eR32G32B32A32Sfloat: + return true; + } + return false; + } + void SHVkUtil::EnsureBufferAndCopyData(Handle device, Handle cmdBuffer, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage) { if (bufferHandle) diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.h b/SHADE_Engine/src/Graphics/SHVkUtil.h index cba5b062..d8625607 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.h +++ b/SHADE_Engine/src/Graphics/SHVkUtil.h @@ -22,6 +22,7 @@ namespace SHADE public: static bool IsDepthOnlyFormat (vk::Format format) noexcept; static bool IsDepthStencilAttachment(vk::Format format) noexcept; + static bool IsBlendCompatible (vk::Format format) noexcept; /***********************************************************************************/ /*! diff --git a/TempShaderFolder/TestCubeFs.glsl b/TempShaderFolder/TestCubeFs.glsl index 3a25ad71..ab0f089f 100644 --- a/TempShaderFolder/TestCubeFs.glsl +++ b/TempShaderFolder/TestCubeFs.glsl @@ -33,12 +33,13 @@ layout (set = 3, binding = 0) buffer MaterialProperties // For materials } MatProp; layout(location = 0) out vec4 outColor; +layout(location = 1) out uint outEntityID; void main() { - outColor = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) + MatProp.data[In2.materialIndex].color / MatProp.data[In2.materialIndex].alpha; + outEntityID = 5; //outColor = vec4 (1.0f); } \ No newline at end of file diff --git a/TempShaderFolder/TestCubeFs.spv b/TempShaderFolder/TestCubeFs.spv index 07f67a459c18377f70ada5712194e5a5029322de..a069acf6e2e436753364704fd981a0cad627a143 100644 GIT binary patch delta 164 zcmX@WzeRwTnMs+Qfq{{Mi-DKHej;x!Bj?0wSw`E9Q`cv0W8ZE;{X5v delta 53 zcmdlYaDbnenMs+Qfq{{Mi-DKHdLnNwBge#Q*^P4)m^NQvQefP~BEhsdg6#w&$6uft H3m^snDAWsH From e1fb92e3f1ae9d0d760462bbe0b2432b749cac68 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 13 Oct 2022 17:32:53 +0800 Subject: [PATCH 38/61] Adding Bounding Spheres --- .../src/Math/Geometry/SHBoundingBox.cpp | 17 +- .../src/Math/Geometry/SHBoundingBox.h | 4 +- .../src/Math/Geometry/SHBoundingSphere.cpp | 183 ++++++++++++++++++ .../src/Math/Geometry/SHBoundingSphere.h | 83 ++++++++ SHADE_Engine/src/Math/Geometry/SHShape.h | 3 +- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 2 +- 6 files changed, 277 insertions(+), 15 deletions(-) create mode 100644 SHADE_Engine/src/Math/Geometry/SHBoundingSphere.cpp create mode 100644 SHADE_Engine/src/Math/Geometry/SHBoundingSphere.h diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp index 11a14eed..0dd02caa 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.cpp @@ -26,12 +26,12 @@ namespace SHADE SHBoundingBox::SHBoundingBox() noexcept { - type = Type::BOUNDING_BOX; + type = Type::BOX; } SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept { - type = Type::BOUNDING_BOX; + type = Type::BOX; Center = c; Extents = hE; @@ -43,7 +43,7 @@ namespace SHADE if (this == &rhs) return; - type = Type::BOUNDING_BOX; + type = Type::BOX; Center = rhs.Center; Extents = rhs.Extents; @@ -51,7 +51,7 @@ namespace SHADE SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept { - type = Type::BOUNDING_BOX; + type = Type::BOX; Center = rhs.Center; Extents = rhs.Extents; @@ -63,14 +63,11 @@ namespace SHADE SHBoundingBox& SHBoundingBox::operator=(const SHBoundingBox& rhs) noexcept { - if (this == &rhs) - return *this; - - if (rhs.type != Type::BOUNDING_BOX) + if (rhs.type != Type::BOX) { SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!") } - else + else if (this != &rhs) { Center = rhs.Center; Extents = rhs.Extents; @@ -81,7 +78,7 @@ namespace SHADE SHBoundingBox& SHBoundingBox::operator=(SHBoundingBox&& rhs) noexcept { - if (rhs.type != Type::BOUNDING_BOX) + if (rhs.type != Type::BOX) { SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!") } diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h index 5c38e1b8..2fdc6634 100644 --- a/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingBox.h @@ -36,7 +36,7 @@ namespace SHADE /* Constructors & Destructor */ /*---------------------------------------------------------------------------------*/ - ~SHBoundingBox () noexcept = default; + ~SHBoundingBox () override = default; SHBoundingBox () noexcept; SHBoundingBox (const SHVec3& center, const SHVec3& halfExtents) noexcept; @@ -44,7 +44,7 @@ namespace SHADE SHBoundingBox (SHBoundingBox&& rhs) noexcept; /*---------------------------------------------------------------------------------*/ - /* Operator Overloads */ + /* Operator Overloads */ /*---------------------------------------------------------------------------------*/ SHBoundingBox& operator= (const SHBoundingBox& rhs) noexcept; diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.cpp b/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.cpp new file mode 100644 index 00000000..c9bdcfe2 --- /dev/null +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.cpp @@ -0,0 +1,183 @@ +/**************************************************************************************** + * \file SHBoundingSphere.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for a Bounding Sphere + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHBoundingSphere.h" +// Project Headers +#include "Math/SHMathHelpers.h" +#include "Math/SHRay.h" + +using namespace DirectX; + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHBoundingSphere::SHBoundingSphere() noexcept + { + type = Type::SPHERE; + } + + SHBoundingSphere::SHBoundingSphere(const SHVec3& center, float radius) noexcept + { + type = Type::SPHERE; + + Center = center; + Radius = radius; + } + + SHBoundingSphere::SHBoundingSphere(const SHBoundingSphere& rhs) noexcept + { + if (this == &rhs) + return; + + type = Type::SPHERE; + + Center = rhs.Center; + Radius = rhs.Radius; + } + + SHBoundingSphere::SHBoundingSphere(SHBoundingSphere&& rhs) noexcept + { + type = Type::SPHERE; + + Center = rhs.Center; + Radius = rhs.Radius; + } + + /*-----------------------------------------------------------------------------------*/ + /* Operator Overload Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHBoundingSphere& SHBoundingSphere::operator=(const SHBoundingSphere& rhs) noexcept + { + if (rhs.type != Type::SPHERE) + { + SHLOG_WARNING("Cannot assign a non-sphere to a sphere!") + } + else if (this != &rhs) + { + Center = rhs.Center; + Radius = rhs.Radius; + } + + return *this; + } + + SHBoundingSphere& SHBoundingSphere::operator=(SHBoundingSphere&& rhs) noexcept + { + if (rhs.type != Type::SPHERE) + { + SHLOG_WARNING("Cannot assign a non-sphere to a sphere!") + } + else + { + Center = rhs.Center; + Radius = rhs.Radius; + } + + return *this; + } + + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + const SHVec3& SHBoundingSphere::GetCenter() const noexcept + { + return Center; + } + + float SHBoundingSphere::GetRadius() const noexcept + { + return Radius; + } + + /*-----------------------------------------------------------------------------------*/ + /* Setter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHBoundingSphere::SetCenter(const SHVec3& center) noexcept + { + Center = center; + } + + void SHBoundingSphere::SetRadius(float radius) noexcept + { + Radius = radius; + } + + /*-----------------------------------------------------------------------------------*/ + /* Public Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + bool SHBoundingSphere::TestPoint(const SHVec3& point) noexcept + { + return BoundingSphere::Contains(point); + } + + bool SHBoundingSphere::Raycast(const SHRay& ray, float& distance) noexcept + { + return Intersects(ray.position, ray.direction, distance); + } + + bool SHBoundingSphere::Contains(const SHBoundingSphere& rhs) const noexcept + { + return BoundingSphere::Contains(rhs); + } + + float SHBoundingSphere::Volume() const noexcept + { + return (4.0f / 3.0f) * SHMath::PI * (Radius * Radius * Radius); + } + + float SHBoundingSphere::SurfaceArea() const noexcept + { + return 4.0f * SHMath::PI * (Radius * Radius); + } + + /*-----------------------------------------------------------------------------------*/ + /* Static Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHBoundingSphere SHBoundingSphere::Combine(const SHBoundingSphere& lhs, const SHBoundingSphere& rhs) noexcept + { + SHBoundingSphere result; + CreateMerged(result, lhs, rhs); + return result; + } + + bool SHBoundingSphere::Intersect(const SHBoundingSphere& lhs, const SHBoundingSphere& rhs) noexcept + { + return lhs.Intersects(rhs); + } + + SHBoundingSphere SHBoundingSphere::BuildFromSpheres(const SHBoundingSphere* spheres, size_t numSpheres) noexcept + { + SHBoundingSphere result; + + for (size_t i = 1; i < numSpheres; ++i) + CreateMerged(result, spheres[i - 1], spheres[i]); + + return result; + } + + SHBoundingSphere SHBoundingSphere::BuildFromVertices(const SHVec3* vertices, size_t numVertices, size_t stride) noexcept + { + SHBoundingSphere result; + CreateFromPoints(result, numVertices, vertices, stride); + return result; + } + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.h b/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.h new file mode 100644 index 00000000..00ce3e57 --- /dev/null +++ b/SHADE_Engine/src/Math/Geometry/SHBoundingSphere.h @@ -0,0 +1,83 @@ +/**************************************************************************************** + * \file SHBoundingSphere.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for a Bounding Sphere. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include + +// Project Headers +#include "SHShape.h" +#include "SH_API.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SH_API SHBoundingSphere : public SHShape, + private DirectX::BoundingSphere + { + public: + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHBoundingSphere () noexcept; + SHBoundingSphere (const SHVec3& center, float radius) noexcept; + SHBoundingSphere (const SHBoundingSphere& rhs) noexcept; + SHBoundingSphere (SHBoundingSphere&& rhs) noexcept; + + ~SHBoundingSphere () override = default; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + SHBoundingSphere& operator= (const SHBoundingSphere& rhs) noexcept; + SHBoundingSphere& operator= (SHBoundingSphere&& rhs) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] const SHVec3& GetCenter () const noexcept; + [[nodiscard]] float GetRadius () const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Setter Functions */ + /*---------------------------------------------------------------------------------*/ + + void SetCenter (const SHVec3& center) noexcept; + void SetRadius (float radius) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] bool TestPoint (const SHVec3& point) noexcept override; + [[nodiscard]] bool Raycast (const SHRay& ray, float& distance) noexcept override; + + [[nodiscard]] bool Contains (const SHBoundingSphere& rhs) const noexcept; + [[nodiscard]] float Volume () const noexcept; + [[nodiscard]] float SurfaceArea () const noexcept; + + + /*---------------------------------------------------------------------------------*/ + /* Static Function Members */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] static SHBoundingSphere Combine (const SHBoundingSphere& lhs, const SHBoundingSphere& rhs) noexcept; + [[nodiscard]] static bool Intersect (const SHBoundingSphere& lhs, const SHBoundingSphere& rhs) noexcept; + [[nodiscard]] static SHBoundingSphere BuildFromSpheres (const SHBoundingSphere* spheres, size_t numSpheres) noexcept; + [[nodiscard]] static SHBoundingSphere BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept; + + }; +} // namespace SHADE diff --git a/SHADE_Engine/src/Math/Geometry/SHShape.h b/SHADE_Engine/src/Math/Geometry/SHShape.h index 69578cb3..ab2db558 100644 --- a/SHADE_Engine/src/Math/Geometry/SHShape.h +++ b/SHADE_Engine/src/Math/Geometry/SHShape.h @@ -31,11 +31,10 @@ namespace SHADE enum class Type { - BOUNDING_BOX + BOX , SPHERE , CAPSULE , CONVEX_HULL - , TRIANGLE , COUNT , NONE = -1 diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index f3a4c276..6f3cadb6 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -398,7 +398,7 @@ namespace SHADE switch (shape->GetType()) { - case SHShape::Type::BOUNDING_BOX: + case SHShape::Type::BOX: { auto* box = reinterpret_cast(shape); const SHVec3& SHADE_EXTENTS = box->GetHalfExtents(); From 288f58c9788fbbc5c8bbd6013c5fecaab16414bf Mon Sep 17 00:00:00 2001 From: mushgunAX Date: Thu, 13 Oct 2022 23:03:30 +0800 Subject: [PATCH 39/61] fixed timing of memcpy of keys to keysLast This in turn fixes GetKeyDown() and GetKeyUp() as the input manager now knows changes of keys between the last frame and current frame. --- SHADE_Engine/src/Input/SHInputManager.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Input/SHInputManager.cpp b/SHADE_Engine/src/Input/SHInputManager.cpp index 04f2b02e..18d9e3e2 100644 --- a/SHADE_Engine/src/Input/SHInputManager.cpp +++ b/SHADE_Engine/src/Input/SHInputManager.cpp @@ -43,7 +43,10 @@ namespace SHADE void SHInputManager::UpdateInput(double dt) noexcept { - //Keyboard and Mouse Buttons//////////////////////////////////////////////// + //Keyboard and Mouse Buttons//////////////////////////////////////////////// + //Write to lastKeys + memcpy(keysLast, keys, sizeof(keys)); + //Poll unsigned char keyboardState[MAX_KEYS]; //if (GetKeyboardState(keyboardState) == false) return; @@ -96,9 +99,6 @@ namespace SHADE } } - //Write to lastKeys - memcpy(keysLast, keys, sizeof(keys)); - //Mouse Positioning///////////////////////////////////// //https://stackoverflow.com/a/6423739 From ab09d78e42ccef97d78fe9fcbf09d2772042d153 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Fri, 14 Oct 2022 00:08:14 +0800 Subject: [PATCH 40/61] removed routines for graphics from application (remember to add back after ingui update routine is added). Scene graph and physics system had some extra couts input system bug fix (this change is now in main) Mouse pick system wip --- .../src/Application/SBApplication.cpp | 6 +- SHADE_Application/src/Scenes/SBTestScene.cpp | 22 +++---- .../Graphics/Commands/SHVkCommandBuffer.cpp | 5 ++ .../src/Graphics/Commands/SHVkCommandBuffer.h | 3 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 12 +++- .../MiddleEnd/Interface/SHGraphicsSystem.h | 6 +- .../MiddleEnd/Interface/SHMousePickSystem.cpp | 59 +++++++++++++++++++ .../MiddleEnd/Interface/SHMousePickSystem.h | 38 ++++++++++++ .../Graphics/RenderGraph/SHRenderGraph.cpp | 9 +++ .../src/Graphics/RenderGraph/SHRenderGraph.h | 3 +- .../RenderGraph/SHRenderGraphResource.cpp | 52 ++++++++++++++++ .../RenderGraph/SHRenderGraphResource.h | 12 ++++ SHADE_Engine/src/Graphics/SHVkUtil.cpp | 13 ++++ SHADE_Engine/src/Graphics/SHVkUtil.h | 10 ++-- SHADE_Engine/src/Input/SHInputManager.cpp | 6 +- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 14 ++--- SHADE_Engine/src/Scene/SHSceneGraph.cpp | 6 +- 17 files changed, 241 insertions(+), 35 deletions(-) create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index c6da6f1f..861a92d6 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -81,9 +81,9 @@ namespace Sandbox SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHSystemManager::RegisterRoutine(); - SHADE::SHSystemManager::RegisterRoutine(); - SHADE::SHSystemManager::RegisterRoutine(); - SHADE::SHSystemManager::RegisterRoutine(); + //SHADE::SHSystemManager::RegisterRoutine(); + //SHADE::SHSystemManager::RegisterRoutine(); + //SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHComponentManager::CreateComponentSparseSet(); SHADE::SHComponentManager::CreateComponentSparseSet(); diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 3b277e6c..96be39f0 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -86,10 +86,10 @@ namespace Sandbox for (int y = 0; y < NUM_ROWS; ++y) for (int x = 0; x < NUM_COLS; ++x) { - auto entity = SHEntityManager::CreateEntity(); + auto entity = SHEntityManager::CreateEntity(); auto& renderable = *SHComponentManager::GetComponent_s(entity); auto& transform = *SHComponentManager::GetComponent_s(entity); - auto& collider = *SHComponentManager::GetComponent_s(entity); + //auto& collider = *SHComponentManager::GetComponent_s(entity); //renderable.Mesh = handles.front(); renderable.Mesh = CUBE_MESH; @@ -99,13 +99,13 @@ namespace Sandbox renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 0.0f, 0.0f, 1.0f)); //Set initial positions - transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, y * TEST_OBJ_SPACING.y, SHMath::GenerateRandomNumber(-3.5f, -5.0f)}); + transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, y * TEST_OBJ_SPACING.y, SHMath::GenerateRandomNumber(-300.5f, 500.0f)}); //transform.SetWorldPosition({-1.0f, -1.0f, -1.0f}); transform.SetWorldRotation(SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber()); transform.SetWorldScale(TEST_OBJ_SCALE); - auto* box = collider.AddBoundingBox(); - box->SetHalfExtents(transform.GetWorldScale() * 0.5f); + //auto* box = collider.AddBoundingBox(); + //box->SetHalfExtents(transform.GetWorldScale() * 0.5f); stressTestObjects.emplace_back(entity); } @@ -123,11 +123,11 @@ namespace Sandbox transform.SetWorldPosition({ -3.0f, -1.0f, -1.0f }); transform.SetLocalScale({ 5.0f, 5.0f, 5.0f }); - auto floor = SHEntityManager::CreateEntity(); + auto floor = SHEntityManager::CreateEntity(); auto& floorRenderable = *SHComponentManager::GetComponent_s(floor); auto& floorTransform = *SHComponentManager::GetComponent_s(floor); - auto& floorRigidBody = *SHComponentManager::GetComponent_s(floor); - auto& floorCollider = *SHComponentManager::GetComponent_s(floor); + //auto& floorRigidBody = *SHComponentManager::GetComponent_s(floor); + //auto& floorCollider = *SHComponentManager::GetComponent_s(floor); floorRenderable.Mesh = CUBE_MESH; floorRenderable.SetMaterial(customMat); @@ -136,10 +136,10 @@ namespace Sandbox floorTransform.SetWorldScale({7.5f, 0.5f, 7.5}); floorTransform.SetWorldPosition({0.0f, -3.0f, -5.0f}); - floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC); + //floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC); - auto* floorBox = floorCollider.AddBoundingBox(); - floorBox->SetHalfExtents(floorTransform.GetWorldScale() * 0.5f); + //auto* floorBox = floorCollider.AddBoundingBox(); + //floorBox->SetHalfExtents(floorTransform.GetWorldScale() * 0.5f); // Create blank entity with a script //testObj = SHADE::SHEntityManager::CreateEntity(); diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp index 9ebbd227..4501ba7b 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp @@ -461,6 +461,11 @@ namespace SHADE ); } + void SHVkCommandBuffer::CopyImageToBuffer(const vk::Image& src, const vk::Buffer& dst, const std::vector& copyInfo) + { + vkCommandBuffer.copyImageToBuffer (src, vk::ImageLayout::eTransferSrcOptimal, dst, copyInfo); + } + void SHVkCommandBuffer::PipelineBarrier( vk::PipelineStageFlags srcStage, vk::PipelineStageFlags dstStage, diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h index c18527b3..9416a1aa 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h @@ -120,7 +120,8 @@ namespace SHADE void DrawMultiIndirect (Handle indirectDrawData, uint32_t drawCount); // Buffer Copy - void CopyBufferToImage (const vk::Buffer& src, const vk::Image& dst, const std::vector& copyInfo); + void CopyBufferToImage (const vk::Buffer& src, const vk::Image& dst, const std::vector& copyInfo); + void CopyImageToBuffer (const vk::Image& src, const vk::Buffer& dst, const std::vector& copyInfo); // memory barriers void PipelineBarrier ( diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 09579f02..636aa27a 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -32,6 +32,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Images/SHVkSampler.h" #include "Assets/Asset Types/SHTextureAsset.h" +#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h" namespace SHADE { @@ -197,6 +198,15 @@ namespace SHADE cubeFS->Reflect(); defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass); + + mousePickSystem = resourceManager.Create(); + + std::vector> cmdPools; + cmdPools.reserve(swapchain->GetNumImages()); + for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i) + cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]); + + mousePickSystem->Init(device, cmdPools, worldRenderGraph->GetRenderGraphResource("Entity ID")); } /***************************************************************************/ @@ -396,10 +406,10 @@ namespace SHADE } - const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame(); auto& currFrameData = renderContext.GetCurrentFrameData(); + mousePickSystem->Run(graphicsQueue, CURR_FRAME_IDX); // #BackEndTest: queues an image for presentation if (auto result = graphicsQueue->Present(swapchain, { currFrameData.semRenderFinishHdl }, CURR_FRAME_IDX); result != vk::Result::eSuccess) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index c89e6ebc..981600f3 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -52,6 +52,7 @@ namespace SHADE class SHVkShaderModule; class SHMaterial; class SHMaterialInstance; + class SHMousePickSystem; /*---------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -294,7 +295,7 @@ namespace SHADE SHWindow* window = nullptr; // Middle End Resources - ResourceManager resourceManager; + ResourceManager resourceManager; SHMeshLibrary meshLibrary; SHTextureLibrary texLibrary; SHSamplerCache samplerCache; @@ -322,5 +323,8 @@ namespace SHADE Handle defaultMaterial; Handle worldRenderGraph; + + // Sub systems + Handle mousePickSystem; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp new file mode 100644 index 00000000..ec7a5491 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp @@ -0,0 +1,59 @@ +#include "SHpch.h" +#include "SHMousePickSystem.h" +#include "Input/SHInputManager.h" +#include "Graphics/Commands/SHVkCommandPool.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/Synchronization/SHVkFence.h" +#include "Graphics/Buffers/SHVkBuffer.h" +#include "Graphics/SHVkUtil.h" + +namespace SHADE +{ + void SHMousePickSystem::Init(Handle logicalDevice, std::span> cmdPools, Handle eidAttachment) noexcept + { + // Create command buffers + for (auto& pool : cmdPools) + { + commandBuffers.push_back(pool->RequestCommandBuffer (SH_CMD_BUFFER_TYPE::PRIMARY)); + } + + // assign the attachment + entityIDAttachment = eidAttachment; + + // Create the fence + afterCopyFence = logicalDevice->CreateFence(); + + uint32_t bufferSize = entityIDAttachment->GetWidth() * eidAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat()); + + // Create the buffer + imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + } + + void SHMousePickSystem::Run(Handle queue, uint32_t frameIndex) noexcept + { + // if input detected + if (/*SHInputManager::GetKey(SHInputManager::SH_KEYCODE::LEFT_CTRL) && */SHInputManager::GetKeyUp(SHInputManager::SH_KEYCODE::LMB)) + { + std::cout << "Input registered... " << std::endl; + + //// begin command buffer for recording + //commandBuffers[frameIndex]->BeginRecording(); + + //// transition the image for optimized copying + //entityIDAttachment->TransitionImage (vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eTransferSrcOptimal, commandBuffers[frameIndex], vk::PipelineStageFlagBits::eColorAttachmentOutput, vk::PipelineStageFlagBits::eTransfer, 0); + + //// copy the image here. Last argument is 0 because the attachment isn't a swapchain image. + //entityIDAttachment->CopyToBuffer(imageDataDstBuffer, commandBuffers[frameIndex], 0); + + //// end command buffer for recording + //commandBuffers[frameIndex]->EndRecording(); + + //// submit the command buffer to copy image to buffer + //queue->SubmitCommandBuffer({ commandBuffers[frameIndex] }, {}, {}, vk::PipelineStageFlagBits::eColorAttachmentOutput, afterCopyFence); + + //// wait for the copy to be done + //afterCopyFence->Wait(true, std::numeric_limits::max()); + } + } + +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h new file mode 100644 index 00000000..815eb938 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h @@ -0,0 +1,38 @@ +#pragma once + +#include "Graphics/RenderGraph/SHRenderGraphResource.h" +#include "ECS_Base/SHECSMacros.h" +#include "Math/Vector/SHVec2.h" +#include + +namespace SHADE +{ + class SHVkLogicalDevice; + class SHVkCommandPool; + class SHVkCommandBuffer; + class SHVkFence; + class SHVkQueue; + class SHVkBuffer; + + class SHMousePickSystem + { + private: + //! Handle to the render graph resource that will contain the entity IDs + Handle entityIDAttachment; + + //! Command buffers meant for copying image to buffer + std::vector> commandBuffers; + + //! After the attachment has copied its data to a buffer, we want to signal this fence + Handle afterCopyFence; + + //! buffer to contain the attachment data after copying + Handle imageDataDstBuffer; + + public: + void Init(Handle logicalDevice, std::span> cmdPools, Handle eidAttachment) noexcept; + + void Run (Handle queue, uint32_t frameIndex) noexcept; + + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index cad6a78e..78bd1ca6 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -498,4 +498,13 @@ namespace SHADE } + Handle SHRenderGraph::GetRenderGraphResource(std::string const& resourceName) const noexcept + { + if (graphResources.contains(resourceName)) + { + return graphResources.at(resourceName); + } + return {}; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index a3140a4f..2e9a3310 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -85,7 +85,8 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ - Handle GetNode (std::string const& nodeName) const noexcept; + Handle GetNode (std::string const& nodeName) const noexcept; + Handle GetRenderGraphResource (std::string const& resourceName) const noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index 6da6593e..e8c9863f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -3,6 +3,8 @@ #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Swapchain/SHVkSwapchain.h" #include "Graphics/Images/SHVkImageView.h" +#include "Graphics/Buffers/SHVkBuffer.h" +#include "Graphics/SHVkUtil.h" namespace SHADE { @@ -242,9 +244,59 @@ namespace SHADE } } + void SHRenderGraphResource::TransitionImage(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, Handle commandBuffer, vk::PipelineStageFlagBits srcStage, vk::PipelineStageFlagBits dstStage, uint32_t frameIndex) noexcept + { + vk::ImageMemoryBarrier barrier; + barrier.oldLayout = oldLayout; + barrier.newLayout = newLayout; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.image = images[frameIndex]->GetVkImage(), + barrier.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor; // TODO: Need to change this to base it off image format. + barrier.subresourceRange.baseMipLevel = 0; + barrier.subresourceRange.levelCount = mipLevels; + barrier.subresourceRange.baseArrayLayer = 0; + barrier.subresourceRange.layerCount = 1; // always 1 since we wont have array of images for attachments + + commandBuffer->PipelineBarrier(srcStage, dstStage, {}, {}, {}, {barrier}); + } + + void SHRenderGraphResource::CopyToBuffer(Handle dstBuffer, Handle commandBuffer, uint32_t frameIndex) const noexcept + { + vk::ImageSubresourceLayers subResource + { + .aspectMask = SHVkUtil::IsDepthOnlyFormat(resourceFormat) ? vk::ImageAspectFlagBits::eDepth : vk::ImageAspectFlagBits::eColor, + .mipLevel = 0, + .baseArrayLayer = 0, + .layerCount = 1 + }; + + vk::BufferImageCopy region + { + .bufferOffset = 0, + .bufferRowLength = 0, + .bufferImageHeight = 0, + .imageSubresource = subResource, + .imageOffset = vk::Offset3D {0,0,0}, + .imageExtent = vk::Extent3D {width, height, 1} + }; + + commandBuffer->CopyImageToBuffer(images[frameIndex]->GetVkImage(), dstBuffer->GetVkBuffer(), {region}); + } + vk::Format SHRenderGraphResource::GetResourceFormat(void) const noexcept { return resourceFormat; } + uint32_t SHRenderGraphResource::GetWidth(void) const noexcept + { + return width; + } + + uint32_t SHRenderGraphResource::GetHeight(void) const noexcept + { + return height; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h index d4782226..a490ab95 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h @@ -13,6 +13,8 @@ namespace SHADE class SHVkImageView; class SHVkLogicalDevice; class SHVkSwapchain; + class SHVkCommandBuffer; + class SHVkBuffer; class SH_API SHRenderGraphResource { @@ -70,9 +72,19 @@ namespace SHADE SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept; ~SHRenderGraphResource(void) noexcept; + /*-----------------------------------------------------------------------*/ + /* PUBLIC MEMBER FUNCTIONS */ + /*-----------------------------------------------------------------------*/ void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept; + void TransitionImage(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, Handle commandBuffer, vk::PipelineStageFlagBits srcStage, vk::PipelineStageFlagBits dstStage, uint32_t frameIndex) noexcept; + void CopyToBuffer (Handle dstBuffer, Handle commandBuffer, uint32_t frameIndex = 0) const noexcept; + /*-----------------------------------------------------------------------*/ + /* SETTERS AND GETTERS */ + /*-----------------------------------------------------------------------*/ vk::Format GetResourceFormat (void) const noexcept; + uint32_t GetWidth (void) const noexcept; + uint32_t GetHeight (void) const noexcept; friend class SHRenderGraphNode; friend class SHRenderGraph; diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.cpp b/SHADE_Engine/src/Graphics/SHVkUtil.cpp index 2d0e7cf2..c8c563a1 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.cpp +++ b/SHADE_Engine/src/Graphics/SHVkUtil.cpp @@ -42,6 +42,19 @@ namespace SHADE return false; } + uint32_t SHVkUtil::GetBytesPerPixelFromFormat(vk::Format format) noexcept + { + // TODO: Update with all formats + switch (format) + { + case vk::Format::eR32Sint: + case vk::Format::eR32Uint: + case vk::Format::eR32Sfloat: + return 4; + } + return 0; + } + void SHVkUtil::EnsureBufferAndCopyData(Handle device, Handle cmdBuffer, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage) { if (bufferHandle) diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.h b/SHADE_Engine/src/Graphics/SHVkUtil.h index d8625607..ca3b6f83 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.h +++ b/SHADE_Engine/src/Graphics/SHVkUtil.h @@ -19,10 +19,12 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ class SHVkUtil { - public: - static bool IsDepthOnlyFormat (vk::Format format) noexcept; - static bool IsDepthStencilAttachment(vk::Format format) noexcept; - static bool IsBlendCompatible (vk::Format format) noexcept; + public: + static bool IsDepthOnlyFormat (vk::Format format) noexcept; + static bool IsDepthStencilAttachment (vk::Format format) noexcept; + static bool IsBlendCompatible (vk::Format format) noexcept; + static uint32_t GetBytesPerPixelFromFormat (vk::Format format) noexcept; + /***********************************************************************************/ /*! diff --git a/SHADE_Engine/src/Input/SHInputManager.cpp b/SHADE_Engine/src/Input/SHInputManager.cpp index 04f2b02e..a6090062 100644 --- a/SHADE_Engine/src/Input/SHInputManager.cpp +++ b/SHADE_Engine/src/Input/SHInputManager.cpp @@ -44,6 +44,9 @@ namespace SHADE void SHInputManager::UpdateInput(double dt) noexcept { //Keyboard and Mouse Buttons//////////////////////////////////////////////// + //Write to lastKeys + memcpy(keysLast, keys, sizeof(keys)); + //Poll unsigned char keyboardState[MAX_KEYS]; //if (GetKeyboardState(keyboardState) == false) return; @@ -96,9 +99,6 @@ namespace SHADE } } - //Write to lastKeys - memcpy(keysLast, keys, sizeof(keys)); - //Mouse Positioning///////////////////////////////////// //https://stackoverflow.com/a/6423739 diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index f3a4c276..7d2e257b 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -203,9 +203,9 @@ namespace SHADE void SHPhysicsSystem::AddRigidBody(EntityID entityID) noexcept { - #ifdef _DEBUG - SHLOG_INFO("Adding a Rigidbody to the Physics World.") - #endif + //#ifdef _DEBUG + // SHLOG_INFO("Adding a Rigidbody to the Physics World.") + //#endif // Check if entity is already a physics object auto* physicsObject = GetPhysicsObject(entityID); @@ -274,9 +274,9 @@ namespace SHADE void SHPhysicsSystem::AddCollider(EntityID entityID) noexcept { - #ifdef _DEBUG - SHLOG_INFO("Adding a Collider to the Physics World.") - #endif + //#ifdef _DEBUG + // SHLOG_INFO("Adding a Collider to the Physics World.") + //#endif // Check if entity is already a physics object auto* physicsObject = GetPhysicsObject(entityID); @@ -488,7 +488,7 @@ namespace SHADE const auto it = map.find(entityID); if (it == map.end()) { - SHLOG_ERROR("Entity {} is not in the physics system!", entityID) + //SHLOG_ERROR("Entity {} is not in the physics system!", entityID) return nullptr; } diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.cpp b/SHADE_Engine/src/Scene/SHSceneGraph.cpp index 3fe85809..bbbdb7e4 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.cpp +++ b/SHADE_Engine/src/Scene/SHSceneGraph.cpp @@ -571,9 +571,9 @@ namespace SHADE { SHSceneNode* newNode = new SHSceneNode{entityID}; - #ifdef _DEBUG - SHLOG_INFO("Allocated a new Scene Node for Entity {}!", entityID) - #endif + //#ifdef _DEBUG + // SHLOG_INFO("Allocated a new Scene Node for Entity {}!", entityID) + //#endif entityNodeMap.emplace(entityID, newNode); return newNode; From 682a5a6cbfaf5313b59c26cebf9a9e6ded7efe54 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Fri, 14 Oct 2022 00:10:56 +0800 Subject: [PATCH 41/61] bug fix --- SHADE_Application/src/Scenes/SBTestScene.cpp | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index e327f833..f1d656ee 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -86,10 +86,10 @@ namespace Sandbox for (int y = 0; y < NUM_ROWS; ++y) for (int x = 0; x < NUM_COLS; ++x) { - auto entity = SHEntityManager::CreateEntity(); + auto entity = SHEntityManager::CreateEntity(); auto& renderable = *SHComponentManager::GetComponent_s(entity); auto& transform = *SHComponentManager::GetComponent_s(entity); - //auto& collider = *SHComponentManager::GetComponent_s(entity); + auto& collider = *SHComponentManager::GetComponent_s(entity); //renderable.Mesh = handles.front(); renderable.Mesh = CUBE_MESH; @@ -99,7 +99,7 @@ namespace Sandbox renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 0.0f, 0.0f, 1.0f)); //Set initial positions - transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, y * TEST_OBJ_SPACING.y, SHMath::GenerateRandomNumber(-300.5f, 500.0f)}); + transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, y * TEST_OBJ_SPACING.y, SHMath::GenerateRandomNumber(-3.5f, -5.0f) }); //transform.SetWorldPosition({-1.0f, -1.0f, -1.0f}); transform.SetWorldRotation(SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber()); transform.SetWorldScale(TEST_OBJ_SCALE); @@ -125,23 +125,23 @@ namespace Sandbox transform.SetWorldPosition({ -3.0f, -1.0f, -1.0f }); transform.SetLocalScale({ 5.0f, 5.0f, 5.0f }); - auto floor = SHEntityManager::CreateEntity(); + auto floor = SHEntityManager::CreateEntity(); auto& floorRenderable = *SHComponentManager::GetComponent_s(floor); auto& floorTransform = *SHComponentManager::GetComponent_s(floor); - //auto& floorRigidBody = *SHComponentManager::GetComponent_s(floor); - //auto& floorCollider = *SHComponentManager::GetComponent_s(floor); + auto& floorRigidBody = *SHComponentManager::GetComponent_s(floor); + auto& floorCollider = *SHComponentManager::GetComponent_s(floor); floorRenderable.Mesh = CUBE_MESH; floorRenderable.SetMaterial(customMat); floorRenderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 1.0f, 1.0f, 1.0f)); - floorTransform.SetWorldScale({7.5f, 0.5f, 7.5}); - floorTransform.SetWorldPosition({0.0f, -3.0f, -5.0f}); + floorTransform.SetWorldScale({ 7.5f, 0.5f, 7.5 }); + floorTransform.SetWorldPosition({ 0.0f, -3.0f, -5.0f }); - //floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC); + floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC); - //auto* floorBox = floorCollider.AddBoundingBox(); - //floorBox->SetHalfExtents(floorTransform.GetWorldScale() * 0.5f); + auto* floorBox = floorCollider.AddBoundingBox(); + floorBox->SetHalfExtents(floorTransform.GetWorldScale() * 0.5f); // Create blank entity with a script //testObj = SHADE::SHEntityManager::CreateEntity(); From faa55847cb5b139a0a957cd6e2efbd6f732c0df5 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Fri, 14 Oct 2022 11:52:15 +0800 Subject: [PATCH 42/61] Mouse picking is working from rendering side - Buffer now has function to get data from mapped pointer if it exists - Batches now also pass a buffer of EIDs to the GPU - Global vertex attributes now have 1 extra instanced attribute for storing EntityIDs - Render graph resources now have a usage flags on top of the usage flags calculated in the graph AddResource function. This is to tell vulkan that we want some resources to be copyable for example (EID render target copy to buffer). - Mouse pick system stores eid picked --- .../src/Graphics/Buffers/SHVkBuffer.h | 11 +++++ .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 45 +++++++++++++++++- .../src/Graphics/MiddleEnd/Batching/SHBatch.h | 6 ++- .../MiddleEnd/Batching/SHSuperBatch.cpp | 3 +- .../GlobalData/SHGraphicsGlobalData.cpp | 7 +-- .../MiddleEnd/Interface/SHGraphicsConstants.h | 8 ++++ .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 2 +- .../MiddleEnd/Interface/SHGraphicsSystem.h | 1 + .../MiddleEnd/Interface/SHMousePickSystem.cpp | 40 ++++++++++------ .../MiddleEnd/Interface/SHMousePickSystem.h | 11 ++++- .../Graphics/RenderGraph/SHRenderGraph.cpp | 4 +- .../src/Graphics/RenderGraph/SHRenderGraph.h | 2 +- .../RenderGraph/SHRenderGraphResource.cpp | 4 +- .../RenderGraph/SHRenderGraphResource.h | 2 +- TempShaderFolder/TestCubeFs.glsl | 3 +- TempShaderFolder/TestCubeFs.spv | Bin 2100 -> 2156 bytes TempShaderFolder/TestCubeVs.glsl | 4 ++ TempShaderFolder/TestCubeVs.spv | Bin 2152 -> 2300 bytes 18 files changed, 123 insertions(+), 30 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h index 648a07e8..e931fec5 100644 --- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h +++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h @@ -105,6 +105,17 @@ namespace SHADE vk::Buffer GetVkBuffer (void) const noexcept; vk::BufferUsageFlags GetUsageBits(void) const noexcept; + template + T GetDataFromMappedPointer(uint32_t index) const noexcept + { + if (mappedPtr && index < sizeStored / sizeof (T)) + { + return (static_cast(mappedPtr))[index]; + } + else + return {}; + }; + }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 181c1f22..2705b4d1 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -110,6 +110,7 @@ namespace SHADE // Clear CPU buffers drawData.clear(); transformData.clear(); + eidData.clear(); matPropsData.reset(); matPropsDataSize = 0; @@ -119,6 +120,7 @@ namespace SHADE { drawDataBuffer[i].Free(); transformDataBuffer[i].Free(); + eidBuffer[i].Free(); matPropsBuffer[i].Free(); } } @@ -206,7 +208,31 @@ namespace SHADE transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), static_cast(transformData.size() * sizeof(SHMatrix)), 0, 0); } - void SHBatch::Build(Handle _device, Handle descPool, uint32_t frameIndex) + void SHBatch::UpdateEIDBuffer(uint32_t frameIndex) + { + if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) + { + SHLOG_WARNING("[SHBatch] Attempted to update eid buffers with an invalid frame index."); + return; + } + + // Reset Transform Data + eidData.clear(); + + // Populate on the CPU + for (auto& subBatch : subBatches) + for (const SHRenderable* renderable : subBatch.Renderables) + { + eidData.emplace_back(renderable->GetEID()); + } + + // Transfer to GPU + if (eidBuffer[frameIndex]) + eidBuffer[frameIndex]->WriteToMemory(eidData.data(), static_cast(eidData.size() * sizeof(EntityID)), 0, 0); + + } + + void SHBatch::Build(Handle _device, Handle descPool, uint32_t frameIndex) { if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) { @@ -237,6 +263,11 @@ namespace SHADE // - Transform data transformData.reserve(numTotalElements); transformData.clear(); + // - EID data + eidData.reserve(numTotalElements); + eidData.clear(); + + // - Material Properties Data const Handle SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface ( @@ -277,7 +308,8 @@ namespace SHADE for (const SHRenderable* renderable : subBatch.Renderables) { // Transform - auto transform = SHComponentManager::GetComponent_s(renderable->GetEID()); + EntityID eid = renderable->GetEID(); + auto transform = SHComponentManager::GetComponent_s(eid); if (!transform) { SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!"); @@ -287,6 +319,8 @@ namespace SHADE { transformData.emplace_back(transform->GetTRS()); } + + eidData.emplace_back(eid); // Material Properties if (!EMPTY_MAT_PROPS) @@ -317,6 +351,12 @@ namespace SHADE device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES, BuffUsage::eVertexBuffer ); + const uint32_t EID_DATA_BYTES = static_cast(eidData.size() * sizeof(EntityID)); + SHVkUtil::EnsureBufferAndCopyHostVisibleData + ( + device, eidBuffer[frameIndex], eidData.data(), EID_DATA_BYTES, + BuffUsage::eVertexBuffer + ); // - Material Properties Buffer rebuildMaterialBuffers(frameIndex, descPool); @@ -339,6 +379,7 @@ namespace SHADE static std::array dynamicOffset { 0 }; cmdBuffer->BindPipeline(pipeline); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0); + cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::EID, eidBuffer[frameIndex], 0); if (matPropsDescSet[frameIndex]) { cmdBuffer->BindDescriptorSet diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h index abe691ca..37c57396 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h @@ -22,6 +22,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Interface/SHMaterial.h" #include "Math/SHMatrix.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" +#include "ECS_Base/SHECSMacros.h" namespace SHADE { @@ -78,6 +79,7 @@ namespace SHADE void Clear(); void UpdateMaterialBuffer(uint32_t frameIndex, Handle descPool); void UpdateTransformBuffer(uint32_t frameIndex); + void UpdateEIDBuffer(uint32_t frameIndex); void Build(Handle device, Handle descPool, uint32_t frameIndex) ; void Draw(Handle cmdBuffer, uint32_t frameIndex); @@ -109,14 +111,16 @@ namespace SHADE // CPU Buffers std::vector drawData; std::vector transformData; + std::vector eidData; std::unique_ptr matPropsData; Byte matPropsDataSize = 0; Byte singleMatPropAlignedSize = 0; - Byte singleMatPropSize = 0; + Byte singleMatPropSize = 0; bool isCPUBuffersDirty = true; // GPU Buffers TripleBuffer drawDataBuffer; TripleBuffer transformDataBuffer; + TripleBuffer eidBuffer; TripleBuffer matPropsBuffer; TripleDescSet matPropsDescSet; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index 0d75dca8..add51196 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -83,8 +83,9 @@ namespace SHADE { for (auto& batch : batches) { - batch.UpdateMaterialBuffer(frameIndex, descPool); + batch.UpdateMaterialBuffer(frameIndex, descPool); batch.UpdateTransformBuffer(frameIndex); + batch.UpdateEIDBuffer(frameIndex); } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp index 6a7b23f2..d8b1bad1 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp @@ -91,9 +91,10 @@ namespace SHADE { defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // positions at binding 0 defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_2D) }); // UVs at binding 1 - defaultVertexInputState.AddBinding(false, false, {SHVertexAttribute(SHAttribFormat::FLOAT_3D)}); // Normals at binding 2 - defaultVertexInputState.AddBinding(false, false, {SHVertexAttribute(SHAttribFormat::FLOAT_3D)}); // Tangents at binding 3 - defaultVertexInputState.AddBinding(true, true, {SHVertexAttribute(SHAttribFormat::MAT_4D)}); // Transform at binding 4 - 7 (4 slots) + defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Normals at binding 2 + defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Tangents at binding 3 + defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // Transform at binding 4 - 7 (4 slots) + defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::UINT32_1D) }); // EID at binding 8 } void SHGraphicsGlobalData::Init(Handle logicalDevice) noexcept diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h index 0818ebab..ac2f1f8c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h @@ -144,6 +144,14 @@ namespace SHADE */ /***************************************************************************/ static constexpr uint32_t TRANSFORM = 4; + /***************************************************************************/ + /*! + \brief + Vertex buffer bindings for the eid buffer. + */ + /***************************************************************************/ + static constexpr uint32_t EID = 5; + }; /*******************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 636aa27a..09f1c93e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -146,7 +146,7 @@ namespace SHADE worldRenderGraph->Init(device, swapchain); worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second); worldRenderGraph->AddResource("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); - worldRenderGraph->AddResource("Entity ID", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR32Uint); + worldRenderGraph->AddResource("Entity ID", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); //worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); //worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 981600f3..3160cd57 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -269,6 +269,7 @@ namespace SHADE Handle GetQueue() const { return graphicsQueue; } Handle GetDescriptorPool() const { return descPool; } Handle GetDefaultViewport() const {return defaultViewport;} + Handle GetMousePickSystem(void) const noexcept {return mousePickSystem;}; //SHRenderGraph const& GetRenderGraph(void) const noexcept; //Handle GetRenderPass() const { return renderPass; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp index ec7a5491..ee8665d5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp @@ -11,6 +11,8 @@ namespace SHADE { void SHMousePickSystem::Init(Handle logicalDevice, std::span> cmdPools, Handle eidAttachment) noexcept { + pickedEID = 0; + // Create command buffers for (auto& pool : cmdPools) { @@ -32,28 +34,38 @@ namespace SHADE void SHMousePickSystem::Run(Handle queue, uint32_t frameIndex) noexcept { // if input detected - if (/*SHInputManager::GetKey(SHInputManager::SH_KEYCODE::LEFT_CTRL) && */SHInputManager::GetKeyUp(SHInputManager::SH_KEYCODE::LMB)) + if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::LEFT_CTRL) && SHInputManager::GetKeyUp(SHInputManager::SH_KEYCODE::LMB)) { - std::cout << "Input registered... " << std::endl; + afterCopyFence->Reset(); - //// begin command buffer for recording - //commandBuffers[frameIndex]->BeginRecording(); + // begin command buffer for recording + commandBuffers[frameIndex]->BeginRecording(); - //// transition the image for optimized copying - //entityIDAttachment->TransitionImage (vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eTransferSrcOptimal, commandBuffers[frameIndex], vk::PipelineStageFlagBits::eColorAttachmentOutput, vk::PipelineStageFlagBits::eTransfer, 0); + // transition the image for optimized copying + entityIDAttachment->TransitionImage (vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eTransferSrcOptimal, commandBuffers[frameIndex], vk::PipelineStageFlagBits::eColorAttachmentOutput, vk::PipelineStageFlagBits::eTransfer, 0); - //// copy the image here. Last argument is 0 because the attachment isn't a swapchain image. - //entityIDAttachment->CopyToBuffer(imageDataDstBuffer, commandBuffers[frameIndex], 0); + // copy the image here. Last argument is 0 because the attachment isn't a swapchain image. + entityIDAttachment->CopyToBuffer(imageDataDstBuffer, commandBuffers[frameIndex], 0); - //// end command buffer for recording - //commandBuffers[frameIndex]->EndRecording(); + // end command buffer for recording + commandBuffers[frameIndex]->EndRecording(); - //// submit the command buffer to copy image to buffer - //queue->SubmitCommandBuffer({ commandBuffers[frameIndex] }, {}, {}, vk::PipelineStageFlagBits::eColorAttachmentOutput, afterCopyFence); + // submit the command buffer to copy image to buffer + queue->SubmitCommandBuffer({ commandBuffers[frameIndex] }, {}, {}, vk::PipelineStageFlagBits::eColorAttachmentOutput, afterCopyFence); - //// wait for the copy to be done - //afterCopyFence->Wait(true, std::numeric_limits::max()); + // wait for the copy to be done + afterCopyFence->Wait(true, std::numeric_limits::max()); + + int mouseX = 0, mouseY = 0; + SHInputManager::GetMouseWindowPosition(&mouseX, &mouseY); + + pickedEID = imageDataDstBuffer->GetDataFromMappedPointer(mouseY * entityIDAttachment->GetWidth() + mouseX); } } + EntityID SHMousePickSystem::GetPickedEntity(void) const noexcept + { + return pickedEID; + } + } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h index 815eb938..080a192c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h @@ -29,10 +29,19 @@ namespace SHADE //! buffer to contain the attachment data after copying Handle imageDataDstBuffer; + //! eid picked from screen + EntityID pickedEID; public: + /*-----------------------------------------------------------------------*/ + /* PUBLIC MEMBER FUNCTIONS */ + /*-----------------------------------------------------------------------*/ void Init(Handle logicalDevice, std::span> cmdPools, Handle eidAttachment) noexcept; - void Run (Handle queue, uint32_t frameIndex) noexcept; + /*-----------------------------------------------------------------------*/ + /* SETTERS AND GETTERS */ + /*-----------------------------------------------------------------------*/ + EntityID GetPickedEntity (void) const noexcept; + }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 78bd1ca6..1861f6d2 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -40,7 +40,7 @@ namespace SHADE */ /***************************************************************************/ - void SHRenderGraph::AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w /*= static_cast(-1)*/, uint32_t h /*= static_cast(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageCreateFlagBits createFlags /*= {}*/) + void SHRenderGraph::AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w /*= static_cast(-1)*/, uint32_t h /*= static_cast(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/) { // If we set to if (w == static_cast(-1) && h == static_cast(-1)) @@ -50,7 +50,7 @@ namespace SHADE format = swapchainHdl->GetSurfaceFormatKHR().format; } - graphResources.try_emplace(resourceName, resourceManager.Create(logicalDeviceHdl, swapchainHdl, resourceName, type, format, w, h, levels, createFlags)); + graphResources.try_emplace(resourceName, resourceManager.Create(logicalDeviceHdl, swapchainHdl, resourceName, type, format, w, h, levels, usageFlags, createFlags)); } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 2e9a3310..cfc29bc2 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -75,7 +75,7 @@ namespace SHADE /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ void Init (Handle const& logicalDevice, Handle const& swapchain) noexcept; - void AddResource (std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast(-1), uint32_t h = static_cast(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageCreateFlagBits createFlags = {}); + void AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast(-1), uint32_t h = static_cast(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {}); Handle AddNode (std::string nodeName, std::initializer_list resourceNames, std::initializer_list predecessorNodes) noexcept; void Generate (void) noexcept; void Execute (uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index e8c9863f..bcd1dc9f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -45,7 +45,7 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphResource::SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageCreateFlagBits createFlags) noexcept + SHRenderGraphResource::SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept : logicalDevice {logicalDevice} , swapchain{ swapchain } , resourceType{ type } @@ -61,7 +61,7 @@ namespace SHADE if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT) { imageAspectFlags = vk::ImageAspectFlags{}; - usage = {}; + usage = usageFlags; // Check the resource type and set image usage flags and image aspect flags accordingly switch (resourceType) diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h index a490ab95..66f0677b 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h @@ -67,7 +67,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageCreateFlagBits createFlags) noexcept; + SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept; SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept; SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept; ~SHRenderGraphResource(void) noexcept; diff --git a/TempShaderFolder/TestCubeFs.glsl b/TempShaderFolder/TestCubeFs.glsl index ab0f089f..18890c92 100644 --- a/TempShaderFolder/TestCubeFs.glsl +++ b/TempShaderFolder/TestCubeFs.glsl @@ -22,6 +22,7 @@ layout(location = 0) in struct layout(location = 2) flat in struct { int materialIndex; + uint eid; } In2; //layout (set = 0, binding = ) @@ -40,6 +41,6 @@ void main() outColor = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) + MatProp.data[In2.materialIndex].color / MatProp.data[In2.materialIndex].alpha; - outEntityID = 5; + outEntityID = In2.eid; //outColor = vec4 (1.0f); } \ No newline at end of file diff --git a/TempShaderFolder/TestCubeFs.spv b/TempShaderFolder/TestCubeFs.spv index a069acf6e2e436753364704fd981a0cad627a143..bde6213644b38cb5e844a04ac20ad1ca3e43b62c 100644 GIT binary patch literal 2156 zcmZ9MOH&g;5XVRJ5QC_wh>Btm-w#9t#J5qYn5tM%VyU;SH5qU}04;w3X=)>dBy z%Wqx=P1|iGQ73IDK@>Obb`)=zVN=ZRSLky9$()Q#Ho?(B-^5tM#Dr;&ITmoiGVg8+6}=O`8Pmx9@Eu?f&Z{ zlgbKOVZ6}`H*7FJH`@st9~5VZIJ6PB<6a!Cx0B7_V=rt)>yb@lFJZ5)tW@jEL8H?N zy6H~K2CXQzK{HB}DcZ8+%HlY`C~mZR%|VBPJO=wLm_pWTyO%y`x7vx?5>n87j7jZw z+DoiD=wqYe&%<;zX?LE6X{gB-w3q&AxXVRN2#mS9`!#lfm-lCOVXN~l9KhJdTdSZt z1;sclu3R>W!WIc_l15ZQ3~ZbxMd;Aen7FG=dd?ifphG=g-gNPNK}FreMy)n#X7|{6 zEuPEd3z9iS{dsvyh4?{nADsKWE$YZ+@1>>}#0+^in(K0$M(IxNsj14JcQq;Epfl$) znf6zol1|KLis9!w?R-3j9qizMA9DrMXYuDQa|J7l$ahG*DB>d^mY*d)oT_>N;~xIZ zmHGyC>f_+cyyyX6WO}0xY~1^zVvx@c$mjmZ`D|W;^I&G^^mka1h&84A76qs z{eXB`L@a7!H{>Gsq$GApUHE}xCkH#hHYu6eqmz$4(lZ$O(Afvr6_@X*WDfbq#mgu< zlhS$HbXd6Y%$1Rre7%ll4AE{oRO-7}KGh(9gP zH{rj3?(oj|Ho);=9#=%n$j4P z=bYWgyD9zuc=N)*iN`K(iF`b4?25kF&yooHs(gum+hO3IKD&PI2qQl}pB#2qGJRru gpl$I@gHa!QeJG+nKPPtlNCb{Q?*RRmUci#*H@-Bqy8r+H delta 902 zcmZ9Kxk^J(5QZnY$qg!TL1SFw5|_B|`$j5BCx}=JS_o<(Dt19^Y~^CK0|A~p@HZSc=JGe?r=#PrSnZJ2DKK}du%Qg5>k{D0>Yu55gq%PQ zF}C7!du0>fb+vu6;mUecHdGXNE_iC#)_@?s8YeOKsK6?`Fe?~y{Jw-(3)p&uiVb;3AheN+ZJCA%P-md(rV$(Cd_*=yOTej}QHD^Z{d>WyZ7d%NCv z-E8%G&3^tZiJD2AM$LAdMXfyEkI;<|>Eg7N4BEqjk`%+Wl(ffT?ZGJP=hypDmRGw; zH?w?TdCoJ~H-;F_usz7_nzMu-KiTyetr=xAX8gJn=1~@h$yVBqzFJ>kedLScw&DWY z3*~!AY)P^7WiM%NrTsiiTagd7d(bZzS2ow2ZYRnDzSn3No+BR|v**YO zM=w3c8ZMC4@;9BC;#L0@mh|&#Q8JP=h^@8j4*>U({s+~ zY6|Rk31;B0X$Jdz^cl=qPK$+~5dyQG(yFYvB0Hye>H?D=OfSJ`r-k_r(ZE-Pk7yFJeYg;{zfu{v561`6I6XZ1 zz`PrB`2Ejm&0zoYn%RpS=)t@zzyBqziFM})%$35&e(1sU*Xt`E#_6{l!lX`gm6c?=k;`>FF=U;C~=P1CNGYF3afSduiz5 zz4E#z1xMd@)MfhoR7N~{{M^S+<#l)9_D91RxSur{Z_M`u{LJ#Mwij9t s*S0PU$MAJ*Xbm@9+slF*uI-gL;x}aYsm<3>)tbBXb%4?TRn}G6KNk$B#sB~S literal 2152 zcmZ9NYflqF6ovc&^rtYs=lJxxBLa z9K{uri-l;$g&28R%kcvIQQ5d`N;WGi%O1;~$+l$`Sx&z}&408=Ub|Oo_3Ghawf4T= z=ydAc=)3RMeJ^n9O)qpCk=J+84QF&-(C~ZBte_x8wvK}KxTHN8Mg6Sbcf)A6?YG02 z&&NDx>Gh2vhx!kDQS5UL=ksaoPs(Q$&5*Hv%Zc33bNqv#>3&m;8aTJ|U!pBYOApTc z`a#f*oS@-asbWQQCy5=o;i;;MmxybHXDIKe-Sr}`9mM;>Q)|q7L3Hf>P-l{wh|yEU zc73n2=Oz1{=W%PqdcJ=ix5mVW1h6KN*@ zp5{g-pEGjzU)!PIJPDnk`=uSW5-sn+Nsg^E!sX-l;e3?D@#FO>Xil8q%njJWRHfm5 z<^dXD?g&gRVEPZH7hw8N&XR0jtJ>beF)T+u9JA$E1CHKV4j+!UR#n9Iow)6lo%f}} zXU&4lYQXSUFL3%8V~%x++cVJDg$uYW%;1dlm@_9e<>PNH+oSC?Zr7`%IH!41yTF&V zCm4TPUQu&NHltOk3(Wf9;S{5t7v|eS178vz(ac)#8!5JZoD#kq>yo}KrFcvneIcK} zD)_8NKA3y9@d^2?Pkde;-(#|7-ds;(aO8q{6X@+;)AAYYHKUnz$wv?7&Dgze$|sjN zwa;lT$r!8$zAZyPCrsbz72Lc$-iPfUF^qjnnpu}P`-00dxLM%^&E(N@dc2roc=GRR zrvLEdgLx-##P6rR)jtv*kb%*Ic{gy}=~K#Yz*@Lis2jC6wAHxZE)v1V!7{YGTspHWJ?)fH0ZgT8#3+< zJ$H6X#=Udb=)q`+)0+n}`o(&zL0=xq;4NN~Pmg{phxij28hAAHhJT9m<&!k@gg^Xn z49mTe4@WO7w~})7;YeMhZ>uu$(G#b?zqBr~H5vP(;SBV9T~?OaGlJ3C+TO^|*7jBy nj$!NAkPnxw?On=cYugk@K6>KRX6x9J&)wKM!07*J)pgl_O#Gk( From e027318d22dbc5682a0ea116762734e03290d5bc Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Fri, 14 Oct 2022 14:35:09 +0800 Subject: [PATCH 43/61] Inspector View - Collider Component --- .../Inspector/SHEditorComponentView.hpp | 138 ++++++--- .../Inspector/SHEditorInspector.cpp | 22 +- SHADE_Engine/src/Editor/SHEditor.cpp | 2 +- SHADE_Engine/src/Editor/SHEditorWidgets.hpp | 278 ++++++++++++------ 4 files changed, 311 insertions(+), 129 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index a546504b..93f6984e 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -12,19 +12,20 @@ #include "Editor/IconsMaterialDesign.h" #include "ECS_Base/Components/SHComponent.h" #include "Editor/SHEditorWidgets.hpp" +#include "Physics/Components/SHColliderComponent.h" #include "Reflection/SHReflectionMetadata.h" namespace SHADE { template::value, bool> = true> static void DrawContextMenu(T* component) { - if(!component) + if (!component) return; rttr::string_view componentName = rttr::type::get().get_name(); if (ImGui::BeginPopupContextItem(componentName.data())) { - + if (ImGui::Selectable(std::format("{} Copy {}", ICON_MD_CONTENT_COPY, componentName.data()).data())) { //SHClipboardUtil::WriteStringToClipboard(SHClipboardUtil::CFNAME::CFCOMPONENT, SHComponentToString(component)); @@ -45,7 +46,7 @@ namespace SHADE { if (!component) return; - auto componentType = rttr::type::get(*component); + const auto componentType = rttr::type::get(*component); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }); ImGui::SameLine(); if (ImGui::CollapsingHeader(componentType.get_name().data())) @@ -56,26 +57,26 @@ namespace SHADE { auto const& type = property.get_type(); - if(type.is_enumeration()) + if (type.is_enumeration()) { auto enumAlign = type.get_enumeration(); auto names = enumAlign.get_names(); std::vector list; - for(auto const& name : names) + for (auto const& name : names) list.push_back(name.data()); - SHEditorWidgets::ComboBox(property.get_name().data(), list, [component, property]{return property.get_value(component).to_int();}, [component, property](int const& idx) - { - auto enumAlign = property.get_enumeration(); - auto values = enumAlign.get_values(); - auto it = std::next(values.begin(), idx); - property.set_value(component, *it); - }); + SHEditorWidgets::ComboBox(property.get_name().data(), list, [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& idx) + { + auto enumAlign = property.get_enumeration(); + auto values = enumAlign.get_values(); + auto it = std::next(values.begin(), idx); + property.set_value(component, *it); + }); } - else if(type.is_arithmetic()) + else if (type.is_arithmetic()) { if (type == rttr::type::get()) { - SHEditorWidgets::CheckBox(property.get_name().data(), [component, property]{return property.get_value(component).to_bool();}, [component, property](bool const& result){property.set_value(component, result);}); + SHEditorWidgets::CheckBox(property.get_name().data(), [component, property] {return property.get_value(component).to_bool(); }, [component, property](bool const& result) {property.set_value(component, result); }); } //else if (type == rttr::type::get()) //{ @@ -85,39 +86,39 @@ namespace SHADE { auto metaMin = property.get_metadata(META::min); auto metaMax = property.get_metadata(META::max); - if(metaMin && metaMax) + if (metaMin && metaMax) { - SHEditorWidgets::SliderInt(property.get_name().data(), metaMin.template get_value(), metaMin.template get_value(), [component, property]{return property.get_value(component).to_int();}, [component, property](int const& result){property.set_value(component, result);}); + SHEditorWidgets::SliderInt(property.get_name().data(), metaMin.template get_value(), metaMin.template get_value(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); }); } else { - SHEditorWidgets::DragInt(property.get_name().data(), [component, property]{return property.get_value(component).to_int();}, [component, property](int const& result){property.set_value(component, result);}); + SHEditorWidgets::DragInt(property.get_name().data(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); }); } } else if (type == rttr::type::get()) { auto metaMin = property.get_metadata(META::min); auto metaMax = property.get_metadata(META::max); - if(metaMin.is_valid() && metaMax.is_valid()) + if (metaMin.is_valid() && metaMax.is_valid()) { - SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U8, metaMin.template get_value(), metaMax.template get_value(), [component, property]{return property.get_value(component).to_uint8();}, [component, property](uint8_t const& result){property.set_value(component, result);},"%zu"); + SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U8, metaMin.template get_value(), metaMax.template get_value(), [component, property] {return property.get_value(component).to_uint8(); }, [component, property](uint8_t const& result) {property.set_value(component, result); }, "%zu"); } else { - SHEditorWidgets::DragScalar(property.get_name().data(), ImGuiDataType_U8, [component, property]{return property.get_value(component).to_uint8();}, [component, property](uint8_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu"); + SHEditorWidgets::DragScalar(property.get_name().data(), ImGuiDataType_U8, [component, property] {return property.get_value(component).to_uint8(); }, [component, property](uint8_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu"); } } else if (type == rttr::type::get()) { auto metaMin = property.get_metadata(META::min); auto metaMax = property.get_metadata(META::max); - if(metaMin.is_valid() && metaMax.is_valid()) + if (metaMin.is_valid() && metaMax.is_valid()) { - SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value(), metaMin.template get_value(), [component, property]{return property.get_value(component).to_uint16();}, [component, property](uint16_t const& result){property.set_value(component, result);},"%zu"); + SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value(), metaMin.template get_value(), [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, "%zu"); } else { - SHEditorWidgets::DragScalar(property.get_name().data(), ImGuiDataType_U16, [component, property]{return property.get_value(component).to_uint16();}, [component, property](uint16_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu"); + SHEditorWidgets::DragScalar(property.get_name().data(), ImGuiDataType_U16, [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu"); } } else if (type == rttr::type::get()) @@ -126,50 +127,50 @@ namespace SHADE auto metaMax = property.get_metadata(META::max); if (metaMin.is_valid() && metaMax.is_valid()) { - SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value(), metaMin.template get_value(), [component, property]{ return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result){property.set_value(component, result); },"%zu"); + SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value(), metaMin.template get_value(), [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, "%zu"); } else { - SHEditorWidgets::DragScalar(property.get_name().data(), ImGuiDataType_U32, [component, property]{ return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result){property.set_value(component, result); },0.1f,0,0,"%zu"); + SHEditorWidgets::DragScalar(property.get_name().data(), ImGuiDataType_U32, [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu"); } } else if (type == rttr::type::get()) { auto metaMin = property.get_metadata(META::min); auto metaMax = property.get_metadata(META::max); - if(metaMin.is_valid() && metaMax.is_valid()) + if (metaMin.is_valid() && metaMax.is_valid()) { - SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value(), metaMin.template get_value(), [component, property]{return property.get_value(component).to_uint64();}, [component, property](uint64_t const& result){property.set_value(component, result);},"%zu"); + SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value(), metaMin.template get_value(), [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, "%zu"); } else { - SHEditorWidgets::DragScalar(property.get_name().data(), ImGuiDataType_U64, [component, property]{return property.get_value(component).to_uint64();}, [component, property](uint64_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu"); + SHEditorWidgets::DragScalar(property.get_name().data(), ImGuiDataType_U64, [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu"); } } else if (type == rttr::type::get()) { auto metaMin = property.get_metadata(META::min); auto metaMax = property.get_metadata(META::max); - if(metaMin.is_valid() && metaMax.is_valid()) + if (metaMin.is_valid() && metaMax.is_valid()) { - SHEditorWidgets::SliderFloat(property.get_name().data(), metaMin.template get_value(), metaMin.template get_value(), [component, property]{return property.get_value(component).to_float();}, [component, property](float const& result){property.set_value(component, result);}); + SHEditorWidgets::SliderFloat(property.get_name().data(), metaMin.template get_value(), metaMin.template get_value(), [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); }); } else { - SHEditorWidgets::DragFloat(property.get_name().data(), [component, property]{return property.get_value(component).to_float();}, [component, property](float const& result){property.set_value(component, result);}); + SHEditorWidgets::DragFloat(property.get_name().data(), [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); }); } } else if (type == rttr::type::get()) { auto metaMin = property.get_metadata(META::min); auto metaMax = property.get_metadata(META::max); - if(metaMin.is_valid() && metaMax.is_valid()) + if (metaMin.is_valid() && metaMax.is_valid()) { - SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value(), metaMin.template get_value(), [component, property]{return property.get_value(component).to_double();}, [component, property](double const& result){property.set_value(component, result);}); + SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value(), metaMin.template get_value(), [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); }); } else { - SHEditorWidgets::DragScalar(property.get_name().data(), ImGuiDataType_Double, [component, property]{return property.get_value(component).to_double();}, [component, property](double const& result){property.set_value(component, result);}, 0.1f); + SHEditorWidgets::DragScalar(property.get_name().data(), ImGuiDataType_Double, [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); }, 0.1f); } } } @@ -183,9 +184,74 @@ namespace SHADE } else if (type == rttr::type::get()) { - SHEditorWidgets::DragVec2(property.get_name().data(), { "X", "Y"}, [component, property]() {return property.get_value(component).template convert(); }, [component, property](SHVec2 vec) {return property.set_value(component, vec); }); + SHEditorWidgets::DragVec2(property.get_name().data(), { "X", "Y" }, [component, property]() {return property.get_value(component).template convert(); }, [component, property](SHVec2 vec) {return property.set_value(component, vec); }); } - + + } + } + else DrawContextMenu(component); + } + + template<> + static void DrawComponent(SHColliderComponent* component) + { + if (!component) + return; + const auto componentType = rttr::type::get(*component); + SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }); + ImGui::SameLine(); + if (ImGui::CollapsingHeader(componentType.get_name().data())) + { + DrawContextMenu(component); + + auto& colliders = component->GetColliders(); + int const size = static_cast(colliders.size()); + ImGui::BeginChild("Colliders", {0.0f, colliders.empty() ? 1.0f : 250.0f}, true); + for (int i{}; i < size; ++i) + { + SHCollider& collider = component->GetCollider(i); + auto cursorPos = ImGui::GetCursorPos(); + + if (collider.GetType() == SHCollider::Type::BOX) + { + SHEditorWidgets::BeginPanel( std::format("{} Box Collider #{}", ICON_MD_VIEW_IN_AR, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); + auto box = reinterpret_cast(collider.GetShape()); + SHEditorWidgets::DragVec3("Half Extents", { "X", "Y", "Z" }, [box] {return box->GetHalfExtents(); }, [box](SHVec3 const& vec) {box->SetHalfExtents(vec);}); + } + else if (collider.GetType() == SHCollider::Type::SPHERE) + { + SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); + auto sphere = reinterpret_cast(collider.GetShape()); + SHEditorWidgets::DragFloat("Radius", [sphere] {return sphere->GetRadius(); }, [sphere](float const& value) {sphere->SetRadius(value);}); + } + else if (collider.GetType() == SHCollider::Type::CAPSULE) + { + + } + { + SHEditorWidgets::BeginPanel("Offset", { ImGui::GetContentRegionAvail().x, 30.0f }); + SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider.GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider.SetPositionOffset(vec); }); + SHEditorWidgets::EndPanel(); + } + if(ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data())) + { + component->RemoveCollider(i); + } + SHEditorWidgets::EndPanel(); + } + ImGui::EndChild(); + + if (ImGui::BeginMenu("Add Collider")) + { + if(ImGui::Selectable("Box Collider")) + { + component->AddBoundingBox(); + } + if(ImGui::Selectable("Sphere Collider")) + { + component->AddBoundingSphere(); + } + ImGui::EndMenu(); } } else DrawContextMenu(component); diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index 3d00ac4b..4fc097be 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -24,12 +24,15 @@ namespace SHADE { template, bool> = true> - void DrawAddComponentButton(EntityID const& eid) + bool DrawAddComponentButton(EntityID const& eid) { - if(!SHComponentManager::HasComponent(eid) && ImGui::Selectable(std::format("Add {}", rttr::type::get().get_name().data()).data())) + bool selected = false; + if(!SHComponentManager::HasComponent(eid)) { - SHComponentManager::AddComponent(eid); + if(selected = ImGui::Selectable(std::format("Add {}", rttr::type::get().get_name().data()).data()); selected) + SHComponentManager::AddComponent(eid); } + return selected; } SHEditorInspector::SHEditorInspector() @@ -47,11 +50,6 @@ namespace SHADE SHEditorWindow::Update(); if (Begin()) { - if (ImGui::Button("AUDIO")) - { - auto audioSystem = SHSystemManager::GetSystem(); - audioSystem->PlayEventOnce("event:/Characters/sfx_footsteps_raccoon"); - } if (!SHEditor::selectedEntities.empty()) { @@ -90,7 +88,13 @@ namespace SHADE DrawAddComponentButton(eid); DrawAddComponentButton(eid); DrawAddComponentButton(eid); - DrawAddComponentButton(eid); + if(DrawAddComponentButton(eid)) + { + if(SHComponentManager::GetComponent_s(eid) == nullptr) + { + SHComponentManager::AddComponent(eid); + } + } ImGui::EndMenu(); } diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index e94f7398..e1c309b4 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -147,7 +147,7 @@ namespace SHADE ImFont* mainFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path static const ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 }; - ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.PixelSnapH = true; + ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f; ImFont* UIFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges); //TODO: Change to config based assets path io.Fonts->Build(); diff --git a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp index 8d2adcc6..3fa1789e 100644 --- a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp +++ b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp @@ -26,7 +26,7 @@ namespace SHADE { class SH_API SHEditorWidgets { - public: + public: //#==============================================================# //|| Constructor || //#==============================================================# @@ -35,6 +35,118 @@ namespace SHADE //#==============================================================# //|| Custom Widgets || //#==============================================================# + inline static ImVector panelStack{}; + static void BeginPanel(std::string_view const& name, const ImVec2& size) + { + ImGui::BeginGroup(); + + auto cursorPos = ImGui::GetCursorScreenPos(); + auto itemSpacing = ImGui::GetStyle().ItemSpacing; + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); + + auto frameHeight = ImGui::GetFrameHeight(); + ImGui::BeginGroup(); + + ImVec2 effectiveSize = size; + if (size.x < 0.0f) + effectiveSize.x = ImGui::GetContentRegionAvail().x; + else + effectiveSize.x = size.x; + ImGui::Dummy(ImVec2(effectiveSize.x, 0.0f)); + + ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); + ImGui::SameLine(0.0f, 0.0f); + ImGui::BeginGroup(); + ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); + ImGui::SameLine(0.0f, 0.0f); + ImGui::TextUnformatted(name.data()); + auto labelMin = ImGui::GetItemRectMin(); + auto labelMax = ImGui::GetItemRectMax(); + ImGui::SameLine(0.0f, 0.0f); + ImGui::Dummy(ImVec2(0.0, frameHeight + itemSpacing.y)); + ImGui::BeginGroup(); + + ImGui::PopStyleVar(2); + + ImGui::GetCurrentWindow()->ContentRegionRect.Max.x -= frameHeight * 0.5f; + ImGui::GetCurrentWindow()->WorkRect.Max.x -= frameHeight * 0.5f; + ImGui::GetCurrentWindow()->InnerRect.Max.x -= frameHeight * 0.5f; + + ImGui::GetCurrentWindow()->Size.x -= frameHeight; + + auto itemWidth = ImGui::CalcItemWidth(); + ImGui::PushItemWidth(ImMax(0.0f, itemWidth - frameHeight)); + + panelStack.push_back(ImRect(labelMin, labelMax)); + } + + static void EndPanel() + { + ImGui::PopItemWidth(); + + auto itemSpacing = ImGui::GetStyle().ItemSpacing; + + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); + + auto frameHeight = ImGui::GetFrameHeight(); + + ImGui::EndGroup(); + + ImGui::EndGroup(); + + ImGui::SameLine(0.0f, 0.0f); + ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); + ImGui::Dummy(ImVec2(0.0, frameHeight - frameHeight * 0.5f - itemSpacing.y)); + + ImGui::EndGroup(); + + auto itemMin = ImGui::GetItemRectMin(); + auto itemMax = ImGui::GetItemRectMax(); + + auto labelRect = panelStack.back(); + panelStack.pop_back(); + + ImVec2 halfFrame = ImVec2(frameHeight * 0.25f, frameHeight) * 0.5f; + ImRect frameRect = ImRect(itemMin + halfFrame, itemMax - ImVec2(halfFrame.x, 0.0f)); + labelRect.Min.x -= itemSpacing.x; + labelRect.Max.x += itemSpacing.x; + for (int i = 0; i < 4; ++i) + { + switch (i) + { + // left half-plane + case 0: ImGui::PushClipRect(ImVec2(-FLT_MAX, -FLT_MAX), ImVec2(labelRect.Min.x, FLT_MAX), true); break; + // right half-plane + case 1: ImGui::PushClipRect(ImVec2(labelRect.Max.x, -FLT_MAX), ImVec2(FLT_MAX, FLT_MAX), true); break; + // top + case 2: ImGui::PushClipRect(ImVec2(labelRect.Min.x, -FLT_MAX), ImVec2(labelRect.Max.x, labelRect.Min.y), true); break; + // bottom + case 3: ImGui::PushClipRect(ImVec2(labelRect.Min.x, labelRect.Max.y), ImVec2(labelRect.Max.x, FLT_MAX), true); break; + } + + ImGui::GetWindowDrawList()->AddRect( + frameRect.Min, frameRect.Max, + ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Button)), + halfFrame.x); + + ImGui::PopClipRect(); + } + + ImGui::PopStyleVar(2); + + ImGui::GetCurrentWindow()->ContentRegionRect.Max.x += frameHeight * 0.5f; + ImGui::GetCurrentWindow()->WorkRect.Max.x += frameHeight * 0.5f; + ImGui::GetCurrentWindow()->InnerRect.Max.x += frameHeight * 0.5f; + + ImGui::GetCurrentWindow()->Size.x += frameHeight; + + ImGui::Dummy(ImVec2(0.0f, 0.0f)); + + ImGui::EndGroup(); + } + static bool Splitter(bool verticalSplit, float thickness, float* size1, float* size2, float minSize1, float minSize2, float splitterAxisSize = -1.0f) { ImGuiWindow* window = ImGui::GetCurrentWindow(); @@ -44,7 +156,7 @@ namespace SHADE bb.Max = bb.Min + (verticalSplit ? ImVec2(thickness, splitterAxisSize) : ImVec2(splitterAxisSize, thickness)); return ImGui::SplitterBehavior(bb, id, verticalSplit ? ImGuiAxis_X : ImGuiAxis_Y, size1, size2, minSize1, minSize2, 0.0f); } - + template static bool DragN(const std::string& fieldLabel, std::vectorconst& componentLabels, std::vector values, float speed = 0.1f, const char* displayFormat = "", T valueMin = T(), T valueMax = T(), @@ -53,7 +165,7 @@ namespace SHADE const ImGuiWindow* const window = ImGui::GetCurrentWindow(); if (window->SkipItems) return false; - + const ImGuiContext& g = *GImGui; bool valueChanged = false; ImGui::BeginGroup(); @@ -69,15 +181,15 @@ namespace SHADE ImGui::TextUnformatted(componentLabels[i].c_str(), ImGui::FindRenderedTextEnd(componentLabels[i].c_str())); ImGui::SameLine(); ImGui::SetNextItemWidth(80.0f); valueChanged |= ImGui::DragFloat("##v", values[i], speed, valueMin, valueMax, displayFormat, flags); - + const ImVec2 min = ImGui::GetItemRectMin(); const ImVec2 max = ImGui::GetItemRectMax(); const float spacing = g.Style.FrameRounding; const float halfSpacing = spacing / 2; - + window->DrawList->AddLine({ min.x + spacing, max.y - halfSpacing }, { max.x - spacing, max.y - halfSpacing }, ImGuiColors::colors[i], 4); - + ImGui::SameLine(0, g.Style.ItemInnerSpacing.x); ImGui::PopID(); ImGui::PopItemWidth(); @@ -85,10 +197,10 @@ namespace SHADE ImGui::EndColumns(); ImGui::PopID(); ImGui::EndGroup(); - + return valueChanged; } - + static bool DragVec2(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, std::function set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f, ImGuiSliderFlags flags = 0) @@ -99,98 +211,98 @@ namespace SHADE { changed = true; } - + if (changed) { if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); } - + return changed; } - + static bool DragVec3(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, std::function set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f, ImGuiSliderFlags flags = 0) { SHVec3 values = get(); bool changed = false; - if (DragN(fieldLabel, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags)) + if (DragN(fieldLabel, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags)) { changed = true; } - + if (changed) { if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); } - + return changed; } - + static bool DragVec4(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, std::function set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f, ImGuiSliderFlags flags = 0) { SHVec4 values = get(); bool changed = false; - if (DragN(fieldLabel, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags)) + if (DragN(fieldLabel, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags)) { changed = true; } - + if (changed) { if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); } - + return changed; } - + //#==============================================================# //|| Widget Extensions || //#==============================================================# - + static bool CheckBox(std::string const& label, std::function get, std::function set) { bool value = get(); if (ImGui::Checkbox(label.c_str(), &value)) { - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); return true; } return false; } - + template - static bool RadioButton(std::vector const& listLabels, std::vector const& listTypes, std::function get, std::function set) + static bool RadioButton(std::vector const& listLabels, std::vector const& listTypes, std::function get, std::function set) { T type = get(); for (size_t i = 0; i < listTypes.size(); i++) { if (ImGui::RadioButton(listLabels[i].c_str(), type == listTypes[i])) { - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), listTypes[i], set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), listTypes[i], set)), false); } ImGui::SameLine(); } return true; } - + static bool InputText(const std::string& label, const std::function get, const std::function set, ImGuiInputTextFlags flag = 0, ImGuiInputTextCallback callback = (ImGuiInputTextCallback)0, void* userData = (void*)0) @@ -199,35 +311,35 @@ namespace SHADE if (ImGui::InputText(label.c_str(), &text, flag, callback, userData)) { if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), text, set)), false); - + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), text, set)), false); + return true; } return false; } - + template static bool DragScalar(const std::string& fieldLabel, ImGuiDataType data_type, std::function get, std::function set, float speed = 1.0f, T p_min = T(), T p_max = T(), const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) { T value = get(); - std::cout << value <<" \n"; + std::cout << value << " \n"; //bool hasChange = ImGui::DragScalar(fieldLabel.c_str(), data_type, &value, speed, &p_min, &p_max, displayFormat, flags); - + if (ImGui::DragScalar(fieldLabel.c_str(), data_type, &value, speed, &p_min, &p_max, displayFormat, flags)) { if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); - + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + return true; } return false; } - + static bool DragFloat(const std::string& fieldLabel, std::function get, std::function set, float speed = 0.1f, float p_min = float(), float p_max = float(), const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) { @@ -236,18 +348,18 @@ namespace SHADE if (ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags)) { if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); - + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + return true; } - + return false; } - + static bool DragInt(const std::string& fieldLabel, std::function get, std::function set, float speed = 1.0f, int p_min = int(), int p_max = int(), const char* displayFormat = "%d", ImGuiSliderFlags flags = 0) { @@ -256,35 +368,35 @@ namespace SHADE if (ImGui::DragInt(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags)) { if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); - + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + return true; } - + return false; } - template - static bool SliderScalar(const std::string& fieldLabel, ImGuiDataType data_type, T min, T max, std::function get, std::function set, + template + static bool SliderScalar(const std::string& fieldLabel, ImGuiDataType data_type, T min, T max, std::function get, std::function set, const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) + { + T value = get(); + if (ImGui::SliderScalar(fieldLabel.c_str(), data_type, &value, &min, &max, displayFormat, flags)) { - T value = get(); - if (ImGui::SliderScalar(fieldLabel.c_str(), data_type, &value, &min, &max, displayFormat, flags)) - { - if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); - else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); - - return true; - } - - return false; + if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f)) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + + return true; } - + + return false; + } + static bool SliderFloat(const std::string& fieldLabel, float min, float max, std::function get, std::function set, const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) { @@ -292,17 +404,17 @@ namespace SHADE if (ImGui::SliderFloat(fieldLabel.c_str(), &value, min, max, displayFormat, flags)) { if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); - - + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + + return true; } - + return false; } - + static bool SliderInt(const std::string& fieldLabel, int min, int max, std::function get, std::function set, const char* displayFormat = "%d", ImGuiSliderFlags flags = 0) { @@ -310,26 +422,26 @@ namespace SHADE if (ImGui::SliderInt(fieldLabel.c_str(), &value, min, max, displayFormat, flags)) { if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); - + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + return true; } - + return false; } - + static bool ComboBox(const std::string& fieldLabel, std::vector list, std::function get, std::function set) { bool edited = false; int selected = get(); ImGui::PushID(fieldLabel.c_str()); ImGui::Text(fieldLabel.c_str()); ImGui::SameLine(); - + if (edited = ImGui::Combo("##Combo", &selected, list.data(), static_cast(list.size()))) { - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), selected, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), selected, set)), false); } ImGui::PopID(); return edited; From 49575893fe9228192fa759b6a067e843eac06918 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Fri, 14 Oct 2022 15:39:43 +0800 Subject: [PATCH 44/61] Made Editor a system and create editor routine so that the editor routine will run between graphics routines --- .../src/Application/SBApplication.cpp | 96 ++++----- .../HierarchyPanel/SHHierarchyPanel.cpp | 23 ++- .../Inspector/SHEditorInspector.cpp | 8 +- .../EditorWindow/MenuBar/SHEditorMenuBar.cpp | 5 +- SHADE_Engine/src/Editor/SHEditor.cpp | 37 ++-- SHADE_Engine/src/Editor/SHEditor.hpp | 191 ++++++++++-------- 6 files changed, 198 insertions(+), 162 deletions(-) diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index c6da6f1f..eb7d5432 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -56,46 +56,58 @@ namespace Sandbox ) { // Set working directory - SHADE::SHFileUtilities::SetWorkDirToExecDir(); + SHFileUtilities::SetWorkDirToExecDir(); window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow); // Create Systems - SHADE::SHSystemManager::CreateSystem(); - SHADE::SHSystemManager::CreateSystem(); - SHADE::SHSystemManager::CreateSystem(); - SHADE::SHSystemManager::CreateSystem(); - SHADE::SHGraphicsSystem* graphicsSystem = static_cast(SHADE::SHSystemManager::GetSystem()); - SHADE::SHSystemManager::CreateSystem(); + SHSystemManager::CreateSystem(); + SHSystemManager::CreateSystem(); + SHSystemManager::CreateSystem(); + SHSystemManager::CreateSystem(); + SHGraphicsSystem* graphicsSystem = static_cast(SHSystemManager::GetSystem()); + SHSystemManager::CreateSystem(); + +#ifdef SHEDITOR + SDL_Init(SDL_INIT_VIDEO); + sdlWindow = SDL_CreateWindowFrom(window.GetHWND()); + SHSystemManager::CreateSystem(); + SHSystemManager::GetSystem()->SetSDLWindow(sdlWindow); +#endif // Create Routines - SHADE::SHSystemManager::RegisterRoutine(); - SHADE::SHSystemManager::RegisterRoutine(); - SHADE::SHSystemManager::RegisterRoutine(); - SHADE::SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); - SHADE::SHSystemManager::RegisterRoutine(); - SHADE::SHSystemManager::RegisterRoutine(); - SHADE::SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); - SHADE::SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); - SHADE::SHSystemManager::RegisterRoutine(); - SHADE::SHSystemManager::RegisterRoutine(); - SHADE::SHSystemManager::RegisterRoutine(); - SHADE::SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); + +#ifdef SHEDITOR + SHSystemManager::RegisterRoutine(); +#endif - SHADE::SHComponentManager::CreateComponentSparseSet(); - SHADE::SHComponentManager::CreateComponentSparseSet(); - SHADE::SHComponentManager::CreateComponentSparseSet(); - SHADE::SHComponentManager::CreateComponentSparseSet(); + SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); + + SHComponentManager::CreateComponentSparseSet(); + SHComponentManager::CreateComponentSparseSet(); + SHComponentManager::CreateComponentSparseSet(); + SHComponentManager::CreateComponentSparseSet(); //TODO: REMOVE AFTER PRESENTATION - //SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf"); - SHADE::SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh"); - //SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds"); - //SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds"); - SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex"); + //SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf"); + SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh"); + //SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds"); + //SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds"); + SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex"); //TODO: REMOVE AFTER PRESENTATION @@ -103,19 +115,12 @@ namespace Sandbox auto id2 = SHFamilyID::GetID(); auto id3 = SHFamilyID::GetID(); - SHADE::SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); // Set up graphics system and windows graphicsSystem->SetWindow(&window); - SHADE::SHSystemManager::Init(); - #ifdef SHEDITOR - SDL_Init(SDL_INIT_VIDEO); - sdlWindow = SDL_CreateWindowFrom(window.GetHWND()); - SHADE::SHEditor::Initialise(sdlWindow); - #else - #endif - + SHSystemManager::Init(); SHSceneManager::InitSceneManager("TestScene"); @@ -124,7 +129,7 @@ namespace Sandbox void SBApplication::Update(void) { - SHADE::SHGraphicsSystem* graphicsSystem = static_cast(SHADE::SHSystemManager::GetSystem()); + SHGraphicsSystem* graphicsSystem = SHADE::SHSystemManager::GetSystem(); //TODO: Change true to window is open while (!window.WindowShouldClose()) { @@ -134,16 +139,16 @@ namespace Sandbox SHSceneManager::SceneUpdate(1/60.0f); //#ifdef SHEDITOR //#endif - graphicsSystem->BeginRender(); + //graphicsSystem->BeginRender(); #ifdef SHEDITOR - SHADE::SHEditor::Update(0.16f); + //SHADE::SHEditor::Update(0.16f); #endif - graphicsSystem->Run(1.0f); - graphicsSystem->EndRender(); + //graphicsSystem->Run(1.0f); + //graphicsSystem->EndRender(); - SHADE::SHSystemManager::RunRoutines(false, 0.016f); + SHSystemManager::RunRoutines(false, 0.016f); } // Finish all graphics jobs first @@ -154,13 +159,12 @@ namespace Sandbox void SBApplication::Exit(void) { #ifdef SHEDITOR - SHADE::SHEditor::Exit(); SDL_DestroyWindow(sdlWindow); SDL_Quit(); - #endif + #endif SHSceneManager::Exit(); - SHADE::SHSystemManager::Exit(); + SHSystemManager::Exit(); } } diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp index 25cd5a6a..0f25175f 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp @@ -6,11 +6,11 @@ //#==============================================================# //|| SHADE Includes || //#==============================================================# +#include "Editor/SHEditor.hpp" #include "Editor/SHImGuiHelpers.hpp" #include "Editor/SHEditorWidgets.hpp" #include "SHHierarchyPanel.h" #include "ECS_Base/Managers/SHEntityManager.h" -#include "Editor/SHEditor.hpp" #include "Scene/SHSceneManager.h" #include "Editor/DragDrop/SHDragDrop.hpp" #include "Tools/SHException.h" @@ -62,7 +62,8 @@ namespace SHADE if(ImGui::IsWindowHovered() && !SHDragDrop::hasDragDrop && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) { - SHEditor::selectedEntities.clear(); + if(auto editor = SHSystemManager::GetSystem()) + editor->selectedEntities.clear(); } ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal); ImGui::End(); @@ -102,7 +103,9 @@ namespace SHADE //Get node data (Children, eid, selected) auto& children = currentNode->GetChildren(); EntityID eid = currentNode->GetEntityID(); - const bool isSelected = (std::ranges::find(SHEditor::selectedEntities, eid) != SHEditor::selectedEntities.end()); + auto editor = SHSystemManager::GetSystem(); + + const bool isSelected = (std::ranges::find(editor->selectedEntities, eid) != editor->selectedEntities.end()); const ImGuiTreeNodeFlags nodeFlags = ((isSelected) ? ImGuiTreeNodeFlags_Selected : 0) | ((children.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow); @@ -140,8 +143,8 @@ namespace SHADE { if(!isSelected) { - SHEditor::selectedEntities.clear(); - SHEditor::selectedEntities.push_back(eid); + editor->selectedEntities.clear(); + editor->selectedEntities.push_back(eid); } if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data())) { @@ -163,19 +166,19 @@ namespace SHADE if (!isSelected) { if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) - SHEditor::selectedEntities.clear(); - SHEditor::selectedEntities.push_back(eid); + editor->selectedEntities.clear(); + editor->selectedEntities.push_back(eid); }//if not selected else { if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) { - auto it = std::ranges::remove(SHEditor::selectedEntities, eid).begin(); + auto it = std::ranges::remove(editor->selectedEntities, eid).begin(); }//if mod ctrl is not pressed else { - SHEditor::selectedEntities.clear(); - SHEditor::selectedEntities.push_back(eid); + editor->selectedEntities.clear(); + editor->selectedEntities.push_back(eid); } }//if selected }//if left mouse button released diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index 4fc097be..a9b1c724 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -1,5 +1,6 @@ #include "SHpch.h" +#include "Editor/SHEditor.hpp" #include "SHEditorInspector.h" #include "ECS_Base/SHECSMacros.h" @@ -7,7 +8,6 @@ #include "ECS_Base/Managers/SHEntityManager.h" #include "Math/Transform/SHTransformComponent.h" -#include "Editor/SHEditor.hpp" #include "Editor/SHImGuiHelpers.hpp" #include "Editor/SHEditorWidgets.hpp" #include "SHEditorComponentView.hpp" @@ -50,10 +50,10 @@ namespace SHADE SHEditorWindow::Update(); if (Begin()) { - - if (!SHEditor::selectedEntities.empty()) + auto editor = SHSystemManager::GetSystem(); + if (editor && !editor->selectedEntities.empty()) { - EntityID const& eid = SHEditor::selectedEntities[0]; + EntityID const& eid = editor->selectedEntities[0]; SHEntity* entity = SHEntityManager::GetEntityByID(eid); ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid); diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp index 8e26ae78..a49af994 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp @@ -3,11 +3,11 @@ //#==============================================================# //|| SHADE Includes || //#==============================================================# +#include "Editor/SHEditor.hpp" #include "SHEditorMenuBar.h" #include "Editor/IconsMaterialDesign.h" #include "Editor/Command/SHCommandManager.h" #include "Scripting/SHScriptEngine.h" -#include "Editor/SHEditor.hpp" #include "ECS_Base/Managers/SHSystemManager.h" //#==============================================================# @@ -95,7 +95,8 @@ namespace SHADE { if(ImGui::Selectable(style.to_string().c_str())) { - SHEditor::SetStyle(style.convert()); + if(auto editor = SHSystemManager::GetSystem()) + editor->SetStyle(style.convert()); } } ImGui::EndMenu(); diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index e1c309b4..d9fc8373 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -60,18 +60,18 @@ RTTR_REGISTRATION namespace SHADE { //#==============================================================# - //|| Initialise static members || + //|| Init static members || //#==============================================================# - Handle SHEditor::imguiCommandPool; - Handle SHEditor::imguiCommandBuffer; - SHEditor::EditorWindowMap SHEditor::editorWindows{}; - SHEditor::EditorWindowID SHEditor::windowCount{}; - std::vector SHEditor::selectedEntities; + //Handle SHEditor::imguiCommandPool; + //Handle SHEditor::imguiCommandBuffer; + SHEditorWindowManager::EditorWindowMap SHEditorWindowManager::editorWindows{}; + SHEditorWindowManager::EditorWindowID SHEditorWindowManager::windowCount{}; + //std::vector SHEditor::selectedEntities; //#==============================================================# //|| Public Member Functions || //#==============================================================# - void SHEditor::Initialise(SDL_Window* const sdlWindow) + void SHEditor::Init() { IMGUI_CHECKVERSION(); if(auto context = ImGui::CreateContext()) @@ -90,28 +90,28 @@ namespace SHADE InitFonts(); - auto id = SHFamilyID::GetID(); auto id2 = SHFamilyID::GetID(); auto id3 = SHFamilyID::GetID(); - InitBackend(sdlWindow); + + InitBackend(); SetStyle(Style::SHADE); //Add editor windows - CreateEditorWindow(); - CreateEditorWindow(); - CreateEditorWindow(); - CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); SHLOG_INFO("Successfully initialised SHADE Engine Editor") } - void SHEditor::Update(float const dt) + void SHEditor::Update(double const dt) { (void)dt; NewFrame(); - for (const auto& window : editorWindows | std::views::values) + for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values) { if(window->isOpen) window->Update(); @@ -260,7 +260,7 @@ namespace SHADE //#==============================================================# //|| Private Member Functions || //#==============================================================# - void SHEditor::InitBackend(SDL_Window* sdlWindow) + void SHEditor::InitBackend() { if(ImGui_ImplSDL2_InitForVulkan(sdlWindow) == false) { @@ -322,4 +322,9 @@ namespace SHADE } + void SHEditor::EditorRoutine::Execute(double dt) noexcept + { + reinterpret_cast(system)->Update(dt); + } + }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/SHEditor.hpp b/SHADE_Engine/src/Editor/SHEditor.hpp index 467cbcd0..d579a9b5 100644 --- a/SHADE_Engine/src/Editor/SHEditor.hpp +++ b/SHADE_Engine/src/Editor/SHEditor.hpp @@ -11,6 +11,8 @@ //#==============================================================# #include "SH_API.h" #include "ECS_Base/SHECSMacros.h" +#include "ECS_Base/System/SHSystem.h" +#include "ECS_Base/System/SHSystemRoutine.h" #include "Resource/Handle.h" #include "EditorWindow/SHEditorWindow.h" #include "Tools/SHLogger.h" @@ -28,11 +30,7 @@ namespace SHADE class SHVkCommandBuffer; class SHVkCommandPool; - /** - * @brief SHEditor static class contains editor variables and implementation of editor functions. - * - */ - class SH_API SHEditor + class SHEditorWindowManager { public: //#==============================================================# @@ -41,46 +39,6 @@ namespace SHADE using EditorWindowID = uint8_t; using EditorWindowPtr = std::unique_ptr; using EditorWindowMap = std::unordered_map; - - /** - * @brief Style options - * - */ - enum class Style : uint8_t - { - SHADE, - DARK, - LIGHT, - CLASSIC - }; - - /** - * @brief Initialise the editor - * - * @param sdlWindow pointer to SDL_Window object created in application - */ - static void Initialise(SDL_Window* sdlWindow); - - /** - * @brief Update the editor and add to ImGui DrawList - * - * @param dt Delta-time of the frame - */ - static void Update(float dt); - - /** - * @brief Safely shutdown the editor - * - */ - static void Exit(); - - /** - * @brief Set the Style for the editor - * - * @param style Desired style - */ - static void SetStyle(Style style); - /** * @brief Get ID for the Editor Window Type * @@ -100,39 +58,6 @@ namespace SHADE return id; } - /** - * @brief Get pointer to the Editor Window - * - * @tparam T Type of editor window to retrieve - * @return T* Pointer to the editor window - */ - template , bool> = true> - static T* GetEditorWindow() - { - return reinterpret_cast(editorWindows[GetEditorWindowID()].get()); - } - - // List of selected entities - static std::vector selectedEntities; - - private: - /** - * @brief Initialise Backend for ImGui (SDL and Vulkan backend) - * - * @param sdlWindow Pointer to SDL_Window - */ - static void InitBackend(SDL_Window* sdlWindow); - /** - * @brief Start new frame for editor - * - */ - static void NewFrame(); - /** - * @brief Perform ImGui and ImGui Backend Render - * - */ - static void Render(); - /** * @brief Create an Editor Window * @@ -153,16 +78,114 @@ namespace SHADE } } - static void InitFonts() noexcept; - - // Handle to command pool used for ImGui Vulkan Backend - static Handle imguiCommandPool; - // Handle to command buffer used for ImGui Vulkan Backend - static Handle imguiCommandBuffer; + /** + * @brief Get pointer to the Editor Window + * + * @tparam T Type of editor window to retrieve + * @return T* Pointer to the editor window + */ + template , bool> = true> + static T* GetEditorWindow() + { + return reinterpret_cast(editorWindows[GetEditorWindowID()].get()); + } + private: // Number of windows; used for Editor Window ID Generation static EditorWindowID windowCount; // Map of Editor Windows static EditorWindowMap editorWindows; + friend class SHEditor; + }; + + /** + * @brief SHEditor static class contains editor variables and implementation of editor functions. + * + */ + class SH_API SHEditor final : public SHSystem + { + public: + + + class SH_API EditorRoutine final : public SHSystemRoutine + { + public: + EditorRoutine() = default; + void Execute(double dt) noexcept override final; + }; + + /** + * @brief Style options + * + */ + enum class Style : uint8_t + { + SHADE, + DARK, + LIGHT, + CLASSIC + }; + + /** + * @brief Initialise the editor + * + * @param sdlWindow pointer to SDL_Window object created in application + */ + void Init(); + + /** + * @brief Update the editor and add to ImGui DrawList + * + * @param dt Delta-time of the frame + */ + void Update(double dt); + + /** + * @brief Safely shutdown the editor + * + */ + void Exit(); + + /** + * @brief Set the Style for the editor + * + * @param style Desired style + */ + void SetStyle(Style style); + + /** + * @brief Initialise Backend for ImGui (SDL and Vulkan backend) + * + * @param sdlWindow Pointer to SDL_Window + */ + void InitBackend(); + + void SetSDLWindow(SDL_Window* inSDLWindow){sdlWindow = inSDLWindow;}; + + // List of selected entities + std::vector selectedEntities; + + private: + /** + * @brief Start new frame for editor + * + */ + void NewFrame(); + /** + * @brief Perform ImGui and ImGui Backend Render + * + */ + void Render(); + + + + void InitFonts() noexcept; + + // Handle to command pool used for ImGui Vulkan Backend + Handle imguiCommandPool; + // Handle to command buffer used for ImGui Vulkan Backend + Handle imguiCommandBuffer; + + SDL_Window* sdlWindow; };//class SHEditor }//namespace SHADE From 22cad78728a22e198a848d273a1d4ee52bc23321 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Fri, 14 Oct 2022 15:53:29 +0800 Subject: [PATCH 45/61] Clean up --- SHADE_Application/src/Application/SBApplication.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index eb7d5432..202a3852 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -136,18 +136,7 @@ namespace Sandbox SHFrameRateController::UpdateFRC(); SHInputManager::UpdateInput(SHFrameRateController::GetRawDeltaTime()); SHSceneManager::UpdateSceneManager(); - SHSceneManager::SceneUpdate(1/60.0f); - //#ifdef SHEDITOR - //#endif - //graphicsSystem->BeginRender(); - - #ifdef SHEDITOR - //SHADE::SHEditor::Update(0.16f); - #endif - - //graphicsSystem->Run(1.0f); - //graphicsSystem->EndRender(); - + SHSceneManager::SceneUpdate(0.016f); SHSystemManager::RunRoutines(false, 0.016f); } From 3b3492843fe743c28dd1c5961977e449e8e4c638 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sun, 16 Oct 2022 03:25:33 +0800 Subject: [PATCH 46/61] Added input class --- SHADE_Managed/src/Input/Input.cxx | 102 ++++++++++ SHADE_Managed/src/Input/Input.hxx | 325 ++++++++++++++++++++++++++++++ 2 files changed, 427 insertions(+) create mode 100644 SHADE_Managed/src/Input/Input.cxx create mode 100644 SHADE_Managed/src/Input/Input.hxx diff --git a/SHADE_Managed/src/Input/Input.cxx b/SHADE_Managed/src/Input/Input.cxx new file mode 100644 index 00000000..0a386f3a --- /dev/null +++ b/SHADE_Managed/src/Input/Input.cxx @@ -0,0 +1,102 @@ +/************************************************************************************//*! +\file Input.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 16, 2022 +\brief Contains the definition of the managed Input static class. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#include "SHpch.h" +#include "Input.hxx" +#include "Utility/Convert.hxx" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + Vector3 Input::MousePosition::get() + { + int x, y; + SHInputManager::GetMouseWindowPosition(&x, &y); + return Vector3(static_cast(x), static_cast(y), 0.0f); + } + int Input::MouseScrollDelta::get() + { + return SHInputManager::GetMouseWheelVerticalDelta(); + } + + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + bool Input::GetKey(KeyCode key) + { + return SHInputManager::GetKey(static_cast(key)); + } + + bool Input::GetKeyDown(KeyCode key) + { + return SHInputManager::GetKeyDown(static_cast(key)); + } + + bool Input::GetKeyUp(KeyCode key) + { + return SHInputManager::GetKeyUp(static_cast(key)); + } + + bool Input::GetMouseButton(MouseCode mouseButton) + { + return SHInputManager::GetKey(static_cast(mouseButton)); + } + + bool Input::GetMouseButtonDown(MouseCode mouseButton) + { + return SHInputManager::GetKeyDown(static_cast(mouseButton)); + } + + bool Input::GetMouseButtonUp(MouseCode mouseButton) + { + return SHInputManager::GetKeyUp(static_cast(mouseButton)); + } + + /*---------------------------------------------------------------------------------*/ + /* Cursor Functions */ + /*---------------------------------------------------------------------------------*/ + void Input::SetMousePosition(Vector2 pos) + { + SHInputManager::SetMouseWindowPosition + ( + static_cast(pos.x), + static_cast(pos.y) + ); + } + + /*---------------------------------------------------------------------------------*/ + /* Time Functions */ + /*---------------------------------------------------------------------------------*/ + double Input::GetKeyHeldTime(KeyCode key) + { + return SHInputManager::GetKeyHeldTime(static_cast(key)); + } + + double Input::GetKeyReleasedTime(KeyCode key) + { + return SHInputManager::GetKeyReleasedTime(static_cast(key)); + } + + double Input::GetMouseHeldTime(MouseCode key) + { + return SHInputManager::GetKeyHeldTime(static_cast(key)); + } + + double Input::GetMouseReleasedTime(MouseCode key) + { + return SHInputManager::GetKeyReleasedTime(static_cast(key)); + } + +} \ No newline at end of file diff --git a/SHADE_Managed/src/Input/Input.hxx b/SHADE_Managed/src/Input/Input.hxx new file mode 100644 index 00000000..f281e4c8 --- /dev/null +++ b/SHADE_Managed/src/Input/Input.hxx @@ -0,0 +1,325 @@ +/************************************************************************************//*! +\file Input.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 16, 2022 +\brief Contains the definition of the managed Input static class. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +#include "Input/SHInputManager.h" +#include "Math/Vector2.hxx" +#include "Math/Vector3.hxx" + +namespace SHADE +{ + /// + /// Static class responsible for providing access to Input-related functionality. + /// + public ref class Input abstract sealed + { + public: + /*-----------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Represents the available supported keycodes that can be passed into the + /// key-based Input functions. + /// + enum class KeyCode : int + { + Space = static_cast(SHInputManager::SH_KEYCODE::SPACE), + //Apostrophe = static_cast(SHInputManager::SH_KEYCODE::APOSTROPHE), + Comma = static_cast(SHInputManager::SH_KEYCODE::OEM_COMMA), + Minus = static_cast(SHInputManager::SH_KEYCODE::OEM_MINUS), + Period = static_cast(SHInputManager::SH_KEYCODE::OEM_PERIOD), + //Slash = static_cast(SHInputManager::SH_KEYCODE::SLASH), + Key0 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_0), + Key1 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_1), + Key2 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_2), + Key3 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_3), + Key4 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_4), + Key5 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_5), + Key6 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_6), + Key7 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_7), + Key8 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_8), + Key9 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_9), + + //Semicolon = static_cast(SHInputManager::SH_KEYCODE::SEMICOLON), + //Equal = static_cast(SHInputManager::SH_KEYCODE::EQUAL), + + A = static_cast(SHInputManager::SH_KEYCODE::A), + B = static_cast(SHInputManager::SH_KEYCODE::B), + C = static_cast(SHInputManager::SH_KEYCODE::C), + D = static_cast(SHInputManager::SH_KEYCODE::D), + E = static_cast(SHInputManager::SH_KEYCODE::E), + F = static_cast(SHInputManager::SH_KEYCODE::F), + G = static_cast(SHInputManager::SH_KEYCODE::G), + H = static_cast(SHInputManager::SH_KEYCODE::H), + I = static_cast(SHInputManager::SH_KEYCODE::I), + J = static_cast(SHInputManager::SH_KEYCODE::J), + K = static_cast(SHInputManager::SH_KEYCODE::K), + L = static_cast(SHInputManager::SH_KEYCODE::L), + M = static_cast(SHInputManager::SH_KEYCODE::M), + N = static_cast(SHInputManager::SH_KEYCODE::N), + O = static_cast(SHInputManager::SH_KEYCODE::O), + P = static_cast(SHInputManager::SH_KEYCODE::P), + Q = static_cast(SHInputManager::SH_KEYCODE::Q), + R = static_cast(SHInputManager::SH_KEYCODE::R), + S = static_cast(SHInputManager::SH_KEYCODE::S), + T = static_cast(SHInputManager::SH_KEYCODE::T), + U = static_cast(SHInputManager::SH_KEYCODE::U), + V = static_cast(SHInputManager::SH_KEYCODE::V), + W = static_cast(SHInputManager::SH_KEYCODE::W), + X = static_cast(SHInputManager::SH_KEYCODE::X), + Y = static_cast(SHInputManager::SH_KEYCODE::Y), + Z = static_cast(SHInputManager::SH_KEYCODE::Z), + + //LeftBracket = static_cast(SHInputManager::SH_KEYCODE::LEFTBRACKET), + //BackSlash = static_cast(SHInputManager::SH_KEYCODE::BACKSLASH), + //RightBracket = static_cast(SHInputManager::SH_KEYCODE::RIGHTBRACKET), + //GraveAccent = static_cast(SHInputManager::SH_KEYCODE::GRAVEACCENT), + + //WORLD1 = static_cast(SHInputManager::SH_KEYCODE::WORLD1), + //WORLD2 = static_cast(SHInputManager::SH_KEYCODE::WORLD2), + + /* Function keys */ + Escape = static_cast(SHInputManager::SH_KEYCODE::ESCAPE), + Enter = static_cast(SHInputManager::SH_KEYCODE::ENTER), + Tab = static_cast(SHInputManager::SH_KEYCODE::TAB), + Backspace = static_cast(SHInputManager::SH_KEYCODE::BACKSPACE), + Insert = static_cast(SHInputManager::SH_KEYCODE::INSERT), + Delete = static_cast(SHInputManager::SH_KEYCODE::DEL), + Right = static_cast(SHInputManager::SH_KEYCODE::RIGHT_ARROW), + Left = static_cast(SHInputManager::SH_KEYCODE::LEFT_ARROW), + Down = static_cast(SHInputManager::SH_KEYCODE::DOWN_ARROW), + Up = static_cast(SHInputManager::SH_KEYCODE::UP_ARROW), + PageUp = static_cast(SHInputManager::SH_KEYCODE::PAGE_UP), + PageDown = static_cast(SHInputManager::SH_KEYCODE::PAGE_DOWN), + Home = static_cast(SHInputManager::SH_KEYCODE::HOME), + End = static_cast(SHInputManager::SH_KEYCODE::END), + CapsLock = static_cast(SHInputManager::SH_KEYCODE::CAPS_LOCK), + ScrollLock = static_cast(SHInputManager::SH_KEYCODE::SCROLL_LOCK), + NumLock = static_cast(SHInputManager::SH_KEYCODE::NUM_LOCK), + PrintScreen = static_cast(SHInputManager::SH_KEYCODE::PRINT_SCREEN), + Pause = static_cast(SHInputManager::SH_KEYCODE::PAUSE), + F1 = static_cast(SHInputManager::SH_KEYCODE::F1), + F2 = static_cast(SHInputManager::SH_KEYCODE::F2), + F3 = static_cast(SHInputManager::SH_KEYCODE::F3), + F4 = static_cast(SHInputManager::SH_KEYCODE::F4), + F5 = static_cast(SHInputManager::SH_KEYCODE::F5), + F6 = static_cast(SHInputManager::SH_KEYCODE::F6), + F7 = static_cast(SHInputManager::SH_KEYCODE::F7), + F8 = static_cast(SHInputManager::SH_KEYCODE::F8), + F9 = static_cast(SHInputManager::SH_KEYCODE::F9), + F10 = static_cast(SHInputManager::SH_KEYCODE::F10), + F11 = static_cast(SHInputManager::SH_KEYCODE::F11), + F12 = static_cast(SHInputManager::SH_KEYCODE::F12), + F13 = static_cast(SHInputManager::SH_KEYCODE::F13), + F14 = static_cast(SHInputManager::SH_KEYCODE::F14), + F15 = static_cast(SHInputManager::SH_KEYCODE::F15), + F16 = static_cast(SHInputManager::SH_KEYCODE::F16), + F17 = static_cast(SHInputManager::SH_KEYCODE::F17), + F18 = static_cast(SHInputManager::SH_KEYCODE::F18), + F19 = static_cast(SHInputManager::SH_KEYCODE::F19), + F20 = static_cast(SHInputManager::SH_KEYCODE::F20), + F21 = static_cast(SHInputManager::SH_KEYCODE::F21), + F22 = static_cast(SHInputManager::SH_KEYCODE::F22), + F23 = static_cast(SHInputManager::SH_KEYCODE::F23), + F24 = static_cast(SHInputManager::SH_KEYCODE::F24), + + /* Keypad */ + KeyPad0 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_0), + KeyPad1 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_1), + KeyPad2 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_2), + KeyPad3 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_3), + KeyPad4 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_4), + KeyPad5 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_5), + KeyPad6 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_6), + KeyPad7 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_7), + KeyPad8 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_8), + KeyPad9 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_9), + //KeyPadDecimal = static_cast(SHInputManager::SH_KEYCODE::KPDECIMAL), + //KeyPadDivide = static_cast(SHInputManager::SH_KEYCODE::KPDIVIDE), + //KeyPadMultiply = static_cast(SHInputManager::SH_KEYCODE::KPMULTIPLY), + //KeyPadSubtract = static_cast(SHInputManager::SH_KEYCODE::KPSUBTRACT), + //KeyPadAdd = static_cast(SHInputManager::SH_KEYCODE::KPADD), + //KeyPadEnter = static_cast(SHInputManager::SH_KEYCODE::KPENTER), + //KeyPadEqual = static_cast(SHInputManager::SH_KEYCODE::KEYPAD), + + Shift = static_cast(SHInputManager::SH_KEYCODE::SHIFT), + LeftControl = static_cast(SHInputManager::SH_KEYCODE::LEFT_CTRL), + LeftAlt = static_cast(SHInputManager::SH_KEYCODE::LEFT_ALT), + LeftSuper = static_cast(SHInputManager::SH_KEYCODE::LEFT_WINDOWS), + RightShift = static_cast(SHInputManager::SH_KEYCODE::RIGHT_SHIFT), + RightControl = static_cast(SHInputManager::SH_KEYCODE::RIGHT_CTRL), + RightAlt = static_cast(SHInputManager::SH_KEYCODE::RIGHT_ALT), + RightSuper = static_cast(SHInputManager::SH_KEYCODE::RIGHT_WINDOWS), + + /* Gamepad */ + JoystickA = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_A), + JoystickB = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_B), + JoystickX = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_X), + JoystickY = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_Y), + JoystickLeftBumper = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_LEFTSHOULDER), + JoystickRightBumper = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_RIGHTSHOULDER), + JoystickLeftTrigger = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_LEFTTRIGGER), + JoystickRightTrigger = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_RIGHTTRIGGER), + JoystickDPadUp = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_UP), + JoystickDPadDown = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_DOWN), + JoystickDPadLeft = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_LEFT), + JoystickDPadRight = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_RIGHT), + JoystickMenu = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_MENU), + JoystickView = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_VIEW), + JoystickLeftStick = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_LEFT_THUMBSTICK_BUTTON), + JoystickRightStick = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_RIGHT_THUMBSTICK_BUTTON), + + /* Unity Gamepad Mappings */ + JoystickButton0 = JoystickA, + JoystickButton1 = JoystickB, + JoystickButton2 = JoystickX, + JoystickButton3 = JoystickY, + JoystickButton4 = JoystickLeftBumper, + JoystickButton5 = JoystickRightBumper, + JoystickButton6 = JoystickView, + JoystickButton7 = JoystickMenu, + JoystickButton8 = JoystickLeftStick, + JoystickButton9 = JoystickRightStick + + }; + /// + /// Represents the available supported mouse keycodes that can be passed into the + /// mouse-button-based Input functions. + /// + enum class MouseCode : int + { + LeftButton = static_cast(SHInputManager::SH_KEYCODE::LMB), + RightButton = static_cast(SHInputManager::SH_KEYCODE::RMB), + MiddleButton = static_cast(SHInputManager::SH_KEYCODE::MMB), + Button3 = static_cast(SHInputManager::SH_KEYCODE::XMB1), + Button4 = static_cast(SHInputManager::SH_KEYCODE::XMB2) + }; + + /*-----------------------------------------------------------------------------*/ + /* Properites */ + /*-----------------------------------------------------------------------------*/ + /// + /// Mouse position in screen coordinates relative to the top left of the window. + /// This value is a Vector3 for compatibility with functions that have Vector3 + /// arguments. The z component of the Vector3 is always 0 + /// + static property Vector3 MousePosition + { + Vector3 get(); + } + /// + /// Amnount of vertical mouse scroll in this frame. + /// + static property int MouseScrollDelta + { + int get(); + } + + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Checks if a specified key is being held down. + /// This will also be true if GetKeyDown() is true. + /// + /// KeyCode of the key to check. + /// True while the user holds down the key specified. + static bool GetKey(KeyCode key); + /// + /// Checks if a specified key is pressed and was not pressed before. + /// + /// KeyCode of the key to check. + /// + /// True during the frame the user starts pressing down the key specified. + /// + static bool GetKeyDown(KeyCode key); + /// + /// Checks if a specified key is no longer pressed pressed and was pressed + /// before. + /// + /// KeyCode of the key to check. + /// + /// True during the frame the user releases the key identified by name. + /// + static bool GetKeyUp(KeyCode key); + /// + /// Checks if a specified mouse button is being held down. + /// This will also be true if GetMouseButtonDown() is true. + /// + /// MouseCode of the mouse button to check. + /// True while the user holds down the mouse button specified. + static bool GetMouseButton(MouseCode mouseButton); + /// + /// Checks if a specified mouse button is pressed and was not pressed before. + /// + /// MouseCode of the mouse button to check. + /// + /// True during the frame the user pressed the given mouse button. + /// + static bool GetMouseButtonDown(MouseCode mouseButton); + /// + /// Checks if a specified mouse button is no longer pressed and was pressed + /// before. + /// + /// MouseCode of the mouse button to check. + /// + /// True during the frame the user releases the given mouse button. + /// + static bool GetMouseButtonUp(MouseCode mouseButton); + + /*-----------------------------------------------------------------------------*/ + /* Cursor Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Sets the position of the mouse cursor relative to the top left corner of the + /// window. + /// + /// + /// Position of the mouse in window pixel coordinates to set. + /// + static void SetMousePosition(Vector2 pos); + + /*-----------------------------------------------------------------------------*/ + /* Timing Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Retrieves the duration that the specified key has been held or was last held + /// for. + /// + /// The key to check. + /// Time in seconds that the key was held. + static double GetKeyHeldTime(KeyCode key); + /// + /// Retrieves the duration that the specified key has not been held or was last + /// not been held for. + /// + /// The key to check. + /// Time in seconds that the key was held. + static double GetKeyReleasedTime(KeyCode key); + /// + /// Retrieves the duration that the specified key has been held or was last held + /// for. + /// + /// The key to check. + /// Time in seconds that the key was held. + static double GetMouseHeldTime(MouseCode mouseButton); + /// + /// Retrieves the duration that the specified key has not been held or was last + /// not been held for. + /// + /// The key to check. + /// Time in seconds that the key was held. + static double GetMouseReleasedTime(MouseCode mouseButton); + }; +} \ No newline at end of file From 808274fce08c6f1ebf72f6b4308440b79b63e9e7 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 16 Oct 2022 14:16:14 +0800 Subject: [PATCH 47/61] Lots of changes - World renderer graph add new resource for scene - G-Buffer Write subpass now renders offscreen to a color attachment - Added a new subpass "Scene layout transition" to get vulkan to help transition our scene image layout to shader read - Added back SHEDITOR check - Created a post offscreen render system to create the necessary objects - SH_ATT_DESC_TYPE is now SH_ATT_DESC_TYPE_FLAGS. Render graph resources also now store a bit field instead of a single type. - Render graph nodes now have more customization when it comes to registering resources. They now have the option to not clear resources on begin. --- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 23 +++- .../MiddleEnd/Interface/SHGraphicsSystem.h | 20 +-- .../Interface/SHPostOffscreenRenderSystem.cpp | 79 ++++++++++++ .../Interface/SHPostOffscreenRenderSystem.h | 29 +++++ .../SHAttachmentDescInitParams.cpp | 7 + .../RenderGraph/SHAttachmentDescInitParams.h | 14 ++ .../RenderGraph/SHAttachmentDescriptionType.h | 13 +- .../Graphics/RenderGraph/SHRenderGraph.cpp | 50 +++++-- .../src/Graphics/RenderGraph/SHRenderGraph.h | 23 +++- .../RenderGraph/SHRenderGraphNode.cpp | 16 ++- .../Graphics/RenderGraph/SHRenderGraphNode.h | 3 +- .../RenderGraph/SHRenderGraphResource.cpp | 122 +++++++++++------- .../RenderGraph/SHRenderGraphResource.h | 13 +- .../src/Graphics/RenderGraph/SHSubpass.cpp | 8 +- .../src/Graphics/RenderGraph/SHSubpass.h | 2 +- SHADE_Engine/src/Graphics/SHVulkanDefines.h | 1 + 16 files changed, 317 insertions(+), 106 deletions(-) create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h create mode 100644 SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.cpp create mode 100644 SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.h diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 09f1c93e..14ddf7be 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -144,27 +144,32 @@ namespace SHADE // Initialize world render graph worldRenderGraph->Init(device, swapchain); - worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second); - worldRenderGraph->AddResource("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); - worldRenderGraph->AddResource("Entity ID", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); + worldRenderGraph->AddResource("Present", {SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT}, windowDims.first, windowDims.second); + worldRenderGraph->AddResource("Scene", {SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT}, windowDims.first, windowDims.second); + worldRenderGraph->AddResource("Depth Buffer", {SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL}, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); + worldRenderGraph->AddResource("Entity ID", {SH_ATT_DESC_TYPE_FLAGS::COLOR}, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); //worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); //worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); //worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); //worldRenderGraph->AddResource("Scene", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eB8G8R8A8Unorm); - auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Present"}, {}); // no predecessors + auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene"}, {}); // no predecessors //First subpass to write to G-Buffer auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write"); - gBufferWriteSubpass->AddColorOutput("Present"); + gBufferWriteSubpass->AddColorOutput("Scene"); gBufferWriteSubpass->AddColorOutput("Entity ID"); - gBufferWriteSubpass->AddDepthOutput ("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL); + gBufferWriteSubpass->AddDepthOutput ("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); + // We do this to just transition our scene layout to shader read + auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition"); + sceneLayoutTransitionSubpass->AddInput("Scene"); - // TODO: Use macro to add this node when SH_EDITOR is enabled +#ifdef SHEDITOR auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {"G-Buffer"}); auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw"); imguiSubpass->AddColorOutput("Present"); +#endif worldRenderGraph->Generate(); @@ -207,6 +212,10 @@ namespace SHADE cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]); mousePickSystem->Init(device, cmdPools, worldRenderGraph->GetRenderGraphResource("Entity ID")); + + // Register the post offscreen render to the system + postOffscreenRender = resourceManager.Create(); + postOffscreenRender->Init(device, worldRenderGraph->GetRenderGraphResource("Scene"), descPool); } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 3160cd57..517b5999 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -31,6 +31,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h" #include "../Textures/SHTextureLibrary.h" #include "../Textures/SHVkSamplerCache.h" +#include "Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h" namespace SHADE { @@ -262,14 +263,15 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Getters (Temporary) */ /*-----------------------------------------------------------------------------*/ - Handle GetDevice() const { return device; } - Handle GetSwapchain() const { return swapchain; } - Handle GetSurface() const { return surface; } - Handle GetPhysicalDevice() const { return physicalDevice; } - Handle GetQueue() const { return graphicsQueue; } - Handle GetDescriptorPool() const { return descPool; } - Handle GetDefaultViewport() const {return defaultViewport;} - Handle GetMousePickSystem(void) const noexcept {return mousePickSystem;}; + Handle GetDevice() const { return device; } + Handle GetSwapchain() const { return swapchain; } + Handle GetSurface() const { return surface; } + Handle GetPhysicalDevice() const { return physicalDevice; } + Handle GetQueue() const { return graphicsQueue; } + Handle GetDescriptorPool() const { return descPool; } + Handle GetDefaultViewport() const {return defaultViewport;} + Handle GetMousePickSystem(void) const noexcept {return mousePickSystem;}; + Handle GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;}; //SHRenderGraph const& GetRenderGraph(void) const noexcept; //Handle GetRenderPass() const { return renderPass; } @@ -327,5 +329,7 @@ namespace SHADE // Sub systems Handle mousePickSystem; + Handle postOffscreenRender; + }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp new file mode 100644 index 00000000..7d40d9bd --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp @@ -0,0 +1,79 @@ +#include "SHpch.h" +#include "SHPostOffscreenRenderSystem.h" +#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" +#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" +#include "Graphics/Descriptors/SHVkDescriptorPool.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/Images/SHVkSampler.h" +#include "Graphics/RenderGraph/SHRenderGraphResource.h" + +namespace SHADE +{ + /***************************************************************************/ + /*! + + \brief + This function basically creates the entities required for offscreen + rendering. It takes in a render graph resource. Side note: it creates + a descriptor set layout that is similar to the one created in imgui. This + is so that the descriptor set passed to imGui won't be invalid. + + \param logicalDevice + For vulkan object creation + + \param renderGraphResource + The resource in which has been + + \param descriptorPool + + \return + + */ + /***************************************************************************/ + void SHPostOffscreenRenderSystem::Init(Handle logicalDevice, Handle renderGraphResource, Handle descriptorPool) noexcept + { + offscreenRender = renderGraphResource; + + // Create sampler + offscreenRenderSampler = logicalDevice->CreateSampler( + { + .minFilter = vk::Filter::eLinear, + .magFilter = vk::Filter::eLinear, + .addressMode = vk::SamplerAddressMode::eRepeat, + .mipmapMode = vk::SamplerMipmapMode::eLinear, + .minLod = -1000, + .maxLod = 1000 + } + ); + + // Create descriptor set layout binding + SHVkDescriptorSetLayout::Binding imageBinding + { + .Type = vk::DescriptorType::eCombinedImageSampler, + .Stage = vk::ShaderStageFlagBits::eFragment, + .BindPoint = 0, + .DescriptorCount = 1, + }; + + // Create descriptor set layout + offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout(0, { imageBinding }); + + // Create descriptor set + offscreenRenderDescSet = descriptorPool->Allocate({ offscreenRenderDescSetLayout }, { 1 }); + + std::vector combinedImageSampler + { + std::make_tuple(renderGraphResource->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eShaderReadOnlyOptimal), + }; + + // Register the image view and sampler with the descriptor set. Now whenever rendering to the offscreen image is done, the descriptor set will see the change + offscreenRenderDescSet->ModifyWriteDescImage(0, 0, combinedImageSampler); + offscreenRenderDescSet->UpdateDescriptorSetImages(0, 0); + } + + Handle SHPostOffscreenRenderSystem::GetDescriptorSetGroup(void) const noexcept + { + return offscreenRenderDescSet; + } + +} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h new file mode 100644 index 00000000..90767bc2 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h @@ -0,0 +1,29 @@ +#pragma once + +#include "Resource/Handle.h" + +namespace SHADE +{ + class SHVkLogicalDevice; + class SHVkDescriptorSetLayout; + class SHVkDescriptorSetGroup; + class SHVkDescriptorPool; + class SHVkSampler; + class SHRenderGraphResource; + + class SHPostOffscreenRenderSystem + { + private: + Handle offscreenRender; + + Handle offscreenRenderDescSetLayout; + Handle offscreenRenderDescSet; + Handle offscreenRenderSampler; + + public: + void Init (Handle logicalDevice, Handle renderGraphResource, Handle descriptorPool) noexcept; + //void Run () + + Handle GetDescriptorSetGroup (void) const noexcept; + }; +} diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.cpp new file mode 100644 index 00000000..6e01269e --- /dev/null +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.cpp @@ -0,0 +1,7 @@ +#include "SHpch.h" +#include "SHAttachmentDescInitParams.h" + +namespace SHADE +{ + +} diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.h b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.h new file mode 100644 index 00000000..20e924cb --- /dev/null +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Resource/Handle.h" + +namespace SHADE +{ + class SHRenderGraphResource; + + struct SHAttachmentDescInitParams + { + Handle resourceHdl; + bool dontClearOnLoad{false}; + }; +} diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h index dc21fa37..241292d4 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h @@ -3,12 +3,13 @@ namespace SHADE { // Used for attachment description creation for renderpass node - enum class SH_ATT_DESC_TYPE + enum class SH_ATT_DESC_TYPE_FLAGS { - COLOR, - COLOR_PRESENT, - DEPTH, - STENCIL, - DEPTH_STENCIL, + COLOR = 0x01, + COLOR_PRESENT = 0x02, + DEPTH = 0x04, + STENCIL = 0x08, + DEPTH_STENCIL = 0x10, + INPUT = 0x20 }; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 1861f6d2..51584300 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -8,10 +8,17 @@ #include "Graphics/Framebuffer/SHVkFramebuffer.h" #include "Graphics/Buffers/SHVkBuffer.h" #include "Tools/SHLogger.h" +#include "SHAttachmentDescInitParams.h" namespace SHADE { - + + SHRenderGraph::ResourceInstruction::ResourceInstruction(char const* resourceName, bool dontClearOnLoad /*= false*/) noexcept + : resourceName{ resourceName } + , dontClearOnLoad{ dontClearOnLoad } + { + + } /***************************************************************************/ /*! @@ -40,7 +47,7 @@ namespace SHADE */ /***************************************************************************/ - void SHRenderGraph::AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w /*= static_cast(-1)*/, uint32_t h /*= static_cast(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/) + void SHRenderGraph::AddResource(std::string resourceName, std::initializer_list typeFlags, uint32_t w /*= static_cast(-1)*/, uint32_t h /*= static_cast(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/) { // If we set to if (w == static_cast(-1) && h == static_cast(-1)) @@ -50,7 +57,7 @@ namespace SHADE format = swapchainHdl->GetSurfaceFormatKHR().format; } - graphResources.try_emplace(resourceName, resourceManager.Create(logicalDeviceHdl, swapchainHdl, resourceName, type, format, w, h, levels, usageFlags, createFlags)); + graphResources.try_emplace(resourceName, resourceManager.Create(logicalDeviceHdl, swapchainHdl, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); } /***************************************************************************/ @@ -82,7 +89,7 @@ namespace SHADE { for (auto& color : subpass->colorReferences) { - if (i == nodes.size() - 1 && node->attResources[color.attachment]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) + if (i == nodes.size() - 1 && (node->attResources[color.attachment]->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT))) resourceAttLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR; else resourceAttLayouts[color.attachment] = color.layout; @@ -210,10 +217,18 @@ namespace SHADE for (auto& inputAtt : subpass->inputReferences) { auto resource = node->attResources[inputAtt.attachment]; - if (resource->resourceType == SH_ATT_DESC_TYPE::COLOR || resource->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) - colorRead |= (1 << i); - else if (resource->resourceType == SH_ATT_DESC_TYPE::DEPTH_STENCIL) - depthRead |= (1 << i); + if (resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::INPUT)) + { + if (resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR) || + resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) + colorRead |= (1 << i); + else if (resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL)) + depthRead |= (1 << i); + } + else + { + SHLOG_ERROR("While configuring subpass, an input reference was detected but the resource to be used is not marked as SH_ATT_DESC_TYPE_FLAGS::INPUT. "); + } } ++i; @@ -400,7 +415,7 @@ namespace SHADE */ /***************************************************************************/ - Handle SHRenderGraph::AddNode(std::string nodeName, std::initializer_list resourceNames, std::initializer_list predecessorNodes) noexcept + SHADE::Handle SHRenderGraph::AddNode(std::string nodeName, std::initializer_list resourceInstruction, std::initializer_list predecessorNodes) noexcept { if (nodeIndexing.contains(nodeName)) { @@ -408,12 +423,19 @@ namespace SHADE return {}; } - std::vector> resources; - for (auto const& name : resourceNames) + std::vector descInitParams; + for (auto const& instruction : resourceInstruction) { // If the resource that the new node is requesting for exists, allow the graph to reference it - if (graphResources.contains(name)) - resources.push_back(graphResources.at(name)); + if (graphResources.contains(instruction.resourceName)) + { + descInitParams.push_back( + { + .resourceHdl = graphResources.at(instruction.resourceName), + .dontClearOnLoad = false, + } + ); + } else { SHLOG_ERROR("Resource doesn't exist in graph yet. Cannot create new node."); @@ -435,7 +457,7 @@ namespace SHADE } } - nodes.emplace_back(resourceManager.Create(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(resources), std::move(predecessors), &graphResources)); + nodes.emplace_back(resourceManager.Create(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(descInitParams), std::move(predecessors), &graphResources)); nodeIndexing.emplace(nodeName, static_cast(nodes.size()) - 1u); return nodes.at(nodeIndexing[nodeName]); } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index cfc29bc2..8eb458aa 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -33,7 +33,17 @@ namespace SHADE class SH_API SHRenderGraph { + public: + struct ResourceInstruction + { + std::string resourceName; + bool dontClearOnLoad; + + ResourceInstruction (char const* resourceName, bool dontClearOnLoad = false) noexcept; + }; + private: + /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ @@ -74,13 +84,14 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - void Init (Handle const& logicalDevice, Handle const& swapchain) noexcept; - void AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast(-1), uint32_t h = static_cast(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {}); - Handle AddNode (std::string nodeName, std::initializer_list resourceNames, std::initializer_list predecessorNodes) noexcept; + void Init (Handle const& logicalDevice, Handle const& swapchain) noexcept; + void AddResource(std::string resourceName, std::initializer_list typeFlags, uint32_t w = static_cast(-1), uint32_t h = static_cast(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {}); + Handle AddNode (std::string nodeName, std::initializer_list resourceInstruction, std::initializer_list predecessorNodes) noexcept; + void Generate (void) noexcept; - void Execute (uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept; - void FinaliseBatch(uint32_t frameIndex, Handle descPool); - void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept; + void Execute (uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept; + void FinaliseBatch(uint32_t frameIndex, Handle descPool); + void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept; /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index ea09dd47..0ff8fe96 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -42,7 +42,7 @@ namespace SHADE for (uint32_t j = 0; j < attResources.size(); ++j) { - uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) ? i : 0; + uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0; imageViews[j] = attResources[j]->imageViews[imageViewIndex]; // We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's @@ -69,7 +69,7 @@ namespace SHADE for (uint32_t j = 0; j < attResources.size(); ++j) { - uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) ? i : 0; + uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0; imageViews[j] = attResources[j]->imageViews[imageViewIndex]; // We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's @@ -104,14 +104,14 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphNode::SHRenderGraphNode(ResourceManager& rm, Handle const& logicalDevice, Handle const& swapchain, std::vector> attRes, std::vector> predecessors, std::unordered_map> const* resources) noexcept + SHRenderGraphNode::SHRenderGraphNode(ResourceManager& rm, Handle const& logicalDevice, Handle const& swapchain, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept : logicalDeviceHdl{ logicalDevice } , renderpass{} , framebuffers{} , prereqNodes{ std::move(predecessors) } , attachmentDescriptions{} , resourceAttachmentMapping{} - , attResources{ std::move(attRes) } + , attResources{ } , subpasses{} , executed{ false } , configured{ false } @@ -121,6 +121,12 @@ namespace SHADE // pipeline library initialization pipelineLibrary.Init(logicalDeviceHdl); + // Store all the handles to resources + attResources.reserve (attDescInitParams.size()); + for (auto& param : attDescInitParams) + attResources.push_back(param.resourceHdl); + + // We have as many descriptions as we have resources attachmentDescriptions.resize(attResources.size()); bool containsSwapchainImage = false; @@ -140,7 +146,7 @@ namespace SHADE newDesc.format = attResources[i]->resourceFormat; - if (attResources[i]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) + if (attResources[i]->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) containsSwapchainImage = true; resourceAttachmentMapping.try_emplace(attResources[i].GetId().Raw, i); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 28527a92..f36e7622 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -9,6 +9,7 @@ #include "SH_API.h" #include "Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h" #include "Graphics/MiddleEnd/Batching/SHBatcher.h" +#include "SHAttachmentDescInitParams.h" namespace SHADE { @@ -87,7 +88,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphNode(ResourceManager& rm, Handle const& logicalDevice, Handle const& swapchain, std::vector> attRes, std::vector> predecessors, std::unordered_map> const* resources) noexcept; + SHRenderGraphNode(ResourceManager& rm, Handle const& logicalDevice, Handle const& swapchain, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept; SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index bcd1dc9f..adf3b6cd 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -45,10 +45,10 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphResource::SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept + SHRenderGraphResource::SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept : logicalDevice {logicalDevice} , swapchain{ swapchain } - , resourceType{ type } + , resourceTypeFlags{ } , resourceFormat{ format } , images{} , imageViews{} @@ -58,52 +58,10 @@ namespace SHADE , resourceName{ name } { // If the resource type is an arbitrary image and not swapchain image - if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT) + if (typeFlags.size() == 1 && *typeFlags.begin() == SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT) { - imageAspectFlags = vk::ImageAspectFlags{}; - usage = usageFlags; + resourceTypeFlags |= static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT); - // Check the resource type and set image usage flags and image aspect flags accordingly - switch (resourceType) - { - case SH_ATT_DESC_TYPE::COLOR: - usage |= vk::ImageUsageFlagBits::eColorAttachment; - imageAspectFlags |= vk::ImageAspectFlagBits::eColor; - break; - case SH_ATT_DESC_TYPE::DEPTH: - usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; - imageAspectFlags |= vk::ImageAspectFlagBits::eDepth; - break; - case SH_ATT_DESC_TYPE::STENCIL: - usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; - imageAspectFlags |= vk::ImageAspectFlagBits::eStencil; - break; - case SH_ATT_DESC_TYPE::DEPTH_STENCIL: - usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; - imageAspectFlags |= vk::ImageAspectFlagBits::eStencil | vk::ImageAspectFlagBits::eDepth; - break; - } - - // The resource is not a swapchain image, just use the first slot of the vector - images.push_back(logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags)); - - // prepare image view details - SHImageViewDetails viewDetails - { - .viewType = vk::ImageViewType::e2D, - .format = images[0]->GetImageFormat(), - .imageAspectFlags = imageAspectFlags, - .baseMipLevel = 0, - .mipLevelCount = mipLevels, - .baseArrayLayer = 0, - .layerCount = 1, - }; - - // just 1 image view created - imageViews.push_back(images[0]->CreateImageView(logicalDevice, images[0], viewDetails)); - } - else // if swapchain image resource - { // Prepare image view details SHImageViewDetails viewDetails { @@ -126,6 +84,65 @@ namespace SHADE imageViews[i] = images[i]->CreateImageView(logicalDevice, images[i], viewDetails); } } + else // if swapchain image resource + { + imageAspectFlags = vk::ImageAspectFlags{}; + usage = usageFlags; + + for (auto& type : typeFlags) + { + // store the flags + resourceTypeFlags |= static_cast(type); + + // Check the resource type and set image usage flags and image aspect flags accordingly + switch (type) + { + case SH_ATT_DESC_TYPE_FLAGS::COLOR: + usage |= vk::ImageUsageFlagBits::eColorAttachment; + imageAspectFlags |= vk::ImageAspectFlagBits::eColor; + break; + case SH_ATT_DESC_TYPE_FLAGS::DEPTH: + usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; + imageAspectFlags |= vk::ImageAspectFlagBits::eDepth; + break; + case SH_ATT_DESC_TYPE_FLAGS::STENCIL: + usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; + imageAspectFlags |= vk::ImageAspectFlagBits::eStencil; + break; + case SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL: + usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; + imageAspectFlags |= vk::ImageAspectFlagBits::eStencil | vk::ImageAspectFlagBits::eDepth; + break; + case SH_ATT_DESC_TYPE_FLAGS::INPUT: + usage |= vk::ImageUsageFlagBits::eInputAttachment; + usage |= vk::ImageUsageFlagBits::eSampled; + break; + case SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT: + { + SHLOG_ERROR ("COLOR_PRESENT cannot be with other resource type flags. "); + return; + } + } + } + + // The resource is not a swapchain image, just use the first slot of the vector + images.push_back(logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags)); + + // prepare image view details + SHImageViewDetails viewDetails + { + .viewType = vk::ImageViewType::e2D, + .format = images[0]->GetImageFormat(), + .imageAspectFlags = imageAspectFlags, + .baseMipLevel = 0, + .mipLevelCount = mipLevels, + .baseArrayLayer = 0, + .layerCount = 1, + }; + + // just 1 image view created + imageViews.push_back(images[0]->CreateImageView(logicalDevice, images[0], viewDetails)); + } } /***************************************************************************/ @@ -141,7 +158,7 @@ namespace SHADE /***************************************************************************/ SHRenderGraphResource::SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept : resourceName{ std::move(rhs.resourceName) } - , resourceType{ std::move(rhs.resourceType) } + , resourceTypeFlags{ std::move(rhs.resourceTypeFlags) } , images{ std::move(rhs.images) } , imageViews{ std::move(rhs.imageViews) } , resourceFormat{ std::move(rhs.resourceFormat) } @@ -149,6 +166,7 @@ namespace SHADE , height{ rhs.height } , mipLevels{ rhs.mipLevels } , imageAspectFlags{ rhs.imageAspectFlags } + , swapchain {rhs.swapchain} { } @@ -172,7 +190,7 @@ namespace SHADE return *this; resourceName = std::move(rhs.resourceName); - resourceType = std::move(rhs.resourceType); + resourceTypeFlags = std::move(rhs.resourceTypeFlags); images = std::move(rhs.images); imageViews = std::move(rhs.imageViews); resourceFormat = std::move(rhs.resourceFormat); @@ -180,6 +198,7 @@ namespace SHADE height = rhs.height; mipLevels = rhs.mipLevels; imageAspectFlags = rhs.imageAspectFlags; + swapchain = rhs.swapchain; return *this; } @@ -202,7 +221,7 @@ namespace SHADE width = newWidth; height = newHeight; - if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT) + if ((resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) == 0) { // prepare image view details SHImageViewDetails viewDetails @@ -299,4 +318,9 @@ namespace SHADE return height; } + Handle SHRenderGraphResource::GetImageView(uint32_t index /*= NON_SWAPCHAIN_RESOURCE_INDEX*/) const noexcept + { + return imageViews [index]; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h index 66f0677b..efaf9bf5 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h @@ -16,6 +16,8 @@ namespace SHADE class SHVkCommandBuffer; class SHVkBuffer; + static constexpr uint32_t NON_SWAPCHAIN_RESOURCE_INDEX = 0; + class SH_API SHRenderGraphResource { private: @@ -32,7 +34,7 @@ namespace SHADE std::string resourceName; //! Used for initializing image layouts - SH_ATT_DESC_TYPE resourceType; + SHRenderGraphResourceFlags resourceTypeFlags; //! The resource itself (this is a vector because if the resource happens //! to be a swapchain image, then we need however many frames in flight). @@ -67,7 +69,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept; + SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept; SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept; SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept; ~SHRenderGraphResource(void) noexcept; @@ -82,9 +84,10 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ - vk::Format GetResourceFormat (void) const noexcept; - uint32_t GetWidth (void) const noexcept; - uint32_t GetHeight (void) const noexcept; + vk::Format GetResourceFormat (void) const noexcept; + uint32_t GetWidth (void) const noexcept; + uint32_t GetHeight (void) const noexcept; + Handle GetImageView (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept; friend class SHRenderGraphNode; friend class SHRenderGraph; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index abd3a7be..6afbfb09 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -120,18 +120,18 @@ namespace SHADE */ /***************************************************************************/ - void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType) noexcept + void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType) noexcept { vk::ImageLayout imageLayout; switch (attachmentDescriptionType) { - case SH_ATT_DESC_TYPE::DEPTH: + case SH_ATT_DESC_TYPE_FLAGS::DEPTH: imageLayout = vk::ImageLayout::eDepthAttachmentOptimal; break; - case SH_ATT_DESC_TYPE::STENCIL: + case SH_ATT_DESC_TYPE_FLAGS::STENCIL: imageLayout = vk::ImageLayout::eStencilAttachmentOptimal; break; - case SH_ATT_DESC_TYPE::DEPTH_STENCIL: + case SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL: imageLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal; break; default: diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h index aba282b9..2e883ebc 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h @@ -71,7 +71,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ // Preparation functions void AddColorOutput(std::string resourceToReference) noexcept; - void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType = SH_ATT_DESC_TYPE::DEPTH_STENCIL) noexcept; + void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType = SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL) noexcept; void AddInput(std::string resourceToReference) noexcept; // Runtime functions diff --git a/SHADE_Engine/src/Graphics/SHVulkanDefines.h b/SHADE_Engine/src/Graphics/SHVulkanDefines.h index 1cbcae0f..a0a6d57c 100644 --- a/SHADE_Engine/src/Graphics/SHVulkanDefines.h +++ b/SHADE_Engine/src/Graphics/SHVulkanDefines.h @@ -12,6 +12,7 @@ namespace SHADE using BindingAndSetHash = uint64_t; using SetIndex = uint32_t; using SHSubPassIndex = uint32_t; + using SHRenderGraphResourceFlags = uint32_t; } From 2830dad8e3f9d810d71d4dbeaaf80f704857e5c0 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 16 Oct 2022 15:35:32 +0800 Subject: [PATCH 48/61] Fixed Kai Wei's issues (sampler move ctor never move device :D) --- SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp | 4 +++- .../src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp b/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp index f12b834d..30bcde79 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp +++ b/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp @@ -39,7 +39,8 @@ namespace SHADE } SHVkSampler::SHVkSampler(SHVkSampler&& rhs) noexcept - : vkSampler { rhs.vkSampler } + : vkSampler{ rhs.vkSampler } + , device{ rhs.device } { rhs.vkSampler = nullptr; } @@ -56,6 +57,7 @@ namespace SHADE SHADE::SHVkSampler& SHVkSampler::operator=(SHVkSampler&& rhs) noexcept { vkSampler = rhs.vkSampler; + device = rhs.device; rhs.vkSampler = nullptr; return *this; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 14ddf7be..247c58fd 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -189,7 +189,6 @@ namespace SHADE worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); worldRenderer->SetCamera(worldCamera); - // TODO: This is VERY temporarily here until a more solid resource management system is implemented shaderSourceLibrary.Init("../../TempShaderFolder/"); From 0d02ece4c1f88272bb5b135a7cafccceaeacb38c Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 16 Oct 2022 16:28:29 +0800 Subject: [PATCH 49/61] Wrote handle resize for mouse picking objects --- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 2 ++ .../MiddleEnd/Interface/SHMousePickSystem.cpp | 29 ++++++++++++++----- .../MiddleEnd/Interface/SHMousePickSystem.h | 5 +++- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 247c58fd..cd99648c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -559,6 +559,8 @@ namespace SHADE worldRenderGraph->HandleResize(windowDims.first, windowDims.second); + mousePickSystem->HandleResize(); + defaultViewport->SetWidth(static_cast(windowDims.first)); defaultViewport->SetHeight(static_cast(windowDims.second)); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp index ee8665d5..e4ac92e5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp @@ -9,8 +9,10 @@ namespace SHADE { - void SHMousePickSystem::Init(Handle logicalDevice, std::span> cmdPools, Handle eidAttachment) noexcept + void SHMousePickSystem::Init(Handle device, std::span> cmdPools, Handle eidAttachment) noexcept { + logicalDevice = device; + pickedEID = 0; // Create command buffers @@ -22,13 +24,7 @@ namespace SHADE // assign the attachment entityIDAttachment = eidAttachment; - // Create the fence - afterCopyFence = logicalDevice->CreateFence(); - - uint32_t bufferSize = entityIDAttachment->GetWidth() * eidAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat()); - - // Create the buffer - imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + HandleResize(); } void SHMousePickSystem::Run(Handle queue, uint32_t frameIndex) noexcept @@ -63,6 +59,23 @@ namespace SHADE } } + void SHMousePickSystem::HandleResize(void) noexcept + { + if (afterCopyFence) + afterCopyFence.Free(); + + if (imageDataDstBuffer) + imageDataDstBuffer.Free(); + + // Create the fence + afterCopyFence = logicalDevice->CreateFence(); + + uint32_t bufferSize = entityIDAttachment->GetWidth() * entityIDAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat()); + + // Create the buffer + imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + } + EntityID SHMousePickSystem::GetPickedEntity(void) const noexcept { return pickedEID; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h index 080a192c..4b84c1df 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h @@ -17,6 +17,8 @@ namespace SHADE class SHMousePickSystem { private: + Handle logicalDevice; + //! Handle to the render graph resource that will contain the entity IDs Handle entityIDAttachment; @@ -35,8 +37,9 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - void Init(Handle logicalDevice, std::span> cmdPools, Handle eidAttachment) noexcept; + void Init(Handle device, std::span> cmdPools, Handle eidAttachment) noexcept; void Run (Handle queue, uint32_t frameIndex) noexcept; + void HandleResize (void) noexcept; /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ From 1117ecc5ef9556061681b7f50b20450ba93270da Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 16 Oct 2022 17:31:53 +0800 Subject: [PATCH 50/61] WIP --- .../src/Graphics/Devices/SHVkLogicalDevice.cpp | 5 ++--- .../src/Graphics/Devices/SHVkLogicalDevice.h | 2 +- .../src/Graphics/Images/SHVkSampler.cpp | 17 +++++++++-------- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 1 + .../Interface/SHPostOffscreenRenderSystem.cpp | 4 ++-- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index 4f4f94a4..7c7acfc5 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -550,10 +550,9 @@ namespace SHADE } - Handle SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector const& bindings) noexcept + Handle SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector const& bindings, bool genImmutableSamplers/* = false*/) noexcept { - return SHVkInstance::GetResourceManager().Create (GetHandle(), setIndex, bindings); - + return SHVkInstance::GetResourceManager().Create (GetHandle(), setIndex, bindings, genImmutableSamplers); } Handle SHVkLogicalDevice::CreateDescriptorPools(const SHVkDescriptorPool::Config& config /*= {}*/) noexcept diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index 5c400e02..6f7048b8 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -186,7 +186,7 @@ namespace SHADE Handle CreateRenderpass (std::span const vkDescriptions, std::vector const& subpasses) noexcept; Handle CreateRenderpass (std::span const vkDescriptions, std::span const spDescs, std::span const spDeps) noexcept; Handle CreateFramebuffer (Handle const& renderpassHdl, std::vector> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept; - Handle CreateDescriptorSetLayout (SetIndex setIndex, std::vector const& bindings) noexcept; + Handle CreateDescriptorSetLayout (SetIndex setIndex, std::vector const& bindings, bool genImmutableSamplers = false) noexcept; Handle CreateDescriptorPools (const SHVkDescriptorPool::Config& config = {}) noexcept; Handle CreateDescriptorSetGroup(Handle pool, std::vector> const& layouts, diff --git a/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp b/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp index 30bcde79..4300f2bd 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp +++ b/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp @@ -24,14 +24,15 @@ namespace SHADE { const vk::SamplerCreateInfo SAMPLER_CREATE_INFO { - .magFilter = params.magFilter, - .minFilter = params.minFilter, - .mipmapMode = params.mipmapMode, - .addressModeU = params.addressMode, - .addressModeV = params.addressMode, - .addressModeW = params.addressMode, - .minLod = params.minLod, - .maxLod = params.maxLod + .magFilter = params.magFilter, + .minFilter = params.minFilter, + .mipmapMode = params.mipmapMode, + .addressModeU = params.addressMode, + .addressModeV = params.addressMode, + .addressModeW = params.addressMode, + .maxAnisotropy = 1.0f, + .minLod = params.minLod, + .maxLod = params.maxLod, }; // Create the sampler diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index cd99648c..6d9a84aa 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -560,6 +560,7 @@ namespace SHADE worldRenderGraph->HandleResize(windowDims.first, windowDims.second); mousePickSystem->HandleResize(); + //postOffscreenRender->HandleResize(); defaultViewport->SetWidth(static_cast(windowDims.first)); defaultViewport->SetHeight(static_cast(windowDims.second)); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp index 7d40d9bd..bbc7c021 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp @@ -56,14 +56,14 @@ namespace SHADE }; // Create descriptor set layout - offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout(0, { imageBinding }); + offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout(0, { imageBinding }, true); // Create descriptor set offscreenRenderDescSet = descriptorPool->Allocate({ offscreenRenderDescSetLayout }, { 1 }); std::vector combinedImageSampler { - std::make_tuple(renderGraphResource->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eShaderReadOnlyOptimal), + std::make_tuple(renderGraphResource->GetImageView(), Handle{}, vk::ImageLayout::eShaderReadOnlyOptimal), }; // Register the image view and sampler with the descriptor set. Now whenever rendering to the offscreen image is done, the descriptor set will see the change From c16bea2d39fb0e86d6820ee0eb166e2b1d3ca852 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 16 Oct 2022 17:35:15 +0800 Subject: [PATCH 51/61] WIP --- .../Descriptors/SHVkDescriptorSetGroup.cpp | 2 +- .../Descriptors/SHVkDescriptorSetLayout.cpp | 29 +++++++++++++++++-- .../Descriptors/SHVkDescriptorSetLayout.h | 4 ++- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp index e842df47..ea859718 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp @@ -172,7 +172,7 @@ namespace SHADE // write sampler and image view auto& [view, sampler, layout] = imageViewsAndSamplers[i]; writeInfo.descImageInfos[i].imageView = view->GetImageView(); - writeInfo.descImageInfos[i].sampler = sampler->GetVkSampler(); + writeInfo.descImageInfos[i].sampler = sampler ? sampler->GetVkSampler() : nullptr; writeInfo.descImageInfos[i].imageLayout = layout; } } diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp index 002aa29d..0943c489 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp @@ -1,16 +1,18 @@ #include "SHPch.h" #include "SHVkDescriptorSetLayout.h" #include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/Images/SHVkSampler.h" namespace SHADE { /*---------------------------------------------------------------------------------*/ /* Constructor/Destructor */ /*---------------------------------------------------------------------------------*/ - SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle device, SetIndex set, const std::vector& bindings) + SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle device, SetIndex set, const std::vector& bindings, bool genImmutableSamplers/* = false*/) : device { device } , layoutDesc { bindings } , setIndex {set} + , immutableSampler{} { // Check if auto-binding point calculation configuration is valid bool autoCalc = false; @@ -26,6 +28,25 @@ namespace SHADE } } + vk::Sampler tempVkSampler = nullptr; + if (genImmutableSamplers) + { + // Create sampler + immutableSampler = device->CreateSampler( + { + .minFilter = vk::Filter::eLinear, + .magFilter = vk::Filter::eLinear, + .addressMode = vk::SamplerAddressMode::eRepeat, + .mipmapMode = vk::SamplerMipmapMode::eLinear, + .minLod = -1000, + .maxLod = 1000 + } + ); + + tempVkSampler = immutableSampler->GetVkSampler(); + } + + // Fill up VK bindings with auto calculated bind points if needed std::vector layoutBindings; layoutBindings.reserve(bindings.size()); @@ -39,7 +60,7 @@ namespace SHADE .descriptorType = binding.Type, .descriptorCount = binding.DescriptorCount, .stageFlags = binding.Stage, - .pImmutableSamplers = nullptr // We will create our own samplers + .pImmutableSamplers = genImmutableSamplers ? &tempVkSampler : nullptr, }; layoutBindings.emplace_back(VK_BINDING); @@ -75,7 +96,8 @@ namespace SHADE : device {rhs.device} , setLayout {rhs.setLayout} , layoutDesc{std::move (rhs.layoutDesc)} - , setIndex {rhs.setIndex} + , setIndex{ rhs.setIndex } + , immutableSampler{ rhs.immutableSampler } { rhs.setLayout = VK_NULL_HANDLE; } @@ -106,6 +128,7 @@ namespace SHADE setLayout = rhs.setLayout; layoutDesc = std::move(rhs.layoutDesc); setIndex = rhs.setIndex; + immutableSampler = rhs.immutableSampler; rhs.setLayout = VK_NULL_HANDLE; diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h index 9b436026..4fffbc96 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h @@ -10,6 +10,7 @@ namespace SHADE /* Forward Declarations */ /*---------------------------------------------------------------------------------*/ class SHVkLogicalDevice; + class SHVkSampler; /*---------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -74,7 +75,7 @@ namespace SHADE /// /// /// - SHVkDescriptorSetLayout(Handle device, SetIndex setIndex, const std::vector& bindings); + SHVkDescriptorSetLayout(Handle device, SetIndex setIndex, const std::vector& bindings, bool genImmutableSamplers = false); SHVkDescriptorSetLayout(const SHVkDescriptorSetLayout&) = delete; SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept; /// @@ -107,5 +108,6 @@ namespace SHADE vk::DescriptorSetLayout setLayout; std::vector layoutDesc; // Stores description of the layout SetIndex setIndex; // Index of the set + Handle immutableSampler; }; } \ No newline at end of file From 95ee4b7b550c090bd982a3f59615243ffc297a12 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 16 Oct 2022 19:42:44 +0800 Subject: [PATCH 52/61] Resize half working --- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 20 +++++++++++++------ .../MiddleEnd/Interface/SHGraphicsSystem.h | 3 +++ .../Interface/SHPostOffscreenRenderSystem.cpp | 9 +++++++-- .../Interface/SHPostOffscreenRenderSystem.h | 2 ++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 6d9a84aa..21d7569e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -71,7 +71,7 @@ namespace SHADE if (width == 0 || height == 0) return; - renderContext.SetIsResized(true); + PrepareResize(resizeWidth, resizeHeight); }); window->RegisterWindowCloseCallback([&](void) @@ -545,6 +545,14 @@ namespace SHADE ); } + void SHGraphicsSystem::PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept + { + resizeWidth = newWidth; + resizeHeight = newHeight; + + renderContext.SetIsResized(true); + } + void SHGraphicsSystem::HandleResize(void) noexcept { if (window->IsMinimized() || renderContext.GetWindowIsDead()) @@ -557,15 +565,15 @@ namespace SHADE renderContext.HandleResize(); - worldRenderGraph->HandleResize(windowDims.first, windowDims.second); + worldRenderGraph->HandleResize(resizeWidth, resizeHeight); mousePickSystem->HandleResize(); - //postOffscreenRender->HandleResize(); + postOffscreenRender->HandleResize(); - defaultViewport->SetWidth(static_cast(windowDims.first)); - defaultViewport->SetHeight(static_cast(windowDims.second)); + defaultViewport->SetWidth(static_cast(resizeWidth)); + defaultViewport->SetHeight(static_cast(resizeHeight)); - worldCamera->SetPerspective(90.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 100.0f); + worldCamera->SetPerspective(90.0f, static_cast(resizeWidth), static_cast(resizeHeight), 0.0f, 100.0f); } void SHGraphicsSystem::AwaitGraphicsExecution() diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 517b5999..c3b39514 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -252,6 +252,7 @@ namespace SHADE /***************************************************************************/ void BuildTextures(); + void PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept; void HandleResize(void) noexcept; void AwaitGraphicsExecution(); @@ -331,5 +332,7 @@ namespace SHADE Handle mousePickSystem; Handle postOffscreenRender; + uint32_t resizeWidth; + uint32_t resizeHeight; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp index bbc7c021..8b41a979 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp @@ -56,14 +56,19 @@ namespace SHADE }; // Create descriptor set layout - offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout(0, { imageBinding }, true); + offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout(0, { imageBinding }, false); // Create descriptor set offscreenRenderDescSet = descriptorPool->Allocate({ offscreenRenderDescSetLayout }, { 1 }); + HandleResize(); + } + + void SHPostOffscreenRenderSystem::HandleResize(void) noexcept + { std::vector combinedImageSampler { - std::make_tuple(renderGraphResource->GetImageView(), Handle{}, vk::ImageLayout::eShaderReadOnlyOptimal), + std::make_tuple(offscreenRender->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eShaderReadOnlyOptimal), }; // Register the image view and sampler with the descriptor set. Now whenever rendering to the offscreen image is done, the descriptor set will see the change diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h index 90767bc2..d3360b87 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h @@ -24,6 +24,8 @@ namespace SHADE void Init (Handle logicalDevice, Handle renderGraphResource, Handle descriptorPool) noexcept; //void Run () + void HandleResize (void) noexcept; + Handle GetDescriptorSetGroup (void) const noexcept; }; } From b10f490e45381422cdd81ef68d99aaca2d67215b Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sun, 16 Oct 2022 23:15:11 +0800 Subject: [PATCH 53/61] SP3-102 SP3-248 Saving of SHMETA files with asset IDs, retrieval of asset data under works, currently all assets are loaded into memory automatically --- Assets/Cube.003.shmesh.shmeta | 3 + Assets/Cube.012.shmesh.shmeta | 3 + .../RaccoonPreTexturedVer1_Base9.shtex.shmeta | 3 + .../src/Application/SBApplication.cpp | 7 +- .../src/Assets/Asset Types/SHTextureAsset.h | 1 + .../src/Assets/Libraries/SHMeshCompiler.cpp | 4 +- .../src/Assets/Libraries/SHMeshCompiler.h | 2 +- .../src/Assets/Libraries/SHMeshLoader.cpp | 3 +- .../src/Assets/Libraries/SHMeshLoader.h | 2 +- .../Assets/Libraries/SHTextureCompiler.cpp | 4 +- .../src/Assets/Libraries/SHTextureCompiler.h | 2 +- .../src/Assets/Libraries/SHTextureLoader.cpp | 1 + .../src/Assets/Libraries/SHTextureLoader.h | 2 +- SHADE_Engine/src/Assets/SHAssetMacros.h | 9 +- SHADE_Engine/src/Assets/SHAssetManager.cpp | 112 ++++++++++++------ .../src/Assets/SHAssetMetaHandler.cpp | 29 +++-- 16 files changed, 132 insertions(+), 55 deletions(-) create mode 100644 Assets/Cube.003.shmesh.shmeta create mode 100644 Assets/Cube.012.shmesh.shmeta create mode 100644 Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta diff --git a/Assets/Cube.003.shmesh.shmeta b/Assets/Cube.003.shmesh.shmeta new file mode 100644 index 00000000..d41be546 --- /dev/null +++ b/Assets/Cube.003.shmesh.shmeta @@ -0,0 +1,3 @@ +Name: Cube.003 +ID: 110152941 +Type:  diff --git a/Assets/Cube.012.shmesh.shmeta b/Assets/Cube.012.shmesh.shmeta new file mode 100644 index 00000000..d5cd1090 --- /dev/null +++ b/Assets/Cube.012.shmesh.shmeta @@ -0,0 +1,3 @@ +Name: Cube.012 +ID: 107348815 +Type:  diff --git a/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta b/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta new file mode 100644 index 00000000..f8c267d9 --- /dev/null +++ b/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta @@ -0,0 +1,3 @@ +Name: RaccoonPreTexturedVer1_Base9 +ID: 91918845 +Type:  diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 202a3852..5a265d39 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -104,10 +104,10 @@ namespace Sandbox //TODO: REMOVE AFTER PRESENTATION //SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf"); - SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh"); + //SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh"); //SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds"); //SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds"); - SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex"); + //SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex"); //TODO: REMOVE AFTER PRESENTATION @@ -125,6 +125,8 @@ namespace Sandbox SHSceneManager::InitSceneManager("TestScene"); SHFrameRateController::UpdateFRC(); + + SHAssetManager::Load(); } void SBApplication::Update(void) @@ -154,6 +156,7 @@ namespace Sandbox SHSceneManager::Exit(); SHSystemManager::Exit(); + SHAssetManager::Unload(); } } diff --git a/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h index 07cebea9..d24b6c02 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h @@ -9,6 +9,7 @@ namespace SHADE { bool compiled; + std::string name; uint32_t numBytes; uint32_t width; uint32_t height; diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp index 12b2517e..8026f0e1 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp @@ -16,7 +16,7 @@ #include -void SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept +std::string SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept { std::string newPath{ path.string() }; newPath = newPath.substr(0, newPath.find_last_of('/') + 1); @@ -67,4 +67,6 @@ void SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPat ); file.close(); + + return newPath; } diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.h b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.h index 6da00525..a8ce67be 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.h +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.h @@ -21,6 +21,6 @@ namespace SHADE { private: public: - static void CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept; + static std::string CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp index 3a5fb9ec..4bfa2d9b 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp @@ -142,8 +142,7 @@ namespace SHADE SHLOG_ERROR("Unable to open SHMesh File: {}", path.string()); } - std::string name{ path.filename().string() }; - name = name.substr(0, name.find_last_of('.')); + const std::string name{ path.stem().string() }; file.seekg(0); diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h index 3e430aca..a27d63ea 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h @@ -29,8 +29,8 @@ namespace SHADE static void LoadExternal(std::vector& meshes, AssetPath path) noexcept; - static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept; public: static void LoadMesh(std::vector& meshes, AssetPath path) noexcept; + static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.cpp b/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.cpp index 62af4da6..49de6b5c 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.cpp @@ -17,7 +17,7 @@ namespace SHADE { - void SHTextureCompiler::CompileTextureBinary(SHTextureAsset const& asset, AssetPath path) + std::string SHTextureCompiler::CompileTextureBinary(SHTextureAsset const& asset, AssetPath path) { std::string newPath{ path.string() }; newPath = newPath.substr(0, newPath.find_last_of('.')); @@ -69,5 +69,7 @@ namespace SHADE ); file.close(); + + return newPath; } } diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.h b/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.h index d8685795..52980084 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.h +++ b/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.h @@ -19,6 +19,6 @@ namespace SHADE { struct SHTextureCompiler { - static void CompileTextureBinary(SHTextureAsset const& asset, AssetPath path); + static std::string CompileTextureBinary(SHTextureAsset const& asset, AssetPath path); }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp index 47501d42..5147562a 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp @@ -93,6 +93,7 @@ namespace SHADE std::memcpy(pixel, file.GetImageData()->m_mem, totalBytes); //pixel = std::move(reinterpret_cast(file.GetDDSData())); + asset.name = path.stem().string(); asset.compiled = false; asset.numBytes = static_cast(totalBytes); asset.width = file.GetWidth(); diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h index e84fe5cf..eb61ea91 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h @@ -26,8 +26,8 @@ namespace SHADE static void LoadTinyDDS(AssetPath path, SHTextureAsset& asset) noexcept; - static void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept; public: static void LoadImageAsset(AssetPath paths, SHTextureAsset& image); + static void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept; }; } diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index 8c462af7..61c5879d 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -40,7 +40,7 @@ typedef FMOD::Sound* SHSound; #define ASSET_META_VER "1.0" // Asset type enum -enum class AssetType : uint8_t +enum class AssetType : AssetTypeMeta { INVALID = 0, AUDIO = 1, @@ -57,7 +57,12 @@ enum class AssetType : uint8_t }; //Directory -#define ASSET_ROOT "./Assets/" +#ifdef _PUBLISH +#define ASSET_ROOT "Assets" +#else +#define ASSET_ROOT "../../Assets" +#endif + // ASSET EXTENSIONS #define META_EXTENSION ".shmeta" diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 430b8c79..e3578f92 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -307,12 +307,22 @@ namespace SHADE for (auto const& mesh : meshes) { - meshCollection.emplace(GenerateAssetID(AssetType::MESH), mesh); + auto id{ GenerateAssetID(AssetType::MESH) }; + meshCollection.emplace(id, mesh); + AssetPath path; if (!mesh.compiled) { - SHMeshCompiler::CompileMeshBinary(mesh, asset.path); + path = SHMeshCompiler::CompileMeshBinary(mesh, asset.path); } + + assetCollection.emplace_back( + mesh.header.meshName, + id, + AssetType::MESH, + path, + 0 + ); } } @@ -322,11 +332,20 @@ namespace SHADE SHTextureLoader::LoadImageAsset(asset.path, image); - textureCollection.emplace(GenerateAssetID(AssetType::DDS), image); - if (!image.compiled) { - SHTextureCompiler::CompileTextureBinary(image, asset.path); + auto id{ GenerateAssetID(AssetType::TEXTURE) }; + textureCollection.emplace(id, image); + + auto path{ SHTextureCompiler::CompileTextureBinary(image, asset.path) }; + + assetCollection.emplace_back( + image.name, + id, + AssetType::TEXTURE, + path, + 0 + ); } } @@ -344,8 +363,24 @@ namespace SHADE ****************************************************************************/ void SHAssetManager::LoadAllData() noexcept { + //TODO Remove when on demand loading is done for (auto const& asset : assetCollection) { + switch (asset.type) + { + case AssetType::MESH: + meshCollection.emplace(asset.id, SHMeshAsset()); + SHMeshLoader::LoadSHMesh(meshCollection[asset.id], asset.path); + break; + + case AssetType::TEXTURE: + textureCollection.emplace(asset.id, SHTextureAsset()); + SHTextureLoader::LoadSHTexture(asset.path, textureCollection[asset.id]); + break; + + default: + void; + } } } @@ -362,40 +397,51 @@ namespace SHADE std::vector metaFiles; std::vector AssetFiles; - //TODO: Write new function for file manager to loop through all files - SHFileSystem::StartupFillDirectories(ASSET_ROOT); - FolderPointer rootFolder = SHFileSystem::GetRoot(); - - for (auto const& meta : metaFiles) + for (auto const dir : std::filesystem::recursive_directory_iterator(ASSET_ROOT)) { - for (std::vector::const_iterator it{ AssetFiles.cbegin() }; - it != AssetFiles.cend(); - ++it) + if (dir.path().extension().string() == META_EXTENSION) { - // Asset exists for meta file - std::string fileExtCheck{ it->filename().string() }; - fileExtCheck += META_EXTENSION; - if (meta.filename().string() == fileExtCheck) - { - RegisterAsset(meta, *it); - AssetFiles.erase(it); - break; - } + auto meta{ SHAssetMetaHandler::RetrieveMetaData(dir.path()) }; + + assetCollection.push_back(meta); + assetRegistry.emplace(meta.id, meta); } } + //TODO: Write new function for file manager to loop through all files + //SHFileSystem::StartupFillDirectories(ASSET_ROOT); + //FolderPointer rootFolder = SHFileSystem::GetRoot(); + + //for (auto const& meta : metaFiles) + //{ + // for (std::vector::const_iterator it{ AssetFiles.cbegin() }; + // it != AssetFiles.cend(); + // ++it) + // { + // // Asset exists for meta file + // std::string fileExtCheck{ it->filename().string() }; + // fileExtCheck += META_EXTENSION; + // if (meta.filename().string() == fileExtCheck) + // { + // RegisterAsset(meta, *it); + // AssetFiles.erase(it); + // break; + // } + // } + //} + //TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa) - for (auto const& file : AssetFiles) - { - if (IsRecognised(file.extension().string().c_str())) - { - SHAssetMetaHandler::WriteMetaData(RegisterAssetNew(file)); - } - else - { - std::cout << "Unsupported File Format: " << file.filename() << "\n"; - } - } + //for (auto const& file : AssetFiles) + //{ + // if (IsRecognised(file.extension().string().c_str())) + // { + // SHAssetMetaHandler::WriteMetaData(RegisterAssetNew(file)); + // } + // else + // { + // std::cout << "Unsupported File Format: " << file.filename() << "\n"; + // } + //} } AssetID SHAssetManager::RetrieveAsset(char const* path) noexcept diff --git a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp index 6554a3e4..442c3d96 100644 --- a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp +++ b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp @@ -72,6 +72,13 @@ namespace SHADE std::string line; SHAsset meta; + // Get resource name + GetFieldValue(metaFile, line); + std::stringstream nameStream{ line }; + AssetName name; + nameStream >> name; + meta.name = name; + // Get resource id GetFieldValue(metaFile, line); std::stringstream idStream{ line }; @@ -88,6 +95,8 @@ namespace SHADE metaFile.close(); + meta.path = path.parent_path().string() + "/" + path.stem().string(); + return meta; } @@ -103,7 +112,7 @@ namespace SHADE std::string path{ meta.path.string() }; path.append(META_EXTENSION); - std::ofstream metaFile{ path, std::ios_base::out }; + std::ofstream metaFile{ path, std::ios_base::out | std::ios_base::trunc }; if (!metaFile.is_open()) { @@ -113,17 +122,17 @@ namespace SHADE metaFile << "Name: " << meta.name << "\n"; metaFile << "ID: " << meta.id << "\n"; - metaFile << "Type: " << static_cast(meta.type) << std::endl; + metaFile << "Type: " << static_cast(meta.type) << std::endl; - //TODO Add in information that is specific to types like mesh - switch(meta.type) - { - case AssetType::MESH: - break; + ////TODO Add in information that is specific to types like mesh + //switch(meta.type) + //{ + //case AssetType::MESH: + // break; - default: - break; - } + //default: + // break; + //} metaFile.close(); } From 013bb713258fafbe46917380763ec0beaf76b05b Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Mon, 17 Oct 2022 15:04:38 +0800 Subject: [PATCH 54/61] Functions to retrieve mesh and texture data --- SHADE_Engine/src/Assets/SHAssetManager.cpp | 20 ++++++++++++++++++++ SHADE_Engine/src/Assets/SHAssetManager.h | 2 ++ 2 files changed, 22 insertions(+) diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index e3578f92..aa9772dd 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -255,6 +255,26 @@ namespace SHADE return result; } + SHMeshAsset const* SHAssetManager::GetMesh(AssetID id) noexcept + { + if (meshCollection.find(id) == meshCollection.end()) + { + return nullptr; + } + + return &meshCollection[id]; + } + + SHTextureAsset const* SHAssetManager::GetTexture(AssetID id) noexcept + { + if (textureCollection.find(id) == textureCollection.end()) + { + return nullptr; + } + + return &textureCollection[id]; + } + /**************************************************************************** * \param Path for meta data file * \param Path for asset file diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index 7064d63d..50549e01 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -75,6 +75,8 @@ namespace SHADE static std::vector GetAllMeshes() noexcept; static std::vector GetAllTextures() noexcept; + static SHMeshAsset const* GetMesh(AssetID id) noexcept; + static SHTextureAsset const* GetTexture(AssetID id) noexcept; private: /**************************************************************************** * \brief Load resource data into memory From 17b71393f34974c64a55285518c0044a1889033f Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Mon, 17 Oct 2022 16:50:53 +0800 Subject: [PATCH 55/61] Restructured abit --- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 207 ++++++++++-------- .../MiddleEnd/Interface/SHGraphicsSystem.h | 15 +- 2 files changed, 132 insertions(+), 90 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 21d7569e..d5a45cf7 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -36,11 +36,9 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { +#pragma region INIT_EXIT - /*---------------------------------------------------------------------------------*/ - /* Constructor/Destructors */ - /*---------------------------------------------------------------------------------*/ - void SHGraphicsSystem::Init(void) + void SHGraphicsSystem::InitBoilerplate(void) noexcept { /*-----------------------------------------------------------------------*/ /* BACKEND BOILERPLATE */ @@ -51,7 +49,7 @@ namespace SHADE // Get Physical Device and Construct Logical Device physicalDevice = SHVkInstance::CreatePhysicalDevice(SH_PHYSICAL_DEVICE_TYPE::BEST); device = SHVkInstance::CreateLogicalDevice({ SHQueueParams(SH_Q_FAM::GRAPHICS, SH_QUEUE_SELECT::DEDICATED), SHQueueParams(SH_Q_FAM::TRANSFER, SH_QUEUE_SELECT::DEDICATED) }, physicalDevice); - + // Construct surface surface = device->CreateSurface(window->GetHWND()); @@ -106,11 +104,12 @@ namespace SHADE graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true); transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); + } - - + void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept + { /*-----------------------------------------------------------------------*/ - /* MIDDLE END SETUP + /* MIDDLE END SETUP - Viewports - Renderer - Render graph in renderers @@ -118,6 +117,7 @@ namespace SHADE - Default vertex input state - Global data /*-----------------------------------------------------------------------*/ + auto windowDims = window->GetWindowSize(); SHGraphicsGlobalData::Init(device); @@ -132,63 +132,49 @@ namespace SHADE // Create Default Viewport defaultViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast(window->GetWindowSize().first), static_cast(window->GetWindowSize().second), 0.0f, 1.0f)); - + // Get render graph from default viewport world renderer - worldRenderGraph = resourceManager.Create(); - - std::vector> renderContextCmdPools{swapchain->GetNumImages()}; + sceneRenderGraph = resourceManager.Create(); + + std::vector> renderContextCmdPools{ swapchain->GetNumImages() }; for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i) { renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0]; } // Initialize world render graph - worldRenderGraph->Init(device, swapchain); - worldRenderGraph->AddResource("Present", {SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT}, windowDims.first, windowDims.second); - worldRenderGraph->AddResource("Scene", {SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT}, windowDims.first, windowDims.second); - worldRenderGraph->AddResource("Depth Buffer", {SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL}, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); - worldRenderGraph->AddResource("Entity ID", {SH_ATT_DESC_TYPE_FLAGS::COLOR}, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); + sceneRenderGraph->Init(device, swapchain); + sceneRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); + sceneRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT }, windowDims.first, windowDims.second); + sceneRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); + sceneRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); - //worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); - //worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); - //worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); - //worldRenderGraph->AddResource("Scene", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eB8G8R8A8Unorm); - auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene"}, {}); // no predecessors + auto node = sceneRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene" }, {}); // no predecessors //First subpass to write to G-Buffer auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write"); gBufferWriteSubpass->AddColorOutput("Scene"); gBufferWriteSubpass->AddColorOutput("Entity ID"); - gBufferWriteSubpass->AddDepthOutput ("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); + gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); // We do this to just transition our scene layout to shader read auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition"); sceneLayoutTransitionSubpass->AddInput("Scene"); #ifdef SHEDITOR - auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {"G-Buffer"}); + auto imguiNode = sceneRenderGraph->AddNode("ImGui Node", { "Present" }, { "G-Buffer" }); auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw"); imguiSubpass->AddColorOutput("Present"); #endif - worldRenderGraph->Generate(); - - // Create Semaphore - for (auto& semaHandle : graphSemaphores) - { - semaHandle = device->CreateSemaphore(); - } - - // Create Debug Renderers - /*debugScreenRenderer = defaultViewport->AddRenderer(resourceManager, worldRenderGraph); - debugScreenRenderer->SetCamera(screenCamera); - debugWorldRenderer = defaultViewport->AddRenderer(resourceManager, worldRenderGraph); - debugWorldRenderer->SetCamera(worldCamera);*/ + // Generate world render graph + sceneRenderGraph->Generate(); // Add world renderer to default viewport - worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); + worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], sceneRenderGraph); worldRenderer->SetCamera(worldCamera); + // TODO: This is VERY temporarily here until a more solid resource management system is implemented shaderSourceLibrary.Init("../../TempShaderFolder/"); @@ -202,21 +188,59 @@ namespace SHADE cubeFS->Reflect(); defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass); + } + + void SHGraphicsSystem::InitMiddleEnd(void) noexcept + { + InitSceneRenderGraph(); + + // Create Semaphore + for (auto& semaHandle : graphSemaphores) + { + semaHandle = device->CreateSemaphore(); + } + } + + void SHGraphicsSystem::InitSubsystems(void) noexcept + { mousePickSystem = resourceManager.Create(); std::vector> cmdPools; cmdPools.reserve(swapchain->GetNumImages()); for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i) - cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]); + cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]); - mousePickSystem->Init(device, cmdPools, worldRenderGraph->GetRenderGraphResource("Entity ID")); + mousePickSystem->Init(device, cmdPools, sceneRenderGraph->GetRenderGraphResource("Entity ID")); // Register the post offscreen render to the system postOffscreenRender = resourceManager.Create(); - postOffscreenRender->Init(device, worldRenderGraph->GetRenderGraphResource("Scene"), descPool); + postOffscreenRender->Init(device, sceneRenderGraph->GetRenderGraphResource("Scene"), descPool); } + /*---------------------------------------------------------------------------------*/ + /* Constructor/Destructors */ + /*---------------------------------------------------------------------------------*/ + void SHGraphicsSystem::Init(void) + { + InitBoilerplate(); + InitMiddleEnd(); + InitSubsystems(); + + + } + + void SHGraphicsSystem::Exit(void) + { + } + +#pragma endregion INIT_EXIT + +#pragma region LIFECYCLE + + /*---------------------------------------------------------------------------------*/ + /* Lifecycle Functions */ + /*---------------------------------------------------------------------------------*/ /***************************************************************************/ /*! @@ -336,14 +360,7 @@ namespace SHADE } } } - - void SHGraphicsSystem::Exit(void) - { - } - - /*---------------------------------------------------------------------------------*/ - /* Lifecycle Functions */ - /*---------------------------------------------------------------------------------*/ + /***************************************************************************/ /*! @@ -435,6 +452,10 @@ namespace SHADE renderContext.AdvanceFrame(); } +#pragma endregion LIFECYCLE + +#pragma region ADD_REMOVE_BUILD + Handle SHGraphicsSystem::AddViewport(const vk::Viewport& viewport) { // Create the viewport @@ -545,47 +566,9 @@ namespace SHADE ); } - void SHGraphicsSystem::PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept - { - resizeWidth = newWidth; - resizeHeight = newHeight; - - renderContext.SetIsResized(true); - } - - void SHGraphicsSystem::HandleResize(void) noexcept - { - if (window->IsMinimized() || renderContext.GetWindowIsDead()) - return; - - auto windowDims = window->GetWindowSize(); - - // Resize the swapchain - swapchain->Resize(surface, windowDims.first, windowDims.second); - - renderContext.HandleResize(); - - worldRenderGraph->HandleResize(resizeWidth, resizeHeight); - - mousePickSystem->HandleResize(); - postOffscreenRender->HandleResize(); - - defaultViewport->SetWidth(static_cast(resizeWidth)); - defaultViewport->SetHeight(static_cast(resizeHeight)); - - worldCamera->SetPerspective(90.0f, static_cast(resizeWidth), static_cast(resizeHeight), 0.0f, 100.0f); - } - - void SHGraphicsSystem::AwaitGraphicsExecution() - { - device->WaitIdle(); - } - - void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept - { - window = wind; - } +#pragma endregion ADD_REMOVE +#pragma region ROUTINES /*-----------------------------------------------------------------------------------*/ /* System Routine Functions - BeginRoutine */ /*-----------------------------------------------------------------------------------*/ @@ -657,5 +640,51 @@ namespace SHADE renderable.ResetChangedFlag(); } } +#pragma endregion ROUTINES +#pragma region MISC + + void SHGraphicsSystem::PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept + { + resizeWidth = newWidth; + resizeHeight = newHeight; + + renderContext.SetIsResized(true); + } + + void SHGraphicsSystem::HandleResize(void) noexcept + { + if (window->IsMinimized() || renderContext.GetWindowIsDead()) + return; + + auto windowDims = window->GetWindowSize(); + + // Resize the swapchain + swapchain->Resize(surface, windowDims.first, windowDims.second); + + renderContext.HandleResize(); + + sceneRenderGraph->HandleResize(resizeWidth, resizeHeight); + + mousePickSystem->HandleResize(); + postOffscreenRender->HandleResize(); + + defaultViewport->SetWidth(static_cast(resizeWidth)); + defaultViewport->SetHeight(static_cast(resizeHeight)); + + worldCamera->SetPerspective(90.0f, static_cast(resizeWidth), static_cast(resizeHeight), 0.0f, 100.0f); + } + + void SHGraphicsSystem::AwaitGraphicsExecution() + { + device->WaitIdle(); + } + + void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept + { + window = wind; + } + + +#pragma endregion MISC } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index c3b39514..e6739715 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -67,6 +67,12 @@ namespace SHADE /***********************************************************************************/ class SH_API SHGraphicsSystem : public SHSystem { + private: + void InitBoilerplate (void) noexcept; + void InitSceneRenderGraph(void) noexcept; + void InitMiddleEnd (void) noexcept; + void InitSubsystems (void) noexcept; + public: class SH_API BeginRoutine final : public SHSystemRoutine { @@ -279,6 +285,7 @@ namespace SHADE private: + /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ @@ -305,6 +312,12 @@ namespace SHADE SHSamplerCache samplerCache; SHMaterialInstanceCache materialInstanceCache; // Viewports +#ifdef SHEDITOR + Handle editorViewport; + Handle editorRenderer; + Handle editorRenderGraph; +#endif + Handle defaultViewport; // Whole screen std::vector> viewports; // Additional viewports @@ -326,7 +339,7 @@ namespace SHADE // Temp Materials Handle defaultMaterial; - Handle worldRenderGraph; + Handle sceneRenderGraph; // Sub systems Handle mousePickSystem; From 7b7533420eca64a859209f782e3ef2689afb3a23 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Tue, 18 Oct 2022 01:12:03 +0800 Subject: [PATCH 56/61] WIP --- .../MiddleEnd/Interface/SHGraphicsConstants.h | 6 ++ .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 75 ++++++++++++++----- .../MiddleEnd/Interface/SHGraphicsSystem.h | 19 +++-- .../MiddleEnd/Interface/SHMousePickSystem.cpp | 3 + .../MiddleEnd/Interface/SHRenderer.cpp | 11 ++- .../Graphics/RenderGraph/SHRenderGraph.cpp | 15 ++-- .../src/Graphics/RenderGraph/SHRenderGraph.h | 3 +- .../RenderGraph/SHRenderGraphNode.cpp | 15 ++-- .../Graphics/RenderGraph/SHRenderGraphNode.h | 4 +- .../src/Graphics/RenderGraph/SHSubpass.cpp | 6 +- .../src/Graphics/RenderGraph/SHSubpass.h | 2 +- .../Graphics/Renderpass/SHVkRenderpass.cpp | 3 +- SHADE_Engine/src/Resource/SparseSet.h | 6 +- 13 files changed, 118 insertions(+), 50 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h index ac2f1f8c..67cbc001 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h @@ -25,6 +25,12 @@ namespace SHADE struct SHGraphicsConstants { public: + struct RenderGraphIndices + { + static constexpr uint32_t WORLD = 0; + static constexpr uint32_t EDITOR = 0; + }; + struct DescriptorSetIndex { /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index d5a45cf7..929e5d54 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -119,7 +119,6 @@ namespace SHADE /*-----------------------------------------------------------------------*/ auto windowDims = window->GetWindowSize(); - SHGraphicsGlobalData::Init(device); // Set Up Cameras screenCamera = resourceManager.Create(); @@ -134,7 +133,7 @@ namespace SHADE defaultViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast(window->GetWindowSize().first), static_cast(window->GetWindowSize().second), 0.0f, 1.0f)); // Get render graph from default viewport world renderer - sceneRenderGraph = resourceManager.Create(); + worldRenderGraph = resourceManager.Create(); std::vector> renderContextCmdPools{ swapchain->GetNumImages() }; for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i) @@ -143,35 +142,36 @@ namespace SHADE } // Initialize world render graph - sceneRenderGraph->Init(device, swapchain); - sceneRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); - sceneRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT }, windowDims.first, windowDims.second); - sceneRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); - sceneRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); + worldRenderGraph->Init(device, swapchain); + //worldRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); + worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT }, windowDims.first, windowDims.second); + worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); + worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); - auto node = sceneRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene" }, {}); // no predecessors + auto node = worldRenderGraph->AddNode("G-Buffer", { /*"Present", */"Entity ID", "Depth Buffer", "Scene"}, {}); // no predecessors //First subpass to write to G-Buffer auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write"); gBufferWriteSubpass->AddColorOutput("Scene"); gBufferWriteSubpass->AddColorOutput("Entity ID"); + //gBufferWriteSubpass->AddColorOutput("Present"); gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); // We do this to just transition our scene layout to shader read auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition"); sceneLayoutTransitionSubpass->AddInput("Scene"); -#ifdef SHEDITOR - auto imguiNode = sceneRenderGraph->AddNode("ImGui Node", { "Present" }, { "G-Buffer" }); - auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw"); - imguiSubpass->AddColorOutput("Present"); -#endif +//#ifdef SHEDITOR +// auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, { "G-Buffer" }); +// auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw"); +// imguiSubpass->AddColorOutput("Present"); +//#endif // Generate world render graph - sceneRenderGraph->Generate(); + worldRenderGraph->Generate(); // Add world renderer to default viewport - worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], sceneRenderGraph); + worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); worldRenderer->SetCamera(worldCamera); @@ -192,8 +192,14 @@ namespace SHADE void SHGraphicsSystem::InitMiddleEnd(void) noexcept { + SHGraphicsGlobalData::Init(device); + InitSceneRenderGraph(); +#ifdef SHEDITOR + InitEditorRenderGraph(); +#endif + // Create Semaphore for (auto& semaHandle : graphSemaphores) { @@ -211,13 +217,45 @@ namespace SHADE for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i) cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]); - mousePickSystem->Init(device, cmdPools, sceneRenderGraph->GetRenderGraphResource("Entity ID")); + mousePickSystem->Init(device, cmdPools, worldRenderGraph->GetRenderGraphResource("Entity ID")); // Register the post offscreen render to the system postOffscreenRender = resourceManager.Create(); - postOffscreenRender->Init(device, sceneRenderGraph->GetRenderGraphResource("Scene"), descPool); + postOffscreenRender->Init(device, worldRenderGraph->GetRenderGraphResource("Scene"), descPool); } +#ifdef SHEDITOR + void SHGraphicsSystem::InitEditorRenderGraph(void) noexcept + { + auto windowDims = window->GetWindowSize(); + + // Create Default Viewport + editorViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 1.0f)); + + // Get render graph from viewport editor renderer + editorRenderGraph = resourceManager.Create(); + + std::vector> renderContextCmdPools{ swapchain->GetNumImages() }; + for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i) + renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0]; + + editorRenderGraph->Init(device, swapchain); + editorRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); + + + auto imguiNode = editorRenderGraph->AddNode("ImGui Node", { "Present"}, {}); + auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw"); + imguiSubpass->AddColorOutput("Present"); + + // Generate world render graph + editorRenderGraph->Generate(); + + // Add world renderer to default viewport + editorRenderer = editorViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], editorRenderGraph); + editorRenderer->SetCamera(worldCamera); + } +#endif + /*---------------------------------------------------------------------------------*/ /* Constructor/Destructors */ /*---------------------------------------------------------------------------------*/ @@ -664,7 +702,8 @@ namespace SHADE renderContext.HandleResize(); - sceneRenderGraph->HandleResize(resizeWidth, resizeHeight); + worldRenderGraph->HandleResize(resizeWidth, resizeHeight); + editorRenderGraph->HandleResize(windowDims.first, windowDims.second); mousePickSystem->HandleResize(); postOffscreenRender->HandleResize(); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index e6739715..0e1e2f78 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -68,10 +68,14 @@ namespace SHADE class SH_API SHGraphicsSystem : public SHSystem { private: - void InitBoilerplate (void) noexcept; - void InitSceneRenderGraph(void) noexcept; - void InitMiddleEnd (void) noexcept; - void InitSubsystems (void) noexcept; + void InitBoilerplate (void) noexcept; + void InitSceneRenderGraph (void) noexcept; + void InitMiddleEnd (void) noexcept; + void InitSubsystems (void) noexcept; + +#ifdef SHEDITOR + void InitEditorRenderGraph (void) noexcept; +#endif public: class SH_API BeginRoutine final : public SHSystemRoutine @@ -277,6 +281,9 @@ namespace SHADE Handle GetQueue() const { return graphicsQueue; } Handle GetDescriptorPool() const { return descPool; } Handle GetDefaultViewport() const {return defaultViewport;} +#ifdef SHEDITOR + Handle GetEditorViewport () const {return editorViewport;}; +#endif Handle GetMousePickSystem(void) const noexcept {return mousePickSystem;}; Handle GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;}; //SHRenderGraph const& GetRenderGraph(void) const noexcept; @@ -306,7 +313,7 @@ namespace SHADE SHWindow* window = nullptr; // Middle End Resources - ResourceManager resourceManager; + ResourceManager resourceManager; SHMeshLibrary meshLibrary; SHTextureLibrary texLibrary; SHSamplerCache samplerCache; @@ -339,7 +346,7 @@ namespace SHADE // Temp Materials Handle defaultMaterial; - Handle sceneRenderGraph; + Handle worldRenderGraph; // Sub systems Handle mousePickSystem; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp index e4ac92e5..1dd8212d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp @@ -62,7 +62,10 @@ namespace SHADE void SHMousePickSystem::HandleResize(void) noexcept { if (afterCopyFence) + { + afterCopyFence->Reset(); afterCopyFence.Free(); + } if (imageDataDstBuffer) imageDataDstBuffer.Free(); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index 14af56ee..425e9c81 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -75,12 +75,15 @@ namespace SHADE void SHRenderer::UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex) noexcept { - cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix(); - cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex); + if (camera) + { + cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix(); + cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex); - std::array dynamicOffsets{ frameIndex * cameraDataAlignedSize }; + std::array dynamicOffsets{ frameIndex * cameraDataAlignedSize }; - cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 }); + cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 }); + } } void SHRenderer::UpdateCameraDataToBuffer(void) noexcept diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 51584300..98cb6709 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -57,7 +57,7 @@ namespace SHADE format = swapchainHdl->GetSurfaceFormatKHR().format; } - graphResources.try_emplace(resourceName, resourceManager.Create(logicalDeviceHdl, swapchainHdl, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); + graphResources.try_emplace(resourceName, resourceManager->Create(logicalDeviceHdl, swapchainHdl, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); } /***************************************************************************/ @@ -102,11 +102,11 @@ namespace SHADE resourceAttLayouts[input.attachment] = input.layout; } - for (uint32_t i = 0; i < node->attachmentDescriptions.size(); ++i) + for (uint32_t j = 0; j < node->attachmentDescriptions.size(); ++j) { - auto& att = node->attachmentDescriptions[i]; + auto& att = node->attachmentDescriptions[j]; att.initialLayout = vk::ImageLayout::eUndefined; - att.finalLayout = resourceAttLayouts[i]; + att.finalLayout = resourceAttLayouts[j]; } ++i; } @@ -365,10 +365,9 @@ namespace SHADE , swapchainHdl{ } , nodes{} , graphResources{} - , resourceManager{} - + , resourceManager{nullptr} { - + resourceManager = std::make_shared(); } SHRenderGraph::SHRenderGraph(SHRenderGraph&& rhs) noexcept @@ -457,7 +456,7 @@ namespace SHADE } } - nodes.emplace_back(resourceManager.Create(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(descInitParams), std::move(predecessors), &graphResources)); + nodes.emplace_back(resourceManager->Create(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(descInitParams), std::move(predecessors), &graphResources)); nodeIndexing.emplace(nodeName, static_cast(nodes.size()) - 1u); return nodes.at(nodeIndexing[nodeName]); } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 8eb458aa..952c6d8f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -16,6 +16,7 @@ #include #include +#include namespace SHADE { @@ -70,7 +71,7 @@ namespace SHADE std::unordered_map> graphResources; //! Resource library for graph handles - ResourceManager resourceManager; + std::shared_ptr resourceManager; public: /*-----------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 0ff8fe96..ec184386 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -104,7 +104,7 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphNode::SHRenderGraphNode(ResourceManager& rm, Handle const& logicalDevice, Handle const& swapchain, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept + SHRenderGraphNode::SHRenderGraphNode(std::shared_ptr rm, Handle const& logicalDevice, Handle const& swapchain, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept : logicalDeviceHdl{ logicalDevice } , renderpass{} , framebuffers{} @@ -162,7 +162,7 @@ namespace SHADE } SHRenderGraphNode::SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept - : resourceManager{ rhs.resourceManager } + : resourceManager{ std::move (rhs.resourceManager) } , logicalDeviceHdl{ rhs.logicalDeviceHdl } , renderpass{ rhs.renderpass } , framebuffers{ std::move(rhs.framebuffers) } @@ -177,6 +177,8 @@ namespace SHADE , ptrToResources{ rhs.ptrToResources } , pipelineLibrary{ std::move(rhs.pipelineLibrary) } , batcher{ std::move(rhs.batcher) } + , spDescs{ std::move(rhs.spDescs) } + , spDeps{ std::move(rhs.spDeps) } { rhs.renderpass = {}; @@ -187,7 +189,7 @@ namespace SHADE if (&rhs == this) return *this; - resourceManager = rhs.resourceManager; + resourceManager = std::move(rhs.resourceManager); logicalDeviceHdl = rhs.logicalDeviceHdl; renderpass = rhs.renderpass; framebuffers = std::move(rhs.framebuffers); @@ -200,6 +202,9 @@ namespace SHADE ptrToResources = std::move(rhs.ptrToResources); pipelineLibrary = std::move(rhs.pipelineLibrary); batcher = std::move(rhs.batcher); + spDescs = std::move(rhs.spDescs); + spDeps = std::move(rhs.spDeps); + rhs.renderpass = {}; @@ -230,10 +235,10 @@ namespace SHADE } // Add subpass to container and create mapping for it - subpasses.emplace_back(resourceManager.Create(resourceManager, GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); + subpasses.emplace_back(resourceManager->Create(GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); subpassIndexing.try_emplace(subpassName, static_cast(subpasses.size()) - 1u); Handle subpass = subpasses.back(); - subpass->Init(resourceManager); + subpass->Init(*resourceManager); // Register the SuperBatch batcher.RegisterSuperBatch(subpass->GetSuperBatch()); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index f36e7622..77861108 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -26,7 +26,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ - ResourceManager& resourceManager; + std::shared_ptr resourceManager; //! For Vulkan object creation Handle logicalDeviceHdl; @@ -88,7 +88,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphNode(ResourceManager& rm, Handle const& logicalDevice, Handle const& swapchain, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept; + SHRenderGraphNode(std::shared_ptr rm, Handle const& logicalDevice, Handle const& swapchain, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept; SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index 6afbfb09..ffbe4ff0 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -23,7 +23,7 @@ namespace SHADE */ /***************************************************************************/ - SHSubpass::SHSubpass(ResourceManager& rm, Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* resources) noexcept + SHSubpass::SHSubpass(Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* resources) noexcept : resourceAttachmentMapping{ mapping } , ptrToResources{ resources } , parentNode{ parent } @@ -55,6 +55,8 @@ namespace SHADE , inputReferences{ std::move(rhs.inputReferences) } , resourceAttachmentMapping{ rhs.resourceAttachmentMapping } , ptrToResources{ rhs.ptrToResources } + , descriptorSetLayout{ rhs.descriptorSetLayout } + , exteriorDrawCalls{ std::move (rhs.exteriorDrawCalls) } { } @@ -83,6 +85,8 @@ namespace SHADE inputReferences = std::move(rhs.inputReferences); resourceAttachmentMapping = rhs.resourceAttachmentMapping; ptrToResources = rhs.ptrToResources; + descriptorSetLayout = rhs.descriptorSetLayout; + exteriorDrawCalls = std::move(rhs.exteriorDrawCalls); return *this; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h index 2e883ebc..c567a897 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h @@ -62,7 +62,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHSubpass(ResourceManager& rm, Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* ptrToResources) noexcept; + SHSubpass(Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* ptrToResources) noexcept; SHSubpass(SHSubpass&& rhs) noexcept; SHSubpass& operator=(SHSubpass&& rhs) noexcept; diff --git a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp index fee23f13..74128ec8 100644 --- a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp +++ b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp @@ -253,7 +253,8 @@ namespace SHADE SHVkRenderpass::~SHVkRenderpass(void) noexcept { - logicalDeviceHdl->GetVkLogicalDevice().destroyRenderPass(vkRenderpass, nullptr); + if (vkRenderpass) + logicalDeviceHdl->GetVkLogicalDevice().destroyRenderPass(vkRenderpass, nullptr); } diff --git a/SHADE_Engine/src/Resource/SparseSet.h b/SHADE_Engine/src/Resource/SparseSet.h index 8a3f9c6e..fb4a8311 100644 --- a/SHADE_Engine/src/Resource/SparseSet.h +++ b/SHADE_Engine/src/Resource/SparseSet.h @@ -59,9 +59,9 @@ namespace SHADE SparseSet(); ~SparseSet() = default; - // Disallow moving or copying - SparseSet(const SparseSet&) = delete; - SparseSet(SparseSet&&) = delete; + //// Disallow moving or copying + //SparseSet(const SparseSet&) = delete; + //SparseSet(SparseSet&&) = delete; /*-----------------------------------------------------------------------------*/ /* Usage Functions */ From e76bc6ef58985f524c65cede1f1e8f82923a8b70 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Tue, 18 Oct 2022 02:41:27 +0800 Subject: [PATCH 57/61] World render graph now doesn't render to swapchain image. world render graph now only renders to "Scene" resource. Editor render graph renders to "Present" swapchain image. Removed some unnecessary if statements slowing down the resizing Printing for success also disabled for now --- .../Graphics/Debugging/SHVulkanDebugUtil.cpp | 2 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 34 ++++++------------- .../MiddleEnd/PerFrame/SHRenderContext.cpp | 1 - 3 files changed, 12 insertions(+), 25 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.cpp b/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.cpp index c8a1fe1a..fd39da24 100644 --- a/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.cpp +++ b/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.cpp @@ -99,7 +99,7 @@ namespace SHADE void SHVulkanDebugUtil::ReportVkSuccess(std::string_view message) noexcept { - SHLOGV_INFO(message); + //SHLOGV_INFO(message); } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 929e5d54..c78cc58f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -143,30 +143,22 @@ namespace SHADE // Initialize world render graph worldRenderGraph->Init(device, swapchain); - //worldRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT }, windowDims.first, windowDims.second); worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); - auto node = worldRenderGraph->AddNode("G-Buffer", { /*"Present", */"Entity ID", "Depth Buffer", "Scene"}, {}); // no predecessors + auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene"}, {}); // no predecessors //First subpass to write to G-Buffer auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write"); gBufferWriteSubpass->AddColorOutput("Scene"); gBufferWriteSubpass->AddColorOutput("Entity ID"); - //gBufferWriteSubpass->AddColorOutput("Present"); gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); // We do this to just transition our scene layout to shader read auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition"); sceneLayoutTransitionSubpass->AddInput("Scene"); -//#ifdef SHEDITOR -// auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, { "G-Buffer" }); -// auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw"); -// imguiSubpass->AddColorOutput("Present"); -//#endif - // Generate world render graph worldRenderGraph->Generate(); @@ -297,12 +289,6 @@ namespace SHADE if (window->IsMinimized() || renderContext.GetWindowIsDead()) return; - if (renderContext.GetResized()) - { - return; - } - - // Frame data for the current frame auto const& frameData = renderContext.GetCurrentFrameData(); uint32_t frameIndex = renderContext.GetCurrentFrame(); @@ -463,12 +449,6 @@ namespace SHADE if (window->IsMinimized() || renderContext.GetWindowIsDead()) return; - if (renderContext.GetResized()) - { - return; - } - - const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame(); auto& currFrameData = renderContext.GetCurrentFrameData(); @@ -480,9 +460,7 @@ namespace SHADE // If swapchain is incompatible/outdated if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR) { - HandleResize(); - } } @@ -692,9 +670,14 @@ namespace SHADE void SHGraphicsSystem::HandleResize(void) noexcept { + device->WaitIdle(); + if (window->IsMinimized() || renderContext.GetWindowIsDead()) return; + graphSemaphores[0].Free(); + graphSemaphores[1].Free(); + auto windowDims = window->GetWindowSize(); // Resize the swapchain @@ -712,6 +695,11 @@ namespace SHADE defaultViewport->SetHeight(static_cast(resizeHeight)); worldCamera->SetPerspective(90.0f, static_cast(resizeWidth), static_cast(resizeHeight), 0.0f, 100.0f); + + for (auto& semaHandle : graphSemaphores) + semaHandle = device->CreateSemaphore(); + + } void SHGraphicsSystem::AwaitGraphicsExecution() diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp index 0ac7013a..8041adfd 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp @@ -52,7 +52,6 @@ namespace SHADE { frameData[i].cmdPoolHdls.push_back(logicalDeviceHdl->CreateCommandPool(params.cmdPoolQueueFamilyType, params.cmdPoolResetMode, params.cmdBufferTransient)); } - } // Initialize all the info. From 033ba48304bd51152fcb1e32312796b354808f3c Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Tue, 18 Oct 2022 15:04:25 +0800 Subject: [PATCH 58/61] Editor changes to support viewport integration --- Assets/Editor/Layouts/Default.ini | 48 ++++ Assets/Editor/Layouts/UserLayout.ini | 48 ++++ .../HierarchyPanel/SHHierarchyPanel.cpp | 31 ++- .../HierarchyPanel/SHHierarchyPanel.h | 2 + .../Inspector/SHEditorComponentView.hpp | 9 +- .../Inspector/SHEditorInspector.cpp | 2 +- .../EditorWindow/MenuBar/SHEditorMenuBar.cpp | 88 +++++-- .../EditorWindow/MenuBar/SHEditorMenuBar.h | 1 + .../Profiling/SHEditorProfiler.cpp | 2 +- .../Editor/EditorWindow/SHEditorWindow.cpp | 26 +- .../src/Editor/EditorWindow/SHEditorWindow.h | 9 +- .../EditorWindow/SHEditorWindowIncludes.h | 3 +- .../ViewportWindow/SHEditorViewport.cpp | 60 +++++ .../ViewportWindow/SHEditorViewport.h | 29 +++ SHADE_Engine/src/Editor/SHEditor.cpp | 244 +++++++++++------- SHADE_Engine/src/Editor/SHEditor.hpp | 21 +- 16 files changed, 492 insertions(+), 131 deletions(-) create mode 100644 Assets/Editor/Layouts/Default.ini create mode 100644 Assets/Editor/Layouts/UserLayout.ini create mode 100644 SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp create mode 100644 SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.h diff --git a/Assets/Editor/Layouts/Default.ini b/Assets/Editor/Layouts/Default.ini new file mode 100644 index 00000000..4ddc46c2 --- /dev/null +++ b/Assets/Editor/Layouts/Default.ini @@ -0,0 +1,48 @@ +[Window][MainStatusBar] +Pos=0,1060 +Size=1920,20 +Collapsed=0 + +[Window][SHEditorMenuBar] +Pos=0,24 +Size=1920,1036 +Collapsed=0 + +[Window][Hierarchy Panel] +Pos=0,120 +Size=225,940 +Collapsed=0 +DockId=0x00000004,0 + +[Window][Debug##Default] +Pos=60,60 +Size=400,400 +Collapsed=0 + +[Window][Inspector] +Pos=1686,24 +Size=234,1036 +Collapsed=0 +DockId=0x00000006,0 + +[Window][Profiler] +Pos=0,24 +Size=225,94 +Collapsed=0 +DockId=0x00000003,0 + +[Window][Viewport] +Pos=227,24 +Size=1457,1036 +Collapsed=0 +DockId=0x00000002,0 + +[Docking][Data] +DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,55 Size=1920,1036 Split=X + DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1684,1036 Split=X + DockNode ID=0x00000001 Parent=0x00000005 SizeRef=225,1036 Split=Y Selected=0x1E6EB881 + DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 + DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE + DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1293,1036 CentralNode=1 Selected=0x13926F0B + DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=234,1036 Selected=0xE7039252 + diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini new file mode 100644 index 00000000..869da91a --- /dev/null +++ b/Assets/Editor/Layouts/UserLayout.ini @@ -0,0 +1,48 @@ +[Window][MainStatusBar] +Pos=0,1167 +Size=2314,20 +Collapsed=0 + +[Window][SHEditorMenuBar] +Pos=0,48 +Size=2314,1119 +Collapsed=0 + +[Window][Hierarchy Panel] +Pos=0,152 +Size=208,1015 +Collapsed=0 +DockId=0x00000004,0 + +[Window][Debug##Default] +Pos=60,60 +Size=400,400 +Collapsed=0 + +[Window][Inspector] +Pos=2044,48 +Size=270,1119 +Collapsed=0 +DockId=0x00000006,0 + +[Window][Profiler] +Pos=0,48 +Size=208,102 +Collapsed=0 +DockId=0x00000003,0 + +[Window][Viewport] +Pos=210,48 +Size=1832,1119 +Collapsed=0 +DockId=0x00000002,0 + +[Docking][Data] +DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=-7,358 Size=2314,1119 Split=X + DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=2042,1036 Split=X + DockNode ID=0x00000001 Parent=0x00000005 SizeRef=208,1036 Split=Y Selected=0x1E6EB881 + DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 + DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE + DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1832,1036 CentralNode=1 Selected=0x13926F0B + DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=270,1036 Selected=0xE7039252 + diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp index 0f25175f..42c9da66 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp @@ -66,8 +66,8 @@ namespace SHADE editor->selectedEntities.clear(); } ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal); - ImGui::End(); } + ImGui::End(); } void SHHierarchyPanel::Exit() @@ -75,6 +75,11 @@ namespace SHADE SHEditorWindow::Exit(); } + void SHHierarchyPanel::SetScrollTo(EntityID eid) + { + scrollTo = eid; + } + //#==============================================================# //|| Private Member Functions || //#==============================================================# @@ -82,7 +87,20 @@ namespace SHADE { if (ImGui::BeginMenuBar()) { - if (ImGui::SmallButton(ICON_MD_ADD)) + + ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x - 35.0f); + if(ImGui::SmallButton(ICON_MD_DESELECT)) + { + auto editor = SHSystemManager::GetSystem(); + editor->selectedEntities.clear(); + } + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text("Clear Selections"); + ImGui::EndTooltip(); + } + if (ImGui::SmallButton(ICON_MD_ADD_CIRCLE)) { SHEntityManager::CreateEntity(); } @@ -103,6 +121,13 @@ namespace SHADE //Get node data (Children, eid, selected) auto& children = currentNode->GetChildren(); EntityID eid = currentNode->GetEntityID(); + + if(scrollTo != MAX_EID && eid == scrollTo) + { + ImGui::SetScrollHereY(); + scrollTo = MAX_EID; + } + auto editor = SHSystemManager::GetSystem(); const bool isSelected = (std::ranges::find(editor->selectedEntities, eid) != editor->selectedEntities.end()); @@ -157,7 +182,7 @@ namespace SHADE } ImGui::EndPopup(); } - + //Handle node selection if (ImGui::IsItemHovered()) { diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h index 78e445fd..88983ca9 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h @@ -23,11 +23,13 @@ namespace SHADE void Init() override; void Update() override; void Exit() override; + void SetScrollTo(EntityID eid); private: void DrawMenuBar() const noexcept; ImRect RecursivelyDrawEntityNode(SHSceneNode*); void CreateChildEntity(EntityID parentEID) const noexcept; std::string filter; bool isAnyNodeSelected = false; + EntityID scrollTo = MAX_EID; };//class SHHierarchyPanel }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 93f6984e..47fec730 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -207,8 +207,10 @@ namespace SHADE auto& colliders = component->GetColliders(); int const size = static_cast(colliders.size()); ImGui::BeginChild("Colliders", {0.0f, colliders.empty() ? 1.0f : 250.0f}, true); + std::optional colliderToDelete{std::nullopt}; for (int i{}; i < size; ++i) { + ImGui::PushID(i); SHCollider& collider = component->GetCollider(i); auto cursorPos = ImGui::GetCursorPos(); @@ -235,9 +237,14 @@ namespace SHADE } if(ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data())) { - component->RemoveCollider(i); + colliderToDelete = i; } SHEditorWidgets::EndPanel(); + ImGui::PopID(); + } + if(colliderToDelete.has_value()) + { + component->RemoveCollider(colliderToDelete.value()); } ImGui::EndChild(); diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index a9b1c724..da09f345 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -99,8 +99,8 @@ namespace SHADE } } - ImGui::End(); } + ImGui::End(); } void SHEditorInspector::Exit() diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp index a49af994..3cb6561d 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp @@ -36,6 +36,11 @@ namespace SHADE void SHEditorMenuBar::Init() { SHEditorWindow::Init(); + constexpr std::string_view path = "../../Assets/Editor/Layouts"; + for(auto const& entry : std::filesystem::directory_iterator(path)) + { + layoutPaths.push_back(entry.path()); + } } void SHEditorMenuBar::Update() @@ -87,20 +92,6 @@ namespace SHADE ImGui::EndDisabled(); ImGui::EndMenu(); } - if(ImGui::BeginMenu("Theme")) - { - auto styles = rttr::type::get().get_enumeration(); - auto values = styles.get_values(); - for (auto style : values) - { - if(ImGui::Selectable(style.to_string().c_str())) - { - if(auto editor = SHSystemManager::GetSystem()) - editor->SetStyle(style.convert()); - } - } - ImGui::EndMenu(); - } if (ImGui::BeginMenu("Scripts")) { if (ImGui::Selectable("Generate Visual Studio Project")) @@ -120,18 +111,79 @@ namespace SHADE } ImGui::EndMenu(); } + + if (ImGui::BeginMenu("Window")) + { + for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values) + { + if (window.get() != this) + ImGui::Checkbox(window->windowName.data(), &window->isOpen); + } + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Theme")) + { + const auto styles = rttr::type::get().get_enumeration(); + auto values = styles.get_values(); + for (auto style : values) + { + if (ImGui::Selectable(style.to_string().c_str())) + { + if (auto editor = SHSystemManager::GetSystem()) + editor->SetStyle(style.convert()); + } + } + ImGui::EndMenu(); + } + if(ImGui::BeginMenu("Layout")) + { + for(auto const& entry : layoutPaths) + { + if(ImGui::Selectable(entry.stem().string().c_str())) + { + ImGui::LoadIniSettingsFromDisk(entry.string().c_str()); + } + } + ImGui::EndMenu(); + } ImGui::EndMainMenuBar(); } - const ImGuiID dockspace_id = ImGui::GetID("DockSpace"); - ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspaceFlags); + const ImGuiID dockspaceId = ImGui::GetID("DockSpace"); + ImGui::DockSpace(dockspaceId, ImVec2(0.0f, 0.0f), dockspaceFlags); ImGui::End(); } } void SHEditorMenuBar::DrawSecondaryBar() const noexcept { - + ImGuiViewport* viewport = ImGui::GetMainViewport(); + if(ImGui::BeginViewportSideBar("##SecondaryMenuBar", viewport, ImGuiDir_Up, ImGui::GetFrameHeight(), ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_MenuBar)) + { + ImGui::BeginMenuBar(); + ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x * 0.5f - 80.f); + const auto editor = SHSystemManager::GetSystem(); + ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY); + if(ImGui::SmallButton(ICON_MD_PLAY_ARROW)) + { + editor->editorState = SHEditor::State::PLAY; + } + ImGui::EndDisabled(); + ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE); + if(ImGui::SmallButton(ICON_MD_PAUSE)) + { + editor->editorState = SHEditor::State::PAUSE; + } + ImGui::EndDisabled(); + ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP); + if(ImGui::SmallButton(ICON_MD_STOP)) + { + editor->editorState = SHEditor::State::STOP; + } + ImGui::EndDisabled(); + ImGui::EndMenuBar(); + } + ImGui::End(); } void SHEditorMenuBar::DrawStatusBar() const noexcept @@ -142,8 +194,8 @@ namespace SHADE if (ImGui::BeginViewportSideBar("MainStatusBar", ImGui::GetMainViewport(), ImGuiDir_Down, menuBarHeight, editorMenuBarFlags)) { ImGui::Text("Entity count: "); - ImGui::End(); } + ImGui::End(); ImGui::PopStyleVar(3); } diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h index 616ba43e..7cbcd696 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h @@ -18,5 +18,6 @@ namespace SHADE void DrawSecondaryBar() const noexcept; void DrawStatusBar() const noexcept; float menuBarHeight = 20.0f; + std::vector layoutPaths; };//class SHEditorMenuBar }//namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp b/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp index 4b36fe5d..ef2ff8c0 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp @@ -37,8 +37,8 @@ namespace SHADE if(Begin()) { ImGui::PlotLines("DT", frames.data(), static_cast(frames.size()), 0, nullptr, 0.0f, 16.0f); - ImGui::End(); } + ImGui::End(); } void SHEditorProfiler::Exit() diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp index 2e2c820c..491c1bc2 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp @@ -19,7 +19,7 @@ namespace SHADE //|| Public Member Functions || //#==============================================================# SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags) - : isOpen(true), windowName(name), windowFlags(inFlags), io(ImGui::GetIO()) + : windowName(name), windowFlags(inFlags), io(ImGui::GetIO()) { } @@ -40,7 +40,29 @@ namespace SHADE //#==============================================================# bool SHEditorWindow::Begin() { - return ImGui::Begin(windowName.data(), &isOpen, windowFlags); + bool result = ImGui::Begin(windowName.data(), &isOpen, windowFlags); + + auto wndSize = ImGui::GetWindowSize(); + if(windowSize.x != wndSize.x || windowSize.y != wndSize.y) + { + windowSize = {wndSize.x, wndSize.y}; + OnResize(); + } + auto wndPos = ImGui::GetWindowPos(); + if(windowPos.x != wndPos.x || windowPos.y != wndPos.y) + { + windowPos = {wndPos.x, wndPos.y}; + OnPosChange(); + } + return result; + } + + void SHEditorWindow::OnResize() + { + } + + void SHEditorWindow::OnPosChange() + { } }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h index 244ef677..3e7a2a5c 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h @@ -5,6 +5,8 @@ //#==============================================================# #include +#include "Math/Vector/SHVec2.h" + //#==============================================================# //|| Forward Declarations || //#==============================================================# @@ -21,11 +23,16 @@ namespace SHADE virtual void Init(); virtual void Update(); virtual void Exit(); - bool isOpen = false; + bool isOpen; std::string_view windowName; protected: virtual bool Begin(); + virtual void OnResize(); + virtual void OnPosChange(); + ImGuiWindowFlags windowFlags = 0; ImGuiIO& io; + SHVec2 windowSize; + SHVec2 windowPos; };//class SHEditorWindow }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h index d1ebfbf4..f0267b06 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h @@ -2,4 +2,5 @@ #include "MenuBar/SHEditorMenuBar.h" //Menu Bar #include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel #include "Inspector/SHEditorInspector.h" //Inspector -#include "Profiling/SHEditorProfiler.h" //Profiler \ No newline at end of file +#include "Profiling/SHEditorProfiler.h" //Profiler +#include "ViewportWindow/SHEditorViewport.h" //Editor Viewport \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp new file mode 100644 index 00000000..c903a80f --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp @@ -0,0 +1,60 @@ +#include "SHpch.h" +#include "SHEditorViewport.h" + +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" +#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" + +namespace SHADE +{ + SHEditorViewport::SHEditorViewport() + :SHEditorWindow("Viewport", ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoScrollbar) + { + } + + void SHEditorViewport::Init() + { + SHEditorWindow::Init(); + + } + + void SHEditorViewport::Update() + { + SHEditorWindow::Update(); + if(Begin()) + { + DrawMenuBar(); + auto gfxSystem = SHSystemManager::GetSystem(); + auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0]; + ImGui::Image((ImTextureID)descriptorSet, ImGui::GetWindowSize()); + } + ImGui::End(); + } + + void SHEditorViewport::Exit() + { + SHEditorWindow::Exit(); + } + + void SHEditorViewport::OnResize() + { + SHEditorWindow::OnResize(); + //Get graphics system to resize swapchain image + auto gfxSystem = SHSystemManager::GetSystem(); + + gfxSystem->PrepareResize(static_cast(windowSize.x), static_cast(windowSize.y)); + } + + void SHEditorViewport::OnPosChange() + { + SHEditorWindow::OnPosChange(); + } + + void SHEditorViewport::DrawMenuBar() const noexcept + { + if(ImGui::BeginMenuBar()) + { + ImGui::EndMenuBar(); + } + } +}//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.h b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.h new file mode 100644 index 00000000..5f4a5919 --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.h @@ -0,0 +1,29 @@ +#pragma once +//#==============================================================# +//|| Library Includes || +//#==============================================================# +#include + +//#==============================================================# +//|| SHADE Includes || +//#==============================================================# +#include "imgui_internal.h" +#include "ECS_Base/SHECSMacros.h" +#include "Editor/EditorWindow/SHEditorWindow.h" + +namespace SHADE +{ + class SHEditorViewport final : public SHEditorWindow + { + public: + SHEditorViewport(); + void Init() override; + void Update() override; + void Exit() override; + protected: + void OnResize() override; + void OnPosChange() override; + private: + void DrawMenuBar() const noexcept; + };//class SHEditorViewport +}//namespace SHADE diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index d9fc8373..4c6caff0 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -43,6 +43,8 @@ #include #include +#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h" + RTTR_REGISTRATION { using namespace SHADE; @@ -73,6 +75,7 @@ namespace SHADE //#==============================================================# void SHEditor::Init() { + IMGUI_CHECKVERSION(); if(auto context = ImGui::CreateContext()) { @@ -82,11 +85,21 @@ namespace SHADE } } - ImGuiIO& io = ImGui::GetIO(); (void)io; + //Add editor windows + SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); - io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls - io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports - io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking + io = &ImGui::GetIO(); + + io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports + io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking + io->IniFilename = "../../Assets/Editor/Layouts/UserLayout.ini"; + + InitLayout(); InitFonts(); @@ -98,11 +111,11 @@ namespace SHADE SetStyle(Style::SHADE); - //Add editor windows - SHEditorWindowManager::CreateEditorWindow(); - SHEditorWindowManager::CreateEditorWindow(); - SHEditorWindowManager::CreateEditorWindow(); - SHEditorWindowManager::CreateEditorWindow(); + + for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values) + { + window->Init(); + } SHLOG_INFO("Successfully initialised SHADE Engine Editor") } @@ -116,7 +129,7 @@ namespace SHADE if(window->isOpen) window->Update(); } - + if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z)) { SHCommandManager::RedoCommand(); @@ -125,36 +138,46 @@ namespace SHADE { SHCommandManager::UndoCommand(); } - - + Render(); } void SHEditor::Render() { ImGui::Render(); - ImGuiIO& io = ImGui::GetIO(); - if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + if (io->ConfigFlags & ImGuiConfigFlags_ViewportsEnable) { ImGui::UpdatePlatformWindows(); ImGui::RenderPlatformWindowsDefault(); } } + void SHEditor::InitLayout() noexcept + { + if(!std::filesystem::exists(io->IniFilename)) + { + std::filesystem::copy_file("../../Assets/Editor/Layouts/Default.ini", io->IniFilename); + } + //eventually load preferred layout here + } + void SHEditor::InitFonts() noexcept { - ImGuiIO& io = ImGui::GetIO(); - ImFont* mainFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path + ImFont* mainFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path - static const ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 }; + constexpr ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 }; ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f; - ImFont* UIFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges); //TODO: Change to config based assets path + ImFont* UIFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges); //TODO: Change to config based assets path - io.Fonts->Build(); + io->Fonts->Build(); } void SHEditor::Exit() { + for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values) + { + window->Init(); + } ImGui_ImplVulkan_Shutdown(); ImGui_ImplSDL2_Shutdown(); ImGui::DestroyContext(); @@ -167,86 +190,86 @@ namespace SHADE default: case Style::SHADE: { - ImGuiStyle& imStyle = ImGui::GetStyle(); - ImVec4* colors = imStyle.Colors; - colors[ImGuiCol_Text] = ImVec4(0.706f, 0.729f, 0.757f, 1.00f); - colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); - colors[ImGuiCol_WindowBg] = ImVec4(0.172f, 0.184f, 0.203f, 1.f); - colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_PopupBg] = ImVec4(0.19f, 0.19f, 0.19f, 0.92f); - colors[ImGuiCol_Border] = ImVec4(0.19f, 0.19f, 0.19f, 0.29f); - colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.24f); - colors[ImGuiCol_FrameBg] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f); - colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 0.54f); - colors[ImGuiCol_FrameBgActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f); - colors[ImGuiCol_TitleBg] = colors[ImGuiCol_WindowBg]; - colors[ImGuiCol_TitleBgActive] = colors[ImGuiCol_WindowBg]; - colors[ImGuiCol_TitleBgCollapsed] = colors[ImGuiCol_WindowBg]; - colors[ImGuiCol_MenuBarBg] = ImVec4(0.129f, 0.141f, 0.157f, 1.f); - colors[ImGuiCol_ScrollbarBg] = colors[ImGuiCol_WindowBg]; - colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f); - colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.40f, 0.54f); - colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f); - colors[ImGuiCol_CheckMark] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f); - colors[ImGuiCol_SliderGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f); - colors[ImGuiCol_SliderGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f); - colors[ImGuiCol_Button] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f); - colors[ImGuiCol_ButtonHovered] = ImVec4(0.15f, 0.15f, 0.15f, 0.54f); - colors[ImGuiCol_ButtonActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f); - colors[ImGuiCol_Header] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); - colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.00f, 0.00f, 0.36f); - colors[ImGuiCol_HeaderActive] = ImVec4(0.20f, 0.22f, 0.23f, 0.33f); - colors[ImGuiCol_Separator] = colors[ImGuiCol_MenuBarBg]; - colors[ImGuiCol_SeparatorHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f); - colors[ImGuiCol_SeparatorActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f); - colors[ImGuiCol_ResizeGrip] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f); - colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f); - colors[ImGuiCol_ResizeGripActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f); - colors[ImGuiCol_Tab] = colors[ImGuiCol_WindowBg]; - colors[ImGuiCol_TabHovered] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); - colors[ImGuiCol_TabActive] = ImVec4(0.14f, 0.14f, 0.14f, 0.8f); - colors[ImGuiCol_TabUnfocused] = colors[ImGuiCol_WindowBg]; - colors[ImGuiCol_TabUnfocusedActive] = colors[ImGuiCol_WindowBg]; - colors[ImGuiCol_DockingPreview] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f); - colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.855f, 0.6f, 0.941f, 1.00f); - colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); - colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); - colors[ImGuiCol_PlotHistogram] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); - colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); - colors[ImGuiCol_TableHeaderBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); - colors[ImGuiCol_TableBorderStrong] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); - colors[ImGuiCol_TableBorderLight] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f); - colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f); - colors[ImGuiCol_TextSelectedBg] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f); - colors[ImGuiCol_DragDropTarget] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f); - colors[ImGuiCol_NavHighlight] = ImVec4(0.73f, 0.73f, 0.73f, 0.7f); + ImGuiStyle& imStyle = ImGui::GetStyle(); + ImVec4* colors = imStyle.Colors; + colors[ImGuiCol_Text] = ImVec4(0.706f, 0.729f, 0.757f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.172f, 0.184f, 0.203f, 1.f); + colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_PopupBg] = ImVec4(0.19f, 0.19f, 0.19f, 0.92f); + colors[ImGuiCol_Border] = ImVec4(0.19f, 0.19f, 0.19f, 0.29f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.24f); + colors[ImGuiCol_FrameBg] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 0.54f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f); + colors[ImGuiCol_TitleBg] = colors[ImGuiCol_WindowBg]; + colors[ImGuiCol_TitleBgActive] = colors[ImGuiCol_WindowBg]; + colors[ImGuiCol_TitleBgCollapsed] = colors[ImGuiCol_WindowBg]; + colors[ImGuiCol_MenuBarBg] = ImVec4(0.129f, 0.141f, 0.157f, 1.f); + colors[ImGuiCol_ScrollbarBg] = colors[ImGuiCol_WindowBg]; + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.40f, 0.54f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f); + colors[ImGuiCol_CheckMark] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f); + colors[ImGuiCol_SliderGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f); + colors[ImGuiCol_Button] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.15f, 0.15f, 0.15f, 0.54f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.00f, 0.00f, 0.36f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.20f, 0.22f, 0.23f, 0.33f); + colors[ImGuiCol_Separator] = colors[ImGuiCol_MenuBarBg]; + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f); + colors[ImGuiCol_Tab] = colors[ImGuiCol_WindowBg]; + colors[ImGuiCol_TabHovered] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); + colors[ImGuiCol_TabActive] = ImVec4(0.14f, 0.14f, 0.14f, 0.8f); + colors[ImGuiCol_TabUnfocused] = colors[ImGuiCol_WindowBg]; + colors[ImGuiCol_TabUnfocusedActive] = colors[ImGuiCol_WindowBg]; + colors[ImGuiCol_DockingPreview] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f); + colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.855f, 0.6f, 0.941f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); + colors[ImGuiCol_TableHeaderBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); + colors[ImGuiCol_TableBorderStrong] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); + colors[ImGuiCol_TableBorderLight] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f); + colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f); + colors[ImGuiCol_DragDropTarget] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f); + colors[ImGuiCol_NavHighlight] = ImVec4(0.73f, 0.73f, 0.73f, 0.7f); colors[ImGuiCol_NavWindowingHighlight] = ImVec4(0.141f, 0.141f, 0.141f, 0.70f); - colors[ImGuiCol_NavWindowingDimBg] = colors[ImGuiCol_NavHighlight]; - colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.2f, 0.2f, 0.2f, 0.65f); + colors[ImGuiCol_NavWindowingDimBg] = colors[ImGuiCol_NavHighlight]; + colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.2f, 0.2f, 0.2f, 0.65f); - imStyle.WindowPadding = ImVec2(8.00f, 8.00f); - imStyle.FramePadding = ImVec2(5.00f, 2.00f); - imStyle.CellPadding = ImVec2(6.00f, 8.00f); - imStyle.ItemSpacing = ImVec2(6.00f, 6.00f); - imStyle.ItemInnerSpacing = ImVec2(6.00f, 6.00f); - imStyle.TouchExtraPadding = ImVec2(0.00f, 0.00f); - imStyle.IndentSpacing = 25; - imStyle.ScrollbarSize = 15; - imStyle.GrabMinSize = 10; - imStyle.WindowBorderSize = 0.6f; - imStyle.ChildBorderSize = 1; - imStyle.PopupBorderSize = 1; - imStyle.FrameBorderSize = 1; - imStyle.TabBorderSize = 1; - imStyle.WindowRounding = 7; - imStyle.ChildRounding = 4; - imStyle.FrameRounding = 3; - imStyle.PopupRounding = 4; - imStyle.ScrollbarRounding = 9; - imStyle.GrabRounding = 3; - imStyle.LogSliderDeadzone = 4; - imStyle.TabRounding = 4; + imStyle.WindowPadding = ImVec2(8.00f, 8.00f); + imStyle.FramePadding = ImVec2(5.00f, 2.00f); + imStyle.CellPadding = ImVec2(6.00f, 8.00f); + imStyle.ItemSpacing = ImVec2(6.00f, 6.00f); + imStyle.ItemInnerSpacing = ImVec2(6.00f, 6.00f); + imStyle.TouchExtraPadding = ImVec2(0.00f, 0.00f); + imStyle.IndentSpacing = 25; + imStyle.ScrollbarSize = 15; + imStyle.GrabMinSize = 10; + imStyle.WindowBorderSize = 0.6f; + imStyle.ChildBorderSize = 1; + imStyle.PopupBorderSize = 1; + imStyle.FrameBorderSize = 1; + imStyle.TabBorderSize = 1; + imStyle.WindowRounding = 7; + imStyle.ChildRounding = 4; + imStyle.FrameRounding = 3; + imStyle.PopupRounding = 4; + imStyle.ScrollbarRounding = 9; + imStyle.GrabRounding = 3; + imStyle.LogSliderDeadzone = 4; + imStyle.TabRounding = 4; imStyle.WindowMenuButtonPosition = ImGuiDir_None; } break; @@ -281,10 +304,11 @@ namespace SHADE imguiCommandPool = gfxSystem->GetDevice()->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true); imguiCommandBuffer = imguiCommandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); - auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers(); + //auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers(); + auto const& renderers = gfxSystem->GetEditorViewport()->GetRenderers(); SHASSERT(!renderers.empty(), "No Renderers available") - auto renderGraph = renderers[0]->GetRenderGraph(); + auto renderGraph = renderers[SHGraphicsConstants::RenderGraphIndices::EDITOR]->GetRenderGraph(); auto renderPass = renderGraph->GetNode("ImGui Node")->GetRenderpass(); if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false) @@ -309,6 +333,28 @@ namespace SHADE }); } + void SHEditor::PollPicking() + { + if (auto gfxSystem = SHSystemManager::GetSystem()) + { + if (!ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + { + EntityID pickedEID = gfxSystem->GetMousePickSystem()->GetPickedEntity(); + if(pickedEID == MAX_EID) + return; + if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) + { + if (const auto hierarchyPanel = SHEditorWindowManager::GetEditorWindow()) + { + hierarchyPanel->SetScrollTo(pickedEID); + } + selectedEntities.clear(); + } + selectedEntities.push_back(pickedEID); + } + } + } + void SHEditor::NewFrame() { SDL_Event event; diff --git a/SHADE_Engine/src/Editor/SHEditor.hpp b/SHADE_Engine/src/Editor/SHEditor.hpp index d579a9b5..baa6324e 100644 --- a/SHADE_Engine/src/Editor/SHEditor.hpp +++ b/SHADE_Engine/src/Editor/SHEditor.hpp @@ -90,11 +90,11 @@ namespace SHADE return reinterpret_cast(editorWindows[GetEditorWindowID()].get()); } + static EditorWindowMap editorWindows; private: // Number of windows; used for Editor Window ID Generation static EditorWindowID windowCount; // Map of Editor Windows - static EditorWindowMap editorWindows; friend class SHEditor; }; @@ -110,10 +110,17 @@ namespace SHADE class SH_API EditorRoutine final : public SHSystemRoutine { public: - EditorRoutine() = default; + EditorRoutine():SHSystemRoutine("Editor routine", true) {}; void Execute(double dt) noexcept override final; }; + enum class State : uint8_t + { + PLAY, + PAUSE, + STOP + }; + /** * @brief Style options * @@ -162,9 +169,13 @@ namespace SHADE void SetSDLWindow(SDL_Window* inSDLWindow){sdlWindow = inSDLWindow;}; + void PollPicking(); + // List of selected entities std::vector selectedEntities; + State editorState = State::STOP; + private: /** * @brief Start new frame for editor @@ -177,7 +188,7 @@ namespace SHADE */ void Render(); - + void InitLayout() noexcept; void InitFonts() noexcept; @@ -186,6 +197,8 @@ namespace SHADE // Handle to command buffer used for ImGui Vulkan Backend Handle imguiCommandBuffer; - SDL_Window* sdlWindow; + SDL_Window* sdlWindow {nullptr}; + + ImGuiIO* io{nullptr}; };//class SHEditor }//namespace SHADE From 9ce5a4a47bb6031d75db0e7f19241b2797d47ff0 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Tue, 18 Oct 2022 17:41:14 +0800 Subject: [PATCH 59/61] Mouse picking system now uses cursor returned from editor - This new cursor position is relative to where the viewport is rendering - Window resize callback in Graphics system now checks if editor is enabled before signaling for resize. This is because editor will handle the signaling for resizing when its enabled. When its disabled, the graphics system will signal itself to resize when the window resize callback is called. --- Assets/Editor/Layouts/UserLayout.ini | 30 +++++++++---------- .../src/Editor/EditorWindow/SHEditorWindow.h | 1 + .../ViewportWindow/SHEditorViewport.cpp | 11 +++++++ .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 18 +++++++---- .../MiddleEnd/Interface/SHGraphicsSystem.h | 4 +-- .../MiddleEnd/Interface/SHMousePickSystem.cpp | 14 +++++---- .../MiddleEnd/Interface/SHMousePickSystem.h | 7 +++++ .../MiddleEnd/Interface/SHViewport.cpp | 10 +++++++ .../Graphics/MiddleEnd/Interface/SHViewport.h | 2 ++ 9 files changed, 70 insertions(+), 27 deletions(-) diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini index 869da91a..e55aeb81 100644 --- a/Assets/Editor/Layouts/UserLayout.ini +++ b/Assets/Editor/Layouts/UserLayout.ini @@ -1,16 +1,16 @@ [Window][MainStatusBar] -Pos=0,1167 -Size=2314,20 +Pos=0,1060 +Size=1920,20 Collapsed=0 [Window][SHEditorMenuBar] Pos=0,48 -Size=2314,1119 +Size=1920,1012 Collapsed=0 [Window][Hierarchy Panel] -Pos=0,152 -Size=208,1015 +Pos=0,142 +Size=321,918 Collapsed=0 DockId=0x00000004,0 @@ -20,29 +20,29 @@ Size=400,400 Collapsed=0 [Window][Inspector] -Pos=2044,48 -Size=270,1119 +Pos=1649,48 +Size=271,1012 Collapsed=0 DockId=0x00000006,0 [Window][Profiler] Pos=0,48 -Size=208,102 +Size=321,92 Collapsed=0 DockId=0x00000003,0 [Window][Viewport] -Pos=210,48 -Size=1832,1119 +Pos=323,48 +Size=1324,1012 Collapsed=0 DockId=0x00000002,0 [Docking][Data] -DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=-7,358 Size=2314,1119 Split=X - DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=2042,1036 Split=X - DockNode ID=0x00000001 Parent=0x00000005 SizeRef=208,1036 Split=Y Selected=0x1E6EB881 +DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=617,298 Size=1920,1012 Split=X + DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X + DockNode ID=0x00000001 Parent=0x00000005 SizeRef=321,1036 Split=Y Selected=0x1E6EB881 DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE - DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1832,1036 CentralNode=1 Selected=0x13926F0B - DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=270,1036 Selected=0xE7039252 + DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1324,1036 CentralNode=1 Selected=0x13926F0B + DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=271,1036 Selected=0xE7039252 diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h index 3e7a2a5c..dca02399 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h @@ -34,5 +34,6 @@ namespace SHADE ImGuiIO& io; SHVec2 windowSize; SHVec2 windowPos; + SHVec2 viewportMousePos; };//class SHEditorWindow }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp index c903a80f..f6e6dcff 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp @@ -4,6 +4,7 @@ #include "ECS_Base/Managers/SHSystemManager.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" +#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h" namespace SHADE { @@ -26,6 +27,14 @@ namespace SHADE DrawMenuBar(); auto gfxSystem = SHSystemManager::GetSystem(); auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0]; + + if (ImGui::IsWindowHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + { + auto mousePos = ImGui::GetMousePos(); + auto cursorPos = ImGui::GetCursorScreenPos(); + viewportMousePos = {mousePos.x - cursorPos.x, mousePos.y - cursorPos.y}; + gfxSystem->GetMousePickSystem ()->SetViewportMousePos (viewportMousePos); + } ImGui::Image((ImTextureID)descriptorSet, ImGui::GetWindowSize()); } ImGui::End(); @@ -42,6 +51,8 @@ namespace SHADE //Get graphics system to resize swapchain image auto gfxSystem = SHSystemManager::GetSystem(); + //auto pos = ImGui::GetCursorPos(); + //windowCursorPos = {} gfxSystem->PrepareResize(static_cast(windowSize.x), static_cast(windowSize.y)); } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index c78cc58f..b160d863 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -69,7 +69,15 @@ namespace SHADE if (width == 0 || height == 0) return; - PrepareResize(resizeWidth, resizeHeight); +#ifdef SHEDITOR + + //PrepareResize(1, 1, SHVec2(0, 0)); + +#else + + PrepareResize(resizeWidth, resizeHeight, SHVec2(0, 0)); + +#endif }); window->RegisterWindowCloseCallback([&](void) @@ -130,7 +138,7 @@ namespace SHADE worldCamera->SetPerspective(90.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 100.0f); // Create Default Viewport - defaultViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast(window->GetWindowSize().first), static_cast(window->GetWindowSize().second), 0.0f, 1.0f)); + worldViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast(window->GetWindowSize().first), static_cast(window->GetWindowSize().second), 0.0f, 1.0f)); // Get render graph from default viewport world renderer worldRenderGraph = resourceManager.Create(); @@ -163,7 +171,7 @@ namespace SHADE worldRenderGraph->Generate(); // Add world renderer to default viewport - worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); + worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); worldRenderer->SetCamera(worldCamera); @@ -691,8 +699,8 @@ namespace SHADE mousePickSystem->HandleResize(); postOffscreenRender->HandleResize(); - defaultViewport->SetWidth(static_cast(resizeWidth)); - defaultViewport->SetHeight(static_cast(resizeHeight)); + worldViewport->SetWidth(static_cast(resizeWidth)); + worldViewport->SetHeight(static_cast(resizeHeight)); worldCamera->SetPerspective(90.0f, static_cast(resizeWidth), static_cast(resizeHeight), 0.0f, 100.0f); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 0e1e2f78..7d0fa3ab 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -280,7 +280,7 @@ namespace SHADE Handle GetPhysicalDevice() const { return physicalDevice; } Handle GetQueue() const { return graphicsQueue; } Handle GetDescriptorPool() const { return descPool; } - Handle GetDefaultViewport() const {return defaultViewport;} + Handle GetDefaultViewport() const {return worldViewport;} #ifdef SHEDITOR Handle GetEditorViewport () const {return editorViewport;}; #endif @@ -325,7 +325,7 @@ namespace SHADE Handle editorRenderGraph; #endif - Handle defaultViewport; // Whole screen + Handle worldViewport; // Whole screen std::vector> viewports; // Additional viewports // Debug Renderers diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp index 1dd8212d..57a08d47 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp @@ -6,6 +6,7 @@ #include "Graphics/Synchronization/SHVkFence.h" #include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/SHVkUtil.h" +#include "Graphics/MiddleEnd/Interface/SHViewport.h" namespace SHADE { @@ -13,7 +14,7 @@ namespace SHADE { logicalDevice = device; - pickedEID = 0; + pickedEID = MAX_EID; // Create command buffers for (auto& pool : cmdPools) @@ -30,7 +31,7 @@ namespace SHADE void SHMousePickSystem::Run(Handle queue, uint32_t frameIndex) noexcept { // if input detected - if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::LEFT_CTRL) && SHInputManager::GetKeyUp(SHInputManager::SH_KEYCODE::LMB)) + if (SHInputManager::GetKeyUp(SHInputManager::SH_KEYCODE::LMB)) { afterCopyFence->Reset(); @@ -52,10 +53,8 @@ namespace SHADE // wait for the copy to be done afterCopyFence->Wait(true, std::numeric_limits::max()); - int mouseX = 0, mouseY = 0; - SHInputManager::GetMouseWindowPosition(&mouseX, &mouseY); + pickedEID = imageDataDstBuffer->GetDataFromMappedPointer(static_cast(viewportMousePos.y) * entityIDAttachment->GetWidth() + static_cast(viewportMousePos.x)); - pickedEID = imageDataDstBuffer->GetDataFromMappedPointer(mouseY * entityIDAttachment->GetWidth() + mouseX); } } @@ -79,6 +78,11 @@ namespace SHADE imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); } + void SHMousePickSystem::SetViewportMousePos(SHVec2 vpMousePos) noexcept + { + viewportMousePos = vpMousePos; + } + EntityID SHMousePickSystem::GetPickedEntity(void) const noexcept { return pickedEID; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h index 4b84c1df..85e86969 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h @@ -13,6 +13,7 @@ namespace SHADE class SHVkFence; class SHVkQueue; class SHVkBuffer; + class SHViewport; class SHMousePickSystem { @@ -33,6 +34,10 @@ namespace SHADE //! eid picked from screen EntityID pickedEID; + + //! mouse position relative to the viewport window displaying the world + SHVec2 viewportMousePos; + public: /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ @@ -44,6 +49,8 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ + void SetViewportMousePos (SHVec2 vpMousePos) noexcept; + EntityID GetPickedEntity (void) const noexcept; }; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp index dc534a49..f47920e0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp @@ -85,4 +85,14 @@ namespace SHADE } + void SHViewport::SetX(float x) noexcept + { + viewport.x = x; + } + + void SHViewport::SetY(float y) noexcept + { + viewport.y = y; + } + } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h index 221dbe7e..04b39f00 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h @@ -67,6 +67,8 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ void SetWidth(float w) noexcept; void SetHeight (float h) noexcept; + void SetX (float x) noexcept; + void SetY (float y) noexcept; /*-----------------------------------------------------------------------------*/ /* Getters */ From 15a17deaf0d0592261904fd7bee3e764815ff71f Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Tue, 18 Oct 2022 19:08:31 +0800 Subject: [PATCH 60/61] select picked entity in hierarchy panel --- .gitignore | 2 ++ .../src/Application/SBApplication.cpp | 9 +++++-- .../Editor/EditorWindow/SHEditorWindow.cpp | 1 + .../src/Editor/EditorWindow/SHEditorWindow.h | 1 + .../ViewportWindow/SHEditorViewport.cpp | 27 ++++++++++++++----- SHADE_Engine/src/Editor/SHEditor.cpp | 3 ++- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 8 +++--- 7 files changed, 37 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 1110510c..5d998cfd 100644 --- a/.gitignore +++ b/.gitignore @@ -362,3 +362,5 @@ MigrationBackup/ *.csproj *.filters + +Assets/Editor/Layouts/UserLayout.ini diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 202a3852..23943940 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -130,14 +130,19 @@ namespace Sandbox void SBApplication::Update(void) { SHGraphicsSystem* graphicsSystem = SHADE::SHSystemManager::GetSystem(); + SHEditor* editor = SHADE::SHSystemManager::GetSystem(); //TODO: Change true to window is open while (!window.WindowShouldClose()) { SHFrameRateController::UpdateFRC(); SHInputManager::UpdateInput(SHFrameRateController::GetRawDeltaTime()); SHSceneManager::UpdateSceneManager(); - SHSceneManager::SceneUpdate(0.016f); - SHSystemManager::RunRoutines(false, 0.016f); +#ifdef SHEDITOR + if(editor->editorState == SHEditor::State::PLAY) + SHSceneManager::SceneUpdate(0.016f); +#endif + SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f); + editor->PollPicking(); } // Finish all graphics jobs first diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp index 491c1bc2..edbe0faa 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp @@ -54,6 +54,7 @@ namespace SHADE windowPos = {wndPos.x, wndPos.y}; OnPosChange(); } + isWindowHovered = ImGui::IsWindowHovered(); return result; } diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h index dca02399..f46cd880 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h @@ -24,6 +24,7 @@ namespace SHADE virtual void Update(); virtual void Exit(); bool isOpen; + bool isWindowHovered; std::string_view windowName; protected: virtual bool Begin(); diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp index f6e6dcff..420443ae 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp @@ -2,6 +2,8 @@ #include "SHEditorViewport.h" #include "ECS_Base/Managers/SHSystemManager.h" +#include "Editor/SHEditor.hpp" +#include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h" @@ -27,14 +29,25 @@ namespace SHADE DrawMenuBar(); auto gfxSystem = SHSystemManager::GetSystem(); auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0]; + auto mousePos = ImGui::GetMousePos(); + auto cursorPos = ImGui::GetCursorScreenPos(); + viewportMousePos = {mousePos.x - cursorPos.x, mousePos.y - cursorPos.y}; + gfxSystem->GetMousePickSystem ()->SetViewportMousePos (viewportMousePos); + //if (ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + //{ + // auto eid = gfxSystem->GetMousePickSystem ()->GetPickedEntity(); + // if(eid != MAX_EID) + // { + // auto editor = SHSystemManager::GetSystem(); + // editor->selectedEntities.clear(); + // editor->selectedEntities.push_back(eid); + // if (const auto hierarchyPanel = SHEditorWindowManager::GetEditorWindow()) + // { + // hierarchyPanel->SetScrollTo(eid); + // } + // } + //} - if (ImGui::IsWindowHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) - { - auto mousePos = ImGui::GetMousePos(); - auto cursorPos = ImGui::GetCursorScreenPos(); - viewportMousePos = {mousePos.x - cursorPos.x, mousePos.y - cursorPos.y}; - gfxSystem->GetMousePickSystem ()->SetViewportMousePos (viewportMousePos); - } ImGui::Image((ImTextureID)descriptorSet, ImGui::GetWindowSize()); } ImGui::End(); diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index 4c6caff0..6b3c3a93 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -337,7 +337,8 @@ namespace SHADE { if (auto gfxSystem = SHSystemManager::GetSystem()) { - if (!ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + auto viewportWindow = SHEditorWindowManager::GetEditorWindow(); + if (viewportWindow->isWindowHovered && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) { EntityID pickedEID = gfxSystem->GetMousePickSystem()->GetPickedEntity(); if(pickedEID == MAX_EID) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index b160d863..143f3bf5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -597,7 +597,7 @@ namespace SHADE /* System Routine Functions - BeginRoutine */ /*-----------------------------------------------------------------------------------*/ SHGraphicsSystem::BeginRoutine::BeginRoutine() - : SHSystemRoutine("Graphics System Frame Set Up", false) + : SHSystemRoutine("Graphics System Frame Set Up", true) {} void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept @@ -609,7 +609,7 @@ namespace SHADE /* System Routine Functions - RenderRoutine */ /*-----------------------------------------------------------------------------------*/ SHGraphicsSystem::RenderRoutine::RenderRoutine() - : SHSystemRoutine("Graphics System Render", false) + : SHSystemRoutine("Graphics System Render", true) {} void SHGraphicsSystem::RenderRoutine::Execute(double dt) noexcept @@ -621,7 +621,7 @@ namespace SHADE /* System Routine Functions - EndRoutine */ /*-----------------------------------------------------------------------------------*/ SHGraphicsSystem::EndRoutine::EndRoutine() - : SHSystemRoutine("Graphics System Frame Clean Up", false) + : SHSystemRoutine("Graphics System Frame Clean Up", true) {} void SHGraphicsSystem::EndRoutine::Execute(double) noexcept @@ -633,7 +633,7 @@ namespace SHADE /* System Routine Functions - BatcherDispatcherRoutine */ /*-----------------------------------------------------------------------------------*/ SHGraphicsSystem::BatcherDispatcherRoutine::BatcherDispatcherRoutine() - : SHSystemRoutine("Graphics System Batcher Dispatcher", false) + : SHSystemRoutine("Graphics System Batcher Dispatcher", true) {} void SHGraphicsSystem::BatcherDispatcherRoutine::Execute(double) noexcept From 82637b620d953b01adb8201168031b13fcaeefd4 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Tue, 18 Oct 2022 19:36:49 +0800 Subject: [PATCH 61/61] Delete UserLayout.ini --- Assets/Editor/Layouts/UserLayout.ini | 48 ---------------------------- 1 file changed, 48 deletions(-) delete mode 100644 Assets/Editor/Layouts/UserLayout.ini diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini deleted file mode 100644 index e55aeb81..00000000 --- a/Assets/Editor/Layouts/UserLayout.ini +++ /dev/null @@ -1,48 +0,0 @@ -[Window][MainStatusBar] -Pos=0,1060 -Size=1920,20 -Collapsed=0 - -[Window][SHEditorMenuBar] -Pos=0,48 -Size=1920,1012 -Collapsed=0 - -[Window][Hierarchy Panel] -Pos=0,142 -Size=321,918 -Collapsed=0 -DockId=0x00000004,0 - -[Window][Debug##Default] -Pos=60,60 -Size=400,400 -Collapsed=0 - -[Window][Inspector] -Pos=1649,48 -Size=271,1012 -Collapsed=0 -DockId=0x00000006,0 - -[Window][Profiler] -Pos=0,48 -Size=321,92 -Collapsed=0 -DockId=0x00000003,0 - -[Window][Viewport] -Pos=323,48 -Size=1324,1012 -Collapsed=0 -DockId=0x00000002,0 - -[Docking][Data] -DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=617,298 Size=1920,1012 Split=X - DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X - DockNode ID=0x00000001 Parent=0x00000005 SizeRef=321,1036 Split=Y Selected=0x1E6EB881 - DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 - DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE - DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1324,1036 CentralNode=1 Selected=0x13926F0B - DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=271,1036 Selected=0xE7039252 -