From 62433d1a5360d060679681aeb6fb71d70c651326 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sun, 20 Nov 2022 02:35:02 +0800 Subject: [PATCH] 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