Exemplo n.º 1
0
        public static bool IntersectsWithShapePolygon(ShapePolygon shapePolygon, CSGPlane polygonPlane, Ray ray)
        {
            var intersection = polygonPlane.Intersection(ray);
            var vertices     = shapePolygon.Vertices;

            for (int v0 = vertices.Length - 1, v1 = 0; v1 < vertices.Length; v0 = v1, v1++)
            {
                var vertex0 = vertices[v0];
                var vertex1 = vertices[v1];
                var delta   = (vertex1 - vertex0);
                var length  = delta.sqrMagnitude;
                if (length <= MathConstants.EqualityEpsilonSqr)
                {
                    continue;
                }

                var tangent = delta / Mathf.Sqrt(length);
                var normal  = Vector3.Cross(polygonPlane.normal, tangent);
                var plane   = new CSGPlane(normal, vertex0);
                if (plane.Distance(intersection) < MathConstants.DistanceEpsilon)
                {
                    return(false);
                }
            }
            return(true);
        }
        public static float DistanceToLine(CSGPlane cameraPlane, Vector2 mousePoint, Vector3 point1, Vector3 point2)
        {
            var dist1 = cameraPlane.Distance(point1);
            var dist2 = cameraPlane.Distance(point2);

            if (dist1 < 0 && dist2 > 0)
            {
                point1 = cameraPlane.Intersection(point1, point2);
            }
            else
            if (dist2 < 0 && dist1 > 0)
            {
                point2 = cameraPlane.Intersection(point1, point2);
            }

            return(DistanceToLine(mousePoint, point1, point2) * 0.5f);
        }
        Vector3 GetHeightHandlePosition(Vector3 point)
        {
            var mouseRay      = HandleUtility.GUIPointToWorldRay(heightPosition);
            var alignedPlane  = new CSGPlane(Camera.current.transform.forward, point);
            var planePosition = alignedPlane.Intersection(mouseRay);                  // buildPlane.Project() - grabOffset;
            var worldPosition = GeometryUtility.ProjectPointOnInfiniteLine(planePosition, brushPosition, movePolygonDirection);

            return(worldPosition);
        }
Exemplo n.º 4
0
        public static Vector3 CubeProject(CSGPlane plane, Vector3 pos)
        {
            UpdateGridOrientation();
            var closest_axis = GeometryUtility.SnapToClosestAxis(plane.normal);
            var intersection = plane.Intersection(pos, pos + closest_axis);

            if (float.IsNaN(intersection.x) || float.IsInfinity(intersection.x) ||
                float.IsNaN(intersection.y) || float.IsInfinity(intersection.y) ||
                float.IsNaN(intersection.z) || float.IsInfinity(intersection.z))
            {
                // should never happen, but if all else fails just do a projection ..
                intersection = plane.Project(pos);
            }
            return(intersection);
        }
