Added Collider component and Ray struct for C#

This commit is contained in:
Kah Wei 2022-10-20 17:07:21 +08:00
parent 323a95e5d5
commit 488fd51d05
7 changed files with 564 additions and 0 deletions

View File

@ -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<SHBoundingBox>().GetCenter());
}
void BoxColliderBound::Center::set(Vector3 value)
{
getNativeBoundObject<SHBoundingBox>().SetCenter(Convert::ToNative(value));
}
Vector3 BoxColliderBound::HalfExtents::get()
{
return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetHalfExtents());
}
void BoxColliderBound::HalfExtents::set(Vector3 value)
{
getNativeBoundObject<SHBoundingBox>().SetHalfExtents(Convert::ToNative(value));
}
Vector3 BoxColliderBound::Min::get()
{
return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetMin());
}
void BoxColliderBound::Min::set(Vector3 value)
{
getNativeBoundObject<SHBoundingBox>().SetMin(Convert::ToNative(value));
}
Vector3 BoxColliderBound::Max::get()
{
return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetMax());
}
void BoxColliderBound::Max::set(Vector3 value)
{
getNativeBoundObject<SHBoundingBox>().SetMax(Convert::ToNative(value));
}
/*---------------------------------------------------------------------------------*/
/* BoxColliderBound - Usage Functions */
/*---------------------------------------------------------------------------------*/
bool BoxColliderBound::TestPoint(Vector3 point)
{
return getNativeBoundObject<SHBoundingBox>().TestPoint(Convert::ToNative(point));
}
bool BoxColliderBound::Raycast(Ray ray, float maxDistance)
{
return getNativeBoundObject<SHBoundingBox>().Raycast(Convert::ToNative(ray), maxDistance);
}
/*---------------------------------------------------------------------------------*/
/* BoxColliderBound - Properties */
/*---------------------------------------------------------------------------------*/
Vector3 SphereColliderBound::Center::get()
{
return Convert::ToCLI(getNativeBoundObject<SHBoundingSphere>().GetCenter());
}
void SphereColliderBound::Center::set(Vector3 value)
{
getNativeBoundObject<SHBoundingSphere>().SetCenter(Convert::ToNative(value));
}
float SphereColliderBound::Radius::get()
{
return getNativeBoundObject<SHBoundingSphere>().GetRadius();
}
void SphereColliderBound::Radius::set(float value)
{
getNativeBoundObject<SHBoundingSphere>().SetRadius(value);
}
/*---------------------------------------------------------------------------------*/
/* SphereColliderBound - Usage Functions */
/*---------------------------------------------------------------------------------*/
bool SphereColliderBound::TestPoint(Vector3 point)
{
return getNativeBoundObject<SHBoundingBox>().TestPoint(Convert::ToNative(point));
}
bool SphereColliderBound::Raycast(Ray ray, float maxDistance)
{
return getNativeBoundObject<SHBoundingBox>().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<int>(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<ColliderBound^>();
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<typename T>
T Collider::GetColliderBound(int index)
{
return safe_cast<T>(GetColliderBound(index));
}
}

View File

@ -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<typename ColliderBoundType>
ColliderBoundType& SHADE::ColliderBound::getNativeBoundObject()
{
SHColliderComponent* collider = SHComponentManager::GetComponent_s<SHColliderComponent>(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<ColliderBoundType&>(bounds);
}
catch (std::invalid_argument&)
{
throw gcnew System::IndexOutOfRangeException("Attempted to retrieve out of range ColliderBound!");
}
}
}

View File

