123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827 |
- using MTE.Undo;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEditor;
- using UnityEngine;
- namespace MTE
- {
- internal class MeshToolbox : IEditor
- {
- public int Id { get; } = 9;
- public bool Enabled { get; set; } = true;
- public string Name { get; } = "MeshToolbox";
- public Texture Icon { get; } =
- EditorGUIUtility.IconContent("Mesh Icon").image;
- public bool WantMouseMove { get; } = false;
- public bool WillEditMesh { get; } = true;
- private enum SelectMode
- {
- Vertex,
- Quad,
- }
- private enum EditorState
- {
- Selecting,
- Action,
- }
- /// <summary>
- /// AABB that can contain only one point
- /// </summary>
- private class AABB
- {
- float xMin = float.NaN, yMin, zMin;
- float xMax, yMax, zMax;
- public Vector3 Min { get { return new Vector3(xMin, yMin, zMin); } }
- public Vector3 Max { get { return new Vector3(xMax, yMax, zMax); } }
- public Vector3 Center { get { return 0.5f*(Min + Max); } }
- public bool IsEmpty { get { return float.IsNaN(xMin); } }
- /// <summary>Reset to initial state (empty) </summary>
- public void Reset()
- {
- xMin = float.NaN;
- }
- public void AddPoint(Vector3 point)
- {
- if (IsEmpty)
- {
- this.xMin = this.xMax = point.x;
- this.yMin = this.yMax = point.y;
- this.zMin = this.zMax = point.z;
- }
- if (point.x > xMax)
- {
- this.xMax = point.x;
- }
- else if(point.x < xMin)
- {
- this.xMin = point.x;
- }
- if (point.y > yMax)
- {
- this.yMax = point.y;
- }
- else if (point.y < yMin)
- {
- this.yMin = point.y;
- }
- if (point.z > zMax)
- {
- this.zMax = point.z;
- }
- else if (point.z < zMin)
- {
- this.zMin = point.z;
- }
- }
- }
- private class VertexModifyGroup
- {
- private readonly GameObject gameObject;
- private List<int> vertexIndexList;
- public GameObject Target { get { return gameObject; } }
- public List<int> VertexIndexList
- {
- get { return vertexIndexList;}
- }
- public VertexModifyGroup(GameObject gameObject)
- {
- this.gameObject = gameObject;
- }
- public void AppendVertices(IList<int> vertexIndexList)
- {
- if (this.vertexIndexList == null)
- {
- this.vertexIndexList = new List<int>();
- }
- this.vertexIndexList.AddRange(vertexIndexList);
- this.vertexIndexList = this.vertexIndexList.Distinct().ToList();
- }
- public void RemoveVertices(IList<int> remove_vertexIndexList)
- {
- if (this.vertexIndexList == null)
- {
- return;
- }
- for (var i = this.VertexIndexList.Count - 1; i >= 0; i--)
- {
- var vertexIndex = this.VertexIndexList[i];
- var foundIndex = remove_vertexIndexList.IndexOf(vertexIndex);
- if (foundIndex >= 0)
- {
- this.VertexIndexList.RemoveAt(i);
- remove_vertexIndexList.RemoveAt(foundIndex);
- }
- }
- }
- public void Clear()
- {
- this.VertexIndexList.Clear();
- }
- }
- #region modfication
- private readonly List<VertexModifyGroup> vertexModifyGroups = new List<VertexModifyGroup>(4);
- private readonly AABB aabb = new AABB();
- private void AddVerticesToModifyGroup(GameObject gameObject, IList<int> vertexIndexList)
- {
- if (gameObject == null)
- {
- throw new ArgumentNullException("gameObject");
- }
- if (vertexIndexList == null)
- {
- throw new ArgumentNullException("vertexIndexList");
- }
- if (vertexIndexList.Count == 0)
- {
- return;
- }
- {
- var modifyGroup = vertexModifyGroups.Find(group => group.Target == gameObject);
- if (modifyGroup == null)
- {
- modifyGroup = new VertexModifyGroup(gameObject);
- vertexModifyGroups.Add(modifyGroup);
- }
- modifyGroup.AppendVertices(vertexIndexList);
- }
- }
- private void RemoveVerticesFromModifyGroup(GameObject gameObject, IList<int> vertexIndexList)
- {
- if (gameObject == null)
- {
- throw new ArgumentNullException("gameObject");
- }
- if (vertexIndexList == null)
- {
- throw new ArgumentNullException("vertexIndexList");
- }
- if (vertexIndexList.Count == 0)
- {
- return;
- }
- {
- var modifyGroup = vertexModifyGroups.Find(group => group.Target == gameObject);
- if (modifyGroup == null)
- {
- modifyGroup = new VertexModifyGroup(gameObject);
- vertexModifyGroups.Add(modifyGroup);
- }
- modifyGroup.RemoveVertices(vertexIndexList);
- }
- }
- private void RefreshAABB()
- {
- aabb.Reset();
- for (var i = 0; i < vertexModifyGroups.Count; i++)
- {
- var modifyGroup = vertexModifyGroups[i];
- var gameObject = modifyGroup.Target;
- if (!gameObject)
- {
- continue;
- }
- var transform = gameObject.transform;
- var meshFilter = gameObject.GetComponent<MeshFilter>();
- if (!meshFilter)
- {
- continue;
- }
- var mesh = meshFilter.sharedMesh;
- if (!mesh)
- {
- continue;
- }
- var meshVertices = mesh.vertices;
- for (int j = 0; j < modifyGroup.VertexIndexList.Count; j++)
- {
- var vertexIndex = modifyGroup.VertexIndexList[j];
- if (vertexIndex >= meshVertices.Length)
- {
- MTEDebug.LogError(
- $"Mesh {mesh.name}'s vertices on GameObject has been changed.");
- continue;
- }
- var vertexPosition = meshVertices[vertexIndex];
- var pWorld = transform.TransformPoint(vertexPosition);
- aabb.AddPoint(pWorld);
- }
- }
- }
- #endregion
- #region Parameters
- #region Constant
- // default
- const float DefaultBrushSize = 4;
- // min/max
- const float MinBrushSize = 0.1f;
- const float MaxBrushSize = 10f;
- #endregion
- private float brushSize;
- /// <summary>
- /// Brush size (unit: meter)
- /// </summary>
- public float BrushSize
- {
- get { return brushSize; }
- set
- {
- value = Mathf.Clamp(value, MinBrushSize, MaxBrushSize);
- if (!MathEx.AmostEqual(value, brushSize))
- {
- brushSize = value;
- EditorPrefs.SetFloat("MTE_MeshToolbox.brushSize", value);
- }
- }
- }
- private float BrushSizeInU3D => BrushSize * Settings.BrushUnit;
- #endregion
- public MeshToolbox()
- {
- MTEContext.EnableEvent += (sender, args) =>
- {
- if (MTEContext.editor == this)
- {
- LoadSavedParamter();
- }
- };
- MTEContext.EditTypeChangedEvent += (sender, args) =>
- {
- if (MTEContext.editor == this)
- {
- LoadSavedParamter();
- }
- };
- brushSize = DefaultBrushSize;
- }
-
- public HashSet<Hotkey> DefineHotkeys()
- {
- return new HashSet<Hotkey>
- {
- new Hotkey(this, KeyCode.LeftBracket, () =>
- {
- BrushSize -= 1;
- MTEEditorWindow.Instance.Repaint();
- }),
- new Hotkey(this, KeyCode.RightBracket, () =>
- {
- BrushSize += 1;
- MTEEditorWindow.Instance.Repaint();
- })
- };
- }
- private void LoadSavedParamter()
- {
- // Load parameters from the EditorPrefs
- brushSize = EditorPrefs.GetFloat("MTE_MeshToolbox.brushSize", DefaultBrushSize);
- }
- public string Header{ get { return StringTable.Get(C.MeshMisc_Header); } }
- public string Description { get { return StringTable.Get(C.MeshMisc_Description); } }
- private static class Styles
- {
- private static bool unloaded= true;
- public static void Init()
- {
- if (!unloaded) return;
- //nothing for now
- unloaded = false;
- }
- }
- private bool pressedHotkeyOnEditor;
- public void DoArgsGUI()
- {
- Styles.Init();
- if (!Settings.CompactGUI)
- {
- GUILayout.Label(StringTable.Get(C.Settings), MTEStyles.SubHeader);
- }
- BrushSize = EditorGUILayoutEx.Slider(StringTable.Get(C.Size), "-", "+", BrushSize, MinBrushSize, MaxBrushSize);
- if (!Settings.CompactGUI)
- {
- EditorGUILayout.Space();
- GUILayout.Label(StringTable.Get(C.Tools), MTEStyles.SubHeader);
- }
-
- mode = (SelectMode)GUILayout.Toolbar((int)mode, MTEStyles.MeshSelectModeContents, Settings.CompactGUI ? GUILayout.Height(32) : GUILayout.Height(48));
- if (mode == SelectMode.Vertex)
- {
- EditorGUILayout.BeginHorizontal();
- {
- GUI.enabled = CanDelete();
- if (GUILayout.Button(StringTable.Get(C.Delete), GUILayout.Width(100), GUILayout.Height(40)))
- {
- Delete();
- }
- GUI.enabled = true;
- GUILayout.Space(20);
- EditorGUILayout.LabelField(StringTable.Get(C.Info_ToolDescription_DeleteVertices), MTEStyles.labelFieldWordwrap);
- }
- EditorGUILayout.EndHorizontal();
- }
- else if (mode == SelectMode.Quad)
- {
- EditorGUILayout.HelpBox(StringTable.Get(C.Info_SwapQuadSplitDirection), MessageType.Info);
- if (IsPressedHotkeyForQuadMode(Event.current))
- {
- pressedHotkeyOnEditor = true;
- }
- }
- }
- private EditorState state = EditorState.Selecting;
- private SelectMode mode = SelectMode.Vertex;
-
- //debug only data
- private static Vector3 pTest;
- private static Vector3 pMaxEdgePoint0;
- private static Vector3 pMaxEdgePoint1;
- //debug only data
- public void OnSceneGUI()
- {
- var e = Event.current;
- if (e.commandName == "UndoRedoPerformed")
- {
- SceneView.RepaintAll();
- return;
- }
- if (mode == SelectMode.Vertex)
- {
- OnSceneGUIForVertex();
- }
- else if(mode == SelectMode.Quad)
- {
- OnSceneGUIForQuad();
- if (Settings.DebugMode)
- {
- var oldHandlesColor = Handles.color;
- Handles.color = Color.red;
- var size = Utility.GetHandleSize(pTest);
- Handles.DotHandleCap(0, pTest, Quaternion.identity, size * Settings.PointSize, EventType.Repaint);
- Handles.DrawLine(pMaxEdgePoint0, pMaxEdgePoint1);
- if (e.type == EventType.MouseDown && e.button == 1)
- {
- pMaxEdgePoint1 = pMaxEdgePoint0 = pTest = new Vector3(-9999, -9999, -9999);
- }
- Handles.color = oldHandlesColor;
- }
- }
- }
- private void OnSceneGUIForQuad()
- {
- var e = Event.current;
- if (!(EditorWindow.mouseOverWindow is SceneView))
- {
- return;
- }
- if (e.control || e.alt)
- return;
-
- HandleUtility.AddDefaultControl(0);
- RaycastHit raycastHit;
- Ray ray = HandleUtility.GUIPointToWorldRay(e.mousePosition);
- if (Physics.Raycast(ray, out raycastHit,
- Mathf.Infinity,
- 1 << MTEContext.TargetLayer //only hit target layer
- ))
- {
- //check tag
- if (!raycastHit.transform.CompareTag(MTEContext.TargetTag))
- {
- return;
- }
-
- var transform = raycastHit.transform;
- var target = transform.gameObject;
- var meshFilter = target.GetComponent<MeshFilter>();
- if (meshFilter == null)
- {
- return;
- }
- var mesh = meshFilter.sharedMesh;
- if (mesh == null)
- {
- return;
- }
- var triangleIndex0 = raycastHit.triangleIndex * 3 + 0;
- var triangleIndex1 = raycastHit.triangleIndex * 3 + 1;
- var triangleIndex2 = raycastHit.triangleIndex * 3 + 2;
- // highlight hovered quad
- if (QuadMap.FindQuad(target, triangleIndex0, triangleIndex1, triangleIndex2, out Quad quad))
- {
- Handles.color = Settings.FlashAffectedVertex ? Utility.GetFlashingColor(0.583f) : Color.blue;
-
- var meshVertices = mesh.vertices;
- int index0 = quad.index[0];
- int index1 = quad.index[1];
- int index2 = quad.index[2];
- var p0 = transform.TransformPoint(meshVertices[index0]);
- var p1 = transform.TransformPoint(meshVertices[index1]);
- var p2 = transform.TransformPoint(meshVertices[index2]);
- int index3 = quad.index[3];
- int index4 = quad.index[4];
- int index5 = quad.index[5];
- var p3 = transform.TransformPoint(meshVertices[index3]);
- var p4 = transform.TransformPoint(meshVertices[index4]);
- var p5 = transform.TransformPoint(meshVertices[index5]);
- var oldHandlesColor = Handles.color;
- if (Settings.DebugMode)
- {
- Handles.color = Color.green;
- Handles.DrawPolyLine(p0, p1, p2, p0);
- Handles.color = Color.blue;
- Handles.DrawPolyLine(p3, p4, p5, p3);
- }
- else
- {
- Handles.color = Utility.GetFlashingColor();
- //Handles.DrawAAPolyLine(3, 4, p0, p1, p2, p0);
- //Handles.DrawAAPolyLine(3, 4, p3, p4, p5, p3);
- Handles.DrawPolyLine(p0, p1, p2, p0);
- Handles.DrawPolyLine(p3, p4, p5, p3);
- }
- Handles.color = oldHandlesColor;
- }
- bool pressed = IsPressedHotkeyForQuadMode(e) || pressedHotkeyOnEditor;
- if (pressed)
- {
- pressedHotkeyOnEditor = false;
- ChangeQuadSplitDirection(target, triangleIndex0, triangleIndex1, triangleIndex2);
- var meshCollider = target.GetComponent<MeshCollider>();
- MTEEditorWindow.Instance.UpdateMeshColliderImmediately(meshCollider);
- MTEEditorWindow.Instance.HandleMeshSave();
- }
- }
- SceneView.RepaintAll();
- }
- private bool IsPressedHotkeyForQuadMode(Event e)
- {
- return e.isKey && e.type == EventType.KeyUp && e.keyCode == KeyCode.S;
- }
- private void ChangeQuadSplitDirection(GameObject target, int index0, int index1, int index2)
- {
- if (!QuadMap.FindQuad(target, index0, index1, index2, out Quad quad))
- {
- return;
- }
- Quad newQuad = quad;
- newQuad.ChangeSplitDirection();
- int firstIndex = -1;
- if (index0 % 6 == 0)
- {
- firstIndex = index0;
- }
- else if (index0 % 6 == 3)
- {
- firstIndex = index0 - 3;
- }
- else
- {
- throw new MTEEditException("Argument index0 is not a valid first index of triangle");
- }
- Utility.RecordMeshIndices("Swap Quad Split Direction", target, () => { QuadMap.Rebuild(target); });
- QuadMap.ModifyQuad(target, firstIndex, newQuad);
- }
- private void OnSceneGUIForVertex()
- {
- var e = Event.current;
- // show modifying points
- if (vertexModifyGroups.Count != 0)
- {
- Handles.color = Settings.FlashAffectedVertex ? Utility.GetFlashingColor(0.583f) : Color.blue;
- for (var i = 0; i < vertexModifyGroups.Count; i++)
- {
- var modifyGroup = vertexModifyGroups[i];
- if (modifyGroup.VertexIndexList == null || modifyGroup.VertexIndexList.Count == 0) continue;
- if (!modifyGroup.Target) continue;
- var meshFilter = modifyGroup.Target.GetComponent<MeshFilter>();
- if (meshFilter == null) continue;
- var mesh = meshFilter.sharedMesh;
- if (mesh == null) continue;
- var meshVertices = mesh.vertices;
- var transform = modifyGroup.Target.transform;
- for (int j = 0; j < modifyGroup.VertexIndexList.Count; j++)
- {
- var vertexIndex = modifyGroup.VertexIndexList[j];
- var vertexPosition = meshVertices[vertexIndex];
- var p = transform.TransformPoint(vertexPosition);
- var size = Utility.GetHandleSize(p);
- Handles.DotHandleCap(0, p, Quaternion.identity, size * Settings.PointSize, EventType.Repaint);
- }
- }
- }
- if (!(EditorWindow.mouseOverWindow is SceneView))
- {
- return;
- }
- if (e.button != 0 || e.control || e.alt)
- return;
- if (state == EditorState.Selecting)
- {
- HandleUtility.AddDefaultControl(0);
- RaycastHit raycastHit;
- Ray ray = HandleUtility.GUIPointToWorldRay(e.mousePosition);
- //Debug.Log(string.Format("mouse at ({0}, {1})", e.mousePosition.x, e.mousePosition.y));
- if (Physics.Raycast(ray, out raycastHit,
- Mathf.Infinity,
- 1 << MTEContext.TargetLayer //only hit target layer
- ))
- {
- //check tag
- if (!raycastHit.transform.CompareTag(MTEContext.TargetTag))
- {
- return;
- }
- if (Settings.ShowBrushRect)
- {
- Utility.ShowBrushRect(raycastHit.point, BrushSizeInU3D);
- }
- if (e.isKey && e.keyCode == KeyCode.Return && vertexModifyGroups.Count != 0)
- {
- RefreshAABB();
- state = EditorState.Action;
- return;
- }
- // collect modify group
- foreach (var gameObject in MTEContext.Targets)
- {
- if (!gameObject)
- {
- continue;
- }
- var meshFilter = gameObject.GetComponent<MeshFilter>();
- var mesh = meshFilter.sharedMesh;
- var hitPointLocal = gameObject.transform.InverseTransformPoint(raycastHit.point);
- List<int> vIndex;
- List<float> vDistance;
- VertexMap.GetAffectedVertex(gameObject, hitPointLocal, this.BrushSizeInU3D,
- out vIndex, out vDistance);
- if (Settings.ShowAffectedVertex)
- {
- Utility.ShowAffectedVertices(gameObject, mesh, vIndex);
- }
- if (e.type == EventType.MouseDown || e.type == EventType.MouseDrag)
- {
- if (vIndex.Count != 0)
- {
- if (!e.shift)
- {
- AddVerticesToModifyGroup(gameObject, vIndex);
- }
- else
- {
- RemoveVerticesFromModifyGroup(gameObject, vIndex);
- }
- }
- }
- }
- }
- }
- if (state == EditorState.Action)
- {
- if (e.isKey && e.keyCode == KeyCode.Escape)
- {
- state = EditorState.Selecting;
- return;
- }
- //record undo operation for targets that to be modified
- if (e.type == EventType.MouseDown)
- {
- Utility.Record("Mesh Toolbox: move",
- Vector3.zero, this.BrushSizeInU3D, () =>
- {
- RefreshAABB();
- for (var i = 0; i < vertexModifyGroups.Count; i++)
- {
- var modifyGroup = vertexModifyGroups[i];
- if (!modifyGroup.Target)
- {
- continue;
- }
- VertexMap.Rebuild(modifyGroup.Target);
- }
- });
- }
- if (e.type == EventType.MouseUp)
- {
- MTEEditorWindow.Instance.UpdateDirtyMeshCollidersImmediately();
- MTEEditorWindow.Instance.HandleMeshSave();
- }
- // execute the modification
- if (vertexModifyGroups.Count != 0)
- {
- var newPostion = Handles.DoPositionHandle(this.aabb.Center, Quaternion.identity);
- var offset = newPostion - this.aabb.Center;
- TranslateVertices(offset);
- }
- }
- SceneView.RepaintAll();
- }
- private void TranslateVertices(Vector3 offset)
- {
- // check if offset is big enough
- if (!(Mathf.Abs(offset.x) > 0.001f) && !(Mathf.Abs(offset.y) > 0.001f) && !(Mathf.Abs(offset.z) > 0.001f)) return;
- for (var i = 0; i < vertexModifyGroups.Count; i++)
- {
- var modifyGroup = vertexModifyGroups[i];
- if (modifyGroup.VertexIndexList == null
- || modifyGroup.VertexIndexList.Count == 0
- || !modifyGroup.Target)
- {
- continue;
- }
- var gameObject = modifyGroup.Target;
- var transform = gameObject.transform;
- var offsetLocal = transform.InverseTransformDirection(offset);
- var mesh = gameObject.GetComponent<MeshFilter>().sharedMesh;
- var meshCollider = modifyGroup.Target.GetComponent<MeshCollider>();
- var vertices = mesh.vertices;//TODO performance improvement: mesh.vertices will copy vertices
- for (int j = 0; j < modifyGroup.VertexIndexList.Count; j++)
- {
- var index = modifyGroup.VertexIndexList[j];
- vertices[index] += offsetLocal;
- }
- mesh.vertices = vertices;
- MTEEditorWindow.Instance.SetMeshDirty(gameObject);
- MTEEditorWindow.Instance.SetMeshColliderDirty(meshCollider, mesh.vertexCount);
- // Rebuild vertex map for this GameObject if its vertices have been translated in xOz.
- if (Math.Abs(offset.x) > 0.001 || Math.Abs(offset.z) > 0.001)
- {
- VertexMap.Rebuild(gameObject);
- }
- }
- RefreshAABB();
- }
- bool CanDelete()
- {
- if (vertexModifyGroups.Count == 0)
- {
- return false;
- }
- for (var i = 0; i < vertexModifyGroups.Count; i++)
- {
- var modifyGroup = vertexModifyGroups[i];
- if (modifyGroup.VertexIndexList.Count != 0)
- {
- return true;
- }
- }
- return false;
- }
- void Delete()
- {
- using (new Undo.UndoTransaction("Mesh Toolbox: delete"))
- {
- for (var i = 0; i < vertexModifyGroups.Count; i++)
- {
- var modifyGroup = vertexModifyGroups[i];
- var gameObject = modifyGroup.Target;
- if (!gameObject)
- {
- continue;
- }
- if (gameObject.GetComponent<VertexColorInitializer>() != null)//ignore vertex colored GameObjects
- {
- continue;
- }
- var mesh = gameObject.GetComponent<MeshFilter>().sharedMesh;
- var meshCollider = modifyGroup.Target.GetComponent<MeshCollider>();
- var meshTriangles = mesh.triangles;
- var indexList = modifyGroup.VertexIndexList;
- // create new indexes
- List<int> newMeshTriangles = new List<int>(meshTriangles);
- // remove triangles that contains the removed vertices
- for (var j = newMeshTriangles.Count - 1; j >= 0; j -= 3)
- {
- var index0 = newMeshTriangles[j];
- var index1 = newMeshTriangles[j - 1];
- var index2 = newMeshTriangles[j - 2];
- if (indexList.Contains(index0) || indexList.Contains(index1) || indexList.Contains(index2))
- {
- newMeshTriangles.RemoveAt(j);
- newMeshTriangles.RemoveAt(j - 1);
- newMeshTriangles.RemoveAt(j - 2);
- }
- }
- var newTriangles = newMeshTriangles.ToArray();
- // record undo operation for targets that to be modified
- var newIndices = mesh.triangles;
- UndoRedoManager.Instance().Push(a =>
- {
- mesh.ModifyIndices("Mesh Toolbox: delete", meshCollider, a, () =>
- {
- VertexMap.Rebuild(gameObject);
- });
- meshCollider.enabled = false;
- meshCollider.enabled = true;
- }, newIndices, "Mesh Toolbox: delete");
- // assign
- mesh.triangles = newTriangles;
- MTEEditorWindow.Instance.SetMeshDirty(gameObject);
- // rebuild vertex map
- VertexMap.Rebuild(gameObject);
- modifyGroup.Clear();
- }
- }
- }
- }
- }
|