Implemented a custom physics engine #316

Merged
direnbharwani merged 95 commits from SHPhysics into main 2023-01-23 15:55:45 +08:00
23 changed files with 1908 additions and 627 deletions
Showing only changes of commit af39662748 - Show all commits

View File

@ -0,0 +1,27 @@
#version 450
#extension GL_KHR_vulkan_glsl : enable
layout(location = 0) in vec3 aVertexPos;
layout(location = 1) in mat4 worldTransform;
layout(location = 5) in vec4 color;
// Output
layout(location = 0) out struct
{
vec4 Color;
} Out;
layout(set = 2, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 perspectiveMat;
mat4 orthoMat;
} cameraData;
void main()
{
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos.xyz, 1.0f);
Out.Color = color;
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: DebugDrawMesh_VS
ID: 42127043
Type: 2

View File

@ -1,14 +1,13 @@
#version 450 #version 450
#extension GL_KHR_vulkan_glsl : enable #extension GL_KHR_vulkan_glsl : enable
layout(location = 0) in vec4 aVertexPos; layout(location = 0) in vec3 aVertexPos;
layout(location = 1) in vec4 aVertColor; layout(location = 1) in vec4 aVertColor;
// Output
layout(location = 0) out struct layout(location = 0) out struct
{ {
vec4 vertColor; // location 0 vec4 vertColor; // location 0
} Out; } Out;
layout(set = 2, binding = 0) uniform CameraData layout(set = 2, binding = 0) uniform CameraData
@ -22,6 +21,6 @@ layout(set = 2, binding = 0) uniform CameraData
void main() void main()
{ {
gl_Position = cameraData.vpMat * vec4 (aVertexPos.xyz, 1.0f); gl_Position = cameraData.vpMat * vec4 (aVertexPos, 1.0f);
Out.vertColor = aVertColor; Out.vertColor = aVertColor;
} }

View File

@ -231,8 +231,6 @@ namespace Sandbox
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>()); SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
scriptEngine->RemoveAllScripts(testObj); scriptEngine->RemoveAllScripts(testObj);
} }
SHDebugDraw::Cube(SHColour::CRIMSON, SHVec3(1.0f, 0.0f, 0.0f), SHVec3(1.0f, 1.0f, 1.0f));
} }
void SBTestScene::Render() void SBTestScene::Render()

View File

@ -271,7 +271,7 @@ namespace SHADE
void SHEditor::SetUpGridLines(bool drawGrid, bool drawAxes) void SHEditor::SetUpGridLines(bool drawGrid, bool drawAxes)
{ {
// Clear existing lines // Clear existing lines
SHDebugDraw::ClearPersistentDraws(); SHDebugDraw::Persistent::ClearDraws();
static constexpr float DELTA = 1.0f; static constexpr float DELTA = 1.0f;
static constexpr int EXTENT_COUNT = static_cast<int>(500.0f /* TODO: Remove hard code */ / DELTA); static constexpr int EXTENT_COUNT = static_cast<int>(500.0f /* TODO: Remove hard code */ / DELTA);
@ -284,30 +284,34 @@ namespace SHADE
for (int i = 1; i < EXTENT_COUNT; ++i) for (int i = 1; i < EXTENT_COUNT; ++i)
{ {
// X-Axis Lines // X-Axis Lines
SHDebugDraw::PersistentLine SHDebugDraw::Persistent::Line
( (
GRID_COL,
SHVec3 { -LINE_HALF_LENGTH, 0.0f, i * DELTA }, SHVec3 { -LINE_HALF_LENGTH, 0.0f, i * DELTA },
SHVec3 { LINE_HALF_LENGTH, 0.0f, i * DELTA } SHVec3 { LINE_HALF_LENGTH, 0.0f, i * DELTA },
);
SHDebugDraw::PersistentLine
(
GRID_COL, GRID_COL,
true
);
SHDebugDraw::Persistent::Line
(
SHVec3 { -LINE_HALF_LENGTH, 0.0f, i * -DELTA }, SHVec3 { -LINE_HALF_LENGTH, 0.0f, i * -DELTA },
SHVec3 { LINE_HALF_LENGTH, 0.0f, i * -DELTA } SHVec3 { LINE_HALF_LENGTH, 0.0f, i * -DELTA },
GRID_COL,
true
); );
// Y-Axis Lines // Y-Axis Lines
SHDebugDraw::PersistentLine SHDebugDraw::Persistent::Line
( (
GRID_COL,
SHVec3 { i * DELTA, 0.0f, -LINE_HALF_LENGTH }, SHVec3 { i * DELTA, 0.0f, -LINE_HALF_LENGTH },
SHVec3 { i * DELTA, 0.0f, LINE_HALF_LENGTH } SHVec3 { i * DELTA, 0.0f, LINE_HALF_LENGTH },
);
SHDebugDraw::PersistentLine
(
GRID_COL, GRID_COL,
true
);
SHDebugDraw::Persistent::Line
(
SHVec3 { -i * DELTA, 0.0f, -LINE_HALF_LENGTH }, SHVec3 { -i * DELTA, 0.0f, -LINE_HALF_LENGTH },
SHVec3 { -i * DELTA, 0.0f, LINE_HALF_LENGTH } SHVec3 { -i * DELTA, 0.0f, LINE_HALF_LENGTH },
GRID_COL,
true
); );
} }
} }
@ -319,25 +323,28 @@ namespace SHADE
const SHColour Y_AXIS_COL = drawAxes ? SHColour::GREEN : GRID_COL; const SHColour Y_AXIS_COL = drawAxes ? SHColour::GREEN : GRID_COL;
const SHColour Z_AXIS_COL = drawAxes ? SHColour::BLUE : GRID_COL; const SHColour Z_AXIS_COL = drawAxes ? SHColour::BLUE : GRID_COL;
// X // X
SHDebugDraw::PersistentLine SHDebugDraw::Persistent::Line
( (
X_AXIS_COL,
SHVec3 { -LINE_HALF_LENGTH, 0.0f, 0.0f }, SHVec3 { -LINE_HALF_LENGTH, 0.0f, 0.0f },
SHVec3 { LINE_HALF_LENGTH, 0.0f, 0.0f } SHVec3 { LINE_HALF_LENGTH, 0.0f, 0.0f },
X_AXIS_COL,
true
); );
// Y // Y
SHDebugDraw::PersistentLine SHDebugDraw::Persistent::Line
( (
Y_AXIS_COL,
SHVec3 { 0.0f, -LINE_HALF_LENGTH, 0.0f }, SHVec3 { 0.0f, -LINE_HALF_LENGTH, 0.0f },
SHVec3 { 0.0f, LINE_HALF_LENGTH, 0.0f } SHVec3 { 0.0f, LINE_HALF_LENGTH, 0.0f },
Y_AXIS_COL,
true
); );
// Z // Z
SHDebugDraw::PersistentLine SHDebugDraw::Persistent::Line
( (
Z_AXIS_COL,
SHVec3 { 0.0f, 0.0f, -LINE_HALF_LENGTH }, SHVec3 { 0.0f, 0.0f, -LINE_HALF_LENGTH },
SHVec3 { 0.0f, 0.0f, LINE_HALF_LENGTH } SHVec3 { 0.0f, 0.0f, LINE_HALF_LENGTH },
Z_AXIS_COL,
true
); );
} }
} }
@ -353,7 +360,7 @@ namespace SHADE
break; break;
case State::PLAY: case State::PLAY:
default: default:
SHDebugDraw::ClearPersistentDraws(); SHDebugDraw::Persistent::ClearDraws();
break; break;
} }
return eventData->handle; return eventData->handle;

View File

