diff --git a/game/addons/mesh_data_resource_editor/MDIEd.gd b/game/addons/mesh_data_resource_editor/MDIEd.gd index 6bfd0b26..eaa82744 100644 --- a/game/addons/mesh_data_resource_editor/MDIEd.gd +++ b/game/addons/mesh_data_resource_editor/MDIEd.gd @@ -247,3 +247,6 @@ func onhandle_selection_type_back_toggled(on : bool): func onhandle_selection_type_all_toggled(on : bool): if on: _plugin.handle_selection_type_all() + +func _on_clean_mesh_pressed(): + _plugin.clean_mesh() diff --git a/game/addons/mesh_data_resource_editor/MDIEd.tscn b/game/addons/mesh_data_resource_editor/MDIEd.tscn index ef21ffc5..66e54f20 100644 --- a/game/addons/mesh_data_resource_editor/MDIEd.tscn +++ b/game/addons/mesh_data_resource_editor/MDIEd.tscn @@ -754,7 +754,7 @@ size_flags_vertical = 3 [connection signal="pressed" from="VBoxContainer/ScrollContainer/VBoxContainer2/Operations/Operations/GenTangents" to="." method="_on_GenTangents_pressed"] [connection signal="pressed" from="VBoxContainer/ScrollContainer/VBoxContainer2/Operations/Operations/RemDoubles" to="." method="_on_RemDoubles_pressed"] [connection signal="pressed" from="VBoxContainer/ScrollContainer/VBoxContainer2/Operations/Operations/MergeOptimize" to="." method="_on_MergeOptimize_pressed"] -[connection signal="pressed" from="VBoxContainer/ScrollContainer/VBoxContainer2/Operations/Operations/Clean" to="." method="_on_MergeOptimize_pressed"] +[connection signal="pressed" from="VBoxContainer/ScrollContainer/VBoxContainer2/Operations/Operations/Clean" to="." method="_on_clean_mesh_pressed"] [connection signal="pressed" from="VBoxContainer/ScrollContainer/VBoxContainer2/Operations/Operations/UVEditButton" to="." method="_on_uv_edit_pressed"] [connection signal="pressed" from="VBoxContainer/ScrollContainer/VBoxContainer2/Operations/Operations/ApplySeams" to="." method="_on_apply_seams_pressed"] [connection signal="pressed" from="VBoxContainer/ScrollContainer/VBoxContainer2/Operations/Operations/UnwrapButton2" to="." method="_on_UnwrapButton_pressed"] diff --git a/game/addons/mesh_data_resource_editor/MIDGizmo.gd b/game/addons/mesh_data_resource_editor/MIDGizmo.gd index 9c490f81..e1f00304 100644 --- a/game/addons/mesh_data_resource_editor/MIDGizmo.gd +++ b/game/addons/mesh_data_resource_editor/MIDGizmo.gd @@ -1550,7 +1550,34 @@ func apply_seam(): add_mesh_change_undo_redo(orig_arr, _mdr.array, "apply_seam") enable_change_event() + +func clean_mesh(): + if !_mdr: + return + var arrays : Array = _mdr.array + + if arrays.size() != ArrayMesh.ARRAY_MAX: + return arrays + + if arrays[ArrayMesh.ARRAY_VERTEX] == null || arrays[ArrayMesh.ARRAY_INDEX] == null: + return arrays + + var old_vert_size : int = arrays[ArrayMesh.ARRAY_VERTEX].size() + + disable_change_event() + + var orig_arr : Array = copy_arrays(arrays) + arrays = MDRMeshUtils.remove_used_vertices(arrays) + var new_vert_size : int = arrays[ArrayMesh.ARRAY_VERTEX].size() + add_mesh_change_undo_redo(orig_arr, arrays, "clean_mesh") + + enable_change_event() + + var d : int = old_vert_size - new_vert_size + + print("MDRED: Removed " + str(d) + " unused vertices.") + func uv_unwrap() -> void: if !_mdr: return diff --git a/game/addons/mesh_data_resource_editor/plugin.gd b/game/addons/mesh_data_resource_editor/plugin.gd index e187b947..8569be37 100644 --- a/game/addons/mesh_data_resource_editor/plugin.gd +++ b/game/addons/mesh_data_resource_editor/plugin.gd @@ -276,3 +276,7 @@ func handle_selection_type_all(): func extrude(): if current_mesh_data_instance && current_mesh_data_instance.gizmo: current_mesh_data_instance.gizmo.extrude() + +func clean_mesh(): + if current_mesh_data_instance && current_mesh_data_instance.gizmo: + current_mesh_data_instance.gizmo.clean_mesh() 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 926f417f..a6b197c5 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 @@ -861,6 +861,164 @@ static func generate_tangents(mdr : MeshDataResource) -> void: mdr.array = st.commit_to_arrays() +static func remove_used_vertices(arrays : Array) -> Array: + if arrays.size() != ArrayMesh.ARRAY_MAX: + return arrays + + if arrays[ArrayMesh.ARRAY_VERTEX] == null || arrays[ArrayMesh.ARRAY_INDEX] == null: + return arrays + + var vert_size : int = arrays[ArrayMesh.ARRAY_VERTEX].size() + var indices : PoolIntArray = arrays[ArrayMesh.ARRAY_INDEX] + var unused_indices : PoolIntArray = PoolIntArray() + + for i in range(vert_size): + if !pool_int_arr_contains(indices, i): + unused_indices.append(i) + + remove_vertices(arrays, unused_indices) + + return arrays + + +static func remove_vertices(arrays : Array, indices : PoolIntArray) -> Array: + if indices.size() == 0: + return arrays + + var vertices : PoolVector3Array = arrays[ArrayMesh.ARRAY_VERTEX] + + var normals : PoolVector3Array + var tangents : PoolRealArray + var colors : PoolColorArray + var uv : PoolVector2Array + var uv2 : PoolVector2Array + var bones : PoolRealArray + var weights : PoolRealArray + + if arrays[ArrayMesh.ARRAY_NORMAL] != null: + normals = arrays[ArrayMesh.ARRAY_NORMAL] + + if arrays[ArrayMesh.ARRAY_TANGENT] != null: + tangents = arrays[ArrayMesh.ARRAY_TANGENT] + + if arrays[ArrayMesh.ARRAY_COLOR] != null: + colors = arrays[ArrayMesh.ARRAY_COLOR] + + if arrays[ArrayMesh.ARRAY_TEX_UV] != null: + uv = arrays[ArrayMesh.ARRAY_TEX_UV] + + if arrays[ArrayMesh.ARRAY_TEX_UV2] != null: + uv2 = arrays[ArrayMesh.ARRAY_TEX_UV2] + + if arrays[ArrayMesh.ARRAY_BONES] != null: + bones = arrays[ArrayMesh.ARRAY_BONES] + + if arrays[ArrayMesh.ARRAY_WEIGHTS] != null: + weights = arrays[ArrayMesh.ARRAY_WEIGHTS] + + for index in indices: + vertices.remove(index) + + if arrays[ArrayMesh.ARRAY_NORMAL] != null: + normals.remove(index) + + if arrays[ArrayMesh.ARRAY_TANGENT] != null: + var tindex : int = index * 4 + + tangents.remove(tindex) + tangents.remove(tindex) + tangents.remove(tindex) + tangents.remove(tindex) + + if arrays[ArrayMesh.ARRAY_COLOR] != null: + colors.remove(index) + + if arrays[ArrayMesh.ARRAY_TEX_UV] != null: + uv.remove(index) + + if arrays[ArrayMesh.ARRAY_TEX_UV2] != null: + uv2.remove(index) + + if arrays[ArrayMesh.ARRAY_BONES] != null: + bones.remove(index) + bones.remove(index) + bones.remove(index) + bones.remove(index) + + if arrays[ArrayMesh.ARRAY_WEIGHTS] != null: + weights.remove(index) + weights.remove(index) + weights.remove(index) + weights.remove(index) + + #write back + arrays[ArrayMesh.ARRAY_VERTEX] = vertices + + if arrays[ArrayMesh.ARRAY_NORMAL] != null: + arrays[ArrayMesh.ARRAY_NORMAL] = normals + + if arrays[ArrayMesh.ARRAY_TANGENT] != null: + arrays[ArrayMesh.ARRAY_TANGENT] = tangents + + if arrays[ArrayMesh.ARRAY_COLOR] != null: + arrays[ArrayMesh.ARRAY_COLOR] = colors + + if arrays[ArrayMesh.ARRAY_TEX_UV] != null: + arrays[ArrayMesh.ARRAY_TEX_UV] = uv + + if arrays[ArrayMesh.ARRAY_TEX_UV2] != null: + arrays[ArrayMesh.ARRAY_TEX_UV2] = uv2 + + if arrays[ArrayMesh.ARRAY_BONES] != null: + arrays[ArrayMesh.ARRAY_BONES] = bones + + if arrays[ArrayMesh.ARRAY_WEIGHTS] != null: + arrays[ArrayMesh.ARRAY_WEIGHTS] = weights + + if arrays[ArrayMesh.ARRAY_INDEX] == null: + return arrays + + #udpate indices + var arr_indices : PoolIntArray = arrays[ArrayMesh.ARRAY_INDEX] + + var max_index : int = find_max(indices) + + for k in range(indices.size()): + for i in range(arr_indices.size()): + var ai : int = arr_indices[i] + + if ai >= max_index: + arr_indices[i] = ai - 1 + + max_index = find_max_capped(indices, max_index) + + arrays[ArrayMesh.ARRAY_INDEX] = arr_indices + + return arrays + +static func find_max(arr : PoolIntArray) -> int: + var m : int = arr[0] + + for v in arr: + if v > m: + m = v + + return m + +static func find_max_capped(arr : PoolIntArray, last : int) -> int: + var m : int = 0 + + for v in arr: + if v < last: + m = v + break + + for v in arr: + if v > m && v < last: + m = v + + return m + static func order_seam_indices(arr : PoolIntArray) -> PoolIntArray: var ret : PoolIntArray = PoolIntArray() @@ -1021,7 +1179,7 @@ static func pool_int_arr_contains(arr : PoolIntArray, val : int) -> bool: return true return false - + class SeamTriangleHelper: var i0 : int = 0