diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 54461bf70f5..4433559e6de 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -104,9 +104,11 @@ void TriangleMesh::get_indices(Vector *r_triangles_indices) const { } } -void TriangleMesh::create(const Vector &p_faces) { +void TriangleMesh::create(const Vector &p_faces, const Vector &p_surface_indices) { valid = false; + ERR_FAIL_COND(p_surface_indices.size() && p_surface_indices.size() != p_faces.size()); + int fc = p_faces.size(); ERR_FAIL_COND(!fc || ((fc % 3) != 0)); fc /= 3; @@ -121,6 +123,7 @@ void TriangleMesh::create(const Vector &p_faces) { //goes in-place. const Vector3 *r = p_faces.ptr(); + const int32_t *si = p_surface_indices.ptr(); Triangle *w = triangles.ptrw(); HashMap db; @@ -148,6 +151,7 @@ void TriangleMesh::create(const Vector &p_faces) { } f.normal = Face3(r[i * 3 + 0], r[i * 3 + 1], r[i * 3 + 2]).get_plane().get_normal(); + f.surface_index = si ? si[i] : 0; bw[i].left = -1; bw[i].right = -1; @@ -264,7 +268,7 @@ Vector3 TriangleMesh::get_area_normal(const AABB &p_aabb) const { return n; } -bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const { +bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index) const { uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); enum { @@ -317,6 +321,9 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en d = nd; r_point = res; r_normal = f3.get_plane().get_normal(); + if (r_surf_index) { + *r_surf_index = s.surface_index; + } inters = true; } } @@ -366,7 +373,7 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en return inters; } -bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal) const { +bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index) const { uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); enum { @@ -417,6 +424,9 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V d = nd; r_point = res; r_normal = f3.get_plane().get_normal(); + if (r_surf_index) { + *r_surf_index = s.surface_index; + } inters = true; } } diff --git a/core/math/triangle_mesh.h b/core/math/triangle_mesh.h index 1b99945698e..166b4adb7a2 100644 --- a/core/math/triangle_mesh.h +++ b/core/math/triangle_mesh.h @@ -41,6 +41,7 @@ public: struct Triangle { Vector3 normal; int indices[3]; + int32_t surface_index; }; private: @@ -81,8 +82,8 @@ private: public: bool is_valid() const; - bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const; - bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal) const; + bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr) const; + bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr) const; bool intersect_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count) const; bool inside_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count, Vector3 p_scale = Vector3(1, 1, 1)) const; Vector3 get_area_normal(const AABB &p_aabb) const; @@ -92,7 +93,7 @@ public: const Vector &get_vertices() const { return vertices; } void get_indices(Vector *r_triangles_indices) const; - void create(const Vector &p_faces); + void create(const Vector &p_faces, const Vector &p_surface_indices = Vector()); TriangleMesh(); }; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index b8c83ac89ec..3e7b0a2808a 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -188,7 +188,10 @@ Ref Mesh::generate_triangle_mesh() const { Vector faces; faces.resize(faces_size); + Vector surface_indices; + surface_indices.resize(faces_size / 3); Vector3 *facesw = faces.ptrw(); + int32_t *surface_indicesw = surface_indices.ptrw(); int widx = 0; @@ -210,6 +213,8 @@ Ref Mesh::generate_triangle_mesh() const { Vector vertices = a[ARRAY_VERTEX]; const Vector3 *vr = vertices.ptr(); + int32_t from_index = widx / 3; + if (surface_get_format(i) & ARRAY_FORMAT_INDEX) { int ic = surface_get_array_index_len(i); Vector indices = a[ARRAY_INDEX]; @@ -241,6 +246,12 @@ Ref Mesh::generate_triangle_mesh() const { } } } + + int32_t to_index = widx / 3; + + for (int j = from_index; j < to_index; j++) { + surface_indicesw[j] = i; + } } triangle_mesh = Ref(memnew(TriangleMesh));