6 #include <unordered_map>
7 #include <unordered_set>
10 #include <reactphysics3d/collision/shapes/ConvexMeshShape.h>
35 using std::make_unique;
40 using std::unique_ptr;
41 using std::unordered_map;
42 using std::unordered_set;
65 ConvexMesh::ConvexMesh()
74 const auto& vertex =
vertices[vertexIdx];
94 vector<Triangle> triangles;
98 unordered_map<int, vector<const Triangle*>> trianglesCoplanar;
100 auto triangle1Idx = 0;
101 unordered_set<int> trianglesProcessed;
103 for (
const auto& triangle1: triangles) {
104 if (trianglesProcessed.find(triangle1Idx) != trianglesProcessed.end()) {
109 trianglesCoplanar[triangle1Idx].push_back(&triangle1);
110 trianglesProcessed.insert(triangle1Idx);
112 auto triangle2Added = 0;
114 auto triangle2Idx = 0;
116 for (
const auto& triangle2: triangles) {
118 if (trianglesProcessed.find(triangle2Idx) != trianglesProcessed.end()) {
124 if (adjacent ==
false) {
125 for (
auto triangle1CoplanarTriangle: trianglesCoplanar[triangle1Idx]) {
133 auto triangle2OnTriangle1Plane =
137 if (adjacent ==
true && triangle2OnTriangle1Plane ==
true) {
138 trianglesCoplanar[triangle1Idx].push_back(&triangle2);
140 trianglesProcessed.insert(triangle2Idx);
146 }
while (triangle2Added > 0);
153 for (
const auto& [trianglesCoplanarIdx, trianglesCoplanarVector]: trianglesCoplanar) {
155 vector<Vector3> polygonVertices;
158 for (
auto triangle: trianglesCoplanarVector) {
159 for (
const auto& triangleVertex: triangle->getVertices()) {
160 bool foundVertex =
false;
161 for (
const auto& polygonVertex: polygonVertices) {
167 if (foundVertex ==
false) {
168 polygonVertices.push_back(triangleVertex);
204 if (polygonVertices.size() > 2) {
208 unordered_set<int> foundIndices;
209 for (
auto i = 0; i < faceVertexCount; i++) {
210 auto foundVertex =
false;
211 for (
const auto& polygonVertex: polygonVertices) {
213 foundIndices.insert(
indices[idx]);
219 if (foundIndices.size() == polygonVertices.size()) {
230 if (polygonVertices.size() < 3)
continue;
234 for (
const auto& polygonVertex: polygonVertices) {
235 polygonCenter.
add(polygonVertex);
237 polygonCenter.
scale(1.0f / polygonVertices.size());
244 auto polygonNormal = Vector3::computeCrossProduct(triangle1Edge1, triangle1Edge2).
normalize();
247 vector<int> polygonVerticesOrdered;
249 polygonVerticesOrdered.push_back(0);
255 while (polygonVerticesOrdered.size() != polygonVertices.size()) {
257 auto hitVertexAngle = 0.0f;
258 auto hitVertexIdx = -1;
259 for (
int i = 0; i < polygonVertices.size(); i++) {
261 if (find(polygonVerticesOrdered.begin(), polygonVerticesOrdered.end(), i) != polygonVerticesOrdered.end())
continue;
264 auto angleCurrent = Vector3::computeAngle(
265 polygonVertices[0].
clone().sub(polygonCenter).normalize(),
266 polygonVertices[i].
clone().sub(polygonCenter).normalize(),
269 if (hitVertexIdx == -1 || angleCurrent < hitVertexAngle) {
270 hitVertexAngle = angleCurrent;
275 polygonVerticesOrdered.push_back(hitVertexIdx);
299 for (
auto polygonVerticesOrderedIdx: polygonVerticesOrdered) {
301 auto& polygonVertex = polygonVertices[polygonVerticesOrderedIdx];
305 for (
const auto& vertexExisting:
vertices) {
363 for (
const auto& vertex:
vertices) {
364 vertexTransformed.
set(vertex);
367 verticesBuffer.put(vertexTransformed.
getArray());
370 indicesBuffer.put(index);
375 reactphysics3d::PolygonVertexArray::PolygonFace face;
376 face.nbVertices = faceVerticesCount;
377 face.indexBase = indexIdx;
378 faces.push_back(face);
379 indexIdx+= faceVerticesCount;
396 if (this->world !=
nullptr && this->world !=
world) {
397 Console::println(
"ConvexMesh::createCollisionShape(): already attached to a world.");
405 static_cast<uint32_t
>(
vertices.size()),
410 static_cast<uint32_t
>(
faces.size()),
412 reactphysics3d::PolygonVertexArray::VertexDataType::VERTEX_FLOAT_TYPE,
413 reactphysics3d::PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE
422 Console::println(
"ConvexMesh::createCollisionShape(): an error occurred: " +
string(exception.what()));
432 this->world =
nullptr;
Wavefront object model writer.
Dynamic physics world class.
reactphysics3d::PhysicsCommon physicsCommon
Bounding volume interface.
reactphysics3d::Transform collisionShapeLocalTransform
reactphysics3d::Transform collisionShapeTransform
Vector3 collisionShapeLocalTranslation
reactphysics3d::CollisionShape * collisionShape
Convex mesh physics primitive.
~ConvexMesh()
Public destructor.
vector< int > facesVerticesCount
unique_ptr< reactphysics3d::PolygonVertexArray > polygonVertexArray
static constexpr float VERTEX_COMPARE_EPSILON
reactphysics3d::PolyhedronMesh * polyhedronMesh
bool isVertexOnTrianglePlane(const Triangle &triangle, const Vector3 &vertex)
Checks if vertex lives on triangle plane.
void createConvexMesh(const vector< Vector3 > &vertices, const vector< int > &facesVerticesCount, const vector< int > &indices, const Vector3 &scale)
Create convex mesh Note: it also translates center into origin.
void destroyCollisionShape() override
Destroy collision shape.
void setScale(const Vector3 &scale) override
Set local scale.
ConvexMesh()
Public constructor.
const vector< Vector3 > & getVertices()
vector< Vector3 > vertices
void createCollisionShape(World *world) override
Create collision shap.
BoundingVolume * clone() const override
Clones this bounding volume.
unique_ptr< ByteBuffer > verticesByteBuffer
vector< reactphysics3d::PolygonVertexArray::PolygonFace > faces
unique_ptr< ByteBuffer > indicesByteBuffer
bool areTrianglesAdjacent(const Triangle &triangle1, const Triangle &triangle2)
Checks if 2 triangles are adjacent.
Line segment helper functions.
Triangle entity, this is not directly connectable with physics engine.
void getTriangles(vector< Triangle > &triangles, int nodeIdx=-1)
Retrieves list of triangles of all or given nodes.
Vector3 class representing vector3 mathematical structure and operations with x, y,...
Vector3 & add(float scalar)
Adds a scalar.
const array< float, 3 > & getArray() const
Vector3 & sub(float scalar)
Subtracts a scalar.
Vector3 & scale(float scalar)
Scales by scalar.
Vector3 & set(float x, float y, float z)
Sets this vector3 by its components.
Vector3 & normalize()
Normalizes this vector3.
std::exception Exception
Exception base class.