Added box & sphere debug draw for physics

This commit is contained in:
Diren D Bharwani 2022-11-10 14:30:30 +08:00
parent 99f41e947f
commit 3efecd64e7
4 changed files with 148 additions and 47 deletions

View File

@ -226,4 +226,36 @@
Color: {x: 1, y: 1, z: 1, w: 1}
Layer: 4294967295
Strength: 0.25
Scripts: ~
- EID: 10
Name: Default
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: -1.50709069, y: 2.57871056, z: -5}
Rotate: {x: -0.463157475, y: -0.553180635, z: 0.0868046582}
Scale: {x: 0.99998343, y: 0.999987662, z: 0.999981642}
RigidBody Component:
Type: Dynamic
Mass: 1
Drag: 0
Angular Drag: 0
Use Gravity: true
Interpolate: 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
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}
Scripts: ~

View File

@ -24,14 +24,15 @@
#include "Scene/SHSceneManager.h"
// Systems
#include "Scripting/SHScriptEngine.h"
#include "Physics/SHPhysicsSystem.h"
#include "Math/Transform/SHTransformSystem.h"
#include "Input/SHInputManager.h"
#include "FRC/SHFramerateController.h"
#include "AudioSystem/SHAudioSystem.h"
#include "Camera/SHCameraSystem.h"
#include "FRC/SHFramerateController.h"
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
#include "Input/SHInputManager.h"
#include "Math/Transform/SHTransformSystem.h"
#include "Physics/SHPhysicsSystem.h"
#include "Physics/SHPhysicsDebugDrawSystem.h"
#include "Scripting/SHScriptEngine.h"
// Components
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
@ -39,7 +40,6 @@
#include "Scenes/SBTestScene.h"
#include "Assets/SHAssetManager.h"
#include "Scenes/SBMainScene.h"
#include "Serialization/Configurations/SHConfigurationManager.h"
@ -67,16 +67,21 @@ namespace Sandbox
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow, wndData);
// Create Systems
SHSystemManager::CreateSystem<SHGraphicsSystem>();
SHSystemManager::CreateSystem<SHScriptEngine>();
SHSystemManager::CreateSystem<SHPhysicsSystem>();
SHSystemManager::CreateSystem<SHTransformSystem>();
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
SHSystemManager::CreateSystem<SHPhysicsSystem>();
SHSystemManager::CreateSystem<SHPhysicsDebugDrawSystem>();
SHSystemManager::CreateSystem<SHAudioSystem>();
SHSystemManager::CreateSystem<SHCameraSystem>();
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
SHSystemManager::CreateSystem<SHGraphicsSystem>();
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
// Link up SHDebugDraw
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
SHDebugDraw::Init(SHSystemManager::GetSystem<SHDebugDrawSystem>());
#ifdef SHEDITOR
@ -102,6 +107,8 @@ namespace Sandbox
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsDebugDrawSystem, SHPhysicsDebugDrawSystem::PhysicsDebugDrawRoutine>();
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
@ -160,12 +167,12 @@ namespace Sandbox
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
editor->PollPicking();
//static bool drawColliders = false;
//if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10))
//{
// drawColliders = !drawColliders;
// SHSystemManager::GetSystem<SHPhysicsSystem>()->SetDrawColliders(drawColliders);
//}
static bool drawColliders = false;
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10))
{
drawColliders = !drawColliders;
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::COLLIDER, drawColliders);
}
}
// Finish all graphics jobs first
graphicsSystem->AwaitGraphicsExecution();

View File

