Moved debug draw state to colliders. Synced collider positions with rigid bodies

This commit is contained in:
Diren D Bharwani 2022-12-11 20:12:26 +08:00
parent 74e50e10bd
commit c1d7702914
16 changed files with 230 additions and 71 deletions

View File

@ -25,6 +25,17 @@
Freeze Rotation Y: false
Freeze Rotation Z: false
IsActive: true
Collider Component:
Colliders:
- Is Trigger: false
Type: Sphere
Radius: 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: 1
Name: Default

View File

@ -111,6 +111,9 @@ namespace Sandbox
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
#ifdef SHEDITOR
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsDebugDraw>();
#endif
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();

View File

@ -322,18 +322,21 @@ namespace SHADE
{
DrawContextMenu(component);
auto* colliders = component->GetCollisionShapes();
int const size = colliders ? static_cast<int>(colliders->size()) : 0;
ImGui::BeginChild("Collision Shapes", { 0.0f, colliders->empty() ? 1.0f : 250.0f }, true);
auto* collider = component->GetCollider();
SHEditorWidgets::CheckBox("Draw Colliders", [collider] { return collider->GetDebugDrawState(); }, [collider](bool value) { collider->SetDebugDrawState(value); });
auto* collisionShapes = component->GetCollisionShapes();
int const size = collisionShapes ? static_cast<int>(collisionShapes->size()) : 0;
ImGui::BeginChild("Collision Shapes", { 0.0f, collisionShapes->empty() ? 1.0f : 250.0f }, true);
std::optional<int> colliderToDelete{ std::nullopt };
for (int i{}; i < size; ++i)
{
ImGui::PushID(i);
SHCollisionShape* collider = component->GetCollisionShape(i);
SHCollisionShape* shape = component->GetCollisionShape(i);
auto cursorPos = ImGui::GetCursorPos();
//collider->IsTrigger
if (collider->GetType() == SHCollisionShape::Type::BOX)
if (shape->GetType() == SHCollisionShape::Type::BOX)
{
//SHEditorWidgets::BeginPanel(std::format("{} Box #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
//
@ -344,42 +347,42 @@ namespace SHADE
// [BOX] { return BOX->GetRelativeExtents(); },
// [collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
}
else if (collider->GetType() == SHCollisionShape::Type::SPHERE)
else if (shape->GetType() == SHCollisionShape::Type::SPHERE)
{
SHEditorWidgets::BeginPanel(std::format("{} Sphere #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
auto* SPHERE = reinterpret_cast<SHSphereCollisionShape*>(collider);
auto* SPHERE = reinterpret_cast<SHSphereCollisionShape*>(shape);
SHEditorWidgets::DragFloat
(
"Radius",
[SPHERE] { return SPHERE->GetRelativeRadius(); },
[SPHERE](float const& value) { SPHERE->SetRelativeRadius(value); });
}
else if (collider->GetType() == SHCollisionShape::Type::CAPSULE)
else if (shape->GetType() == SHCollisionShape::Type::CAPSULE)
{
}
{
SHEditorWidgets::CheckBox("Is Trigger", [collider] { return collider->IsTrigger(); }, [collider](bool value) { collider->SetIsTrigger(value); });
SHEditorWidgets::CheckBox("Is Trigger", [shape] { return shape->IsTrigger(); }, [shape](bool value) { shape->SetIsTrigger(value); });
if(ImGui::CollapsingHeader("Physics Material"))
{
SHEditorWidgets::DragFloat("Friction", [collider] { return collider->GetFriction(); }, [collider](float value) { collider->SetFriction(value); }, "Friction", 0.05f, 0.0f, 1.0f);
SHEditorWidgets::DragFloat("Bounciness", [collider] { return collider->GetBounciness(); }, [collider](float value) { collider->SetBounciness(value); }, "Bounciness", 0.05f, 0.0f, 1.0f);
SHEditorWidgets::DragFloat("Mass Density", [collider] { return collider->GetDensity(); }, [collider](float value) { collider->SetDensity(value); }, "Mass Density", 0.1f, 0.0f);
SHEditorWidgets::DragFloat("Friction", [shape] { return shape->GetFriction(); }, [shape](float value) { shape->SetFriction(value); }, "Friction", 0.05f, 0.0f, 1.0f);
SHEditorWidgets::DragFloat("Bounciness", [shape] { return shape->GetBounciness(); }, [shape](float value) { shape->SetBounciness(value); }, "Bounciness", 0.05f, 0.0f, 1.0f);
SHEditorWidgets::DragFloat("Mass Density", [shape] { return shape->GetDensity(); }, [shape](float value) { shape->SetDensity(value); }, "Mass Density", 0.1f, 0.0f);
}
SHEditorWidgets::BeginPanel("Offsets",{ ImGui::GetContentRegionAvail().x, 30.0f });
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider->GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider->SetPositionOffset(vec); });
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&shape] {return shape->GetPositionOffset(); }, [&shape](SHVec3 const& vec) {shape->SetPositionOffset(vec); });
SHEditorWidgets::DragVec3("Rotation", { "X", "Y", "Z" },
[&collider]
[&shape]
{
auto offset = collider->GetRotationOffset();
auto offset = shape->GetRotationOffset();
return offset;
},
[&collider](SHVec3 const& vec)
[&shape](SHVec3 const& vec)
{
collider->SetRotationOffset(vec);
shape->SetRotationOffset(vec);
}, true);
SHEditorWidgets::EndPanel();
}

