diff options
-rw-r--r-- | core/math/triangle_mesh.h | 6 | ||||
-rw-r--r-- | editor/import/scene_importer_mesh.cpp | 51 | ||||
-rw-r--r-- | modules/vhacd/register_types.cpp | 52 | ||||
-rw-r--r-- | scene/resources/mesh.cpp | 98 | ||||
-rw-r--r-- | scene/resources/mesh.h | 4 |
5 files changed, 84 insertions, 127 deletions
diff --git a/core/math/triangle_mesh.h b/core/math/triangle_mesh.h index 463b0dd5c8..2d3b4db4bb 100644 --- a/core/math/triangle_mesh.h +++ b/core/math/triangle_mesh.h @@ -37,11 +37,13 @@ class TriangleMesh : public RefCounted { GDCLASS(TriangleMesh, RefCounted); +public: struct Triangle { Vector3 normal; int indices[3]; }; +private: Vector<Triangle> triangles; Vector<Vector3> vertices; @@ -86,8 +88,8 @@ public: Vector3 get_area_normal(const AABB &p_aabb) const; Vector<Face3> get_faces() const; - Vector<Triangle> get_triangles() const { return triangles; } - Vector<Vector3> get_vertices() const { return vertices; } + const Vector<Triangle> &get_triangles() const { return triangles; } + const Vector<Vector3> &get_vertices() const { return vertices; } void get_indices(Vector<int> *r_triangles_indices) const; void create(const Vector<Vector3> &p_faces); diff --git a/editor/import/scene_importer_mesh.cpp b/editor/import/scene_importer_mesh.cpp index 55bea50432..5e6dd08e79 100644 --- a/editor/import/scene_importer_mesh.cpp +++ b/editor/import/scene_importer_mesh.cpp @@ -525,35 +525,46 @@ Vector<Face3> EditorSceneImporterMesh::get_faces() const { } Vector<Ref<Shape3D>> EditorSceneImporterMesh::convex_decompose(const Mesh::ConvexDecompositionSettings &p_settings) const { - ERR_FAIL_COND_V(!Mesh::convex_composition_function, Vector<Ref<Shape3D>>()); + ERR_FAIL_COND_V(!Mesh::convex_decomposition_function, Vector<Ref<Shape3D>>()); const Vector<Face3> faces = get_faces(); + int face_count = faces.size(); - Vector<Vector<Face3>> decomposed = Mesh::convex_composition_function(faces, p_settings); + Vector<Vector3> vertices; + uint32_t vertex_count = 0; + vertices.resize(face_count * 3); + Vector<uint32_t> indices; + indices.resize(face_count * 3); + { + Map<Vector3, uint32_t> vertex_map; + Vector3 *vertex_w = vertices.ptrw(); + uint32_t *index_w = indices.ptrw(); + for (int i = 0; i < face_count; i++) { + for (int j = 0; j < 3; j++) { + const Vector3 &vertex = faces[i].vertex[j]; + Map<Vector3, uint32_t>::Element *found_vertex = vertex_map.find(vertex); + uint32_t index; + if (found_vertex) { + index = found_vertex->get(); + } else { + index = ++vertex_count; + vertex_map[vertex] = index; + vertex_w[index] = vertex; + } + index_w[i * 3 + j] = index; + } + } + } + vertices.resize(vertex_count); + + Vector<Vector<Vector3>> decomposed = Mesh::convex_decomposition_function((real_t *)vertices.ptr(), vertex_count, indices.ptr(), face_count, p_settings, nullptr); Vector<Ref<Shape3D>> ret; for (int i = 0; i < decomposed.size(); i++) { - Set<Vector3> points; - for (int j = 0; j < decomposed[i].size(); j++) { - points.insert(decomposed[i][j].vertex[0]); - points.insert(decomposed[i][j].vertex[1]); - points.insert(decomposed[i][j].vertex[2]); - } - - Vector<Vector3> convex_points; - convex_points.resize(points.size()); - { - Vector3 *w = convex_points.ptrw(); - int idx = 0; - for (Set<Vector3>::Element *E = points.front(); E; E = E->next()) { - w[idx++] = E->get(); - } - } - Ref<ConvexPolygonShape3D> shape; shape.instantiate(); - shape->set_points(convex_points); + shape->set_points(decomposed[i]); ret.push_back(shape); } diff --git a/modules/vhacd/register_types.cpp b/modules/vhacd/register_types.cpp index 88b2a568ea..54240e66fc 100644 --- a/modules/vhacd/register_types.cpp +++ b/modules/vhacd/register_types.cpp @@ -32,7 +32,7 @@ #include "scene/resources/mesh.h" #include "thirdparty/vhacd/public/VHACD.h" -static Vector<Vector<Face3>> convex_decompose(const Vector<Face3> &p_faces, const Mesh::ConvexDecompositionSettings &p_settings) { +static Vector<Vector<Vector3>> convex_decompose(const real_t *p_vertices, int p_vertex_count, const uint32_t *p_triangles, int p_triangle_count, const Mesh::ConvexDecompositionSettings &p_settings, Vector<Vector<uint32_t>> *r_convex_indices) { VHACD::IVHACD::Parameters params; params.m_concavity = p_settings.max_concavity; params.m_alpha = p_settings.symmetry_planes_clipping_bias; @@ -49,42 +49,38 @@ static Vector<Vector<Face3>> convex_decompose(const Vector<Face3> &p_faces, cons params.m_maxConvexHulls = p_settings.max_convex_hulls; params.m_projectHullVertices = p_settings.project_hull_vertices; - Vector<real_t> vertices; - vertices.resize(p_faces.size() * 9); - Vector<uint32_t> indices; - indices.resize(p_faces.size() * 3); - - for (int i = 0; i < p_faces.size(); i++) { - for (int j = 0; j < 3; j++) { - vertices.write[i * 9 + j * 3 + 0] = p_faces[i].vertex[j].x; - vertices.write[i * 9 + j * 3 + 1] = p_faces[i].vertex[j].y; - vertices.write[i * 9 + j * 3 + 2] = p_faces[i].vertex[j].z; - indices.write[i * 3 + j] = i * 3 + j; - } - } - VHACD::IVHACD *decomposer = VHACD::CreateVHACD(); - decomposer->Compute(vertices.ptr(), vertices.size() / 3, indices.ptr(), indices.size() / 3, params); + decomposer->Compute(p_vertices, p_vertex_count, p_triangles, p_triangle_count, params); int hull_count = decomposer->GetNConvexHulls(); - Vector<Vector<Face3>> ret; + Vector<Vector<Vector3>> ret; + ret.resize(hull_count); + + if (r_convex_indices) { + r_convex_indices->resize(hull_count); + } for (int i = 0; i < hull_count; i++) { - Vector<Face3> triangles; VHACD::IVHACD::ConvexHull hull; decomposer->GetConvexHull(i, hull); - triangles.resize(hull.m_nTriangles); - for (uint32_t j = 0; j < hull.m_nTriangles; j++) { - Face3 f; + + Vector<Vector3> &points = ret.write[i]; + points.resize(hull.m_nPoints); + + Vector3 *w = points.ptrw(); + for (uint32_t j = 0; j < hull.m_nPoints; ++j) { for (int k = 0; k < 3; k++) { - for (int l = 0; l < 3; l++) { - f.vertex[k][l] = hull.m_points[hull.m_triangles[j * 3 + k] * 3 + l]; - } + w[j][k] = hull.m_points[j * 3 + k]; } - triangles.write[j] = f; } - ret.push_back(triangles); + + if (r_convex_indices) { + Vector<uint32_t> &indices = r_convex_indices->write[i]; + indices.resize(hull.m_nTriangles * 3); + + memcpy(indices.ptrw(), hull.m_triangles, hull.m_nTriangles * 3 * sizeof(uint32_t)); + } } decomposer->Clean(); @@ -94,9 +90,9 @@ static Vector<Vector<Face3>> convex_decompose(const Vector<Face3> &p_faces, cons } void register_vhacd_types() { - Mesh::convex_composition_function = convex_decompose; + Mesh::convex_decomposition_function = convex_decompose; } void unregister_vhacd_types() { - Mesh::convex_composition_function = nullptr; + Mesh::convex_decomposition_function = nullptr; } diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 1edc3ff38b..8f3f25f104 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -38,7 +38,7 @@ #include <stdlib.h> -Mesh::ConvexDecompositionFunc Mesh::convex_composition_function = nullptr; +Mesh::ConvexDecompositionFunc Mesh::convex_decomposition_function = nullptr; Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { if (triangle_mesh.is_valid()) { @@ -167,59 +167,6 @@ Vector<Face3> Mesh::get_faces() const { return tm->get_faces(); } return Vector<Face3>(); - /* - for (int i=0;i<surfaces.size();i++) { - if (RenderingServer::get_singleton()->mesh_surface_get_primitive_type( mesh, i ) != RenderingServer::PRIMITIVE_TRIANGLES ) - continue; - - Vector<int> indices; - Vector<Vector3> vertices; - - vertices=RenderingServer::get_singleton()->mesh_surface_get_array(mesh, i,RenderingServer::ARRAY_VERTEX); - - int len=RenderingServer::get_singleton()->mesh_surface_get_array_index_len(mesh, i); - bool has_indices; - - if (len>0) { - indices=RenderingServer::get_singleton()->mesh_surface_get_array(mesh, i,RenderingServer::ARRAY_INDEX); - has_indices=true; - - } else { - len=vertices.size(); - has_indices=false; - } - - if (len<=0) - continue; - - const int* indicesr = indices.ptr(); - const int *indicesptr = indicesr.ptr(); - - const Vector3* verticesr = vertices.ptr(); - const Vector3 *verticesptr = verticesr.ptr(); - - int old_faces=faces.size(); - int new_faces=old_faces+(len/3); - - faces.resize(new_faces); - - Face3* facesw = faces.ptrw(); - Face3 *facesptr=facesw.ptr(); - - - for (int i=0;i<len/3;i++) { - Face3 face; - - for (int j=0;j<3;j++) { - int idx=i*3+j; - face.vertex[j] = has_indices ? verticesptr[ indicesptr[ idx ] ] : verticesptr[idx]; - } - - facesptr[i+old_faces]=face; - } - - } -*/ } Ref<Shape3D> Mesh::create_convex_shape(bool p_clean, bool p_simplify) const { @@ -568,35 +515,36 @@ void Mesh::clear_cache() const { } Vector<Ref<Shape3D>> Mesh::convex_decompose(const ConvexDecompositionSettings &p_settings) const { - ERR_FAIL_COND_V(!convex_composition_function, Vector<Ref<Shape3D>>()); - - const Vector<Face3> faces = get_faces(); + ERR_FAIL_COND_V(!convex_decomposition_function, Vector<Ref<Shape3D>>()); - const Vector<Vector<Face3>> decomposed = convex_composition_function(faces, p_settings); - - Vector<Ref<Shape3D>> ret; + Ref<TriangleMesh> tm = generate_triangle_mesh(); + ERR_FAIL_COND_V(!tm.is_valid(), Vector<Ref<Shape3D>>()); - for (int i = 0; i < decomposed.size(); i++) { - Set<Vector3> points; - for (int j = 0; j < decomposed[i].size(); j++) { - points.insert(decomposed[i][j].vertex[0]); - points.insert(decomposed[i][j].vertex[1]); - points.insert(decomposed[i][j].vertex[2]); - } + const Vector<TriangleMesh::Triangle> &triangles = tm->get_triangles(); + int triangle_count = triangles.size(); - Vector<Vector3> convex_points; - convex_points.resize(points.size()); - { - Vector3 *w = convex_points.ptrw(); - int idx = 0; - for (Set<Vector3>::Element *E = points.front(); E; E = E->next()) { - w[idx++] = E->get(); + Vector<uint32_t> indices; + { + indices.resize(triangle_count * 3); + uint32_t *w = indices.ptrw(); + for (int i = 0; i < triangle_count; i++) { + for (int j = 0; j < 3; j++) { + w[i * 3 + j] = triangles[i].indices[j]; } } + } + + const Vector<Vector3> &vertices = tm->get_vertices(); + int vertex_count = vertices.size(); + Vector<Vector<Vector3>> decomposed = convex_decomposition_function((real_t *)vertices.ptr(), vertex_count, indices.ptr(), triangle_count, p_settings, nullptr); + + Vector<Ref<Shape3D>> ret; + + for (int i = 0; i < decomposed.size(); i++) { Ref<ConvexPolygonShape3D> shape; shape.instantiate(); - shape->set_points(convex_points); + shape->set_points(decomposed[i]); ret.push_back(shape); } diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 4d0ee0f247..0776585a11 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -191,9 +191,9 @@ public: uint32_t max_convex_hulls = 1; bool project_hull_vertices = true; }; - typedef Vector<Vector<Face3>> (*ConvexDecompositionFunc)(const Vector<Face3> &p_faces, const ConvexDecompositionSettings &p_settings); + typedef Vector<Vector<Vector3>> (*ConvexDecompositionFunc)(const real_t *p_vertices, int p_vertex_count, const uint32_t *p_triangles, int p_triangle_count, const ConvexDecompositionSettings &p_settings, Vector<Vector<uint32_t>> *r_convex_indices); - static ConvexDecompositionFunc convex_composition_function; + static ConvexDecompositionFunc convex_decomposition_function; Vector<Ref<Shape3D>> convex_decompose(const ConvexDecompositionSettings &p_settings) const; |