@ -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
{
/// <summary>
/// Base interface for all Collider Shapes.
/// </summary>
public ref class ColliderBound
{
public:
/*-----------------------------------------------------------------------------*/
/* Usage Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Checks if the specified point is within this shape's bounds.
/// </summary>
/// <param name="point">Point to test with.</param>
/// <returns>True if the point is in the shape's bounds.</returns>
virtual bool TestPoint(Vector3 point) = 0;
/// <summary>
/// Computes a Raycast and checks if there is a collision with any object.
/// </summary>
/// <param name="ray">The ray to cast.</param>
/// <param name="maxDistance">Maximum distance for the raycast check.</param>
/// <returns>True if the ray intersects with an object in the scene.</returns>
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<typename ColliderBoundType>
ColliderBoundType& getNativeBoundObject();
internal:
/*-----------------------------------------------------------------------------*/
/* Setter Functions */
/*-----------------------------------------------------------------------------*/
void updateArrayIndex(int index);
};
/// <summary>
/// Box-shaped Collider Bound.
/// </summary>
public ref class BoxColliderBound : public ColliderBound
{
public:
/*-----------------------------------------------------------------------------*/
/* Properties */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Center of the Bounding Box formed by this bound.
/// </summary>
property Vector3 Center
{
Vector3 get();
void set(Vector3 value);
}
/// <summary>
/// Half of the scale of the Bounding Box formed by this bound.
/// </summary>
property Vector3 HalfExtents
{
Vector3 get();
void set(Vector3 value);
}
/// <summary>
/// Position of the bottom left back corner of the Bounding Box formed by this
/// bound.
/// </summary>
property Vector3 Min
{
Vector3 get();
void set(Vector3 value);
}
/// <summary>
/// Position of the top right front corner of the Bounding Box formed by this
/// bound.
/// </summary>
property Vector3 Max
{
Vector3 get();
void set(Vector3 value);
}
/*-----------------------------------------------------------------------------*/
/* ColliderBound Functions */
/*-----------------------------------------------------------------------------*/
/// <inheritdoc/>
bool TestPoint(Vector3 point) override;
/// <inheritdoc/>
bool Raycast(Ray ray, float maxDistance) override;
internal:
/*-----------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------*/
BoxColliderBound(int arrayIndex, Entity attachedEntity);
};
/// <summary>
/// Sphere-shaped Collider Bound.
/// </summary>
public ref class SphereColliderBound : public ColliderBound
{
public:
/*-----------------------------------------------------------------------------*/
/* Properties */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Center of the Bounding Sphere formed by this bound.
/// </summary>
property Vector3 Center
{
Vector3 get();
void set(Vector3 value);
}
/// <summary>
/// Radius of the Bounding Sphere formed by this bound.
/// </summary>
property float Radius
{
float get();
void set(float value);
}
/*-----------------------------------------------------------------------------*/
/* ColliderBound Functions */
/*-----------------------------------------------------------------------------*/
/// <inheritdoc/>
bool TestPoint(Vector3 point) override;
/// <inheritdoc/>
bool Raycast(Ray ray, float maxDistance) override;
internal:
/*-----------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------*/
SphereColliderBound(int arrayIndex, Entity attachedEntity);
};
/// <summary>
/// CLR version of the the SHADE Engine's SHColliderComponent.
/// A single Collider component can contain one or multiple Collider Bounds.
/// </summary>
public ref class Collider : public Component<SHColliderComponent>
{
internal:
/*-----------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Constructs a Collider Component that represents a native SHColliderComponent
/// component tied to the specified Entity.
/// </summary>
/// <param name="entity">Entity that this Component will be tied to.</param>
Collider(Entity entity);
public:
/*-----------------------------------------------------------------------------*/
/* Properties */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Total number of ColliderBounds in the Collider component.
/// </summary>
property int ColliderBoundsCount
{
int get();
}
/*-----------------------------------------------------------------------------*/
/* Usage Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Retrieves a ColliderBound at the specified index in the ColliderBound list.
/// </summary>
/// <param name="index">Index to retrieve a ColliderBound from.</param>
/// <returns>ColliderBound for the specified index.</returns>
ColliderBound^ GetColliderBound(int index);
/// <summary>
/// Retrieves a ColliderBound at the specified index in the ColliderBound list
/// and casts it to the appropriate type.
/// </summary>
/// <typeparam name="T">Type of the ColliderBound to cast to.</typeparam>
/// <param name="index">Index to retrieve a ColliderBound from.</param>
/// <returns>ColliderBound for the specified index.</returns>
generic<typename T> where T:ColliderBound
T GetColliderBound(int index);
private:
System::Collections::Generic::List<ColliderBound^>^ subColliderList; // TODO: Update elements in this list if the list on native collider changes
};
}
#include "Collider.h++"

View File

@ -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 }
{}
}

View File

@ -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
{
///<summary>
/// CLR version of the the SHADE Engine's Ray class that represents a ray in
/// 3-Dimensional space.
/// </summary>
public value struct Ray
{
public:
/*-----------------------------------------------------------------------------*/
/* Public Members */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// The start point of the ray.
/// </summary>
Vector3 Origin;
/// <summary>
/// The direction that a ray travels in.
/// </summary>
Vector3 Direction;
/*-----------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Creates a ray starting at origin along direction.
/// </summary>
/// <param name="origin">Source of the ray.</param>
/// <param name="direction">Direction the ray travels in.</param>
Ray(Vector3 origin, Vector3 direction);
};
}

View File

@ -40,6 +40,7 @@ namespace SHADE
const double Z = vec.z; const double Z = vec.z;
return SHVec3(X, Y, Z); return SHVec3(X, Y, Z);
} }
Vector3 Convert::ToCLI(const SHVec3& vec) Vector3 Convert::ToCLI(const SHVec3& vec)
{ {
return Vector3(vec.x, vec.y, vec.z); return Vector3(vec.x, vec.y, vec.z);
@ -56,6 +57,16 @@ namespace SHADE
return Vector2(vec.x, vec.y); 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 */ /* String Conversions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -18,10 +18,12 @@ of DigiPen Institute of Technology is prohibited.
#include "ECS_Base/Entity/SHEntity.h" #include "ECS_Base/Entity/SHEntity.h"
#include "Math/Vector/SHVec2.h" #include "Math/Vector/SHVec2.h"
#include "Math/Vector/SHVec3.h" #include "Math/Vector/SHVec3.h"
#include "Math/SHRay.h"
// Project Includes // Project Includes
#include "Engine/Entity.hxx" #include "Engine/Entity.hxx"
#include "Math/Vector2.hxx" #include "Math/Vector2.hxx"
#include "Math/Vector3.hxx" #include "Math/Vector3.hxx"
#include "Math/Ray.hxx"
namespace SHADE namespace SHADE
{ {
@ -74,6 +76,18 @@ namespace SHADE
/// <param name="vec">The native Vector2 to convert from.</param> /// <param name="vec">The native Vector2 to convert from.</param>
/// <returns>Managed copy of a native Vector2.</returns> /// <returns>Managed copy of a native Vector2.</returns>
static Vector2 ToCLI(const SHVec2& vec); static Vector2 ToCLI(const SHVec2& vec);
/// <summary>
/// Converts from a managed Vector2 to a native Vector2.
/// </summary>
/// <param name="vec">The managed Vector2 to convert from.</param>
/// <returns>Native copy of a managed Vector2.</returns>
static SHRay ToNative(Ray vec);
/// <summary>
/// Converts from a native Vector2 to a managed Vector2.
/// </summary>
/// <param name="vec">The native Vector2 to convert from.</param>
/// <returns>Managed copy of a native Vector2.</returns>
static Ray ToCLI(const SHRay& vec);
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* String Conversions */ /* String Conversions */