View File

@ -14,7 +14,7 @@
#include "SHCollisionShape.h"
// Project Headers
#include "Physics/Collision/SHCollisionTagMatrix.h"
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
#include "Reflection/SHReflectionMetadata.h"
#include "Tools/Utilities/SHUtilities.h"
@ -95,14 +95,6 @@ namespace SHADE
return flags & FLAG_VALUE;
}
bool SHCollisionShape::GetDebugDrawState() const noexcept
{
static constexpr int FLAG_POS = 6;
static constexpr uint8_t FLAG_VALUE = 1U << FLAG_POS;
return flags & FLAG_VALUE;
}
const SHCollisionTag& SHCollisionShape::GetCollisionTag() const noexcept
{
return *collisionTag;
@ -150,14 +142,6 @@ namespace SHADE
isTrigger ? flags |= FLAG_VALUE : flags &= ~FLAG_VALUE;
}
void SHCollisionShape::SetDebugDrawState(bool isDebugDrawing) noexcept
{
static constexpr int FLAG_POS = 6;
static constexpr uint8_t FLAG_VALUE = 1U << FLAG_POS;
isDebugDrawing ? flags |= FLAG_VALUE : flags &= ~FLAG_VALUE;
}
void SHCollisionShape::SetCollisionTag(SHCollisionTag* newCollisionTag) noexcept
{
collisionTag = newCollisionTag;

View File

@ -16,7 +16,7 @@
#include "ECS_Base/Entity/SHEntity.h"
#include "Math/Geometry/SHShape.h"
#include "Math/SHQuaternion.h"
#include "Physics/Collision/SHCollisionTags.h"
#include "Physics/Collision/CollisionTags/SHCollisionTags.h"
#include "Physics/Collision/SHPhysicsMaterial.h"
#include "SHCollisionShapeID.h"
@ -44,8 +44,8 @@ namespace SHADE
enum class Type
{
BOX
, SPHERE
SPHERE
, BOX
, CAPSULE
, COUNT
@ -91,8 +91,6 @@ namespace SHADE
[[nodiscard]] Type GetType () const noexcept;
[[nodiscard]] bool IsTrigger () const noexcept;
[[nodiscard]] bool IsColliding () const noexcept;
[[nodiscard]] bool GetDebugDrawState () const noexcept;
[[nodiscard]] const SHCollisionTag& GetCollisionTag () const noexcept;
@ -110,7 +108,6 @@ namespace SHADE
// Flags
void SetIsTrigger (bool isTrigger) noexcept;
void SetDebugDrawState (bool isDebugDrawing) noexcept;
void SetCollisionTag (SHCollisionTag* newCollisionTag) noexcept;
@ -126,7 +123,7 @@ namespace SHADE
SHVec3 positionOffset;
SHVec3 rotationOffset;
uint8_t flags; // 0 debugDraw wasColliding isColliding trigger capsule sphere box
uint8_t flags; // 0 0 wasColliding isColliding trigger capsule sphere box
SHCollisionTag* collisionTag;
RTTR_ENABLE()

View File

@ -25,14 +25,22 @@ namespace SHADE
SHCollider::SHCollider(EntityID eid, const SHTransform& worldTransform) noexcept
: entityID { eid }
, shapeIDCounter { 0 }
#ifdef SHEDITOR
, debugDraw { false }
#endif
, rigidBody { nullptr }
, shapeFactory { nullptr }
, transform { worldTransform }
{}
{
}
SHCollider::SHCollider(const SHCollider& rhs) noexcept
: entityID { rhs.entityID }
, shapeIDCounter { rhs.shapeIDCounter }
#ifdef SHEDITOR
, debugDraw { rhs.debugDraw }
#endif
, rigidBody { rhs.rigidBody }
, shapeFactory { rhs.shapeFactory }
, transform { rhs.transform }
@ -49,6 +57,9 @@ namespace SHADE
SHCollider::SHCollider(SHCollider&& rhs) noexcept
: entityID { rhs.entityID }
, shapeIDCounter { rhs.shapeIDCounter }
#ifdef SHEDITOR
, debugDraw { rhs.debugDraw }
#endif
, rigidBody { rhs.rigidBody }
, shapeFactory { rhs.shapeFactory }
, transform { rhs.transform }
@ -94,6 +105,10 @@ namespace SHADE
shapeFactory = rhs.shapeFactory;
transform = rhs.transform;
#ifdef SHEDITOR
debugDraw = rhs.debugDraw;
#endif
copyShapes(rhs);
return *this;
@ -112,6 +127,10 @@ namespace SHADE
shapeFactory = rhs.shapeFactory;
transform = rhs.transform;
#ifdef SHEDITOR
debugDraw = rhs.debugDraw;
#endif
copyShapes(rhs);
return *this;
@ -121,6 +140,13 @@ namespace SHADE
/* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/
#ifdef SHEDITOR
bool SHCollider::GetDebugDrawState() const noexcept
{
return debugDraw;
}
#endif
const SHTransform& SHCollider::GetTransform() const noexcept
{
return transform;
@ -160,6 +186,13 @@ namespace SHADE
/* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/
#ifdef SHEDITOR
void SHCollider::SetDebugDrawState(bool state) noexcept
{
debugDraw = state;
}
#endif
void SHCollider::SetRigidBody(SHRigidBody* rb) noexcept
{
rigidBody = rb;
@ -190,7 +223,6 @@ namespace SHADE
shapeFactory = factory;
}
/*-----------------------------------------------------------------------------------*/
/* Public Member Function Definitions */
/*-----------------------------------------------------------------------------------*/
@ -266,9 +298,28 @@ namespace SHADE
SHLOG_INFO_D("Removing Collision Shape {} from Entity {}", index, entityID)
}
void SHCollider::RecomputeShapes() const noexcept
void SHCollider::RecomputeShapes() noexcept
{
for (auto* shape : shapes)
{
switch (shape->GetType())
{
case SHCollisionShape::Type::SPHERE:
{
recomputeSphere(dynamic_cast<SHSphereCollisionShape*>(shape));
break;
}
case SHCollisionShape::Type::BOX:
{
break;
}
case SHCollisionShape::Type::CAPSULE:
{
break;
}
default: break;
}
}
}
/*-----------------------------------------------------------------------------------*/
@ -324,4 +375,19 @@ namespace SHADE
++shapeIDCounter;
}
void SHCollider::recomputeSphere(SHSphereCollisionShape* sphere) noexcept
{
// Recompute world radius
const float SPHERE_SCALE = std::fabs(SHMath::Max({ transform.scale.x, transform.scale.y, transform.scale.z }));
sphere->SetScale(SPHERE_SCALE);
// Recompute center
const SHQuaternion FINAL_ROT = transform.orientation * SHQuaternion::FromEuler(sphere->rotationOffset);
const SHMatrix TRS = SHMatrix::Rotate(FINAL_ROT) * SHMatrix::Translate(transform.position);
const SHVec3 NEW_CENTER = SHVec3::Transform(sphere->positionOffset, TRS);
sphere->SetCenter(NEW_CENTER);
}
} // namespace SHADE

