/// <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!"); } } } }