public static void Clear() { BrushOutlineManager.ClearOutlines(); ClearRegistration(); ClearCaches(); _isHierarchyModified = true; }
public static void UndoRedoPerformed() { BrushOutlineManager.ClearOutlines(); CheckForChanges(forceHierarchyUpdate: true); if (!IgnoreMaterials) { foreach (var brush in Brushes) { try { //brush.EnsureInitialized(); if (brush.Shape != null) { ShapeUtility.CheckMaterials(brush.Shape); } } finally { } } foreach (var brush in Brushes) { try { InternalCSGModelManager.CheckSurfaceModifications(brush, true); //InternalCSGModelManager.ValidateBrush(brush); } finally { } } } }
public static void DrawSimpleOutlines(LineMeshManager lineMeshManager, Int32 brushNodeID, Matrix4x4 transformation, Color color) { // .. could be a prefab if (brushNodeID == CSGNode.InvalidNodeID) { return; } var outline = BrushOutlineManager.GetBrushOutline(brushNodeID); DrawSimpleOutlines(lineMeshManager, outline, transformation, color); }
public static void DrawOutlines(Int32 brushNodeID, Matrix4x4 transformation, Color outerColor, Color outerColorOccluded, Color innerColor, Color innerColorOccluded, float thickness = -1) { // .. could be a prefab if (brushNodeID == CSGNode.InvalidNodeID) { return; } var outline = BrushOutlineManager.GetBrushOutline(brushNodeID); DrawOutlines(outline, transformation, outerColor, outerColorOccluded, innerColor, innerColorOccluded, thickness); }
public static void DrawSimpleOutlines(LineMeshManager lineMeshManager, Int32 brushID, Vector3 translation, Color color) { // .. could be a prefab if (brushID == -1) { return; } var outline = BrushOutlineManager.GetBrushOutline(brushID); DrawSimpleOutlines(lineMeshManager, outline, translation, color); }
public static void DrawOutlines(Int32 brushID, Vector3 translation, Color outerColor, Color outerColorOccluded, Color innerColor, Color innerColorOccluded, float thickness = -1) { // .. could be a prefab if (brushID == -1) { return; } var outline = BrushOutlineManager.GetBrushOutline(brushID); DrawOutlines(outline, translation, outerColor, outerColorOccluded, innerColor, innerColorOccluded, thickness); }
public static void DrawSelectedBrushes(LineMeshManager zTestLineMeshManager, LineMeshManager noZTestLineMeshManager, Int32[] brushNodeIDs, Matrix4x4[] transformations, Color wireframeColor, float thickness = -1) { Color selectedOuterColor = wireframeColor; //selectedOuterColor.a = 1.0f; Color selectedInnerColor = selectedOuterColor * inner_factor; Color selectedOuterOccludedColor = selectedOuterColor * occluded_factor; Color selectedInnerOccludedColor = selectedInnerColor * occluded_factor; selectedOuterOccludedColor.a *= 0.5f; selectedInnerOccludedColor.a *= 0.5f; var wireframes = BrushOutlineManager.GetBrushOutlines(brushNodeIDs); CSGRenderer.DrawOutlines(zTestLineMeshManager, noZTestLineMeshManager, wireframes, transformations, selectedOuterColor, selectedOuterOccludedColor, selectedInnerColor, selectedInnerOccludedColor, thickness); }
public static void OnSceneGUI(SceneView sceneView) { if (EditorApplication.isPlayingOrWillChangePlaymode) { return; } CameraUtility.InitDistanceChecks(sceneView); SelectionUtility.HandleEvents(); InitTools(); HandleBuilderEvents(); { UpdateTool(); if (instance.activeTool != null) { if (RealtimeCSG.CSGSettings.EnableRealtimeCSG) { // handle the tool var sceneSize = sceneView.position.size; var sceneRect = new Rect(0, 0, sceneSize.x, sceneSize.y - ((CSG_GUIStyleUtility.BottomToolBarHeight + 4) + 17)); instance.activeTool.HandleEvents(sceneRect); } else { if (Event.current.type == EventType.Repaint) { var brushes = instance.filteredSelection.BrushTargets; var wireframes = new List <GeometryWireframe>(brushes.Length); var transformations = new List <Matrix4x4>(brushes.Length); for (int i = 0; i < brushes.Length; i++) { var brush = brushes[i]; if (!brush) { continue; } if (brush.ChildData == null || !brush.ChildData.Model) { continue; } var brushTransformation = brush.compareTransformation.localToWorldMatrix; wireframes.Add(BrushOutlineManager.GetBrushOutline(brushes[i].brushNodeID)); transformations.Add(brushTransformation); } if (wireframes.Count > 0) { CSGRenderer.DrawSelectedBrushes(instance.zTestLineMeshManager, instance.noZTestLineMeshManager, wireframes.ToArray(), transformations.ToArray(), ColorSettings.SelectedOutlines, GUIConstants.thickLineScale); } MaterialUtility.LineDashMultiplier = 1.0f; MaterialUtility.LineThicknessMultiplier = 1.0f; MaterialUtility.LineAlphaMultiplier = 1.0f; instance.zTestLineMeshManager.Render(MaterialUtility.ZTestGenericLine); instance.zTestLineMeshManager.Render(MaterialUtility.ZTestGenericLine); } } } } int sceneWindowId = GUIUtility.GetControlID(SceneWindowHash, FocusType.Passive); var sceneWindowType = Event.current.GetTypeForControl(sceneWindowId); if (sceneWindowType == EventType.Repaint) { if (currentEditorWindows.Count > 0) { for (int i = 0; i < currentEditorWindows.Count; i++) { currentEditorWindows[i].Repaint(); } return; } } if (sceneWindowType == EventType.MouseMove) { SceneDragToolManager.IsDraggingObjectInScene = false; } if (RealtimeCSG.CSGSettings.EnableRealtimeCSG) { if (sceneView && sceneWindowType != EventType.Used && !SceneDragToolManager.IsDraggingObjectInScene) { if (currentEditorWindows.Count == 0) { try { Handles.BeginGUI(); Rect windowRect = new Rect(Vector2.zero, sceneView.position.size); EditModeSelectionGUI.HandleWindowGUI(windowRect); } finally { Handles.EndGUI(); } } } } }
public static bool SnapToVertices(CSGBrush brush, CSGPlane?snapPlane, Vector3 worldPosition, out List <Vector3> outEdgePoints, out Vector3 outPosition, float closestDistance = float.PositiveInfinity) { outPosition = MathConstants.zeroVector3; outEdgePoints = null; if (!brush) { return(false); } var controlMesh = brush.ControlMesh; if (controlMesh == null) { return(false); } Vector3?outPoint = null; // Find an edge to snap against the point we're interested in var guiPoint = CameraUtility.WorldToGUIPoint(worldPosition); var closestDistanceSqr = closestDistance * closestDistance; /* * var points = controlMesh.vertices; * var edges = controlMesh.edges; * var polygons = controlMesh.polygons; * var localToWorld = brush.transform.localToWorldMatrix; * for(int p = 0; p < polygons.Length; p++) * { * var edgeIndices = polygons[p].edgeIndices; * for (int e = 0; e < edgeIndices.Length; e++) * { * var edgeIndex = edgeIndices[e]; * if (!edges[edgeIndex].hardEdge) * continue; * * var twinIndex = edges[edgeIndex].twinIndex; * * var vertexIndex1 = edges[edgeIndex].vertexIndex; * var vertexIndex2 = edges[twinIndex].vertexIndex; * * var vertex1 = localToWorld.MultiplyPoint(points[vertexIndex1]); * var vertex2 = localToWorld.MultiplyPoint(points[vertexIndex2]); * * if (!snapPlane.HasValue || * Mathf.Abs(snapPlane.Value.Distance(vertex1)) < Constants.DistanceEpsilon) * { * var guiVertex1 = (Vector3)CameraUtility.WorldToGUIPoint(vertex1); * var guiDistance = (guiVertex1 - guiPoint).magnitude * VertexFudgeFactor; * if (guiDistance + Constants.DistanceEpsilon < closestDistance) * { * closestDistance = guiDistance; * outPoint = vertex1; * } * } * * if (!snapPlane.HasValue || * Mathf.Abs(snapPlane.Value.Distance(vertex2)) < Constants.DistanceEpsilon) * { * var guiVertex2 = (Vector3)CameraUtility.WorldToGUIPoint(vertex2); * var guiDistance = (guiVertex2 - guiPoint).magnitude * VertexFudgeFactor; * if (guiDistance + Constants.DistanceEpsilon < closestDistance) * { * closestDistance = guiDistance; * outPoint = vertex2; * } * } * } * }*/ var outline = BrushOutlineManager.GetBrushOutline(brush.brushNodeID); if (outline != null) { var localToWorld = brush.transform.localToWorldMatrix; var indices = outline.visibleInnerLines; var vertices = outline.vertices; if (indices != null && vertices != null) { for (int i = 0; i < indices.Length; i += 2) { var index1 = indices[i + 0]; var index2 = indices[i + 1]; var vertex1 = localToWorld.MultiplyPoint(vertices[index1]); var vertex2 = localToWorld.MultiplyPoint(vertices[index2]); if (!snapPlane.HasValue || Mathf.Abs(snapPlane.Value.Distance(vertex1)) < MathConstants.DistanceEpsilon) { var guiVertex1 = CameraUtility.WorldToGUIPoint(vertex1); var guiDistance = (guiVertex1 - guiPoint).sqrMagnitude * VertexFudgeFactor; if (guiDistance + MathConstants.DistanceEpsilon < closestDistanceSqr) { closestDistanceSqr = guiDistance; outPoint = vertex1; continue; } } if (!snapPlane.HasValue || Mathf.Abs(snapPlane.Value.Distance(vertex2)) < MathConstants.DistanceEpsilon) { var guiVertex2 = CameraUtility.WorldToGUIPoint(vertex2); var guiDistance = (guiVertex2 - guiPoint).sqrMagnitude * VertexFudgeFactor; if (guiDistance + MathConstants.DistanceEpsilon < closestDistanceSqr) { closestDistanceSqr = guiDistance; outPoint = vertex2; continue; } } } } if ((RealtimeCSG.CSGSettings.VisibleHelperSurfaces & HelperSurfaceFlags.ShowCulledSurfaces) == HelperSurfaceFlags.ShowCulledSurfaces) { indices = outline.invisibleInnerLines; vertices = outline.vertices; if (indices != null && vertices != null) { for (int i = 0; i < indices.Length; i += 2) { var index1 = indices[i + 0]; var index2 = indices[i + 1]; var vertex1 = localToWorld.MultiplyPoint(vertices[index1]); var vertex2 = localToWorld.MultiplyPoint(vertices[index2]); if (!snapPlane.HasValue || Mathf.Abs(snapPlane.Value.Distance(vertex1)) < MathConstants.DistanceEpsilon) { var guiVertex1 = CameraUtility.WorldToGUIPoint(vertex1); var guiDistance = (guiVertex1 - guiPoint).sqrMagnitude * VertexFudgeFactor; if (guiDistance + MathConstants.DistanceEpsilon < closestDistanceSqr) { closestDistanceSqr = guiDistance; outPoint = vertex1; } } if (!snapPlane.HasValue || Mathf.Abs(snapPlane.Value.Distance(vertex1)) < MathConstants.DistanceEpsilon) { var guiVertex2 = CameraUtility.WorldToGUIPoint(vertex2); var guiDistance = (guiVertex2 - guiPoint).magnitude * VertexFudgeFactor; if (guiDistance + MathConstants.DistanceEpsilon < closestDistanceSqr) { closestDistanceSqr = guiDistance; outPoint = vertex2; } } } } } } if (!outPoint.HasValue || float.IsInfinity(closestDistance)) { return(false); } closestDistance = Mathf.Sqrt(closestDistanceSqr); outPosition = outPoint.Value; outEdgePoints = FindAllEdgesThatTouchPoint(brush, outPosition); return(true); }
public static bool SnapToEdge(Camera camera, CSGBrush brush, CSGPlane?_snapPlane, Vector3 _worldPoint, out List <Vector3> outEdgePoints, out Vector3 outPosition) //, float _closestDistance = float.PositiveInfinity) { outPosition = MathConstants.zeroVector3; outEdgePoints = null; if (!brush) { return(false); } var controlMesh = brush.ControlMesh; if (controlMesh == null || camera == null) { return(false); } var snapData = new SnapData { // Find an edge to snap against the point we're interested in worldPoint = _worldPoint, guiPoint = CameraUtility.WorldToGUIPoint(_worldPoint), closestDistance = float.PositiveInfinity, closestDistanceSqr = float.PositiveInfinity, snapPlane = _snapPlane, outEdge = null, snappedWorldPoint = MathConstants.PositiveInfinityVector3 }; var points = controlMesh.Vertices; var edges = controlMesh.Edges; var polygons = controlMesh.Polygons; var localToWorld = brush.transform.localToWorldMatrix; if (_internal_snapEdgesUsed == null || _internal_snapEdgesUsed.Length < edges.Length) { _internal_snapEdgesUsed = new bool[edges.Length]; _internal_snapVertices = new Vector3[edges.Length * 2]; } Array.Clear(_internal_snapEdgesUsed, 0, _internal_snapEdgesUsed.Length); _internal_snapVertexCount = 0; for (int p = 0; p < polygons.Length; p++) { var edgeIndices = polygons[p].EdgeIndices; for (int e = 0; e < edgeIndices.Length; e++) { var edgeIndex = edgeIndices[e]; if (!edges[edgeIndex].HardEdge) { continue; } if (_internal_snapEdgesUsed[edgeIndex]) { continue; } var twin = controlMesh.GetTwinEdgeIndex(edgeIndex); _internal_snapEdgesUsed[edgeIndex] = true; _internal_snapEdgesUsed[twin] = true; var twinIndex = edges[edgeIndex].TwinIndex; var vertexIndex1 = edges[edgeIndex].VertexIndex; var vertexIndex2 = edges[twinIndex].VertexIndex; _internal_snapVertices[_internal_snapVertexCount + 0] = localToWorld.MultiplyPoint(points[vertexIndex1]); _internal_snapVertices[_internal_snapVertexCount + 1] = localToWorld.MultiplyPoint(points[vertexIndex2]); _internal_snapVertexCount += 2; } } if (_internal_snapVertexCount > 0) { SnapToLines(_internal_snapVertices, _internal_snapVertexCount, ref snapData); } var outline = BrushOutlineManager.GetBrushOutline(brush.brushNodeID); if (outline != null) { var vertices = outline.vertices; var indices = outline.visibleInnerLines; SnapToLines(indices, vertices, localToWorld, ref snapData); if ((RealtimeCSG.CSGSettings.VisibleHelperSurfaces & HelperSurfaceFlags.ShowCulledSurfaces) == HelperSurfaceFlags.ShowCulledSurfaces) { indices = outline.invisibleInnerLines; SnapToLines(indices, vertices, localToWorld, ref snapData); } } if (snapData.outEdge == null || float.IsInfinity(snapData.closestDistanceSqr)) { return(false); } snapData.closestDistance = Mathf.Sqrt(snapData.closestDistanceSqr); outEdgePoints = snapData.outEdge; outPosition = snapData.snappedWorldPoint; return(true); }
private static List <Vector3> FindAllEdgesThatTouchPoint(CSGBrush brush, Vector3 point) { var lines = new List <Vector3>(); if (!brush) { return(lines); } var outline = BrushOutlineManager.GetBrushOutline(brush.brushNodeID); if (outline == null) { return(lines); } var controlMesh = brush.ControlMesh; if (controlMesh == null) { return(lines); } var localToWorld = brush.transform.localToWorldMatrix; var edges = controlMesh.Edges; var points = controlMesh.Vertices; for (int e = 0; e < edges.Length; e++) { var vertexIndex1 = edges[e].VertexIndex; var vertex1 = localToWorld.MultiplyPoint(points[vertexIndex1]); var distance = (point - vertex1).sqrMagnitude; if (distance < MathConstants.EqualityEpsilonSqr) { var twinIndex = edges[e].TwinIndex; var vertexIndex2 = edges[twinIndex].VertexIndex; var vertex2 = localToWorld.MultiplyPoint(points[vertexIndex2]); lines.Add(vertex1); lines.Add(vertex2); } } var indices = outline.visibleInnerLines; var vertices = outline.vertices; if (indices != null && vertices != null) { for (int i = 0; i < indices.Length; i += 2) { var index1 = indices[i + 0]; var index2 = indices[i + 1]; var vertex1 = localToWorld.MultiplyPoint(vertices[index1]); var vertex2 = localToWorld.MultiplyPoint(vertices[index2]); var distance1 = (point - vertex1).sqrMagnitude; var distance2 = (point - vertex2).sqrMagnitude; if (distance1 < MathConstants.EqualityEpsilonSqr || distance2 < MathConstants.EqualityEpsilonSqr) { lines.Add(vertex1); lines.Add(vertex2); } } } if ((RealtimeCSG.CSGSettings.VisibleHelperSurfaces & HelperSurfaceFlags.ShowCulledSurfaces) == HelperSurfaceFlags.ShowCulledSurfaces) { indices = outline.invisibleInnerLines; vertices = outline.vertices; if (indices != null && vertices != null) { for (int i = 0; i < indices.Length; i += 2) { var index1 = indices[i + 0]; var index2 = indices[i + 1]; var vertex1 = localToWorld.MultiplyPoint(vertices[index1]); var vertex2 = localToWorld.MultiplyPoint(vertices[index2]); var distance1 = (point - vertex1).sqrMagnitude; var distance2 = (point - vertex2).sqrMagnitude; if (distance1 < MathConstants.EqualityEpsilonSqr || distance2 < MathConstants.EqualityEpsilonSqr) { lines.Add(vertex1); lines.Add(vertex2); } } } } return(lines); }
public override void OnInspectorGUI() { GUILayout.BeginVertical(GUI.skin.box); { GUILayout.Label("A hidden CSG model, and all it's brushes and operations, is contained by this object. This will automatically be removed at build time.", GUIStyleUtility.wrapLabel); GUILayout.Space(10); if (GUILayout.Button("Revert back to CSG model")) { Undo.IncrementCurrentGroup(); var groupIndex = Undo.GetCurrentGroup(); Undo.SetCurrentGroupName("Reverted to former CSG model"); try { var selection = new List <UnityEngine.Object>(); var updateScenes = new HashSet <Scene>(); foreach (var target in targets) { var exportedModel = target as CSGModelExported; if (!exportedModel) { continue; } exportedModel.disarm = true; exportedModel.hideFlags = HideFlags.DontSaveInBuild; updateScenes.Add(exportedModel.gameObject.scene); if (exportedModel.containedModel) { Undo.RecordObject(exportedModel.containedModel, "Revert model"); selection.Add(exportedModel.containedModel.gameObject); exportedModel.containedModel.transform.SetParent(exportedModel.transform.parent, true); exportedModel.containedModel.transform.SetSiblingIndex(exportedModel.transform.GetSiblingIndex()); exportedModel.containedModel.gameObject.SetActive(true); exportedModel.containedModel.gameObject.hideFlags = HideFlags.None; EditorUtility.SetDirty(exportedModel.containedModel); Undo.DestroyObjectImmediate(exportedModel); } else { MeshInstanceManager.ReverseExport(exportedModel); selection.Add(exportedModel.gameObject); EditorUtility.SetDirty(exportedModel); Undo.DestroyObjectImmediate(exportedModel); } } Selection.objects = selection.ToArray(); InternalCSGModelManager.skipRefresh = true; BrushOutlineManager.ClearOutlines(); //CSGModelManager.Refresh(forceHierarchyUpdate: true); InternalCSGModelManager.Rebuild(); foreach (var scene in updateScenes) { UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(scene); } } finally { InternalCSGModelManager.skipRefresh = false; Undo.CollapseUndoOperations(groupIndex); } } } GUILayout.Space(30); if (GUILayout.Button("Remove hidden CSG model")) { Undo.IncrementCurrentGroup(); var groupIndex = Undo.GetCurrentGroup(); Undo.SetCurrentGroupName("Removed hidden CSG model"); Undo.RecordObject(this, "Removed hidden CSG model"); foreach (var target in targets) { var exportedModel = target as CSGModelExported; if (!exportedModel) { continue; } exportedModel.DestroyModel(undoable: true); Undo.DestroyObjectImmediate(exportedModel); } Undo.CollapseUndoOperations(groupIndex); } GUILayout.Space(10); GUILayout.EndVertical(); }
//void OnSceneGUI() <- paints -everything- again for every selected brush public static void OnSceneGUI(SceneView sceneView) { if (EditorApplication.isPlayingOrWillChangePlaymode) { return; } /* * int prevHotControl = GUIUtility.hotControl; * int prevKeyboardControl = GUIUtility.keyboardControl; * * // make it impossible for the tool to click in the bottom bar area * int bottomBarId = GUIUtility.GetControlID (BottomBarInputHash, FocusType.Passive); * bool forceRevert = false; * //if (GUIUtility.hotControl == 0) * { * var bottomBarRect = sceneView.position; * var min = bottomBarRect.min; * var max = bottomBarRect.max; * * min.y = max.y - (GUIStyleUtility.BottomToolBarHeight + 18); * * bottomBarRect.min = min; * bottomBarRect.max = max; * * if (bottomBarRect.Contains(Event.current.mousePosition)) * { * GUIUtility.hotControl = bottomBarId; * GUIUtility.keyboardControl = bottomBarId; * forceRevert = true; * } * } */ SelectionUtility.HandleEvents(); InitTools(); HandleBuilderEvents(); //HandleYMode(); { UpdateTool(); if (instance.activeTool != null) { if (RealtimeCSG.CSGSettings.EnableRealtimeCSG) { // handle the tool var sceneSize = sceneView.position.size; var sceneRect = new Rect(0, 0, sceneSize.x, sceneSize.y - ((GUIStyleUtility.BottomToolBarHeight + 4) + 17)); //var originalEventType = Event.current.type; //if (originalEventType == EventType.MouseMove || // originalEventType == EventType.MouseUp) // holdingDownMouse = false; //var mousePos = Event.current.mousePosition; //if (originalEventType == EventType.Layout || // originalEventType == EventType.Repaint || // sceneRect.Contains(mousePos) || // holdingDownMouse) instance.activeTool.HandleEvents(sceneRect); //if (originalEventType == EventType.MouseDown || // originalEventType == EventType.MouseDrag) // holdingDownMouse = true; } else { if (Event.current.type == EventType.Repaint) { var brushes = instance.filteredSelection.BrushTargets; var wireframes = new List <GeometryWireframe>(brushes.Length); var translations = new List <Vector3>(brushes.Length); for (int i = 0; i < brushes.Length; i++) { var brush = brushes[i]; if (!brush) { continue; } var brushCache = InternalCSGModelManager.GetBrushCache(brush); if (brushCache == null || brushCache.childData == null || !brushCache.childData.Model) { continue; } var brushTranslation = brushCache.compareTransformation.modelLocalPosition + brushCache.childData.ModelTransform.position; wireframes.Add(BrushOutlineManager.GetBrushOutline(brushes[i].brushID)); translations.Add(brushTranslation); } if (wireframes.Count > 0) { CSGRenderer.DrawSelectedBrushes(instance.zTestLineMeshManager, instance.noZTestLineMeshManager, wireframes.ToArray(), translations.ToArray(), ColorSettings.SelectedOutlines, ToolConstants.thickLineScale); } MaterialUtility.LineDashMultiplier = 1.0f; MaterialUtility.LineThicknessMultiplier = 1.0f; MaterialUtility.LineAlphaMultiplier = 1.0f; instance.zTestLineMeshManager.Render(MaterialUtility.ZTestGenericLine); instance.zTestLineMeshManager.Render(MaterialUtility.ZTestGenericLine); } } } } /* * // reset the control so the bottom bar can take over * if (forceRevert) * { * GUIUtility.hotControl = prevHotControl; * GUIUtility.keyboardControl = prevKeyboardControl; * } */ int sceneWindowId = GUIUtility.GetControlID(SceneWindowHash, FocusType.Passive); var sceneWindowType = Event.current.GetTypeForControl(sceneWindowId); if (sceneWindowType == EventType.Repaint) { if (currentEditorWindows.Count > 0) { for (int i = 0; i < currentEditorWindows.Count; i++) { currentEditorWindows[i].Repaint(); } return; } } if (sceneWindowType == EventType.MouseMove) { SceneTools.IsDraggingObjectInScene = false; } if (RealtimeCSG.CSGSettings.EnableRealtimeCSG) { if (sceneView != null && sceneWindowType != EventType.Used && !SceneTools.IsDraggingObjectInScene) { if (currentEditorWindows.Count == 0) { try { Handles.BeginGUI(); Rect windowRect = new Rect(Vector2.zero, sceneView.position.size); CSGBrushEditorGUI.HandleWindowGUI(windowRect); } finally { Handles.EndGUI(); } } } } }
public static void UndoRedoPerformed() { BrushOutlineManager.ClearOutlines(); CheckForChanges(forceHierarchyUpdate: true); }
public static bool SnapToEdge(CSGBrush brush, CSGPlane?_snapPlane, Vector3 _worldPoint, out List <Vector3> outEdgePoints, out Vector3 outPosition) //, float _closestDistance = float.PositiveInfinity) { outPosition = MathConstants.zeroVector3; outEdgePoints = null; if (!brush) { return(false); } var controlMesh = brush.ControlMesh; if (controlMesh == null || Camera.current == null) { return(false); } var snapData = new SnapData(); // Find an edge to snap against the point we're interested in snapData.worldPoint = _worldPoint; snapData.guiPoint = (Vector3)HandleUtility.WorldToGUIPoint(_worldPoint); snapData.closestDistance = float.PositiveInfinity; snapData.closestDistanceSqr = float.PositiveInfinity; snapData.snapPlane = _snapPlane; snapData.outEdge = null; snapData.snappedWorldPoint = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity); var points = controlMesh.Vertices; var edges = controlMesh.Edges; var polygons = controlMesh.Polygons; var localToWorld = brush.transform.localToWorldMatrix; var worldToLocal = brush.transform.worldToLocalMatrix; for (int p = 0; p < polygons.Length; p++) { var edgeIndices = polygons[p].EdgeIndices; var indices = new List <int>(edgeIndices.Length * 2); for (int e = 0; e < edgeIndices.Length; e++) { var edgeIndex = edgeIndices[e]; if (!edges[edgeIndex].HardEdge) { continue; } var twinIndex = edges[edgeIndex].TwinIndex; var vertexIndex1 = edges[edgeIndex].VertexIndex; var vertexIndex2 = edges[twinIndex].VertexIndex; indices.Add(vertexIndex1); indices.Add(vertexIndex2); } SnapToLines(indices.ToArray(), points, localToWorld, worldToLocal, ref snapData); } var outline = BrushOutlineManager.GetBrushOutline(brush.brushID); if (outline != null) { var translation = Matrix4x4.TRS(brush.transform.position, MathConstants.identityQuaternion, MathConstants.oneVector3); var invTranslation = Matrix4x4.TRS(-brush.transform.position, MathConstants.identityQuaternion, MathConstants.oneVector3); var vertices = outline.vertices; var indices = outline.visibleInnerLines; SnapToLines(indices, vertices, translation, invTranslation, ref snapData); if ((RealtimeCSG.CSGSettings.VisibleHelperSurfaces & HelperSurfaceFlags.ShowInvisibleSurfaces) == HelperSurfaceFlags.ShowInvisibleSurfaces) { indices = outline.invisibleInnerLines; SnapToLines(indices, vertices, translation, invTranslation, ref snapData); } } if (snapData.outEdge == null || float.IsInfinity(snapData.closestDistanceSqr)) { return(false); } snapData.closestDistance = Mathf.Sqrt(snapData.closestDistanceSqr); outEdgePoints = snapData.outEdge; outPosition = snapData.snappedWorldPoint; return(true); }