From 86aa2a85784890e448b006691a524b7aad293fc3 Mon Sep 17 00:00:00 2001 From: SaracenOne Date: Sat, 23 Apr 2022 13:32:55 +0100 Subject: Add drag-and-drop support for materials in 3D Add mesh surface picking for material drag & drop, show drag info label --- scene/resources/mesh.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ scene/resources/mesh.h | 3 +++ 2 files changed, 69 insertions(+) (limited to 'scene/resources') diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 3e7b0a2808..ec9db89794 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -260,6 +260,64 @@ Ref Mesh::generate_triangle_mesh() const { return triangle_mesh; } +Ref Mesh::generate_surface_triangle_mesh(int p_surface) const { + ERR_FAIL_INDEX_V(p_surface, get_surface_count(), Ref()); + + if (surface_triangle_meshes.size() != get_surface_count()) { + surface_triangle_meshes.resize(get_surface_count()); + } + + if (surface_triangle_meshes[p_surface].is_valid()) { + return surface_triangle_meshes[p_surface]; + } + + int facecount = 0; + + if (surface_get_primitive_type(p_surface) != PRIMITIVE_TRIANGLES) { + return Ref(); + } + + if (surface_get_format(p_surface) & ARRAY_FORMAT_INDEX) { + facecount += surface_get_array_index_len(p_surface); + } else { + facecount += surface_get_array_len(p_surface); + } + + Vector faces; + faces.resize(facecount); + Vector3 *facesw = faces.ptrw(); + + Array a = surface_get_arrays(p_surface); + ERR_FAIL_COND_V(a.is_empty(), Ref()); + + int vc = surface_get_array_len(p_surface); + Vector vertices = a[ARRAY_VERTEX]; + const Vector3 *vr = vertices.ptr(); + int widx = 0; + + if (surface_get_format(p_surface) & ARRAY_FORMAT_INDEX) { + int ic = surface_get_array_index_len(p_surface); + Vector indices = a[ARRAY_INDEX]; + const int *ir = indices.ptr(); + + for (int j = 0; j < ic; j++) { + int index = ir[j]; + facesw[widx++] = vr[index]; + } + + } else { + for (int j = 0; j < vc; j++) { + facesw[widx++] = vr[j]; + } + } + + Ref triangle_mesh = Ref(memnew(TriangleMesh)); + triangle_mesh->create(faces); + surface_triangle_meshes.set(p_surface, triangle_mesh); + + return triangle_mesh; +} + void Mesh::generate_debug_mesh_lines(Vector &r_lines) { if (debug_lines.size() > 0) { r_lines = debug_lines; @@ -320,6 +378,14 @@ Vector Mesh::get_faces() const { return Vector(); } +Vector Mesh::get_surface_faces(int p_surface) const { + Ref tm = generate_surface_triangle_mesh(p_surface); + if (tm.is_valid()) { + return tm->get_faces(); + } + return Vector(); +} + Ref Mesh::create_convex_shape(bool p_clean, bool p_simplify) const { if (p_simplify) { ConvexDecompositionSettings settings; diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index b166d12ead..b46a2a8a88 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -42,6 +42,7 @@ class Mesh : public Resource { GDCLASS(Mesh, Resource); mutable Ref triangle_mesh; //cached + mutable Vector> surface_triangle_meshes; //cached mutable Vector debug_lines; Size2i lightmap_size_hint; @@ -161,7 +162,9 @@ public: virtual AABB get_aabb() const; Vector get_faces() const; + Vector get_surface_faces(int p_surface) const; Ref generate_triangle_mesh() const; + Ref generate_surface_triangle_mesh(int p_surface) const; void generate_debug_mesh_lines(Vector &r_lines); void generate_debug_mesh_indices(Vector &r_points); -- cgit v1.2.3