@ -25,310 +25,696 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE namespace SHADE
{ {
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* DrawRoutine */ /* DrawRoutine */
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHDebugDrawSystem::ProcessPointsRoutine::ProcessPointsRoutine() SHDebugDrawSystem::ProcessPointsRoutine::ProcessPointsRoutine()
: SHSystemRoutine("Debug Draw", true) : SHSystemRoutine("Debug Draw", true)
{
SystemFamily::GetID<SHDebugDrawSystem>();
}
void SHDebugDrawSystem::ProcessPointsRoutine::Execute(double dt) noexcept
{
auto gfxSys = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSys)
{ {
SystemFamily::GetID<SHDebugDrawSystem>(); SHLOG_ERROR("[DebugDraw] Attempted to do debug draw without a graphics system.");
return;
} }
void SHDebugDrawSystem::ProcessPointsRoutine::Execute(double dt) noexcept // Get the system
{ SHDebugDrawSystem* system = static_cast<SHDebugDrawSystem*>(GetSystem());
auto gfxSys = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSys)
{
SHLOG_WARNING("[DebugDraw] Attempted to do debug draw without a graphics system.");
return;
}
// Get the system // Get current frame index
SHDebugDrawSystem* system = static_cast<SHDebugDrawSystem*>(GetSystem()); const uint32_t FRAME_IDX = gfxSys->GetCurrentFrameIndex();
// Get current frame index
const uint32_t FRAME_IDX = gfxSys->GetCurrentFrameIndex();
/* Non-Persistent Buffer */
// Update the buffer
system->numPoints[FRAME_IDX] = system->points.size();
const uint32_t DATA_SIZE = sizeof(PointVertex) * system->points.size();
if (DATA_SIZE > 0)
{
system->vertexBuffers[FRAME_IDX]->WriteToMemory(system->points.data(), DATA_SIZE, 0, 0);
}
// Reset for next frame
system->points.clear();
/* Persistent Buffer */
// Check if there are changes
if (system->persistentBuffersCleared[FRAME_IDX]
||
system->numPersistentPoints[FRAME_IDX] != system->persistentPoints.size())
{
// Update Buffer
system->numPersistentPoints[FRAME_IDX] = system->persistentPoints.size();
const uint32_t DATA_SIZE = sizeof(PointVertex) * system->persistentPoints.size();
if (DATA_SIZE > 0)
{
system->persistentVertexBuffers[FRAME_IDX]->WriteToMemory(system->persistentPoints.data(), DATA_SIZE, 0, 0);
}
// Reset Flag
system->persistentBuffersCleared[FRAME_IDX] = false;
}
}
/*---------------------------------------------------------------------------------*/ // Set up line batches
/* SHSystem overrides */ for (auto& batch : system->lineBatches)
/*---------------------------------------------------------------------------------*/
void SHDebugDrawSystem::Init()
{ {
// Register function for subpass system->prepareBatch(batch, FRAME_IDX);
const auto* GFX_SYSTEM = SHSystemManager::GetSystem<SHGraphicsSystem>(); batch.Points.clear();
auto const& RENDERERS = GFX_SYSTEM->GetDefaultViewport()->GetRenderers(); }
auto renderGraph = RENDERERS[SHGraphicsConstants::RenderGraphIndices::WORLD]->GetRenderGraph();
auto subPass = renderGraph->GetNode("Debug Draw")->GetSubpass("Debug Draw"); // Set up mesh batches
subPass->AddExteriorDrawCalls([this, GFX_SYSTEM](Handle<SHVkCommandBuffer>& cmdBuffer, uint32_t frameIndex) for (auto& batch : system->meshBatches)
{
system->prepareBatch(batch, FRAME_IDX);
for (auto& subBatch : batch.SubBatches)
{
subBatch.second.InstanceColors.clear();
subBatch.second.InstanceTransforms.clear();
}
}
// Set up persistent batches if it was changed
if (system->persistentBuffersUpdated[FRAME_IDX])
{
for (auto& batch : system->persistentLineBatches)
{
system->prepareBatch(batch, FRAME_IDX);
}
for (auto& batch : system->persistentMeshBatches)
{
system->prepareBatch(batch, FRAME_IDX);
}
system->persistentBuffersUpdated[FRAME_IDX] = false;
}
}
/*-----------------------------------------------------------------------------------*/
/* SHSystem overrides */
/*-----------------------------------------------------------------------------------*/
void SHDebugDrawSystem::Init()
{
gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSystem)
{
SHLOG_ERROR("[DebugDraw] Attempted to do debug draw without a graphics system.");
return;
}
// Create all batches
createLineBatches();
createMeshBatches();
// Register function for subpass
auto const& RENDERERS = gfxSystem->GetDefaultViewport()->GetRenderers();
auto renderGraph = RENDERERS[SHGraphicsConstants::RenderGraphIndices::WORLD]->GetRenderGraph();
auto subPass = renderGraph->GetNode("Debug Draw")->GetSubpass("Debug Draw");
subPass->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer>& cmdBuffer, uint32_t frameIndex)
{
const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex();
cmdBuffer->BeginLabeledSegment("SHDebugDraw (No Depth Test)");
{
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Lines)");
{ {
// Get Current frame index renderBatch(lineBatches[static_cast<int>(LineRenderMode::NoDepthTest)], cmdBuffer, FRAME_IDX);
const uint32_t FRAME_IDX = GFX_SYSTEM->GetCurrentFrameIndex(); renderBatch(persistentLineBatches[static_cast<int>(LineRenderMode::NoDepthTest)], cmdBuffer, FRAME_IDX);
// Don't draw if no points
if (numPoints[FRAME_IDX] > 0)
{
cmdBuffer->BeginLabeledSegment("SHDebugDraw");
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline());
cmdBuffer->SetLineWidth(LineWidth);
cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0);
cmdBuffer->DrawArrays(numPoints[FRAME_IDX], 1, 0, 0);
}
});
auto subPassWithDepth = renderGraph->GetNode("Debug Draw with Depth")->GetSubpass("Debug Draw with Depth");
subPassWithDepth->AddExteriorDrawCalls([this, GFX_SYSTEM](Handle<SHVkCommandBuffer>& cmdBuffer, uint32_t frameIndex)
{
// Get Current frame index
const uint32_t FRAME_IDX = GFX_SYSTEM->GetCurrentFrameIndex();
// Don't draw if no points
if (numPersistentPoints[FRAME_IDX] > 0)
{
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Persistent)");
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawDepthPipeline());
cmdBuffer->SetLineWidth(LineWidth);
cmdBuffer->BindVertexBuffer(0, persistentVertexBuffers[FRAME_IDX], 0);
cmdBuffer->DrawArrays(numPersistentPoints[FRAME_IDX], 1, 0, 0);
cmdBuffer->EndLabeledSegment();
}
});
// Reset trackers
std::fill_n(numPoints.begin(), numPoints.size(), 0);
std::fill_n(numPersistentPoints.begin(), numPersistentPoints.size(), 0);
for (bool& cleared : persistentBuffersCleared)
cleared = true;
// Allocate buffers
// - Non-Persistent Draws
static constexpr uint32_t BUFFER_SIZE = MAX_POINTS * sizeof(PointVertex);
for (Handle<SHVkBuffer>& bufHandle : vertexBuffers)
{
bufHandle = GFX_SYSTEM->GetDevice()->CreateBuffer
(
BUFFER_SIZE,
nullptr,
0,
vk::BufferUsageFlagBits::eVertexBuffer,
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT,
"Debug Draw Non-Persistent Vertex Buffer"
);
} }
// - Persistent Draws cmdBuffer->EndLabeledSegment();
for (Handle<SHVkBuffer>& bufHandle : persistentVertexBuffers)
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Meshes)");
{ {
bufHandle = GFX_SYSTEM->GetDevice()->CreateBuffer renderBatch(meshBatches[static_cast<int>(MeshRenderMode::WireNoDepthTest)], cmdBuffer, FRAME_IDX);
( renderBatch(meshBatches[static_cast<int>(MeshRenderMode::FilledNoDepthTest)], cmdBuffer, FRAME_IDX);
BUFFER_SIZE, renderBatch(persistentMeshBatches[static_cast<int>(MeshRenderMode::WireNoDepthTest)], cmdBuffer, FRAME_IDX);
nullptr, renderBatch(persistentMeshBatches[static_cast<int>(MeshRenderMode::FilledNoDepthTest)], cmdBuffer, FRAME_IDX);
0,
vk::BufferUsageFlagBits::eVertexBuffer,
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT,
"Debug Draw Persistent Vertex Buffer"
);
} }
} cmdBuffer->EndLabeledSegment();
}
void SHDebugDrawSystem::Exit() cmdBuffer->EndLabeledSegment();
});
auto subPassWithDepth = renderGraph->GetNode("Debug Draw with Depth")->GetSubpass("Debug Draw with Depth");
subPassWithDepth->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer>& cmdBuffer, uint32_t frameIndex)
{ {
for (auto vertexBuffer : vertexBuffers) const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex();
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Depth Tested)");
{
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Lines)");
{ {
if (vertexBuffer) renderBatch(lineBatches[static_cast<int>(LineRenderMode::DepthTested)], cmdBuffer, FRAME_IDX);
vertexBuffer.Free(); renderBatch(persistentLineBatches[static_cast<int>(LineRenderMode::DepthTested)], cmdBuffer, FRAME_IDX);
} }
for (auto vertexBuffer : persistentVertexBuffers) cmdBuffer->EndLabeledSegment();
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Meshes)");
{ {
if (vertexBuffer) renderBatch(meshBatches[static_cast<int>(MeshRenderMode::WireDepthTested)], cmdBuffer, FRAME_IDX);
vertexBuffer.Free(); renderBatch(meshBatches[static_cast<int>(MeshRenderMode::FilledDepthTested)], cmdBuffer, FRAME_IDX);
renderBatch(persistentMeshBatches[static_cast<int>(MeshRenderMode::WireDepthTested)], cmdBuffer, FRAME_IDX);
renderBatch(persistentMeshBatches[static_cast<int>(MeshRenderMode::FilledDepthTested)], cmdBuffer, FRAME_IDX);
} }
} cmdBuffer->EndLabeledSegment();
}
cmdBuffer->EndLabeledSegment();
});
}
/*---------------------------------------------------------------------------------*/ void SHDebugDrawSystem::Exit()
/* Draw Functions */ {
/*---------------------------------------------------------------------------------*/ // Destroy buffers in the batches
void SHDebugDrawSystem::DrawLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt) destroyLineBatches();
destroyMeshBatches();
}
/*-----------------------------------------------------------------------------------*/
/* Draw Functions */
/*-----------------------------------------------------------------------------------*/
void SHDebugDrawSystem::DrawLine(const SHVec3& start, const SHVec3& end, const SHColour& color, bool depthTested)
{
// Insert into the batch
drawLine(getLineBatch(depthTested), start, end, color);
}
void SHDebugDrawSystem::DrawLineLoop(std::initializer_list<SHVec3> points, const SHColour& color, bool depthTested)
{
DrawLineLoop(points.begin(), points.end(), color, depthTested);
}
void SHDebugDrawSystem::DrawTri(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHColour& color, bool depthTested)
{
DrawLineLoop({ p1, p2, p3 }, color, depthTested);
}
void SHDebugDrawSystem::DrawQuad(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHVec3& p4, const SHColour& color, bool depthTested)
{
DrawLineLoop({ p1, p2, p3, p4 }, color, depthTested);
}
void SHDebugDrawSystem::DrawCircle(const SHMatrix& matrix, const SHColour& color /*= SHColour::WHITE*/, bool depthTested /*= false*/)
{
drawCircle(getMeshBatch(false, depthTested), matrix, color);
}
void SHDebugDrawSystem::DrawWireCube(const SHMatrix& matrix, const SHColour& color, bool depthTested)
{
drawWireCube(getMeshBatch(false, depthTested), matrix, color);
}
void SHDebugDrawSystem::DrawWireSphere(const SHMatrix& matrix, const SHColour& color /*= SHColour::WHITE*/, bool depthTested /*= false*/)
{
drawWireSphere(getMeshBatch(false, depthTested), matrix, color);
}
void SHDebugDrawSystem::DrawCube(const SHMatrix& matrix, const SHColour& color /*= SHColour::WHITE*/, bool depthTested /*= false*/)
{
drawCube(getMeshBatch(true, depthTested), matrix, color);
}
void SHDebugDrawSystem::DrawSphere(const SHMatrix& matrix, const SHColour& color /*= SHColour::WHITE*/, bool depthTested /*= false*/)
{
drawSphere(getMeshBatch(true, depthTested), matrix, color);
}
/*-----------------------------------------------------------------------------------*/
/* Persistent Draw Functions */
/*-----------------------------------------------------------------------------------*/
void SHDebugDrawSystem::DrawPersistentLine(const SHVec3& start, const SHVec3& end, const SHColour& color, bool depthTested)
{
// Insert into the batch
drawLine(getPersistentLineBatch(depthTested), start, end, color);
markPersistentDrawsDirty();
}
void SHDebugDrawSystem::DrawPersistentLineLoop(std::initializer_list<SHVec3> points, const SHColour& color, bool depthTested)
{
DrawPersistentLineLoop(points.begin(), points.end(), color, depthTested);
markPersistentDrawsDirty();
}
void SHDebugDrawSystem::DrawPersistentTri(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHColour& color, bool depthTested)
{
DrawPersistentLineLoop({ p1, p2, p3 }, color, depthTested);
markPersistentDrawsDirty();
}
void SHDebugDrawSystem::DrawPersistentQuad(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHVec3& p4, const SHColour& color, bool depthTested)
{
DrawPersistentLineLoop({ p1, p2, p3, p4 }, color, depthTested);
markPersistentDrawsDirty();
}
void SHDebugDrawSystem::DrawPersistentCircle(const SHMatrix& matrix, const SHColour& color, bool depthTested)
{
drawCircle(getPersistentMeshBatch(false, depthTested), matrix, color);
markPersistentDrawsDirty();
}
void SHDebugDrawSystem::DrawPersistentWireCube(const SHMatrix& matrix, const SHColour& color, bool depthTested)
{
drawWireCube(getPersistentMeshBatch(false, depthTested), matrix, color);
markPersistentDrawsDirty();
}
void SHDebugDrawSystem::DrawPersistentWireSphere(const SHMatrix& matrix, const SHColour& color, bool depthTested)
{
drawWireSphere(getPersistentMeshBatch(false, depthTested), matrix, color);
markPersistentDrawsDirty();
}
void SHDebugDrawSystem::DrawPersistentCube(const SHMatrix& matrix, const SHColour& color, bool depthTested)
{
drawCube(getPersistentMeshBatch(true, depthTested), matrix, color);
markPersistentDrawsDirty();
}
void SHDebugDrawSystem::DrawPersistentSphere(const SHMatrix& matrix, const SHColour& color, bool depthTested)
{
drawSphere(getPersistentMeshBatch(true, depthTested), matrix, color);
markPersistentDrawsDirty();
}
void SHDebugDrawSystem::ClearPersistentDraws()
{
for (auto& batch : persistentLineBatches)
batch.Points.clear();
markPersistentDrawsDirty();
}
/*-----------------------------------------------------------------------------------*/
/* Helper Draw Functions */
/*-----------------------------------------------------------------------------------*/
void SHDebugDrawSystem::drawLine(LinesBatch& batch, const SHVec3& start, const SHVec3& end, const SHColour& color)
{
// Check if points exceeded max
if (batch.Points.size() >= MAX_POINTS)
{ {
drawLine(points, color, startPt, endPt); SHLOG_WARNING("[SHDebugDrawSystem] Exceeded maximum size of drawable debug lines. Ignoring.");
return;
} }
void SHDebugDrawSystem::DrawTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3) batch.Points.emplace_back(start, color);
batch.Points.emplace_back(end, color);
}
void SHDebugDrawSystem::drawMesh(Handle<SHMesh> mesh, MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color)
{
// Create if doesn't exist
if (!batch.SubBatches.contains(mesh))
{ {
drawPoly(points, color, { pt1, pt2, pt3 }); MeshBatch::MultiDrawSet set;
set.Mesh = mesh;
batch.SubBatches.emplace(mesh, std::move(set));
} }
void SHDebugDrawSystem::DrawQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4) // Add to the batch
auto& subBatch = batch.SubBatches[mesh];
subBatch.InstanceTransforms.emplace_back(transformMatrix);
subBatch.InstanceColors.emplace_back(color);
}
void SHDebugDrawSystem::drawWireCube(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color)
{
drawMesh
(
gfxSystem->GetMeshPrimitive(PrimitiveType::LineCube),
batch, transformMatrix, color
);
}
void SHDebugDrawSystem::drawWireSphere(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color)
{
drawMesh
(
gfxSystem->GetMeshPrimitive(PrimitiveType::Sphere),
batch, transformMatrix, color
);
}
void SHDebugDrawSystem::drawCube(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color)
{
drawMesh
(
gfxSystem->GetMeshPrimitive(PrimitiveType::Cube),
batch, transformMatrix, color
);
}
void SHDebugDrawSystem::drawSphere(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color)
{
drawMesh
(
gfxSystem->GetMeshPrimitive(PrimitiveType::Sphere),
batch, transformMatrix, color
);
}
void SHDebugDrawSystem::drawCircle(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color)
{
drawMesh
(
gfxSystem->GetMeshPrimitive(PrimitiveType::LineCircle),
batch, transformMatrix, color
);
}
/*-----------------------------------------------------------------------------------*/
/* Helper Batch Functions - Lines */
/*-----------------------------------------------------------------------------------*/
SHDebugDrawSystem::LinesBatch& SHDebugDrawSystem::getLineBatch(bool depthTested)
{
return lineBatches[static_cast<int>(depthTested ? LineRenderMode::DepthTested : LineRenderMode::NoDepthTest)];
}
SHDebugDrawSystem::LinesBatch& SHDebugDrawSystem::getPersistentLineBatch(bool depthTested)
{
return persistentLineBatches[static_cast<int>(depthTested ? LineRenderMode::DepthTested : LineRenderMode::NoDepthTest)];
}
void SHDebugDrawSystem::createLineBatches()
{
auto gfxSys = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSys)
{ {
drawPoly(points, color, { pt1, pt2, pt3, pt4 }); SHLOG_ERROR("[DebugDraw] Attempted to do debug draw without a graphics system.");
return;
} }
void SHDebugDrawSystem::DrawPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList) // Line Batches
initBatch
(
getLineBatch(false),
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineNoDepthTest),
"Debug Draw Non-Persistent Vertex Buffer"
);
initBatch
(
getLineBatch(true),
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineDepthTested),
"Debug Draw Depth Tested Non-Persistent Vertex Buffer"
);
// Persistent Line Batches
initBatch
(
getPersistentLineBatch(false),
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineNoDepthTest),
"Debug Draw Persistent Vertex Buffer"
);
initBatch
(
getPersistentLineBatch(true),
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineDepthTested),
"Debug Draw Depth Tested Persistent Vertex Buffer"
);
}
void SHDebugDrawSystem::initBatch(LinesBatch& batch, Handle<SHVkPipeline> pipeline, const std::string& vertexBufferName)
{
auto gfxSys = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSys)
{ {
drawPoly(points, color, pointList.begin(), pointList.end()); SHLOG_WARNING("[DebugDraw] Attempted to do debug draw without a graphics system.");
return;
} }
void SHDebugDrawSystem::DrawCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size) batch.Pipeline = pipeline;
for (auto& vBuffer : batch.VertexBuffers)
{ {
drawCube(points, color, pos, size); vBuffer = gfxSys->GetDevice()->CreateBuffer
(
sizeof(PointVertex) * MAX_POINTS,
nullptr,
0,
vk::BufferUsageFlagBits::eVertexBuffer,
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT,
vertexBufferName
);
} }
}
void SHDebugDrawSystem::DrawSphere(const SHVec4& color, const SHVec3& pos, const SHVec3& rot, double radius)
void SHDebugDrawSystem::prepareBatch(LinesBatch& batch, uint32_t frameIndex)
{
// Parameter checks
if (frameIndex > batch.VertexBuffers.size())
{ {
drawSphere(points, color, pos, rot, radius); SHLOG_ERROR("[SHDebugDrawSystem] An invalid frame index was specified for debug drawing. Skipping.");
return;
} }
/*---------------------------------------------------------------------------------*/ // Fill data into the buffers
/* Persistent Draw Functions */ batch.NumPoints[frameIndex] = batch.Points.size();
/*---------------------------------------------------------------------------------*/ const uint32_t DATA_SIZE = sizeof(PointVertex) * batch.Points.size();
void SHDebugDrawSystem::DrawPersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt) if (DATA_SIZE > 0)
{ {
drawLine(persistentPoints, color, startPt, endPt); batch.VertexBuffers[frameIndex]->WriteToMemory(batch.Points.data(), DATA_SIZE, 0, 0);
} }
}
void SHDebugDrawSystem::DrawPersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3) void SHDebugDrawSystem::renderBatch(LinesBatch& batch, Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex)
{
if (batch.NumPoints[frameIndex] > 0)
{ {
drawPoly(persistentPoints, color, { pt1, pt2, pt3 }); cmdBuffer->BindPipeline(batch.Pipeline);
cmdBuffer->SetLineWidth(LineWidth);
cmdBuffer->BindVertexBuffer(0, batch.VertexBuffers[frameIndex], 0);
cmdBuffer->DrawArrays(batch.NumPoints[frameIndex], 1, 0, 0);
} }
}
void SHDebugDrawSystem::DrawPersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4) void SHDebugDrawSystem::destroyBatch(LinesBatch& batch)
{
for (auto& vBuffer : batch.VertexBuffers)
{ {
drawPoly(persistentPoints, color, { pt1, pt2, pt3, pt4 }); if (vBuffer)
{
vBuffer.Free();
vBuffer = {};
}
} }
}
void SHDebugDrawSystem::DrawPersistentPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList) void SHDebugDrawSystem::destroyLineBatches()
{
destroyBatch(getLineBatch(true));
destroyBatch(getLineBatch(false));
destroyBatch(getPersistentLineBatch(true));
destroyBatch(getPersistentLineBatch(false));
}
/*-----------------------------------------------------------------------------------*/
/* Helper Batch Functions - Meshes */
/*-----------------------------------------------------------------------------------*/
SHDebugDrawSystem::MeshBatch& SHDebugDrawSystem::getMeshBatch(bool filled, bool depthTested)
{
MeshRenderMode mode = {};
if (filled)
{ {
drawPoly(persistentPoints, color, pointList.begin(), pointList.end()); mode = depthTested ? MeshRenderMode::FilledDepthTested
: MeshRenderMode::FilledNoDepthTest;
} }
else
void SHDebugDrawSystem::DrawPersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size)
{ {
drawCube(persistentPoints, color, pos, size); mode = depthTested ? MeshRenderMode::WireDepthTested
: MeshRenderMode::WireNoDepthTest;
} }
void SHDebugDrawSystem::DrawPersistentSphere(const SHVec4& color, const SHVec3& pos, double radius) return meshBatches[static_cast<int>(mode)];
}
SHDebugDrawSystem::MeshBatch& SHDebugDrawSystem::getPersistentMeshBatch(bool filled, bool depthTested)
{
MeshRenderMode mode = {};
if (filled)
{ {
drawSphere(persistentPoints, color, pos, SHVec3::Zero, radius); mode = depthTested ? MeshRenderMode::FilledDepthTested
: MeshRenderMode::FilledNoDepthTest;
} }
else
void SHDebugDrawSystem::ClearPersistentDraws()
{ {
persistentPoints.clear(); mode = depthTested ? MeshRenderMode::WireDepthTested
for (bool& cleared : persistentBuffersCleared) : MeshRenderMode::WireNoDepthTest;
cleared = true;
} }
void SHDebugDrawSystem::drawLine(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt) return persistentMeshBatches[static_cast<int>(mode)];
}
void SHDebugDrawSystem::createMeshBatches()
{
auto gfxSys = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSys)
{ {
if (storage.size() > MAX_POINTS) SHLOG_ERROR("[DebugDraw] Attempted to do debug draw without a graphics system.");
{ return;
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements.");
return;
}
storage.emplace_back(PointVertex{ startPt, color });
storage.emplace_back(PointVertex{ endPt, color });
} }
void SHDebugDrawSystem::drawLineSet(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList) // Set up batches
initBatch
(
meshBatches[static_cast<int>(MeshRenderMode::FilledNoDepthTest)],
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::FilledMeshNoDepthTest)
);
initBatch
(
meshBatches[static_cast<int>(MeshRenderMode::FilledDepthTested)],
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::FilledMeshDepthTested)
);
initBatch
(
meshBatches[static_cast<int>(MeshRenderMode::WireNoDepthTest)],
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineMeshNoDepthTest)
);
initBatch
(
meshBatches[static_cast<int>(MeshRenderMode::WireDepthTested)],
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineMeshDepthTested)
);
// Set up persistent batches
initBatch
(
persistentMeshBatches[static_cast<int>(MeshRenderMode::FilledNoDepthTest)],
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::FilledMeshNoDepthTest)
);
initBatch
(
persistentMeshBatches[static_cast<int>(MeshRenderMode::FilledDepthTested)],
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::FilledMeshDepthTested)
);
initBatch
(
persistentMeshBatches[static_cast<int>(MeshRenderMode::WireNoDepthTest)],
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineMeshNoDepthTest)
);
initBatch
(
persistentMeshBatches[static_cast<int>(MeshRenderMode::WireDepthTested)],
gfxSys->GetDebugDrawPipeline(DebugDrawPipelineType::LineMeshDepthTested)
);
}
void SHDebugDrawSystem::initBatch(MeshBatch& batch, Handle<SHVkPipeline> pipeline)
{
batch.Pipeline = pipeline;
}
void SHDebugDrawSystem::prepareBatch(MeshBatch& batch, uint32_t frameIndex)
{
// Parameter checks
if (frameIndex > batch.MDIBuffer.size())
{ {
drawLineSet(storage, color, pointList.begin(), pointList.end()); SHLOG_ERROR("[SHDebugDrawSystem] An invalid frame index was specified for debug drawing. Skipping.");
return;
} }
void SHDebugDrawSystem::drawPoly(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList) // Clear existing data
batch.InstanceTransforms.clear();
batch.InstanceColors.clear();
batch.MDIData.clear();
// Populate
for (auto& subBatch : batch.SubBatches)
{ {
drawPoly(storage, color, pointList.begin(), pointList.end()); auto& multiDrawSet = subBatch.second;
}
void SHDebugDrawSystem::drawCube(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, const SHVec3& size) // Nothing to populate with
if (multiDrawSet.InstanceTransforms.empty())
continue;
// Populate batch data on CPU
batch.MDIData.emplace_back(vk::DrawIndexedIndirectCommand
{
.indexCount = multiDrawSet.Mesh->IndexCount,
.instanceCount = static_cast<uint32_t>(multiDrawSet.InstanceTransforms.size()),
.firstIndex = multiDrawSet.Mesh->FirstIndex,
.vertexOffset = multiDrawSet.Mesh->FirstVertex,
.firstInstance = static_cast<uint32_t>(batch.InstanceTransforms.size())
});
batch.InstanceTransforms.insert
(
batch.InstanceTransforms.end(),
multiDrawSet.InstanceTransforms.begin(),
multiDrawSet.InstanceTransforms.end()
);
batch.InstanceColors.insert
(
batch.InstanceColors.end(),
multiDrawSet.InstanceColors.begin(),
multiDrawSet.InstanceColors.end()
);
// Copy to GPU
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
gfxSystem->GetDevice(),
batch.MDIBuffer[frameIndex],
batch.MDIData.data(), static_cast<uint32_t>(batch.MDIData.size() * sizeof(vk::DrawIndexedIndirectCommand)),
vk::BufferUsageFlagBits::eIndirectBuffer,
"Debug Draw Mesh Batch MDI Buffer"
);
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
gfxSystem->GetDevice(),
batch.InstanceTransformBuffer[frameIndex],
batch.InstanceTransforms.data(), static_cast<uint32_t>(batch.InstanceTransforms.size() * sizeof(SHMatrix)),
vk::BufferUsageFlagBits::eVertexBuffer,
"Debug Draw Mesh Batch Instance Transform Buffer"
);
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
gfxSystem->GetDevice(),
batch.InstanceColorBuffer[frameIndex],
batch.InstanceColors.data(), static_cast<uint32_t>(batch.InstanceColors.size() * sizeof(SHVec4)),
vk::BufferUsageFlagBits::eVertexBuffer,
"Debug Draw Mesh Batch Instance Color Buffer"
);
}
}
void SHDebugDrawSystem::renderBatch(MeshBatch& batch, Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex)
{
static constexpr uint32_t TRANSFORM_BIND_PT = 1;
static constexpr uint32_t COLOR_BIND_PT = 2;
// Nothing to draw
if (batch.MDIData.empty())
return;
// Bind Pipeline
cmdBuffer->BindPipeline(batch.Pipeline);
// Bind meshes
cmdBuffer->BindVertexBuffer(0, gfxSystem->GetMeshLibrary().GetVertexPositionsBuffer(), 0);
cmdBuffer->BindIndexBuffer(gfxSystem->GetMeshLibrary().GetIndexBuffer(), 0);
// Bind instance attributes
cmdBuffer->BindVertexBuffer(TRANSFORM_BIND_PT, batch.InstanceTransformBuffer[frameIndex], 0);
cmdBuffer->BindVertexBuffer(COLOR_BIND_PT, batch.InstanceColorBuffer[frameIndex], 0);
// Execute draw
cmdBuffer->DrawMultiIndirect(batch.MDIBuffer[frameIndex], static_cast<uint32_t>(batch.MDIData.size()));
}
void SHDebugDrawSystem::destroyBatch(MeshBatch& batch)
{
for (auto& buffer : batch.InstanceColorBuffer)
{ {
static const SHVec3 EXTENTS = SHVec3{ 0.5f, 0.5f, 0.5f }; if (buffer)
static const SHVec3 UNIT_BOT_LEFT_FRONT = SHVec3{ pos - EXTENTS }; {
static const SHVec3 UNIT_BOT_RIGHT_FRONT = SHVec3{ pos + SHVec3 { EXTENTS.x, -EXTENTS.y, -EXTENTS.z } }; buffer.Free();
static const SHVec3 UNIT_BOT_RIGHT_BACK = SHVec3{ pos + SHVec3 { EXTENTS.x, -EXTENTS.y, EXTENTS.z } }; buffer = {};
static const SHVec3 UNIT_BOT_LEFT_BACK = SHVec3{ pos + SHVec3 { -EXTENTS.x, -EXTENTS.y, EXTENTS.z } }; }
static const SHVec3 UNIT_TOP_LEFT_BACK = SHVec3{ pos + SHVec3 { -EXTENTS.x, EXTENTS.y, EXTENTS.z } };
static const SHVec3 UNIT_TOP_RIGHT_FRONT = SHVec3{ pos + SHVec3 { EXTENTS.x, EXTENTS.y, -EXTENTS.z } };
static const SHVec3 UNIT_TOP_LEFT_FRONT = SHVec3{ pos + SHVec3 { -EXTENTS.x, EXTENTS.y, -EXTENTS.z } };
static const SHVec3 UNIT_TOP_RIGHT_BACK = SHVec3{ pos + EXTENTS };
const SHVec3 BOT_LEFT_BACK = UNIT_BOT_LEFT_BACK * size;
const SHVec3 BOT_RIGHT_BACK = UNIT_BOT_RIGHT_BACK * size;
const SHVec3 BOT_LEFT_FRONT = UNIT_BOT_LEFT_FRONT * size;
const SHVec3 BOT_RIGHT_FRONT = UNIT_BOT_RIGHT_FRONT * size;
const SHVec3 TOP_LEFT_BACK = UNIT_TOP_LEFT_BACK * size;
const SHVec3 TOP_RIGHT_BACK = UNIT_TOP_RIGHT_BACK * size;
const SHVec3 TOP_LEFT_FRONT = UNIT_TOP_LEFT_FRONT * size;
const SHVec3 TOP_RIGHT_FRONT = UNIT_TOP_RIGHT_FRONT * size;
drawLineSet
(
storage,
color,
{
// Bottom Square
BOT_LEFT_BACK , BOT_RIGHT_BACK,
BOT_RIGHT_BACK , BOT_RIGHT_FRONT,
BOT_RIGHT_FRONT, BOT_LEFT_FRONT,
BOT_LEFT_FRONT , BOT_LEFT_BACK,
// Top Square
TOP_LEFT_BACK , TOP_RIGHT_BACK,
TOP_RIGHT_BACK , TOP_RIGHT_FRONT,
TOP_RIGHT_FRONT, TOP_LEFT_FRONT,
TOP_LEFT_FRONT , TOP_LEFT_BACK,
// Middle Lines
TOP_LEFT_BACK , BOT_LEFT_BACK,
TOP_RIGHT_BACK , BOT_RIGHT_BACK,
TOP_RIGHT_FRONT, BOT_RIGHT_FRONT,
TOP_LEFT_FRONT , BOT_LEFT_FRONT
}
);
} }
for (auto& buffer : batch.InstanceTransformBuffer)
void SHDebugDrawSystem::drawSphere(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, const SHVec3& rot, double radius)
{ {
//if (spherePoints.empty()) if (buffer)
{ {
spherePoints.clear(); buffer.Free();
// Generate buffer = {};
static const SHMeshData SPHERE = SHPrimitiveGenerator::Sphere(); }
for (const auto& idx : SPHERE.Indices)
{
SHVec3 SCALE { static_cast<float>(radius) };
const SHMatrix TRS = SHMatrix::Transform(pos, rot, { static_cast<float>(radius) });
spherePoints.emplace_back(SHVec3::Transform(SPHERE.VertexPositions[idx], TRS));
}
}
drawLineSet(storage, color, spherePoints.begin(), spherePoints.end());
} }
for (auto& buffer : batch.MDIBuffer)
{
if (buffer)
{
buffer.Free();
buffer = {};
}
}
}
void SHDebugDrawSystem::destroyMeshBatches()
{
destroyBatch(meshBatches[static_cast<int>(MeshRenderMode::FilledNoDepthTest)]);
destroyBatch(meshBatches[static_cast<int>(MeshRenderMode::FilledDepthTested)]);
destroyBatch(meshBatches[static_cast<int>(MeshRenderMode::WireNoDepthTest)]);
destroyBatch(meshBatches[static_cast<int>(MeshRenderMode::WireDepthTested)]);
destroyBatch(persistentMeshBatches[static_cast<int>(MeshRenderMode::FilledNoDepthTest)]);
destroyBatch(persistentMeshBatches[static_cast<int>(MeshRenderMode::FilledDepthTested)]);
destroyBatch(persistentMeshBatches[static_cast<int>(MeshRenderMode::WireNoDepthTest)]);
destroyBatch(persistentMeshBatches[static_cast<int>(MeshRenderMode::WireDepthTested)]);
}
/*-----------------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------------*/
void SHDebugDrawSystem::markPersistentDrawsDirty()
{
for (bool& dirty : persistentBuffersUpdated)
dirty = true;
}
} }

