static GameObject PickClosestGameObjectDelegated(Vector2 position, ref GameObject[] ignore, ref GameObject[] filter, out ChiselIntersection intersection) { var camera = Camera.current; int layers = camera.cullingMask; var pickposition = GUIClip.GUIClipUnclip(position); pickposition = EditorGUIUtility.PointsToPixels(pickposition); pickposition.y = Screen.height - pickposition.y - camera.pixelRect.yMin; var gameObject = PickNodeOrGameObject(camera, pickposition, layers, ref ignore, ref filter, out var model, out var node, out intersection); if (!model) { return(gameObject); } if (node) { return(gameObject); } return(null); }
// TODO: rewrite this, why do we need hashes? public static GameObject PickClosestGameObject(Vector2 mousePosition, out CSGTreeBrushIntersection intersection) { intersection = new CSGTreeBrushIntersection { surfaceID = -1, brushUserID = -1 }; s_RetainHashes = true; if (enumerator == null || (prevMousePosition - mousePosition).sqrMagnitude > 2) { enumerator = GetAllOverlapping(mousePosition).GetEnumerator(); prevMousePosition = mousePosition; } if (!enumerator.MoveNext()) { enumerator = GetAllOverlapping(mousePosition).GetEnumerator(); if (!enumerator.MoveNext()) { return(null); } } var topmost = enumerator.Current; var selectionBase = GUIClip.FindSelectionBase(topmost.Key); var first = (selectionBase == null ? topmost.Key : selectionBase); int topmostHash = topmost.GetHashCode(); int prefixHash = topmostHash; if (Selection.activeGameObject == null) { // Nothing selected // Return selection base if it exists, otherwise topmost game object s_PreviousTopmostHash = topmostHash; s_PreviousPrefixHash = prefixHash; intersection = topmost.Value; return(first); } if (topmostHash != s_PreviousTopmostHash) { // Topmost game object changed // Return selection base if exists and is not already selected, otherwise topmost game object s_PreviousTopmostHash = topmostHash; s_PreviousPrefixHash = prefixHash; intersection = topmost.Value; return(Selection.activeGameObject == selectionBase ? topmost.Key : first); } s_PreviousTopmostHash = topmostHash; // Pick potential selection base before topmost game object if (Selection.activeGameObject == selectionBase) { intersection = topmost.Value; if (prefixHash != s_PreviousPrefixHash) { s_PreviousPrefixHash = prefixHash; return(selectionBase); } return(topmost.Key); } // Check if active game object will appear in selection stack GameObject[] ignore = null; GameObject[] filter = new GameObject[] { Selection.activeGameObject }; var picked = PickClosestGameObjectDelegated(mousePosition, ref ignore, ref filter, out intersection); if (picked == Selection.activeGameObject) { // Advance enumerator to active game object while (enumerator.Current.Key != Selection.activeGameObject) { if (!enumerator.MoveNext()) { s_PreviousPrefixHash = topmostHash; intersection = topmost.Value; return(first); // Should not occur } UpdateHash(ref prefixHash, enumerator.Current); } } if (prefixHash != s_PreviousPrefixHash) { // Prefix hash changed, start over s_PreviousPrefixHash = topmostHash; intersection = topmost.Value; return(first); } // Move on to next game object if (!enumerator.MoveNext()) { s_PreviousPrefixHash = topmostHash; intersection = topmost.Value; return(first); // End reached, start over } UpdateHash(ref prefixHash, enumerator.Current); if (enumerator.Current.Key == selectionBase) { // Skip selection base if (!enumerator.MoveNext()) { s_PreviousPrefixHash = topmostHash; intersection = topmost.Value; return(first); // End reached, start over } UpdateHash(ref prefixHash, enumerator.Current); } s_PreviousPrefixHash = prefixHash; return(enumerator.Current.Key); }