Log an error when convex mesh is created with duplicated vertices and add in user manual that this is not supported
This commit is contained in:
parent
30af76dfaf
commit
71f7980fdf
|
@ -1236,6 +1236,9 @@ ConvexMeshShape* convexMeshShape = physicsCommon.createConvexMeshShape(polyhedro
|
|||
that you need to avoid coplanar faces in your convex mesh shape. Coplanar faces have to be merged together. Remember that convex meshes are
|
||||
not limited to triangular faces, you can create faces with more than three vertices. \\
|
||||
|
||||
Also note that meshes with duplicated vertices are not supported. The number of vertices you pass to create the PolygonVertexArray must be exactly
|
||||
the number of vertices in your convex mesh. \\
|
||||
|
||||
When you specify the vertices for each face of your convex mesh, be careful with their order. The vertices of a face must be specified in
|
||||
counter clockwise order as seen from the outside of your convex mesh. \\
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
// Libraries
|
||||
#include <reactphysics3d/mathematics/mathematics.h>
|
||||
#include <reactphysics3d/containers/Array.h>
|
||||
#include "HalfEdgeStructure.h"
|
||||
|
||||
namespace reactphysics3d {
|
||||
|
@ -69,7 +70,7 @@ class PolyhedronMesh {
|
|||
PolyhedronMesh(PolygonVertexArray* polygonVertexArray, MemoryAllocator& allocator);
|
||||
|
||||
/// Create the half-edge structure of the mesh
|
||||
void createHalfEdgeStructure();
|
||||
bool createHalfEdgeStructure();
|
||||
|
||||
/// Compute the faces normals
|
||||
void computeFacesNormals();
|
||||
|
@ -80,6 +81,9 @@ class PolyhedronMesh {
|
|||
/// Compute and return the area of a face
|
||||
decimal getFaceArea(uint faceIndex) const;
|
||||
|
||||
/// Static factory method to create a polyhedron mesh
|
||||
static PolyhedronMesh* create(PolygonVertexArray* polygonVertexArray, MemoryAllocator& polyhedronMeshAllocator, MemoryAllocator& dataAllocator);
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include <reactphysics3d/collision/PolyhedronMesh.h>
|
||||
#include <reactphysics3d/memory/MemoryManager.h>
|
||||
#include <reactphysics3d/collision/PolygonVertexArray.h>
|
||||
#include <reactphysics3d/utils/DefaultLogger.h>
|
||||
#include <reactphysics3d/engine/PhysicsCommon.h>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace reactphysics3d;
|
||||
|
@ -37,38 +39,62 @@ using namespace reactphysics3d;
|
|||
* Create a polyhedron mesh given an array of polygons.
|
||||
* @param polygonVertexArray Pointer to the array of polygons and their vertices
|
||||
*/
|
||||
PolyhedronMesh::PolyhedronMesh(PolygonVertexArray* polygonVertexArray, MemoryAllocator &allocator)
|
||||
PolyhedronMesh::PolyhedronMesh(PolygonVertexArray* polygonVertexArray, MemoryAllocator& allocator)
|
||||
: mMemoryAllocator(allocator), mHalfEdgeStructure(allocator, polygonVertexArray->getNbFaces(), polygonVertexArray->getNbVertices(),
|
||||
(polygonVertexArray->getNbFaces() + polygonVertexArray->getNbVertices() - 2) * 2) {
|
||||
(polygonVertexArray->getNbFaces() + polygonVertexArray->getNbVertices() - 2) * 2), mFacesNormals(nullptr) {
|
||||
|
||||
mPolygonVertexArray = polygonVertexArray;
|
||||
|
||||
// Create the half-edge structure of the mesh
|
||||
createHalfEdgeStructure();
|
||||
|
||||
// Create the face normals array
|
||||
mFacesNormals = new Vector3[mHalfEdgeStructure.getNbFaces()];
|
||||
|
||||
// Compute the faces normals
|
||||
computeFacesNormals();
|
||||
|
||||
// Compute the centroid
|
||||
computeCentroid();
|
||||
}
|
||||
|
||||
// Destructor
|
||||
PolyhedronMesh::~PolyhedronMesh() {
|
||||
delete[] mFacesNormals;
|
||||
|
||||
if (mFacesNormals != nullptr) {
|
||||
|
||||
for (uint f=0; f < mHalfEdgeStructure.getNbFaces(); f++) {
|
||||
mFacesNormals[f].~Vector3();
|
||||
}
|
||||
|
||||
mMemoryAllocator.release(mFacesNormals, mHalfEdgeStructure.getNbFaces() * sizeof(Vector3));
|
||||
}
|
||||
}
|
||||
|
||||
/// Static factory method to create a polyhedron mesh. This methods returns null_ptr if the mesh is not valid
|
||||
PolyhedronMesh* PolyhedronMesh::create(PolygonVertexArray* polygonVertexArray, MemoryAllocator& polyhedronMeshAllocator, MemoryAllocator& dataAllocator) {
|
||||
|
||||
PolyhedronMesh* mesh = new (polyhedronMeshAllocator.allocate(sizeof(PolyhedronMesh))) PolyhedronMesh(polygonVertexArray, dataAllocator);
|
||||
|
||||
// Create the half-edge structure of the mesh
|
||||
bool isValid = mesh->createHalfEdgeStructure();
|
||||
|
||||
if (isValid) {
|
||||
|
||||
// Compute the faces normals
|
||||
mesh->computeFacesNormals();
|
||||
|
||||
// Compute the centroid
|
||||
mesh->computeCentroid();
|
||||
}
|
||||
else {
|
||||
mesh->~PolyhedronMesh();
|
||||
polyhedronMeshAllocator.release(mesh, sizeof(PolyhedronMesh));
|
||||
mesh = nullptr;
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
// Create the half-edge structure of the mesh
|
||||
void PolyhedronMesh::createHalfEdgeStructure() {
|
||||
/// This method returns true if the mesh is valid or false otherwise
|
||||
bool PolyhedronMesh::createHalfEdgeStructure() {
|
||||
|
||||
// For each vertex of the mesh
|
||||
for (uint v=0; v < mPolygonVertexArray->getNbVertices(); v++) {
|
||||
mHalfEdgeStructure.addVertex(v);
|
||||
}
|
||||
|
||||
uint32 nbEdges = 0;
|
||||
|
||||
// For each polygon face of the mesh
|
||||
for (uint f=0; f < mPolygonVertexArray->getNbFaces(); f++) {
|
||||
|
||||
|
@ -82,14 +108,34 @@ void PolyhedronMesh::createHalfEdgeStructure() {
|
|||
faceVertices.add(mPolygonVertexArray->getVertexIndexInFace(f, v));
|
||||
}
|
||||
|
||||
nbEdges += face->nbVertices;
|
||||
|
||||
assert(faceVertices.size() >= 3);
|
||||
|
||||
// Addd the face into the half-edge structure
|
||||
mHalfEdgeStructure.addFace(faceVertices);
|
||||
}
|
||||
|
||||
nbEdges /= 2;
|
||||
|
||||
// If the mesh is valid (check Euler formula V + F - E = 2) and does not use duplicated vertices
|
||||
if (2 + nbEdges - mPolygonVertexArray->getNbFaces() != mPolygonVertexArray->getNbVertices()) {
|
||||
|
||||
RP3D_LOG("PhysicsCommon", Logger::Level::Error, Logger::Category::PhysicCommon,
|
||||
"Error when creating a PolyhedronMesh: input PolygonVertexArray is not valid. Mesh with duplicated vertices is not supported.", __FILE__, __LINE__);
|
||||
|
||||
assert(false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialize the half-edge structure
|
||||
mHalfEdgeStructure.init();
|
||||
|
||||
// Create the face normals array
|
||||
mFacesNormals = new (mMemoryAllocator.allocate(mHalfEdgeStructure.getNbFaces() * sizeof(Vector3))) Vector3[mHalfEdgeStructure.getNbFaces()];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Return a vertex
|
||||
|
|
|
@ -488,13 +488,18 @@ void PhysicsCommon::deleteConcaveMeshShape(ConcaveMeshShape* concaveMeshShape) {
|
|||
// Create a polyhedron mesh
|
||||
/**
|
||||
* @param polygonVertexArray A pointer to the polygon vertex array to use to create the polyhedron mesh
|
||||
* @return A pointer to the created polyhedron mesh
|
||||
* @return A pointer to the created polyhedron mesh or nullptr if the mesh is not valid
|
||||
*/
|
||||
PolyhedronMesh* PhysicsCommon::createPolyhedronMesh(PolygonVertexArray* polygonVertexArray) {
|
||||
|
||||
PolyhedronMesh* mesh = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(PolyhedronMesh))) PolyhedronMesh(polygonVertexArray, mMemoryManager.getHeapAllocator());
|
||||
// Create the polyhedron mesh
|
||||
PolyhedronMesh* mesh = PolyhedronMesh::create(polygonVertexArray, mMemoryManager.getPoolAllocator(), mMemoryManager.getHeapAllocator());
|
||||
|
||||
mPolyhedronMeshes.add(mesh);
|
||||
// If the mesh is valid
|
||||
if (mesh != nullptr) {
|
||||
|
||||
mPolyhedronMeshes.add(mesh);
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user