Exemplo n.º 5
0
        protected override void HandleEditShapeEvents(Rect sceneRect)
        {
            if (settings.vertices.Length < 2)
            {
                if (editMode == EditMode.ExtrudeShape ||
                    editMode == EditMode.EditShape)
                {
                    editMode = EditMode.CreatePlane;
                }
            }

            if (!SceneDragToolManager.IsDraggingObjectInScene &&
                Event.current.type == EventType.Repaint)
            {
                if (visualSnappedEdges != null)
                {
                    PaintUtility.DrawLines(visualSnappedEdges.ToArray(), ToolConstants.oldThickLineScale, ColorSettings.SnappedEdges);
                }

                if (visualSnappedGrid != null)
                {
                    var _origMatrix = Handles.matrix;
                    Handles.matrix = MathConstants.identityMatrix;
                    PaintUtility.DrawDottedLines(visualSnappedGrid.ToArray(), ColorSettings.SnappedEdges);
                    Handles.matrix = _origMatrix;
                }

                if (visualSnappedBrush != null)
                {
                    var brush_cache = InternalCSGModelManager.GetBrushCache(visualSnappedBrush);
                    if (brush_cache != null &&
                        brush_cache.compareTransformation != null &&
                        brush_cache.childData != null &&
                        brush_cache.childData.ModelTransform != null &&
                        brush_cache.childData.ModelTransform)
                    {
                        var brush_translation = brush_cache.compareTransformation.modelLocalPosition + brush_cache.childData.ModelTransform.position;
                        CSGRenderer.DrawOutlines(visualSnappedBrush.brushID, brush_translation, ColorSettings.SelectedOutlines, ColorSettings.SelectedOutlines, ColorSettings.SelectedOutlines, ColorSettings.SelectedOutlines);
                    }
                }

                var origMatrix = Handles.matrix;
                Handles.matrix = MathConstants.identityMatrix;
                PaintBounds();
                Handles.matrix = origMatrix;
            }

            HandleHeightHandles(sceneRect, false);

            for (int i = 0; i < settings.vertices.Length; i++)
            {
                var id         = settings.vertexIDs[i];
                var point_type = Event.current.GetTypeForControl(id);
                switch (point_type)
                {
                case EventType.Repaint:
                {
                    if (SceneDragToolManager.IsDraggingObjectInScene)
                    {
                        break;
                    }

                    bool isSelected = id == GUIUtility.keyboardControl;
                    var  temp       = Handles.color;
                    var  origMatrix = Handles.matrix;

                    Handles.matrix = MathConstants.identityMatrix;
                    var rotation = Camera.current.transform.rotation;


                    if (isSelected)
                    {
                        Handles.color = ColorSettings.PointInnerStateColor[3];
                    }
                    else
                    if (HandleUtility.nearestControl == id)
                    {
                        Handles.color = ColorSettings.PointInnerStateColor[1];
                    }
                    else
                    {
                        Handles.color = ColorSettings.PointInnerStateColor[0];
                    }

                    float handleSize       = CSG_HandleUtility.GetHandleSize(settings.vertices[i]);
                    float scaledHandleSize = handleSize * ToolConstants.handleScale;
                    PaintUtility.SquareDotCap(id, settings.vertices[i], rotation, scaledHandleSize);

                    Handles.matrix = origMatrix;
                    Handles.color  = temp;
                    break;
                }

                case EventType.Layout:
                {
                    if ((Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan))
                    {
                        break;
                    }

                    var origMatrix = Handles.matrix;
                    Handles.matrix = MathConstants.identityMatrix;
                    float handleSize       = CSG_HandleUtility.GetHandleSize(settings.vertices[i]);
                    float scaledHandleSize = handleSize * ToolConstants.handleScale;
                    HandleUtility.AddControl(id, HandleUtility.DistanceToCircle(settings.vertices[i], scaledHandleSize));
                    Handles.matrix = origMatrix;

                    break;
                }

                case EventType.ValidateCommand:
                case EventType.KeyDown:
                {
                    if (GUIUtility.hotControl == id)
                    {
                        if (Keys.CancelActionKey.IsKeyPressed())
                        {
                            Event.current.Use();
                            break;
                        }
                    }
                    break;
                }

                case EventType.KeyUp:
                {
                    if (GUIUtility.hotControl == id)
                    {
                        if (Keys.CancelActionKey.IsKeyPressed())
                        {
                            GUIUtility.hotControl             = 0;
                            GUIUtility.keyboardControl        = 0;
                            EditorGUIUtility.editingTextField = false;
                            Event.current.Use();
                            break;
                        }
                    }
                    break;
                }

                case EventType.MouseDown:
                {
                    if (!sceneRect.Contains(Event.current.mousePosition))
                    {
                        break;
                    }
                    if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                    {
                        break;
                    }
                    if (GUIUtility.hotControl == 0 && HandleUtility.nearestControl == id && Event.current.button == 0)
                    {
                        GUIUtility.hotControl             = id;
                        GUIUtility.keyboardControl        = id;
                        EditorGUIUtility.editingTextField = false;
                        EditorGUIUtility.SetWantsMouseJumping(1);
                        Event.current.Use();
                        break;
                    }
                    break;
                }

                case EventType.MouseDrag:
                {
                    if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                    {
                        break;
                    }
                    if (GUIUtility.hotControl == id && Event.current.button == 0)
                    {
                        Undo.RecordObject(this, "Modify shape");

                        var mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                        RealtimeCSG.CSGGrid.SetForcedGrid(buildPlane);
                        var alignedPlane  = new CSGPlane(RealtimeCSG.CSGGrid.CurrentWorkGridPlane.normal, settings.vertices[0]);
                        var worldPosition = buildPlane.Project(alignedPlane.Intersection(mouseRay));
                        if (float.IsInfinity(worldPosition.x) || float.IsNaN(worldPosition.x) ||
                            float.IsInfinity(worldPosition.y) || float.IsNaN(worldPosition.y) ||
                            float.IsInfinity(worldPosition.z) || float.IsNaN(worldPosition.z))
                        {
                            worldPosition = settings.vertices[i];
                        }

                        ResetVisuals();
                        if (snapFunction != null)
                        {
                            CSGBrush snappedOnBrush;
                            worldPosition = snapFunction(worldPosition, buildPlane, ref base.visualSnappedEdges, out snappedOnBrush, generatedBrushes);
                        }

                        base.visualSnappedGrid = RealtimeCSG.CSGGrid.FindAllGridEdgesThatTouchPoint(worldPosition);

                        settings.vertices[i] = worldPosition;

                        CenterExtrusionPoints(buildPlane);
                        UpdateBaseShape();

                        if (editMode == EditMode.ExtrudeShape)
                        {
                            StartExtrudeMode();
                            UpdateBaseShape();
                        }
                        UpdateExtrudedShape();

                        GUI.changed = true;
                        Event.current.Use();
                        break;
                    }
                    break;
                }

                case EventType.MouseUp:
                {
                    if (GUIUtility.hotControl != id)
                    {
                        break;
                    }
                    if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                    {
                        break;
                    }
                    if (Event.current.button == 0)
                    {
                        GUIUtility.hotControl             = 0;
                        GUIUtility.keyboardControl        = 0;
                        EditorGUIUtility.editingTextField = false;
                        EditorGUIUtility.SetWantsMouseJumping(0);
                        Event.current.Use();

                        ResetVisuals();
                        //if (Length == 0 || Width == 0)
                        //{
                        //	Cancel();
                        //}
                        break;
                    }
                    break;
                }
                }
            }
        }
