Merge branch 'SP3-2-Physics' into PlayerControllerWIthNewPhysics

This commit is contained in:
Glence 2023-03-04 00:27:38 +08:00
commit ac99eb9ba0
33 changed files with 204 additions and 512 deletions

File diff suppressed because it is too large Load Diff

View File

@ -10,9 +10,12 @@
IsActive: true IsActive: true
RigidBody Component: RigidBody Component:
Type: Dynamic Type: Dynamic
Auto Mass: false
Mass: 1
Drag: 0.00999999978 Drag: 0.00999999978
Angular Drag: 0.100000001 Angular Drag: 0.100000001
Use Gravity: true Use Gravity: true
Gravity Scale: 1
Interpolate: false Interpolate: false
Sleeping Enabled: true Sleeping Enabled: true
Freeze Position X: false Freeze Position X: false
@ -35,10 +38,6 @@
Rotation Offset: {x: 0, y: 0, z: 0} Rotation Offset: {x: 0, y: 0, z: 0}
IsActive: true IsActive: true
Scripts: Scripts:
- Type: PhysicsTestObj
Enabled: true
forceAmount: 50
torqueAmount: 500
- Type: CollisionTest - Type: CollisionTest
Enabled: true Enabled: true
- EID: 1 - EID: 1
@ -75,10 +74,10 @@
Yaw: 0 Yaw: 0
Roll: 0 Roll: 0
Width: 1920 Width: 1920
Height: 1080
Near: 0.00999999978 Near: 0.00999999978
Far: 10000 Far: 10000
Perspective: true Perspective: true
FOV: 90
IsActive: true IsActive: true
Scripts: ~ Scripts: ~
- EID: 65539 - EID: 65539
@ -173,43 +172,6 @@
Rotation Offset: {x: 0, y: 0, z: 0} Rotation Offset: {x: 0, y: 0, z: 0}
IsActive: true IsActive: true
Scripts: ~ Scripts: ~
- EID: 7
Name: Default
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: 0, y: 0, z: 3}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 1, y: 1, z: 1}
IsActive: true
RigidBody Component:
Type: Dynamic
Drag: 0.00999999978
Angular Drag: 0.100000001
Use Gravity: true
Interpolate: true
Sleeping Enabled: true
Freeze Position X: false
Freeze Position Y: false
Freeze Position Z: false
Freeze Rotation X: false
Freeze Rotation Y: false
Freeze Rotation Z: false
IsActive: true
Collider Component:
Colliders:
- Is Trigger: false
Collision Tag: 1
Type: Box
Half Extents: {x: 1, y: 1, z: 1}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0, z: 0}
Rotation Offset: {x: 0, y: 0, z: 0}
IsActive: true
Scripts: ~
- EID: 8 - EID: 8
Name: Target Name: Target
IsActive: true IsActive: true

View File