View File

@ -78,6 +78,10 @@ namespace SHADE
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
#ifdef SHEDITOR
[[nodiscard]] bool GetDebugDrawState () const noexcept;
#endif
[[nodiscard]] const SHTransform& GetTransform () const noexcept;
[[nodiscard]] const SHVec3& GetPosition () const noexcept;
[[nodiscard]] const SHQuaternion& GetOrientation () const noexcept;
@ -90,6 +94,10 @@ namespace SHADE
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
#ifdef SHEDITOR
void SetDebugDrawState (bool state) noexcept;
#endif
void SetRigidBody (SHRigidBody* rb) noexcept;
void SetTransform (const SHTransform& newTransform) noexcept;
@ -125,6 +133,7 @@ namespace SHADE
* The index of the newly added shape.
*/
int AddSphereCollisionShape (float relativeRadius, const SHVec3& posOffset = SHVec3::Zero, const SHVec3& rotOffset = SHVec3::Zero);
// TODO: Add Box & Capsule
/**
@ -142,7 +151,7 @@ namespace SHADE
* @brief
* Recomputes the transforms for all shapes in this composite collider.
*/
void RecomputeShapes () const noexcept;
void RecomputeShapes () noexcept;
protected:
/*---------------------------------------------------------------------------------*/
@ -152,6 +161,10 @@ namespace SHADE
EntityID entityID;
uint32_t shapeIDCounter; // This increments everytime a shape is added to differentiate shapes.
#ifdef SHEDITOR
bool debugDraw;
#endif
SHRigidBody* rigidBody;
SHCollisionShapeFactory* shapeFactory;
@ -165,6 +178,8 @@ namespace SHADE
void copyShapes (const SHCollider& rhsCollider);
void copyShape (const SHCollisionShape* rhsShape);
void recomputeSphere (SHSphereCollisionShape* sphere) noexcept;
};
} // namespace SHADE

