SDK/DebugSystem: Add support for Collider2D

This commit is contained in:
Lynix 2019-03-26 19:05:25 +01:00
parent 1f5a82d178
commit e00d0baa00
4 changed files with 94 additions and 19 deletions

View File

@ -175,7 +175,7 @@ Nazara Engine:
- Fixed ENet UnreliableFragment packets sent as Unreliable (and such being incomplete upon reception) - Fixed ENet UnreliableFragment packets sent as Unreliable (and such being incomplete upon reception)
- ENet DisconnectLater now reflects libenet behavior (and is waiting for unreliable commands to be sent before disconnecting for good) - ENet DisconnectLater now reflects libenet behavior (and is waiting for unreliable commands to be sent before disconnecting for good)
- ⚠ Collider3D::ForEachPolygon now takes a void(Vector3f\*, std::size_t) callback (instead of void(float\*, std::size_t)) - ⚠ Collider3D::ForEachPolygon now takes a void(Vector3f\*, std::size_t) callback (instead of void(float\*, std::size_t))
- Added Collider2D::ForEachPolygon - Added Collider2D::ForEachPolygon method
Nazara Development Kit: Nazara Development Kit:
- Added ImageWidget (#139) - Added ImageWidget (#139)
@ -219,7 +219,7 @@ Nazara Development Kit:
- Fix GraphicsComponent bounding volume not taking local matrix in account - Fix GraphicsComponent bounding volume not taking local matrix in account
- ⚠️ Rewrote all render queue system, which should be more efficient, take scissor box into account - ⚠️ Rewrote all render queue system, which should be more efficient, take scissor box into account
- ⚠️ All widgets are now bound to a scissor box when rendering - ⚠️ All widgets are now bound to a scissor box when rendering
- Add DebugComponent (a component able to show aabb/obb/collision mesh) - Add DebugComponent (a component able to show aabb/obb/collision mesh 2D and 3D)
- ⚠️ TextAreaWidget now support text selection (WIP) - ⚠️ TextAreaWidget now support text selection (WIP)
- ⚠️ TextAreaWidget::GetHoveredGlyph now returns a two-dimensional position instead of a single glyph position - ⚠️ TextAreaWidget::GetHoveredGlyph now returns a two-dimensional position instead of a single glyph position
- Fixed Entity::OnEntityDestruction signal not being properly moved and thus not being called. - Fixed Entity::OnEntityDestruction signal not being properly moved and thus not being called.

View File

@ -16,7 +16,7 @@ namespace Ndk
{ {
enum class DebugDraw enum class DebugDraw
{ {
//TODO: Collider2D Collider2D,
Collider3D, Collider3D,
GraphicsAABB, GraphicsAABB,
GraphicsOBB, GraphicsOBB,

View File

@ -26,6 +26,7 @@ namespace Ndk
private: private:
Nz::InstancedRenderableRef GenerateBox(Nz::Boxf box); Nz::InstancedRenderableRef GenerateBox(Nz::Boxf box);
Nz::InstancedRenderableRef GenerateCollision2DMesh(Entity* entity, Nz::Vector3f* origin);
Nz::InstancedRenderableRef GenerateCollision3DMesh(Entity* entity); Nz::InstancedRenderableRef GenerateCollision3DMesh(Entity* entity);
Nz::MaterialRef GetCollisionMaterial(); Nz::MaterialRef GetCollisionMaterial();

View File

@ -8,10 +8,12 @@
#include <Nazara/Utility/IndexIterator.hpp> #include <Nazara/Utility/IndexIterator.hpp>
#include <Nazara/Utility/Mesh.hpp> #include <Nazara/Utility/Mesh.hpp>
#include <Nazara/Utility/StaticMesh.hpp> #include <Nazara/Utility/StaticMesh.hpp>
#include <NDK/Components/CollisionComponent2D.hpp>
#include <NDK/Components/CollisionComponent3D.hpp> #include <NDK/Components/CollisionComponent3D.hpp>
#include <NDK/Components/DebugComponent.hpp> #include <NDK/Components/DebugComponent.hpp>
#include <NDK/Components/GraphicsComponent.hpp> #include <NDK/Components/GraphicsComponent.hpp>
#include <NDK/Components/NodeComponent.hpp> #include <NDK/Components/NodeComponent.hpp>
#include <NDK/Components/PhysicsComponent2D.hpp>
namespace Ndk namespace Ndk
{ {
@ -227,17 +229,26 @@ namespace Ndk
{ {
switch (option) switch (option)
{ {
case DebugDraw::Collider2D:
{
const Nz::Boxf& obb = entityGfx.GetAABB();
Nz::Vector3f origin;
Nz::InstancedRenderableRef renderable = GenerateCollision2DMesh(entity, &origin);
if (renderable)
entityGfx.Attach(renderable, Nz::Matrix4f::Translate(origin - entityNode.GetPosition()), DebugDrawOrder);
entityDebug.UpdateDebugRenderable(option, std::move(renderable));
break;
}
case DebugDraw::Collider3D: case DebugDraw::Collider3D:
{ {
const Nz::Boxf& obb = entityGfx.GetAABB(); const Nz::Boxf& obb = entityGfx.GetAABB();
Nz::InstancedRenderableRef renderable = GenerateCollision3DMesh(entity); Nz::InstancedRenderableRef renderable = GenerateCollision3DMesh(entity);
if (renderable) if (renderable)
{
renderable->SetPersistent(false);
entityGfx.Attach(renderable, Nz::Matrix4f::Translate(obb.GetCenter() - entityNode.GetPosition()), DebugDrawOrder); entityGfx.Attach(renderable, Nz::Matrix4f::Translate(obb.GetCenter() - entityNode.GetPosition()), DebugDrawOrder);
}
entityDebug.UpdateDebugRenderable(option, std::move(renderable)); entityDebug.UpdateDebugRenderable(option, std::move(renderable));
break; break;
@ -306,6 +317,73 @@ namespace Ndk
return model; return model;
} }
Nz::InstancedRenderableRef DebugSystem::GenerateCollision2DMesh(Entity* entity, Nz::Vector3f* origin)
{
if (entity->HasComponent<CollisionComponent2D>())
{
CollisionComponent2D& entityCollision = entity->GetComponent<CollisionComponent2D>();
const Nz::Collider2DRef& geom = entityCollision.GetGeom();
std::vector<Nz::Vector3f> vertices;
std::vector<std::size_t> indices;
geom->ForEachPolygon([&](const Nz::Vector2f* polygonVertices, std::size_t vertexCount)
{
std::size_t firstIndex = vertices.size();
// Don't reserve and let the vector handle its own capacity
for (std::size_t i = 0; i < vertexCount; ++i)
vertices.emplace_back(*polygonVertices++);
for (std::size_t i = 0; i < vertexCount - 1; ++i)
{
indices.push_back(firstIndex + i);
indices.push_back(firstIndex + i + 1);
}
indices.push_back(firstIndex + vertexCount - 1);
indices.push_back(firstIndex);
});
Nz::IndexBufferRef indexBuffer = Nz::IndexBuffer::New(vertices.size() > 0xFFFF, Nz::UInt32(indices.size()), Nz::DataStorage_Hardware, 0);
Nz::IndexMapper indexMapper(indexBuffer, Nz::BufferAccess_WriteOnly);
Nz::IndexIterator indexPtr = indexMapper.begin();
for (std::size_t index : indices)
*indexPtr++ = static_cast<Nz::UInt32>(index);
indexMapper.Unmap();
Nz::VertexBufferRef vertexBuffer = Nz::VertexBuffer::New(Nz::VertexDeclaration::Get(Nz::VertexLayout_XYZ), Nz::UInt32(vertices.size()), Nz::DataStorage_Hardware, 0);
vertexBuffer->Fill(vertices.data(), 0, Nz::UInt32(vertices.size()));
Nz::MeshRef mesh = Nz::Mesh::New();
mesh->CreateStatic();
Nz::StaticMeshRef subMesh = Nz::StaticMesh::New(vertexBuffer, indexBuffer);
subMesh->SetPrimitiveMode(Nz::PrimitiveMode_LineList);
subMesh->SetMaterialIndex(0);
subMesh->GenerateAABB();
mesh->SetMaterialCount(1);
mesh->AddSubMesh(subMesh);
Nz::ModelRef model = Nz::Model::New();
model->SetMesh(mesh);
model->SetMaterial(0, GetCollisionMaterial());
// Find center of mass
if (entity->HasComponent<PhysicsComponent2D>())
*origin = entity->GetComponent<PhysicsComponent2D>().GetMassCenter(Nz::CoordSys_Global);
else
*origin = entity->GetComponent<NodeComponent>().GetPosition(Nz::CoordSys_Global);
return model;
}
else
return nullptr;
}
Nz::InstancedRenderableRef DebugSystem::GenerateCollision3DMesh(Entity* entity) Nz::InstancedRenderableRef DebugSystem::GenerateCollision3DMesh(Entity* entity)
{ {
if (entity->HasComponent<CollisionComponent3D>()) if (entity->HasComponent<CollisionComponent3D>())
@ -316,15 +394,11 @@ namespace Ndk
std::vector<Nz::Vector3f> vertices; std::vector<Nz::Vector3f> vertices;
std::vector<std::size_t> indices; std::vector<std::size_t> indices;
geom->ForEachPolygon([&](const float* polygonVertices, std::size_t vertexCount) geom->ForEachPolygon([&](const Nz::Vector3f* polygonVertices, std::size_t vertexCount)
{ {
std::size_t firstIndex = vertices.size(); std::size_t firstIndex = vertices.size();
vertices.resize(firstIndex + vertexCount);
for (std::size_t i = 0; i < vertexCount; ++i) std::copy(polygonVertices, polygonVertices + vertexCount, &vertices[firstIndex]);
{
const float* vertexData = &polygonVertices[i * 3];
vertices.emplace_back(vertexData[0], vertexData[1], vertexData[2]);
}
for (std::size_t i = 0; i < vertexCount - 1; ++i) for (std::size_t i = 0; i < vertexCount - 1; ++i)
{ {
@ -378,7 +452,7 @@ namespace Ndk
m_globalAabbMaterial->EnableDepthBuffer(true); m_globalAabbMaterial->EnableDepthBuffer(true);
m_globalAabbMaterial->SetDiffuseColor(Nz::Color::Orange); m_globalAabbMaterial->SetDiffuseColor(Nz::Color::Orange);
m_globalAabbMaterial->SetFaceFilling(Nz::FaceFilling_Line); m_globalAabbMaterial->SetFaceFilling(Nz::FaceFilling_Line);
m_globalAabbMaterial->SetLineWidth(2.f); //m_globalAabbMaterial->SetLineWidth(2.f);
} }
return m_globalAabbMaterial; return m_globalAabbMaterial;
@ -393,7 +467,7 @@ namespace Ndk
m_localAabbMaterial->EnableDepthBuffer(true); m_localAabbMaterial->EnableDepthBuffer(true);
m_localAabbMaterial->SetDiffuseColor(Nz::Color::Red); m_localAabbMaterial->SetDiffuseColor(Nz::Color::Red);
m_localAabbMaterial->SetFaceFilling(Nz::FaceFilling_Line); m_localAabbMaterial->SetFaceFilling(Nz::FaceFilling_Line);
m_localAabbMaterial->SetLineWidth(2.f); //m_localAabbMaterial->SetLineWidth(2.f);
} }
return m_localAabbMaterial; return m_localAabbMaterial;
@ -408,7 +482,7 @@ namespace Ndk
m_collisionMaterial->EnableDepthBuffer(true); m_collisionMaterial->EnableDepthBuffer(true);
m_collisionMaterial->SetDiffuseColor(Nz::Color::Blue); m_collisionMaterial->SetDiffuseColor(Nz::Color::Blue);
m_collisionMaterial->SetFaceFilling(Nz::FaceFilling_Line); m_collisionMaterial->SetFaceFilling(Nz::FaceFilling_Line);
m_collisionMaterial->SetLineWidth(2.f); //m_collisionMaterial->SetLineWidth(2.f);
} }
return m_collisionMaterial; return m_collisionMaterial;
@ -423,7 +497,7 @@ namespace Ndk
m_obbMaterial->EnableDepthBuffer(true); m_obbMaterial->EnableDepthBuffer(true);
m_obbMaterial->SetDiffuseColor(Nz::Color::Green); m_obbMaterial->SetDiffuseColor(Nz::Color::Green);
m_obbMaterial->SetFaceFilling(Nz::FaceFilling_Line); m_obbMaterial->SetFaceFilling(Nz::FaceFilling_Line);
m_obbMaterial->SetLineWidth(2.f); //m_obbMaterial->SetLineWidth(2.f);
} }
return m_obbMaterial; return m_obbMaterial;