Browse Source

Add surface indices to TriangleMesh

Helps unblock #56597
reduz 3 years ago
parent
commit
3d1ab570b9
3 changed files with 28 additions and 6 deletions
  1. 13 3
      core/math/triangle_mesh.cpp
  2. 4 3
      core/math/triangle_mesh.h
  3. 11 0
      scene/resources/mesh.cpp

+ 13 - 3
core/math/triangle_mesh.cpp

@@ -104,9 +104,11 @@ void TriangleMesh::get_indices(Vector<int> *r_triangles_indices) const {
 	}
 }
 
-void TriangleMesh::create(const Vector<Vector3> &p_faces) {
+void TriangleMesh::create(const Vector<Vector3> &p_faces, const Vector<int32_t> &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<Vector3> &p_faces) {
 		//goes in-place.
 
 		const Vector3 *r = p_faces.ptr();
+		const int32_t *si = p_surface_indices.ptr();
 		Triangle *w = triangles.ptrw();
 		HashMap<Vector3, int> db;
 
@@ -148,6 +151,7 @@ void TriangleMesh::create(const Vector<Vector3> &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;
 							}
 						}

+ 4 - 3
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<Vector3> &get_vertices() const { return vertices; }
 	void get_indices(Vector<int> *r_triangles_indices) const;
 
-	void create(const Vector<Vector3> &p_faces);
+	void create(const Vector<Vector3> &p_faces, const Vector<int32_t> &p_surface_indices = Vector<int32_t>());
 	TriangleMesh();
 };
 

+ 11 - 0
scene/resources/mesh.cpp

@@ -188,7 +188,10 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
 
 	Vector<Vector3> faces;
 	faces.resize(faces_size);
+	Vector<int32_t> 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<TriangleMesh> Mesh::generate_triangle_mesh() const {
 		Vector<Vector3> 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<int> indices = a[ARRAY_INDEX];
@@ -241,6 +246,12 @@ Ref<TriangleMesh> 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<TriangleMesh>(memnew(TriangleMesh));