@ -1,4 +1,4 @@
/********************************************************************* /*********************************************************************
* \file LeafChase.cs * \file LeafChase.cs
* \author Ryan Wang Nian Jing * \author Ryan Wang Nian Jing
* \brief Leaf node implementation for AI chasing the player * \brief Leaf node implementation for AI chasing the player

View File

@ -1,4 +1,4 @@
/********************************************************************* /*********************************************************************
* \file LeafPatrol.cs * \file LeafPatrol.cs
* \author Ryan Wang Nian Jing * \author Ryan Wang Nian Jing
* \brief Leaf node implementation for patrolling AI * \brief Leaf node implementation for patrolling AI

View File

@ -1,4 +1,4 @@
/********************************************************************* /*********************************************************************
* \file LeafSearch.cs * \file LeafSearch.cs
* \author Ryan Wang Nian Jing * \author Ryan Wang Nian Jing
* \brief Leaf node implementation for AI searching for player * \brief Leaf node implementation for AI searching for player

View File

@ -1,4 +1,4 @@
using SHADE; using SHADE;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using static Item; using static Item;
@ -65,37 +65,8 @@ public class PhysicsTestObj : Script
}; };
public float forceAmount = 50.0f; public float forceAmount = 50.0f;
public float torqueAmount = 25.0f; public float torqueAmount = 500.0f;
protected override void onTriggerEnter(CollisionInfo info)
{
Debug.Log("Trigger Enter");
}
protected override void onTriggerStay(CollisionInfo info)
{
Debug.Log("Trigger Stay");
}
protected override void onTriggerExit(CollisionInfo info)
{
Debug.Log("Trigger Exit");
}
protected override void onCollisionEnter(CollisionInfo info)
{
Debug.Log("Collision Enter");
}
protected override void onCollisionStay(CollisionInfo info)
{
Debug.Log("Collision Stay");
}
protected override void onCollisionExit(CollisionInfo info)
{
Debug.Log("Collision Exit");
}
protected override void awake() protected override void awake()
{ {
tf = GetComponent<Transform>(); tf = GetComponent<Transform>();

View File

@ -1,4 +1,4 @@
using System; using System;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using SHADE; using SHADE;
using SHADE_Scripting.UI; using SHADE_Scripting.UI;

View File

@ -1,4 +1,4 @@
using System; using System;
using SHADE; using SHADE;
using SHADE_Scripting.Audio; using SHADE_Scripting.Audio;
using SHADE_Scripting.UI; using SHADE_Scripting.UI;

View File

@ -1,4 +1,4 @@
using System; using System;
using SHADE; using SHADE;
using SHADE_Scripting.Audio; using SHADE_Scripting.Audio;
using SHADE_Scripting.UI; using SHADE_Scripting.UI;

View File

@ -436,24 +436,15 @@ namespace SHADE
if (ImGui::Selectable("Box Collider")) if (ImGui::Selectable("Box Collider"))
{ {
auto* compositeCollider = dynamic_cast<SHCompositeCollider* const>(component->GetCollider()); auto* compositeCollider = reinterpret_cast<SHCompositeCollider* const>(component->GetCollider());
compositeCollider->AddBoxCollisionShape(SHVec3::One); compositeCollider->AddBoxCollisionShape(SHVec3::One);
} }
if (ImGui::Selectable("Sphere Collider")) if (ImGui::Selectable("Sphere Collider"))
{ {
auto* compositeCollider = dynamic_cast<SHCompositeCollider* const>(component->GetCollider()); auto* compositeCollider = reinterpret_cast<SHCompositeCollider* const>(component->GetCollider());
compositeCollider->AddSphereCollisionShape(1.0f); compositeCollider->AddSphereCollisionShape(1.0f);
} }
//No idea why this doesn't work
//if (newColl > 0)
//{
// auto newCollisionShape = component->GetCollisionShape(newColl);
// auto prevCollisionShapeInSeq = component->GetCollisionShape(newColl - 1);
// newCollisionShape.SetCollisionTag(SHCollisionTagMatrix::GetTag(prevCollisionShapeInSeq.GetCollisionTag().GetName()));
//}
ImGui::EndMenu(); ImGui::EndMenu();
} }
} }

View File

@ -10,6 +10,8 @@
#include <SHpch.h> #include <SHpch.h>
#include <reactphysics3d/mathematics/Ray.h>
// Primary Header // Primary Header
#include "SHRay.h" #include "SHRay.h"

View File

@ -13,8 +13,13 @@
// Project Headers // Project Headers
#include "Vector/SHVec3.h" #include "Vector/SHVec3.h"
/*-------------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-------------------------------------------------------------------------------------*/
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -47,8 +47,8 @@ namespace SHADE
bool SHCollision::ConvexVsConvex(const SHCollisionShape& A, const SHCollisionShape& B) noexcept bool SHCollision::ConvexVsConvex(const SHCollisionShape& A, const SHCollisionShape& B) noexcept
{ {
const SHConvexPolyhedron& POLY_A = dynamic_cast<const SHConvexPolyhedron&>(A); const SHConvexPolyhedron& POLY_A = reinterpret_cast<const SHConvexPolyhedron&>(A);
const SHConvexPolyhedron& POLY_B = dynamic_cast<const SHConvexPolyhedron&>(B); const SHConvexPolyhedron& POLY_B = reinterpret_cast<const SHConvexPolyhedron&>(B);
const SHCollisionUtils::SHCollisionUtils::FaceQuery FACE_QUERY_A = queryFaceDirections(POLY_A, POLY_B); const SHCollisionUtils::SHCollisionUtils::FaceQuery FACE_QUERY_A = queryFaceDirections(POLY_A, POLY_B);
if (FACE_QUERY_A.bestDistance > 0.0f) if (FACE_QUERY_A.bestDistance > 0.0f)
@ -70,8 +70,8 @@ namespace SHADE
static constexpr float ABSOLUTE_TOLERANCE = 0.01f; static constexpr float ABSOLUTE_TOLERANCE = 0.01f;
static constexpr float RELATIVE_TOLERANCE = 0.95f; static constexpr float RELATIVE_TOLERANCE = 0.95f;
const SHConvexPolyhedron& POLY_A = dynamic_cast<const SHConvexPolyhedron&>(A); const SHConvexPolyhedron& POLY_A = reinterpret_cast<const SHConvexPolyhedron&>(A);
const SHConvexPolyhedron& POLY_B = dynamic_cast<const SHConvexPolyhedron&>(B); const SHConvexPolyhedron& POLY_B = reinterpret_cast<const SHConvexPolyhedron&>(B);
const SHCollisionUtils::ShapeTransform TF_A { POLY_A.GetWorldCentroid(), POLY_A.GetWorldOrientation() }; const SHCollisionUtils::ShapeTransform TF_A { POLY_A.GetWorldCentroid(), POLY_A.GetWorldOrientation() };
const SHCollisionUtils::ShapeTransform TF_B { POLY_B.GetWorldCentroid(), POLY_B.GetWorldOrientation() }; const SHCollisionUtils::ShapeTransform TF_B { POLY_B.GetWorldCentroid(), POLY_B.GetWorldOrientation() };

View File

@ -42,8 +42,8 @@ namespace SHADE
bool SHCollision::SphereVsConvex(const SHCollisionShape& A, const SHCollisionShape& B) noexcept bool SHCollision::SphereVsConvex(const SHCollisionShape& A, const SHCollisionShape& B) noexcept
{ {
const SHSphere& SPHERE = dynamic_cast<const SHSphere&>(A); const SHSphere& SPHERE = reinterpret_cast<const SHSphere&>(A);
const SHConvexPolyhedron& POLYHEDRON = dynamic_cast<const SHConvexPolyhedron&>(B); const SHConvexPolyhedron& POLYHEDRON = reinterpret_cast<const SHConvexPolyhedron&>(B);
const SHVec3 CENTER = SPHERE.Center; const SHVec3 CENTER = SPHERE.Center;
const float RADIUS = SPHERE.GetWorldRadius(); const float RADIUS = SPHERE.GetWorldRadius();
@ -90,8 +90,8 @@ namespace SHADE
{ {
// Convert to underlying types // Convert to underlying types
// For the convex, we only need the convex polyhedron shape since the get vertex is pure virtual. // For the convex, we only need the convex polyhedron shape since the get vertex is pure virtual.
const SHSphere& SPHERE = dynamic_cast<const SHSphere&>(A); const SHSphere& SPHERE = reinterpret_cast<const SHSphere&>(A);
const SHConvexPolyhedron& POLY = dynamic_cast<const SHConvexPolyhedron&>(B); const SHConvexPolyhedron& POLY = reinterpret_cast<const SHConvexPolyhedron&>(B);
const SHVec3 CENTER = SPHERE.Center; const SHVec3 CENTER = SPHERE.Center;
const float RADIUS = SPHERE.GetWorldRadius(); const float RADIUS = SPHERE.GetWorldRadius();

View File

@ -26,8 +26,8 @@ namespace SHADE
bool SHCollision::SphereVsSphere(const SHCollisionShape& A, const SHCollisionShape& B) noexcept bool SHCollision::SphereVsSphere(const SHCollisionShape& A, const SHCollisionShape& B) noexcept
{ {
const SHSphere& SPHERE_A = dynamic_cast<const SHSphere&>(A); const SHSphere& SPHERE_A = reinterpret_cast<const SHSphere&>(A);
const SHSphere& SPHERE_B = dynamic_cast<const SHSphere&>(B); const SHSphere& SPHERE_B = reinterpret_cast<const SHSphere&>(B);
const SHVec3 CENTER_A = SPHERE_A.Center; const SHVec3 CENTER_A = SPHERE_A.Center;
const float RADIUS_A = SPHERE_A.Radius; const float RADIUS_A = SPHERE_A.Radius;
@ -48,8 +48,8 @@ namespace SHADE
bool SHCollision::SphereVsSphere(SHManifold& manifold, const SHCollisionShape& A, const SHCollisionShape& B) noexcept bool SHCollision::SphereVsSphere(SHManifold& manifold, const SHCollisionShape& A, const SHCollisionShape& B) noexcept
{ {
// Convert to underlying types // Convert to underlying types
const SHSphere& SPHERE_A = dynamic_cast<const SHSphere&>(A); const SHSphere& SPHERE_A = reinterpret_cast<const SHSphere&>(A);
const SHSphere& SPHERE_B = dynamic_cast<const SHSphere&>(B); const SHSphere& SPHERE_B = reinterpret_cast<const SHSphere&>(B);
const SHVec3 CENTER_A = SPHERE_A.Center; const SHVec3 CENTER_A = SPHERE_A.Center;
const float RADIUS_A = SPHERE_A.Radius; const float RADIUS_A = SPHERE_A.Radius;

View File

@ -338,7 +338,7 @@ namespace SHADE
{ {
case SHCollisionShape::Type::BOX: case SHCollisionShape::Type::BOX:
{ {
const SHBox* RHS_BOX = dynamic_cast<const SHBox*>(shape); const SHBox* RHS_BOX = reinterpret_cast<const SHBox*>(shape);
const SHBoxCreateInfo BOX_CREATE_INFO const SHBoxCreateInfo BOX_CREATE_INFO
{ {
@ -361,7 +361,7 @@ namespace SHADE
} }
case SHCollisionShape::Type::SPHERE: case SHCollisionShape::Type::SPHERE:
{ {
const SHSphere* RHS_SPHERE = dynamic_cast<const SHSphere*>(shape); const SHSphere* RHS_SPHERE = reinterpret_cast<const SHSphere*>(shape);
const SHSphereCreateInfo SPHERE_CREATE_INFO const SHSphereCreateInfo SPHERE_CREATE_INFO
{ {

View File

@ -209,12 +209,12 @@ namespace SHADE
{ {
case SHCollisionShape::Type::SPHERE: case SHCollisionShape::Type::SPHERE:
{ {
baseResult = dynamic_cast<const SHSphere*>(SHAPE)->Raycast(info.ray); baseResult = reinterpret_cast<const SHSphere*>(SHAPE)->Raycast(info.ray);
break; break;
} }
case SHCollisionShape::Type::BOX: case SHCollisionShape::Type::BOX:
{ {
baseResult = dynamic_cast<const SHBox*>(SHAPE)->Raycast(info.ray); baseResult = reinterpret_cast<const SHBox*>(SHAPE)->Raycast(info.ray);
break; break;
} }
case SHCollisionShape::Type::CAPSULE: case SHCollisionShape::Type::CAPSULE:

View File

@ -76,8 +76,6 @@ namespace SHADE
continue; continue;
const auto* SHAPE_A = manifold.shapeA; const auto* SHAPE_A = manifold.shapeA;
const auto* SHAPE_B = manifold.shapeB;
const SHCollisionUtils::ShapeTransform TF_A = { SHAPE_A->GetWorldCentroid(), SHAPE_A->GetWorldOrientation() }; const SHCollisionUtils::ShapeTransform TF_A = { SHAPE_A->GetWorldCentroid(), SHAPE_A->GetWorldOrientation() };
for (uint32_t i = 0; i < manifold.numContacts; ++i) for (uint32_t i = 0; i < manifold.numContacts; ++i)
@ -138,22 +136,41 @@ namespace SHADE
removeInvalidObject(manifolds, eid, shapeIndex); removeInvalidObject(manifolds, eid, shapeIndex);
} }
void SHContactManager::RemoveExpiredContacts() noexcept
{
// Manifolds
for (auto manifoldsIter = manifolds.begin(); manifoldsIter != manifolds.end();)
{
const auto STATE = manifoldsIter->second.state;
if (STATE == SHCollisionState::INVALID || STATE == SHCollisionState::EXIT)
manifoldsIter = manifolds.erase(manifoldsIter);
else
++manifoldsIter;
}
// Triggers
for (auto triggersIter = triggers.begin(); triggersIter != triggers.end();)
{
const auto STATE = triggersIter->second.state;
if (STATE == SHCollisionState::INVALID || STATE == SHCollisionState::EXIT)
triggersIter = triggers.erase(triggersIter);
else
++triggersIter;
}
}
void SHContactManager::Update() noexcept void SHContactManager::Update() noexcept
{ {
// Clear expired or invalid collisions. If not, test collision.
for (auto manifoldPair = manifolds.begin(); manifoldPair != manifolds.end();) for (auto manifoldPair = manifolds.begin(); manifoldPair != manifolds.end();)
{ {
// Test collision of every manifold.
SHManifold& manifold = manifoldPair->second; SHManifold& manifold = manifoldPair->second;
SHManifold oldManifold = manifold; SHManifold oldManifold = manifold;
const bool IS_COLLIDING = SHCollisionDispatcher::Collide(manifold, *manifold.shapeA, *manifold.shapeB); const bool IS_COLLIDING = SHCollisionDispatcher::Collide(manifold, *manifold.shapeA, *manifold.shapeB);
updateCollisionState(IS_COLLIDING, manifold.state);
auto& collisionState = manifold.state; // For any false positives
updateCollisionState(IS_COLLIDING, collisionState); if (manifold.state == SHCollisionState::INVALID)
const bool IS_INVALID = collisionState == SHCollisionState::INVALID;
if (IS_INVALID)
{ {
manifoldPair = manifolds.erase(manifoldPair); manifoldPair = manifolds.erase(manifoldPair);
continue; continue;
@ -163,19 +180,16 @@ namespace SHADE
++manifoldPair; ++manifoldPair;
} }
// Clear expired or invalid triggers, If not, test collision.
for (auto triggerPair = triggers.begin(); triggerPair != triggers.end();) for (auto triggerPair = triggers.begin(); triggerPair != triggers.end();)
{ {
// Test collision of every trigger. // Test collision of every trigger.
Trigger& trigger = triggerPair->second; Trigger& trigger = triggerPair->second;
const bool IS_COLLIDING = SHCollisionDispatcher::Collide(*trigger.A, *trigger.B); const bool IS_COLLIDING = SHCollisionDispatcher::Collide(*trigger.A, *trigger.B);
updateCollisionState(IS_COLLIDING, trigger.state);
auto& collisionState = trigger.state; // For any false positives
updateCollisionState(IS_COLLIDING, collisionState); if (trigger.state == SHCollisionState::INVALID)
const bool IS_INVALID = collisionState == SHCollisionState::INVALID;
if (IS_INVALID)
triggerPair = triggers.erase(triggerPair); triggerPair = triggers.erase(triggerPair);
else else
++triggerPair; ++triggerPair;
@ -238,7 +252,11 @@ namespace SHADE
{ {
// New states start at invalid. In the first frame of collision, move to enter. // New states start at invalid. In the first frame of collision, move to enter.
// If it already in enter, move to stay // If it already in enter, move to stay
state = state == SHCollisionState::INVALID ? SHCollisionState::ENTER : SHCollisionState::STAY; if (state == SHCollisionState::ENTER)
state = SHCollisionState::STAY;
if (state == SHCollisionState::INVALID)
state = SHCollisionState::ENTER;
} }
else else
{ {

View File

@ -79,6 +79,12 @@ namespace SHADE
void RemoveInvalidatedManifold (EntityID eid) noexcept; void RemoveInvalidatedManifold (EntityID eid) noexcept;
void RemoveInvalidatedManifold (EntityID eid, uint32_t shapeIndex) noexcept; void RemoveInvalidatedManifold (EntityID eid, uint32_t shapeIndex) noexcept;
/**
* @brief
* Removes any contact manifold or triggers that are in the exit or invalid state.
*/
void RemoveExpiredContacts () noexcept;
/** /**
* @brief * @brief
* Removes any invalidated contacts and triggers, then performs narrowphase collision * Removes any invalidated contacts and triggers, then performs narrowphase collision

View File

@ -86,13 +86,19 @@ namespace SHADE
void SHPhysicsWorld::Step(float dt) void SHPhysicsWorld::Step(float dt)
{ {
/* /*
* Detect Collisions * Detect Collisions
*/ */
contactManager.RemoveExpiredContacts();
if (collisionSpace) if (collisionSpace)
collisionSpace->DetectCollisions(); collisionSpace->DetectCollisions();
// TODO: Build Islands
/* /*
* Integrate Forces * Integrate Forces
*/ */
@ -106,7 +112,6 @@ namespace SHADE
integrateForces(*rigidBody, dt); integrateForces(*rigidBody, dt);
} }
/* /*
* Resolve Contacts * Resolve Contacts
*/ */

View File

@ -9,6 +9,7 @@
****************************************************************************************/ ****************************************************************************************/
#include <SHpch.h> #include <SHpch.h>
#include <reactphysics3d/reactphysics3d.h>
// Primary Header // Primary Header
#include "SHColliderComponent.h" #include "SHColliderComponent.h"

View File

@ -10,6 +10,8 @@
#pragma once #pragma once
#include <vector>
#include <rttr/registration> #include <rttr/registration>
// Project Headers // Project Headers
@ -29,6 +31,7 @@ namespace SHADE
/* Friends */ /* Friends */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
friend class SHCollisionShape;
friend class SHPhysicsSystem; friend class SHPhysicsSystem;
friend struct SHPhysicsObject; friend struct SHPhysicsObject;

View File

@ -17,6 +17,15 @@
#include "Math/Vector/SHVec3.h" #include "Math/Vector/SHVec3.h"
#include "Physics/Dynamics/SHRigidBody.h" #include "Physics/Dynamics/SHRigidBody.h"
/*-------------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-------------------------------------------------------------------------------------*/
namespace reactphysics3d
{
class RigidBody;
}
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -141,6 +150,22 @@ namespace SHADE
void ClearForces () const noexcept; void ClearForces () const noexcept;
private: private:
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
enum class Flags : uint8_t
{
GRAVITY = 0x1
, SLEEPING = 0x2
, LINEAR_X = 0x4
, LINEAR_Y = 0x8
, LINEAR_Z = 0x10
, ANGULAR_X = 0x20
, ANGULAR_Y = 0x40
, ANGULAR_Z = 0x80
};
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -15,6 +15,7 @@
// Project Headers // Project Headers
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/SHEditor.h"
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h" #include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
#include "Physics/System/SHPhysicsSystem.h" #include "Physics/System/SHPhysicsSystem.h"
@ -36,7 +37,6 @@ namespace SHADE
void SHPhysicsDebugDrawSystem::PhysicsDebugDraw::Execute(double) noexcept void SHPhysicsDebugDrawSystem::PhysicsDebugDraw::Execute(double) noexcept
{ {
#ifdef SHEDITOR
auto* physicsDebugDrawSystem = reinterpret_cast<SHPhysicsDebugDrawSystem*>(GetSystem()); auto* physicsDebugDrawSystem = reinterpret_cast<SHPhysicsDebugDrawSystem*>(GetSystem());
if (!physicsDebugDrawSystem->IsDebugDrawActive()) if (!physicsDebugDrawSystem->IsDebugDrawActive())
@ -86,17 +86,22 @@ namespace SHADE
} }
} }
#ifdef SHEDITOR
if (DRAW_RAYCASTS) if (DRAW_RAYCASTS)
{ {
const SHColour& RAY_COLOUR = physicsDebugDrawSystem->DEBUG_DRAW_COLOURS[SHUtilities::ConvertEnum(Colours::RAYCAST)]; const SHColour& RAY_COLOUR = physicsDebugDrawSystem->DEBUG_DRAW_COLOURS[SHUtilities::ConvertEnum(Colours::RAYCAST)];
const auto& RAYS = physicsSystem->raycastHits; auto& rays = physicsSystem->raycastHits;
for (const auto& hit : RAYS) for (const auto& hit : rays)
debugDrawSystem->DrawLine(hit.start, hit.end, RAY_COLOUR, true); debugDrawSystem->DrawLine(hit.start, hit.end, RAY_COLOUR, true);
// Clear rays for the physics system // Clear the raycast hit container only in play mode.
physicsSystem->raycastHits.clear(); // No other raycasts are assumed to be done in pause or stop mode.
const auto EDITOR_STATE = SHSystemManager::GetSystem<SHEditor>()->editorState;
if (EDITOR_STATE == SHEditor::State::PLAY)
rays.clear();
} }
#endif
if (DRAW_BROADPHASE) if (DRAW_BROADPHASE)
{ {
@ -110,7 +115,6 @@ namespace SHADE
debugDrawSystem->DrawWireCube(TRS, AABB_COLOUR); debugDrawSystem->DrawWireCube(TRS, AABB_COLOUR);
} }
} }
#endif
} }
} // namespace SHADE } // namespace SHADE

View File

@ -93,10 +93,6 @@ namespace SHADE
*/ */
} }
} }
// Collision & Trigger messages
if (scriptingSystem != nullptr)
scriptingSystem->ExecuteCollisionFunctions();
} }
} // namespace SHADE } // namespace SHADE

View File

@ -35,10 +35,10 @@ namespace SHADE
{ {
auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem()); auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
auto* scriptEngine = SHSystemManager::GetSystem<SHScriptEngine>(); auto* scriptingSystem = SHSystemManager::GetSystem<SHScriptEngine>();
if (!scriptEngine) if (!scriptingSystem)
{ {
SHLOGV_ERROR("Unable to invoke FixedUpdate() on scripts due to missing ScriptEngine!") SHLOGV_ERROR("Unable to invoke FixedUpdate() on scripts due to missing SHScriptEngine!")
} }
const double FIXED_DT = physicsSystem->fixedDT; const double FIXED_DT = physicsSystem->fixedDT;
@ -47,12 +47,15 @@ namespace SHADE
int count = 0; int count = 0;
while (accumulatedTime > FIXED_DT) while (accumulatedTime > FIXED_DT)
{ {
if (scriptEngine) if (scriptingSystem)
scriptEngine->ExecuteFixedUpdates(); scriptingSystem->ExecuteFixedUpdates();
if (physicsSystem->physicsWorld) if (physicsSystem->physicsWorld)
physicsSystem->physicsWorld->Step(static_cast<float>(FIXED_DT)); physicsSystem->physicsWorld->Step(static_cast<float>(FIXED_DT));
if (scriptingSystem != nullptr)
scriptingSystem->ExecuteCollisionFunctions();
accumulatedTime -= FIXED_DT; accumulatedTime -= FIXED_DT;
++count; ++count;
} }

View File

@ -287,6 +287,11 @@ namespace SHADE
collisionSpace->RemoveCollider(PHYSICS_OBJECT.collider); collisionSpace->RemoveCollider(PHYSICS_OBJECT.collider);
} }
#ifdef SHEDITOR
// HACK: Editor stop always goes into scene exit
raycastHits.clear();
#endif
delete collisionSpace; delete collisionSpace;
collisionSpace = nullptr; collisionSpace = nullptr;

View File

@ -39,8 +39,12 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
friend class SHPhysicsDebugDrawSystem; friend class SHPhysicsDebugDrawSystem;
friend class SHCollisionListener;
friend class SHRaycaster;
public: public:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */ /* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -17,7 +17,6 @@ of DigiPen Institute of Technology is prohibited.
#include "Physics/Collision/SHCollisionSpace.h" #include "Physics/Collision/SHCollisionSpace.h"
#include "Physics/Collision/Contacts/SHCollisionEvents.h" #include "Physics/Collision/Contacts/SHCollisionEvents.h"
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -29,7 +28,6 @@ namespace SHADE
struct SHPhysicsRaycastResult; struct SHPhysicsRaycastResult;
struct SHCollisionSpace::RaycastInfo; struct SHCollisionSpace::RaycastInfo;
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -40,6 +38,48 @@ namespace SHADE
class SH_API SHPhysicsSystemInterface final class SH_API SHPhysicsSystemInterface final
{ {
public: public:
struct RaycastInfo
{
private:
/*-------------------------------------------------------------------------------*/
/* Friends */
/*-------------------------------------------------------------------------------*/
friend class SHPhysicsSystemInterface;
public:
/*-------------------------------------------------------------------------------*/
/* Data Members */
/*-------------------------------------------------------------------------------*/
bool continuous = false;
uint16_t layers = static_cast<uint16_t>(SHCollisionTag::Layer::ALL);
float distance = std::numeric_limits<float>::infinity();
SHRay ray;
/*-------------------------------------------------------------------------------*/
/* Setter Functions */
/*-------------------------------------------------------------------------------*/
/**
* @brief
* Sets the collider ID for the raycast. Setting this specifies that the ray
* should ignore this collider.
* @param eid
* The entity ID of the collider.
*/
void SetColliderID(EntityID eid) noexcept { colliderEntityID = eid; }
private:
/*-------------------------------------------------------------------------------*/
/* Data Members */
/*-------------------------------------------------------------------------------*/
std::optional<EntityID> colliderEntityID;
};
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Constructor */ /* Constructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -4,7 +4,6 @@
\par email: kahwei.tng\@digipen.edu \par email: kahwei.tng\@digipen.edu
\date Oct 20, 2022 \date Oct 20, 2022
\brief Contains the definition of the functions of the managed Collider class. \brief Contains the definition of the functions of the managed Collider class.
Note: This file is written in C++17/CLI. Note: This file is written in C++17/CLI.
Copyright (C) 2022 DigiPen Institute of Technology. Copyright (C) 2022 DigiPen Institute of Technology.
@ -15,6 +14,9 @@ of DigiPen Institute of Technology is prohibited.
#include "SHpch.h" #include "SHpch.h"
// Primary Header // Primary Header
#include "Collider.hxx" #include "Collider.hxx"
#include "Physics/Collision/Shapes/SHBox.h"
#include "Physics/Collision/Shapes/SHSphere.h"
#include "Utility/Debug.hxx" #include "Utility/Debug.hxx"
namespace SHADE namespace SHADE
@ -120,7 +122,7 @@ namespace SHADE
/* BoxCollider - Constructors */ /* BoxCollider - Constructors */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
BoxCollider::BoxCollider(int arrayIdx, Entity attachedEntity) BoxCollider::BoxCollider(int arrayIdx, Entity attachedEntity)
: CollisionShape { arrayIndex, attachedEntity } : CollisionShape { arrayIdx, attachedEntity }
{} {}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -307,9 +309,9 @@ namespace SHADE
case SHCollisionShape::Type::SPHERE: case SHCollisionShape::Type::SPHERE:
bound = gcnew SphereCollider(i, Owner.GetEntity()); bound = gcnew SphereCollider(i, Owner.GetEntity());
break; break;
case SHCollisionShape::Type::CAPSULE: //case SHCollisionShape::Type::CAPSULE:
// TODO // // TODO
break; // break;
default: default:
Debug::LogWarning("[Collider] An invalid Collider Type was detected. Skipping."); Debug::LogWarning("[Collider] An invalid Collider Type was detected. Skipping.");
break; break;

View File

@ -31,7 +31,7 @@ namespace SHADE
if (!shape || shape->GetType() == SHCollisionShape::Type::INVALID) if (!shape || shape->GetType() == SHCollisionShape::Type::INVALID)
throw gcnew System::InvalidOperationException("Attempted to retrieve invalid CollisionShape."); throw gcnew System::InvalidOperationException("Attempted to retrieve invalid CollisionShape.");
return dynamic_cast<CollisionShapeType&>(*shape); return reinterpret_cast<CollisionShapeType&>(*shape);
} }
catch (std::invalid_argument&) catch (std::invalid_argument&)
{ {

View File

@ -1,7 +1,9 @@
/************************************************************************************//*! /************************************************************************************//*!
\file Collider.hxx \file Collider.hxx
\author Tng Kah Wei, kahwei.tng, 390009620 \author Tng Kah Wei, kahwei.tng, 390009620
Diren D Bharwani, diren.dbharwani, 390002520
\par email: kahwei.tng\@digipen.edu \par email: kahwei.tng\@digipen.edu
email: diren.dbharwani\@digipen.edu
\date Oct 20, 2022 \date Oct 20, 2022
\brief Contains the definition of the managed Collider class with the \brief Contains the definition of the managed Collider class with the
declaration of functions for working with it. declaration of functions for working with it.