diff --git a/include/Nazara/Physics3D/Collider3D.hpp b/include/Nazara/Physics3D/Collider3D.hpp index 519f9871b..0e09bad85 100644 --- a/include/Nazara/Physics3D/Collider3D.hpp +++ b/include/Nazara/Physics3D/Collider3D.hpp @@ -30,6 +30,7 @@ namespace Nz class PrimitiveList; class PhysWorld3D; + class StaticMesh; class NAZARA_PHYSICS3D_API Collider3D { @@ -48,6 +49,8 @@ namespace Nz virtual void ForEachPolygon(const std::function& callback) const; + virtual std::shared_ptr GenerateMesh() const; + NewtonCollision* GetHandle(PhysWorld3D* world) const; virtual ColliderType3D GetType() const = 0; diff --git a/src/Nazara/Physics3D/Collider3D.cpp b/src/Nazara/Physics3D/Collider3D.cpp index f48fa75be..0b1367eb8 100644 --- a/src/Nazara/Physics3D/Collider3D.cpp +++ b/src/Nazara/Physics3D/Collider3D.cpp @@ -5,6 +5,9 @@ #include #include #include +#include +#include +#include #include #include @@ -139,6 +142,44 @@ namespace Nz NewtonCollisionForEachPolygonDo(m_handles.begin()->second, Nz::Matrix4f::Identity(), newtCallback, const_cast(static_cast(&callback))); //< This isn't that bad; pointer will not be used for writing } + std::shared_ptr Collider3D::GenerateMesh() const + { + std::vector colliderVertices; + std::vector colliderIndices; + + // Generate a line list + ForEachPolygon([&](const Nz::Vector3f* vertices, std::size_t vertexCount) + { + Nz::UInt16 firstIndex = colliderVertices.size(); + for (std::size_t i = 0; i < vertexCount; ++i) + colliderVertices.push_back(vertices[i]); + + for (std::size_t i = 1; i < vertexCount; ++i) + { + colliderIndices.push_back(firstIndex + i - 1); + colliderIndices.push_back(firstIndex + i); + } + + if (vertexCount > 2) + { + colliderIndices.push_back(firstIndex + vertexCount - 1); + colliderIndices.push_back(firstIndex); + } + }); + + std::shared_ptr colliderVB = std::make_shared(Nz::VertexDeclaration::Get(Nz::VertexLayout::XYZ), colliderVertices.size(), Nz::DataStorage::Software, 0); + colliderVB->Fill(colliderVertices.data(), 0, colliderVertices.size()); + + std::shared_ptr colliderIB = std::make_shared(false, colliderIndices.size(), Nz::DataStorage::Software, 0); + colliderIB->Fill(colliderIndices.data(), 0, colliderIndices.size()); + + std::shared_ptr colliderSubMesh = std::make_shared(std::move(colliderVB), std::move(colliderIB)); + colliderSubMesh->GenerateAABB(); + colliderSubMesh->SetPrimitiveMode(Nz::PrimitiveMode::LineList); + + return colliderSubMesh; + } + NewtonCollision* Collider3D::GetHandle(PhysWorld3D* world) const { auto it = m_handles.find(world);