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
|
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. \\
|
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
|
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. \\
|
counter clockwise order as seen from the outside of your convex mesh. \\
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
#include <reactphysics3d/mathematics/mathematics.h>
|
#include <reactphysics3d/mathematics/mathematics.h>
|
||||||
|
#include <reactphysics3d/containers/Array.h>
|
||||||
#include "HalfEdgeStructure.h"
|
#include "HalfEdgeStructure.h"
|
||||||
|
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
@ -69,7 +70,7 @@ class PolyhedronMesh {
|
||||||
PolyhedronMesh(PolygonVertexArray* polygonVertexArray, MemoryAllocator& allocator);
|
PolyhedronMesh(PolygonVertexArray* polygonVertexArray, MemoryAllocator& allocator);
|
||||||
|
|
||||||
/// Create the half-edge structure of the mesh
|
/// Create the half-edge structure of the mesh
|
||||||
void createHalfEdgeStructure();
|
bool createHalfEdgeStructure();
|
||||||
|
|
||||||
/// Compute the faces normals
|
/// Compute the faces normals
|
||||||
void computeFacesNormals();
|
void computeFacesNormals();
|
||||||
|
@ -80,6 +81,9 @@ class PolyhedronMesh {
|
||||||
/// Compute and return the area of a face
|
/// Compute and return the area of a face
|
||||||
decimal getFaceArea(uint faceIndex) const;
|
decimal getFaceArea(uint faceIndex) const;
|
||||||
|
|
||||||
|
/// Static factory method to create a polyhedron mesh
|
||||||
|
static PolyhedronMesh* create(PolygonVertexArray* polygonVertexArray, MemoryAllocator& polyhedronMeshAllocator, MemoryAllocator& dataAllocator);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include <reactphysics3d/collision/PolyhedronMesh.h>
|
#include <reactphysics3d/collision/PolyhedronMesh.h>
|
||||||
#include <reactphysics3d/memory/MemoryManager.h>
|
#include <reactphysics3d/memory/MemoryManager.h>
|
||||||
#include <reactphysics3d/collision/PolygonVertexArray.h>
|
#include <reactphysics3d/collision/PolygonVertexArray.h>
|
||||||
|
#include <reactphysics3d/utils/DefaultLogger.h>
|
||||||
|
#include <reactphysics3d/engine/PhysicsCommon.h>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
using namespace reactphysics3d;
|
using namespace reactphysics3d;
|
||||||
|
@ -37,38 +39,62 @@ using namespace reactphysics3d;
|
||||||
* Create a polyhedron mesh given an array of polygons.
|
* Create a polyhedron mesh given an array of polygons.
|
||||||
* @param polygonVertexArray Pointer to the array of polygons and their vertices
|
* @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(),
|
: mMemoryAllocator(allocator), mHalfEdgeStructure(allocator, polygonVertexArray->getNbFaces(), polygonVertexArray->getNbVertices(),
|
||||||
(polygonVertexArray->getNbFaces() + polygonVertexArray->getNbVertices() - 2) * 2) {
|
(polygonVertexArray->getNbFaces() + polygonVertexArray->getNbVertices() - 2) * 2), mFacesNormals(nullptr) {
|
||||||
|
|
||||||
mPolygonVertexArray = polygonVertexArray;
|
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
|
// Destructor
|
||||||
PolyhedronMesh::~PolyhedronMesh() {
|
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
|
// 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 each vertex of the mesh
|
||||||
for (uint v=0; v < mPolygonVertexArray->getNbVertices(); v++) {
|
for (uint v=0; v < mPolygonVertexArray->getNbVertices(); v++) {
|
||||||
mHalfEdgeStructure.addVertex(v);
|
mHalfEdgeStructure.addVertex(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 nbEdges = 0;
|
||||||
|
|
||||||
// For each polygon face of the mesh
|
// For each polygon face of the mesh
|
||||||
for (uint f=0; f < mPolygonVertexArray->getNbFaces(); f++) {
|
for (uint f=0; f < mPolygonVertexArray->getNbFaces(); f++) {
|
||||||
|
|
||||||
|
@ -82,14 +108,34 @@ void PolyhedronMesh::createHalfEdgeStructure() {
|
||||||
faceVertices.add(mPolygonVertexArray->getVertexIndexInFace(f, v));
|
faceVertices.add(mPolygonVertexArray->getVertexIndexInFace(f, v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nbEdges += face->nbVertices;
|
||||||
|
|
||||||
assert(faceVertices.size() >= 3);
|
assert(faceVertices.size() >= 3);
|
||||||
|
|
||||||
// Addd the face into the half-edge structure
|
// Addd the face into the half-edge structure
|
||||||
mHalfEdgeStructure.addFace(faceVertices);
|
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
|
// Initialize the half-edge structure
|
||||||
mHalfEdgeStructure.init();
|
mHalfEdgeStructure.init();
|
||||||
|
|
||||||
|
// Create the face normals array
|
||||||
|
mFacesNormals = new (mMemoryAllocator.allocate(mHalfEdgeStructure.getNbFaces() * sizeof(Vector3))) Vector3[mHalfEdgeStructure.getNbFaces()];
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a vertex
|
/// Return a vertex
|
||||||
|
|
|
@ -488,13 +488,18 @@ void PhysicsCommon::deleteConcaveMeshShape(ConcaveMeshShape* concaveMeshShape) {
|
||||||
// Create a polyhedron mesh
|
// Create a polyhedron mesh
|
||||||
/**
|
/**
|
||||||
* @param polygonVertexArray A pointer to the polygon vertex array to use to create the 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* 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;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user