View File

@ -18,6 +18,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Math/Vector/SHVec2.h" #include "Math/Vector/SHVec2.h"
#include "Math/Vector/SHVec3.h" #include "Math/Vector/SHVec3.h"
#include "Math/Vector/SHVec4.h" #include "Math/Vector/SHVec4.h"
#include "Math/SHMatrix.h"
#include "ECS_Base/System/SHSystem.h" #include "ECS_Base/System/SHSystem.h"
#include "ECS_Base/System/SHSystemRoutine.h" #include "ECS_Base/System/SHSystemRoutine.h"
#include "Resource/SHHandle.h" #include "Resource/SHHandle.h"
@ -30,7 +31,10 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Forward Declarations */ /* Forward Declarations */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
class SHGraphicsSystem;
class SHVkBuffer; class SHVkBuffer;
class SHMesh;
class SHVkPipeline;
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
@ -47,7 +51,7 @@ namespace SHADE
class SH_API ProcessPointsRoutine final : public SHSystemRoutine class SH_API ProcessPointsRoutine final : public SHSystemRoutine
{ {
public: public:
ProcessPointsRoutine(); ProcessPointsRoutine();
virtual void Execute(double dt) noexcept override final; virtual void Execute(double dt) noexcept override final;
}; };
@ -69,135 +73,201 @@ namespace SHADE
/* Draw Functions */ /* Draw Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Renders a line between two points in world space. /// Draws a line between two specified points.
/// </summary> /// </summary>
/// <param name="color">Colour of the line.</param> /// <param name="start">Starting point.</param>
/// <param name="startPt">First point of the line.</param> /// <param name="end">Ending point.</param>
/// <param name="endPt">Second point of the line.</param> /// <param name="color">Colour to draw with.</param>
void DrawLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt); /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawLine(const SHVec3& start, const SHVec3& end, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a triangle indicated by three points in world space. /// Draws a set of points as a connected set of lines that loops back.
/// </summary> /// </summary>
/// <param name="color">Colour of the triangle.</param> /// <param name="points">List of points to draw the line across.</param>
/// <param name="pt1">First point of the triangle.</param> /// <param name="color">Colour to draw with.</param>
/// <param name="pt2">Second point of the triangle.</param> /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
/// <param name="pt3">Third point of the triangle.</param> void DrawLineLoop(std::initializer_list<SHVec3> points, const SHColour& color = SHColour::WHITE, bool depthTested = false);
void DrawTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3);
/// <summary> /// <summary>
/// Renders a quadrilateral indicated by four points in world space. /// Draws a set of points as a connected set of lines that loops back.
/// </summary> /// </summary>
/// <param name="color">Colour of the quadrilateral.</param> /// <typeparam name="IterType">
/// <param name="pt1">First point of the triangle.</param> /// Type of iterator of the container that contains the points.
/// <param name="pt2">Second point of the quadrilateral.</param> /// </typeparam>
/// <param name="pt3">Third point of the quadrilateral.</param> /// <param name="pointListBegin">Starting iterator to the line points.</param>
/// <param name="pt4">Third point of the quadrilateral.</param> /// <param name="pointListEnd">One past end iterator to the line points.</param>
void DrawQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4); /// <param name="color">Colour to draw with.</param>
/// <summary> /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
/// Renders a polygon indicated by the specified set of points in world space.
/// </summary>
/// <param name="color">Colour of the polygon.</param>
/// <param name="pointList">List of points for the polygon.</param>
void DrawPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList);
/// <summary>
/// Renders a polygon indicated by the specified set of points in world space.
/// </summary>
/// <typeparam name="IterType">Iterator for a STL-like container.</typeparam>
/// <param name="color">Colour of the polygon.</param>
/// <param name="pointListBegin">
/// Iterator to the first point of the point container.
/// </param>
/// <param name="pointListEnd">
/// One past last iterator of the point container.
/// </param>
template<typename IterType> template<typename IterType>
void DrawPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd); void DrawLineLoop(IterType pointListBegin, IterType pointListEnd, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a wireframe cube centered around the position specified in world space. /// Draws a triangle from the specified set of points.
/// </summary> /// </summary>
/// <param name="color">Colour of the cube.</param> /// <param name="p1">1st point.</param>
/// <param name="pos">Position where the cube wil be centered at.</param> /// <param name="p2">2nd point.</param>
/// <param name="size">Size of the rendered cube.</param> /// <param name="p3">3rd point.</param>
void DrawCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size); /// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawTri(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a wireframe sphere centered around the position specified in world space. /// Draws a quad from the specified set of points.
/// </summary> /// </summary>
/// <param name="color">Colour of the sphere.</param> /// <param name="p1">1st point.</param>
/// <param name="pos">Position where the sphere wil be centered at.</param> /// <param name="p2">2nd point.</param>
/// <param name="rot">Rotation of the sphere. </param> /// <param name="p3">3rd point.</param>
/// <param name="size">Size of the rendered sphere.</param> /// <param name="p4">4th point.</param>
void DrawSphere(const SHVec4& color, const SHVec3& pos, const SHVec3& rot, double radius); /// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawQuad(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHVec3& p4, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a 2-dimensional circle.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the circle should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawCircle(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the outline of a cube.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the wire cube should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawWireCube(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the wireframe of a sphere.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the sphere should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawWireSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled cube.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the cube should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawCube(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the sphere should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Persistent Draw Functions */ /* Persistent Draw Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Renders a line between two points in world space that will persist until /// Draws a persistent line between two specified points.
/// ClearPersistentDraws() is called. These lines are depth tested. /// This will remain drawn until ClearPersistentDraws() is called.
/// </summary> /// </summary>
/// <param name="color">Colour of the line.</param> /// <param name="start">Starting point.</param>
/// <param name="startPt">First point of the line.</param> /// <param name="end">Ending point.</param>
/// <param name="endPt">Second point of the line.</param> /// <param name="color">Colour to draw with.</param>
void DrawPersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt); /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentLine(const SHVec3& start, const SHVec3& end, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a triangle indicated by three points in world space that will persist /// Draws a persistent set of points as a connected set of lines that loops back.
/// until ClearPersistentDraws() is called. These lines are depth tested. /// This will remain drawn until ClearPersistentDraws() is called.
/// </summary> /// </summary>
/// <param name="color">Colour of the triangle.</param> /// <param name="points">List of points to draw the line across.</param>
/// <param name="pt1">First point of the triangle.</param> /// <param name="color">Colour to draw with.</param>
/// <param name="pt2">Second point of the triangle.</param> /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
/// <param name="pt3">Third point of the triangle.</param> void DrawPersistentLineLoop(std::initializer_list<SHVec3> points, const SHColour& color = SHColour::WHITE, bool depthTested = false);
void DrawPersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3);
/// <summary> /// <summary>
/// Renders a quadrilateral indicated by four points in world space that will persist /// Draws a persistent set of points as a connected set of lines that loops back.
/// until ClearPersistentDraws() is called. These lines are depth tested. /// This will remain drawn until ClearPersistentDraws() is called.
/// </summary> /// </summary>
/// <param name="color">Colour of the quadrilateral.</param> /// <typeparam name="IterType">
/// <param name="pt1">First point of the triangle.</param> /// Type of iterator of the container that contains the points.
/// <param name="pt2">Second point of the quadrilateral.</param> /// </typeparam>
/// <param name="pt3">Third point of the quadrilateral.</param> /// <param name="pointListBegin">Starting iterator to the line points.</param>
/// <param name="pt4">Third point of the quadrilateral.</param> /// <param name="pointListEnd">One past end iterator to the line points.</param>
void DrawPersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4); /// <param name="color">Colour to draw with.</param>
/// <summary> /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
/// Renders a polygon indicated by the specified set of points in world space that
/// will persist until ClearPersistentDraws() is called. These lines are depth
/// tested.
/// </summary>
/// <param name="color">Colour of the polygon.</param>
/// <param name="pointList">List of points for the polygon.</param>
void DrawPersistentPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList);
/// <summary>
/// Renders a polygon indicated by the specified set of points in world space that
/// will persist until ClearPersistentDraws() is called. These lines are depth
/// tested.
/// </summary>
/// <typeparam name="IterType">Iterator for a STL-like container.</typeparam>
/// <param name="color">Colour of the polygon.</param>
/// <param name="pointListBegin">
/// Iterator to the first point of the point container.
/// </param>
/// <param name="pointListEnd">
/// One past last iterator of the point container.
/// </param>
template<typename IterType> template<typename IterType>
void DrawPersistentPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd); void DrawPersistentLineLoop(IterType pointListBegin, IterType pointListEnd, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a wireframe cube centered around the position specified in world space /// Draws a persistent triangle from the specified set of points.
/// that will persist until ClearPersistentDraws() is called. These lines are depth /// This will remain drawn until ClearPersistentDraws() is called.
/// tested.
/// </summary> /// </summary>
/// <param name="color">Colour of the cube.</param> /// <param name="p1">1st point.</param>
/// <param name="pos">Position where the cube wil be centered at.</param> /// <param name="p2">2nd point.</param>
/// <param name="size">Size of the rendered cube.</param> /// <param name="p3">3rd point.</param>
void DrawPersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size); /// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentTri(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a wireframe sphere centered around the position specified in world space /// Draws a persistent quad from the specified set of points.
/// that will persist until ClearPersistentDraws() is called. These lines are depth /// This will remain drawn until ClearPersistentDraws() is called.
/// tested.
/// </summary> /// </summary>
/// <param name="color">Colour of the sphere.</param> /// <param name="p1">1st point.</param>
/// <param name="pos">Position where the sphere wil be centered at.</param> /// <param name="p2">2nd point.</param>
/// <param name="size">Size of the rendered sphere.</param> /// <param name="p3">3rd point.</param>
void DrawPersistentSphere(const SHVec4& color, const SHVec3& pos, double radius); /// <param name="p4">4th point.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentQuad(const SHVec3& p1, const SHVec3& p2, const SHVec3& p3, const SHVec3& p4, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a persistent 2-dimensional circle.
/// This will remain drawn until ClearPersistentDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the circle should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentCircle(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the outline of a persistent cube.
/// This will remain drawn until ClearPersistentDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the wire cube should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentWireCube(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the wireframe of a persistent sphere.
/// This will remain drawn until ClearPersistentDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the sphere should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentWireSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a persistent filled cube.
/// This will remain drawn until ClearPersistentDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the cube should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentCube(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a persistent filled sphere.
/// This will remain drawn until ClearPersistentDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the sphere should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Clears any persistent drawn debug primitives. /// Clears any persistent drawn debug primitives.
/// </summary> /// </summary>
@ -207,47 +277,144 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
using TripleBuffer = std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
using TripleUInt = std::array<uint32_t , SHGraphicsConstants::NUM_FRAME_BUFFERS>;
using TripleBool = std::array<bool , SHGraphicsConstants::NUM_FRAME_BUFFERS>;
/// <summary>
/// Defines the rendering mode for debug lines.
/// </summary>
enum class LineRenderMode : uint32_t
{
NoDepthTest,
DepthTested,
Count
};
/// <summary>
/// Defines the rendering mode for debug meshes.
/// </summary>
enum class MeshRenderMode : uint32_t
{
FilledNoDepthTest,
FilledDepthTested,
WireNoDepthTest,
WireDepthTested,
Count
};
/// <summary>
/// Defines a coloured Vertex
/// </summary>
struct SH_API PointVertex struct SH_API PointVertex
{ {
SHVec4 Position; SHVec4 Position;
SHVec4 Color; SHVec4 Color;
}; };
using TripleBuffer = std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS>; struct Batch
using TripleUInt = std::array<uint32_t , SHGraphicsConstants::NUM_FRAME_BUFFERS>; {
using TripleBool = std::array<bool , SHGraphicsConstants::NUM_FRAME_BUFFERS>; /*-------------------------------------------------------------------------------*/
/* Data Members */
/*-------------------------------------------------------------------------------*/
Handle<SHVkPipeline> Pipeline;
};
struct LinesBatch : public Batch
{
/*-------------------------------------------------------------------------------*/
/* Data Members */
/*-------------------------------------------------------------------------------*/
// CPU Buffers
std::vector<PointVertex> Points;
// GPU Buffers
TripleBuffer VertexBuffers;
TripleUInt NumPoints;
};
struct MeshBatch : public Batch
{
/*-------------------------------------------------------------------------------*/
/* Type Definitions */
/*-------------------------------------------------------------------------------*/
struct MultiDrawSet
{
Handle<SHMesh> Mesh;
std::vector<SHMatrix> InstanceTransforms;
std::vector<SHVec4> InstanceColors;
};
/*-------------------------------------------------------------------------------*/
/* Data Members */
/*-------------------------------------------------------------------------------*/
// CPU Buffers
std::unordered_map<Handle<SHMesh>, MultiDrawSet> SubBatches;
std::vector<SHMatrix> InstanceTransforms;
std::vector<SHVec4> InstanceColors;
std::vector<vk::DrawIndexedIndirectCommand> MDIData;
// GPU Buffers
TripleBuffer MDIBuffer;
TripleBuffer InstanceTransformBuffer;
TripleBuffer InstanceColorBuffer;
};
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Constants */ /* Constants */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
static constexpr uint32_t MAX_POINTS = 100'000; static constexpr uint32_t MAX_POINTS = 100'000;
static constexpr size_t LINE_MODE_COUNT = static_cast<size_t>(LineRenderMode::Count);
static constexpr size_t MESH_MODE_COUNT = static_cast<size_t>(MeshRenderMode::Count);
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
// CPU Buffers // References
std::vector<PointVertex> points; SHGraphicsSystem* gfxSystem = nullptr;
std::vector<PointVertex> persistentPoints; // Batches
// GPU Buffers std::array<LinesBatch, LINE_MODE_COUNT> lineBatches;
TripleBuffer vertexBuffers; std::array<LinesBatch, LINE_MODE_COUNT> persistentLineBatches;
TripleUInt numPoints; std::array<MeshBatch , MESH_MODE_COUNT> meshBatches;
TripleBuffer persistentVertexBuffers; std::array<MeshBatch , MESH_MODE_COUNT> persistentMeshBatches;
TripleUInt numPersistentPoints; // Tracking
TripleBool persistentBuffersCleared; TripleBool persistentBuffersUpdated = { true, true, true };
// Cached Points for polygon drawing
std::vector<SHVec3> spherePoints;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Helper Draw Functions */ /* Helper Draw Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void drawLine(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt); void drawLine(LinesBatch& batch, const SHVec3& start, const SHVec3& end, const SHColour& color);
void drawLineSet(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList);
template<typename IterType> template<typename IterType>
void drawLineSet(std::vector<PointVertex>& storage, const SHVec4& color, IterType pointListBegin, IterType pointListEnd); void drawLineLoop(LinesBatch& batch, IterType pointListBegin, IterType pointListEnd, const SHColour& color);
void drawPoly(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList); void drawMesh(Handle<SHMesh> mesh, MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
template<typename IterType> void drawWireCube(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
void drawPoly(std::vector<PointVertex>& storage, const SHVec4& color, IterType pointListBegin, IterType pointListEnd); void drawWireSphere(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
void drawCube(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, const SHVec3& size); void drawCube(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
void drawSphere(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, const SHVec3& rot, double radius); void drawSphere(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
void drawCircle(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
/*---------------------------------------------------------------------------------*/
/* Helper Batch Functions - Lines */
/*---------------------------------------------------------------------------------*/
LinesBatch& getLineBatch(bool depthTested);
LinesBatch& getPersistentLineBatch(bool depthTested);
void createLineBatches();
void initBatch(LinesBatch& batch, Handle<SHVkPipeline> pipeline, const std::string& vertexBufferName);
void prepareBatch(LinesBatch& batch, uint32_t frameIndex);
void renderBatch(LinesBatch& batch, Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex);
void destroyBatch(LinesBatch& batch);
void destroyLineBatches();
/*---------------------------------------------------------------------------------*/
/* Helper Batch Functions - Meshes */
/*---------------------------------------------------------------------------------*/
MeshBatch& getMeshBatch(bool filled, bool depthTested);
MeshBatch& getPersistentMeshBatch(bool filled, bool depthTested);
void createMeshBatches();
void initBatch(MeshBatch& batch, Handle<SHVkPipeline> pipeline);
void prepareBatch(MeshBatch& batch, uint32_t frameIndex);
void renderBatch(MeshBatch& batch, Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex);
void destroyBatch(MeshBatch& batch);;
void destroyMeshBatches();
/*---------------------------------------------------------------------------------*/
/* Helper Functions */
/*---------------------------------------------------------------------------------*/
void markPersistentDrawsDirty();
}; };
} }

