private void OnDrawGizmos() { RefreshMesh(); if (GetComponent <ShapeRender>()) { return; } Vector3 pos = transform.position; pos.y = 0; Color color = Gizmos.color; switch (Type) { case PolyType.Area: Gizmos.color = new Color(0, 1, 0, 0.5f); break; case PolyType.Hollow: pos.y = 0.01f; Gizmos.color = new Color(1f, 0.921568632f, 0.0156862754f, 0.5f); break; case PolyType.Obstacle: Gizmos.color = new Color(1, 0, 0, 0.5f); pos.y = 0.02f; break; } Gizmos.DrawMesh(ShowMesh, pos, PlaneUtils.TransRotation(transform.rotation)); Gizmos.color = color; }
private void OnSceneGUI() { bool enableEditor = targets.Length == 1; var shape = target as BoxShape; shape.Offset.y = 0; Vector3 pos = shape.transform.position; pos.y = 0; Quaternion rotation = PlaneUtils.TransRotation(shape.transform.rotation); Matrix4x4 matrix = Matrix4x4.TRS(pos, rotation, Vector3.one); using (new Handles.DrawingScope(Color.green, matrix)) { Handles.DrawWireCube(shape.Offset, new Vector3(shape.Size.x, 0, shape.Size.y)); if (enableEditor) { for (int i = 0; i < 4; ++i) { Vector3 normal = ControlPoints[i]; bool isX = (i % 2 == 0); float size = shape.Size.y; if (isX) { size = shape.Size.x; } size *= 0.5f; Vector3 pt = normal * size + shape.Offset; EditorGUI.BeginChangeCheck(); float handleSize = HandleUtility.GetHandleSize(pt) * 0.05f; pt = Handles.FreeMoveHandle(pt, rotation, handleSize, normal, Handles.DotHandleCap); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(shape, "modify box"); EditorUtility.SetDirty(shape); Vector3 otherSide = normal * (-1 * size) + shape.Offset; float newSize = Vector3.Distance(pt, otherSide) * 0.5f; shape.Offset += normal * (newSize - size); if (isX) { shape.Size.x = newSize * 2; } else { shape.Size.y = newSize * 2; } shape.SetDirty(); } } } } }
private ISDFShape ToSDFSharp(Shape shape) { Matrix4x4 matrix = PlaneUtils.ToPlaneMatrix(shape.transform); if (shape is CircleShape circle) { var pos = matrix.MultiplyPoint(circle.Offset); return(new Circle { Position = PlaneUtils.ToVector2(pos), Radius = circle.Radius, }); } else if (shape is BoxShape box) { var pos = matrix.MultiplyPoint(box.Offset); var rotation = matrix.MultiplyVector(new Vector3(1, 0, 0)); return(new Box { Position = PlaneUtils.ToVector2(pos), Rotation = PlaneUtils.ToVector2(rotation), HalfSize = box.Size * 0.5f, }); } else if (shape is PolyShape polygon) { Polygon points = new Polygon { Points = new Vector2[polygon.Points.Count] }; for (int i = 0; i < polygon.Points.Count; ++i) { points.Points[i] = PlaneUtils.ToVector2(matrix.MultiplyPoint(polygon.Points[i])); } return(points); } else if (shape is LineShape line) { Line points = new Line { Points = new Vector2[line.Points.Count] }; for (int i = 0; i < line.Points.Count; ++i) { points.Points[i] = PlaneUtils.ToVector2(matrix.MultiplyPoint(line.Points[i])); } return(points); } return(null); }
private static T CreateShape <T>(MenuCommand menuCommand) where T : Shape { GameObject go = ObjectFactory.CreateGameObject(typeof(T).Name); T shape = Undo.AddComponent <T>(go); var camera = SceneView.lastActiveSceneView.camera; Ray ray = new Ray(camera.transform.position, camera.transform.forward); if (!PlaneUtils.RayCastPlaneXZ(ray, out Vector3 pos)) { pos = ray.origin + ray.direction * 10; } go.transform.position = pos; if (menuCommand.context is GameObject parent) { Undo.SetTransformParent(go.transform, parent.transform, "CreateSharp"); } Selection.activeGameObject = go; //EditorGUIUtility.PingObject(go); SceneView.lastActiveSceneView.FrameSelected(); return(shape); }
private void OnSceneGUI() { bool enableEditor = targets.Length == 1; var shape = target as PolyShape; if (worldPoints == null || worldPoints.Length != shape.Points.Count) { worldPoints = new Vector3[shape.Points.Count]; } Vector3 pos = shape.transform.position; pos.y = 0; Quaternion rotation = PlaneUtils.TransRotation(shape.transform.rotation); Matrix4x4 matrix = Matrix4x4.TRS(pos, rotation, Vector3.one); for (int i = 0; i < shape.Points.Count; ++i) { worldPoints[i] = matrix.MultiplyPoint(shape.Points[i]); } //计算鼠标点击在XZ平面的点 Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); if (!PlaneUtils.RayCastPlaneXZ(ray, out Vector3 mousePos)) { return;//鼠标没有点击在XZ平面 } var result = PlaneUtils.ClosestPointToPolyLine(mousePos, worldPoints); Vector3 closePoint = result.Point; int index = result.Index; using (new Handles.DrawingScope(Color.green)) { //画边缘线 for (int i = 0; i < worldPoints.Length; ++i) { int nextIndex = i + 1; if (nextIndex == shape.Points.Count) { nextIndex = 0; } Vector3 pt = worldPoints[i]; Handles.DrawLine(pt, worldPoints[nextIndex]); if (enableEditor) { //点位置编辑 float handleSize = HandleUtility.GetHandleSize(pt) * 0.05f; EditorGUI.BeginChangeCheck(); pt = Handles.FreeMoveHandle(pt, Quaternion.identity, handleSize, new Vector3(1, 0, 1), Handles.DotHandleCap); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(shape, "move polygon point"); EditorUtility.SetDirty(shape); pt = matrix.inverse.MultiplyPoint(pt); pt.y = 0; worldPoints[i] = pt; shape.Points[i] = pt; shape.SetDirty(); } } } if (!enableEditor) { return; } if (Event.current.control) {//移除点 if (worldPoints.Length > 3) { int removeIndex = index + 1; if (removeIndex == worldPoints.Length) { removeIndex = 0; } int preIndex = removeIndex - 1; if (preIndex < 0) { preIndex = worldPoints.Length - 1; } int nextIndex = removeIndex + 1; if (nextIndex == worldPoints.Length) { nextIndex = 0; } Handles.DrawLine(worldPoints[preIndex], worldPoints[nextIndex]); using (new Handles.DrawingScope(Color.red)) { Handles.DrawAAPolyLine(5, worldPoints[preIndex], worldPoints[removeIndex]); Handles.DrawAAPolyLine(5, worldPoints[nextIndex], worldPoints[removeIndex]); float handleSize = HandleUtility.GetHandleSize(worldPoints[removeIndex]) * 0.05f; var pt1 = HandleUtility.WorldToGUIPoint(worldPoints[removeIndex]); var pt2 = HandleUtility.WorldToGUIPoint(mousePos); float pickSize = Vector2.Distance(pt1, pt2) + 0.1f; if (Handles.Button(worldPoints[removeIndex], Quaternion.identity, handleSize, pickSize, Handles.DotHandleCap)) { Undo.RecordObject(shape, "delete polygon point"); EditorUtility.SetDirty(shape); shape.Points.RemoveAt(removeIndex); shape.SetDirty(); Event.current.Use(); } } } } else if (Event.current.shift && (result.SegmentLength * result.NormalLength) > 0.1f && (result.SegmentLength * result.NormalLength) < (result.SegmentLength - 0.1f)) {//添加点 { float handleSize = HandleUtility.GetHandleSize(closePoint) * 0.08f; //画距离鼠标最近的点 Handles.SphereHandleCap(0, closePoint, Quaternion.identity, handleSize, Event.current.type); } int insertIndex = index + 1; if (insertIndex == worldPoints.Length) { insertIndex = 0; } using (new Handles.DrawingScope(Color.white)) { Handles.DrawLine(mousePos, worldPoints[index]); Handles.DrawLine(mousePos, worldPoints[insertIndex]); float handleSize = HandleUtility.GetHandleSize(mousePos) * 0.05f; if (Handles.Button(mousePos, Quaternion.identity, handleSize, 0.1f, Handles.DotHandleCap)) { Undo.RecordObject(shape, "add polygon point"); EditorUtility.SetDirty(shape); var pt = matrix.inverse.MultiplyPoint(mousePos); shape.Points.Insert(insertIndex, pt); shape.SetDirty(); Event.current.Use(); } } } } SceneView.RepaintAll(); }