Exemplo n.º 6
0
        protected override void HandleCreateShapeEvents(Rect sceneRect)
        {
            if (settings.vertices.Length < 2)
            {
                if (editMode == EditMode.ExtrudeShape ||
                    editMode == EditMode.EditShape)
                {
                    editMode = EditMode.CreatePlane;
                }
            }

            bool     pointOnEdge      = false;
            bool     havePlane        = false;
            bool     vertexOnGeometry = false;
            CSGBrush vertexOnBrush    = null;

            CSGPlane hoverBuildPlane = buildPlane;
            var      sceneView       = SceneView.currentDrawingSceneView; //(SceneView.currentDrawingSceneView != null) ? SceneView.currentDrawingSceneView : SceneView.lastActiveSceneView;
            var      camera          = (sceneView == null) ? null : sceneView.camera;

            if (camera != null &&
                camera.pixelRect.Contains(Event.current.mousePosition))
            {
                if (!hoverDefaultPlane.HasValue ||
                    settings.vertices.Length == 0)
                {
                    bool forceGrid = RealtimeCSG.CSGGrid.ForceGrid;
                    RealtimeCSG.CSGGrid.ForceGrid = false;
                    hoverDefaultPlane             = RealtimeCSG.CSGGrid.CurrentGridPlane;
                    RealtimeCSG.CSGGrid.ForceGrid = forceGrid;
                    firstSnappedEdges             = null;
                    firstSnappedBrush             = null;
                    firstSnappedPlanes            = null;
                    base.geometryModel            = null;
                }
                if (editMode == EditMode.CreatePlane)
                {
                    BrushIntersection intersection;
                    if (!IgnoreDepthForRayCasts(sceneView) && !havePlane &&
                        SceneQueryUtility.FindWorldIntersection(Event.current.mousePosition, out intersection))
                    {
                        worldPosition = intersection.worldIntersection;
                        if (intersection.surfaceInverted)
                        {
                            hoverBuildPlane = intersection.plane.Negated();
                        }
                        else
                        {
                            hoverBuildPlane = intersection.plane;
                        }
                        vertexOnBrush = intersection.brush;

                        vertexOnGeometry = true;
                    }
                    else
                    {
                        hoverBuildPlane = hoverDefaultPlane.Value;
                        vertexOnBrush   = null;

                        var mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                        worldPosition    = hoverBuildPlane.Intersection(mouseRay);
                        vertexOnGeometry = false;
                    }

                    ResetVisuals();
                    if (snapFunction != null)
                    {
                        CSGBrush snappedOnBrush;
                        worldPosition = snapFunction(worldPosition, hoverBuildPlane, ref visualSnappedEdges, out snappedOnBrush, generatedBrushes);
                        if (snappedOnBrush != null)
                        {
                            pointOnEdge = (visualSnappedEdges != null &&
                                           visualSnappedEdges.Count > 0);
                            vertexOnBrush    = snappedOnBrush;
                            vertexOnGeometry = true;
                        }
                    }

                    if (settings.vertices.Length == 1)
                    {
                        if (hoverBuildPlane.normal != MathConstants.zeroVector3)
                        {
                            editMode  = EditMode.CreateShape;
                            havePlane = true;
                        }
                    }
                    else
                    if (settings.vertices.Length == 2)
                    {
                        onLastPoint = true;
                    }
                }
                else
                {
                    var mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                    worldPosition = hoverBuildPlane.Intersection(mouseRay);

                    ResetVisuals();
                    if (snapFunction != null)
                    {
                        CSGBrush snappedOnBrush;
                        worldPosition = snapFunction(worldPosition, hoverBuildPlane, ref visualSnappedEdges, out snappedOnBrush, generatedBrushes);
                        if (snappedOnBrush != null)
                        {
                            pointOnEdge = (visualSnappedEdges != null &&
                                           visualSnappedEdges.Count > 0);
                            vertexOnBrush = snappedOnBrush;
                        }
                    }
                }

                if (geometryModel == null && vertexOnBrush != null)
                {
                    var brush_cache = InternalCSGModelManager.GetBrushCache(vertexOnBrush);
                    if (brush_cache != null && brush_cache.childData != null && brush_cache.childData.Model)
                    {
                        geometryModel = brush_cache.childData.Model;
                    }
                }

                if (worldPosition != prevWorldPosition)
                {
                    prevWorldPosition = worldPosition;
                    if (Event.current.type != EventType.Repaint)
                    {
                        SceneView.RepaintAll();
                    }
                }

                visualSnappedGrid  = RealtimeCSG.CSGGrid.FindAllGridEdgesThatTouchPoint(worldPosition);
                visualSnappedBrush = vertexOnBrush;
            }

            RealtimeCSG.CSGGrid.SetForcedGrid(hoverBuildPlane);


            if (!SceneDragToolManager.IsDraggingObjectInScene &&
                Event.current.type == EventType.Repaint)
            {
                PaintSnapVisualisation();
                PaintShape(base.shapeId);
            }


            var type = Event.current.GetTypeForControl(base.shapeId);

            switch (type)
            {
            case EventType.Layout:
            {
                return;
            }

            case EventType.ValidateCommand:
            case EventType.KeyDown:
            {
                if (GUIUtility.hotControl == base.shapeId)
                {
                    if (Keys.PerformActionKey.IsKeyPressed() ||
                        Keys.DeleteSelectionKey.IsKeyPressed() ||
                        Keys.CancelActionKey.IsKeyPressed())
                    {
                        Event.current.Use();
                    }
                }
                return;
            }

            case EventType.KeyUp:
            {
                if (GUIUtility.hotControl == base.shapeId)
                {
                    if (Keys.BoxBuilderMode.IsKeyPressed() ||
                        Keys.PerformActionKey.IsKeyPressed())
                    {
                        HotKeyReleased();
                        Event.current.Use();
                        return;
                    }
                    if (Keys.DeleteSelectionKey.IsKeyPressed() ||
                        Keys.CancelActionKey.IsKeyPressed())
                    {
                        Cancel();
                        Event.current.Use();
                        return;
                    }
                }
                return;
            }

            case EventType.MouseDown:
            {
                if (!sceneRect.Contains(Event.current.mousePosition))
                {
                    break;
                }
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    return;
                }
                if ((GUIUtility.hotControl != 0 && GUIUtility.hotControl != shapeEditId && GUIUtility.hotControl != base.shapeId) ||
                    Event.current.button != 0)
                {
                    return;
                }

                Event.current.Use();
                if (settings.vertices.Length == 0)
                {
                    if ((GUIUtility.hotControl == 0 ||
                         GUIUtility.hotControl == base.shapeEditId) && base.shapeId != -1)
                    {
                        base.CalculateWorldSpaceTangents();
                        GUIUtility.hotControl             = base.shapeId;
                        GUIUtility.keyboardControl        = base.shapeId;
                        EditorGUIUtility.editingTextField = false;
                    }
                }

                if (GUIUtility.hotControl == base.shapeId && settings.vertices.Length < 2)
                {
                    if (!float.IsNaN(worldPosition.x) && !float.IsInfinity(worldPosition.x) &&
                        !float.IsNaN(worldPosition.y) && !float.IsInfinity(worldPosition.y) &&
                        !float.IsNaN(worldPosition.z) && !float.IsInfinity(worldPosition.z))
                    {
                        if (hoverBuildPlane.normal.sqrMagnitude != 0)
                        {
                            buildPlane = hoverBuildPlane;
                        }
                        CalculateWorldSpaceTangents();

                        if (settings.vertices.Length == 0)
                        {
                            if (pointOnEdge)
                            {
                                firstSnappedEdges  = visualSnappedEdges.ToArray();
                                firstSnappedBrush  = visualSnappedBrush;
                                firstSnappedPlanes = null;
                            }
                            else
                            {
                                firstSnappedBrush  = null;
                                firstSnappedEdges  = null;
                                firstSnappedPlanes = null;
                            }
                            geometryPlane   = buildPlane;
                            planeOnGeometry = vertexOnGeometry;
                        }
                        else
                        {
                            if (firstSnappedEdges != null)
                            {
                                if (firstSnappedPlanes == null)
                                {
                                    CreateSnappedPlanes();
                                }

                                bool outside = true;
                                for (int i = 0; i < firstSnappedPlanes.Length; i++)
                                {
                                    if (firstSnappedPlanes[i].Distance(worldPosition) <= MathConstants.DistanceEpsilon)
                                    {
                                        outside = false;
                                        break;
                                    }
                                }

                                planeOnGeometry = !outside;
                            }

                            if (vertexOnGeometry)
                            {
                                var plane    = hoverDefaultPlane.Value;
                                var distance = plane.Distance(worldPosition);
                                if (float.IsInfinity(distance) || float.IsNaN(distance))
                                {
                                    distance = 1.0f;
                                }
                                plane.d          += distance;
                                hoverDefaultPlane = plane;

                                for (int i = 0; i < settings.vertices.Length; i++)
                                {
                                    if (!settings.onGeometryVertices[i])
                                    {
                                        settings.vertices[i]           = GeometryUtility.ProjectPointOnPlane(plane, settings.vertices[i]);
                                        settings.onGeometryVertices[i] = true;
                                    }
                                }
                            }
                        }
                        ArrayUtility.Add(ref settings.onGeometryVertices, vertexOnGeometry);
                        settings.AddPoint(worldPosition);
                        SceneView.RepaintAll();
                        if (settings.vertices.Length == 2)
                        {
                            HotKeyReleased();
                        }
                    }
                }
                return;
            }

            case EventType.MouseDrag:
            {
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    break;
                }
                if (GUIUtility.hotControl == base.shapeId && Event.current.button == 0)
                {
                    Event.current.Use();
                }
                return;
            }

            case EventType.MouseUp:
            {
                if (GUIUtility.hotControl != base.shapeId)
                {
                    return;
                }
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    return;
                }
                if (Event.current.button == 0)
                {
                    Event.current.Use();

                    ResetVisuals();
                    if (onLastPoint)
                    {
                        GUIUtility.hotControl             = 0;
                        GUIUtility.keyboardControl        = 0;
                        EditorGUIUtility.editingTextField = false;

                        editMode = EditMode.CreateShape;
                        HotKeyReleased();
                    }
                }
                return;
            }
            }
            return;
        }
        protected override void HandleCreateShapeEvents(Rect sceneRect)
        {
            bool     pointOnEdge      = false;
            bool     havePlane        = false;
            bool     vertexOnGeometry = false;
            CSGBrush vertexOnBrush    = null;

            CSGPlane hoverBuildPlane = buildPlane;
            var      sceneView       = SceneView.currentDrawingSceneView; //(SceneView.currentDrawingSceneView != null) ? SceneView.currentDrawingSceneView : SceneView.lastActiveSceneView;
            var      camera          = (sceneView == null) ? null : sceneView.camera;
            var      assume2DView    = CSGSettings.Assume2DView(sceneView);

            if (camera != null &&
                camera.pixelRect.Contains(Event.current.mousePosition))
            {
                if (!hoverDefaultPlane.HasValue ||
                    settings.vertices.Length == 0)
                {
                    bool forceGrid = RealtimeCSG.Grid.ForceGrid;
                    RealtimeCSG.Grid.ForceGrid = false;
                    hoverDefaultPlane          = RealtimeCSG.Grid.CurrentGridPlane;
                    RealtimeCSG.Grid.ForceGrid = forceGrid;
                    firstSnappedEdges          = null;
                    firstSnappedBrush          = null;
                    firstSnappedPlanes         = null;
                    base.geometryModel         = null;
                }
                if (editMode == EditMode.CreatePlane)
                {
                    BrushIntersection intersection;
                    if (!assume2DView && !havePlane &&
                        SceneQueryUtility.FindWorldIntersection(Event.current.mousePosition, out intersection, MathConstants.GrowBrushFactor))
                    {
                        worldPosition = intersection.worldIntersection;
                        if (intersection.surfaceInverted)
                        {
                            hoverBuildPlane = intersection.plane.Negated();
                        }
                        else
                        {
                            hoverBuildPlane = intersection.plane;
                        }
                        vertexOnBrush = intersection.brush;

                        vertexOnGeometry = true;
                    }
                    else
                    {
                        hoverBuildPlane = hoverDefaultPlane.Value;
                        vertexOnBrush   = null;

                        var mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                        worldPosition    = hoverBuildPlane.Intersection(mouseRay);
                        vertexOnGeometry = false;
                    }
                    ResetVisuals();
                    if (snapFunction != null)
                    {
                        CSGBrush snappedOnBrush;
                        worldPosition = snapFunction(worldPosition, hoverBuildPlane, ref visualSnappedEdges, out snappedOnBrush, generatedBrushes, ignoreAllBrushes: true);
                        if (snappedOnBrush != null)
                        {
                            pointOnEdge = (visualSnappedEdges != null &&
                                           visualSnappedEdges.Count > 0);
                            vertexOnBrush    = snappedOnBrush;
                            vertexOnGeometry = true;
                        }
                    }

                    if (settings.vertices.Length == 1)
                    {
                        if (hoverBuildPlane.normal != MathConstants.zeroVector3)
                        {
                            editMode  = EditMode.CreateShape;
                            havePlane = true;
                        }
                    }
                }
                else
                {
                    var mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                    if (settings.vertices.Length == 2)
                    {
                        var startPoint = settings.vertices[1];

                        var forward = camera.transform.forward;
                        if (Vector3.Dot(forward, gridBinormal) < Vector3.Dot(forward, gridTangent))
                        {
                            hoverBuildPlane = new CSGPlane(gridBinormal, startPoint);
                        }
                        else
                        {
                            hoverBuildPlane = new CSGPlane(gridTangent, startPoint);
                        }
                        worldPosition = hoverBuildPlane.Intersection(mouseRay);

                        // the third point is always straight up from the second point
                        //worldPosition = startPoint + (Vector3.Dot(worldPosition - startPoint, gridNormal) * gridNormal);

                        RealtimeCSG.Grid.SetForcedGrid(hoverBuildPlane);
                        ResetVisuals();
                        if (raySnapFunction != null)
                        {
                            Ray      ray = new Ray(startPoint, gridNormal);
                            CSGBrush snappedOnBrush;
                            worldPosition = raySnapFunction(worldPosition, ray, ref visualSnappedEdges, out snappedOnBrush);
                            if (snappedOnBrush != null)
                            {
                                pointOnEdge = (visualSnappedEdges != null &&
                                               visualSnappedEdges.Count > 0);
                                vertexOnBrush = snappedOnBrush;
                            }
                        }

                        worldPosition = GeometryUtility.ProjectPointOnInfiniteLine(worldPosition, startPoint, gridNormal);
                    }
                    else
                    {
                        worldPosition = hoverBuildPlane.Intersection(mouseRay);

                        RealtimeCSG.Grid.SetForcedGrid(hoverBuildPlane);
                        ResetVisuals();
                        if (snapFunction != null)
                        {
                            CSGBrush snappedOnBrush;
                            worldPosition = snapFunction(worldPosition, hoverBuildPlane, ref visualSnappedEdges, out snappedOnBrush, generatedBrushes, ignoreAllBrushes: true);
                            if (snappedOnBrush != null)
                            {
                                pointOnEdge = (visualSnappedEdges != null &&
                                               visualSnappedEdges.Count > 0);
                                vertexOnBrush = snappedOnBrush;
                            }
                        }
                    }
                }

                if (geometryModel == null && vertexOnBrush != null)
                {
                    var brush_cache = InternalCSGModelManager.GetBrushCache(vertexOnBrush);
                    if (brush_cache != null && brush_cache.childData != null && brush_cache.childData.Model)
                    {
                        geometryModel = brush_cache.childData.Model;
                    }
                }

                if (worldPosition != prevWorldPosition)
                {
                    prevWorldPosition = worldPosition;
                    if (settings.vertices.Length > 0)
                    {
                        if ((settings.vertices[0] - worldPosition).sqrMagnitude > MathConstants.EqualityEpsilon)
                        {
                            UpdateSizes();
                            UpdateBaseShape(true);
                        }
                    }
                    if (Event.current.type != EventType.Repaint)
                    {
                        SceneView.RepaintAll();
                    }
                }

                visualSnappedGrid  = RealtimeCSG.Grid.FindAllGridEdgesThatTouchPoint(worldPosition);
                visualSnappedBrush = vertexOnBrush;
            }
            RealtimeCSG.Grid.SetForcedGrid(hoverBuildPlane);



            if (!SceneTools.IsDraggingObjectInScene &&
                Event.current.type == EventType.Repaint)
            {
                PaintSnapVisualisation();
                PaintShape(base.shapeId);
            }


            var type = Event.current.GetTypeForControl(base.shapeId);

            switch (type)
            {
            case EventType.Layout:
            {
                return;
            }

            case EventType.ValidateCommand:
            case EventType.KeyDown:
            {
                if (GUIUtility.hotControl == base.shapeId)
                {
                    if (Keys.PerformActionKey.IsKeyPressed() ||
                        Keys.DeleteSelectionKey.IsKeyPressed() ||
                        Keys.CancelActionKey.IsKeyPressed())
                    {
                        Event.current.Use();
                    }
                }
                return;
            }

            case EventType.KeyUp:
            {
                if (GUIUtility.hotControl == base.shapeId)
                {
                    if (Keys.CylinderBuilderMode.IsKeyPressed() ||
                        Keys.PerformActionKey.IsKeyPressed())
                    {
                        HotKeyReleased();
                        Event.current.Use();
                        return;
                    }
                    if (Keys.DeleteSelectionKey.IsKeyPressed() ||
                        Keys.CancelActionKey.IsKeyPressed())
                    {
                        Cancel();
                        Event.current.Use();
                        return;
                    }
                }
                return;
            }

            case EventType.MouseDown:
            {
                if (!sceneRect.Contains(Event.current.mousePosition))
                {
                    break;
                }
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    return;
                }
                if ((GUIUtility.hotControl != 0 && GUIUtility.hotControl != shapeEditId && GUIUtility.hotControl != base.shapeId) ||
                    Event.current.button != 0)
                {
                    return;
                }

                Event.current.Use();
                if (settings.vertices.Length == 0)
                {
                    if ((GUIUtility.hotControl == 0 ||
                         GUIUtility.hotControl == base.shapeEditId) && base.shapeId != -1)
                    {
                        base.CalculateWorldSpaceTangents();
                        GUIUtility.hotControl             = base.shapeId;
                        GUIUtility.keyboardControl        = base.shapeId;
                        EditorGUIUtility.editingTextField = false;
                    }
                }

                if (GUIUtility.hotControl == base.shapeId &&
                    settings.vertices.Length < kMaxPoints)
                {
                    if (!float.IsNaN(worldPosition.x) && !float.IsInfinity(worldPosition.x) &&
                        !float.IsNaN(worldPosition.y) && !float.IsInfinity(worldPosition.y) &&
                        !float.IsNaN(worldPosition.z) && !float.IsInfinity(worldPosition.z))
                    {
                        if (settings.vertices.Length < 2 &&
                            hoverBuildPlane.normal.sqrMagnitude != 0)
                        {
                            buildPlane = hoverBuildPlane;
                        }
                        CalculateWorldSpaceTangents();

                        if (settings.vertices.Length == 0)
                        {
                            if (pointOnEdge)
                            {
                                firstSnappedEdges  = visualSnappedEdges.ToArray();
                                firstSnappedBrush  = visualSnappedBrush;
                                firstSnappedPlanes = null;
                            }
                            else
                            {
                                firstSnappedBrush  = null;
                                firstSnappedEdges  = null;
                                firstSnappedPlanes = null;
                            }
                            planeOnGeometry = vertexOnGeometry;
                        }
                        else
                        {
                            if (firstSnappedEdges != null)
                            {
                                if (firstSnappedPlanes == null)
                                {
                                    CreateSnappedPlanes();
                                }

                                bool outside = true;
                                for (int i = 0; i < firstSnappedPlanes.Length; i++)
                                {
                                    if (firstSnappedPlanes[i].Distance(worldPosition) <= MathConstants.DistanceEpsilon)
                                    {
                                        outside = false;
                                        break;
                                    }
                                }

                                planeOnGeometry = !outside;
                            }

                            if (vertexOnGeometry)
                            {
                                var plane    = hoverDefaultPlane.Value;
                                var distance = plane.Distance(worldPosition);
                                plane.d          += distance;
                                hoverDefaultPlane = plane;

                                for (int i = 0; i < settings.vertices.Length; i++)
                                {
                                    if (!settings.onGeometryVertices[i])
                                    {
                                        settings.SetPoint(i, GeometryUtility.ProjectPointOnPlane(plane, settings.vertices[i]));
                                        settings.onGeometryVertices[i] = true;
                                    }
                                }
                            }
                        }
                        ArrayUtility.Add(ref settings.onGeometryVertices, vertexOnGeometry);
                        settings.AddPoint(worldPosition);

                        UpdateSizes();
                        SceneView.RepaintAll();
                        if (settings.vertices.Length == kMaxPoints)
                        {
                            HotKeyReleased();
                        }
                    }
                }
                return;
            }

            case EventType.MouseDrag:
            {
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    break;
                }
                if (GUIUtility.hotControl == base.shapeId && Event.current.button == 0)
                {
                    Event.current.Use();
                }
                return;
            }

            case EventType.MouseUp:
            {
                if (GUIUtility.hotControl != base.shapeId)
                {
                    return;
                }
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    return;
                }
                if (Event.current.button == 0)
                {
                    Event.current.Use();

                    ResetVisuals();
                    if (settings.vertices.Length == kMaxPoints)
                    {
                        GUIUtility.hotControl             = 0;
                        GUIUtility.keyboardControl        = 0;
                        EditorGUIUtility.editingTextField = false;

                        editMode = EditMode.CreateShape;
                        HotKeyReleased();
                    }
                }
                return;
            }
            }
        }