View File

@ -17,73 +17,44 @@ namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Draw Functions */ /* Draw Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
template<typename IterType> template<typename IterType>
void SHDebugDrawSystem::DrawPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd) void SHDebugDrawSystem::DrawLineLoop(IterType pointListBegin, IterType pointListEnd, const SHColour& color, bool depthTested)
{ {
drawPoly(points, color, pointListBegin, pointListEnd); // Get Batch
drawLineLoop(getLineBatch(depthTested), pointListBegin, pointListEnd, color);
} }
template<typename IterType>
void SHADE::SHDebugDrawSystem::DrawPersistentLineLoop(IterType pointListBegin, IterType pointListEnd, const SHColour& color , bool depthTested)
{
// Get Batch
drawLineLoop(getPersistentLineBatch(depthTested), pointListBegin, pointListEnd, color);
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Helper Draw Functions */ /* Helper Draw Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
template<typename IterType> template<typename IterType>
void SHDebugDrawSystem::drawLineSet(std::vector<PointVertex>& storage, const SHVec4& color, IterType pointListBegin, IterType pointListEnd) void SHDebugDrawSystem::drawLineLoop(LinesBatch& batch, IterType pointListBegin, IterType pointListEnd, const SHColour& color)
{ {
// Ensure dereferenced type is SHVec3 // Ensure dereferenced type is SHVec3
static_assert(std::is_same_v<SHVec3, std::remove_cvref_t<decltype(*pointListBegin)>>, "Parameters to DrawPoly must be SHVec3."); static_assert(std::is_same_v<SHVec3, std::remove_cvref_t<decltype(*pointListBegin)>>, "Parameters to DrawLineLoop must be SHVec3.");
// Check if points exceeded max
if (storage.size() > MAX_POINTS)
{
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements.");
return;
}
const size_t POINTS_COUNT = pointListEnd - pointListBegin;
// Invalid polygon // Invalid polygon
const size_t POINTS_COUNT = pointListEnd - pointListBegin;
if (POINTS_COUNT < 2) if (POINTS_COUNT < 2)
{ {
SHLOG_WARNING("[SHDebugDraw] Invalid polygon provided to DrawPoly()."); SHLOG_WARNING("[SHDebugDrawSystem] Insufficient points provided to drawLineLoop().");
return;
}
const size_t POINTS_ROUNDED_COUNT = POINTS_COUNT / 2 * 2;
for (auto pointIter = pointListBegin; pointIter != (pointListBegin + POINTS_ROUNDED_COUNT); ++pointIter)
{
storage.emplace_back(PointVertex{ *pointIter, color });
}
}
template<typename IterType>
void SHDebugDrawSystem::drawPoly(std::vector<PointVertex>& storage, const SHVec4& color, IterType pointListBegin, IterType pointListEnd)
{
// Ensure dereferenced type is SHVec3
static_assert(std::is_same_v<SHVec3, std::remove_cvref_t<decltype(*pointListBegin)>>, "Parameters to DrawPoly must be SHVec3.");
// Check if points exceeded max
if (storage.size() > MAX_POINTS)
{
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements.");
return;
}
const size_t POINTS_COUNT = pointListEnd - pointListBegin;
// Invalid polygon
if (POINTS_COUNT < 2)
{
SHLOG_WARNING("[SHDebugDraw] Invalid polygon provided to DrawPoly().");
return; return;
} }
// Trace the polygon // Trace the polygon
for (auto pointIter = pointListBegin + 1; pointIter != pointListEnd; ++pointIter) for (auto pointIter = pointListBegin + 1; pointIter != pointListEnd; ++pointIter)
{ {
storage.emplace_back(PointVertex{ *(pointIter - 1), color }); drawLine(batch, *(pointIter - 1), *pointIter, color);
storage.emplace_back(PointVertex{ *pointIter , color });
} }
// Close the line loop // Close the line loop
storage.emplace_back(PointVertex{ *(pointListEnd - 1), color }); drawLine(batch, *(pointListEnd - 1), *pointListBegin, color);
storage.emplace_back(PointVertex{ *pointListBegin , color });
} }
} }

View File

@ -124,20 +124,12 @@ namespace SHADE
SHFreetypeInstance::Init(); SHFreetypeInstance::Init();
//SHAssetManager::CompileAsset("../../Assets/Shaders/Text_VS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/Text_FS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_VS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/UI_VS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/UI_FS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Models/Quad.gltf", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/ToSwapchain_VS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/ToSwapchain_FS.glsl", false);
// Load Built In Shaders // Load Built In Shaders
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT); static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT); static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT);
static constexpr AssetID VS_DEBUG = 48002439; debugVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEBUG); static constexpr AssetID VS_DEBUG = 48002439; debugVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEBUG);
static constexpr AssetID FS_DEBUG = 36671027; debugFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEBUG); static constexpr AssetID FS_DEBUG = 36671027; debugFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEBUG);
static constexpr AssetID VS_DEBUG_MESH = 42127043; debugMeshVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEBUG_MESH);
static constexpr AssetID CS_COMPOSITE = 45072428; deferredCompositeShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(CS_COMPOSITE); static constexpr AssetID CS_COMPOSITE = 45072428; deferredCompositeShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(CS_COMPOSITE);
static constexpr AssetID SSAO = 38430899; ssaoShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO); static constexpr AssetID SSAO = 38430899; ssaoShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO);
static constexpr AssetID SSAO_BLUR = 39760835; ssaoBlurShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO_BLUR); static constexpr AssetID SSAO_BLUR = 39760835; ssaoBlurShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO_BLUR);
@ -335,14 +327,31 @@ namespace SHADE
screenRenderer->SetCamera(screenCamera); screenRenderer->SetCamera(screenCamera);
screenRenderer->SetCameraDirector(worldCameraDirector); screenRenderer->SetCameraDirector(worldCameraDirector);
// Create debug draw pipeline // Create debug draw pipeline
debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass); debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass, false, false, false);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawPipeline->GetVkPipeline(), "[Pipeline] Debug Draw"); SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawPipeline->GetVkPipeline(), "[Pipeline] Debug Draw");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline Layout] Debug Draw Pipeline Layout"); SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline Layout] Debug Draw");
debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass); debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass, false, false, false);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawDepthPipeline->GetVkPipeline(), "[Pipeline Layout] Debug Draw with Depth Test"); SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawDepthPipeline->GetVkPipeline(), "[Pipeline Layout] Debug Draw with Depth Test");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawDepthPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Debug Draw with Depth Test Pipeline Layout"); SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawDepthPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Debug Draw with Depth Test");
debugDrawLineMeshPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass, false, false, true);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawLineMeshPipeline->GetVkPipeline(), "[Pipeline] Debug Draw Line Mesh");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawLineMeshPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline Layout] Debug Draw Line Mesh");
debugDrawLineMeshDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass, false, false, true);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawLineMeshDepthPipeline->GetVkPipeline(), "[Pipeline Layout] Debug Draw Line Mesh with Depth Test");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawLineMeshDepthPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Debug Draw Line Mesh with Depth Test");
debugDrawWireMeshPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass, false, true, true);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawWireMeshPipeline->GetVkPipeline(), "[Pipeline] Debug Draw Wire Mesh");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawWireMeshPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline Layout] Debug Draw Wire Mesh");
debugDrawWireMeshDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass, false, true, true);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawWireMeshDepthPipeline->GetVkPipeline(), "[Pipeline Layout] Debug Draw Wire Mesh with Depth Test");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawWireMeshDepthPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Debug Draw Wire Mesh with Depth Test");
debugDrawFilledPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass, true, true, true);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawFilledPipeline->GetVkPipeline(), "[Pipeline] Debug Draw Filled Mesh");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawFilledPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline Layout] Debug Draw Filled Mesh");
debugDrawFilledDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass, true, true, true);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawFilledDepthPipeline->GetVkPipeline(), "[Pipeline Layout] Debug Draw Filled Mesh with Depth Test");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawFilledDepthPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Debug Draw Filled Mesh with Depth Test");
} }
void SHGraphicsSystem::InitMiddleEnd(void) noexcept void SHGraphicsSystem::InitMiddleEnd(void) noexcept
@ -405,6 +414,8 @@ namespace SHADE
// Create default meshes // Create default meshes
primitiveMeshes[static_cast<int>(PrimitiveType::Cube)] = SHPrimitiveGenerator::Cube(meshLibrary); primitiveMeshes[static_cast<int>(PrimitiveType::Cube)] = SHPrimitiveGenerator::Cube(meshLibrary);
primitiveMeshes[static_cast<int>(PrimitiveType::Sphere)] = SHPrimitiveGenerator::Sphere(meshLibrary); primitiveMeshes[static_cast<int>(PrimitiveType::Sphere)] = SHPrimitiveGenerator::Sphere(meshLibrary);
primitiveMeshes[static_cast<int>(PrimitiveType::LineCube)] = SHPrimitiveGenerator::LineCube(meshLibrary);
primitiveMeshes[static_cast<int>(PrimitiveType::LineCircle)] = SHPrimitiveGenerator::LineCircle(meshLibrary);
BuildMeshBuffers(); BuildMeshBuffers();
// Create default materials // Create default materials
@ -829,6 +840,8 @@ namespace SHADE
{ {
case PrimitiveType::Cube: case PrimitiveType::Cube:
case PrimitiveType::Sphere: case PrimitiveType::Sphere:
case PrimitiveType::LineCube:
case PrimitiveType::LineCircle:
return primitiveMeshes[static_cast<int>(type)]; return primitiveMeshes[static_cast<int>(type)];
default: default:
return {}; return {};
@ -1083,34 +1096,68 @@ namespace SHADE
return worldRenderGraph->GetNode(G_BUFFER_RENDER_GRAPH_NODE_NAME.data()); return worldRenderGraph->GetNode(G_BUFFER_RENDER_GRAPH_NODE_NAME.data());
} }
SHADE::SHFontLibrary const& SHGraphicsSystem::GetFontLibrary(void) const noexcept Handle<SHVkPipeline> SHGraphicsSystem::GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept
{
switch (type)
{
case DebugDrawPipelineType::LineNoDepthTest: return debugDrawPipeline;
case DebugDrawPipelineType::LineDepthTested: return debugDrawDepthPipeline;
case DebugDrawPipelineType::LineMeshNoDepthTest: return debugDrawLineMeshPipeline;
case DebugDrawPipelineType::LineMeshDepthTested: return debugDrawLineMeshDepthPipeline;
case DebugDrawPipelineType::WireMeshNoDepthTest: return debugDrawWireMeshPipeline;
case DebugDrawPipelineType::WireMeshDepthTested: return debugDrawWireMeshDepthPipeline;
case DebugDrawPipelineType::FilledMeshNoDepthTest: return debugDrawFilledPipeline;
case DebugDrawPipelineType::FilledMeshDepthTested: return debugDrawFilledDepthPipeline;
}
SHLOG_WARNING("[SHGraphicsSystem] Attempted to retrieve an invalid Debug Draw Pipeline. Default Debug Draw Pipeline returned.");
return debugDrawPipeline;
}
SHFontLibrary const& SHGraphicsSystem::GetFontLibrary(void) const noexcept
{ {
return fontLibrary; return fontLibrary;
} }
Handle<SHVkPipeline> SHGraphicsSystem::createDebugDrawPipeline(Handle<SHVkRenderpass> renderPass, Handle<SHSubpass> subpass) Handle<SHVkPipeline> SHGraphicsSystem::createDebugDrawPipeline(Handle<SHVkRenderpass> renderPass, Handle<SHSubpass> subpass, bool filled, bool triMesh, bool instanced)
{ {
auto pipelineLayout = resourceManager.Create<SHVkPipelineLayout> auto pipelineLayout = resourceManager.Create<SHVkPipelineLayout>
( (
device, SHPipelineLayoutParams device, SHPipelineLayoutParams
{ {
.shaderModules = { debugVertShader, debugFragShader }, .shaderModules = { (instanced ? debugMeshVertShader : debugVertShader) , debugFragShader },
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
} }
); );
auto pipeline = resourceManager.Create<SHVkPipeline>(device, pipelineLayout, nullptr, renderPass, subpass); auto pipeline = resourceManager.Create<SHVkPipeline>(device, pipelineLayout, nullptr, renderPass, subpass);
pipeline->GetPipelineState().SetRasterizationState(SHRasterizationState pipeline->GetPipelineState().SetRasterizationState(SHRasterizationState
{ {
.polygonMode = vk::PolygonMode::eLine, .polygonMode = filled ? vk::PolygonMode::eFill : vk::PolygonMode::eLine,
.cull_mode = vk::CullModeFlagBits::eNone .cull_mode = filled ? vk::CullModeFlagBits::eBack : vk::CullModeFlagBits::eNone
}); });
pipeline->GetPipelineState().SetInputAssemblyState(SHInputAssemblyState pipeline->GetPipelineState().SetInputAssemblyState(SHInputAssemblyState
{ {
.topology = vk::PrimitiveTopology::eLineList .topology = triMesh ? vk::PrimitiveTopology::eTriangleList : vk::PrimitiveTopology::eLineList
}); });
SHVertexInputState debugDrawVertexInputState; SHVertexInputState debugDrawVertexInputState;
debugDrawVertexInputState.AddBinding(false, true, { SHVertexAttribute(SHAttribFormat::FLOAT_4D), SHVertexAttribute(SHAttribFormat::FLOAT_4D) }); if (instanced)
{
debugDrawVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // 0: Vertex World Space Position
debugDrawVertexInputState.AddBinding(true , true , { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // 1: Instance Transform Matrix (4 Slots)
debugDrawVertexInputState.AddBinding(true , true , { SHVertexAttribute(SHAttribFormat::FLOAT_4D) }); // 5: Instance Color
}
else
{
debugDrawVertexInputState.AddBinding
(
false, true,
{
SHVertexAttribute(SHAttribFormat::FLOAT_4D), // Vertex World Space Position
SHVertexAttribute(SHAttribFormat::FLOAT_4D) // Vertex Color
}
);
}
pipeline->GetPipelineState().SetVertexInputState(debugDrawVertexInputState); pipeline->GetPipelineState().SetVertexInputState(debugDrawVertexInputState);
SHColorBlendState colorBlendState{}; SHColorBlendState colorBlendState{};
colorBlendState.logic_op_enable = VK_FALSE; colorBlendState.logic_op_enable = VK_FALSE;

View File

@ -70,9 +70,23 @@ namespace SHADE
enum class PrimitiveType enum class PrimitiveType
{ {
Cube, Cube,
Sphere Sphere,
LineCube,
LineCircle
}; };
static constexpr int MAX_PRIMITIVE_TYPES = 2; static constexpr int MAX_PRIMITIVE_TYPES = 4;
enum class DebugDrawPipelineType
{
LineNoDepthTest,
LineDepthTested,
LineMeshNoDepthTest,
LineMeshDepthTested,
WireMeshNoDepthTest,
WireMeshDepthTested,
FilledMeshNoDepthTest,
FilledMeshDepthTested
};
static constexpr int MAX_DEBUG_DRAW_PIPELINE_TYPES = 8;
/***********************************************************************************/ /***********************************************************************************/
/*! /*!
@ -371,10 +385,10 @@ namespace SHADE
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;}; Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;};
Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;}; Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;};
Handle<SHRenderGraphNode> GetPrimaryRenderpass() const noexcept; Handle<SHRenderGraphNode> GetPrimaryRenderpass() const noexcept;
Handle<SHVkPipeline> GetDebugDrawPipeline(void) const noexcept { return debugDrawPipeline; } Handle<SHVkPipeline> GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept;
Handle<SHVkPipeline> GetDebugDrawDepthPipeline(void) const noexcept { return debugDrawDepthPipeline; }
uint32_t GetCurrentFrameIndex(void) const noexcept { return renderContext.GetCurrentFrame(); } uint32_t GetCurrentFrameIndex(void) const noexcept { return renderContext.GetCurrentFrame(); }
SHFontLibrary const& GetFontLibrary (void) const noexcept; SHFontLibrary const& GetFontLibrary (void) const noexcept;
const SHMeshLibrary& GetMeshLibrary() const noexcept { return meshLibrary; };
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Getters */ /* Getters */
@ -439,6 +453,7 @@ namespace SHADE
Handle<SHVkShaderModule> defaultFragShader; Handle<SHVkShaderModule> defaultFragShader;
Handle<SHVkShaderModule> debugVertShader; Handle<SHVkShaderModule> debugVertShader;
Handle<SHVkShaderModule> debugFragShader; Handle<SHVkShaderModule> debugFragShader;
Handle<SHVkShaderModule> debugMeshVertShader;
Handle<SHVkShaderModule> deferredCompositeShader; Handle<SHVkShaderModule> deferredCompositeShader;
Handle<SHVkShaderModule> ssaoShader; Handle<SHVkShaderModule> ssaoShader;
Handle<SHVkShaderModule> ssaoBlurShader; Handle<SHVkShaderModule> ssaoBlurShader;
@ -454,6 +469,12 @@ namespace SHADE
Handle<SHMaterial> defaultMaterial; Handle<SHMaterial> defaultMaterial;
Handle<SHVkPipeline> debugDrawPipeline; Handle<SHVkPipeline> debugDrawPipeline;
Handle<SHVkPipeline> debugDrawDepthPipeline; Handle<SHVkPipeline> debugDrawDepthPipeline;
Handle<SHVkPipeline> debugDrawLineMeshPipeline;
Handle<SHVkPipeline> debugDrawLineMeshDepthPipeline;
Handle<SHVkPipeline> debugDrawWireMeshPipeline;
Handle<SHVkPipeline> debugDrawWireMeshDepthPipeline;
Handle<SHVkPipeline> debugDrawFilledPipeline;
Handle<SHVkPipeline> debugDrawFilledDepthPipeline;
// Built-In Textures // Built-In Textures
Handle<SHTexture> defaultTexture; Handle<SHTexture> defaultTexture;
@ -482,6 +503,6 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Handle<SHVkPipeline> createDebugDrawPipeline(Handle<SHVkRenderpass> renderPass, Handle<SHSubpass> subpass); Handle<SHVkPipeline> createDebugDrawPipeline(Handle<SHVkRenderpass> renderPass, Handle<SHSubpass> subpass, bool filled, bool triMesh, bool instanced);
}; };
} }

