public float GetClosestEdgeDistance(CSGPlane cameraPlane, int pointIndex0, int pointIndex1) { if (pointIndex0 < 0 || pointIndex0 >= WorldPoints.Length || pointIndex1 < 0 || pointIndex1 >= WorldPoints.Length) { return(float.PositiveInfinity); } var point0 = WorldPoints[pointIndex0]; var point1 = WorldPoints[pointIndex1]; var mousePoint = Event.current.mousePosition; var minDistance = CameraUtility.DistanceToLine(cameraPlane, mousePoint, point0, point1) * 3.0f; if (!(Mathf.Abs(minDistance) < 4.0f)) { return(minDistance); } var surfaceIndex1 = EdgeSurfaces[pointIndex0]; var surfaceIndex2 = EdgeSurfaces[pointIndex1]; for (var p = 0; p < PolygonCenterPoints.Length; p++) { if (p != surfaceIndex1 && p != surfaceIndex2) { continue; } var polygonCenterPoint = PolygonCenterPoints[p]; var polygonCenterPointOnLine = GeometryUtility.ProjectPointOnInfiniteLine(PolygonCenterPoints[p], point0, (point1 - point0).normalized); var direction = (polygonCenterPointOnLine - polygonCenterPoint).normalized; var nudgedPoint0 = point0 - (direction * 0.05f); var nudgedPoint1 = point1 - (direction * 0.05f); var otherDistance = CameraUtility.DistanceToLine(cameraPlane, mousePoint, nudgedPoint0, nudgedPoint1); if (otherDistance < minDistance) { minDistance = otherDistance; } } return(minDistance); }
static void SnapToLines(int[] indices, Vector3[] localVertices, Matrix4x4 localToWorld, ref SnapData snapData) { if (indices == null || localVertices == null) { return; } var worldVertex3 = MathConstants.zeroVector3; for (int i = 0; i < indices.Length; i += 2) { var index1 = indices[i + 0]; var index2 = indices[i + 1]; var worldVertex1 = localToWorld.MultiplyPoint(localVertices[index1]); var worldVertex2 = localToWorld.MultiplyPoint(localVertices[index2]); if (!SnapToLine(snapData.worldPoint, worldVertex1, worldVertex2, snapData.snapPlane, out worldVertex3)) { continue; } if (snapData.snapPlane.HasValue && Mathf.Abs(snapData.snapPlane.Value.Distance(worldVertex3)) >= MathConstants.DistanceEpsilon) { continue; } var guiVertex2 = CameraUtility.WorldToGUIPoint(worldVertex3); var guiDistance = (guiVertex2 - snapData.guiPoint).sqrMagnitude * EdgeFudgeFactor; if (guiDistance + MathConstants.DistanceEpsilon >= snapData.closestDistanceSqr) { continue; } snapData.closestDistanceSqr = guiDistance; snapData.outEdge = new List <Vector3>() { worldVertex1, worldVertex2 }; snapData.snappedWorldPoint = worldVertex3; } }
static void SnapToLines(Vector3[] worldVertices, int vertexCount, ref SnapData snapData) { if (worldVertices == null) { return; } var worldVertex3 = MathConstants.zeroVector3; for (int i = 0; i < vertexCount; i += 2) { var worldVertex1 = worldVertices[i + 0]; var worldVertex2 = worldVertices[i + 1]; if (!SnapToLine(snapData.worldPoint, worldVertex1, worldVertex2, snapData.snapPlane, out worldVertex3)) { continue; } if (snapData.snapPlane.HasValue && Mathf.Abs(snapData.snapPlane.Value.Distance(worldVertex3)) >= MathConstants.DistanceEpsilon) { continue; } var guiVertex2 = CameraUtility.WorldToGUIPoint(worldVertex3); var guiDistance = (guiVertex2 - snapData.guiPoint).sqrMagnitude * EdgeFudgeFactor; if (guiDistance + MathConstants.DistanceEpsilon >= snapData.closestDistanceSqr) { continue; } snapData.closestDistanceSqr = guiDistance; snapData.outEdge = new List <Vector3>() { worldVertex1, worldVertex2 }; snapData.snappedWorldPoint = worldVertex3; } }
// Update rectangle selection using reflection // This is hacky & dangerous // LOOK AWAY NOW! internal static void Update(SceneView sceneView) { InitReflectedData(); if (!reflectionSucceeded) { prevStartGUIPoint = new Vector2(float.PositiveInfinity, float.PositiveInfinity); prevMouseGUIPoint = prevStartGUIPoint; prevStartScreenPoint = MathConstants.zeroVector2; prevMouseScreenPoint = MathConstants.zeroVector2; rectFoundGameObjects.Clear(); return; } var s_RectSelectionID_instance = (int)s_RectSelectionID_field.GetValue(null); // check if we're rect-selecting if (GUIUtility.hotControl == s_RectSelectionID_instance) { var typeForControl = Event.current.GetTypeForControl(s_RectSelectionID_instance); if (typeForControl == EventType.Used || Event.current.commandName == "ModifierKeysChanged") { // m_RectSelection field of SceneView var m_RectSelection_instance = m_RectSelection_field.GetValue(sceneView); // m_RectSelecting field of RectSelection instance var m_RectSelecting_instance = (bool)m_RectSelecting_field.GetValue(m_RectSelection_instance); if (m_RectSelecting_instance) { // m_SelectStartPoint of RectSelection instance var m_SelectStartPoint_instance = (Vector2)m_SelectStartPoint_field.GetValue(m_RectSelection_instance); // m_SelectMousePoint of RectSelection instance var m_SelectMousePoint_instance = (Vector2)m_SelectMousePoint_field.GetValue(m_RectSelection_instance); // determine if our frustum changed since the last time bool modified = false; bool needUpdate = false; if (prevStartGUIPoint != m_SelectStartPoint_instance) { prevStartGUIPoint = m_SelectStartPoint_instance; prevStartScreenPoint = Event.current.mousePosition; needUpdate = true; } if (prevMouseGUIPoint != m_SelectMousePoint_instance) { prevMouseGUIPoint = m_SelectMousePoint_instance; prevMouseScreenPoint = Event.current.mousePosition; needUpdate = true; } if (needUpdate) { var rect = CameraUtility.PointsToRect(prevStartScreenPoint, prevMouseScreenPoint); if (rect.width > 3 && rect.height > 3) { var frustum = CameraUtility.GetCameraSubFrustumGUI(sceneView.camera, rect); // Find all the brushes (and it's gameObjects) that are in the frustum if (SceneQueryUtility.GetItemsInFrustum(frustum.Planes, rectFoundGameObjects)) { modified = true; } else { if (rectFoundGameObjects != null && rectFoundGameObjects.Count > 0) { rectFoundGameObjects.Clear(); modified = true; } } } } GameObject[] currentSelection = null; var m_LastSelection_instance = (Dictionary <GameObject, bool>)m_LastSelection_field.GetValue(m_RectSelection_instance); var m_SelectionStart_instance = (UnityEngine.Object[])m_SelectionStart_field.GetValue(m_RectSelection_instance); if (modified && rectFoundGameObjects != null && rectFoundGameObjects.Count > 0) { if (EditModeManager.ActiveTool == null) { if (EditModeManager.EditMode != ToolEditMode.Place || EditModeManager.EditMode != ToolEditMode.Edit) { EditModeManager.EditMode = ToolEditMode.Place; } } foreach (var obj in rectFoundGameObjects) { // if it hasn't already been added, add the obj if (!m_LastSelection_instance.ContainsKey(obj)) { m_LastSelection_instance.Add(obj, false); } // Remove models that we may have selected when we should be selecting it's brushes var models = obj.GetComponentsInParent <CSGModel>(includeInactive: true); var model = models.Length == 0 ? null : models[0]; if (model != null) { var modelObj = model.gameObject; if (model != null && modelObj != obj && m_LastSelection_instance.ContainsKey(modelObj) && !ArrayUtility.Contains(m_SelectionStart_instance, modelObj)) { m_LastSelection_instance.Remove(modelObj); modified = true; } } } currentSelection = m_LastSelection_instance.Keys.ToArray(); m_CurrentSelection_field.SetValue(m_RectSelection_instance, currentSelection); } for (int j = m_SelectionStart_instance.Length - 1; j >= 0; j--) { var obj = m_SelectionStart_instance[j] as GameObject; if (obj == null) { continue; } if (obj.GetComponent <GeneratedMeshInstance>() != null) { ArrayUtility.RemoveAt(ref m_SelectionStart_instance, j); m_LastSelection_instance.Remove(obj); m_SelectionStart_field.SetValue(m_RectSelection_instance, m_SelectionStart_instance); modified = true; } } if ((Event.current.commandName == "ModifierKeysChanged" || modified)) { if (currentSelection == null || modified) { currentSelection = m_LastSelection_instance.Keys.ToArray(); } var foundObjects = currentSelection; for (int j = foundObjects.Length - 1; j >= 0; j--) { var obj = foundObjects[j]; if (obj == null || obj.GetComponent <GeneratedMeshInstance>() != null) { ArrayUtility.RemoveAt(ref foundObjects, j); m_LastSelection_instance.Remove(obj); m_SelectionStart_field.SetValue(m_RectSelection_instance, m_SelectionStart_instance); } } var selectionTypeNormal = SelectionType_Normal; if (Event.current.shift) { selectionTypeNormal = SelectionType_Additive; } else if (EditorGUI.actionKey) { selectionTypeNormal = SelectionType_Subtractive; } // calling static method UpdateSelection of RectSelection UpdateSelection_method.Invoke(null, new object[] { m_SelectionStart_instance, foundObjects, selectionTypeNormal, m_RectSelecting_instance }); } } } } if (GUIUtility.hotControl != s_RectSelectionID_instance) { prevStartGUIPoint = MathConstants.zeroVector2; prevMouseGUIPoint = MathConstants.zeroVector2; rectFoundGameObjects.Clear(); } var eventType = Event.current.GetTypeForControl(s_RectSelectionID_instance); var hotControl = GUIUtility.hotControl; if (hotControl == s_RectSelectionID_instance && EditModeManager.ActiveTool.IgnoreUnityRect) { hotControl = 0; GUIUtility.hotControl = 0; } switch (eventType) { case EventType.MouseDown: { rectClickDown = (Event.current.button == 0 && hotControl == s_RectSelectionID_instance); clickMousePosition = Event.current.mousePosition; mouseDragged = false; break; } case EventType.MouseUp: { rectClickDown = false; break; } case EventType.MouseMove: { rectClickDown = false; break; } case EventType.Used: { if (clickMousePosition != Event.current.mousePosition) { mouseDragged = true; } if (!mouseDragged && rectClickDown && Event.current.button == 0) { // m_RectSelection field of SceneView var m_RectSelection_instance = m_RectSelection_field.GetValue(sceneView); var m_RectSelecting_instance = (bool)m_RectSelecting_field.GetValue(m_RectSelection_instance); if (!m_RectSelecting_instance) { // make sure GeneratedMeshes are not part of our selection if (Selection.gameObjects != null) { var selectedObjects = Selection.objects; var foundObjects = new List <UnityEngine.Object>(); foreach (var obj in selectedObjects) { var component = obj as Component; var gameObject = obj as GameObject; var transform = obj as Transform; if (!(component && component.GetComponent <GeneratedMeshes>()) && !(gameObject && gameObject.GetComponent <GeneratedMeshes>()) && !(transform && transform.GetComponent <Transform>())) { foundObjects.Add(obj); } } if (foundObjects.Count != selectedObjects.Length) { Selection.objects = foundObjects.ToArray(); } } SelectionUtility.DoSelectionClick(sceneView); Event.current.Use(); } } rectClickDown = false; break; } case EventType.ValidateCommand: { if (Event.current.commandName == "SelectAll") { Event.current.Use(); break; } if (Keys.HandleSceneValidate(EditModeManager.CurrentTool, true)) { Event.current.Use(); HandleUtility.Repaint(); } break; } case EventType.ExecuteCommand: { if (Event.current.commandName == "SelectAll") { var transforms = new List <UnityEngine.Object>(); for (int sceneIndex = 0; sceneIndex < SceneManager.sceneCount; sceneIndex++) { var scene = SceneManager.GetSceneAt(sceneIndex); foreach (var gameObject in scene.GetRootGameObjects()) { foreach (var transform in gameObject.GetComponentsInChildren <Transform>()) { if ((transform.hideFlags & (HideFlags.NotEditable | HideFlags.HideInHierarchy)) == (HideFlags.NotEditable | HideFlags.HideInHierarchy)) { continue; } transforms.Add(transform.gameObject); } } } Selection.objects = transforms.ToArray(); Event.current.Use(); break; } break; } case EventType.KeyDown: { if (Keys.HandleSceneKeyDown(EditModeManager.CurrentTool, true)) { Event.current.Use(); HandleUtility.Repaint(); } break; } case EventType.KeyUp: { if (Keys.HandleSceneKeyUp(EditModeManager.CurrentTool, true)) { Event.current.Use(); HandleUtility.Repaint(); } break; } } }
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); }
public static bool SnapToLine(Vector3 worldPoint, Vector3 worldVertex1, Vector3 worldVertex2, CSGPlane?snapPlane, out Vector3 worldSnappedPoint) { var localGridPoint = RealtimeCSG.CSGGrid.PointToGridSpace(worldPoint); var localVertex1 = RealtimeCSG.CSGGrid.PointToGridSpace(worldVertex1); var localVertex2 = RealtimeCSG.CSGGrid.PointToGridSpace(worldVertex2); var snapVector = RealtimeCSG.CSGGrid.gridOrientation.gridSnapVector; float minx = Mathf.Min(localVertex1.x, localVertex2.x); float maxx = Mathf.Max(localVertex1.x, localVertex2.x); float miny = Mathf.Min(localVertex1.y, localVertex2.y); float maxy = Mathf.Max(localVertex1.y, localVertex2.y); float minz = Mathf.Min(localVertex1.z, localVertex2.z); float maxz = Mathf.Max(localVertex1.z, localVertex2.z); var localLengthX = (maxx - minx); var localLengthY = (maxy - miny); var localLengthZ = (maxz - minz); if (localLengthX < MathConstants.AlignmentTestEpsilon && localLengthY < MathConstants.AlignmentTestEpsilon && localLengthZ < MathConstants.AlignmentTestEpsilon) { worldSnappedPoint = worldPoint; return(false); } found_points = new Vector3[6]; var point_count = 0; if (localLengthX > MathConstants.AlignmentTestEpsilon) { float xv = localGridPoint.x / snapVector.x; float x1 = Mathf.Floor(xv) * snapVector.x; if (x1 > minx && x1 < maxx) { var xpos = x1; var t = (xpos - minx) / localLengthX; if (t > 0 && t < 1.0f) { var ypos = localVertex1.y + (t * (localVertex2.y - localVertex1.y)); var zpos = localVertex1.z + (t * (localVertex2.z - localVertex1.z)); var worldIntersection = RealtimeCSG.CSGGrid.PointFromGridSpace(new Vector3(xpos, ypos, zpos)); if (snapPlane.HasValue) { worldIntersection = snapPlane.Value.Project(worldIntersection); } var dist = CameraUtility.DistancePointLine(worldIntersection, worldVertex1, worldVertex2); if (dist < MathConstants.DistanceEpsilon) { found_points[point_count] = worldIntersection; point_count++; } } } float x2 = Mathf.Ceil(xv) * snapVector.x; if (x2 > minx && x2 < maxx) { var xpos = x2; var t = (xpos - minx) / localLengthX; if (t > 0 && t < 1.0f) { var ypos = localVertex1.y + (t * (localVertex2.y - localVertex1.y)); var zpos = localVertex1.z + (t * (localVertex2.z - localVertex1.z)); var worldIntersection = RealtimeCSG.CSGGrid.PointFromGridSpace(new Vector3(xpos, ypos, zpos)); if (snapPlane.HasValue) { worldIntersection = snapPlane.Value.Project(worldIntersection); } var dist = CameraUtility.DistancePointLine(worldIntersection, worldVertex1, worldVertex2); if (dist < MathConstants.DistanceEpsilon) { found_points[point_count] = worldIntersection; point_count++; } } } } if (localLengthY > MathConstants.AlignmentTestEpsilon) { float yv = localGridPoint.y / snapVector.y; float y1 = Mathf.Floor(yv) * snapVector.y; if (y1 > miny && y1 < maxy) { var ypos = y1; var t = (ypos - miny) / localLengthY; if (t > 0 && t < 1.0f) { var zpos = localVertex1.z + (t * localLengthZ); var xpos = localVertex1.x + (t * localLengthX); var worldIntersection = RealtimeCSG.CSGGrid.PointFromGridSpace(new Vector3(xpos, ypos, zpos)); if (snapPlane.HasValue) { worldIntersection = snapPlane.Value.Project(worldIntersection); } var dist = CameraUtility.DistancePointLine(worldIntersection, worldVertex1, worldVertex2); if (dist < MathConstants.DistanceEpsilon) { found_points[point_count] = worldIntersection; point_count++; } } } float y2 = Mathf.Ceil(yv) * snapVector.y; if (y2 > miny && y2 < maxy) { var ypos = y2; var t = (ypos - miny) / localLengthY; if (t > 0 && t < 1.0f) { var zpos = localVertex1.z + (t * localLengthZ); var xpos = localVertex1.x + (t * localLengthX); var worldIntersection = RealtimeCSG.CSGGrid.PointFromGridSpace(new Vector3(xpos, ypos, zpos)); if (snapPlane.HasValue) { worldIntersection = snapPlane.Value.Project(worldIntersection); } var dist = CameraUtility.DistancePointLine(worldIntersection, worldVertex1, worldVertex2); if (dist < MathConstants.DistanceEpsilon) { found_points[point_count] = worldIntersection; point_count++; } } } } if (localLengthZ > MathConstants.AlignmentTestEpsilon) { float zv = localGridPoint.z / snapVector.z; float z1 = Mathf.Floor(zv) * snapVector.z; if (z1 > minz && z1 < maxz) { var zpos = z1; var t = (zpos - minz) / localLengthZ; if (t > 0 && t < 1.0f) { var xpos = localVertex1.x + (t * (localVertex2.x - localVertex1.x)); var ypos = localVertex1.y + (t * (localVertex2.y - localVertex1.y)); var worldIntersection = RealtimeCSG.CSGGrid.PointFromGridSpace(new Vector3(xpos, ypos, zpos)); if (snapPlane.HasValue) { worldIntersection = snapPlane.Value.Project(worldIntersection); } var dist = CameraUtility.DistancePointLine(worldIntersection, worldVertex1, worldVertex2); if (dist < MathConstants.DistanceEpsilon) { found_points[point_count] = worldIntersection; point_count++; } } } float z2 = Mathf.Ceil(zv) * snapVector.z; if (z2 > minz && z2 < maxz) { var zpos = z2; var t = (zpos - minz) / localLengthZ; if (t > 0 && t < 1.0f) { var xpos = localVertex1.x + (t * (localVertex2.x - localVertex1.x)); var ypos = localVertex1.y + (t * (localVertex2.y - localVertex1.y)); var worldIntersection = RealtimeCSG.CSGGrid.PointFromGridSpace(new Vector3(xpos, ypos, zpos)); if (snapPlane.HasValue) { worldIntersection = snapPlane.Value.Project(worldIntersection); } var dist = CameraUtility.DistancePointLine(worldIntersection, worldVertex1, worldVertex2); if (dist < MathConstants.DistanceEpsilon) { found_points[point_count] = worldIntersection; point_count++; } } } } if (point_count == 0) { worldSnappedPoint = MathConstants.zeroVector3; return(false); } if (point_count == 1) { worldSnappedPoint = found_points[0]; return(true); } float found_dist = (found_points[0] - worldPoint).sqrMagnitude; int found_index = 0; for (int i = 1; i < point_count; i++) { float dist = (found_points[i] - worldPoint).sqrMagnitude; if (found_dist > dist) { found_dist = dist; found_index = i; } } worldSnappedPoint = found_points[found_index]; return(true); }
public static Vector3 SnapToWorld(Camera camera, CSGPlane snapPlane, Vector3 unsnappedPosition, Vector3 snappedPosition, ref List <Vector3> snappingEdges, out CSGBrush snappedOnBrush, CSGBrush[] ignoreBrushes = null) { snappedOnBrush = null; test_points[0] = unsnappedPosition; test_points[1] = snappedPosition; worldIntersections.Clear(); for (int i = 0; i < test_points.Length; i++) { var test_point2D = CameraUtility.WorldToGUIPoint(test_points[i]); LegacyBrushIntersection intersection; if (SceneQueryUtility.FindWorldIntersection(camera, test_point2D, out intersection)) { if (intersection.brush && intersection.brush.ControlMesh != null) { intersection.worldIntersection = GeometryUtility.ProjectPointOnPlane(snapPlane, intersection.worldIntersection); worldIntersections.Add(intersection); } } } var old_difference = snappedPosition - unsnappedPosition; var old_difference_magnitude = old_difference.magnitude * 1.5f; Vector3 newSnappedPoint = snappedPosition; CSGPlane?snappingPlane = snapPlane; for (int i = 0; i < worldIntersections.Count; i++) { if (ignoreBrushes != null && ArrayUtility.Contains(ignoreBrushes, worldIntersections[i].brush)) { continue; } List <Vector3> outEdgePoints; Vector3 outPosition; if (GridUtility.SnapToVertices(worldIntersections[i].brush, snappingPlane, unsnappedPosition, out outEdgePoints, out outPosition)) { var new_difference = outPosition - unsnappedPosition; var new_difference_magnitude = new_difference.magnitude; if (new_difference_magnitude <= old_difference_magnitude + MathConstants.EqualityEpsilon) { old_difference_magnitude = new_difference_magnitude; newSnappedPoint = outPosition; snappingEdges = outEdgePoints; snappedOnBrush = worldIntersections[i].brush; } } if (GridUtility.SnapToEdge(camera, worldIntersections[i].brush, snappingPlane ?? worldIntersections[i].worldPlane, worldIntersections[i].worldIntersection, out outEdgePoints, out outPosition)) { var new_difference = outPosition - unsnappedPosition; var new_difference_magnitude = new_difference.magnitude * 1.1f; if (new_difference_magnitude <= old_difference_magnitude + MathConstants.EqualityEpsilon) { old_difference_magnitude = new_difference_magnitude; newSnappedPoint = outPosition; snappingEdges = outEdgePoints; snappedOnBrush = worldIntersections[i].brush; } } } //snappingEdges = FindAllEdgesThatTouchPoint(snappedOnBrush, newSnappedPoint); return(newSnappedPoint); }
// static Rect? currentMarqueRect = null; // Update rectangle selection using reflection // This is hacky, dangerous & the only way to do this .. static void UpdateRectSelection(SceneView sceneView, int s_RectSelectionID_instance) { if (!reflectionSucceeded) { // currentMarqueRect = null; prevStartGUIPoint = new Vector2(float.PositiveInfinity, float.PositiveInfinity); prevMouseGUIPoint = prevStartGUIPoint; prevStartScreenPoint = MathConstants.zeroVector2; prevMouseScreenPoint = MathConstants.zeroVector2; rectFoundGameObjects.Clear(); return; } // check if we're rect-selecting if (GUIUtility.hotControl == s_RectSelectionID_instance) { var typeForControl = Event.current.GetTypeForControl(s_RectSelectionID_instance); if (typeForControl == EventType.Used || Event.current.commandName == "ModifierKeysChanged") { // m_RectSelection field of SceneView var m_RectSelection_instance = m_RectSelection_field.GetValue(sceneView); // m_RectSelecting field of RectSelection instance var m_RectSelecting_instance = (bool)m_RectSelecting_field.GetValue(m_RectSelection_instance); if (m_RectSelecting_instance) { // m_SelectStartPoint of RectSelection instance var m_SelectStartPoint_instance = (Vector2)m_SelectStartPoint_field.GetValue(m_RectSelection_instance); // m_SelectMousePoint of RectSelection instance var m_SelectMousePoint_instance = (Vector2)m_SelectMousePoint_field.GetValue(m_RectSelection_instance); // determine if our frustum changed since the last time bool modified = false; bool needUpdate = false; if (prevStartGUIPoint != m_SelectStartPoint_instance) { prevStartGUIPoint = m_SelectStartPoint_instance; prevStartScreenPoint = Event.current.mousePosition; needUpdate = true; } if (prevMouseGUIPoint != m_SelectMousePoint_instance) { prevMouseGUIPoint = m_SelectMousePoint_instance; prevMouseScreenPoint = Event.current.mousePosition; needUpdate = true; } if (needUpdate) { //var rect = CameraUtility.PointsToRect(prevStartGUIPoint, prevMouseGUIPoint); //var frustum = CameraUtility.GetCameraSubFrustumGUI(Camera.current, rect); var rect = CameraUtility.PointsToRect(prevStartScreenPoint, prevMouseScreenPoint); if (rect.width > 3 && rect.height > 3) { var frustum = CameraUtility.GetCameraSubFrustumGUI(Camera.current, rect); // currentMarqueRect = rect; // Find all the brushes (and it's gameObjects) that are in the frustum if (SceneQueryUtility.GetItemsInFrustum(frustum.Planes, rectFoundGameObjects)) { modified = true; } else { if (rectFoundGameObjects != null && rectFoundGameObjects.Count > 0) { rectFoundGameObjects.Clear(); modified = true; } } } } GameObject[] currentSelection = null; var m_LastSelection_instance = (Dictionary <GameObject, bool>)m_LastSelection_field.GetValue(m_RectSelection_instance); var m_SelectionStart_instance = (UnityEngine.Object[])m_SelectionStart_field.GetValue(m_RectSelection_instance); if (modified && rectFoundGameObjects != null && rectFoundGameObjects.Count > 0) { if (CSGBrushEditorManager.ActiveTool == null) { if (CSGBrushEditorManager.EditMode != ToolEditMode.Object || CSGBrushEditorManager.EditMode != ToolEditMode.Mesh) { CSGBrushEditorManager.EditMode = ToolEditMode.Object; } } foreach (var obj in rectFoundGameObjects) { // if it hasn't already been added, add the obj if (!m_LastSelection_instance.ContainsKey(obj)) { m_LastSelection_instance.Add(obj, false); } // Remove models that we may have selected when we should be selecting it's brushes var model = obj.GetComponentInParent <CSGModel>(); if (model != null) { var modelObj = model.gameObject; if (model != null && modelObj != obj && m_LastSelection_instance.ContainsKey(modelObj) && !ArrayUtility.Contains(m_SelectionStart_instance, modelObj)) { m_LastSelection_instance.Remove(modelObj); modified = true; } } } currentSelection = m_LastSelection_instance.Keys.ToArray(); m_CurrentSelection_field.SetValue(m_RectSelection_instance, currentSelection); } for (int j = m_SelectionStart_instance.Length - 1; j >= 0; j--) { var obj = m_SelectionStart_instance[j] as GameObject; if (obj == null) { continue; } if (obj.GetComponent <GeneratedMeshInstance>() != null) { ArrayUtility.RemoveAt(ref m_SelectionStart_instance, j); m_LastSelection_instance.Remove(obj); m_SelectionStart_field.SetValue(m_RectSelection_instance, m_SelectionStart_instance); modified = true; } } if ( //(rectFoundGameObjects != null && rectFoundGameObjects.Length > 0) && (Event.current.commandName == "ModifierKeysChanged" || modified)) { if (currentSelection == null || modified) { currentSelection = m_LastSelection_instance.Keys.ToArray(); } var foundObjects = currentSelection; for (int j = foundObjects.Length - 1; j >= 0; j--) { var obj = foundObjects[j]; if (obj == null || obj.GetComponent <GeneratedMeshInstance>() != null) { ArrayUtility.RemoveAt(ref foundObjects, j); m_LastSelection_instance.Remove(obj); m_SelectionStart_field.SetValue(m_RectSelection_instance, m_SelectionStart_instance); } } var selectionTypeNormal = SelectionType_Normal; if (Event.current.shift) { selectionTypeNormal = SelectionType_Additive; } else if (EditorGUI.actionKey) { selectionTypeNormal = SelectionType_Subtractive; } // calling static method UpdateSelection of RectSelection UpdateSelection_method.Invoke(null, new object[] { m_SelectionStart_instance, foundObjects, selectionTypeNormal, m_RectSelecting_instance }); } } } } if (GUIUtility.hotControl != s_RectSelectionID_instance) { prevStartGUIPoint = MathConstants.zeroVector2; prevMouseGUIPoint = MathConstants.zeroVector2; rectFoundGameObjects.Clear(); // currentMarqueRect = null; } }