@ -90,6 +90,8 @@ namespace SHADE
void SHPhysicsDebugDrawSystem::Init()
{
SystemFamily::GetID<SHPhysicsDebugDrawSystem>();
SHASSERT(physicsSystem == nullptr, "Non-existent physics system attached to the physics debug draw system!")
physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
}
@ -101,7 +103,14 @@ namespace SHADE
void SHPhysicsDebugDrawSystem::PhysicsDebugDrawRoutine::Execute(double) noexcept
{
auto* system = reinterpret_cast<SHPhysicsDebugDrawSystem*>(GetSystem());
for (int i = 0; i < SHUtilities::ConvertEnum(DebugDrawFlags::NUM_FLAGS); ++i)
{
const bool DRAW = (system->debugDrawFlags & (1U << i)) > 0;
if (DRAW)
drawFunctions[i](system->rp3dDebugRenderer);
}
}
/*-----------------------------------------------------------------------------------*/
@ -110,36 +119,15 @@ namespace SHADE
void SHPhysicsDebugDrawSystem::drawColliders(rp3d::DebugRenderer* debugRenderer) noexcept
{
auto* debugDrawSystem = SHSystemManager::GetSystem<SHDebugDrawSystem>();
if (debugDrawSystem == nullptr)
{
SHLOG_ERROR("Unable to get a debug draw system for Physics Debug Drawing!")
return;
}
const auto& COLLIDER_SET = SHComponentManager::GetDense<SHColliderComponent>();
for (const auto& COLLIDER : COLLIDER_SET)
{
// Get the colliders of each component
const SHVec3& POS = COLLIDER.GetPosition();
const SHQuaternion& ROT = COLLIDER.GetOrientation();
for (auto& collisionShape : COLLIDER.GetCollisionShapes())
{
switch (collisionShape.GetType())
{
case SHCollisionShape::Type::BOX:
{
auto* BOX = reinterpret_cast<const SHBoundingBox*>(collisionShape.GetShape());
break;
}
case SHCollisionShape::Type::SPHERE:
{
break;
}
case SHCollisionShape::Type::BOX: debugDrawBox(COLLIDER, collisionShape); break;
case SHCollisionShape::Type::SPHERE: debugDrawSphere(COLLIDER, collisionShape); break;
default: break;
}
}
@ -166,4 +154,75 @@ namespace SHADE
}
void SHPhysicsDebugDrawSystem::debugDrawBox(const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept
{
static constexpr uint32_t NUM_BOX_VERTICES = 8;
static const SHVec3 boxVertices[NUM_BOX_VERTICES]
{
{ 0.5f, 0.5f, -0.5f } // TOP_RIGHT_BACK
, { -0.5f, 0.5f, -0.5f } // TOP_LEFT_BACK
, { 0.5f, -0.5f, -0.5f } // BTM_RIGHT_BACK
, { -0.5f, -0.5f, -0.5f } // BTM_LEFT_BACK
, { 0.5f, 0.5f, 0.5f } // TOP_RIGHT_FRONT
, { -0.5f, 0.5f, 0.5f } // TOP_LEFT_FRONT
, { 0.5f, -0.5f, 0.5f } // BTM_RIGHT_FRONT
, { -0.5f, -0.5f, 0.5f } // BTM_LEFT_FRONT
};
auto* debugDrawSystem = SHSystemManager::GetSystem<SHDebugDrawSystem>();
if (debugDrawSystem == nullptr)
{
SHLOG_ERROR("Unable to get a debug draw system for Physics Debug Drawing!")
return;
}
auto* BOX = reinterpret_cast<const SHBoundingBox*>(collisionShape.GetShape());
// Calculate final position & orientation
const SHVec3 FINAL_POS = colliderComponent.GetPosition() + collisionShape.GetPositionOffset();
const SHQuaternion FINAL_ROT = colliderComponent.GetOrientation() * SHQuaternion::FromEuler(collisionShape.GetRotationOffset());
const SHMatrix BOX_TRS = SHMatrix::Scale(BOX->GetWorldExtents() * 2.0f) * SHMatrix::Rotate(FINAL_ROT) * SHMatrix::Translate(FINAL_POS);
const SHColour COLLIDER_COLOUR = collisionShape.IsTrigger() ? SHColour::PURPLE : SHColour::GREEN;
std::array<SHVec3, NUM_BOX_VERTICES> transformedVertices;
for (uint32_t i = 0; i < NUM_BOX_VERTICES / 2; ++i)
{
const uint32_t IDX1 = i;
const uint32_t IDX2 = i + NUM_BOX_VERTICES / 2;
transformedVertices[IDX1] = SHVec3::Transform(boxVertices[IDX1], BOX_TRS);
transformedVertices[IDX2] = SHVec3::Transform(boxVertices[IDX2], BOX_TRS);
// Draw 4 line to connect the quads
debugDrawSystem->DrawLine(COLLIDER_COLOUR, transformedVertices[IDX1], transformedVertices[IDX2]);
}
// A, B, C, D
std::array backQuad { transformedVertices[0], transformedVertices[1], transformedVertices[3], transformedVertices[2] };
debugDrawSystem->DrawPoly(COLLIDER_COLOUR, backQuad.begin(), backQuad.end());
// E, F, G, H
std::array frontQuad { transformedVertices[4], transformedVertices[5], transformedVertices[7], transformedVertices[6] };
debugDrawSystem->DrawPoly(COLLIDER_COLOUR, frontQuad.begin(), frontQuad.end());
}
void SHPhysicsDebugDrawSystem::debugDrawSphere(const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept
{
auto* debugDrawSystem = SHSystemManager::GetSystem<SHDebugDrawSystem>();
if (debugDrawSystem == nullptr)
{
SHLOG_ERROR("Unable to get a debug draw system for Physics Debug Drawing!")
return;
}
auto* SPHERE = reinterpret_cast<const SHBoundingSphere*>(collisionShape.GetShape());
const SHColour COLLIDER_COLOUR = collisionShape.IsTrigger() ? SHColour::PURPLE : SHColour::GREEN;
// Calculate final position & orientation
const SHVec3 FINAL_POS = colliderComponent.GetPosition() + collisionShape.GetPositionOffset();
debugDrawSystem->DrawSphere(COLLIDER_COLOUR, FINAL_POS, SPHERE->GetWorldRadius());
}
} // namespace SHADE

View File

@ -24,7 +24,7 @@ namespace SHADE
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SH_API SHPhysicsDebugDrawSystem : public SHSystem
class SH_API SHPhysicsDebugDrawSystem final : public SHSystem
{
public:
/*---------------------------------------------------------------------------------*/
@ -71,7 +71,7 @@ namespace SHADE
/* System Routines */
/*---------------------------------------------------------------------------------*/
class SH_API PhysicsDebugDrawRoutine : public SHSystemRoutine
class SH_API PhysicsDebugDrawRoutine final : public SHSystemRoutine
{
public:
/*-------------------------------------------------------------------------------*/
@ -110,11 +110,14 @@ namespace SHADE
/* Function Members */
/*---------------------------------------------------------------------------------*/
static void drawColliders (rp3d::DebugRenderer* debugRenderer) noexcept;
static void drawColliderAABBs (rp3d::DebugRenderer* debugRenderer) noexcept;
static void drawBroadPhaseAABBs (rp3d::DebugRenderer* debugRenderer) noexcept;
static void drawContactPoints (rp3d::DebugRenderer* debugRenderer) noexcept;
static void drawContactNormals (rp3d::DebugRenderer* debugRenderer) noexcept;
static void drawColliders (rp3d::DebugRenderer* debugRenderer) noexcept;
static void drawColliderAABBs (rp3d::DebugRenderer* debugRenderer) noexcept;
static void drawBroadPhaseAABBs (rp3d::DebugRenderer* debugRenderer) noexcept;
static void drawContactPoints (rp3d::DebugRenderer* debugRenderer) noexcept;
static void drawContactNormals (rp3d::DebugRenderer* debugRenderer) noexcept;
static void debugDrawBox (const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept;
static void debugDrawSphere (const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept;
};
} // namespace SHADE