public static bool FindUnityWorldIntersection(Vector2 screenPos, out GameObject foundObject)
        {
            var sceneView = SceneView.currentDrawingSceneView;            // ? SceneView.currentDrawingSceneView : SceneView.lastActiveSceneView;
            var camera    = sceneView ? sceneView.camera : Camera.current;

            foundObject = null;
            if (!camera)
            {
                return(false);
            }

            var wireframeShown = CSGSettings.IsWireframeShown(sceneView);
            var worldRay       = HandleUtility.GUIPointToWorldRay(screenPos);
            var worldRayStart  = worldRay.origin;
            var worldRayVector = (worldRay.direction * (camera.farClipPlane - camera.nearClipPlane));
            var worldRayEnd    = worldRayStart + worldRayVector;

            CSGModel intersectionModel = null;

            LegacyBrushIntersection[] intersections;
            if (FindMultiWorldIntersection(worldRayStart, worldRayEnd, out intersections, ignoreInvisibleSurfaces: !wireframeShown))
            {
                var visibleLayers = Tools.visibleLayers;
                for (int i = 0; i < intersections.Length; i++)
                {
                    if (((1 << intersections[i].gameObject.layer) & visibleLayers) == 0)
                    {
                        continue;
                    }
                    intersectionModel = intersections[i].model;
                    break;
                }
            }

            GameObject[] modelMeshes = null;
            HideFlags[]  hideFlags   = null;
            if (intersectionModel != null)
            {
                modelMeshes = CSGModelManager.GetModelMeshes(intersectionModel);
                if (modelMeshes != null)
                {
                    hideFlags = new HideFlags[modelMeshes.Length];
                    for (var i = 0; i < modelMeshes.Length; i++)
                    {
                        hideFlags[i]             = modelMeshes[i].hideFlags;
                        modelMeshes[i].hideFlags = HideFlags.None;
                    }
                }
            }

            var gameObject = HandleUtility.PickGameObject(screenPos, false);

            if (modelMeshes != null)
            {
                for (var i = 0; i < modelMeshes.Length; i++)
                {
                    var modelMesh = modelMeshes[i];
                    if (!modelMesh)
                    {
                        continue;
                    }

                    if (gameObject == modelMesh)
                    {
                        gameObject = null;
                    }

                    modelMesh.hideFlags = hideFlags[i];
                }
            }

            if (!gameObject ||
                gameObject.GetComponent <Canvas>() ||
                gameObject.GetComponent <CSGModel>() ||
                gameObject.GetComponent <CSGBrush>() ||
                gameObject.GetComponent <CSGOperation>() ||
                gameObject.GetComponent <GeneratedMeshInstance>() ||
                gameObject.GetComponent <GeneratedMeshes>())
            {
                return(false);
            }

            foundObject = gameObject;
            return(true);
        }
        public static bool FindClickWorldIntersection(Vector2 screenPos, out GameObject foundObject)
        {
            var sceneView = SceneView.currentDrawingSceneView;// ? SceneView.currentDrawingSceneView : SceneView.lastActiveSceneView;
            var camera    = sceneView ? sceneView.camera : Camera.current;

            foundObject = null;
            if (!camera)
            {
                return(false);
            }

            var worldRay       = HandleUtility.GUIPointToWorldRay(screenPos);
            var worldRayStart  = worldRay.origin;
            var worldRayVector = (worldRay.direction * (camera.farClipPlane - camera.nearClipPlane));
            var worldRayEnd    = worldRayStart + worldRayVector;

            CSGModel intersectionModel = null;

            if (_prevSceenPos == screenPos && _prevSceneView == sceneView && _deepClickIntersections != null)
            {
                var prevIntersection = (_deepIndex > 0 && _deepIndex < _deepClickIntersections.Length) ? _deepClickIntersections[_deepIndex] : null;
                if (_deepClickIntersections.Length > 1)
                {
                    var visibleLayers = Tools.visibleLayers;
                    for (var i = _deepClickIntersections.Length - 1; i >= 0; i--)
                    {
                        if (((1 << _deepClickIntersections[i].gameObject.layer) & visibleLayers) == 0)
                        {
                            continue;
                        }

                        if (_deepClickIntersections[i].brush)
                        {
                            continue;
                        }
                        ArrayUtility.RemoveAt(ref _deepClickIntersections, i);
                        if (i <= _deepIndex)
                        {
                            _deepIndex--;
                        }
                    }
                }

                if (_deepClickIntersections.Length <= 1)
                {
                    ResetDeepClick();
                }
                else
                {
                    _deepIndex = (_deepIndex + 1) % _deepClickIntersections.Length;
                    var currentIntersection = (_deepIndex > 0 && _deepIndex < _deepClickIntersections.Length) ? _deepClickIntersections[_deepIndex] : null;
                    if (currentIntersection != prevIntersection &&
                        currentIntersection != null)
                    {
                        foundObject       = currentIntersection.gameObject;
                        _prevSceenPos     = screenPos;
                        _prevSceneView    = sceneView;
                        intersectionModel = currentIntersection.model;
                    }
                    else
                    {
                        ResetDeepClick();
                    }
                }
            }

            if (_prevSceenPos != screenPos)
            {
                var wireframeShown = CSGSettings.IsWireframeShown(sceneView);
                if (FindMultiWorldIntersection(worldRayStart, worldRayEnd, out _deepClickIntersections, ignoreInvisibleSurfaces: !wireframeShown, ignoreUnrenderables: !wireframeShown))
                {
                    var visibleLayers = Tools.visibleLayers;
                    for (int i = 0; i < _deepClickIntersections.Length; i++)
                    {
                        if (((1 << _deepClickIntersections[i].gameObject.layer) & visibleLayers) == 0)
                        {
                            continue;
                        }

                        _deepIndex = 0;
                        var intersection = _deepClickIntersections[i];
                        foundObject       = intersection.gameObject;
                        _prevSceenPos     = screenPos;
                        _prevSceneView    = sceneView;
                        intersectionModel = intersection.model;
                        break;
                    }
                }
                else
                {
                    ResetDeepClick();
                }
            }

            GameObject[] modelMeshes = null;
            if (intersectionModel != null)
            {
                modelMeshes = CSGModelManager.GetModelMeshes(intersectionModel);
            }

            HideFlags[] hideFlags = null;
            if (modelMeshes != null)
            {
                hideFlags = new HideFlags[modelMeshes.Length];
                for (var i = 0; i < modelMeshes.Length; i++)
                {
                    hideFlags[i] = modelMeshes[i].hideFlags;
                    if (modelMeshes[i].hideFlags != HideFlags.None)
                    {
                        modelMeshes[i].hideFlags = HideFlags.None;
                    }
                }
            }

            var gameObject = HandleUtility.PickGameObject(screenPos, true);

            if (modelMeshes != null)
            {
                for (var i = 0; i < modelMeshes.Length; i++)
                {
                    var modelMesh = modelMeshes[i];
                    if (!modelMesh)
                    {
                        continue;
                    }

                    if (gameObject == modelMesh)
                    {
                        gameObject = null;
                    }

                    if (modelMesh.hideFlags != hideFlags[i])
                    {
                        modelMesh.hideFlags = hideFlags[i];
                    }
                }
            }

            if (!gameObject ||
                gameObject.GetComponent <CSGModel>() ||
                gameObject.GetComponent <CSGBrush>() ||
                gameObject.GetComponent <CSGOperation>() ||
                gameObject.GetComponent <GeneratedMeshInstance>() ||
                gameObject.GetComponent <GeneratedMeshes>())
            {
                return(foundObject != null);
            }

            foundObject = gameObject;
            return(true);
        }
        static GameObject FindFirstWorldIntersection(Camera camera, Vector2 screenPos, Vector3 worldRayStart, Vector3 worldRayEnd, List <GameObject> ignoreGameObjects = null, List <CSGBrush> ignoreBrushes = null, bool ignoreInvisibleSurfaces = true)
        {
            var wireframeShown = CSGSettings.IsWireframeShown(camera);

TryAgain:

            CSGModel model;
            GameObject gameObject = null;

            var ignoreGameObjectArray = (ignoreGameObjects == null || ignoreGameObjects.Count == 0) ? null : ignoreGameObjects.ToArray();

            {
                var flagState = BeginPicking(ignoreGameObjectArray);
                try { gameObject = HandleUtility.PickGameObject(screenPos, false, ignoreGameObjectArray); }
                finally { model = EndPicking(flagState, gameObject); }
            }

            if (!object.Equals(gameObject, null) && model)
            {
                if (ignoreGameObjects != null &&
                    ignoreGameObjects.Contains(model.gameObject))
                {
                    Debug.Assert(false);
                }
                else
                {
                    LegacyBrushIntersection[] _deepClickIntersections;
                    var ignoreBrushesArray = (ignoreGameObjects == null || ignoreGameObjects.Count == 0) ? null : ignoreBrushes.ToArray();
                    if (FindWorldIntersection(model, worldRayStart, worldRayEnd, out _deepClickIntersections, ignoreInvisibleSurfaces: ignoreInvisibleSurfaces && !wireframeShown, ignoreUnrenderables: !wireframeShown, ignoreBrushes: ignoreBrushesArray))
                    {
                        var visibleLayers = Tools.visibleLayers;
                        for (int i = 0; i < _deepClickIntersections.Length; i++)
                        {
                            gameObject = _deepClickIntersections[i].gameObject;
                            if (((1 << gameObject.layer) & visibleLayers) == 0)
                            {
                                continue;
                            }

                            return(gameObject);
                        }
                    }
                    if (ignoreGameObjects != null)
                    {
                        ignoreGameObjects.Add(model.gameObject);
                        foreach (var component in model.generatedMeshes.GetComponentsInChildren <GeneratedMeshInstance>())
                        {
                            ignoreGameObjects.Add(component.gameObject);
                        }
                        goto TryAgain;
                    }
                }

                // Try finding a regular unity object instead
                gameObject = HandleUtility.PickGameObject(screenPos, false, ignoreGameObjectArray);
            }


            // If we really didn't find anything, just return null
            if (ReferenceEquals(gameObject, null) ||
                !gameObject)
            {
                return(null);
            }

            // Make sure our found gameobject isn't sneakily a CSG related object (should not happen at this point)
            if (!gameObject.GetComponent <CSGModel>() &&
                !gameObject.GetComponent <CSGBrush>() &&
                !gameObject.GetComponent <CSGOperation>() &&
                !gameObject.GetComponent <GeneratedMeshInstance>() &&
                !gameObject.GetComponent <GeneratedMeshes>())
            {
                return(gameObject);
            }

            // If we're not ignoring something, just return null after all
            if (ignoreGameObjects == null)
            {
                return(null);
            }

            // Ignore this object and try again (might've been blocking a model)
            ignoreGameObjects.Add(gameObject);
            goto TryAgain;
        }
        public static bool FindUnityWorldIntersection(Camera camera, Vector2 screenPos, out GameObject foundObject, bool ignoreInvisibleSurfaces = true)
        {
            foundObject = null;
            if (!camera)
            {
                return(false);
            }

            var wireframeShown = CSGSettings.IsWireframeShown(camera);
            var worldRay       = HandleUtility.GUIPointToWorldRay(screenPos);
            var worldRayStart  = worldRay.origin;
            var worldRayVector = (worldRay.direction * (camera.farClipPlane - camera.nearClipPlane));
            var worldRayEnd    = worldRayStart + worldRayVector;

            CSGModel intersectionModel = null;

            LegacyBrushIntersection[] intersections;
            if (FindMultiWorldIntersection(worldRayStart, worldRayEnd, out intersections, ignoreInvisibleSurfaces: ignoreInvisibleSurfaces && !wireframeShown))
            {
                var visibleLayers = Tools.visibleLayers;
                for (int i = 0; i < intersections.Length; i++)
                {
                    if (((1 << intersections[i].gameObject.layer) & visibleLayers) == 0)
                    {
                        continue;
                    }
                    intersectionModel = intersections[i].model;
                    break;
                }
            }

            /*
             * GameObject[] modelMeshes = null;
             * HideFlags[] hideFlags = null;
             * if (intersectionModel != null)
             * {
             *      modelMeshes = CSGModelManager.GetModelMeshes(intersectionModel);
             *      if (modelMeshes != null)
             *      {
             *              hideFlags = new HideFlags[modelMeshes.Length];
             *              for (var i = 0; i < modelMeshes.Length; i++)
             *              {
             *                      hideFlags[i] = modelMeshes[i].hideFlags;
             *                      modelMeshes[i].hideFlags = HideFlags.None;
             *              }
             *      }
             * }
             */


            CSGModel   foundModel;
            GameObject gameObject = null;
            var        flagState  = BeginPicking(null);

            try { gameObject = HandleUtility.PickGameObject(screenPos, false, null); }
            finally
            {
                foundModel = EndPicking(flagState, gameObject);
            }
            if (foundModel == intersectionModel && intersectionModel)
            {
                return(false);
            }

            /*
             * var gameObject = HandleUtility.PickGameObject(screenPos, false);
             *
             * if (modelMeshes != null)
             * {
             *      for (var i = 0; i < modelMeshes.Length; i++)
             *      {
             *              var modelMesh = modelMeshes[i];
             *              if (!modelMesh)
             *                      continue;
             *
             *              if (gameObject == modelMesh)
             *                      gameObject = null;
             *
             *              modelMesh.hideFlags = hideFlags[i];
             *      }
             * }
             */
            if (!gameObject ||
                gameObject.GetComponent <Canvas>() ||
                gameObject.GetComponent <CSGModel>() ||
                gameObject.GetComponent <CSGBrush>() ||
                gameObject.GetComponent <CSGOperation>() ||
                gameObject.GetComponent <GeneratedMeshInstance>() ||
                gameObject.GetComponent <GeneratedMeshes>())
            {
                return(false);
            }

            foundObject = gameObject;
            return(true);
        }
        static GameObject FindFirstWorldIntersection(Vector2 screenPos, Vector3 worldRayStart, Vector3 worldRayEnd, List <GameObject> ignoreGameObjects = null, List <CSGBrush> ignoreBrushes = null)
        {
            var wireframeShown = CSGSettings.IsWireframeShown(Camera.current);

            return(FindFirstWorldIntersection(screenPos, worldRayStart, worldRayEnd, ignoreGameObjects, ignoreBrushes, wireframeShown));
        }