View File

@ -10,9 +10,13 @@ Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited. of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/ *//*************************************************************************************/
// Precompiled Header
#include "SHpch.h" #include "SHpch.h"
// Primary Includes
#include "SHPrimitiveGenerator.h" #include "SHPrimitiveGenerator.h"
// STL Includes
#include <numbers>
// Project Includes
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
#include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h" #include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h"
@ -23,6 +27,8 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHMeshData SHPrimitiveGenerator::cubeMesh; SHMeshData SHPrimitiveGenerator::cubeMesh;
SHMeshData SHPrimitiveGenerator::sphereMesh; SHMeshData SHPrimitiveGenerator::sphereMesh;
SHMeshData SHPrimitiveGenerator::lineCubeMesh;
SHMeshData SHPrimitiveGenerator::lineCircleMesh;
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Primitive Generation Functions */ /* Primitive Generation Functions */
@ -207,14 +213,14 @@ namespace SHADE
return addMeshDataTo(cubeMesh, meshLibrary); return addMeshDataTo(cubeMesh, meshLibrary);
} }
Handle<SHADE::SHMesh> SHPrimitiveGenerator::Cube(SHGraphicsSystem& gfxSystem) noexcept Handle<SHMesh> SHPrimitiveGenerator::Cube(SHGraphicsSystem& gfxSystem) noexcept
{ {
if (cubeMesh.VertexPositions.empty()) if (cubeMesh.VertexPositions.empty())
cubeMesh = Cube(); cubeMesh = Cube();
return addMeshDataTo(cubeMesh, gfxSystem); return addMeshDataTo(cubeMesh, gfxSystem);
} }
SHADE::SHMeshData SHPrimitiveGenerator::Sphere() noexcept SHMeshData SHPrimitiveGenerator::Sphere() noexcept
{ {
SHMeshData meshData; SHMeshData meshData;
@ -265,7 +271,7 @@ namespace SHADE
return meshData; return meshData;
} }
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::Sphere(SHMeshLibrary& meshLibrary) noexcept Handle<SHMesh> SHPrimitiveGenerator::Sphere(SHMeshLibrary& meshLibrary) noexcept
{ {
if (sphereMesh.VertexPositions.empty()) if (sphereMesh.VertexPositions.empty())
sphereMesh = Sphere(); sphereMesh = Sphere();
@ -273,7 +279,7 @@ namespace SHADE
return addMeshDataTo(sphereMesh, meshLibrary); return addMeshDataTo(sphereMesh, meshLibrary);
} }
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::Sphere(SHGraphicsSystem& gfxSystem) noexcept Handle<SHMesh> SHPrimitiveGenerator::Sphere(SHGraphicsSystem& gfxSystem) noexcept
{ {
if (sphereMesh.VertexPositions.empty()) if (sphereMesh.VertexPositions.empty())
sphereMesh = Sphere(); sphereMesh = Sphere();
@ -281,6 +287,111 @@ namespace SHADE
return addMeshDataTo(sphereMesh, gfxSystem); return addMeshDataTo(sphereMesh, gfxSystem);
} }
SHMeshData SHPrimitiveGenerator::LineCube() noexcept
{
SHMeshData mesh;
mesh.VertexPositions =
{
// Front
SHVec3(-0.5f, -0.5f, 0.5f),
SHVec3( 0.5f, -0.5f, 0.5f),
SHVec3( 0.5f, 0.5f, 0.5f),
SHVec3(-0.5f, 0.5f, 0.5f),
// Back
SHVec3(-0.5f, -0.5f, -0.5f),
SHVec3( 0.5f, -0.5f, -0.5f),
SHVec3( 0.5f, 0.5f, -0.5f),
SHVec3(-0.5f, 0.5f, -0.5f)
};
mesh.VertexNormals.resize(mesh.VertexPositions.size());
mesh.VertexTangents.resize(mesh.VertexPositions.size());
mesh.VertexTexCoords.resize(mesh.VertexPositions.size());
mesh.Indices =
{
// Front
0, 1,
1, 2,
2, 3,
3, 0,
// Connectors
0, 4,
1, 5,
2, 6,
3, 7,
// Back
4, 5,
5, 6,
6, 7,
7, 4,
};
return mesh;
}
Handle<SHMesh> SHPrimitiveGenerator::LineCube(SHMeshLibrary& meshLibrary) noexcept
{
if (lineCubeMesh.VertexPositions.empty())
lineCubeMesh = LineCube();
return addMeshDataTo(lineCubeMesh, meshLibrary);
}
Handle<SHMesh> SHPrimitiveGenerator::LineCube(SHGraphicsSystem& gfxSystem) noexcept
{
if (lineCubeMesh.VertexPositions.empty())
lineCubeMesh = LineCube();
return addMeshDataTo(lineCubeMesh, gfxSystem);
}
SHMeshData SHPrimitiveGenerator::LineCircle() noexcept
{
SHMeshData mesh;
// Generate points of the circle
static constexpr int SPLITS = 36;
static constexpr float ANGLE_INCREMENTS = (std::numbers::pi_v<float> * 2.0f) / static_cast<float>(SPLITS);
for (int i = 0; i < SPLITS; ++i)
{
const float ANGLE = ANGLE_INCREMENTS * i;
mesh.VertexPositions.emplace_back(cos(ANGLE) * 0.5f, sin(ANGLE) * 0.5f, 0.0f);
}
// Generate lines of the circle
for (int i = 1; i < SPLITS; ++i)
{
mesh.Indices.emplace_back(static_cast<uint32_t>(i - 1));
mesh.Indices.emplace_back(static_cast<uint32_t>(i));
}
// Last line to complete the circle
mesh.Indices.emplace_back(static_cast<uint32_t>(SPLITS - 1));
mesh.Indices.emplace_back(static_cast<uint32_t>(0));
mesh.VertexNormals.resize(mesh.VertexPositions.size());
mesh.VertexTangents.resize(mesh.VertexPositions.size());
mesh.VertexTexCoords.resize(mesh.VertexPositions.size());
return mesh;
}
Handle<SHMesh> SHPrimitiveGenerator::LineCircle(SHMeshLibrary& meshLibrary) noexcept
{
if (lineCircleMesh.VertexPositions.empty())
lineCircleMesh = LineCircle();
return addMeshDataTo(lineCircleMesh, meshLibrary);
}
Handle<SHMesh> SHPrimitiveGenerator::LineCircle(SHGraphicsSystem& gfxSystem) noexcept
{
if (lineCircleMesh.VertexPositions.empty())
lineCircleMesh = LineCircle();
return addMeshDataTo(lineCircleMesh, gfxSystem);
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -288,7 +399,7 @@ namespace SHADE
{ {
return meshLibrary.AddMesh return meshLibrary.AddMesh
( (
static_cast<uint32_t>(meshData.VertexPositions.size()), static_cast<uint32_t>(meshData.VertexPositions.size()),
meshData.VertexPositions.data(), meshData.VertexPositions.data(),
meshData.VertexTexCoords.data(), meshData.VertexTexCoords.data(),
meshData.VertexTangents.data(), meshData.VertexTangents.data(),
@ -302,12 +413,12 @@ namespace SHADE
{ {
return gfxSystem.AddMesh return gfxSystem.AddMesh
( (
static_cast<uint32_t>(meshData.VertexPositions.size()), static_cast<uint32_t>(meshData.VertexPositions.size()),
meshData.VertexPositions.data(), meshData.VertexPositions.data(),
meshData.VertexTexCoords.data(), meshData.VertexTexCoords.data(),
meshData.VertexTangents.data(), meshData.VertexTangents.data(),
meshData.VertexNormals.data(), meshData.VertexNormals.data(),
static_cast<uint32_t>(meshData.Indices.size()), static_cast<uint32_t>(meshData.Indices.size()),
meshData.Indices.data() meshData.Indices.data()
); );
} }

View File

@ -43,7 +43,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Primitive Generation Functions */ /* Primitive Generation Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/***********************************************************************************/ /***********************************************************************************/
/*! /*!
\brief \brief
@ -116,6 +116,84 @@ namespace SHADE
*/ */
/***********************************************************************************/ /***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> Sphere(SHGraphicsSystem& gfxSystem) noexcept; [[nodiscard]] static Handle<SHMesh> Sphere(SHGraphicsSystem& gfxSystem) noexcept;
/***********************************************************************************/
/*!
\brief
Produces a cube that is comprised only of lines with no diagonal lines and store
the data in a SHMeshData object.
\return
SHMeshData object containing vertex data for the line cube.
*/
/***********************************************************************************/
[[nodiscard]] static SHMeshData LineCube() noexcept;
/***********************************************************************************/
/*!
\brief
Produces a line cube and constructs a SHMesh using the SHGraphicsSystem provided.
\param meshLibrary
Reference to the SHMeshLibrary to produce and store a line cube mesh in.
\return
SHMesh object that points to the generated line cube mesh in the SHMeshLibrary.
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> LineCube(SHMeshLibrary& meshLibrary) noexcept;
/***********************************************************************************/
/*!
\brief
Produces a line cube and constructs a SHMesh using the SHGraphicsSystem provided.
\param gfxSystem
Reference to the SHGraphicsSystem to produce and store a line cube mesh in.
\return
SHMesh object that points to the generated line cube mesh in the
SHGraphicsSystem.
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> LineCube(SHGraphicsSystem& gfxSystem) noexcept;
/***********************************************************************************/
/*!
\brief
Produces a circle that is comprised only of lines with no diagonal lines and
store the data in a SHMeshData object.
\return
SHMeshData object containing vertex data for the line circle.
*/
/***********************************************************************************/
[[nodiscard]] static SHMeshData LineCircle() noexcept;
/***********************************************************************************/
/*!
\brief
Produces a line circle and constructs a SHMesh using the SHGraphicsSystem
provided.
\param meshLibrary
Reference to the SHMeshLibrary to produce and store a line circle mesh in.
\return
SHMesh object that points to the generated line circle mesh in the SHMeshLibrary.
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> LineCircle(SHMeshLibrary& meshLibrary) noexcept;
/***********************************************************************************/
/*!
\brief
Produces a line circle and constructs a SHMesh using the SHGraphicsSystem
provided.
\param gfxSystem
Reference to the SHGraphicsSystem to produce and store a line circle mesh in.
\return
SHMesh object that points to the generated line circle mesh in the
SHGraphicsSystem.
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> LineCircle(SHGraphicsSystem& gfxSystem) noexcept;
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -129,5 +207,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
static SHMeshData cubeMesh; static SHMeshData cubeMesh;
static SHMeshData sphereMesh; static SHMeshData sphereMesh;
static SHMeshData lineCubeMesh;
static SHMeshData lineCircleMesh;
}; };
} }

View File

@ -186,6 +186,27 @@ namespace SHADE
return NODE_ITER->second->GetChildren(); return NODE_ITER->second->GetChildren();
} }
bool SHSceneGraph::IsActive(EntityID entityID) const noexcept
{
////////////////////////////////////////
// Error handling
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return false;
}
const auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_ERROR("Entity {} cannot be found in the scene!", entityID)
return false;
}
////////////////////////////////////////
return NODE_ITER->second->IsActive();
}
bool SHSceneGraph::IsActiveInHierarchy(EntityID entityID) const noexcept bool SHSceneGraph::IsActiveInHierarchy(EntityID entityID) const noexcept
{ {
//////////////////////////////////////// ////////////////////////////////////////
@ -204,24 +225,7 @@ namespace SHADE
} }
//////////////////////////////////////// ////////////////////////////////////////
// Recurse up the tree until the root. If any parent is inactive, this node is inactive in the hierarchy. return NODE_ITER->second->IsActiveInHierarchy();
const SHSceneNode* PARENT_NODE = NODE_ITER->second->parent;
while (PARENT_NODE->GetEntityID() != root->GetEntityID())
{
if (!PARENT_NODE->IsActive())
return false;
if (!PARENT_NODE->parent)
{
SHLOGV_ERROR("Entity {}'s node that is not the root has no parent!", PARENT_NODE->GetEntityID())
return false;
}
PARENT_NODE = PARENT_NODE->parent;
}
return true;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -306,6 +310,27 @@ namespace SHADE
SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT); SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT);
} }
void SHSceneGraph::SetActive(EntityID entityID, bool isActive) noexcept
{
////////////////////////////////////////
// Error handling
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return;
}
const auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_ERROR("Entity {} cannot be found in the scene!", entityID)
return;
}
////////////////////////////////////////
NODE_ITER->second->SetActive(isActive);
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Public Function Member Definitions */ /* Public Function Member Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -62,6 +62,7 @@ namespace SHADE
[[nodiscard]] SHSceneNode* GetChild (EntityID entityID, EntityID childEntityID) const noexcept; [[nodiscard]] SHSceneNode* GetChild (EntityID entityID, EntityID childEntityID) const noexcept;
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren (EntityID entityID) const noexcept; [[nodiscard]] const std::vector<SHSceneNode*>& GetChildren (EntityID entityID) const noexcept;
[[nodiscard]] bool IsActive (EntityID entityID) const noexcept;
[[nodiscard]] bool IsActiveInHierarchy (EntityID entityID) const noexcept; [[nodiscard]] bool IsActiveInHierarchy (EntityID entityID) const noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -92,6 +93,8 @@ namespace SHADE
*/ */
void SetParent (EntityID entityID, EntityID newParent) noexcept; void SetParent (EntityID entityID, EntityID newParent) noexcept;
void SetActive (EntityID entityID, bool isActive) noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -23,24 +23,27 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHSceneNode::SHSceneNode(EntityID eid, SHSceneNode* parent) noexcept SHSceneNode::SHSceneNode(EntityID eid, SHSceneNode* parent) noexcept
: active { true } : active { true }
, entityID { eid } , isActiveInHierarchy { true }
, parent { parent } , entityID { eid }
, parent { parent }
{} {}
SHSceneNode::SHSceneNode(const SHSceneNode& rhs) noexcept SHSceneNode::SHSceneNode(const SHSceneNode& rhs) noexcept
: active { rhs.active } : active { rhs.active }
, entityID { rhs.entityID } , isActiveInHierarchy { rhs.isActiveInHierarchy }
, parent { rhs.parent } , entityID { rhs.entityID }
, parent { rhs.parent }
{ {
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children)); std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
} }
SHSceneNode::SHSceneNode(SHSceneNode&& rhs) noexcept SHSceneNode::SHSceneNode(SHSceneNode&& rhs) noexcept
: active { rhs.active } : active { rhs.active }
, entityID { rhs.entityID } , isActiveInHierarchy { rhs.isActiveInHierarchy }
, parent { rhs.parent } , entityID { rhs.entityID }
, parent { rhs.parent }
{ {
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children)); std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
} }
@ -50,9 +53,10 @@ namespace SHADE
if (this == &rhs) if (this == &rhs)
return *this; return *this;
active = rhs.active; active = rhs.active;
entityID = rhs.entityID; isActiveInHierarchy = rhs.isActiveInHierarchy;
parent = rhs.parent; entityID = rhs.entityID;
parent = rhs.parent;
children.clear(); children.clear();
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children)); std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
@ -62,9 +66,10 @@ namespace SHADE
SHSceneNode& SHSceneNode::operator=(SHSceneNode&& rhs) noexcept SHSceneNode& SHSceneNode::operator=(SHSceneNode&& rhs) noexcept
{ {
active = rhs.active; active = rhs.active;
entityID = rhs.entityID; isActiveInHierarchy = rhs.isActiveInHierarchy;
parent = rhs.parent; entityID = rhs.entityID;
parent = rhs.parent;
children.clear(); children.clear();
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children)); std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
@ -81,6 +86,11 @@ namespace SHADE
return active; return active;
} }
bool SHSceneNode::IsActiveInHierarchy() const noexcept
{
return isActiveInHierarchy;
}
EntityID SHSceneNode::GetEntityID() const noexcept EntityID SHSceneNode::GetEntityID() const noexcept
{ {
return entityID; return entityID;
@ -132,7 +142,31 @@ namespace SHADE
void SHSceneNode::SetActive(bool newActiveState) noexcept void SHSceneNode::SetActive(bool newActiveState) noexcept
{ {
active = newActiveState; active = newActiveState;
isActiveInHierarchy = newActiveState;
// Set the entity's active state
// TODO(Daniel / Diren): Sync it based on active in hierarchy or active state.
SHEntityManager::GetEntityByID(entityID)->SetActive(active);
// Recurse down the children to set the active in hierarchy state
recursiveSetActiveInHierarchy(active, children);
}
/*-----------------------------------------------------------------------------------*/
/* Private Member Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHSceneNode::recursiveSetActiveInHierarchy(bool activeInHierarchy, const std::vector<SHSceneNode*>& childrenToSet) noexcept
{
if (childrenToSet.empty())
return;
for (auto* child : childrenToSet)
{
child->isActiveInHierarchy = activeInHierarchy;
recursiveSetActiveInHierarchy(activeInHierarchy, child->children);
}
} }
} // namespace SHADE } // namespace SHADE

View File

@ -40,7 +40,7 @@ namespace SHADE
/* Constructors & Destructor */ /* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
~SHSceneNode () = default; ~SHSceneNode () noexcept = default;
SHSceneNode (EntityID eid, SHSceneNode* parent = nullptr) noexcept; SHSceneNode (EntityID eid, SHSceneNode* parent = nullptr) noexcept;
SHSceneNode (const SHSceneNode& rhs) noexcept; SHSceneNode (const SHSceneNode& rhs) noexcept;
@ -52,10 +52,11 @@ namespace SHADE
/* Getter Functions */ /* Getter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
[[nodiscard]] bool IsActive () const noexcept; [[nodiscard]] bool IsActive () const noexcept;
[[nodiscard]] EntityID GetEntityID () const noexcept; [[nodiscard]] bool IsActiveInHierarchy () const noexcept;
[[nodiscard]] SHSceneNode* GetParent () const noexcept; [[nodiscard]] EntityID GetEntityID () const noexcept;
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren () const noexcept; [[nodiscard]] SHSceneNode* GetParent () const noexcept;
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren () const noexcept;
[[nodiscard]] SHSceneNode* GetChild (EntityID childID) const noexcept; [[nodiscard]] SHSceneNode* GetChild (EntityID childID) const noexcept;
@ -71,9 +72,16 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
bool active; bool active;
bool isActiveInHierarchy;
EntityID entityID; EntityID entityID;
SHSceneNode* parent; SHSceneNode* parent;
std::vector<SHSceneNode*> children; std::vector<SHSceneNode*> children;
/*---------------------------------------------------------------------------------*/
/* Member Functions */
/*---------------------------------------------------------------------------------*/
static void recursiveSetActiveInHierarchy(bool activeInHierarchy, const std::vector<SHSceneNode*>& childrenToSet) noexcept;
}; };
} // namespace SHADE } // namespace SHADE

