/// <summary> /// 清空鼠标当前经过的目标 /// </summary> private void ClearHoverTarget() { if (_currentHoverTriangle != null) { _currentHoverTriangle = null; } }
/// <summary> /// 截获鼠标当前经过的目标 /// </summary> private void CaptureHoverTarget() { if (Event.current.type == EventType.MouseMove) { RaycastHit hit; if (Physics.Raycast(HandleUtility.GUIPointToWorldRay(Event.current.mousePosition), out hit)) { if (hit.triangleIndex >= 0 && hit.triangleIndex < _meshMaker.Triangles.Count) { _currentHoverTriangle = _meshMaker.Triangles[hit.triangleIndex]; if (_currentEditMode == EditMode.Face && _currentHoverTriangle == _currentCheckedTriangle) { ClearHoverTarget(); } } else { ClearHoverTarget(); } } else { ClearHoverTarget(); } } else if (Event.current.type == EventType.MouseDown) { ClearHoverTarget(); } ShowHoverTarget(); }
/// <summary> /// 清空鼠标当前选中的目标 /// </summary> private void ClearCheckedTarget() { if (_currentCheckedTriangle != null) { _currentCheckedTriangle = null; } if (_currentCheckedEdge != null) { _currentCheckedEdge = null; } if (_currentCheckedVertex != null) { _currentCheckedVertex = null; } }
/// <summary> /// 截获鼠标当前选中的目标 /// </summary> private void CaptureCheckedTarget() { if (!_secondaryHandle && Event.current.button == 1 && Event.current.isMouse && Event.current.type == EventType.MouseDown) { RaycastHit hit; if (Physics.Raycast(HandleUtility.GUIPointToWorldRay(Event.current.mousePosition), out hit)) { if (hit.triangleIndex >= 0 && hit.triangleIndex < _meshMaker.Triangles.Count) { _currentCheckedTriangle = _meshMaker.Triangles[hit.triangleIndex]; } else { ClearCheckedTarget(); } } else { ClearCheckedTarget(); } if (_currentCheckedTriangle != null) { switch (_currentEditMode) { case EditMode.Vertex: _currentCheckedVertex = _currentCheckedTriangle.GetVertexByClick(hit.point); break; case EditMode.Edge: _currentCheckedEdge = _currentCheckedTriangle.GetEdgeByClick(hit.point); SetEditEdge(); break; case EditMode.Face: SetEditTriangle(); break; } } } Selection.activeObject = _meshMaker.gameObject; ShowCheckedTarget(); }
/// <summary> /// 鼠标点击,获取距离鼠标最近的边 /// </summary> public static MeshMakerEdge GetEdgeByClick(this MeshMakerTriangle triangle, Vector3 clickPoint) { float distance1 = HandleUtility.DistancePointLine(clickPoint, triangle.Edge1.Vertex1.Vertex, triangle.Edge1.Vertex2.Vertex); float distance2 = HandleUtility.DistancePointLine(clickPoint, triangle.Edge2.Vertex1.Vertex, triangle.Edge2.Vertex2.Vertex); float distance3 = HandleUtility.DistancePointLine(clickPoint, triangle.Edge3.Vertex1.Vertex, triangle.Edge3.Vertex2.Vertex); if (distance1 < distance2 && distance1 < distance3) { return(triangle.Edge1); } if (distance2 < distance1 && distance2 < distance3) { return(triangle.Edge2); } if (distance3 < distance1 && distance3 < distance2) { return(triangle.Edge3); } return(triangle.Edge1); }
/// <summary> /// 鼠标点击,获取距离鼠标最近的顶点 /// </summary> public static MeshMakerVertex GetVertexByClick(this MeshMakerTriangle triangle, Vector3 clickPoint) { float distance1 = Vector3.Distance(triangle.Vertex1.Vertex, clickPoint); float distance2 = Vector3.Distance(triangle.Vertex2.Vertex, clickPoint); float distance3 = Vector3.Distance(triangle.Vertex3.Vertex, clickPoint); if (distance1 < distance2 && distance1 < distance3) { return(triangle.Vertex1); } if (distance2 < distance1 && distance2 < distance3) { return(triangle.Vertex2); } if (distance3 < distance1 && distance3 < distance2) { return(triangle.Vertex3); } return(triangle.Vertex1); }
/// <summary> /// 为所有面执行分割操作,条件是该面包含顶点vertex1和vertex2,并以新的顶点newVertex作为分割之后的顶点 /// </summary> public static void SegmentationTriangle(this List <MeshMakerTriangle> triangles, MeshMakerVertex vertex1, MeshMakerVertex vertex2, MeshMakerVertex newVertex) { List <MeshMakerTriangle> newTriangles = new List <MeshMakerTriangle>(); for (int i = 0; i < triangles.Count; i++) { if ((triangles[i].Vertex1 == vertex1 || triangles[i].Vertex1 == vertex2) && (triangles[i].Vertex2 == vertex1 || triangles[i].Vertex2 == vertex2)) { MeshMakerTriangle mmt1 = new MeshMakerTriangle(0, ref triangles[i].Vertex1, ref newVertex, ref triangles[i].Vertex3); MeshMakerTriangle mmt2 = new MeshMakerTriangle(0, ref newVertex, ref triangles[i].Vertex2, ref triangles[i].Vertex3); triangles.RemoveAt(i); newTriangles.Add(mmt1); newTriangles.Add(mmt2); i--; } else if ((triangles[i].Vertex2 == vertex1 || triangles[i].Vertex2 == vertex2) && (triangles[i].Vertex3 == vertex1 || triangles[i].Vertex3 == vertex2)) { MeshMakerTriangle mmt1 = new MeshMakerTriangle(0, ref triangles[i].Vertex1, ref triangles[i].Vertex2, ref newVertex); MeshMakerTriangle mmt2 = new MeshMakerTriangle(0, ref triangles[i].Vertex1, ref newVertex, ref triangles[i].Vertex3); triangles.RemoveAt(i); newTriangles.Add(mmt1); newTriangles.Add(mmt2); i--; } else if ((triangles[i].Vertex1 == vertex1 || triangles[i].Vertex1 == vertex2) && (triangles[i].Vertex3 == vertex1 || triangles[i].Vertex3 == vertex2)) { MeshMakerTriangle mmt1 = new MeshMakerTriangle(0, ref triangles[i].Vertex1, ref triangles[i].Vertex2, ref newVertex); MeshMakerTriangle mmt2 = new MeshMakerTriangle(0, ref newVertex, ref triangles[i].Vertex2, ref triangles[i].Vertex3); triangles.RemoveAt(i); newTriangles.Add(mmt1); newTriangles.Add(mmt2); i--; } } triangles.AddRange(newTriangles); }
/// <summary> /// 初始化 /// </summary> private void Init() { #region 检测Mesh this.CompileNoEditor(delegate() { DestroyImmediate(this); return; }); if (EditorApplication.isPlaying) { DestroyImmediate(this); return; } string msseage = "OK"; if (GetComponent <MeshFilter>() == null) { msseage = "游戏物体缺少组件 MeshFilter!"; } else if (GetComponent <MeshRenderer>() == null) { msseage = "游戏物体缺少组件 MeshRenderer!"; } else if (GetComponent <MeshFilter>().sharedMesh.vertexCount > _astrictVertexNum) { msseage = "游戏物体顶点太多,我无法处理!"; } if (msseage != "OK") { DestroyImmediate(this); Debug.LogWarning(msseage); return; } #endregion #region 识别MeshVertex _allUVs = new List <Vector2>(GetComponent <MeshFilter>().sharedMesh.uv); _allNormals = new List <Vector3>(GetComponent <MeshFilter>().sharedMesh.normals); _allVertexs = new List <Vector3>(GetComponent <MeshFilter>().sharedMesh.vertices); Vertexs = new List <MeshMakerVertex>(); List <int> repetitionVertices = new List <int>(); for (int i = 0; i < _allVertexs.Count; i++) { this.CompileOnlyEditor(delegate() { EditorUtility.DisplayProgressBar("识别顶点", "正在识别顶点(" + i + "/" + _allVertexs.Count + ")......", 1.0f / _allVertexs.Count * i); }); if (repetitionVertices.Contains(i)) { continue; } List <int> verticesGroup = new List <int>(); verticesGroup.Add(i); for (int j = i + 1; j < _allVertexs.Count; j++) { if (_allVertexs[i] == _allVertexs[j]) { verticesGroup.Add(j); repetitionVertices.Add(j); } } Vertexs.Add(new MeshMakerVertex(Vertexs.Count, transform.localToWorldMatrix.MultiplyPoint3x4(_allVertexs[i]), _allUVs[i], _allNormals[i], verticesGroup)); } #endregion #region 识别MeshTriangle _allTriangles = new List <int>(GetComponent <MeshFilter>().sharedMesh.triangles); Triangles = new List <MeshMakerTriangle>(); for (int i = 0; (i + 2) < _allTriangles.Count; i += 3) { this.CompileOnlyEditor(delegate() { EditorUtility.DisplayProgressBar("识别顶点", "正在识别顶点(" + i + "/" + _allTriangles.Count + ")......", 1.0f / _allTriangles.Count * i); }); MeshMakerVertex mmv1 = Vertexs.GetVertexByIndex(_allTriangles[i]); MeshMakerVertex mmv2 = Vertexs.GetVertexByIndex(_allTriangles[i + 1]); MeshMakerVertex mmv3 = Vertexs.GetVertexByIndex(_allTriangles[i + 2]); MeshMakerTriangle mmt = new MeshMakerTriangle(Triangles.Count, ref mmv1, ref mmv2, ref mmv3); Triangles.Add(mmt); } for (int i = 0; i < Vertexs.Count; i++) { Vertexs[i].VertexIndexs.Clear(); } #endregion #region 重构Mesh if (Target) { DestroyImmediate(Target); } Target = new GameObject(transform.name + "(Clone)"); Target.transform.SetParent(transform); Target.transform.localPosition = Vector3.zero; Target.transform.localRotation = Quaternion.Euler(Vector3.zero); Target.transform.localScale = Vector3.one; Target.hideFlags = HideFlags.HideInHierarchy; _meshFilter = Target.AddComponent <MeshFilter>(); _meshRenderer = Target.AddComponent <MeshRenderer>(); _meshRenderer.sharedMaterial = GetComponent <MeshRenderer>().sharedMaterial; _meshCollider = Target.AddComponent <MeshCollider>(); GenerateMesh(); GetComponent <MeshRenderer>().enabled = false; if (GetComponent <Collider>()) { GetComponent <Collider>().enabled = false; } EditorUtility.ClearProgressBar(); #endregion #region 其他编辑器参数初始化 CheckedColor = Color.red; HoverColor = Color.green; VertexHandleSize = 0.005f; IsCanEdit = true; #endregion }
private void Init() { _meshMaker = target as MeshMaker; if (_meshMaker == null || EditorApplication.isPlaying) { return; } TransformChange(_meshMaker); _currentHoverTriangle = null; _currentCheckedTriangle = null; _currentCheckedVertex = null; _currentCheckedEdge = null; _currentHandleTool = HandleTool.None; _currentEditMode = EditMode.Vertex; _currentEditTriangle = new GameObject("Triangle"); _currentEditTriangle.transform.SetParent(_meshMaker.Target.transform); _currentEditTriangle.hideFlags = HideFlags.HideInHierarchy; _currentEditTriangleVertex1 = new GameObject("Vertex1"); _currentEditTriangleVertex1.transform.SetParent(_currentEditTriangle.transform); _currentEditTriangleVertex1.hideFlags = HideFlags.HideInHierarchy; _currentEditTriangleVertex2 = new GameObject("Vertex2"); _currentEditTriangleVertex2.transform.SetParent(_currentEditTriangle.transform); _currentEditTriangleVertex2.hideFlags = HideFlags.HideInHierarchy; _currentEditTriangleVertex3 = new GameObject("Vertex3"); _currentEditTriangleVertex3.transform.SetParent(_currentEditTriangle.transform); _currentEditTriangleVertex3.hideFlags = HideFlags.HideInHierarchy; _currentEditEdge = new GameObject("Edge"); _currentEditEdge.transform.SetParent(_meshMaker.Target.transform); _currentEditEdge.hideFlags = HideFlags.HideInHierarchy; _currentEditEdgeVertex1 = new GameObject("Vertex1"); _currentEditEdgeVertex1.transform.SetParent(_currentEditEdge.transform); _currentEditEdgeVertex1.hideFlags = HideFlags.HideInHierarchy; _currentEditEdgeVertex2 = new GameObject("Vertex2"); _currentEditEdgeVertex2.transform.SetParent(_currentEditEdge.transform); _currentEditEdgeVertex2.hideFlags = HideFlags.HideInHierarchy; if (_vertexButtonContent == null) { Texture2D t2d = AssetDatabase.LoadAssetAtPath("Assets/MeshEditor/MeshMaker/Editor/Texture/Vertex.png", typeof(Texture2D)) as Texture2D; _vertexButtonContent = new GUIContent("", t2d, "Vertex Edit Mode"); } if (_edgeButtonContent == null) { Texture2D t2d = AssetDatabase.LoadAssetAtPath("Assets/MeshEditor/MeshMaker/Editor/Texture/Edge.png", typeof(Texture2D)) as Texture2D; _edgeButtonContent = new GUIContent("", t2d, "Edge Edit Mode"); } if (_faceButtonContent == null) { Texture2D t2d = AssetDatabase.LoadAssetAtPath("Assets/MeshEditor/MeshMaker/Editor/Texture/Face.png", typeof(Texture2D)) as Texture2D; _faceButtonContent = new GUIContent("", t2d, "Face Edit Mode"); } if (_noneButtonContent == null) { Texture2D t2d = AssetDatabase.LoadAssetAtPath("Assets/MeshEditor/MeshMaker/Editor/Texture/None.png", typeof(Texture2D)) as Texture2D; _noneButtonContent = new GUIContent("", t2d, "None Edit Mode"); } _secondaryHandle = false; _secondaryHandleMode = SecondaryHandleMode.None; _sceneCamera = SceneView.lastActiveSceneView.camera; Undo.undoRedoPerformed += OnRecord; }