diff --git a/SHADE_Managed/src/Components/Collider.cxx b/SHADE_Managed/src/Components/Collider.cxx new file mode 100644 index 00000000..e09b7ead --- /dev/null +++ b/SHADE_Managed/src/Components/Collider.cxx @@ -0,0 +1,192 @@ +/************************************************************************************//*! +\file Collider.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 20, 2022 +\brief Contains the definition of the functions of the managed Collider class. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "Collider.hxx" +#include "Utility/Debug.hxx" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* ColliderBound - Constructors */ + /*---------------------------------------------------------------------------------*/ + ColliderBound::ColliderBound(int arrayIdx, Entity attachedEntity) + : arrayIndex { arrayIdx } + , entity { attachedEntity } + {} + + /*---------------------------------------------------------------------------------*/ + /* ColliderBound - Setter Functions */ + /*---------------------------------------------------------------------------------*/ + void ColliderBound::updateArrayIndex(int index) + { + arrayIndex = index; + } + + /*---------------------------------------------------------------------------------*/ + /* BoxColliderBound - Constructors */ + /*---------------------------------------------------------------------------------*/ + BoxColliderBound::BoxColliderBound(int arrayIdx, Entity attachedEntity) + : ColliderBound { arrayIndex, attachedEntity } + {} + + /*---------------------------------------------------------------------------------*/ + /* BoxColliderBound - Properties */ + /*---------------------------------------------------------------------------------*/ + Vector3 BoxColliderBound::Center::get() + { + return Convert::ToCLI(getNativeBoundObject().GetCenter()); + } + void BoxColliderBound::Center::set(Vector3 value) + { + getNativeBoundObject().SetCenter(Convert::ToNative(value)); + } + Vector3 BoxColliderBound::HalfExtents::get() + { + return Convert::ToCLI(getNativeBoundObject().GetHalfExtents()); + } + void BoxColliderBound::HalfExtents::set(Vector3 value) + { + getNativeBoundObject().SetHalfExtents(Convert::ToNative(value)); + } + Vector3 BoxColliderBound::Min::get() + { + return Convert::ToCLI(getNativeBoundObject().GetMin()); + } + void BoxColliderBound::Min::set(Vector3 value) + { + getNativeBoundObject().SetMin(Convert::ToNative(value)); + } + Vector3 BoxColliderBound::Max::get() + { + return Convert::ToCLI(getNativeBoundObject().GetMax()); + } + void BoxColliderBound::Max::set(Vector3 value) + { + getNativeBoundObject().SetMax(Convert::ToNative(value)); + } + + /*---------------------------------------------------------------------------------*/ + /* BoxColliderBound - Usage Functions */ + /*---------------------------------------------------------------------------------*/ + bool BoxColliderBound::TestPoint(Vector3 point) + { + return getNativeBoundObject().TestPoint(Convert::ToNative(point)); + } + bool BoxColliderBound::Raycast(Ray ray, float maxDistance) + { + return getNativeBoundObject().Raycast(Convert::ToNative(ray), maxDistance); + } + + /*---------------------------------------------------------------------------------*/ + /* BoxColliderBound - Properties */ + /*---------------------------------------------------------------------------------*/ + Vector3 SphereColliderBound::Center::get() + { + return Convert::ToCLI(getNativeBoundObject().GetCenter()); + } + void SphereColliderBound::Center::set(Vector3 value) + { + getNativeBoundObject().SetCenter(Convert::ToNative(value)); + } + float SphereColliderBound::Radius::get() + { + return getNativeBoundObject().GetRadius(); + } + void SphereColliderBound::Radius::set(float value) + { + getNativeBoundObject().SetRadius(value); + } + + /*---------------------------------------------------------------------------------*/ + /* SphereColliderBound - Usage Functions */ + /*---------------------------------------------------------------------------------*/ + bool SphereColliderBound::TestPoint(Vector3 point) + { + return getNativeBoundObject().TestPoint(Convert::ToNative(point)); + } + bool SphereColliderBound::Raycast(Ray ray, float maxDistance) + { + return getNativeBoundObject().Raycast(Convert::ToNative(ray), maxDistance); + } + + /*---------------------------------------------------------------------------------*/ + /* SphereColliderBound - Constructors */ + /*---------------------------------------------------------------------------------*/ + SphereColliderBound::SphereColliderBound(int arrayIndex, Entity attachedEntity) + : ColliderBound{ arrayIndex, attachedEntity } + {} + + /*---------------------------------------------------------------------------------*/ + /* Collider - Constructors */ + /*---------------------------------------------------------------------------------*/ + Collider::Collider(Entity entity) + : Component(entity) + {} + + /*---------------------------------------------------------------------------------*/ + /* Collider - Properties */ + /*---------------------------------------------------------------------------------*/ + int Collider::ColliderBoundsCount::get() + { + return static_cast(GetNativeComponent()->GetColliders().size()); + } + + /*---------------------------------------------------------------------------------*/ + /* Collider - ColliderBound Functions */ + /*---------------------------------------------------------------------------------*/ + ColliderBound^ Collider::GetColliderBound(int index) + { + // Populate the list if it hasn't been + if (subColliderList == nullptr) + { + subColliderList = gcnew System::Collections::Generic::List(); + for (const auto& collider : GetNativeComponent()->GetColliders()) + { + ColliderBound^ bound = nullptr; + switch (collider.first.GetType()) + { + case SHCollider::Type::BOX: + bound = gcnew BoxColliderBound(index, Owner.GetEntity()); + break; + case SHCollider::Type::SPHERE: + bound = gcnew SphereColliderBound(index, Owner.GetEntity()); + break; + case SHCollider::Type::CAPSULE: + // TODO + break; + default: + Debug::LogWarning("[Collider] An invalid Collider Type was detected. Skipping."); + break; + } + + // Add into list + subColliderList->Add(bound); + } + } + + // Check if valid + if (index < 0 || index >= subColliderList->Count) + throw gcnew System::ArgumentException("[Collider] Invalid index for Collider Bound retrieval."); + + // Return the bound + return subColliderList[index]; + } + generic + T Collider::GetColliderBound(int index) + { + return safe_cast(GetColliderBound(index)); + } +} diff --git a/SHADE_Managed/src/Components/Collider.h++ b/SHADE_Managed/src/Components/Collider.h++ new file mode 100644 index 00000000..66f77e18 --- /dev/null +++ b/SHADE_Managed/src/Components/Collider.h++ @@ -0,0 +1,41 @@ +/************************************************************************************//*! +\file Collider.h++ +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 20, 2022 +\brief Contains the definition of templated functions for the managed Collider + and related classes. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +// Primary Include +#include "Component.hxx" +namespace SHADE +{ + template + ColliderBoundType& SHADE::ColliderBound::getNativeBoundObject() + { + SHColliderComponent* collider = SHComponentManager::GetComponent_s(entity); + if (!collider) + throw gcnew System::InvalidOperationException("Unable to retrieve Collider component!"); + + try + { + auto& bounds = collider->GetCollider(arrayIndex); + if (bounds.GetType() != SHCollider::Type::BOX) + throw gcnew System::InvalidOperationException("Attempted to retrieve invalid ColliderBound."); + + return reinterpret_cast(bounds); + } + catch (std::invalid_argument&) + { + throw gcnew System::IndexOutOfRangeException("Attempted to retrieve out of range ColliderBound!"); + } + } +} diff --git a/SHADE_Managed/src/Components/Collider.hxx b/SHADE_Managed/src/Components/Collider.hxx new file mode 100644 index 00000000..a831e5f9 --- /dev/null +++ b/SHADE_Managed/src/Components/Collider.hxx @@ -0,0 +1,228 @@ +/************************************************************************************//*! +\file Collider.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 20, 2022 +\brief Contains the definition of the managed Collider class with the + declaration of functions for working with it. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +// External Dependencies +#include "Physics/Components/SHColliderComponent.h" +// Project Includes +#include "Components/Component.hxx" +#include "Math/Vector3.hxx" +#include "Utility/Convert.hxx" +#include "Math/Ray.hxx" + +namespace SHADE +{ + /// + /// Base interface for all Collider Shapes. + /// + public ref class ColliderBound + { + public: + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Checks if the specified point is within this shape's bounds. + /// + /// Point to test with. + /// True if the point is in the shape's bounds. + virtual bool TestPoint(Vector3 point) = 0; + /// + /// Computes a Raycast and checks if there is a collision with any object. + /// + /// The ray to cast. + /// Maximum distance for the raycast check. + /// True if the ray intersects with an object in the scene. + virtual bool Raycast(Ray ray, float maxDistance) = 0; + + protected: + /*-----------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------*/ + ColliderBound(int arrayIdx, Entity attachedEntity); + + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + int arrayIndex; // Index into the colliders vector on the native object + Entity entity; // Entity holding the collider component that this collider bounds is on + + /*-----------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------*/ + template + ColliderBoundType& getNativeBoundObject(); + + internal: + /*-----------------------------------------------------------------------------*/ + /* Setter Functions */ + /*-----------------------------------------------------------------------------*/ + void updateArrayIndex(int index); + }; + + /// + /// Box-shaped Collider Bound. + /// + public ref class BoxColliderBound : public ColliderBound + { + public: + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Center of the Bounding Box formed by this bound. + /// + property Vector3 Center + { + Vector3 get(); + void set(Vector3 value); + } + /// + /// Half of the scale of the Bounding Box formed by this bound. + /// + property Vector3 HalfExtents + { + Vector3 get(); + void set(Vector3 value); + } + /// + /// Position of the bottom left back corner of the Bounding Box formed by this + /// bound. + /// + property Vector3 Min + { + Vector3 get(); + void set(Vector3 value); + } + /// + /// Position of the top right front corner of the Bounding Box formed by this + /// bound. + /// + property Vector3 Max + { + Vector3 get(); + void set(Vector3 value); + } + + /*-----------------------------------------------------------------------------*/ + /* ColliderBound Functions */ + /*-----------------------------------------------------------------------------*/ + /// + bool TestPoint(Vector3 point) override; + /// + bool Raycast(Ray ray, float maxDistance) override; + + internal: + /*-----------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------*/ + BoxColliderBound(int arrayIndex, Entity attachedEntity); + }; + + /// + /// Sphere-shaped Collider Bound. + /// + public ref class SphereColliderBound : public ColliderBound + { + public: + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Center of the Bounding Sphere formed by this bound. + /// + property Vector3 Center + { + Vector3 get(); + void set(Vector3 value); + } + /// + /// Radius of the Bounding Sphere formed by this bound. + /// + property float Radius + { + float get(); + void set(float value); + } + + /*-----------------------------------------------------------------------------*/ + /* ColliderBound Functions */ + /*-----------------------------------------------------------------------------*/ + /// + bool TestPoint(Vector3 point) override; + /// + bool Raycast(Ray ray, float maxDistance) override; + + internal: + /*-----------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------*/ + SphereColliderBound(int arrayIndex, Entity attachedEntity); + }; + + /// + /// CLR version of the the SHADE Engine's SHColliderComponent. + /// A single Collider component can contain one or multiple Collider Bounds. + /// + public ref class Collider : public Component + { + internal: + /*-----------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------*/ + /// + /// Constructs a Collider Component that represents a native SHColliderComponent + /// component tied to the specified Entity. + /// + /// Entity that this Component will be tied to. + Collider(Entity entity); + + public: + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Total number of ColliderBounds in the Collider component. + /// + property int ColliderBoundsCount + { + int get(); + } + + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Retrieves a ColliderBound at the specified index in the ColliderBound list. + /// + /// Index to retrieve a ColliderBound from. + /// ColliderBound for the specified index. + ColliderBound^ GetColliderBound(int index); + /// + /// Retrieves a ColliderBound at the specified index in the ColliderBound list + /// and casts it to the appropriate type. + /// + /// Type of the ColliderBound to cast to. + /// Index to retrieve a ColliderBound from. + /// ColliderBound for the specified index. + generic where T:ColliderBound + T GetColliderBound(int index); + + private: + System::Collections::Generic::List^ subColliderList; // TODO: Update elements in this list if the list on native collider changes + }; +} + +#include "Collider.h++" \ No newline at end of file diff --git a/SHADE_Managed/src/Math/Ray.cxx b/SHADE_Managed/src/Math/Ray.cxx new file mode 100644 index 00000000..ee614cbe --- /dev/null +++ b/SHADE_Managed/src/Math/Ray.cxx @@ -0,0 +1,28 @@ +/************************************************************************************//*! +\file Ray.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 20, 2022 +\brief Contains the definitions of functions of the Vector2 struct. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "Math/Ray.hxx" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Constructors */ + /*---------------------------------------------------------------------------------*/ + Ray::Ray(Vector3 origin, Vector3 direction) + : Origin { origin } + , Direction{ direction } + {} +} \ No newline at end of file diff --git a/SHADE_Managed/src/Math/Ray.hxx b/SHADE_Managed/src/Math/Ray.hxx new file mode 100644 index 00000000..c50191f8 --- /dev/null +++ b/SHADE_Managed/src/Math/Ray.hxx @@ -0,0 +1,50 @@ +/************************************************************************************//*! +\file Ray.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 20, 2021 +\brief Contains the definitions of Vector2 struct. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +// Project Includes +#include "Vector3.hxx" + +namespace SHADE +{ + /// + /// CLR version of the the SHADE Engine's Ray class that represents a ray in + /// 3-Dimensional space. + /// + public value struct Ray + { + public: + /*-----------------------------------------------------------------------------*/ + /* Public Members */ + /*-----------------------------------------------------------------------------*/ + /// + /// The start point of the ray. + /// + Vector3 Origin; + /// + /// The direction that a ray travels in. + /// + Vector3 Direction; + + /*-----------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------*/ + /// + /// Creates a ray starting at origin along direction. + /// + /// Source of the ray. + /// Direction the ray travels in. + Ray(Vector3 origin, Vector3 direction); + }; +} diff --git a/SHADE_Managed/src/Utility/Convert.cxx b/SHADE_Managed/src/Utility/Convert.cxx index 661eb3e4..33c4e4dc 100644 --- a/SHADE_Managed/src/Utility/Convert.cxx +++ b/SHADE_Managed/src/Utility/Convert.cxx @@ -40,6 +40,7 @@ namespace SHADE const double Z = vec.z; return SHVec3(X, Y, Z); } + Vector3 Convert::ToCLI(const SHVec3& vec) { return Vector3(vec.x, vec.y, vec.z); @@ -56,6 +57,16 @@ namespace SHADE return Vector2(vec.x, vec.y); } + SHRay Convert::ToNative(Ray vec) + { + return SHRay(ToNative(vec.Origin), ToNative(vec.Direction)); + } + + Ray Convert::ToCLI(const SHRay& vec) + { + return Ray(ToCLI(vec.position), ToCLI(vec.direction)); + } + /*---------------------------------------------------------------------------------*/ /* String Conversions */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Utility/Convert.hxx b/SHADE_Managed/src/Utility/Convert.hxx index f04cbf4b..fd0ecdce 100644 --- a/SHADE_Managed/src/Utility/Convert.hxx +++ b/SHADE_Managed/src/Utility/Convert.hxx @@ -18,10 +18,12 @@ of DigiPen Institute of Technology is prohibited. #include "ECS_Base/Entity/SHEntity.h" #include "Math/Vector/SHVec2.h" #include "Math/Vector/SHVec3.h" +#include "Math/SHRay.h" // Project Includes #include "Engine/Entity.hxx" #include "Math/Vector2.hxx" #include "Math/Vector3.hxx" +#include "Math/Ray.hxx" namespace SHADE { @@ -74,6 +76,18 @@ namespace SHADE /// The native Vector2 to convert from. /// Managed copy of a native Vector2. static Vector2 ToCLI(const SHVec2& vec); + /// + /// Converts from a managed Vector2 to a native Vector2. + /// + /// The managed Vector2 to convert from. + /// Native copy of a managed Vector2. + static SHRay ToNative(Ray vec); + /// + /// Converts from a native Vector2 to a managed Vector2. + /// + /// The native Vector2 to convert from. + /// Managed copy of a native Vector2. + static Ray ToCLI(const SHRay& vec); /*-----------------------------------------------------------------------------*/ /* String Conversions */