public static T[] ToArrayPooled <T>(this IEnumerable <T> source) { var array = ArrayPool <T> .New(source.Count()); var i = 0; foreach (var item in source) { array[i++] = item; } return(array); }
public static Rect?BoundsToGUIRect(this SceneView sceneView, Bounds worldBounds) { var worldPoints = ArrayPool <Vector3> .New(8); worldBounds.GetPointsNoAlloc(worldPoints); Rect?guiRect = null; foreach (var worldPoint in worldPoints) { var guiPoint = sceneView.WorldToGUIPoint(worldPoint); if (guiPoint.z < 0) { continue; } guiRect = guiRect.Encompass(guiPoint); } worldPoints.Free(); return(guiRect); }
public static void PickAllNonAlloc(List <ProbeHit> hits, ProbeFilter filter, SceneView sceneView, Vector2 guiPosition, int limit = DefaultLimit) { var screenPosition = HandleUtility.GUIPointToScreenPixelCoordinate(guiPosition); var ray3D = HandleUtility.GUIPointToWorldRay(guiPosition); var worldPosition = sceneView.camera.ScreenToWorldPoint(screenPosition); var layerMask = PeekPlugin.Configuration.probeLayerMask; var raycastHits = ArrayPool <RaycastHit> .New(limit); var overlapHits = ArrayPool <Collider2D> .New(limit); var handleHits = HashSetPool <GameObject> .New(); var ancestorHits = HashSetPool <ProbeHit> .New(); #if PROBUILDER_4_OR_NEWER var proBuilderHits = ListPool <ProbeHit> .New(); #endif var gameObjectHits = DictionaryPool <GameObject, ProbeHit> .New(); try { // Raycast (3D) if (filter.raycast) { var raycastHitCount = Physics.RaycastNonAlloc(ray3D, raycastHits, Mathf.Infinity, layerMask); for (var i = 0; i < raycastHitCount; i++) { var raycastHit = raycastHits[i]; #if UNITY_2019_2_OR_NEWER if (SceneVisibilityManager.instance.IsHidden(raycastHit.transform.gameObject)) { continue; } #endif var gameObject = raycastHit.transform.gameObject; if (!gameObjectHits.TryGetValue(gameObject, out var hit)) { hit = new ProbeHit(gameObject); } hit.point = raycastHit.point; hit.distance = raycastHit.distance; gameObjectHits[gameObject] = hit; } } // Overlap (2D) if (filter.overlap) { var overlapHitCount = Physics2D.OverlapPointNonAlloc(worldPosition, overlapHits, layerMask); for (var i = 0; i < overlapHitCount; i++) { var overlapHit = overlapHits[i]; #if UNITY_2019_2_OR_NEWER if (SceneVisibilityManager.instance.IsHidden(overlapHit.transform.gameObject)) { continue; } #endif var gameObject = overlapHit.transform.gameObject; if (!gameObjectHits.TryGetValue(gameObject, out var hit)) { hit = new ProbeHit(gameObject); } hit.distance = hit.distance ?? Vector3.Distance(overlapHit.transform.position, worldPosition); gameObjectHits[gameObject] = hit; } } // Handles (Editor Default) if (filter.handles && canPickHandles) { PickAllHandlesNonAlloc(handleHits, guiPosition, limit); foreach (var handleHit in handleHits) { var gameObject = handleHit; if (!gameObjectHits.TryGetValue(gameObject, out var hit)) { hit = new ProbeHit(gameObject); } hit.distance = hit.distance ?? Vector3.Distance(handleHit.transform.position, worldPosition); gameObjectHits[gameObject] = hit; } } // Ancestors foreach (var gameObjectHit in gameObjectHits) { var gameObject = gameObjectHit.Key; var hit = gameObjectHit.Value; var parent = gameObject.transform.parent; int depth = 0; while (parent != null) { var parentGameObject = parent.gameObject; var parentHit = new ProbeHit(parentGameObject); parentHit.groupGameObject = gameObject; parentHit.distance = hit.distance ?? Vector3.Distance(parentHit.transform.position, worldPosition); parentHit.groupOrder = 1000 + depth; ancestorHits.Add(parentHit); parent = parent.parent; depth++; } } #if PROBUILDER_4_OR_NEWER // ProBuilder if (filter.proBuilder && ProBuilderEditor.instance != null) { var proBuilderMeshes = ListPool <ProBuilderMesh> .New(); try { foreach (var gameObjectHit in gameObjectHits.Values) { var proBuilderMesh = gameObjectHit.gameObject.GetComponent <ProBuilderMesh>(); if (proBuilderMesh != null) { proBuilderMeshes.Add(proBuilderMesh); } } PickProBuilderElementsNonAlloc(proBuilderHits, proBuilderMeshes, sceneView, guiPosition); } finally { proBuilderMeshes.Free(); } } #endif // Prepare final hits hits.Clear(); // Add hits foreach (var gameObjectHit in gameObjectHits.Values) { hits.Add(gameObjectHit); } foreach (var ancestorHit in ancestorHits) { hits.Add(ancestorHit); } #if PROBUILDER_4_OR_NEWER foreach (var proBuilderHit in proBuilderHits) { hits.Add(proBuilderHit); } #endif // Sort by distance hits.Sort(compareHits); } finally { raycastHits.Free(); overlapHits.Free(); handleHits.Free(); ancestorHits.Free(); #if PROBUILDER_4_OR_NEWER proBuilderHits.Free(); #endif gameObjectHits.Free(); } }
public static bool CalculateBounds ( this GameObject root, out Bounds bounds, Space space, bool renderers = true, bool colliders = true, bool meshes = false, bool graphics = true, bool particles = false) { bounds = new Bounds(); var first = true; if (space == Space.Self) { if (renderers) { var _renderers = ListPool <Renderer> .New(); root.GetComponentsInChildren(_renderers); foreach (var renderer in _renderers) { if (!renderer.enabled) { continue; } if (!particles && renderer is ParticleSystemRenderer) { continue; } var rendererBounds = renderer.bounds; rendererBounds.SetMinMax ( root.transform.InverseTransformPoint(rendererBounds.min), root.transform.InverseTransformPoint(rendererBounds.max) ); if (first) { bounds = rendererBounds; first = false; } else { bounds.Encapsulate(rendererBounds); } } _renderers.Free(); } if (meshes) { var _meshFilters = ListPool <MeshFilter> .New(); root.GetComponentsInChildren(_meshFilters); foreach (var meshFilter in _meshFilters) { var mesh = meshFilter.sharedMesh; if (mesh == null) { continue; } var meshBounds = mesh.bounds; meshBounds.SetMinMax ( root.transform.InverseTransformPoint(meshFilter.transform.TransformPoint(meshBounds.min)), root.transform.InverseTransformPoint(meshFilter.transform.TransformPoint(meshBounds.max)) ); if (first) { bounds = meshBounds; first = false; } else { bounds.Encapsulate(meshBounds); } } _meshFilters.Free(); } if (graphics) { var _graphics = ListPool <Graphic> .New(); root.GetComponentsInChildren(_graphics); foreach (var graphic in _graphics) { if (!graphic.enabled) { continue; } var graphicCorners = ArrayPool <Vector3> .New(4); graphic.rectTransform.GetLocalCorners(graphicCorners); var graphicsBounds = BoundsFromCorners(graphicCorners); graphicCorners.Free(); if (first) { bounds = graphicsBounds; first = false; } else { bounds.Encapsulate(graphicsBounds); } } _graphics.Free(); } if (colliders && first) { var _colliders = ListPool <Collider> .New(); root.GetComponentsInChildren(_colliders); foreach (var collider in _colliders) { if (!collider.enabled) { continue; } var colliderBounds = collider.bounds; colliderBounds.SetMinMax ( root.transform.InverseTransformPoint(colliderBounds.min), root.transform.InverseTransformPoint(colliderBounds.max) ); if (first) { bounds = colliderBounds; first = false; } else { bounds.Encapsulate(colliderBounds); } } _colliders.Free(); } return(!first); } else // if (space == Space.World) { if (renderers) { var _renderers = ListPool <Renderer> .New(); root.GetComponentsInChildren(_renderers); foreach (var renderer in _renderers) { if (!renderer.enabled) { continue; } if (!particles && renderer is ParticleSystemRenderer) { continue; } if (first) { bounds = renderer.bounds; first = false; } else { bounds.Encapsulate(renderer.bounds); } } _renderers.Free(); } if (meshes) { var _meshFilters = ListPool <MeshFilter> .New(); root.GetComponentsInChildren(_meshFilters); foreach (var meshFilter in _meshFilters) { var mesh = meshFilter.sharedMesh; if (mesh == null) { continue; } var meshBounds = mesh.bounds; meshBounds.SetMinMax ( root.transform.TransformPoint(meshBounds.min), root.transform.TransformPoint(meshBounds.max) ); if (first) { bounds = meshBounds; first = false; } else { bounds.Encapsulate(meshBounds); } } _meshFilters.Free(); } if (graphics) { var _graphics = ListPool <Graphic> .New(); root.GetComponentsInChildren(_graphics); foreach (var graphic in _graphics) { if (!graphic.enabled) { continue; } var graphicCorners = ArrayPool <Vector3> .New(4); graphic.rectTransform.GetWorldCorners(graphicCorners); var graphicsBounds = BoundsFromCorners(graphicCorners); graphicCorners.Free(); if (first) { bounds = graphicsBounds; first = false; } else { bounds.Encapsulate(graphicsBounds); } } _graphics.Free(); } if (colliders && first) { var _colliders = ListPool <Collider> .New(); root.GetComponentsInChildren(_colliders); foreach (var collider in _colliders) { if (!collider.enabled) { continue; } if (first) { bounds = collider.bounds; first = false; } else { bounds.Encapsulate(collider.bounds); } } _colliders.Free(); } } return(!first); }
protected override void UpdateTools(IList <ITool> tools) { if (mainTool != null) { tools.Add(mainTool); } if (hasPrefabTarget) { return; } mergedScriptsTool.tools.Clear(); foreach (var components in ComponentCache.GetSharedComponents(targets)) { // Being extra picky about allocation here var targets = ArrayPool <UnityObject> .New(components.Count); try { var hide = false; for (var i = 0; i < components.Count; i++) { targets[i] = components[i]; if (!ShouldShowComponent(components[i])) { hide = true; break; } } if (hide) { continue; } var componentStrip = ObjectToolbarProvider.GetToolbar(targets); if (componentStrip.isValid) { componentStrip.Update(); foreach (var componentTool in componentStrip) { if (componentTool is IEditorTool componentEditorTool && typeof(MonoBehaviour).IsAssignableFrom(componentEditorTool.targetType)) { var hasIcon = componentEditorTool.targetType.Icon()?[IconSize.Small] != PeekPlugin.Icons.script?[IconSize.Small]; var merge = PeekPlugin.Configuration.scriptsMerging.Merge(hasIcon); if (merge) { mergedScriptsTool.tools.Add(componentEditorTool); } else { tools.Add(componentEditorTool); } } else { tools.Add(componentTool); } } } }