Exemple #1
0
        public void Search <T>(Func <ISpatialObject, bool> predicate,
                               Func <ISpatialObject, float> prioritizer,
                               int maxResultsCount,
                               ICollection <T> results) where T : ISpatialObject
        {
            lock (m_Lock)
            {
                var count = 0;
                m_PriorityHeap.Clear();
                results.Clear();
                m_PriorityHeap.Push(m_RootNode);

                while (count < maxResultsCount && !m_PriorityHeap.isEmpty)
                {
                    if (!m_PriorityHeap.TryPop(out var obj))
                    {
                        break;
                    }

                    if (obj is SpatialNode node)
                    {
                        foreach (var child in node.children)
                        {
                            if (!predicate(child))
                            {
                                continue;
                            }

                            child.priority = prioritizer(child);
                            m_PriorityHeap.Push(child);
                        }

                        continue;
                    }

                    results.Add((T)obj);
                    ++count;
                }
            }
        }
        protected override void UpdateInternal(float unscaledDeltaTime)
        {
            if (!settings.isActive)
            {
                return;
            }

            CacheCameraData();

            if (spatialCollection.objectCount <= 0)
            {
                return;
            }

            if (!m_IsPendingVisibilityUpdate)
            {
                return;
            }

            m_IsPendingVisibilityUpdate = false;

            m_BoundingBoxIndex = 0;
            foreach (var obj in m_ObjectsByStreamKey.Values)
            {
                // early exit if neither the visibility nor the renderers have changed
                // and the object doesn't require displaying its bounding box (not visible or renderers are loaded)
                // make sure not to exit if we're displaying only bounding boxes
                // or if the bounding box display toggle has changed, to correctly refresh MeshRenderers
                if (!obj.TryRefreshVisibility() &&
                    !obj.HasMeshRendererChanged &&
                    (!obj.isVisible || obj.HasMeshRenderers) &&
                    !m_DisplayOnlyBoundingBoxes &&
                    m_DisplayOnlyBoundingBoxes == settings.displayOnlyBoundingBoxes)
                {
                    continue;
                }

                obj.HasMeshRendererChanged = false;

                // if the object is visible but there is no renderer loaded, display the bounding box instead
                // due to async visibility changes there might be more visible objects than bounding boxes
                // so check to make sure we haven't reached the limit yet
                if ((obj.TryRefreshRenderers(settings.displayOnlyBoundingBoxes) && !settings.displayOnlyBoundingBoxes) ||
                    !obj.isVisible ||
                    !settings.displayUnloadedObjectBoundingBoxes ||
                    m_BoundingBoxIndex >= m_BoundingBoxes.Length)
                {
                    continue;
                }

                var box = m_BoundingBoxes[m_BoundingBoxIndex];
                box.transform.localPosition = obj.center;
                box.transform.localScale    = obj.max - obj.min;
                var meshRenderer = box.meshRenderer;
                if (!meshRenderer.enabled)
                {
                    meshRenderer.enabled = true;
                }
                ++m_BoundingBoxIndex;
            }
            m_DisplayOnlyBoundingBoxes = settings.displayOnlyBoundingBoxes;

            if (m_ObjectsToLoad.count > 0)
            {
                const int count = 5; // TODO improve how we determine the count
                for (var i = 0; i < count; ++i)
                {
                    if (!m_ObjectsToLoad.TryPop(out var obj))
                    {
                        break;
                    }

                    obj.IsLoaded = true;
                    m_StreamOutput.SendStreamAdded(obj.StreamAsset);
                }

                // clear any remaining objects, they will re-add themselves during the next visibility update
                m_ObjectsToLoad.Clear();
            }

            if (!settings.displayUnloadedObjectBoundingBoxes)
            {
                return;
            }

            // hide unused visible boxes
            for (var i = m_BoundingBoxIndex; i < m_PrevBoundingBoxIndex; ++i)
            {
                var meshRenderer = m_BoundingBoxes[i].meshRenderer;
                if (meshRenderer.enabled)
                {
                    meshRenderer.enabled = false;
                }
            }

            m_PrevBoundingBoxIndex = m_BoundingBoxIndex;
        }