View File

@ -15,6 +15,8 @@ of DigiPen Institute of Technology is prohibited.
#include "SHDebugDraw.h" #include "SHDebugDraw.h"
// Project Includes // Project Includes
#include "Math/Vector/SHVec4.h" #include "Math/Vector/SHVec4.h"
#include "Math/SHQuaternion.h"
#include "Math/SHQuaternion.h"
#include "Math/SHColour.h" #include "Math/SHColour.h"
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h" #include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
@ -41,69 +43,181 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Draw Functions */ /* Draw Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHDebugDraw::Line(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt) void SHDebugDraw::Line(const SHVec3& startPt, const SHVec3& endPt, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawLine(color, startPt, endPt); dbgDrawSys->DrawLine(startPt, endPt, color, depthTested);
} }
void SHDebugDraw::Tri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3) void SHDebugDraw::Tri(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawTri(color, pt1, pt2, pt3); dbgDrawSys->DrawTri(pt1, pt2, pt3, color, depthTested);
} }
void SHDebugDraw::Quad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4) void SHDebugDraw::Quad(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawQuad(color, pt1, pt2, pt3, pt4); dbgDrawSys->DrawQuad(pt1, pt2, pt3, pt4, color, depthTested);
} }
void SHDebugDraw::Poly(const SHVec4& color, std::initializer_list<SHVec3> pointList) void SHDebugDraw::Circle(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawPoly(color, pointList); dbgDrawSys->DrawCircle(mat, color, depthTested);
} }
void SHDebugDraw::Cube(const SHVec4& color, const SHVec3& pos, const SHVec3& size) void SHDebugDraw::LineLoop(std::initializer_list<SHVec3> pointList, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawCube(color, pos, size); dbgDrawSys->DrawLineLoop(pointList, color, depthTested);
} }
void SHDebugDraw::Sphere(const SHVec4& color, const SHVec3& pos, double radius) void SHDebugDraw::Cube(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawSphere(color, pos, SHVec3::Zero, radius); dbgDrawSys->DrawCube(mat, color, depthTested);
} }
void SHDebugDraw::PersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt) void SHDebugDraw::Cube(const SHVec3& center, const SHVec3& scale, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawPersistentLine(color, startPt, endPt); dbgDrawSys->DrawCube(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
} }
void SHDebugDraw::PersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3) void SHDebugDraw::Cube(const SHVec3& center, const SHQuaternion& orientation, const SHVec3& scale, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawPersistentTri(color, pt1, pt2, pt3); dbgDrawSys->DrawCube(SHMatrix::Transform(center, orientation, scale), color, depthTested);
} }
void SHDebugDraw::PersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4) void SHDebugDraw::Cube(const SHVec3& center, const SHVec3& eulerAngles, const SHVec3& scale, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawPersistentQuad(color, pt1, pt2, pt3, pt4); dbgDrawSys->DrawCube(SHMatrix::Transform(center, eulerAngles, scale), color, depthTested);
} }
void SHDebugDraw::PersistentPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList) void SHDebugDraw::Sphere(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawPersistentPoly(color, pointList); dbgDrawSys->DrawSphere(mat, color, depthTested);
} }
void SHDebugDraw::PersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size) void SHDebugDraw::Sphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawPersistentCube(color, pos, size); dbgDrawSys->DrawSphere(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
} }
void SHDebugDraw::PersistentSphere(const SHVec4& color, const SHVec3& pos, double radius) void SHDebugDraw::Sphere(const SHVec3& center, const SHQuaternion& orientation, SHVec3& scale, const SHVec4& color, bool depthTested)
{ {
dbgDrawSys->DrawPersistentSphere(color, pos, radius); dbgDrawSys->DrawSphere(SHMatrix::Transform(center, orientation, scale), color, depthTested);
} }
void SHDebugDraw::ClearPersistentDraws() void SHDebugDraw::Sphere(const SHVec3& center, const SHVec3& eulerAngles, SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawSphere(SHMatrix::Transform(center, eulerAngles, scale), color, depthTested);
}
void SHDebugDraw::WireCube(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawWireCube(mat, color, depthTested);
}
void SHDebugDraw::WireCube(const SHVec3& center, const SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawWireCube(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
}
void SHDebugDraw::WireSphere(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawWireSphere(mat, color, depthTested);
}
void SHDebugDraw::WireSphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawWireSphere(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
}
/*-----------------------------------------------------------------------------------*/
/* Persistent Draw Functions */
/*-----------------------------------------------------------------------------------*/
void SHDebugDraw::Persistent::Line(const SHVec3& startPt, const SHVec3& endPt, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentLine(startPt, endPt, color, depthTested);
}
void SHDebugDraw::Persistent::Tri(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentTri(pt1, pt2, pt3, color, depthTested);
}
void SHDebugDraw::Persistent::Quad(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentQuad(pt1, pt2, pt3, pt4, color, depthTested);
}
void SHDebugDraw::Persistent::Circle(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentCircle(mat, color, depthTested);
}
void SHDebugDraw::Persistent::LineLoop(std::initializer_list<SHVec3> pointList, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentLineLoop(pointList, color, depthTested);
}
void SHDebugDraw::Persistent::Cube(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentCube(mat, color, depthTested);
}
void SHDebugDraw::Persistent::Cube(const SHVec3& center, const SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentCube(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
}
void SHDebugDraw::Persistent::Cube(const SHVec3& center, const SHQuaternion& orientation, const SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentCube(SHMatrix::Transform(center, orientation, scale), color, depthTested);
}
void SHDebugDraw::Persistent::Cube(const SHVec3& center, const SHVec3& eulerAngles, const SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentCube(SHMatrix::Transform(center, eulerAngles, scale), color, depthTested);
}
void SHDebugDraw::Persistent::Sphere(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentSphere(mat, color, depthTested);
}
void SHDebugDraw::Persistent::Sphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentSphere(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
}
void SHDebugDraw::Persistent::Sphere(const SHVec3& center, const SHQuaternion& orientation, SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentSphere(SHMatrix::Transform(center, orientation, scale), color, depthTested);
}
void SHDebugDraw::Persistent::Sphere(const SHVec3& center, const SHVec3& eulerAngles, SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentSphere(SHMatrix::Transform(center, eulerAngles, scale), color, depthTested);
}
void SHDebugDraw::Persistent::WireCube(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentWireCube(mat, color, depthTested);
}
void SHDebugDraw::Persistent::WireCube(const SHVec3& center, const SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentWireCube(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
}
void SHDebugDraw::Persistent::WireSphere(const SHMatrix& mat, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentWireSphere(mat, color, depthTested);
}
void SHDebugDraw::Persistent::WireSphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color, bool depthTested)
{
dbgDrawSys->DrawPersistentWireSphere(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
}
void SHDebugDraw::Persistent::ClearDraws()
{ {
dbgDrawSys->ClearPersistentDraws(); dbgDrawSys->ClearPersistentDraws();
} }
}
}

