diff --git a/Assets/Scenes/PhysicsTest.shade b/Assets/Scenes/PhysicsTest.shade index 442ff096..7966307c 100644 --- a/Assets/Scenes/PhysicsTest.shade +++ b/Assets/Scenes/PhysicsTest.shade @@ -38,10 +38,6 @@ Rotation Offset: {x: 0, y: 0, z: 0} IsActive: true Scripts: - - Type: PhysicsTestObj - Enabled: true - forceAmount: 50 - torqueAmount: 500 - Type: CollisionTest Enabled: true - EID: 1 @@ -176,46 +172,6 @@ Rotation Offset: {x: 0, y: 0, z: 0} IsActive: true 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 - Auto Mass: false - Mass: 1 - Drag: 0.00999999978 - Angular Drag: 0.100000001 - Use Gravity: true - Gravity Scale: 1 - 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 Name: Target IsActive: true diff --git a/SHADE_Engine/src/Physics/Dynamics/SHContactManager.cpp b/SHADE_Engine/src/Physics/Dynamics/SHContactManager.cpp index caf2a7d6..c9b8dc5f 100644 --- a/SHADE_Engine/src/Physics/Dynamics/SHContactManager.cpp +++ b/SHADE_Engine/src/Physics/Dynamics/SHContactManager.cpp @@ -76,8 +76,6 @@ namespace SHADE continue; const auto* SHAPE_A = manifold.shapeA; - const auto* SHAPE_B = manifold.shapeB; - const SHCollisionUtils::ShapeTransform TF_A = { SHAPE_A->GetWorldCentroid(), SHAPE_A->GetWorldOrientation() }; for (uint32_t i = 0; i < manifold.numContacts; ++i) @@ -138,22 +136,41 @@ namespace SHADE 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 { - // Clear expired or invalid collisions. If not, test collision. for (auto manifoldPair = manifolds.begin(); manifoldPair != manifolds.end();) { - // Test collision of every manifold. - SHManifold& manifold = manifoldPair->second; + SHManifold& manifold = manifoldPair->second; SHManifold oldManifold = manifold; const bool IS_COLLIDING = SHCollisionDispatcher::Collide(manifold, *manifold.shapeA, *manifold.shapeB); + updateCollisionState(IS_COLLIDING, manifold.state); - auto& collisionState = manifold.state; - updateCollisionState(IS_COLLIDING, collisionState); - - const bool IS_INVALID = collisionState == SHCollisionState::INVALID; - if (IS_INVALID) + // For any false positives + if (manifold.state == SHCollisionState::INVALID) { manifoldPair = manifolds.erase(manifoldPair); continue; @@ -163,19 +180,16 @@ namespace SHADE ++manifoldPair; } - // Clear expired or invalid triggers, If not, test collision. for (auto triggerPair = triggers.begin(); triggerPair != triggers.end();) { // Test collision of every trigger. - Trigger& trigger = triggerPair->second; + Trigger& trigger = triggerPair->second; const bool IS_COLLIDING = SHCollisionDispatcher::Collide(*trigger.A, *trigger.B); + updateCollisionState(IS_COLLIDING, trigger.state); - auto& collisionState = trigger.state; - updateCollisionState(IS_COLLIDING, collisionState); - - const bool IS_INVALID = collisionState == SHCollisionState::INVALID; - if (IS_INVALID) + // For any false positives + if (trigger.state == SHCollisionState::INVALID) triggerPair = triggers.erase(triggerPair); else ++triggerPair; @@ -238,7 +252,11 @@ namespace SHADE { // New states start at invalid. In the first frame of collision, move to enter. // 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 { diff --git a/SHADE_Engine/src/Physics/Dynamics/SHContactManager.h b/SHADE_Engine/src/Physics/Dynamics/SHContactManager.h index 81f37146..654e3d98 100644 --- a/SHADE_Engine/src/Physics/Dynamics/SHContactManager.h +++ b/SHADE_Engine/src/Physics/Dynamics/SHContactManager.h @@ -79,6 +79,12 @@ namespace SHADE void RemoveInvalidatedManifold (EntityID eid) 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 * Removes any invalidated contacts and triggers, then performs narrowphase collision diff --git a/SHADE_Engine/src/Physics/Dynamics/SHPhysicsWorld.cpp b/SHADE_Engine/src/Physics/Dynamics/SHPhysicsWorld.cpp index ed00e80e..b4e67688 100644 --- a/SHADE_Engine/src/Physics/Dynamics/SHPhysicsWorld.cpp +++ b/SHADE_Engine/src/Physics/Dynamics/SHPhysicsWorld.cpp @@ -86,13 +86,19 @@ namespace SHADE void SHPhysicsWorld::Step(float dt) { + + /* * Detect Collisions */ + contactManager.RemoveExpiredContacts(); + if (collisionSpace) collisionSpace->DetectCollisions(); + // TODO: Build Islands + /* * Integrate Forces */ @@ -106,7 +112,6 @@ namespace SHADE integrateForces(*rigidBody, dt); } - /* * Resolve Contacts */ diff --git a/SHADE_Engine/src/Physics/System/Routines/SHPhysicsDebugDrawRoutine.cpp b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsDebugDrawRoutine.cpp index b263df71..fb2750cc 100644 --- a/SHADE_Engine/src/Physics/System/Routines/SHPhysicsDebugDrawRoutine.cpp +++ b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsDebugDrawRoutine.cpp @@ -15,6 +15,7 @@ // Project Headers #include "ECS_Base/Managers/SHSystemManager.h" +#include "Editor/SHEditor.h" #include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h" #include "Math/Transform/SHTransformComponent.h" #include "Physics/System/SHPhysicsSystem.h" @@ -36,7 +37,6 @@ namespace SHADE void SHPhysicsDebugDrawSystem::PhysicsDebugDraw::Execute(double) noexcept { -#ifdef SHEDITOR auto* physicsDebugDrawSystem = reinterpret_cast(GetSystem()); if (!physicsDebugDrawSystem->IsDebugDrawActive()) @@ -86,17 +86,22 @@ namespace SHADE } } - if (DRAW_RAYCASTS) - { - const SHColour& RAY_COLOUR = physicsDebugDrawSystem->DEBUG_DRAW_COLOURS[SHUtilities::ConvertEnum(Colours::RAYCAST)]; + #ifdef SHEDITOR + if (DRAW_RAYCASTS) + { + const SHColour& RAY_COLOUR = physicsDebugDrawSystem->DEBUG_DRAW_COLOURS[SHUtilities::ConvertEnum(Colours::RAYCAST)]; - const auto& RAYS = physicsSystem->raycastHits; - for (const auto& hit : RAYS) - debugDrawSystem->DrawLine(hit.start, hit.end, RAY_COLOUR, true); + auto& rays = physicsSystem->raycastHits; + for (const auto& hit : rays) + debugDrawSystem->DrawLine(hit.start, hit.end, RAY_COLOUR, true); - // Clear rays for the physics system - physicsSystem->raycastHits.clear(); - } + // Clear the raycast hit container only in play mode. + // No other raycasts are assumed to be done in pause or stop mode. + const auto EDITOR_STATE = SHSystemManager::GetSystem()->editorState; + if (EDITOR_STATE == SHEditor::State::PLAY) + rays.clear(); + } + #endif if (DRAW_BROADPHASE) { @@ -110,7 +115,6 @@ namespace SHADE debugDrawSystem->DrawWireCube(TRS, AABB_COLOUR); } } -#endif } } // namespace SHADE diff --git a/SHADE_Engine/src/Physics/System/Routines/SHPhysicsPostUpdateRoutine.cpp b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsPostUpdateRoutine.cpp index 47c4ed7b..c884c01a 100644 --- a/SHADE_Engine/src/Physics/System/Routines/SHPhysicsPostUpdateRoutine.cpp +++ b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsPostUpdateRoutine.cpp @@ -35,7 +35,7 @@ namespace SHADE void SHPhysicsSystem::PhysicsPostUpdate::Execute(double) noexcept { - auto* physicsSystem = reinterpret_cast(GetSystem()); + auto* physicsSystem = reinterpret_cast(GetSystem()); auto* scriptingSystem = SHSystemManager::GetSystem(); if (scriptingSystem == nullptr) @@ -93,10 +93,6 @@ namespace SHADE */ } } - - // Collision & Trigger messages - if (scriptingSystem != nullptr) - scriptingSystem->ExecuteCollisionFunctions(); } } // namespace SHADE diff --git a/SHADE_Engine/src/Physics/System/Routines/SHPhysicsUpdateRoutine.cpp b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsUpdateRoutine.cpp index 6ae53b31..7de0a9e6 100644 --- a/SHADE_Engine/src/Physics/System/Routines/SHPhysicsUpdateRoutine.cpp +++ b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsUpdateRoutine.cpp @@ -35,10 +35,10 @@ namespace SHADE { auto* physicsSystem = reinterpret_cast(GetSystem()); - auto* scriptEngine = SHSystemManager::GetSystem(); - if (!scriptEngine) + auto* scriptingSystem = SHSystemManager::GetSystem(); + 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; @@ -47,12 +47,15 @@ namespace SHADE int count = 0; while (accumulatedTime > FIXED_DT) { - if (scriptEngine) - scriptEngine->ExecuteFixedUpdates(); + if (scriptingSystem) + scriptingSystem->ExecuteFixedUpdates(); if (physicsSystem->physicsWorld) physicsSystem->physicsWorld->Step(static_cast(FIXED_DT)); + if (scriptingSystem != nullptr) + scriptingSystem->ExecuteCollisionFunctions(); + accumulatedTime -= FIXED_DT; ++count; } diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp index 4db693a2..508f8807 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp @@ -287,6 +287,11 @@ namespace SHADE collisionSpace->RemoveCollider(PHYSICS_OBJECT.collider); } + #ifdef SHEDITOR + // HACK: Editor stop always goes into scene exit + raycastHits.clear(); + #endif + delete collisionSpace; collisionSpace = nullptr;