From 62433d1a5360d060679681aeb6fb71d70c651326 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sun, 20 Nov 2022 02:35:02 +0800 Subject: [PATCH 01/14] Added Collision Tags --- .../src/Physics/Collision/SHCollisionTags.cpp | 176 ++++++++++++++++++ .../src/Physics/Collision/SHCollisionTags.h | 125 +++++++++++++ .../Physics/Interface/SHCollisionShape.cpp | 17 ++ .../src/Physics/Interface/SHCollisionShape.h | 6 + .../Physics/PhysicsObject/SHPhysicsObject.cpp | 8 + .../Physics/PhysicsObject/SHPhysicsObject.h | 1 + 6 files changed, 333 insertions(+) create mode 100644 SHADE_Engine/src/Physics/Collision/SHCollisionTags.cpp create mode 100644 SHADE_Engine/src/Physics/Collision/SHCollisionTags.h diff --git a/SHADE_Engine/src/Physics/Collision/SHCollisionTags.cpp b/SHADE_Engine/src/Physics/Collision/SHCollisionTags.cpp new file mode 100644 index 00000000..fdcf72c6 --- /dev/null +++ b/SHADE_Engine/src/Physics/Collision/SHCollisionTags.cpp @@ -0,0 +1,176 @@ +/**************************************************************************************** + * \file SHCollisionTags.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for Collision Tags for filtering collisions. + * + * \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 "SHCollisionTags.h" +// Project Headers +#include "SHCollisionTags.h" + +#include "Tools/Utilities/SHUtilities.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Static Data Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + std::string SHCollisionTag::tagNames[NUM_TAGS]; + + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHCollisionTag::SHCollisionTag() noexcept + : mask { SHUtilities::ConvertEnum(eTag::ALL_TAGS) } + {} + + SHCollisionTag::SHCollisionTag(uint16_t tagValue) noexcept + : mask { tagValue } + {} + + SHCollisionTag::SHCollisionTag(eTag tagValue) noexcept + : mask { SHUtilities::ConvertEnum(tagValue) } + {} + + /*-----------------------------------------------------------------------------------*/ + /* Operator Overload Definitions */ + /*-----------------------------------------------------------------------------------*/ + + bool SHCollisionTag::operator==(const SHCollisionTag& rhs) const noexcept + { + return mask == rhs.mask; + } + + bool SHCollisionTag::operator!=(const SHCollisionTag& rhs) const noexcept + { + return mask != rhs.mask; + } + + SHCollisionTag::operator uint16_t() const noexcept + { + return mask; + } + + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + uint16_t SHCollisionTag::GetTagValue() const noexcept + { + return mask; + } + + bool SHCollisionTag::GetTagState(eTag tag) const noexcept + { + return (mask & SHUtilities::ConvertEnum(tag)) > 0; + } + + bool SHCollisionTag::GetTagState(int tagIndex) const + { + if (tagIndex < 0 || tagIndex > NUM_TAGS) + throw std::invalid_argument("Index out of range!"); + + return (mask & (1U << tagIndex)) > 0; + } + + + /*-----------------------------------------------------------------------------------*/ + /* Setter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHCollisionTag::SetValue(uint16_t tagValue) noexcept + { + mask = tagValue; + } + + void SHCollisionTag::SetTagState(eTag tag, bool tagState) noexcept + { + const auto VALUE = SHUtilities::ConvertEnum(tag); + tagState ? mask |= VALUE : mask &= ~(VALUE); + } + + void SHCollisionTag::SetTagState(const std::string& tagName, bool tagState) noexcept + { + // This find is expensive. + int tagIndex = -1; + for (int i = 0; i < NUM_TAGS; ++i) + { + if (tagNames[i] != tagName) + continue; + + tagIndex = i; + break; + } + + if (tagIndex < 0) + { + SHLOGV_WARNING("Parameter tagName {} not found in list of tag names. Tag unmodified.", tagName) + return; + } + + const auto VALUE = 1U << tagIndex; + tagState ? mask |= (VALUE) : mask &= ~(VALUE); + } + + void SHCollisionTag::SetTagState(int tagIndex, bool tagState) + { + if (tagIndex < 0 || tagIndex > NUM_TAGS) + throw std::invalid_argument("Index out of range!"); + + const auto VALUE = 1U << tagIndex; + tagState ? mask |= (VALUE) : mask &= ~(VALUE); + } + + /*-----------------------------------------------------------------------------------*/ + /* Public Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHCollisionTag::Init(const std::filesystem::path& tagNameFilePath) noexcept + { + // Read tag names from given file. + } + + void SHCollisionTag::Exit(const std::filesystem::path& tagNameFilePath) noexcept + { + // Write current set of names to file. + // This ensures any names changed is reflected on the file for the next run of the application. + } + + void SHCollisionTag::RemoveTagName(int tagIndex) + { + if (tagIndex < 0 || tagIndex > NUM_TAGS) + throw std::invalid_argument("Index out of range!"); + + tagNames[tagIndex].clear(); + } + + void SHCollisionTag::SetTagName(const std::string& newTagName, int tagIndex) + { + if (tagIndex < 0 || tagIndex > NUM_TAGS) + throw std::invalid_argument("Index out of range!"); + + tagNames[tagIndex] = newTagName; + } + + const std::string& SHCollisionTag::GetTagName(int tagIndex) + { + if (tagIndex < 0 || tagIndex > NUM_TAGS) + throw std::invalid_argument("Index out of range!"); + + return tagNames[tagIndex]; + } +} // namespace SHADE + +SHADE::SHCollisionTag::eTag operator|(SHADE::SHCollisionTag::eTag lhs, SHADE::SHCollisionTag::eTag rhs) noexcept +{ + return static_cast(SHADE::SHUtilities::ConvertEnum(lhs) | SHADE::SHUtilities::ConvertEnum(rhs)); +} \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Collision/SHCollisionTags.h b/SHADE_Engine/src/Physics/Collision/SHCollisionTags.h new file mode 100644 index 00000000..e43aae2d --- /dev/null +++ b/SHADE_Engine/src/Physics/Collision/SHCollisionTags.h @@ -0,0 +1,125 @@ +/**************************************************************************************** + * \file SHCollisionTags.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for Collision Tags for filtering collisions. + * + * \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" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SH_API SHCollisionTag + { + public: + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + + enum class eTag : uint16_t + { + TAG_1 = 0x0001 + , TAG_2 = 0x0002 + , TAG_3 = 0x0004 + , TAG_4 = 0x0008 + , TAG_5 = 0x0010 + , TAG_6 = 0x0020 + , TAG_7 = 0x0040 + , TAG_8 = 0x0080 + , TAG_9 = 0x0100 + , TAG_10 = 0x0200 + , TAG_11 = 0x0400 + , TAG_12 = 0x0800 + , TAG_13 = 0x1000 + , TAG_14 = 0x2000 + , TAG_15 = 0x4000 + , TAG_16 = 0x8000 + , ALL_TAGS = 0xFFFF + }; + + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHCollisionTag () noexcept; + SHCollisionTag (uint16_t tagValue) noexcept; + SHCollisionTag (eTag tagValue) noexcept; + + SHCollisionTag (const SHCollisionTag&) noexcept = default; + SHCollisionTag (SHCollisionTag&&) noexcept = default; + ~SHCollisionTag () = default; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + SHCollisionTag& operator=(const SHCollisionTag&) noexcept = default; + SHCollisionTag& operator=(SHCollisionTag&&) noexcept = default; + + [[nodiscard]] bool operator==(const SHCollisionTag& rhs) const noexcept; + [[nodiscard]] bool operator!=(const SHCollisionTag& rhs) const noexcept; + + operator uint16_t() const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] uint16_t GetTagValue () const noexcept; + [[nodiscard]] bool GetTagState (eTag tag) const noexcept; + [[nodiscard]] bool GetTagState (int tagIndex) const; + + /*---------------------------------------------------------------------------------*/ + /* Setter Functions */ + /*---------------------------------------------------------------------------------*/ + + void SetValue (uint16_t tagValue) noexcept; + + void SetTagState (eTag tag, bool tagState) noexcept; + void SetTagState (const std::string& tagName, bool tagState) noexcept; + void SetTagState (int tagIndex, bool tagState); + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + static void Init (const std::filesystem::path& tagNameFilePath) noexcept; + static void Exit (const std::filesystem::path& tagNameFilePath) noexcept; + + static void SetTagName (const std::string& newTagName, int tagIndex); + static void RemoveTagName (int tagIndex); + + [[nodiscard]] static const std::string& GetTagName (int tagIndex); + + private: + /*---------------------------------------------------------------------------------*/ + /* Static Data Members */ + /*---------------------------------------------------------------------------------*/ + + static constexpr int NUM_TAGS = 16; + static std::string tagNames[NUM_TAGS]; + + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + uint16_t mask; + }; + +} // namespace SHADE + +SHADE::SHCollisionTag::eTag SH_API operator|(SHADE::SHCollisionTag::eTag lhs, SHADE::SHCollisionTag::eTag rhs) noexcept; + + diff --git a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp index 14743845..46348c19 100644 --- a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp @@ -134,6 +134,11 @@ namespace SHADE return type; } + const SHCollisionTag& SHCollisionShape::GetCollisionTags() const noexcept + { + return collisionTags; + } + float SHCollisionShape::GetFriction() const noexcept { return material.GetFriction(); @@ -240,6 +245,18 @@ namespace SHADE isTrigger = trigger; } + void SHCollisionShape::SetCollisionTags(const SHCollisionTag& newCollisionTag) noexcept + { + dirty = true; + collisionTags = newCollisionTag; + } + + void SHCollisionShape::SetCollisionTags(SHCollisionTag::eTag newCollisionTag) noexcept + { + dirty = true; + collisionTags = SHCollisionTag{ newCollisionTag }; + } + void SHCollisionShape::SetFriction(float friction) noexcept { dirty = true; diff --git a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.h b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.h index 526428fd..7cd8528a 100644 --- a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.h +++ b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.h @@ -17,6 +17,7 @@ #include "Math/Geometry/SHShape.h" #include "Math/SHQuaternion.h" #include "SHPhysicsMaterial.h" +#include "Physics/Collision/SHCollisionTags.h" namespace SHADE { @@ -74,6 +75,8 @@ namespace SHADE [[nodiscard]] Type GetType () const noexcept; + [[nodiscard]] const SHCollisionTag& GetCollisionTags () const noexcept; + [[nodiscard]] float GetFriction () const noexcept; [[nodiscard]] float GetBounciness () const noexcept; [[nodiscard]] float GetDensity () const noexcept; @@ -92,6 +95,8 @@ namespace SHADE void SetBoundingSphere (float radius); void SetIsTrigger (bool isTrigger) noexcept; + void SetCollisionTags (const SHCollisionTag& newCollisionTag) noexcept; + void SetCollisionTags (SHCollisionTag::eTag newCollisionTag) noexcept; void SetFriction (float friction) noexcept; void SetBounciness (float bounciness) noexcept; void SetDensity (float density) noexcept; @@ -109,6 +114,7 @@ namespace SHADE EntityID entityID; // The entity this collider belongs to bool isTrigger; bool dirty; + SHCollisionTag collisionTags; SHShape* shape; SHPhysicsMaterial material; SHVec3 positionOffset; diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp index 3cfa3ec9..6ce8e9d3 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp @@ -311,6 +311,9 @@ namespace SHADE syncMaterial(i, collisionShape); + // Sync tags + + collisionShape.dirty = false; } } @@ -327,6 +330,11 @@ namespace SHADE rp3dMaterial.setMassDensity(collisionShape.GetDensity()); } + void SHPhysicsObject::syncTags(int colliderIndex, SHCollisionShape& collisionShape) const noexcept + { + + } + void SHPhysicsObject::addBoxShape(SHCollisionShape& boxShape) const noexcept { const rp3d::Transform OFFSETS diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h index 5a0e62ac..a5e8a53c 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h @@ -97,6 +97,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ void syncMaterial (int colliderIndex, SHCollisionShape& collisionShape) const noexcept; + void syncTags (int colliderIndex, SHCollisionShape& collisionShape) const noexcept; // Box Shapes From 7226ccf27998a9222bad29cc0804453aa48e7b95 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sun, 20 Nov 2022 03:16:49 +0800 Subject: [PATCH 02/14] Tested Collision Tags --- .../src/Application/SBApplication.cpp | 1 + .../src/Physics/Collision/SHCollisionTags.cpp | 2 +- .../Physics/Interface/SHCollisionShape.cpp | 6 ---- .../src/Physics/Interface/SHCollisionShape.h | 1 - .../Physics/PhysicsObject/SHPhysicsObject.cpp | 35 +++++++++---------- .../Physics/PhysicsObject/SHPhysicsObject.h | 3 -- 6 files changed, 19 insertions(+), 29 deletions(-) diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 0fb8adf9..cf5a9277 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -174,6 +174,7 @@ namespace Sandbox SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f); editor->PollPicking(); + // TODO: Move into an Editor menu static bool drawColliders = false; if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10)) { diff --git a/SHADE_Engine/src/Physics/Collision/SHCollisionTags.cpp b/SHADE_Engine/src/Physics/Collision/SHCollisionTags.cpp index fdcf72c6..85072e5e 100644 --- a/SHADE_Engine/src/Physics/Collision/SHCollisionTags.cpp +++ b/SHADE_Engine/src/Physics/Collision/SHCollisionTags.cpp @@ -30,7 +30,7 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHCollisionTag::SHCollisionTag() noexcept - : mask { SHUtilities::ConvertEnum(eTag::ALL_TAGS) } + : mask { SHUtilities::ConvertEnum(eTag::TAG_1) } {} SHCollisionTag::SHCollisionTag(uint16_t tagValue) noexcept diff --git a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp index 46348c19..745d64c5 100644 --- a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp @@ -251,12 +251,6 @@ namespace SHADE collisionTags = newCollisionTag; } - void SHCollisionShape::SetCollisionTags(SHCollisionTag::eTag newCollisionTag) noexcept - { - dirty = true; - collisionTags = SHCollisionTag{ newCollisionTag }; - } - void SHCollisionShape::SetFriction(float friction) noexcept { dirty = true; diff --git a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.h b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.h index 7cd8528a..fd08e55d 100644 --- a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.h +++ b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.h @@ -96,7 +96,6 @@ namespace SHADE void SetIsTrigger (bool isTrigger) noexcept; void SetCollisionTags (const SHCollisionTag& newCollisionTag) noexcept; - void SetCollisionTags (SHCollisionTag::eTag newCollisionTag) noexcept; void SetFriction (float friction) noexcept; void SetBounciness (float bounciness) noexcept; void SetDensity (float density) noexcept; diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp index 6ce8e9d3..ea3d5996 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp @@ -254,6 +254,10 @@ namespace SHADE } case 9: // Mass { + rp3dBody->setMass(component.mass); + rp3dBody->updateLocalCenterOfMassFromColliders(); + rp3dBody->updateLocalInertiaTensorFromColliders(); + //if (component.GetAutoMass()) //{ // rp3dBody->updateMassPropertiesFromColliders(); @@ -261,9 +265,9 @@ namespace SHADE //} //else //{ - rp3dBody->setMass(component.mass); - rp3dBody->updateLocalCenterOfMassFromColliders(); - rp3dBody->updateLocalInertiaTensorFromColliders(); + // rp3dBody->setMass(component.mass); + // rp3dBody->updateLocalCenterOfMassFromColliders(); + // rp3dBody->updateLocalInertiaTensorFromColliders(); //} break; @@ -309,10 +313,18 @@ namespace SHADE default: break; } - syncMaterial(i, collisionShape); + // Sync material + auto* rp3dCollider = rp3dBody->getCollider(i); + auto& rp3dMaterial = rp3dCollider->getMaterial(); + + rp3dMaterial.setFrictionCoefficient(collisionShape.GetFriction()); + rp3dMaterial.setBounciness(collisionShape.GetBounciness()); + rp3dMaterial.setMassDensity(collisionShape.GetDensity()); // Sync tags - + const unsigned short MASK_BITS = collisionShape.GetCollisionTags(); + rp3dCollider->setCollisionCategoryBits(MASK_BITS); + rp3dCollider->setCollideWithMaskBits(MASK_BITS); collisionShape.dirty = false; } @@ -322,19 +334,6 @@ namespace SHADE /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHPhysicsObject::syncMaterial(int colliderIndex, SHCollisionShape& collisionShape) const noexcept - { - auto& rp3dMaterial = rp3dBody->getCollider(colliderIndex)->getMaterial(); - rp3dMaterial.setFrictionCoefficient(collisionShape.GetFriction()); - rp3dMaterial.setBounciness(collisionShape.GetBounciness()); - rp3dMaterial.setMassDensity(collisionShape.GetDensity()); - } - - void SHPhysicsObject::syncTags(int colliderIndex, SHCollisionShape& collisionShape) const noexcept - { - - } - void SHPhysicsObject::addBoxShape(SHCollisionShape& boxShape) const noexcept { const rp3d::Transform OFFSETS diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h index a5e8a53c..fefc983f 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h @@ -96,9 +96,6 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - void syncMaterial (int colliderIndex, SHCollisionShape& collisionShape) const noexcept; - void syncTags (int colliderIndex, SHCollisionShape& collisionShape) const noexcept; - // Box Shapes void addBoxShape (SHCollisionShape& boxShape) const noexcept; From a0f4f3b00a84417bdab9e991f0c3265861c704d4 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sun, 20 Nov 2022 15:32:33 +0800 Subject: [PATCH 03/14] Added collision tag names file --- Assets/CollisionTags.SHConfig | 20 +++ .../src/Physics/Collision/SHCollisionTags.cpp | 135 +++++++++++++++++- .../src/Physics/Collision/SHCollisionTags.h | 9 +- .../src/Physics/System/SHPhysicsSystem.cpp | 11 ++ .../src/Physics/System/SHPhysicsSystem.h | 1 + 5 files changed, 167 insertions(+), 9 deletions(-) create mode 100644 Assets/CollisionTags.SHConfig diff --git a/Assets/CollisionTags.SHConfig b/Assets/CollisionTags.SHConfig new file mode 100644 index 00000000..18a339dd --- /dev/null +++ b/Assets/CollisionTags.SHConfig @@ -0,0 +1,20 @@ +0 1 +1 2 +2 3 +3 4 +4 5 +5 6 +6 7 +7 8 +8 9 +9 10 +10 11 +11 12 +12 13 +13 14 +14 15 +15 16 + +note: +All collision tags should follow the above format "indextag name". +If it fails to follow this, the default tag names will be used. \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Collision/SHCollisionTags.cpp b/SHADE_Engine/src/Physics/Collision/SHCollisionTags.cpp index 85072e5e..7275b618 100644 --- a/SHADE_Engine/src/Physics/Collision/SHCollisionTags.cpp +++ b/SHADE_Engine/src/Physics/Collision/SHCollisionTags.cpp @@ -9,12 +9,12 @@ ****************************************************************************************/ #include +#include // Primary Header #include "SHCollisionTags.h" // Project Headers -#include "SHCollisionTags.h" - +#include "Tools/FileIO/SHFileIO.h" #include "Tools/Utilities/SHUtilities.h" namespace SHADE @@ -136,15 +136,140 @@ namespace SHADE void SHCollisionTag::Init(const std::filesystem::path& tagNameFilePath) noexcept { - // Read tag names from given file. + /** + * I HATE FILE IO + * + * Each line in the file should be "indextag name". + * If the line fails to follow this format, use the default tag name (index + 1) + */ + + // Populate tag names with default + for (int i = 0; i < NUM_TAGS; ++i) + tagNames[i] = std::to_string(i + 1); + + std::ifstream collisionTagNamesFile { tagNameFilePath }; + + if (!collisionTagNamesFile.is_open()) + { + SHLOG_ERROR("Failed to open file for Collision Tag Names! Default tag names used!") + return; + } + + std::stringstream ss; + std::string line; + + int linesRead = 0; + while (std::getline(collisionTagNamesFile, line)) + { + // Do not read anything beyond the first 16 lines + if (linesRead >= 16) + break; + + ss << line; + ++linesRead; + + // First element is index. + int tagIndex; + ss >> tagIndex; + + // Next element is name of the tag + std::string tagName; + ss >> tagName; + + // If no tag name read, use default. + if (tagName.empty()) + { + SHLOG_ERROR + ( + "Collision tag file line {} does not match the required format of 'indextag name'. Default tag used for index {}" + , linesRead + 1 + , tagIndex + ) + + // Use default since + tagNames[tagIndex] = std::to_string(tagIndex + 1); + continue; + } + + tagNames[tagIndex] = tagName; + + ss.clear(); + } + + collisionTagNamesFile.close(); } void SHCollisionTag::Exit(const std::filesystem::path& tagNameFilePath) noexcept { - // Write current set of names to file. - // This ensures any names changed is reflected on the file for the next run of the application. + std::ofstream collisionTagNamesFile { tagNameFilePath }; + + if (!collisionTagNamesFile.is_open()) + { + SHLOG_ERROR("Failed to open file for Collision Tag Names! Tag names not saved!") + return; + } + + for (int i = 0; i < NUM_TAGS; ++i) + collisionTagNamesFile << i << " " << tagNames[i] << std::endl; + + collisionTagNamesFile.close(); } + void SHCollisionTag::UpdateTagNamesFromFile(const std::filesystem::path& tagNameFilePath) noexcept + { + std::ifstream collisionTagNamesFile { tagNameFilePath }; + + if (!collisionTagNamesFile.is_open()) + { + SHLOG_ERROR("Failed to open file for Collision Tag Names! Default tag names used!") + return; + } + + std::stringstream ss; + std::string line; + + int linesRead = 0; + while (std::getline(collisionTagNamesFile, line)) + { + // Do not read anything beyond the first 16 lines + if (linesRead >= 16) + break; + + ss << line; + ++linesRead; + + // First element is index. + int tagIndex; + ss >> tagIndex; + + // Next element is name of the tag + std::string tagName; + ss >> tagName; + + // If no tag name read, use default. + if (tagName.empty()) + { + SHLOG_ERROR + ( + "Collision tag file line {} does not match the required format of 'indextag name'. Name left unchanged for index {}" + , linesRead + 1 + , tagIndex + ) + + // Use default since + tagNames[tagIndex] = std::to_string(tagIndex + 1); + continue; + } + + tagNames[tagIndex] = tagName; + + ss.clear(); + } + + collisionTagNamesFile.close(); + } + + void SHCollisionTag::RemoveTagName(int tagIndex) { if (tagIndex < 0 || tagIndex > NUM_TAGS) diff --git a/SHADE_Engine/src/Physics/Collision/SHCollisionTags.h b/SHADE_Engine/src/Physics/Collision/SHCollisionTags.h index e43aae2d..1b709837 100644 --- a/SHADE_Engine/src/Physics/Collision/SHCollisionTags.h +++ b/SHADE_Engine/src/Physics/Collision/SHCollisionTags.h @@ -95,11 +95,12 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - static void Init (const std::filesystem::path& tagNameFilePath) noexcept; - static void Exit (const std::filesystem::path& tagNameFilePath) noexcept; + static void Init (const std::filesystem::path& tagNameFilePath) noexcept; + static void Exit (const std::filesystem::path& tagNameFilePath) noexcept; + static void UpdateTagNamesFromFile(const std::filesystem::path& tagNameFilePath) noexcept; - static void SetTagName (const std::string& newTagName, int tagIndex); - static void RemoveTagName (int tagIndex); + static void SetTagName (const std::string& newTagName, int tagIndex); + static void RemoveTagName (int tagIndex); [[nodiscard]] static const std::string& GetTagName (int tagIndex); diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp index f3513ffb..c343d506 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp @@ -14,6 +14,7 @@ #include "SHPhysicsSystem.h" // Project Headers +#include "Assets/SHAssetMacros.h" #include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/Managers/SHEntityManager.h" #include "ECS_Base/Managers/SHSystemManager.h" @@ -90,6 +91,11 @@ namespace SHADE void SHPhysicsSystem::Init() { + // Initialise collision tags + std::filesystem::path defaultCollisionTagNameFilePath { ASSET_ROOT }; + defaultCollisionTagNameFilePath.append("CollisionTags.SHConfig"); + SHCollisionTag::Init(defaultCollisionTagNameFilePath); + // Subscribe to component events const std::shared_ptr ADD_COMPONENT_RECEIVER { std::make_shared>(this, &SHPhysicsSystem::addPhysicsComponent) }; const ReceiverPtr ADD_COMPONENT_RECEIVER_PTR = std::dynamic_pointer_cast(ADD_COMPONENT_RECEIVER); @@ -122,6 +128,11 @@ namespace SHADE void SHPhysicsSystem::Exit() { worldState.DestroyWorld(factory); + + // Write collision tag names to file + std::filesystem::path defaultCollisionTagNameFilePath { ASSET_ROOT }; + defaultCollisionTagNameFilePath.append("CollisionTags.SHConfig"); + SHCollisionTag::Exit(defaultCollisionTagNameFilePath); } void SHPhysicsSystem::ForceUpdate() diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h index f92be4cd..89ecb51e 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h @@ -69,6 +69,7 @@ namespace SHADE void SetFixedUpdateRate (double fixedUpdateRate) noexcept; void SetWorldSettings (const SHPhysicsWorldState::WorldSettings& settings) noexcept; + void SetCollisionTagFile (const std::filesystem::path& tagNamesFilePath) noexcept; /*---------------------------------------------------------------------------------*/ /* Function Members */ From 4198310b7a8f24fbe917b377ccb7862ad44e0384 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sun, 20 Nov 2022 15:34:34 +0800 Subject: [PATCH 04/14] Missing implementation for updating all tag names through the physics system --- SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp index c343d506..17f27eaf 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp @@ -85,6 +85,12 @@ namespace SHADE worldState.UpdateSettings(); } + void SHPhysicsSystem::SetCollisionTagFile(const std::filesystem::path& tagNamesFilePath) noexcept + { + SHCollisionTag::UpdateTagNamesFromFile(tagNamesFilePath); + } + + /*-----------------------------------------------------------------------------------*/ /* Public Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ From 4ebc16564ae61126321a3850d842e08fd98052c0 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sun, 20 Nov 2022 17:23:28 +0800 Subject: [PATCH 05/14] Added collision matrix for configurating individual collision tags --- .../Collision/SHCollisionTagMatrix.cpp | 255 ++++++++++++++++++ .../Physics/Collision/SHCollisionTagMatrix.h | 65 +++++ .../src/Physics/Collision/SHCollisionTags.cpp | 243 ++--------------- .../src/Physics/Collision/SHCollisionTags.h | 90 +++---- .../Physics/Interface/SHCollisionShape.cpp | 8 +- .../src/Physics/Interface/SHCollisionShape.h | 6 +- .../Physics/PhysicsObject/SHPhysicsObject.cpp | 2 +- .../src/Physics/System/SHPhysicsSystem.cpp | 7 +- 8 files changed, 399 insertions(+), 277 deletions(-) create mode 100644 SHADE_Engine/src/Physics/Collision/SHCollisionTagMatrix.cpp create mode 100644 SHADE_Engine/src/Physics/Collision/SHCollisionTagMatrix.h diff --git a/SHADE_Engine/src/Physics/Collision/SHCollisionTagMatrix.cpp b/SHADE_Engine/src/Physics/Collision/SHCollisionTagMatrix.cpp new file mode 100644 index 00000000..ce6cd900 --- /dev/null +++ b/SHADE_Engine/src/Physics/Collision/SHCollisionTagMatrix.cpp @@ -0,0 +1,255 @@ +/**************************************************************************************** + * \file SHCollisionTagMatrix.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for Collision Tag Matrix for handling sets of Collision Tags. + * + * \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 "SHCollisionTagMatrix.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Static Data Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHCollisionTag SHCollisionTagMatrix::collisionTags[SHCollisionTag::NUM_LAYERS]; + + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + const std::string& SHCollisionTagMatrix::GetTagName(int tagIndex) + { + if (tagIndex < 0 || tagIndex > SHCollisionTag::NUM_LAYERS) + throw std::invalid_argument("Index out of range!"); + + return collisionTags[tagIndex].GetName(); + } + + int SHCollisionTagMatrix::GetTagIndex(const std::string& tagName) noexcept + { + for (int i = 0; i < SHCollisionTag::NUM_LAYERS; ++i) + { + if (collisionTags[i].GetName() == tagName) + return i; + } + + SHLOGV_WARNING("Collision Tag {} cannot be found!", tagName) + return -1; + } + + /*-----------------------------------------------------------------------------------*/ + /* Setter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHCollisionTagMatrix::SetTagName(const std::string& oldTagName, const std::string& newTagName) noexcept + { + for (auto& collisionTag : collisionTags) + { + if (collisionTag.GetName() != oldTagName) + continue; + + collisionTag.SetName(newTagName); + return; + } + + SHLOGV_WARNING("Collision tag {} cannot be found!", oldTagName) + } + + void SHCollisionTagMatrix::SetTag(const std::string& tagName, const SHCollisionTag& newTag) noexcept + { + for (auto& collisionTag : collisionTags) + { + if (collisionTag.GetName() != tagName) + continue; + + collisionTag = newTag; + return; + } + + SHLOGV_WARNING("Collision tag {} cannot be found!", tagName) + } + + void SHCollisionTagMatrix::SetTag(const std::string& tagName, uint16_t mask) noexcept + { + for (auto& collisionTag : collisionTags) + { + if (collisionTag.GetName() != tagName) + continue; + + collisionTag.SetMask(mask); + return; + } + + SHLOGV_WARNING("Collision tag {} cannot be found!", tagName) + } + + void SHCollisionTagMatrix::SetTagName(int tagIndex, const std::string& newTagName) + { + if (tagIndex < 0 || tagIndex > SHCollisionTag::NUM_LAYERS) + throw std::invalid_argument("Index out of range!"); + + collisionTags[tagIndex].SetName(newTagName); + } + + void SHCollisionTagMatrix::SetTag(int tagIndex, const SHCollisionTag& newTag) + { + if (tagIndex < 0 || tagIndex > SHCollisionTag::NUM_LAYERS) + throw std::invalid_argument("Index out of range!"); + + collisionTags[tagIndex] = newTag; + } + + void SHCollisionTagMatrix::SetTag(int tagIndex, uint16_t mask) + { + if (tagIndex < 0 || tagIndex > SHCollisionTag::NUM_LAYERS) + throw std::invalid_argument("Index out of range!"); + + collisionTags[tagIndex].SetMask(mask); + } + + /*-----------------------------------------------------------------------------------*/ + /* Public Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHCollisionTagMatrix::Init(const std::filesystem::path& tagNameFilePath) noexcept + { + /** + * I HATE FILE IO + * + * Each line in the file should be "indextag name". + * If the line fails to follow this format, use the default tag name (index + 1) + */ + + // Populate tag names with default + for (int i = 0; i < SHCollisionTag::NUM_LAYERS; ++i) + collisionTags[i].SetName(std::to_string(i + 1)); + + std::ifstream collisionTagNamesFile { tagNameFilePath }; + + if (!collisionTagNamesFile.is_open()) + { + SHLOG_ERROR("Failed to open file for Collision Tag Names! Default tag names used!") + return; + } + + std::stringstream ss; + std::string line; + + int linesRead = 0; + while (std::getline(collisionTagNamesFile, line)) + { + // Do not read anything beyond the first 16 lines + if (linesRead >= 16) + break; + + ss << line; + ++linesRead; + + // First element is index. + int tagIndex; + ss >> tagIndex; + + // Next element is name of the tag + std::string tagName; + ss >> tagName; + + // If no tag name read, use default. + if (tagName.empty()) + { + SHLOG_ERROR + ( + "Collision tag file line {} does not match the required format of 'indextag name'. Default tag used for index {}" + , linesRead + 1 + , tagIndex + ) + + // Use default + collisionTags[tagIndex].SetName(std::to_string(tagIndex + 1)); + continue; + } + + collisionTags[tagIndex].SetName(tagName); + + ss.clear(); + } + + collisionTagNamesFile.close(); + } + + void SHCollisionTagMatrix::Exit(const std::filesystem::path& tagNameFilePath) noexcept + { + std::ofstream collisionTagNamesFile { tagNameFilePath }; + + if (!collisionTagNamesFile.is_open()) + { + SHLOG_ERROR("Failed to open file for Collision Tag Names! Tag names not saved!") + return; + } + + for (int i = 0; i < SHCollisionTag::NUM_LAYERS; ++i) + collisionTagNamesFile << i << " " << collisionTags[i].GetName() << std::endl; + + collisionTagNamesFile.close(); + } + + void SHCollisionTagMatrix::UpdateTagNamesFromFile(const std::filesystem::path& tagNameFilePath) noexcept + { + std::ifstream collisionTagNamesFile { tagNameFilePath }; + + if (!collisionTagNamesFile.is_open()) + { + SHLOG_ERROR("Failed to open file for Collision Tag Names! Default tag names used!") + return; + } + + std::stringstream ss; + std::string line; + + int linesRead = 0; + while (std::getline(collisionTagNamesFile, line)) + { + // Do not read anything beyond the first 16 lines + if (linesRead >= 16) + break; + + ss << line; + ++linesRead; + + // First element is index. + int tagIndex; + ss >> tagIndex; + + // Next element is name of the tag + std::string tagName; + ss >> tagName; + + // If no tag name read, use default. + if (tagName.empty()) + { + SHLOG_ERROR + ( + "Collision tag file line {} does not match the required format of 'indextag name'. Name left unchanged for index {}" + , linesRead + 1 + , tagIndex + ) + + continue; + } + + collisionTags[tagIndex].SetName(tagName); + + ss.clear(); + } + + collisionTagNamesFile.close(); + } +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Collision/SHCollisionTagMatrix.h b/SHADE_Engine/src/Physics/Collision/SHCollisionTagMatrix.h new file mode 100644 index 00000000..eac23ebb --- /dev/null +++ b/SHADE_Engine/src/Physics/Collision/SHCollisionTagMatrix.h @@ -0,0 +1,65 @@ +/**************************************************************************************** + * \file SHCollisionTagMatrix.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for Collision Tag Matrix for handling sets of Collision Tags. + * + * \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 Includes +#include "SH_API.h" +#include "SHCollisionTags.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SH_API SHCollisionTagMatrix + { + public: + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] static const std::string& GetTagName (int tagIndex); + [[nodiscard]] static int GetTagIndex (const std::string& tagName) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Setter Functions */ + /*---------------------------------------------------------------------------------*/ + + static void SetTagName (const std::string& oldTagName, const std::string& newTagName) noexcept; + static void SetTag (const std::string& tagName, const SHCollisionTag& newTag) noexcept; + static void SetTag (const std::string& tagName, uint16_t mask) noexcept; + + // Unsafe Setters: Can throw exceptions + + static void SetTagName (int tagIndex, const std::string& newTagName); + static void SetTag (int tagIndex, const SHCollisionTag& newTag); + static void SetTag (int tagIndex, uint16_t mask); + + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + static void Init (const std::filesystem::path& tagNameFilePath) noexcept; + static void Exit (const std::filesystem::path& tagNameFilePath) noexcept; + static void UpdateTagNamesFromFile (const std::filesystem::path& tagNameFilePath) noexcept; + + private: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + static SHCollisionTag collisionTags[SHCollisionTag::NUM_LAYERS]; + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Collision/SHCollisionTags.cpp b/SHADE_Engine/src/Physics/Collision/SHCollisionTags.cpp index 7275b618..b1d2d5fc 100644 --- a/SHADE_Engine/src/Physics/Collision/SHCollisionTags.cpp +++ b/SHADE_Engine/src/Physics/Collision/SHCollisionTags.cpp @@ -14,31 +14,24 @@ // Primary Header #include "SHCollisionTags.h" // Project Headers -#include "Tools/FileIO/SHFileIO.h" #include "Tools/Utilities/SHUtilities.h" namespace SHADE { - /*-----------------------------------------------------------------------------------*/ - /* Static Data Member Definitions */ - /*-----------------------------------------------------------------------------------*/ - - std::string SHCollisionTag::tagNames[NUM_TAGS]; - /*-----------------------------------------------------------------------------------*/ /* Constructors & Destructor Definitions */ /*-----------------------------------------------------------------------------------*/ SHCollisionTag::SHCollisionTag() noexcept - : mask { SHUtilities::ConvertEnum(eTag::TAG_1) } + : mask { SHUtilities::ConvertEnum(Layer::ALL) } {} - SHCollisionTag::SHCollisionTag(uint16_t tagValue) noexcept - : mask { tagValue } + SHCollisionTag::SHCollisionTag(uint16_t _mask) noexcept + : mask { _mask } {} - SHCollisionTag::SHCollisionTag(eTag tagValue) noexcept - : mask { SHUtilities::ConvertEnum(tagValue) } + SHCollisionTag::SHCollisionTag(Layer layer) noexcept + : mask { SHUtilities::ConvertEnum(layer) } {} /*-----------------------------------------------------------------------------------*/ @@ -64,238 +57,60 @@ namespace SHADE /* Getter Function Definitions */ /*-----------------------------------------------------------------------------------*/ - uint16_t SHCollisionTag::GetTagValue() const noexcept + uint16_t SHCollisionTag::GetMask() const noexcept { return mask; } - bool SHCollisionTag::GetTagState(eTag tag) const noexcept + const std::string& SHCollisionTag::GetName() const noexcept { - return (mask & SHUtilities::ConvertEnum(tag)) > 0; + return name; } - bool SHCollisionTag::GetTagState(int tagIndex) const + bool SHCollisionTag::GetLayerState(Layer layer) const noexcept { - if (tagIndex < 0 || tagIndex > NUM_TAGS) + return (mask & SHUtilities::ConvertEnum(layer)) > 0; + } + + bool SHCollisionTag::GetLayerState(int layerIndex) const + { + if (layerIndex < 0 || layerIndex > NUM_LAYERS) throw std::invalid_argument("Index out of range!"); - return (mask & (1U << tagIndex)) > 0; + return (mask & (1U << layerIndex)) > 0; } - /*-----------------------------------------------------------------------------------*/ /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHCollisionTag::SetValue(uint16_t tagValue) noexcept + void SHCollisionTag::SetMask(uint16_t newMask) noexcept { - mask = tagValue; + mask = newMask; } - void SHCollisionTag::SetTagState(eTag tag, bool tagState) noexcept + void SHCollisionTag::SetName(const std::string_view& newName) noexcept { - const auto VALUE = SHUtilities::ConvertEnum(tag); - tagState ? mask |= VALUE : mask &= ~(VALUE); + name = newName; } - void SHCollisionTag::SetTagState(const std::string& tagName, bool tagState) noexcept + void SHCollisionTag::SetLayerState(Layer layer, bool state) noexcept { - // This find is expensive. - int tagIndex = -1; - for (int i = 0; i < NUM_TAGS; ++i) - { - if (tagNames[i] != tagName) - continue; - - tagIndex = i; - break; - } - - if (tagIndex < 0) - { - SHLOGV_WARNING("Parameter tagName {} not found in list of tag names. Tag unmodified.", tagName) - return; - } - - const auto VALUE = 1U << tagIndex; - tagState ? mask |= (VALUE) : mask &= ~(VALUE); + const auto VALUE = SHUtilities::ConvertEnum(layer); + state ? mask |= VALUE : mask &= ~(VALUE); } - void SHCollisionTag::SetTagState(int tagIndex, bool tagState) + void SHCollisionTag::SetLayerState(int layerIndex, bool state) { - if (tagIndex < 0 || tagIndex > NUM_TAGS) + if (layerIndex < 0 || layerIndex > NUM_LAYERS) throw std::invalid_argument("Index out of range!"); - const auto VALUE = 1U << tagIndex; - tagState ? mask |= (VALUE) : mask &= ~(VALUE); - } - - /*-----------------------------------------------------------------------------------*/ - /* Public Function Member Definitions */ - /*-----------------------------------------------------------------------------------*/ - - void SHCollisionTag::Init(const std::filesystem::path& tagNameFilePath) noexcept - { - /** - * I HATE FILE IO - * - * Each line in the file should be "indextag name". - * If the line fails to follow this format, use the default tag name (index + 1) - */ - - // Populate tag names with default - for (int i = 0; i < NUM_TAGS; ++i) - tagNames[i] = std::to_string(i + 1); - - std::ifstream collisionTagNamesFile { tagNameFilePath }; - - if (!collisionTagNamesFile.is_open()) - { - SHLOG_ERROR("Failed to open file for Collision Tag Names! Default tag names used!") - return; - } - - std::stringstream ss; - std::string line; - - int linesRead = 0; - while (std::getline(collisionTagNamesFile, line)) - { - // Do not read anything beyond the first 16 lines - if (linesRead >= 16) - break; - - ss << line; - ++linesRead; - - // First element is index. - int tagIndex; - ss >> tagIndex; - - // Next element is name of the tag - std::string tagName; - ss >> tagName; - - // If no tag name read, use default. - if (tagName.empty()) - { - SHLOG_ERROR - ( - "Collision tag file line {} does not match the required format of 'indextag name'. Default tag used for index {}" - , linesRead + 1 - , tagIndex - ) - - // Use default since - tagNames[tagIndex] = std::to_string(tagIndex + 1); - continue; - } - - tagNames[tagIndex] = tagName; - - ss.clear(); - } - - collisionTagNamesFile.close(); - } - - void SHCollisionTag::Exit(const std::filesystem::path& tagNameFilePath) noexcept - { - std::ofstream collisionTagNamesFile { tagNameFilePath }; - - if (!collisionTagNamesFile.is_open()) - { - SHLOG_ERROR("Failed to open file for Collision Tag Names! Tag names not saved!") - return; - } - - for (int i = 0; i < NUM_TAGS; ++i) - collisionTagNamesFile << i << " " << tagNames[i] << std::endl; - - collisionTagNamesFile.close(); - } - - void SHCollisionTag::UpdateTagNamesFromFile(const std::filesystem::path& tagNameFilePath) noexcept - { - std::ifstream collisionTagNamesFile { tagNameFilePath }; - - if (!collisionTagNamesFile.is_open()) - { - SHLOG_ERROR("Failed to open file for Collision Tag Names! Default tag names used!") - return; - } - - std::stringstream ss; - std::string line; - - int linesRead = 0; - while (std::getline(collisionTagNamesFile, line)) - { - // Do not read anything beyond the first 16 lines - if (linesRead >= 16) - break; - - ss << line; - ++linesRead; - - // First element is index. - int tagIndex; - ss >> tagIndex; - - // Next element is name of the tag - std::string tagName; - ss >> tagName; - - // If no tag name read, use default. - if (tagName.empty()) - { - SHLOG_ERROR - ( - "Collision tag file line {} does not match the required format of 'indextag name'. Name left unchanged for index {}" - , linesRead + 1 - , tagIndex - ) - - // Use default since - tagNames[tagIndex] = std::to_string(tagIndex + 1); - continue; - } - - tagNames[tagIndex] = tagName; - - ss.clear(); - } - - collisionTagNamesFile.close(); - } - - - void SHCollisionTag::RemoveTagName(int tagIndex) - { - if (tagIndex < 0 || tagIndex > NUM_TAGS) - throw std::invalid_argument("Index out of range!"); - - tagNames[tagIndex].clear(); - } - - void SHCollisionTag::SetTagName(const std::string& newTagName, int tagIndex) - { - if (tagIndex < 0 || tagIndex > NUM_TAGS) - throw std::invalid_argument("Index out of range!"); - - tagNames[tagIndex] = newTagName; - } - - const std::string& SHCollisionTag::GetTagName(int tagIndex) - { - if (tagIndex < 0 || tagIndex > NUM_TAGS) - throw std::invalid_argument("Index out of range!"); - - return tagNames[tagIndex]; + const auto VALUE = 1U << layerIndex; + state ? mask |= (VALUE) : mask &= ~(VALUE); } } // namespace SHADE -SHADE::SHCollisionTag::eTag operator|(SHADE::SHCollisionTag::eTag lhs, SHADE::SHCollisionTag::eTag rhs) noexcept +SHADE::SHCollisionTag::Layer operator|(SHADE::SHCollisionTag::Layer lhs, SHADE::SHCollisionTag::Layer rhs) noexcept { - return static_cast(SHADE::SHUtilities::ConvertEnum(lhs) | SHADE::SHUtilities::ConvertEnum(rhs)); + return static_cast(SHADE::SHUtilities::ConvertEnum(lhs) | SHADE::SHUtilities::ConvertEnum(rhs)); } \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Collision/SHCollisionTags.h b/SHADE_Engine/src/Physics/Collision/SHCollisionTags.h index 1b709837..9c7b4364 100644 --- a/SHADE_Engine/src/Physics/Collision/SHCollisionTags.h +++ b/SHADE_Engine/src/Physics/Collision/SHCollisionTags.h @@ -10,7 +10,7 @@ #pragma once -#include +#include // Project Headers #include "SH_API.h" @@ -28,34 +28,39 @@ namespace SHADE /* Type Definitions */ /*---------------------------------------------------------------------------------*/ - enum class eTag : uint16_t + enum class Layer : uint16_t { - TAG_1 = 0x0001 - , TAG_2 = 0x0002 - , TAG_3 = 0x0004 - , TAG_4 = 0x0008 - , TAG_5 = 0x0010 - , TAG_6 = 0x0020 - , TAG_7 = 0x0040 - , TAG_8 = 0x0080 - , TAG_9 = 0x0100 - , TAG_10 = 0x0200 - , TAG_11 = 0x0400 - , TAG_12 = 0x0800 - , TAG_13 = 0x1000 - , TAG_14 = 0x2000 - , TAG_15 = 0x4000 - , TAG_16 = 0x8000 - , ALL_TAGS = 0xFFFF + _1 = 0x0001 + , _2 = 0x0002 + , _3 = 0x0004 + , _4 = 0x0008 + , _5 = 0x0010 + , _6 = 0x0020 + , _7 = 0x0040 + , _8 = 0x0080 + , _9 = 0x0100 + , _10 = 0x0200 + , _11 = 0x0400 + , _12 = 0x0800 + , _13 = 0x1000 + , _14 = 0x2000 + , _15 = 0x4000 + , _16 = 0x8000 + , ALL = 0xFFFF }; + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + static constexpr int NUM_LAYERS = 16; + /*---------------------------------------------------------------------------------*/ /* Constructors & Destructor */ /*---------------------------------------------------------------------------------*/ - SHCollisionTag () noexcept; - SHCollisionTag (uint16_t tagValue) noexcept; - SHCollisionTag (eTag tagValue) noexcept; + SHCollisionTag () noexcept; + SHCollisionTag (uint16_t mask) noexcept; + SHCollisionTag (Layer layer) noexcept; SHCollisionTag (const SHCollisionTag&) noexcept = default; SHCollisionTag (SHCollisionTag&&) noexcept = default; @@ -77,50 +82,31 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] uint16_t GetTagValue () const noexcept; - [[nodiscard]] bool GetTagState (eTag tag) const noexcept; - [[nodiscard]] bool GetTagState (int tagIndex) const; + [[nodiscard]] uint16_t GetMask () const noexcept; + [[nodiscard]] const std::string& GetName () const noexcept; + [[nodiscard]] bool GetLayerState (Layer layer) const noexcept; + [[nodiscard]] bool GetLayerState (int layerIndex) const; /*---------------------------------------------------------------------------------*/ /* Setter Functions */ /*---------------------------------------------------------------------------------*/ - void SetValue (uint16_t tagValue) noexcept; - - void SetTagState (eTag tag, bool tagState) noexcept; - void SetTagState (const std::string& tagName, bool tagState) noexcept; - void SetTagState (int tagIndex, bool tagState); - - /*---------------------------------------------------------------------------------*/ - /* Function Members */ - /*---------------------------------------------------------------------------------*/ - - static void Init (const std::filesystem::path& tagNameFilePath) noexcept; - static void Exit (const std::filesystem::path& tagNameFilePath) noexcept; - static void UpdateTagNamesFromFile(const std::filesystem::path& tagNameFilePath) noexcept; - - static void SetTagName (const std::string& newTagName, int tagIndex); - static void RemoveTagName (int tagIndex); - - [[nodiscard]] static const std::string& GetTagName (int tagIndex); + void SetMask (uint16_t newMask) noexcept; + void SetName (const std::string_view& newName) noexcept; + void SetLayerState (Layer layer, bool state) noexcept; + void SetLayerState (int layerIndex, bool state); private: - /*---------------------------------------------------------------------------------*/ - /* Static Data Members */ - /*---------------------------------------------------------------------------------*/ - - static constexpr int NUM_TAGS = 16; - static std::string tagNames[NUM_TAGS]; - /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ - uint16_t mask; + uint16_t mask; + std::string name; }; } // namespace SHADE -SHADE::SHCollisionTag::eTag SH_API operator|(SHADE::SHCollisionTag::eTag lhs, SHADE::SHCollisionTag::eTag rhs) noexcept; +SHADE::SHCollisionTag::Layer SH_API operator|(SHADE::SHCollisionTag::Layer lhs, SHADE::SHCollisionTag::Layer rhs) noexcept; diff --git a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp index 745d64c5..11106cf8 100644 --- a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp @@ -134,9 +134,9 @@ namespace SHADE return type; } - const SHCollisionTag& SHCollisionShape::GetCollisionTags() const noexcept + const SHCollisionTag& SHCollisionShape::GetCollisionTag() const noexcept { - return collisionTags; + return collisionTag; } float SHCollisionShape::GetFriction() const noexcept @@ -245,10 +245,10 @@ namespace SHADE isTrigger = trigger; } - void SHCollisionShape::SetCollisionTags(const SHCollisionTag& newCollisionTag) noexcept + void SHCollisionShape::SetCollisionTag(const SHCollisionTag& newCollisionTag) noexcept { dirty = true; - collisionTags = newCollisionTag; + collisionTag = newCollisionTag; } void SHCollisionShape::SetFriction(float friction) noexcept diff --git a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.h b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.h index fd08e55d..09793026 100644 --- a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.h +++ b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.h @@ -75,7 +75,7 @@ namespace SHADE [[nodiscard]] Type GetType () const noexcept; - [[nodiscard]] const SHCollisionTag& GetCollisionTags () const noexcept; + [[nodiscard]] const SHCollisionTag& GetCollisionTag () const noexcept; [[nodiscard]] float GetFriction () const noexcept; [[nodiscard]] float GetBounciness () const noexcept; @@ -95,7 +95,7 @@ namespace SHADE void SetBoundingSphere (float radius); void SetIsTrigger (bool isTrigger) noexcept; - void SetCollisionTags (const SHCollisionTag& newCollisionTag) noexcept; + void SetCollisionTag (const SHCollisionTag& newCollisionTag) noexcept; void SetFriction (float friction) noexcept; void SetBounciness (float bounciness) noexcept; void SetDensity (float density) noexcept; @@ -113,7 +113,7 @@ namespace SHADE EntityID entityID; // The entity this collider belongs to bool isTrigger; bool dirty; - SHCollisionTag collisionTags; + SHCollisionTag collisionTag; SHShape* shape; SHPhysicsMaterial material; SHVec3 positionOffset; diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp index ea3d5996..8de928f0 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp @@ -322,7 +322,7 @@ namespace SHADE rp3dMaterial.setMassDensity(collisionShape.GetDensity()); // Sync tags - const unsigned short MASK_BITS = collisionShape.GetCollisionTags(); + const unsigned short MASK_BITS = collisionShape.GetCollisionTag(); rp3dCollider->setCollisionCategoryBits(MASK_BITS); rp3dCollider->setCollideWithMaskBits(MASK_BITS); diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp index 17f27eaf..b2f618a7 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp @@ -19,6 +19,7 @@ #include "ECS_Base/Managers/SHEntityManager.h" #include "ECS_Base/Managers/SHSystemManager.h" #include "Editor/SHEditor.h" +#include "Physics/Collision/SHCollisionTagMatrix.h" #include "Physics/SHPhysicsEvents.h" #include "Scene/SHSceneManager.h" #include "Scripting/SHScriptEngine.h" @@ -87,7 +88,7 @@ namespace SHADE void SHPhysicsSystem::SetCollisionTagFile(const std::filesystem::path& tagNamesFilePath) noexcept { - SHCollisionTag::UpdateTagNamesFromFile(tagNamesFilePath); + SHCollisionTagMatrix::UpdateTagNamesFromFile(tagNamesFilePath); } @@ -100,7 +101,7 @@ namespace SHADE // Initialise collision tags std::filesystem::path defaultCollisionTagNameFilePath { ASSET_ROOT }; defaultCollisionTagNameFilePath.append("CollisionTags.SHConfig"); - SHCollisionTag::Init(defaultCollisionTagNameFilePath); + SHCollisionTagMatrix::Init(defaultCollisionTagNameFilePath); // Subscribe to component events const std::shared_ptr ADD_COMPONENT_RECEIVER { std::make_shared>(this, &SHPhysicsSystem::addPhysicsComponent) }; @@ -138,7 +139,7 @@ namespace SHADE // Write collision tag names to file std::filesystem::path defaultCollisionTagNameFilePath { ASSET_ROOT }; defaultCollisionTagNameFilePath.append("CollisionTags.SHConfig"); - SHCollisionTag::Exit(defaultCollisionTagNameFilePath); + SHCollisionTagMatrix::Exit(defaultCollisionTagNameFilePath); } void SHPhysicsSystem::ForceUpdate() From cada3acb8ab4506f77dcadfa97e6496025b31521 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sun, 20 Nov 2022 18:30:08 +0800 Subject: [PATCH 06/14] Collision tags should be referenced by pointers --- .../Collision/SHCollisionTagMatrix.cpp | 72 ++++++------------- .../Physics/Collision/SHCollisionTagMatrix.h | 8 ++- .../Physics/Interface/SHCollisionShape.cpp | 26 ++++--- .../src/Physics/Interface/SHCollisionShape.h | 7 +- 4 files changed, 48 insertions(+), 65 deletions(-) diff --git a/SHADE_Engine/src/Physics/Collision/SHCollisionTagMatrix.cpp b/SHADE_Engine/src/Physics/Collision/SHCollisionTagMatrix.cpp index ce6cd900..b687c6ca 100644 --- a/SHADE_Engine/src/Physics/Collision/SHCollisionTagMatrix.cpp +++ b/SHADE_Engine/src/Physics/Collision/SHCollisionTagMatrix.cpp @@ -46,6 +46,26 @@ namespace SHADE return -1; } + SHCollisionTag* SHCollisionTagMatrix::GetTag(int tagIndex) + { + if (tagIndex < 0 || tagIndex > SHCollisionTag::NUM_LAYERS) + throw std::invalid_argument("Index out of range!"); + + return &collisionTags[tagIndex]; + } + + SHCollisionTag* SHCollisionTagMatrix::GetTag(const std::string& tagName) noexcept + { + for (int i = 0; i < SHCollisionTag::NUM_LAYERS; ++i) + { + if (collisionTags[i].GetName() == tagName) + return &collisionTags[i]; + } + + SHLOGV_WARNING("Collision Tag {} cannot be found!", tagName) + return nullptr; + } + /*-----------------------------------------------------------------------------------*/ /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -200,56 +220,4 @@ namespace SHADE collisionTagNamesFile.close(); } - - void SHCollisionTagMatrix::UpdateTagNamesFromFile(const std::filesystem::path& tagNameFilePath) noexcept - { - std::ifstream collisionTagNamesFile { tagNameFilePath }; - - if (!collisionTagNamesFile.is_open()) - { - SHLOG_ERROR("Failed to open file for Collision Tag Names! Default tag names used!") - return; - } - - std::stringstream ss; - std::string line; - - int linesRead = 0; - while (std::getline(collisionTagNamesFile, line)) - { - // Do not read anything beyond the first 16 lines - if (linesRead >= 16) - break; - - ss << line; - ++linesRead; - - // First element is index. - int tagIndex; - ss >> tagIndex; - - // Next element is name of the tag - std::string tagName; - ss >> tagName; - - // If no tag name read, use default. - if (tagName.empty()) - { - SHLOG_ERROR - ( - "Collision tag file line {} does not match the required format of 'indextag name'. Name left unchanged for index {}" - , linesRead + 1 - , tagIndex - ) - - continue; - } - - collisionTags[tagIndex].SetName(tagName); - - ss.clear(); - } - - collisionTagNamesFile.close(); - } } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Collision/SHCollisionTagMatrix.h b/SHADE_Engine/src/Physics/Collision/SHCollisionTagMatrix.h index eac23ebb..90018fe4 100644 --- a/SHADE_Engine/src/Physics/Collision/SHCollisionTagMatrix.h +++ b/SHADE_Engine/src/Physics/Collision/SHCollisionTagMatrix.h @@ -29,8 +29,11 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] static const std::string& GetTagName (int tagIndex); - [[nodiscard]] static int GetTagIndex (const std::string& tagName) noexcept; + [[nodiscard]] static const std::string& GetTagName (int tagIndex); + [[nodiscard]] static int GetTagIndex (const std::string& tagName) noexcept; + + [[nodiscard]] static SHCollisionTag* GetTag (int tagIndex); + [[nodiscard]] static SHCollisionTag* GetTag (const std::string& tagName) noexcept; /*---------------------------------------------------------------------------------*/ /* Setter Functions */ @@ -53,7 +56,6 @@ namespace SHADE static void Init (const std::filesystem::path& tagNameFilePath) noexcept; static void Exit (const std::filesystem::path& tagNameFilePath) noexcept; - static void UpdateTagNamesFromFile (const std::filesystem::path& tagNameFilePath) noexcept; private: /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp index 11106cf8..c8a082a5 100644 --- a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp @@ -16,6 +16,7 @@ #include "Math/Geometry/SHBox.h" #include "Math/Geometry/SHSphere.h" #include "Math/SHMathHelpers.h" +#include "Physics/Collision/SHCollisionTagMatrix.h" #include "Reflection/SHReflectionMetadata.h" #include "SHColliderComponent.h" @@ -26,12 +27,13 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHCollisionShape::SHCollisionShape(EntityID eid, Type colliderType, const SHPhysicsMaterial& physicsMaterial) - : type { colliderType } - , entityID { eid } - , isTrigger { false } - , dirty { true } - , shape { nullptr } - , material { physicsMaterial } + : type { colliderType } + , entityID { eid } + , isTrigger { false } + , dirty { true } + , shape { nullptr } + , material { physicsMaterial } + , collisionTag { SHCollisionTagMatrix::GetTag(0) } { switch (type) { @@ -57,6 +59,8 @@ namespace SHADE , shape { nullptr } , material { rhs.material } , positionOffset { rhs.positionOffset } + , rotationOffset { rhs.rotationOffset } + , collisionTag { rhs.collisionTag } { CopyShape(rhs.shape); } @@ -69,6 +73,8 @@ namespace SHADE , shape { nullptr } , material { rhs.material } , positionOffset { rhs.positionOffset } + , rotationOffset { rhs.rotationOffset } + , collisionTag { rhs.collisionTag } { CopyShape(rhs.shape); } @@ -93,6 +99,8 @@ namespace SHADE dirty = true; material = rhs.material; positionOffset = rhs.positionOffset; + rotationOffset = rhs.rotationOffset; + collisionTag = rhs.collisionTag; delete shape; CopyShape(rhs.shape); @@ -108,6 +116,8 @@ namespace SHADE dirty = true; material = rhs.material; positionOffset = rhs.positionOffset; + rotationOffset = rhs.rotationOffset; + collisionTag = rhs.collisionTag; delete shape; CopyShape(rhs.shape); @@ -136,7 +146,7 @@ namespace SHADE const SHCollisionTag& SHCollisionShape::GetCollisionTag() const noexcept { - return collisionTag; + return *collisionTag; } float SHCollisionShape::GetFriction() const noexcept @@ -245,7 +255,7 @@ namespace SHADE isTrigger = trigger; } - void SHCollisionShape::SetCollisionTag(const SHCollisionTag& newCollisionTag) noexcept + void SHCollisionShape::SetCollisionTag(SHCollisionTag* newCollisionTag) noexcept { dirty = true; collisionTag = newCollisionTag; diff --git a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.h b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.h index 09793026..597814a6 100644 --- a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.h +++ b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.h @@ -95,7 +95,7 @@ namespace SHADE void SetBoundingSphere (float radius); void SetIsTrigger (bool isTrigger) noexcept; - void SetCollisionTag (const SHCollisionTag& newCollisionTag) noexcept; + void SetCollisionTag (SHCollisionTag* newCollisionTag) noexcept; void SetFriction (float friction) noexcept; void SetBounciness (float bounciness) noexcept; void SetDensity (float density) noexcept; @@ -113,12 +113,15 @@ namespace SHADE EntityID entityID; // The entity this collider belongs to bool isTrigger; bool dirty; - SHCollisionTag collisionTag; + SHShape* shape; SHPhysicsMaterial material; + SHVec3 positionOffset; SHVec3 rotationOffset; + SHCollisionTag* collisionTag; + /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ From d4ad60ea7974ea8ec6111421cf0b063cdc7c6625 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sun, 20 Nov 2022 20:12:20 +0800 Subject: [PATCH 07/14] Fix compile error with collision tags --- SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp | 6 ------ SHADE_Engine/src/Physics/System/SHPhysicsSystem.h | 1 - 2 files changed, 7 deletions(-) diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp index b2f618a7..396edd93 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp @@ -86,12 +86,6 @@ namespace SHADE worldState.UpdateSettings(); } - void SHPhysicsSystem::SetCollisionTagFile(const std::filesystem::path& tagNamesFilePath) noexcept - { - SHCollisionTagMatrix::UpdateTagNamesFromFile(tagNamesFilePath); - } - - /*-----------------------------------------------------------------------------------*/ /* Public Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h index 89ecb51e..f92be4cd 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h @@ -69,7 +69,6 @@ namespace SHADE void SetFixedUpdateRate (double fixedUpdateRate) noexcept; void SetWorldSettings (const SHPhysicsWorldState::WorldSettings& settings) noexcept; - void SetCollisionTagFile (const std::filesystem::path& tagNamesFilePath) noexcept; /*---------------------------------------------------------------------------------*/ /* Function Members */ From 1666a0113b5c79a17075f617e515567e3910f644 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Mon, 21 Nov 2022 00:29:46 +0800 Subject: [PATCH 08/14] Removed test lines for shader compile in graphics system --- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 160e82c6..a2276ed6 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -119,13 +119,12 @@ namespace SHADE SHFreetypeInstance::Init(); - SHAssetManager::CompileAsset("../../Assets/Shaders/Text_VS.glsl", false); - SHAssetManager::CompileAsset("../../Assets/Shaders/Text_FS.glsl", false); - SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_VS.glsl", false); - SHAssetManager::CompileAsset("../../Assets/Shaders/UI_VS.glsl", false); - SHAssetManager::CompileAsset("../../Assets/Shaders/UI_FS.glsl", false); - - SHAssetManager::CompileAsset("../../Assets/Models/Quad.gltf", false); + //SHAssetManager::CompileAsset("../../Assets/Shaders/Text_VS.glsl", false); + //SHAssetManager::CompileAsset("../../Assets/Shaders/Text_FS.glsl", false); + //SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_VS.glsl", false); + //SHAssetManager::CompileAsset("../../Assets/Shaders/UI_VS.glsl", false); + //SHAssetManager::CompileAsset("../../Assets/Shaders/UI_FS.glsl", false); + //SHAssetManager::CompileAsset("../../Assets/Models/Quad.gltf", false); // Load Built In Shaders static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet(VS_DEFAULT); From 0a9dea1c83b83dca0b0ce53856626d84eee5b712 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 21 Nov 2022 12:14:07 +0800 Subject: [PATCH 09/14] Disabled xmldoc generation warnings for SHADE projects --- SHADE_Application/premake5.lua | 5 ++++- SHADE_Engine/premake5.lua | 5 ++++- SHADE_Managed/premake5.lua | 6 +++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/SHADE_Application/premake5.lua b/SHADE_Application/premake5.lua index faa741a6..014df726 100644 --- a/SHADE_Application/premake5.lua +++ b/SHADE_Application/premake5.lua @@ -78,7 +78,10 @@ project "SHADE_Application" "26451", "26437", "4275", - "4635" + "4633", + "4634", + "4635", + "4638" } linkoptions { "-IGNORE:4006" } diff --git a/SHADE_Engine/premake5.lua b/SHADE_Engine/premake5.lua index 88df50d7..7fb7291d 100644 --- a/SHADE_Engine/premake5.lua +++ b/SHADE_Engine/premake5.lua @@ -79,7 +79,10 @@ project "SHADE_Engine" "26451", "26437", "4275", - "4635" + "4633", + "4634", + "4635", + "4638" } linkoptions { "-IGNORE:4006" } diff --git a/SHADE_Managed/premake5.lua b/SHADE_Managed/premake5.lua index 2384cae8..70b01e18 100644 --- a/SHADE_Managed/premake5.lua +++ b/SHADE_Managed/premake5.lua @@ -62,7 +62,11 @@ project "SHADE_Managed" disablewarnings { - "4251" + "4251", + "4633", + "4634", + "4635", + "4638" } defines From 819607925ff45b5b0febfaa9764789fa8f0fd441 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 21 Nov 2022 15:41:15 +0800 Subject: [PATCH 10/14] Added GameObject.Null for setting GameObjects to null. --- SHADE_Managed/src/Engine/GameObject.cxx | 8 ++++++++ SHADE_Managed/src/Engine/GameObject.hxx | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/SHADE_Managed/src/Engine/GameObject.cxx b/SHADE_Managed/src/Engine/GameObject.cxx index 200b2079..3557e8f1 100644 --- a/SHADE_Managed/src/Engine/GameObject.cxx +++ b/SHADE_Managed/src/Engine/GameObject.cxx @@ -54,6 +54,14 @@ namespace SHADE return GameObject(ENTITY_ID); } + /*---------------------------------------------------------------------------------*/ + /* Static Properties */ + /*---------------------------------------------------------------------------------*/ + GameObject GameObject::Null::get() + { + return GameObject(); + } + /*---------------------------------------------------------------------------------*/ /* Properties */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Engine/GameObject.hxx b/SHADE_Managed/src/Engine/GameObject.hxx index 64d1b428..1ebfc250 100644 --- a/SHADE_Managed/src/Engine/GameObject.hxx +++ b/SHADE_Managed/src/Engine/GameObject.hxx @@ -62,6 +62,17 @@ namespace SHADE /// GameObject that has the specified name. Null if not found. static System::Nullable Find(System::String^ name); + /*-----------------------------------------------------------------------------*/ + /* Static Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Default empty GameObject. + /// + static property GameObject Null + { + GameObject get(); + } + /*-----------------------------------------------------------------------------*/ /* Properties */ /*-----------------------------------------------------------------------------*/ From e3c573baa7764ab081427e0b83a37eddf00c3fd3 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 21 Nov 2022 17:16:16 +0800 Subject: [PATCH 11/14] Added support for enabling and disabling scripts OnEnable and OnDisable are not called on GameObject active toggling for now but will be added in future --- SHADE_Engine/src/Editor/SHEditorUI.cpp | 141 ++++++++++++++-------- SHADE_Managed/src/Editor/Editor.cxx | 6 + SHADE_Managed/src/Scripts/Script.cxx | 47 +++++++- SHADE_Managed/src/Scripts/Script.hxx | 46 ++++++- SHADE_Managed/src/Scripts/ScriptStore.cxx | 12 +- 5 files changed, 188 insertions(+), 64 deletions(-) diff --git a/SHADE_Engine/src/Editor/SHEditorUI.cpp b/SHADE_Engine/src/Editor/SHEditorUI.cpp index 40e08042..9fdcbde7 100644 --- a/SHADE_Engine/src/Editor/SHEditorUI.cpp +++ b/SHADE_Engine/src/Editor/SHEditorUI.cpp @@ -4,9 +4,9 @@ \par email: kahwei.tng\@digipen.edu \date Nov 7, 2021 \brief Contains the implementation of the EditorUI class. - + Copyright (C) 2021 DigiPen Institute of Technology. -Reproduction or disclosure of this file or its contents without the prior written consent +Reproduction or disclosure of this file or its contents without the prior written consent of DigiPen Institute of Technology is prohibited. *//*************************************************************************************/ // Precompiled Header @@ -57,10 +57,10 @@ namespace SHADE { const bool OPENED = ImGui::CollapsingHeader(title.c_str(), ImGuiTreeNodeFlags_DefaultOpen); if (isHovered) - *isHovered = ImGui::IsItemHovered(); + *isHovered = ImGui::IsItemHovered(); return OPENED; } - + void SHEditorUI::SameLine() { ImGui::SameLine(); @@ -98,7 +98,7 @@ namespace SHADE void SHEditorUI::EndTooltip() { - ImGui::EndTooltip(); + ImGui::EndTooltip(); } /*-----------------------------------------------------------------------------------*/ @@ -146,7 +146,7 @@ namespace SHADE bool SHEditorUI::Selectable(const std::string& label) { - return ImGui::Selectable(label.data()); + return ImGui::Selectable(label.data()); } bool SHEditorUI::Selectable(const std::string& label, const char* icon) @@ -156,30 +156,41 @@ namespace SHADE bool SHEditorUI::InputCheckbox(const std::string& label, bool& value, bool* isHovered) { - ImGui::Text(label.c_str()); + if (!label.empty()) + { + ImGui::Text(label.c_str()); + ImGui::SameLine(); + } if (isHovered) - *isHovered = ImGui::IsItemHovered(); - ImGui::SameLine(); + *isHovered = ImGui::IsItemHovered(); return ImGui::Checkbox("##", &value); } bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered) { - ImGui::Text(label.c_str()); + if (!label.empty()) + { + ImGui::Text(label.c_str()); + ImGui::SameLine(); + } if (isHovered) - *isHovered = ImGui::IsItemHovered(); + *isHovered = ImGui::IsItemHovered(); ImGui::SameLine(); return ImGui::DragInt("##", &value, 0.001f, - std::numeric_limits::min(), - std::numeric_limits::max(), - "%d", - ImGuiInputTextFlags_EnterReturnsTrue); + std::numeric_limits::min(), + std::numeric_limits::max(), + "%d", + ImGuiInputTextFlags_EnterReturnsTrue); } bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered) { int signedVal = static_cast(value); - ImGui::Text(label.c_str()); + if (!label.empty()) + { + ImGui::Text(label.c_str()); + ImGui::SameLine(); + } if (isHovered) - *isHovered = ImGui::IsItemHovered(); + *isHovered = ImGui::IsItemHovered(); ImGui::SameLine(); const bool CHANGED = InputInt("##", signedVal); if (CHANGED) @@ -191,15 +202,19 @@ namespace SHADE } bool SHEditorUI::InputFloat(const std::string& label, float& value, bool* isHovered) { - ImGui::Text(label.c_str()); + if (!label.empty()) + { + ImGui::Text(label.c_str()); + ImGui::SameLine(); + } if (isHovered) - *isHovered = ImGui::IsItemHovered(); + *isHovered = ImGui::IsItemHovered(); ImGui::SameLine(); return ImGui::DragFloat("##", &value, 0.001f, - std::numeric_limits::lowest(), - std::numeric_limits::max(), - "%.3f", - ImGuiInputTextFlags_EnterReturnsTrue); + std::numeric_limits::lowest(), + std::numeric_limits::max(), + "%.3f", + ImGuiInputTextFlags_EnterReturnsTrue); } bool SHEditorUI::InputDouble(const std::string& label, double& value, bool* isHovered) { @@ -213,48 +228,56 @@ namespace SHADE } bool SHEditorUI::InputSlider(const std::string& label, int min, int max, int& value, bool* isHovered /*= nullptr*/) { + if (!label.empty()) + { ImGui::Text(label.c_str()); - if (isHovered) - *isHovered = ImGui::IsItemHovered(); ImGui::SameLine(); - return ImGui::SliderInt("##", &value, - static_cast(min), static_cast(max), "%d", - ImGuiInputTextFlags_EnterReturnsTrue); + } + if (isHovered) + *isHovered = ImGui::IsItemHovered(); + ImGui::SameLine(); + return ImGui::SliderInt("##", &value, + static_cast(min), static_cast(max), "%d", + ImGuiInputTextFlags_EnterReturnsTrue); } bool SHEditorUI::InputSlider(const std::string& label, unsigned int min, unsigned int max, unsigned int& value, bool* isHovered /*= nullptr*/) { - int val = static_cast(value); - const bool CHANGED = InputSlider(label, min, max, val, isHovered); - if (CHANGED) - { - value = static_cast(val); - } + int val = static_cast(value); + const bool CHANGED = InputSlider(label, min, max, val, isHovered); + if (CHANGED) + { + value = static_cast(val); + } - return CHANGED; + return CHANGED; } bool SHEditorUI::InputSlider(const std::string& label, float min, float max, float& value, bool* isHovered) { + if (!label.empty()) + { ImGui::Text(label.c_str()); - if (isHovered) - *isHovered = ImGui::IsItemHovered(); ImGui::SameLine(); - return ImGui::SliderFloat("##", &value, - static_cast(min), static_cast(max), "%.3f", - ImGuiInputTextFlags_EnterReturnsTrue); + } + if (isHovered) + *isHovered = ImGui::IsItemHovered(); + ImGui::SameLine(); + return ImGui::SliderFloat("##", &value, + static_cast(min), static_cast(max), "%.3f", + ImGuiInputTextFlags_EnterReturnsTrue); } bool SHEditorUI::InputSlider(const std::string& label, double min, double max, double& value, bool* isHovered /*= nullptr*/) { - float val = static_cast(value); - const bool CHANGED = InputSlider(label, min, max, val, isHovered); - if (CHANGED) - { - value = static_cast(val); - } + float val = static_cast(value); + const bool CHANGED = InputSlider(label, min, max, val, isHovered); + if (CHANGED) + { + value = static_cast(val); + } - return CHANGED; + return CHANGED; } bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value, bool* isHovered) @@ -264,7 +287,7 @@ namespace SHADE } bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, bool* isHovered) { - static const std::vector COMPONENT_LABELS = { "X", "Y", "Z"}; + static const std::vector COMPONENT_LABELS = { "X", "Y", "Z" }; return SHEditorWidgets::DragN(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, 0.1f, "%.3f", float{}, float{}, 0, isHovered); } @@ -272,9 +295,13 @@ namespace SHADE { std::array buffer = { '\0' }; strcpy_s(buffer.data(), TEXT_FIELD_MAX_LENGTH, value.c_str()); - ImGui::Text(label.c_str()); + if (!label.empty()) + { + ImGui::Text(label.c_str()); + ImGui::SameLine(); + } if (isHovered) - *isHovered = ImGui::IsItemHovered(); + *isHovered = ImGui::IsItemHovered(); ImGui::SameLine(); const bool CHANGED = ImGui::InputText("##", &buffer[0], TEXT_FIELD_MAX_LENGTH); if (CHANGED) @@ -286,7 +313,11 @@ namespace SHADE bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered, bool alwaysNull) { - ImGui::Text(label.c_str()); + if (!label.empty()) + { + ImGui::Text(label.c_str()); + ImGui::SameLine(); + } if (isHovered) *isHovered = ImGui::IsItemHovered(); ImGui::SameLine(); @@ -326,9 +357,13 @@ namespace SHADE const std::string& INITIAL_NAME = v >= static_cast(enumNames.size()) ? "Unknown" : enumNames[v]; bool b = false; - ImGui::Text(label.c_str()); + if (!label.empty()) + { + ImGui::Text(label.c_str()); + ImGui::SameLine(); + } if (isHovered) - *isHovered = ImGui::IsItemHovered(); + *isHovered = ImGui::IsItemHovered(); ImGui::SameLine(); if (ImGui::BeginCombo("##", INITIAL_NAME.c_str(), ImGuiComboFlags_None)) { diff --git a/SHADE_Managed/src/Editor/Editor.cxx b/SHADE_Managed/src/Editor/Editor.cxx index 7b2e0982..beb667e3 100644 --- a/SHADE_Managed/src/Editor/Editor.cxx +++ b/SHADE_Managed/src/Editor/Editor.cxx @@ -117,6 +117,12 @@ namespace SHADE // Header SHEditorUI::PushID(index); + bool enabled = script->Enabled; + if (SHEditorUI::InputCheckbox("", enabled)) + { + script->Enabled = enabled; + } + SHEditorUI::SameLine(); if (SHEditorUI::CollapsingHeader(LABEL)) { SHEditorUI::PushID(LABEL); diff --git a/SHADE_Managed/src/Scripts/Script.cxx b/SHADE_Managed/src/Scripts/Script.cxx index a2af38a3..2ee7dbf7 100644 --- a/SHADE_Managed/src/Scripts/Script.cxx +++ b/SHADE_Managed/src/Scripts/Script.cxx @@ -22,6 +22,36 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + GameObject Script::Owner::get() + { + return owner; + } + GameObject Script::GameObject::get() + { + return owner; + } + bool Script::Enabled::get() + { + return enabled; + } + void Script::Enabled::set(bool value) + { + // Same, don't set + if (value == enabled) + return; + + enabled = value; + + // There's a change, so call the appropriate function + if (enabled) + OnEnable(); + else + OnDisable(); + } + /*---------------------------------------------------------------------------------*/ /* Component Access Functions */ /*---------------------------------------------------------------------------------*/ @@ -104,11 +134,10 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* "All-time" Lifecycle Functions */ /*---------------------------------------------------------------------------------*/ - void Script::Initialize(GameObject newOwner) + void Script::Initialize(SHADE::GameObject newOwner) { owner = newOwner; } - void Script::OnAttached() { SAFE_NATIVE_CALL_BEGIN @@ -131,6 +160,12 @@ namespace SHADE awake(); SAFE_NATIVE_CALL_END(this) } + void Script::OnEnable() + { + SAFE_NATIVE_CALL_BEGIN + onEnable(); + SAFE_NATIVE_CALL_END(this) + } void Script::Start() { SAFE_NATIVE_CALL_BEGIN @@ -162,6 +197,12 @@ namespace SHADE onDrawGizmos(); SAFE_NATIVE_CALL_END(this) } + void Script::OnDisable() + { + SAFE_NATIVE_CALL_BEGIN + onDisable(); + SAFE_NATIVE_CALL_END(this) + } void Script::OnDestroy() { SAFE_NATIVE_CALL_BEGIN @@ -228,6 +269,7 @@ namespace SHADE /* Virtual Lifecycle Functions */ /*---------------------------------------------------------------------------------*/ void Script::awake() {} + void Script::onEnable() {} void Script::start() {} void Script::fixedUpdate() {} void Script::update() {} @@ -236,6 +278,7 @@ namespace SHADE { OnGizmosDrawOverriden = false; } + void Script::onDisable() {} void Script::onDestroy() {} /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Scripts/Script.hxx b/SHADE_Managed/src/Scripts/Script.hxx index 46736245..62c5015c 100644 --- a/SHADE_Managed/src/Scripts/Script.hxx +++ b/SHADE_Managed/src/Scripts/Script.hxx @@ -38,11 +38,28 @@ namespace SHADE /* Properties */ /*-----------------------------------------------------------------------------*/ /// + /// GameObject that this Script belongs to. This is a legacy interface, use + /// GameObject instead. + /// + [System::ObsoleteAttribute("Use GameObject instead.", false)] + property SHADE::GameObject Owner + { + SHADE::GameObject get(); + } + /// /// GameObject that this Script belongs to. /// - property GameObject Owner + property SHADE::GameObject GameObject { - GameObject get() { return owner; } + SHADE::GameObject get(); + } + /// + /// Whether or not this Script should have it's update functions be executed. + /// + property bool Enabled + { + bool get(); + void set(bool value); } /*-----------------------------------------------------------------------------*/ @@ -127,7 +144,7 @@ namespace SHADE /// /// /// Type of script to get. - /// This needs to be a default constructable Script. + /// This needs to be a default constructible Script. /// /// Reference to the script added generic where T : ref class, Script @@ -206,7 +223,7 @@ namespace SHADE /// /// Used to initialize a Script with a GameObject. /// - void Initialize(GameObject newOwner); + void Initialize(SHADE::GameObject newOwner); /// /// Used to call onAttached(). This is called immediately when this script is /// attached to a GameObject. @@ -232,6 +249,11 @@ namespace SHADE /// void Start(); /// + /// Used to call onEnable. This should be called right when a script is enabled + /// directly. + /// + void OnEnable(); + /// /// Used to call fixedUpdate(). This should be called in sync with Physics /// update steps and thus in most cases will execute more than Update() will. /// This will be called immediately before a Physics update step. @@ -253,6 +275,11 @@ namespace SHADE /// void OnDrawGizmos(); /// + /// Used to call onDisable. This should be called right when a script is disabled + /// directly. + /// + void OnDisable(); + /// /// Used to call onDestroy(). This should be called at the end of the frame /// where the attached GameObject or this script is destroyed directly or /// indirectly due to destruction of the owner. @@ -329,6 +356,10 @@ namespace SHADE /// virtual void awake(); /// + /// Called when this script is enabled. + /// + virtual void onEnable(); + /// /// Called on the first frame that the attached GameObject is active but always /// after Awake(). /// @@ -353,6 +384,10 @@ namespace SHADE /// virtual void onDrawGizmos(); /// + /// Called when this script is disabled. + /// + virtual void onDisable(); + /// /// Called just before the end of the frame where the attached GameObject or /// this script is destroyed directly or indirectly due to destruction of the /// owner. @@ -403,7 +438,8 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ - GameObject owner; + SHADE::GameObject owner; + bool enabled = true; }; } diff --git a/SHADE_Managed/src/Scripts/ScriptStore.cxx b/SHADE_Managed/src/Scripts/ScriptStore.cxx index 29ba6e52..96eb7361 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.cxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.cxx @@ -528,7 +528,8 @@ namespace SHADE ScriptList^ scripts = entity.Value; for (int i = 0; i < scripts->Count; ++i) { - scripts[i]->FixedUpdate(); + if (scripts[i]->Enabled) + scripts[i]->FixedUpdate(); } } SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") @@ -546,7 +547,8 @@ namespace SHADE ScriptList^ scripts = entity.Value; for (int i = 0; i < scripts->Count; ++i) { - scripts[i]->Update(); + if (scripts[i]->Enabled) + scripts[i]->Update(); } } SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") @@ -564,7 +566,8 @@ namespace SHADE ScriptList^ scripts = entity.Value; for (int i = 0; i < scripts->Count; ++i) { - scripts[i]->LateUpdate(); + if (scripts[i]->Enabled) + scripts[i]->LateUpdate(); } } SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") @@ -583,7 +586,8 @@ namespace SHADE ScriptList^ scripts = entity.Value; for (int i = 0; i < scripts->Count; ++i) { - scripts[i]->OnDrawGizmos(); + if (scripts[i]->Enabled) + scripts[i]->OnDrawGizmos(); } } SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") From 1d692d330113a2d56d68d43071fc9f39039dd53b Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 21 Nov 2022 19:59:32 +0800 Subject: [PATCH 12/14] Physics works without SHEDITOR defines. Mass is temporarily auto computed. --- SHADE_Application/premake5.lua | 2 +- .../src/Application/SBApplication.cpp | 20 ++++- SHADE_Application/src/Scenes/SBMainScene.cpp | 10 +++ .../Inspector/SHEditorComponentView.hpp | 3 +- .../Physics/Interface/SHColliderComponent.cpp | 8 ++ .../Interface/SHRigidBodyComponent.cpp | 39 +++++---- .../Physics/Interface/SHRigidBodyComponent.h | 2 +- .../Physics/PhysicsObject/SHPhysicsObject.cpp | 27 +++++-- .../Physics/PhysicsObject/SHPhysicsObject.h | 12 +-- .../System/SHPhysicsDebugDrawSystem.cpp | 56 ++++++++++--- .../Physics/System/SHPhysicsDebugDrawSystem.h | 14 ++-- .../src/Physics/System/SHPhysicsSystem.cpp | 79 ++++++++++++++++--- .../src/Physics/System/SHPhysicsSystem.h | 20 ++--- .../{SHSceneGraphEvents.h => SHSceneEvents.h} | 18 ++--- SHADE_Engine/src/Scene/SHSceneGraph.h | 2 +- SHADE_Engine/src/Scene/SHSceneManager.cpp | 1 - SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 2 +- .../src/Serialization/SHYAMLConverters.h | 4 + SHADE_Managed/src/Components/RigidBody.cxx | 2 +- 19 files changed, 237 insertions(+), 84 deletions(-) rename SHADE_Engine/src/Scene/{SHSceneGraphEvents.h => SHSceneEvents.h} (72%) diff --git a/SHADE_Application/premake5.lua b/SHADE_Application/premake5.lua index faa741a6..c2312805 100644 --- a/SHADE_Application/premake5.lua +++ b/SHADE_Application/premake5.lua @@ -87,7 +87,7 @@ project "SHADE_Application" filter "configurations:Debug" symbols "On" - defines {"_DEBUG", "SHEDITOR"} + defines {"_DEBUG"} filter "configurations:Release" optimize "On" diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index e80b247b..a0375811 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -84,6 +84,7 @@ namespace Sandbox SHSystemManager::CreateSystem(); SHGraphicsSystem* graphicsSystem = static_cast(SHSystemManager::GetSystem()); + SHPhysicsSystem* physicsSystem = SHSystemManager::GetSystem(); // Link up SHDebugDraw SHSystemManager::CreateSystem(); @@ -175,11 +176,15 @@ namespace Sandbox #ifdef SHEDITOR if(editor->editorState == SHEditor::State::PLAY) - SHSceneManager::SceneUpdate(0.016f); - SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f); - editor->PollPicking(); -#endif +#endif + SHSceneManager::SceneUpdate(0.016f); +#ifdef SHEDITOR + SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, SHFrameRateController::GetRawDeltaTime()); + editor->PollPicking(); +#else + SHSystemManager::RunRoutines(false, SHFrameRateController::GetRawDeltaTime()); +#endif // TODO: Move into an Editor menu static bool drawColliders = false; if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10)) @@ -193,6 +198,13 @@ namespace Sandbox drawRays = !drawRays; SHSystemManager::GetSystem()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS, drawRays); } + static bool drawContacts = false; + if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F9)) + { + drawContacts = !drawContacts; + SHSystemManager::GetSystem()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACT_POINTS, drawContacts); + SHSystemManager::GetSystem()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACT_NORMALS, drawContacts); + } } // Finish all graphics jobs first graphicsSystem->AwaitGraphicsExecution(); diff --git a/SHADE_Application/src/Scenes/SBMainScene.cpp b/SHADE_Application/src/Scenes/SBMainScene.cpp index 9da68729..929d28fa 100644 --- a/SHADE_Application/src/Scenes/SBMainScene.cpp +++ b/SHADE_Application/src/Scenes/SBMainScene.cpp @@ -7,6 +7,7 @@ #include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Scene/SHSceneManager.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" +#include "Physics/System/SHPhysicsSystem.h" #include "Scripting/SHScriptEngine.h" #include "Math/Transform/SHTransformComponent.h" #include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" @@ -43,6 +44,15 @@ namespace Sandbox { sceneName = SHSerialization::DeserializeSceneFromFile(sceneAssetID); + auto* physicsSystem = SHSystemManager::GetSystem(); + if (!physicsSystem) + { + SHLOGV_CRITICAL("Failed to get the physics system for building the scene!") + return; + } + + physicsSystem->BuildScene(SHSceneManager::GetCurrentSceneGraph()); + /*-----------------------------------------------------------------------*/ /* TESTING CODE */ /*-----------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index ab844b88..fd36c102 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -252,7 +252,7 @@ namespace SHADE if(rbType == SHRigidBodyComponent::Type::DYNAMIC) //Dynamic only fields { SHEditorWidgets::CheckBox("Use Gravity", [component]{return component->IsGravityEnabled();}, [component](bool const& value){component->SetGravityEnabled(value);}, "Gravity"); - SHEditorWidgets::DragFloat("Mass", [component] {return component->GetMass(); }, [component](float const& value) {component->SetMass(value); }, "Mass"); + //SHEditorWidgets::DragFloat("Mass", [component] {return component->GetMass(); }, [component](float const& value) {component->SetMass(value); }, "Mass"); } if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields { @@ -284,6 +284,7 @@ namespace SHADE //Debug Info (Read-Only) if(ImGui::CollapsingHeader("Debug Information", ImGuiTreeNodeFlags_DefaultOpen))//Dynamic or Kinematic only fields { + SHEditorWidgets::DragFloat("Mass", [component] { return component->GetMass(); }, [](float value){}, "Mass", 0.1f, 0.0f, std::numeric_limits::infinity(), "%.3f", ImGuiSliderFlags_ReadOnly); SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [component] {return component->GetPosition(); }, [](SHVec3 const& value) {}, false, "Position", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); SHEditorWidgets::DragVec3("Rotation", { "X", "Y", "Z" }, [component] {return component->GetRotation(); }, [](SHVec3 const& value) {}, false, "Rotation", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields diff --git a/SHADE_Engine/src/Physics/Interface/SHColliderComponent.cpp b/SHADE_Engine/src/Physics/Interface/SHColliderComponent.cpp index 877d238f..135e7e42 100644 --- a/SHADE_Engine/src/Physics/Interface/SHColliderComponent.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHColliderComponent.cpp @@ -80,6 +80,14 @@ namespace SHADE } system = physicsSystem; + + // Sync with transform if one already exists + if (auto* transformComponent = SHComponentManager::GetComponent_s(GetEID()); transformComponent) + { + position = transformComponent->GetWorldPosition(); + orientation = transformComponent->GetWorldOrientation(); + scale = transformComponent->GetWorldScale(); + } } void SHColliderComponent::OnDestroy() diff --git a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp index 28b6f842..4fddc892 100644 --- a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp @@ -322,25 +322,25 @@ namespace SHADE // dirtyFlags |= 1U << FLAG_POS; //} - void SHRigidBodyComponent::SetMass(float newMass) noexcept - { - static constexpr int FLAG_POS = 9; + //void SHRigidBodyComponent::SetMass(float newMass) noexcept + //{ + // static constexpr int FLAG_POS = 9; - if (newMass < 0.0f) - return; + // if (newMass < 0.0f) + // return; - if (type != Type::DYNAMIC) - { - SHLOG_WARNING("Cannot set mass of a non-dynamic object {}", GetEID()) - return; - } + // if (type != Type::DYNAMIC) + // { + // SHLOG_WARNING("Cannot set mass of a non-dynamic object {}", GetEID()) + // return; + // } - dirtyFlags |= 1U << FLAG_POS; - mass = newMass; + // dirtyFlags |= 1U << FLAG_POS; + // mass = newMass; - // Turn off automass - flags &= ~(1U << FLAG_POS); - } + // // Turn off automass + // flags &= ~(1U << FLAG_POS); + //} void SHRigidBodyComponent::SetDrag(float newDrag) noexcept { @@ -411,6 +411,13 @@ namespace SHADE } system = physicsSystem; + + // Sync with transform if one already exists + if (auto* transformComponent = SHComponentManager::GetComponent_s(GetEID()); transformComponent) + { + position = transformComponent->GetWorldPosition(); + orientation = transformComponent->GetWorldOrientation(); + } } void SHRigidBodyComponent::AddForce(const SHVec3& force) const noexcept @@ -489,7 +496,7 @@ RTTR_REGISTRATION registration::class_("RigidBody Component") .property("Type" , &SHRigidBodyComponent::GetType , &SHRigidBodyComponent::SetType ) - .property("Mass" , &SHRigidBodyComponent::GetMass , &SHRigidBodyComponent::SetMass ) + //.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 ) diff --git a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h index d5204d94..532b3312 100644 --- a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h @@ -114,7 +114,7 @@ namespace SHADE void SetInterpolate (bool allowInterpolation) noexcept; //void SetAutoMass (bool autoMass) noexcept; - void SetMass (float newMass) noexcept; + //void SetMass (float newMass) noexcept; void SetDrag (float newDrag) noexcept; void SetAngularDrag (float newAngularDrag) noexcept; diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp index 8de928f0..00f280e9 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp @@ -94,7 +94,7 @@ namespace SHADE /* Public Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - int SHPhysicsObject::AddCollisionShape(int index) const + int SHPhysicsObject::AddCollisionShape(int index) { // Get collider component auto* colliderComponent = SHComponentManager::GetComponent_s(entityID); @@ -123,13 +123,19 @@ namespace SHADE default: break; } - rp3dBody->updateLocalCenterOfMassFromColliders(); - rp3dBody->updateLocalInertiaTensorFromColliders(); + if (rp3dBody->getType() == rp3d::BodyType::DYNAMIC) + { + rp3dBody->updateMassPropertiesFromColliders(); + + auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); + if (rigidBodyComponent) + rigidBodyComponent->mass = rp3dBody->getMass(); + } return index; } - void SHPhysicsObject::RemoveCollisionShape(int index) const + void SHPhysicsObject::RemoveCollisionShape(int index) { const int NUM_COLLIDERS = static_cast(rp3dBody->getNbColliders()); if (NUM_COLLIDERS == 0) @@ -140,6 +146,15 @@ namespace SHADE auto* collider = rp3dBody->getCollider(index); rp3dBody->removeCollider(collider); + + if (rp3dBody->getType() == rp3d::BodyType::DYNAMIC) + { + rp3dBody->updateMassPropertiesFromColliders(); + + auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); + if (rigidBodyComponent) + rigidBodyComponent->mass = rp3dBody->getMass(); + } } void SHPhysicsObject::RemoveAllCollisionShapes() const noexcept @@ -254,9 +269,7 @@ namespace SHADE } case 9: // Mass { - rp3dBody->setMass(component.mass); - rp3dBody->updateLocalCenterOfMassFromColliders(); - rp3dBody->updateLocalInertiaTensorFromColliders(); + //rp3dBody->setMass(component.mass); //if (component.GetAutoMass()) //{ diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h index fefc983f..818e5471 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h @@ -71,8 +71,8 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - int AddCollisionShape (int index) const; - void RemoveCollisionShape (int index) const; + int AddCollisionShape (int index); + void RemoveCollisionShape (int index); void RemoveAllCollisionShapes () const noexcept; void SyncRigidBody (SHRigidBodyComponent& component) const noexcept; @@ -98,12 +98,12 @@ namespace SHADE // Box Shapes - void addBoxShape (SHCollisionShape& boxShape) const noexcept; - void syncBoxShape (int index, SHCollisionShape& boxShape) const noexcept; + void addBoxShape (SHCollisionShape& boxShape) const noexcept; + void syncBoxShape (int index, SHCollisionShape& boxShape) const noexcept; // Sphere Shapes - void addSphereShape (SHCollisionShape& sphereShape) const noexcept; - void syncSphereShape (int index, SHCollisionShape& sphereShape) const noexcept; + void addSphereShape (SHCollisionShape& sphereShape) const noexcept; + void syncSphereShape (int index, SHCollisionShape& sphereShape) const noexcept; }; } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp index bf1debac..3c80883c 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp @@ -15,6 +15,7 @@ // Project Headers #include "ECS_Base/Managers/SHSystemManager.h" +#include "Editor/SHEditor.h" #include "Scene/SHSceneManager.h" namespace SHADE @@ -118,11 +119,22 @@ namespace SHADE return; } + rp3d::DebugRenderer* rp3dRenderer = nullptr; + #ifdef SHEDITOR + const auto* EDITOR = SHSystemManager::GetSystem(); + if (EDITOR && EDITOR->editorState != SHEditor::State::STOP) + { + rp3dRenderer = &system->physicsSystem->worldState.world->getDebugRenderer(); + rp3dRenderer->setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_POINT, false); + rp3dRenderer->setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_NORMAL, false); + } + #endif + for (int i = 0; i < SHUtilities::ConvertEnum(DebugDrawFlags::NUM_FLAGS); ++i) { const bool DRAW = (system->debugDrawFlags & (1U << i)) > 0; if (DRAW) - drawFunctions[i](debugDrawSystem); + drawFunctions[i](debugDrawSystem, rp3dRenderer); } // Automatically clear the container of raycasts despite debug drawing state @@ -134,7 +146,7 @@ namespace SHADE /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHPhysicsDebugDrawSystem::drawColliders(SHDebugDrawSystem* debugRenderer) noexcept + void SHPhysicsDebugDrawSystem::drawColliders(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept { const auto& COLLIDER_SET = SHComponentManager::GetDense(); for (const auto& COLLIDER : COLLIDER_SET) @@ -155,27 +167,53 @@ namespace SHADE } } - void SHPhysicsDebugDrawSystem::drawColliderAABBs(SHDebugDrawSystem* debugRenderer) noexcept + void SHPhysicsDebugDrawSystem::drawColliderAABBs(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept { } - void SHPhysicsDebugDrawSystem::drawBroadPhaseAABBs(SHDebugDrawSystem* debugRenderer) noexcept + void SHPhysicsDebugDrawSystem::drawBroadPhaseAABBs(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept { } - void SHPhysicsDebugDrawSystem::drawContactPoints(SHDebugDrawSystem* debugRenderer) noexcept + void SHPhysicsDebugDrawSystem::drawContactPoints(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept { - + #ifdef SHEDITOR + const auto* EDITOR = SHSystemManager::GetSystem(); + if (EDITOR && EDITOR->editorState != SHEditor::State::STOP) + { + rp3dRenderer->setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_POINT, true); + const int NUM_TRIS = static_cast(rp3dRenderer->getNbTriangles()); + if (NUM_TRIS == 0) + return; + + const auto& TRI_ARRAY = rp3dRenderer->getTrianglesArray(); + for (int i = 0; i < NUM_TRIS; ++i) + debugRenderer->DrawTri(SHColour::RED, TRI_ARRAY[i].point1, TRI_ARRAY[i].point2, TRI_ARRAY[i].point3); + } + #endif } - void SHPhysicsDebugDrawSystem::drawContactNormals(SHDebugDrawSystem* debugRenderer) noexcept + void SHPhysicsDebugDrawSystem::drawContactNormals(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept { - + #ifdef SHEDITOR + const auto* EDITOR = SHSystemManager::GetSystem(); + if (EDITOR && EDITOR->editorState != SHEditor::State::STOP) + { + rp3dRenderer->setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_NORMAL, true); + const int NUM_LINES = static_cast(rp3dRenderer->getNbLines()); + if (NUM_LINES == 0) + return; + + const auto& LINE_ARRAY = rp3dRenderer->getLinesArray(); + for (int i = 0; i < NUM_LINES; ++i) + debugRenderer->DrawLine(SHColour::RED, LINE_ARRAY[i].point1, LINE_ARRAY[i].point2); + } + #endif } - void SHPhysicsDebugDrawSystem::drawRaycasts(SHDebugDrawSystem* debugRenderer) noexcept + void SHPhysicsDebugDrawSystem::drawRaycasts(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept { auto* physicsSystem = SHSystemManager::GetSystem(); if (!physicsSystem) diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h index 867a6e11..dc703092 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h @@ -93,7 +93,7 @@ namespace SHADE /* Type Definitions */ /*---------------------------------------------------------------------------------*/ - using DebugDrawFunction = void(*)(SHDebugDrawSystem*) noexcept; + using DebugDrawFunction = void(*)(SHDebugDrawSystem*, rp3d::DebugRenderer*) noexcept; /*---------------------------------------------------------------------------------*/ /* Data Members */ @@ -118,12 +118,12 @@ namespace SHADE // Generic Draw Functions - static void drawColliders (SHDebugDrawSystem* debugRenderer) noexcept; - static void drawColliderAABBs (SHDebugDrawSystem* debugRenderer) noexcept; - static void drawBroadPhaseAABBs (SHDebugDrawSystem* debugRenderer) noexcept; - static void drawContactPoints (SHDebugDrawSystem* debugRenderer) noexcept; - static void drawContactNormals (SHDebugDrawSystem* debugRenderer) noexcept; - static void drawRaycasts (SHDebugDrawSystem* debugRenderer) noexcept; + static void drawColliders (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept; + static void drawColliderAABBs (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept; + static void drawBroadPhaseAABBs (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept; + static void drawContactPoints (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept; + static void drawContactNormals (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept; + static void drawRaycasts (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept; // Shape Generation Functions diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp index 396edd93..89be2614 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp @@ -97,6 +97,13 @@ namespace SHADE defaultCollisionTagNameFilePath.append("CollisionTags.SHConfig"); SHCollisionTagMatrix::Init(defaultCollisionTagNameFilePath); + // Link Physics Object Manager with System & Raycaster + objectManager.SetFactory(factory); + raycaster.SetObjectManager(&objectManager); + + // Link Collision Listener with System + collisionListener.BindToSystem(this); + // Subscribe to component events const std::shared_ptr ADD_COMPONENT_RECEIVER { std::make_shared>(this, &SHPhysicsSystem::addPhysicsComponent) }; const ReceiverPtr ADD_COMPONENT_RECEIVER_PTR = std::dynamic_pointer_cast(ADD_COMPONENT_RECEIVER); @@ -118,12 +125,7 @@ namespace SHADE SHEventManager::SubscribeTo(SH_EDITOR_ON_STOP_EVENT, ON_STOP_RECEIVER_PTR); #endif - // Link Physics Object Manager with System & Raycaster - objectManager.SetFactory(factory); - raycaster.SetObjectManager(&objectManager); - - // Link Collision Listener with System - collisionListener.BindToSystem(this); + } void SHPhysicsSystem::Exit() @@ -136,6 +138,55 @@ namespace SHADE SHCollisionTagMatrix::Exit(defaultCollisionTagNameFilePath); } + void SHPhysicsSystem::BuildScene(SHSceneGraph& sceneGraph) + { + static const auto BUILD_NEW_SCENE_PHYSICS_OBJECT = [&](SHSceneNode* node) + { + const EntityID EID = node->GetEntityID(); + + if (SHComponentManager::HasComponent(EID)) + objectManager.AddRigidBody(EID); + + if (SHComponentManager::HasComponent(EID)) + objectManager.AddCollider(EID); + }; + + //////////////////////////////// + + // Destroy an existing world + if (worldState.world != nullptr) + { + objectManager.RemoveAllObjects(); + objectManager.SetWorld(nullptr); + + collisionListener.ClearContainers(); + raycaster.ClearFrame(); + + worldState.DestroyWorld(factory); + } + + worldState.CreateWorld(factory); + #ifdef _PUBLISH + worldState.world->setIsDebugRenderingEnabled(false); + #else + worldState.world->setIsDebugRenderingEnabled(true); + #endif + + // Link Collision Listener & Raycaster + collisionListener.BindToWorld(worldState.world); + raycaster.BindToWorld(worldState.world); + + // Link with object manager & create all physics objects + objectManager.SetWorld(worldState.world); + + // When building a scene, clear the object manager command queue and build scene objects again. + // This is done to avoid duplicate adds. + while (!objectManager.commandQueue.empty()) + objectManager.commandQueue.pop(); + + sceneGraph.Traverse(BUILD_NEW_SCENE_PHYSICS_OBJECT); + } + void SHPhysicsSystem::ForceUpdate() { if (!worldState.world) @@ -228,10 +279,13 @@ namespace SHADE { objectManager.AddCollisionShape(entityID, index); + auto* colliderComponent = SHComponentManager::GetComponent(entityID); + auto& collisionShape = colliderComponent->GetCollisionShape(index); + const SHPhysicsColliderAddedEvent COLLIDER_ADDED_EVENT_DATA { .entityID = entityID - , .colliderType = SHComponentManager::GetComponent(entityID)->GetCollisionShape(index).GetType() + , .colliderType = collisionShape.GetType() , .colliderIndex = index }; @@ -367,6 +421,11 @@ namespace SHADE return onPlayEvent->handle; worldState.CreateWorld(factory); + #ifdef _PUBLISH + worldState.world->setIsDebugRenderingEnabled(false); + #else + worldState.world->setIsDebugRenderingEnabled(true); + #endif // Link Collision Listener & Raycaster collisionListener.BindToWorld(worldState.world); @@ -375,8 +434,8 @@ namespace SHADE // Link with object manager & create all physics objects objectManager.SetWorld(worldState.world); - const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); - SCENE_GRAPH.Traverse(BUILD_PHYSICS_OBJECT); + // Build scene + SHSceneManager::GetCurrentSceneGraph().Traverse(BUILD_PHYSICS_OBJECT); return onPlayEvent->handle; } @@ -390,11 +449,11 @@ namespace SHADE // Clear all collision info // Collision listener is automatically unbound when world is destroyed collisionListener.ClearContainers(); + raycaster.ClearFrame(); // Destroy the world worldState.DestroyWorld(factory); return onStopEvent->handle; } - } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h index f92be4cd..f7340d31 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h @@ -27,7 +27,7 @@ #include "Physics/Interface/SHColliderComponent.h" #include "Physics/PhysicsObject/SHPhysicsObjectManager.h" #include "Physics/SHPhysicsWorld.h" - +#include "Scene/SHSceneGraph.h" namespace SHADE { @@ -74,10 +74,12 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - void Init () override; - void Exit () override; + void Init () override; + void Exit () override; + + void BuildScene (SHSceneGraph& sceneGraph); + void ForceUpdate (); - void ForceUpdate (); /** * @brief Casts a ray into the world. @@ -280,11 +282,11 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - SHEventHandle addPhysicsComponent (SHEventPtr addComponentEvent) noexcept; - SHEventHandle removePhysicsComponent (SHEventPtr removeComponentEvent) noexcept; - - SHEventHandle onPlay (SHEventPtr onPlayEvent); - SHEventHandle onStop (SHEventPtr onStopEvent); + SHEventHandle addPhysicsComponent (SHEventPtr addComponentEvent) noexcept; + SHEventHandle removePhysicsComponent (SHEventPtr removeComponentEvent) noexcept; + SHEventHandle onPlay (SHEventPtr onPlayEvent); + SHEventHandle onStop (SHEventPtr onStopEvent); + SHEventHandle buildScene (SHEventPtr onSceneChangeEvent); }; } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Scene/SHSceneGraphEvents.h b/SHADE_Engine/src/Scene/SHSceneEvents.h similarity index 72% rename from SHADE_Engine/src/Scene/SHSceneGraphEvents.h rename to SHADE_Engine/src/Scene/SHSceneEvents.h index ccdf06be..c0d7dbc1 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraphEvents.h +++ b/SHADE_Engine/src/Scene/SHSceneEvents.h @@ -1,7 +1,7 @@ /**************************************************************************************** - * \file SHSceneGraphEvents.h + * \file SHSceneEvents.h * \author Diren D Bharwani, diren.dbharwani, 390002520 - * \brief Interface for Scene Graph Events. + * \brief Interface for Scene Events. * * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or * disclosure of this file or its contents without the prior written consent @@ -21,21 +21,21 @@ namespace SHADE struct SHSceneGraphChangeParentEvent { - SHSceneNode* node; - SHSceneNode* oldParent; - SHSceneNode* newParent; + SHSceneNode* node = nullptr; + SHSceneNode* oldParent = nullptr; + SHSceneNode* newParent = nullptr; }; struct SHSceneGraphAddChildEvent { - SHSceneNode* parent; - SHSceneNode* childAdded; + SHSceneNode* parent = nullptr; + SHSceneNode* childAdded = nullptr; }; struct SHSceneGraphRemoveChildEvent { - SHSceneNode* parent; - SHSceneNode* childRemoved; + SHSceneNode* parent = nullptr; + SHSceneNode* childRemoved = nullptr; }; } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.h b/SHADE_Engine/src/Scene/SHSceneGraph.h index 5747be7b..37d0e063 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.h +++ b/SHADE_Engine/src/Scene/SHSceneGraph.h @@ -16,7 +16,7 @@ #include "ECS_Base/Entity/SHEntity.h" #include "SH_API.h" #include "SHSceneNode.h" -#include "SHSceneGraphEvents.h" +#include "SHSceneEvents.h" namespace SHADE { diff --git a/SHADE_Engine/src/Scene/SHSceneManager.cpp b/SHADE_Engine/src/Scene/SHSceneManager.cpp index be9c7755..110aaea6 100644 --- a/SHADE_Engine/src/Scene/SHSceneManager.cpp +++ b/SHADE_Engine/src/Scene/SHSceneManager.cpp @@ -85,7 +85,6 @@ namespace SHADE currentScene->Load(); currentScene->Init(); } - } else // restarting scene { diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index 84b50373..90121994 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -27,7 +27,7 @@ of DigiPen Institute of Technology is prohibited. #include "Events/SHEventManager.hpp" #include "Physics/System/SHPhysicsSystem.h" #include "Physics/SHPhysicsEvents.h" -#include "Scene/SHSceneGraphEvents.h" +#include "Scene/SHSceneEvents.h" #include "Assets/SHAssetMacros.h" diff --git a/SHADE_Engine/src/Serialization/SHYAMLConverters.h b/SHADE_Engine/src/Serialization/SHYAMLConverters.h index d66a7506..4fe28153 100644 --- a/SHADE_Engine/src/Serialization/SHYAMLConverters.h +++ b/SHADE_Engine/src/Serialization/SHYAMLConverters.h @@ -113,6 +113,7 @@ namespace YAML static constexpr const char* Bounciness = "Bounciness"; static constexpr const char* Density = "Density"; static constexpr const char* PositionOffset = "Position Offset"; + static constexpr const char* RotationOffset = "Rotation Offset"; static Node encode(SHCollisionShape& rhs) { @@ -148,6 +149,7 @@ namespace YAML node[Bounciness] = rhs.GetBounciness(); node[Density] = rhs.GetDensity(); node[PositionOffset] = rhs.GetPositionOffset(); + node[RotationOffset] = rhs.GetRotationOffset(); return node; } @@ -188,6 +190,8 @@ namespace YAML rhs.SetDensity(node[Density].as()); if (node[PositionOffset].IsDefined()) rhs.SetPositionOffset(node[PositionOffset].as()); + if (node[RotationOffset].IsDefined()) + rhs.SetRotationOffset(node[RotationOffset].as()); return true; } diff --git a/SHADE_Managed/src/Components/RigidBody.cxx b/SHADE_Managed/src/Components/RigidBody.cxx index cdaa296a..a564402f 100644 --- a/SHADE_Managed/src/Components/RigidBody.cxx +++ b/SHADE_Managed/src/Components/RigidBody.cxx @@ -58,7 +58,7 @@ namespace SHADE } void RigidBody::Mass::set(float value) { - return GetNativeComponent()->SetMass(value); + /*return GetNativeComponent()->SetMass(value);*/ } float RigidBody::Drag::get() { From 9cc008eaf4e1231cb3f6e0147a1ca4b7dc1479dd Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 21 Nov 2022 20:21:08 +0800 Subject: [PATCH 13/14] Fixed ghosts of a renderable being rendered when a material is changed --- SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index 91728d71..ec19691f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -55,7 +55,7 @@ namespace SHADE void SHSuperBatch::Remove(const SHRenderable* renderable) noexcept { - Handle baseMat = renderable->GetMaterial()->GetBaseMaterial(); + Handle baseMat = (renderable->HasMaterialChanged() ? renderable->GetPrevMaterial() : renderable->GetMaterial())->GetBaseMaterial(); const Handle PIPELINE = baseMat->HasPipelineChanged() ? baseMat->GetPrevPipeline() : baseMat->GetPipeline(); // Check if we have a Batch with the same pipeline yet From 1ed0181c9e2019e12871077436b53224cbca1074 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Mon, 21 Nov 2022 20:27:38 +0800 Subject: [PATCH 14/14] Reverted premake changes --- SHADE_Application/premake5.lua | 7 +++++-- SHADE_Engine/premake5.lua | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/SHADE_Application/premake5.lua b/SHADE_Application/premake5.lua index c2312805..014df726 100644 --- a/SHADE_Application/premake5.lua +++ b/SHADE_Application/premake5.lua @@ -78,7 +78,10 @@ project "SHADE_Application" "26451", "26437", "4275", - "4635" + "4633", + "4634", + "4635", + "4638" } linkoptions { "-IGNORE:4006" } @@ -87,7 +90,7 @@ project "SHADE_Application" filter "configurations:Debug" symbols "On" - defines {"_DEBUG"} + defines {"_DEBUG", "SHEDITOR"} filter "configurations:Release" optimize "On" diff --git a/SHADE_Engine/premake5.lua b/SHADE_Engine/premake5.lua index 88df50d7..7fb7291d 100644 --- a/SHADE_Engine/premake5.lua +++ b/SHADE_Engine/premake5.lua @@ -79,7 +79,10 @@ project "SHADE_Engine" "26451", "26437", "4275", - "4635" + "4633", + "4634", + "4635", + "4638" } linkoptions { "-IGNORE:4006" }