View File

@ -122,15 +122,20 @@ namespace SHADE
{
rigidBody.linearVelocity = SHVec3::Zero;
}
else // Dynamic & Kinematic bodies
{
// Dynamic & Kinematic bodies
// Both dynamic and kinematic can sleep when their velocities are under the thresholds.
if (!rigidBody.IsSleeping())
else if (!rigidBody.IsSleeping())
{
ENFORCE_CONSTRAINED_VELOCITIES(rigidBody);
rigidBody.motionState.IntegratePosition(rigidBody.linearVelocity, dt);
// TODO: Integrate orientations
// Sync with collider transforms if a collider is present
if (rigidBody.collider)
{
rigidBody.collider->SetPosition(rigidBody.motionState.position);
// TODO: Sync orientations
}
}

View File

@ -0,0 +1,60 @@
/****************************************************************************************
* \file SHPhysicsDebugDrawRoutine.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for the Physics Debug-Draw Routine
*
* \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 <SHpch.h>
// Primary Header
#include "Physics/System/SHPhysicsSystem.h"
// Project Headers
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
#include "Scripting/SHScriptEngine.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHPhysicsSystem::PhysicsDebugDraw::PhysicsDebugDraw()
: SHSystemRoutine { "Physics Debug Draw", false }
{}
/*-----------------------------------------------------------------------------------*/
/* Public Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
void SHPhysicsSystem::PhysicsDebugDraw::Execute(double) noexcept
{
auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
// Get debug drawing system
auto* debugDrawSystem = SHSystemManager::GetSystem<SHDebugDrawSystem>();
if (!debugDrawSystem)
{
SHLOG_ERROR("Debug draw system unavailable! Colliders cannot be drawn!")
return;
}
//SHPhysicsDebugDraw& physicsDebugRenderer = physicsSystem->debugRenderer;
//if (!physicsDebugRenderer.GetDebugDrawState())
// return;
//// Draw colliders
//if (physicsDebugRenderer.GetDrawSpecificCollidersState())
// physicsDebugRenderer.DrawSpecificColliders(debugDrawSystem);
//else if (physicsDebugRenderer.GetDrawAllCollidersState())
// physicsDebugRenderer.DrawAllColliders(debugDrawSystem);
}
}

View File

@ -15,6 +15,7 @@
// Project Headers
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Scripting/SHScriptEngine.h"
@ -77,4 +78,5 @@ namespace SHADE
if (scriptingSystem != nullptr)
scriptingSystem->ExecuteCollisionFunctions();
}
}
} // namespace SHADE

View File

@ -19,7 +19,7 @@
#include "ECS_Base/Managers/SHEntityManager.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/SHEditor.h"
#include "Physics/Collision/SHCollisionTagMatrix.h"
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
#include "Physics/Interface/SHColliderComponent.h"
namespace SHADE

View File

@ -21,7 +21,6 @@
#include "Physics/Interface/SHRigidBodyComponent.h"
#include "Physics/Interface/SHColliderComponent.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
@ -95,7 +94,8 @@ namespace SHADE
/**
* @brief
* The physics update that runs after the simulation. This sets the rendering
* transforms and sends messages to scripting system for collision & trigger events.
* transforms and sends messages to scripting system for collision & trigger events. <br/>
*
*/
class SH_API PhysicsPostUpdate final : public SHSystemRoutine
{
@ -104,6 +104,21 @@ namespace SHADE
void Execute(double dt) noexcept override;
};
#ifdef SHEDITOR
/**
* @brief
* If the editor is enabled, this routine invokes debug drawing for colliders.
* and collision information.
*/
class SH_API PhysicsDebugDraw final : public SHSystemRoutine
{
public:
PhysicsDebugDraw();
void Execute(double dt) noexcept override;
};
#endif
private:
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
@ -125,7 +140,6 @@ namespace SHADE
EventFunctionPair eventFunctions[NUM_EVENT_FUNCTIONS];
// System data
bool worldUpdated;
double interpolationFactor;
double fixedDT;
@ -133,7 +147,6 @@ namespace SHADE
// Sub-systems / managers
SHPhysicsWorld* physicsWorld;
SHPhysicsObjectManager physicsObjectManager;
/*---------------------------------------------------------------------------------*/