From 53f01ae370d9c95e3ee6a446919aef2e6df1dc1f Mon Sep 17 00:00:00 2001 From: Relintai Date: Thu, 27 Jan 2022 19:26:47 +0100 Subject: [PATCH] Use the new delaunay triangulation for the add face action in case more than 3 verts are selected. --- .../mesh_data_resource_editor/MDIEd.tscn | 26 +++---- .../mesh_data_resource_editor/MIDGizmo.gd | 43 ++++++++++- .../utilities/mdred_mesh_utils.gd | 75 +++++++++++++++++++ 3 files changed, 129 insertions(+), 15 deletions(-) diff --git a/game/addons/mesh_data_resource_editor/MDIEd.tscn b/game/addons/mesh_data_resource_editor/MDIEd.tscn index c64811eb..ef21ffc5 100644 --- a/game/addons/mesh_data_resource_editor/MDIEd.tscn +++ b/game/addons/mesh_data_resource_editor/MDIEd.tscn @@ -203,7 +203,7 @@ scroll_horizontal_enabled = false [node name="VBoxContainer2" type="VBoxContainer" parent="VBoxContainer/ScrollContainer"] margin_right = 998.0 -margin_bottom = 698.0 +margin_bottom = 674.0 size_flags_horizontal = 3 [node name="HBoxContainer6" type="HBoxContainer" parent="VBoxContainer/ScrollContainer/VBoxContainer2"] @@ -379,7 +379,7 @@ __meta__ = { [node name="VertexOps" type="VBoxContainer" parent="VBoxContainer/ScrollContainer/VBoxContainer2"] margin_top = 112.0 margin_right = 998.0 -margin_bottom = 216.0 +margin_bottom = 192.0 [node name="OperationsLabel" type="Label" parent="VBoxContainer/ScrollContainer/VBoxContainer2/VertexOps"] margin_right = 998.0 @@ -391,7 +391,7 @@ valign = 1 [node name="Operations" type="VBoxContainer" parent="VBoxContainer/ScrollContainer/VBoxContainer2/VertexOps"] margin_top = 18.0 margin_right = 998.0 -margin_bottom = 104.0 +margin_bottom = 80.0 [node name="AddFace" type="Button" parent="VBoxContainer/ScrollContainer/VBoxContainer2/VertexOps/Operations"] margin_right = 998.0 @@ -541,14 +541,14 @@ margin_bottom = 20.0 text = "Delete" [node name="HSeparator4" type="HSeparator" parent="VBoxContainer/ScrollContainer/VBoxContainer2"] -margin_top = 220.0 +margin_top = 196.0 margin_right = 998.0 -margin_bottom = 224.0 +margin_bottom = 200.0 [node name="Operations" type="VBoxContainer" parent="VBoxContainer/ScrollContainer/VBoxContainer2"] -margin_top = 228.0 +margin_top = 204.0 margin_right = 998.0 -margin_bottom = 592.0 +margin_bottom = 568.0 [node name="OperationsLabel" type="Label" parent="VBoxContainer/ScrollContainer/VBoxContainer2/Operations"] margin_right = 998.0 @@ -642,14 +642,14 @@ margin_bottom = 346.0 text = "Unwrap" [node name="HSeparator3" type="HSeparator" parent="VBoxContainer/ScrollContainer/VBoxContainer2"] -margin_top = 596.0 +margin_top = 572.0 margin_right = 998.0 -margin_bottom = 600.0 +margin_bottom = 576.0 [node name="Add" type="VBoxContainer" parent="VBoxContainer/ScrollContainer/VBoxContainer2"] -margin_top = 604.0 +margin_top = 580.0 margin_right = 998.0 -margin_bottom = 690.0 +margin_bottom = 666.0 [node name="AddLabel" type="Label" parent="VBoxContainer/ScrollContainer/VBoxContainer2/Add"] margin_right = 998.0 @@ -683,9 +683,9 @@ size_flags_horizontal = 3 text = "Quad" [node name="HSeparator2" type="HSeparator" parent="VBoxContainer/ScrollContainer/VBoxContainer2"] -margin_top = 694.0 +margin_top = 670.0 margin_right = 998.0 -margin_bottom = 698.0 +margin_bottom = 674.0 [node name="Popups" type="Control" parent="."] margin_left = 7.0 diff --git a/game/addons/mesh_data_resource_editor/MIDGizmo.gd b/game/addons/mesh_data_resource_editor/MIDGizmo.gd index 6cdb5b0e..9cd2290a 100644 --- a/game/addons/mesh_data_resource_editor/MIDGizmo.gd +++ b/game/addons/mesh_data_resource_editor/MIDGizmo.gd @@ -1037,6 +1037,13 @@ func split(): func disconnect_action(): pass +func get_first_triangle_index_for_vertex(indx : int) -> int: + for i in range(_indices.size()): + if _indices[i] == indx: + return i / 3 + + return -1 + func create_face(): if !_mdr: return @@ -1053,12 +1060,44 @@ func create_face(): for sp in _selected_points: points.push_back(_handle_points[sp]) + + if points.size() == 3: + var i0 : int = _handle_to_vertex_map[_selected_points[0]][0] + var i1 : int = _handle_to_vertex_map[_selected_points[1]][0] + var i2 : int = _handle_to_vertex_map[_selected_points[2]][0] - MDRMeshUtils.add_triangulated_mesh_from_points(_mdr, points, _last_known_camera_facing) + var v0 : Vector3 = points[0] + var v1 : Vector3 = points[1] + var v2 : Vector3 = points[2] + + var tfn : Vector3 = Vector3() + + if orig_arr[ArrayMesh.ARRAY_NORMAL] != null && orig_arr[ArrayMesh.ARRAY_NORMAL].size() == orig_arr[ArrayMesh.ARRAY_VERTEX].size(): + var normals : PoolVector3Array = orig_arr[ArrayMesh.ARRAY_NORMAL] + + tfn += normals[i0] + tfn += normals[i1] + tfn += normals[i2] + tfn /= 3 + tfn = tfn.normalized() + else: + tfn = MDRMeshUtils.get_face_normal(_vertices[i0], _vertices[i1], _vertices[i2]) + + + var flip : bool = MDRMeshUtils.should_triangle_flip(v0, v1, v2, tfn) + + MDRMeshUtils.add_triangle_at(_mdr, v0, v1, v2, flip) + add_mesh_change_undo_redo(orig_arr, _mdr.array, "Create Face") + enable_change_event() + return + + if !MDRMeshUtils.add_triangulated_mesh_from_points_delaunay(_mdr, points, _last_known_camera_facing): + enable_change_event() + return add_mesh_change_undo_redo(orig_arr, _mdr.array, "Create Face") - _selected_points.resize(0) + #_selected_points.resize(0) enable_change_event() elif selection_mode == SelectionMode.SELECTION_MODE_EDGE: pass diff --git a/game/addons/mesh_data_resource_editor/utilities/mdred_mesh_utils.gd b/game/addons/mesh_data_resource_editor/utilities/mdred_mesh_utils.gd index bb2decdf..926f417f 100644 --- a/game/addons/mesh_data_resource_editor/utilities/mdred_mesh_utils.gd +++ b/game/addons/mesh_data_resource_editor/utilities/mdred_mesh_utils.gd @@ -34,6 +34,81 @@ static func remove_triangle(mdr : MeshDataResource, triangle_index : int) -> voi mdr.set_array(arrays) +static func add_triangulated_mesh_from_points_delaunay(mdr : MeshDataResource, selected_points : PoolVector3Array, last_known_camera_facing : Vector3) -> bool: + if selected_points.size() < 3: + return false + + var tetrahedrons : PoolIntArray = MeshUtils.delaunay3d_tetrahedralize(selected_points) + + if tetrahedrons.size() == 0: + # try randomly displacing the points a bit, it can help + var rnd_selected_points : PoolVector3Array = PoolVector3Array() + rnd_selected_points.append_array(selected_points) + + for i in range(rnd_selected_points.size()): + rnd_selected_points[i] = rnd_selected_points[i] + (Vector3(randf(),randf(), randf()) * 0.1) + + tetrahedrons = MeshUtils.delaunay3d_tetrahedralize(rnd_selected_points) + + if tetrahedrons.size() == 0: + print("add_triangulated_mesh_from_points_delaunay: tetrahedrons.size() == 0!") + return false + + var st : SurfaceTool = SurfaceTool.new() + + st.begin(Mesh.PRIMITIVE_TRIANGLES) + + for i in range(0, tetrahedrons.size(), 4): + var i0 : int = tetrahedrons[i] + var i1 : int = tetrahedrons[i + 1] + var i2 : int = tetrahedrons[i + 2] + var i3 : int = tetrahedrons[i + 3] + + var v0 : Vector3 = selected_points[i0] + var v1 : Vector3 = selected_points[i1] + var v2 : Vector3 = selected_points[i2] + var v3 : Vector3 = selected_points[i3] + + var flip : bool = is_normal_similar(v0, v1, v2, last_known_camera_facing) + + var normal : Vector3 = get_face_normal(v0, v1, v2, flip) + + st.add_uv(Vector2(0, 1)) + st.add_normal(normal) + st.add_vertex(v0) + st.add_uv(Vector2(0.5, 0)) + st.add_normal(normal) + st.add_vertex(v1) + st.add_uv(Vector2(1, 1)) + st.add_normal(normal) + st.add_vertex(v2) + st.add_uv(Vector2(1, 1)) + st.add_normal(normal) + st.add_vertex(v3) + + var im3 : int = i + + if !flip: + st.add_index(im3 + 0) + st.add_index(im3 + 1) + st.add_index(im3 + 2) + + st.add_index(im3 + 0) + st.add_index(im3 + 2) + st.add_index(im3 + 3) + else: + st.add_index(im3 + 3) + st.add_index(im3 + 2) + st.add_index(im3 + 0) + + st.add_index(im3 + 2) + st.add_index(im3 + 1) + st.add_index(im3 + 0) + + merge_in_surface_tool(mdr, st) + + return true + static func add_triangulated_mesh_from_points(mdr : MeshDataResource, selected_points : PoolVector3Array, last_known_camera_facing : Vector3) -> void: if selected_points.size() < 3: return