Example #1
0
        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);
        }
Example #2
0
        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;
            }
        }
Example #3
0
        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();
                        }
                    }
                }
            }
        }
Example #6
0
        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);
        }
Example #7
0
        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);
        }
Example #8
0
        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);
        }
Example #9
0
        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);
        }
Example #10
0
//		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;
            }
        }