View File

@ -13,6 +13,7 @@ of DigiPen Institute of Technology is prohibited.
// Project Includes // Project Includes
#include "SH_API.h" #include "SH_API.h"
#include "Math/SHColour.h"
namespace SHADE namespace SHADE
{ {
@ -22,7 +23,8 @@ namespace SHADE
class SHDebugDrawSystem; class SHDebugDrawSystem;
class SHVec4; class SHVec4;
class SHVec3; class SHVec3;
class SHColour; class SHQuaternion;
class SHMatrix;
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
@ -50,105 +52,324 @@ namespace SHADE
/// <summary> /// <summary>
/// Renders a line between two points in world space. /// Renders a line between two points in world space.
/// </summary> /// </summary>
/// <param name="color">Colour of the line.</param>
/// <param name="startPt">First point of the line.</param> /// <param name="startPt">First point of the line.</param>
/// <param name="endPt">Second point of the line.</param> /// <param name="endPt">Second point of the line.</param>
static void Line(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt); /// <param name="color">Colour of the line.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Line(const SHVec3& startPt, const SHVec3& endPt, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a triangle indicated by three points in world space. /// Renders a triangle indicated by three points in world space.
/// </summary> /// </summary>
/// <param name="color">Colour of the triangle.</param>
/// <param name="pt1">First point of the triangle.</param> /// <param name="pt1">First point of the triangle.</param>
/// <param name="pt2">Second point of the triangle.</param> /// <param name="pt2">Second point of the triangle.</param>
/// <param name="pt3">Third point of the triangle.</param> /// <param name="pt3">Third point of the triangle.</param>
static void Tri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3); /// <param name="color">Colour of the triangle.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Tri(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a quadrilateral indicated by four points in world space. /// Renders a quadrilateral indicated by four points in world space.
/// </summary> /// </summary>
/// <param name="color">Colour of the quadrilateral.</param>
/// <param name="pt1">First point of the triangle.</param> /// <param name="pt1">First point of the triangle.</param>
/// <param name="pt2">Second point of the quadrilateral.</param> /// <param name="pt2">Second point of the quadrilateral.</param>
/// <param name="pt3">Third point of the quadrilateral.</param> /// <param name="pt3">Third point of the quadrilateral.</param>
/// <param name="pt4">Third point of the quadrilateral.</param> /// <param name="pt4">Third point of the quadrilateral.</param>
static void Quad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4); /// <param name="color">Colour of the quadrilateral.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Quad(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a 2-dimensional circle in world space.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the circle should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Circle(const SHMatrix& mat,const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a polygon indicated by the specified set of points in world space. /// Renders a polygon indicated by the specified set of points in world space.
/// </summary> /// </summary>
/// <param name="color">Colour of the polygon.</param>
/// <param name="pointList">List of points for the polygon.</param> /// <param name="pointList">List of points for the polygon.</param>
static void Poly(const SHVec4& color, std::initializer_list<SHVec3> pointList); /// <param name="color">Colour of the polygon.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void LineLoop(std::initializer_list<SHVec3> pointList, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a wireframe cube centered around the position specified in world space. /// Draws a filled cube in world space.
/// </summary> /// </summary>
/// <param name="color">Colour of the cube.</param> /// <param name="matrix">
/// <param name="pos">Position where the cube wil be centered at.</param> /// Matrix transformation that defines how the cube should be drawn.
/// <param name="size">Size of the rendered cube.</param> /// </param>
static void Cube(const SHVec4& color, const SHVec3& pos, const SHVec3& size); /// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Cube(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary> /// <summary>
/// Renders a wireframe sphere centered around the position specified in world space. /// Draws a filled cube in world space.
/// </summary> /// </summary>
/// <param name="color">Colour of the sphere.</param> /// <param name="center">Center of the Cube.</param>
/// <param name="pos">Position where the sphere wil be centered at.</param> /// <param name="scale">Size of the Cube.</param>
/// <param name="size">Size of the rendered sphere.</param> /// <param name="color">Colour to draw with.</param>
static void Sphere(const SHVec4& color, const SHVec3& pos, double radius); /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Cube(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled cube in world space.
/// </summary>
/// <param name="center">Center of the Cube.</param>
/// <param name="orientation">Orientation of the cube.</param>
/// <param name="scale">Size of the Cube.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Cube(const SHVec3& center, const SHQuaternion& orientation, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled cube in world space.
/// </summary>
/// <param name="center">Center of the Cube.</param>
/// <param name="eulerAngles">Euler angle rotation of the cube in radians.</param>
/// <param name="scale">Size of the Cube.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Cube(const SHVec3& center, const SHVec3& eulerAngles, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere in world space.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the sphere should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Sphere(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere in world space.
/// </summary>
/// <param name="center">Center point of the sphere.</param>
/// <param name="scale">Size of the sphere.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Sphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere in world space.
/// </summary>
/// <param name="center">Center point of the sphere.</param>
/// <param name="orientation">Orientation of the sphere.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Sphere(const SHVec3& center, const SHQuaternion& orientation, SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere in world space.
/// </summary>
/// <param name="center">Center point of the sphere.</param>
/// <param name="eulerAngles">Euler angle rotation of the sphere in radians.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Sphere(const SHVec3& center, const SHVec3& eulerAngles, SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the outline of a cube in world space.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the wire cube should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireCube(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the outline of a cube in world space.
/// </summary>
/// <param name="center">Center of the Cube.</param>
/// <param name="scale">Size of the Cube.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireCube(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the wireframe of a sphere in world space.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the sphere should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireSphere(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the wireframe of a sphere in world space.
/// </summary>
/// <param name="center">Center point of the sphere.</param>
/// <param name="scale">Size of the sphere.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireSphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Persistent Draw Functions */ /* Persistent Draw Function Class "Folder" */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/// <summary> struct SH_API Persistent
/// Renders a line between two points in world space that will persist until {
/// ClearPersistentDraws() is called. /*-------------------------------------------------------------------------------*/
/// </summary> /* Persistent Draw Functions */
/// <param name="color">Colour of the line.</param> /*-------------------------------------------------------------------------------*/
/// <param name="startPt">First point of the line.</param> /// <summary>
/// <param name="endPt">Second point of the line.</param> /// Renders a line between two points in world space.
static void PersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt); /// This will remain drawn until ClearDraws() is called.
/// <summary> /// </summary>
/// Renders a triangle indicated by three points in world space that will persist /// <param name="startPt">First point of the line.</param>
/// until ClearPersistentDraws() is called. /// <param name="endPt">Second point of the line.</param>
/// </summary> /// <param name="color">Colour of the line.</param>
/// <param name="color">Colour of the triangle.</param> /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
/// <param name="pt1">First point of the triangle.</param> static void Line(const SHVec3& startPt, const SHVec3& endPt, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <param name="pt2">Second point of the triangle.</param> /// <summary>
/// <param name="pt3">Third point of the triangle.</param> /// Renders a triangle indicated by three points in world space.
static void PersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3); /// This will remain drawn until ClearDraws() is called.
/// <summary> /// </summary>
/// Renders a quadrilateral indicated by four points in world space that will persist /// <param name="pt1">First point of the triangle.</param>
/// until ClearPersistentDraws() is called. /// <param name="pt2">Second point of the triangle.</param>
/// </summary> /// <param name="pt3">Third point of the triangle.</param>
/// <param name="color">Colour of the quadrilateral.</param> /// <param name="color">Colour of the triangle.</param>
/// <param name="pt1">First point of the triangle.</param> /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
/// <param name="pt2">Second point of the quadrilateral.</param> static void Tri(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <param name="pt3">Third point of the quadrilateral.</param> /// <summary>
/// <param name="pt4">Third point of the quadrilateral.</param> /// Renders a quadrilateral indicated by four points in world space.
static void PersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4); /// This will remain drawn until ClearDraws() is called.
/// <summary> /// </summary>
/// Renders a polygon indicated by the specified set of points in world space that /// <param name="pt1">First point of the triangle.</param>
/// will persist until ClearPersistentDraws() is called. /// <param name="pt2">Second point of the quadrilateral.</param>
/// </summary> /// <param name="pt3">Third point of the quadrilateral.</param>
/// <param name="color">Colour of the polygon.</param> /// <param name="pt4">Third point of the quadrilateral.</param>
/// <param name="pointList">List of points for the polygon.</param> /// <param name="color">Colour of the quadrilateral.</param>
static void PersistentPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList); /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
/// <summary> static void Quad(const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// Renders a wireframe cube centered around the position specified in world space /// <summary>
/// that will persist until ClearPersistentDraws() is called. /// Draws a 2-dimensional circle in world space.
/// </summary> /// This will remain drawn until ClearDraws() is called.
/// <param name="color">Colour of the cube.</param> /// </summary>
/// <param name="pos">Position where the cube wil be centered at.</param> /// <param name="matrix">
/// <param name="size">Size of the rendered cube.</param> /// Matrix transformation that defines how the circle should be drawn.
static void PersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size); /// </param>
/// <summary> /// <param name="color">Colour to draw with.</param>
/// Renders a wireframe sphere centered around the position specified in world space /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
/// that will persist until ClearPersistentDraws() is called. static void Circle(const SHMatrix& mat,const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// </summary> /// <summary>
/// <param name="color">Colour of the sphere.</param> /// Renders a polygon indicated by the specified set of points in world space.
/// <param name="pos">Position where the sphere wil be centered at.</param> /// This will remain drawn until ClearDraws() is called.
/// <param name="size">Size of the rendered sphere.</param> /// </summary>
static void PersistentSphere(const SHVec4& color, const SHVec3& pos, double radius); /// <param name="pointList">List of points for the polygon.</param>
/// <summary> /// <param name="color">Colour of the polygon.</param>
/// Clears any persistent drawn debug primitives. /// <param name="depthTested">Whether or not drawn object will be occluded.</param>
/// </summary> static void LineLoop(std::initializer_list<SHVec3> pointList, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
static void ClearPersistentDraws(); /// <summary>
/// Draws a filled cube in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the cube should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Cube(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled cube in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="center">Center of the Cube.</param>
/// <param name="scale">Size of the Cube.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Cube(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled cube in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="center">Center of the Cube.</param>
/// <param name="orientation">Orientation of the cube.</param>
/// <param name="scale">Size of the Cube.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Cube(const SHVec3& center, const SHQuaternion& orientation, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled cube in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="center">Center of the Cube.</param>
/// <param name="eulerAngles">Euler angle rotation of the cube in radians.</param>
/// <param name="scale">Size of the Cube.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Cube(const SHVec3& center, const SHVec3& eulerAngles, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the sphere should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Sphere(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="center">Center point of the sphere.</param>
/// <param name="scale">Size of the sphere.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Sphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="center">Center point of the sphere.</param>
/// <param name="orientation">Orientation of the sphere.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Sphere(const SHVec3& center, const SHQuaternion& orientation, SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a filled sphere in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="center">Center point of the sphere.</param>
/// <param name="eulerAngles">Euler angle rotation of the sphere in radians.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void Sphere(const SHVec3& center, const SHVec3& eulerAngles, SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the outline of a cube in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the wire cube should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireCube(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the outline of a cube in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="center">Center of the Cube.</param>
/// <param name="scale">Size of the Cube.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireCube(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the wireframe of a sphere in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="matrix">
/// Matrix transformation that defines how the sphere should be drawn.
/// </param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireSphere(const SHMatrix& mat, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the wireframe of a sphere in world space.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="center">Center point of the sphere.</param>
/// <param name="scale">Size of the sphere.</param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireSphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Clears any persistent drawn debug primitives.
/// </summary>
static void ClearDraws();
};
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -76,7 +76,13 @@ namespace SHADE
{ {
if (!valid) if (!valid)
throw gcnew System::NullReferenceException(); throw gcnew System::NullReferenceException();
return GetNativeEntity().GetActive(); auto node = SHSceneManager::GetCurrentSceneGraph().GetNode(GetEntity());
if (!node)
{
Debug::LogWarning("Attempting to access a GameObject's Active state which does not exist. Assuming inactive.");
return false;
}
return node->IsActive();
} }
bool GameObject::IsActiveInHierarchy::get() bool GameObject::IsActiveInHierarchy::get()
{ {
@ -88,7 +94,7 @@ namespace SHADE
Debug::LogWarning("Attempting to access a GameObject's ActiveInHierarchy state which does not exist. Assuming inactive."); Debug::LogWarning("Attempting to access a GameObject's ActiveInHierarchy state which does not exist. Assuming inactive.");
return false; return false;
} }
return node->IsActive(); return node->IsActiveInHierarchy();
} }
Entity GameObject::EntityId::get() Entity GameObject::EntityId::get()
{ {
@ -148,7 +154,8 @@ namespace SHADE
{ {
if (!valid) if (!valid)
throw gcnew System::NullReferenceException(); throw gcnew System::NullReferenceException();
GetNativeEntity().SetActive(active);
SHSceneManager::GetCurrentSceneGraph().SetActive(GetEntity(), active);
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -44,7 +44,27 @@ namespace SHADE
void Gizmos::DrawLine(Vector3 from, Vector3 to, SHADE::Color color) void Gizmos::DrawLine(Vector3 from, Vector3 to, SHADE::Color color)
{ {
SHDebugDraw::Line(Convert::ToNative(color), Convert::ToNative(from), Convert::ToNative(to)); SHDebugDraw::Line(Convert::ToNative(from), Convert::ToNative(to), Convert::ToNative(color));
}
void Gizmos::DrawCube(Vector3 center, Vector3 extents)
{
DrawCube(center, extents, defaultColor);
}
void Gizmos::DrawCube(Vector3 center, Vector3 extents, SHADE::Color color)
{
SHDebugDraw::Cube(Convert::ToNative(center), Convert::ToNative(extents), Convert::ToNative(color));
}
void Gizmos::DrawSphere(Vector3 center, float radius)
{
DrawSphere(center, radius, defaultColor);
}
void Gizmos::DrawSphere(Vector3 center, float radius, SHADE::Color color)
{
SHDebugDraw::Sphere(Convert::ToNative(center), SHVec3(radius, radius, radius), Convert::ToNative(color));
} }
void Gizmos::DrawWireCube(Vector3 center, Vector3 extents) void Gizmos::DrawWireCube(Vector3 center, Vector3 extents)
@ -54,7 +74,7 @@ namespace SHADE
void Gizmos::DrawWireCube(Vector3 center, Vector3 extents, SHADE::Color color) void Gizmos::DrawWireCube(Vector3 center, Vector3 extents, SHADE::Color color)
{ {
SHDebugDraw::Cube(Convert::ToNative(color), Convert::ToNative(center), Convert::ToNative(extents)); SHDebugDraw::WireCube(Convert::ToNative(center), Convert::ToNative(extents), Convert::ToNative(color));
} }
void Gizmos::DrawWireSphere(Vector3 center, float radius) void Gizmos::DrawWireSphere(Vector3 center, float radius)
@ -64,6 +84,6 @@ namespace SHADE
void Gizmos::DrawWireSphere(Vector3 center, float radius, SHADE::Color color) void Gizmos::DrawWireSphere(Vector3 center, float radius, SHADE::Color color)
{ {
SHDebugDraw::Sphere(Convert::ToNative(color), Convert::ToNative(center), radius); SHDebugDraw::WireSphere(Convert::ToNative(center), SHVec3(radius, radius, radius), Convert::ToNative(color));
} }
} }

View File

@ -56,6 +56,38 @@ namespace SHADE
/// <param name="color">Colour of the line.</param> /// <param name="color">Colour of the line.</param>
static void DrawLine(Vector3 from, Vector3 to, SHADE::Color color); static void DrawLine(Vector3 from, Vector3 to, SHADE::Color color);
/// <summary> /// <summary>
/// Renders a cube centered around the position specified in world
/// space.
/// Uses <see cref="Gizmos.Color">Color</see> to render.
/// </summary>
/// <param name="center">Position where the cube wil be centered at.</param>
/// <param name="extents">Size of the rendered cube.</param>
static void DrawCube(Vector3 center, Vector3 extents);
/// <summary>
/// Renders a cube centered around the position specified in world
/// space.
/// </summary>
/// <param name="center">Position where the cube wil be centered at.</param>
/// <param name="extents">Size of the rendered cube.</param>
/// <param name="color">Colour of the cube.</param>
static void DrawCube(Vector3 center, Vector3 extents, SHADE::Color color);
/// <summary>
/// Renders a sphere centered around the position specified in world
/// space.
/// Uses <see cref="Gizmos.Color">Color</see> to render.
/// </summary>
/// <param name="center">Position where the sphere wil be centered at.</param>
/// <param name="radius">Radius of the rendered sphere.</param>
static void DrawSphere(Vector3 center, float radius);
/// <summary>
/// Renders a sphere centered around the position specified in world
/// space.
/// </summary>
/// <param name="center">Position where the sphere wil be centered at.</param>
/// <param name="radius">Radius of the rendered sphere.</param>
/// <param name="color">Colour of the sphere.</param>
static void DrawSphere(Vector3 center, float radius, SHADE::Color color);
/// <summary>
/// Renders a wireframe cube centered around the position specified in world /// Renders a wireframe cube centered around the position specified in world
/// space. /// space.
/// Uses <see cref="Gizmos.Color">Color</see> to render. /// Uses <see cref="Gizmos.Color">Color</see> to render.