예제 #1
0
        /// <summary>
        /// Executes view update using the given update state object.
        /// </summary>
        /// <param name="updateState">The update state.</param>
        internal void UpdateForView(SceneRelatedUpdateState updateState)
        {
            if (m_disposed)
            {
                throw new ObjectDisposedException("ViewRelatedLayerSubset");
            }

            // TODO: Trigger some other logic to update transparent object order
            // TODO: Performance improvement!!!
            bool         anyOrderChanges = false;
            Camera3DBase camera          = m_viewInformation.Camera;

            m_objectsPassTransparentRender.Subscriptions.Sort(new Comparison <RenderPassSubscription>((left, right) =>
            {
                SceneSpacialObject leftSpacial  = left.SceneObject as SceneSpacialObject;
                SceneSpacialObject rightSpacial = right.SceneObject as SceneSpacialObject;
                if ((leftSpacial != null) && (rightSpacial != null))
                {
                    float leftDistance  = (camera.Position - leftSpacial.Position).LengthSquared();
                    float rightDistance = (camera.Position - rightSpacial.Position).LengthSquared();
                    anyOrderChanges     = true;
                    return(rightDistance.CompareTo(leftDistance));
                }
                else if (leftSpacial != null)
                {
                    anyOrderChanges = true; return(-1);
                }
                else if (rightSpacial != null)
                {
                    anyOrderChanges = true; return(1);
                }
                {
                    return(0);
                }
            }));
            if (anyOrderChanges)
            {
                // Synchronize ordering changes with corresponding scene object
                for (int loop = 0; loop < m_objectsPassTransparentRender.Subscriptions.Count; loop++)
                {
                    var actSubscription = m_objectsPassTransparentRender.Subscriptions[loop];
                    actSubscription.SubscriptionIndex = loop;
                    actSubscription.SceneObject.UpdateSubscription(actSubscription, this);
                    m_objectsPassTransparentRender.Subscriptions[loop] = actSubscription;
                }
            }

            // Update all objects related to this view
            m_isSubscribeUnsubscribeAllowed = true;
            try
            {
                // Update subscriptions based on visibility check result
                if (m_changedVisibilitiesAction != null)
                {
                    m_changedVisibilitiesAction();
                    m_changedVisibilitiesAction = null;
                }

                // Unsubscribe all invalid objects
                SceneObject actInvalidObject = null;
                while (m_invalidObjectsToDeregister.Count > 0)
                {
                    actInvalidObject = m_invalidObjectsToDeregister.Dequeue();
                    actInvalidObject.UnsubsribeFromAllPasses(this);
                }

                // Update subsccriptions based on boject state
                List <SceneObject> allObjects = m_sceneLayer.ObjectsInternal;
                int allObjectsLength          = allObjects.Count;
                int visibleObjectCount        = m_viewInformation.Owner.VisibleObjectCountInternal;
                for (int loop = 0; loop < allObjectsLength; loop++)
                {
                    SceneObject actSceneObject = allObjects[loop];
                    if (m_invalidObjects.ContainsKey(actSceneObject))
                    {
                        continue;
                    }

                    if (actSceneObject.IsLayerViewSubsetRegistered(this.ViewIndex) &&
                        actSceneObject.IsVisible(m_viewInformation))
                    {
                        actSceneObject.UpdateForView(updateState, this);
                        visibleObjectCount++;
                    }
                }
                m_viewInformation.Owner.VisibleObjectCountInternal = visibleObjectCount;
            }
            finally
            {
                m_isSubscribeUnsubscribeAllowed = false;
            }

            // Reorganize subscriptions if there is anything unsubscribed
            if (m_anythingUnsubscribed)
            {
                m_anythingUnsubscribed = false;
                foreach (var actPassProperties in m_objectsPerPass)
                {
                    if (actPassProperties.UnsubscribeCallCount <= 0)
                    {
                        continue;
                    }

                    // Variables for consistency checking
                    int givenUnsubscribeCount = actPassProperties.UnsubscribeCallCount;
                    int trueUnsubscribeCount  = 0;

                    // Handle case where we have unsubscribed some
                    //  => Build new subscription list and ignore all whith 'IsSubscribed' == false
                    List <RenderPassSubscription> newSubscriptionList = new List <RenderPassSubscription>(
                        (actPassProperties.Subscriptions.Count - actPassProperties.UnsubscribeCallCount) + 128);
                    for (int loop = 0; loop < actPassProperties.Subscriptions.Count; loop++)
                    {
                        RenderPassSubscription actSubscription = actPassProperties.Subscriptions[loop];
                        if (!actSubscription.IsSubscribed)
                        {
                            actSubscription.SceneObject.ClearSubscriptionsWithoutUnsubscribeCall(this, actSubscription);
                            trueUnsubscribeCount++;
                            continue;
                        }

                        // Add this item to new subscription list
                        actSubscription.SubscriptionIndex = newSubscriptionList.Count;
                        newSubscriptionList.Add(actSubscription);

                        actSubscription.SceneObject.UpdateSubscription(actSubscription, this);
                    }
                    actPassProperties.Subscriptions        = newSubscriptionList;
                    actPassProperties.UnsubscribeCallCount = 0;

                    // Check for consistency: Does unsubscribe-count match true unsubscriptions using IsSubscribed flag
                    if (givenUnsubscribeCount != trueUnsubscribeCount)
                    {
                        throw new SeeingSharpException("Inconsistency: Given unsubscribe count does not mach true count of unsubscriptions!");
                    }
                }
            }
        }