diff --git a/ChangeLog.md b/ChangeLog.md index 99b199f87..64d99fc76 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -75,6 +75,7 @@ Nazara Engine: - ⚠️ Renamed Bitset::Read to Bitset::Write - Fixed ENetCompressor class destructor not being virtual - ⚠️ Added a type tag parameter to Serialize and Unserialize functions, to prevent implicit conversions with overloads +- Added Collider3D::ForEachPolygon method, allowing construction of a debug mesh based on the physics collider Nazara Development Kit: - Added ImageWidget (#139) diff --git a/include/Nazara/Physics3D/Collider3D.hpp b/include/Nazara/Physics3D/Collider3D.hpp index b8a239349..a7a59a2d1 100644 --- a/include/Nazara/Physics3D/Collider3D.hpp +++ b/include/Nazara/Physics3D/Collider3D.hpp @@ -54,6 +54,8 @@ namespace Nz virtual void ComputeInertialMatrix(Vector3f* inertia, Vector3f* center) const; virtual float ComputeVolume() const; + virtual void ForEachPolygon(const std::function& callback) 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 454c18037..ff7253b5a 100644 --- a/src/Nazara/Physics3D/Collider3D.cpp +++ b/src/Nazara/Physics3D/Collider3D.cpp @@ -50,7 +50,7 @@ namespace Nz { Vector3f min, max; - // Si nous n'avons aucune instance, nous en cr�ons une temporaire + // Check for existing collision handles, and create a temporary one if none is available if (m_handles.empty()) { PhysWorld3D world; @@ -61,7 +61,7 @@ namespace Nz } NewtonDestroyCollision(collision); } - else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute fa�on) + else NewtonCollisionCalculateAABB(m_handles.begin()->second, offsetMatrix, min, max); return Boxf(scale * min, scale * max); @@ -72,7 +72,7 @@ namespace Nz float inertiaMatrix[3]; float origin[3]; - // Si nous n'avons aucune instance, nous en cr�ons une temporaire + // Check for existing collision handles, and create a temporary one if none is available if (m_handles.empty()) { PhysWorld3D world; @@ -83,7 +83,7 @@ namespace Nz } NewtonDestroyCollision(collision); } - else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute fa�on) + else NewtonConvexCollisionCalculateInertialMatrix(m_handles.begin()->second, inertiaMatrix, origin); if (inertia) @@ -97,7 +97,7 @@ namespace Nz { float volume; - // Si nous n'avons aucune instance, nous en cr�ons une temporaire + // Check for existing collision handles, and create a temporary one if none is available if (m_handles.empty()) { PhysWorld3D world; @@ -108,12 +108,35 @@ namespace Nz } NewtonDestroyCollision(collision); } - else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute fa�on) + else volume = NewtonConvexCollisionCalculateVolume(m_handles.begin()->second); return volume; } + void Collider3D::ForEachPolygon(const std::function& callback) const + { + auto newtCallback = [](void* const userData, int vertexCount, const dFloat* const faceArray, int /*faceId*/) + { + const auto& cb = *static_cast>(userData); + cb(faceArray, vertexCount); + }; + + // Check for existing collision handles, and create a temporary one if none is available + if (m_handles.empty()) + { + PhysWorld3D world; + + NewtonCollision* collision = CreateHandle(&world); + { + NewtonCollisionForEachPolygonDo(collision, Nz::Matrix4f::Identity(), newtCallback, const_cast(static_cast(&callback))); //< This isn't that bad; pointer will not be used for writing + } + NewtonDestroyCollision(collision); + } + else + 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 + } + NewtonCollision* Collider3D::GetHandle(PhysWorld3D* world) const { auto it = m_handles.find(world);