/// <summary> /// Updates all children of this object. Override this to change default behavior. /// </summary> /// <param name="updateState">The current update state.</param> /// <param name="children">The full list of children that should be updated.</param> protected override void UpdateChildrenInternal(SceneRelatedUpdateState updateState, List <SceneObject> children) { bool prevForceState = updateState.ForceTransformUpdatesOnChilds; updateState.ForceTransformUpdatesOnChilds = prevForceState || m_forceTransformUpdateOnChilds; m_forceTransformUpdateOnChilds = false; try { int childCount = children.Count; for (int loop = 0; loop < childCount; loop++) { // Forward current transform matrix to child objects Matrix4Stack currentWorld = updateState.World; currentWorld.Push(m_transform); try { children[loop].Update(updateState); } finally { currentWorld.Pop(); } } } finally { updateState.ForceTransformUpdatesOnChilds = prevForceState; } }
/// <summary> /// Updates the scene (called beside rendering). /// </summary> internal void UpdateBesideRender(SceneRelatedUpdateState updateState) { // Invoke all async action attached to this scene Action actAsyncAction = null; while (m_asyncInvokesUpdateBesideRendering.Dequeue(out actAsyncAction)) { actAsyncAction(); } // Reset all filter flags before continue to next step foreach (var actView in m_registeredViews) { foreach (SceneObjectFilter actFilter in actView.Filters) { actFilter.ConfigurationChanged = actFilter.ConfigurationChangedUI; actFilter.ConfigurationChangedUI = false; } } // Performs update logic beside rendering foreach (SceneLayer actLayer in m_sceneLayers) { actLayer.UpdateBesideRender(updateState); } }
/// <summary> /// Updates all children of this object (overall update). Override this to change default behavior. /// </summary> /// <param name="updateState">The current update state.</param> /// <param name="children">The full list of children that should be updated.</param> protected virtual void UpdateChildrenOverallInternal(SceneRelatedUpdateState updateState, List <SceneObject> children) { // Trigger updates of all dependencies foreach (SceneObject actDependency in m_children) { actDependency.UpdateOverall(updateState); } }
/// <summary> /// Update logic for overall updates. /// This method should be used for update logic that also depends on other object. /// UpdateOverall methods are called sequentially object by object. /// </summary> /// <param name="updateState">Current update state of the scene.</param> internal void UpdateOverall(SceneRelatedUpdateState updateState) { // Update all dependencies finally if (m_children.Count > 0) { UpdateChildrenOverallInternal(updateState, m_children); } // Update all behaviors first foreach (SceneObjectBehavior actBehavior in m_behaviors) { actBehavior.UpdateOverall(updateState); } }
/// <summary> /// Updates the layer. /// </summary> /// <param name="updateState">Current update state.</param> internal void Update(SceneRelatedUpdateState updateState) { updateState.SceneLayer = this; m_isInUpdate = true; try { // Update all objects which are registered for initial update call int initialUpdateCallCount = m_sceneObjectsForSingleUpdateCall.Count; if (initialUpdateCallCount > 0) { SceneObject[] initialUpdateCallItems = m_sceneObjectsForSingleUpdateCall.GetBackingArray(); for (int loop = 0; loop < initialUpdateCallCount; loop++) { initialUpdateCallItems[loop].Update(updateState); } } // Call default update method for each object int updateListLength = m_sceneObjectsNotStatic.Count; SceneObject[] updateList = m_sceneObjectsNotStatic.GetBackingArray(); for (int actIndex = 0; actIndex < updateListLength; actIndex++) { if (!updateList[actIndex].HasParent) { updateList[actIndex].Update(updateState); } } // Call overall updates on all objects for (int loop = 0; loop < updateListLength; loop++) { if (!updateList[loop].HasParent) { updateList[loop].UpdateOverall(updateState); } } // Now update all view specific references foreach (var actViewSubset in m_viewSubsets) { actViewSubset.UpdateForView(updateState); } } finally { updateState.SceneLayer = null; m_isInUpdate = false; } }
/// <summary> /// Performs "update-beside-render" for this layer. /// </summary> /// <param name="updateState">Current update state.</param> internal void UpdateBesideRender(SceneRelatedUpdateState updateState) { updateState.SceneLayer = this; m_isInUpdateBeside = true; try { // Now update all view specific references foreach (var actViewSubset in m_viewSubsets) { actViewSubset.UpdateBesideRender(updateState, m_sceneObjectsForSingleUpdateCall); } } finally { updateState.SceneLayer = null; m_isInUpdateBeside = false; // Some work after whole update processes m_sceneObjectsForSingleUpdateCall.Clear(); } }
/// <summary> /// Updates this object. /// </summary> /// <param name="updateState">State of update process.</param> internal void Update(SceneRelatedUpdateState updateState) { // Update all behaviors first foreach (SceneObjectBehavior actBehavior in m_behaviors) { actBehavior.Update(updateState); } // Update current animation state if (m_animationHandler != null) { m_animationHandler.Update(updateState); } // Update the object UpdateInternal(updateState); // Update all dependencies finally if (m_children.Count > 0) { UpdateChildrenInternal(updateState, m_children); } }
protected override void UpdateInternal(SceneRelatedUpdateState updateState) { }
/// <summary> /// Internal method for updating all scene components. /// </summary> /// <param name="updateState">Current update state.</param> internal void UpdateSceneComponents(SceneRelatedUpdateState updateState) { // Update all components int attachedComponentsCount = m_attachedComponents.Count; for (int loop = 0; loop < attachedComponentsCount; loop++) { m_attachedComponents[loop].Component.UpdateInternal( updateState, m_attachedComponents[loop].CorrespondingView, m_attachedComponents[loop].Context); } // Attach all components which are comming in SceneComponentRequest actRequest = default(SceneComponentRequest); int actIndex = 0; while (m_componentRequests.Dequeue(out actRequest)) { SceneComponentInfo actComponent; int actComponentIndex = -1; switch (actRequest.RequestType) { case SceneComponentRequestType.Attach: if (actRequest.Component == null) { continue; } if (TryGetAttachedComponent( actRequest.Component, actRequest.CorrespondingView, out actComponent, out actComponentIndex)) { // We've already attached this component, so skip this request continue; } // Trigger removing of all components with the same group like the new one // (new components replace old components with same group name) if (!string.IsNullOrEmpty(actRequest.Component.ComponentGroup)) { foreach (SceneComponentInfo actObsoleteComponent in GetExistingComponentsByGroup( actRequest.Component.ComponentGroup, actRequest.Component.IsViewSpecific ? actRequest.CorrespondingView : null)) { m_componentRequests.Enqueue(new SceneComponentRequest() { RequestType = SceneComponentRequestType.Detach, Component = actObsoleteComponent.Component, CorrespondingView = actObsoleteComponent.CorrespondingView }); } } SceneManipulator actManipulator = new SceneManipulator(m_owner); actManipulator.IsValid = true; try { SceneComponentInfo newRegisteredComponentInfo = new SceneComponentInfo(); newRegisteredComponentInfo.Component = actRequest.Component; newRegisteredComponentInfo.CorrespondingView = actRequest.CorrespondingView; newRegisteredComponentInfo.Context = actRequest.Component.AttachInternal( actManipulator, actRequest.CorrespondingView); actIndex++; // Register the component on local list of attached ones m_attachedComponents.Add(newRegisteredComponentInfo); } finally { actManipulator.IsValid = false; } break; case SceneComponentRequestType.Detach: if (actRequest.Component == null) { continue; } if (!TryGetAttachedComponent( actRequest.Component, actRequest.CorrespondingView, out actComponent, out actComponentIndex)) { // We don't have any component that is like the requested one continue; } actManipulator = new SceneManipulator(m_owner); actManipulator.IsValid = true; try { actComponent.Component.DetachInternal( actManipulator, actComponent.CorrespondingView, actComponent.Context); // Remove the component m_attachedComponents.RemoveAt(actComponentIndex); } finally { actManipulator.IsValid = false; } break; case SceneComponentRequestType.DetachAll: while (m_attachedComponents.Count > 0) { actManipulator = new SceneManipulator(m_owner); actManipulator.IsValid = true; try { actComponent = m_attachedComponents[0]; actComponent.Component.DetachInternal( actManipulator, actComponent.CorrespondingView, actComponent.Context); // Remove the component m_attachedComponents.RemoveAt(0); } finally { actManipulator.IsValid = false; } } break; } } }
/// <summary> /// Updates the scene. /// </summary> internal void Update(SceneRelatedUpdateState updateState) { // Apply local SynchronizationContext if configured so SynchronizationContext previousSyncContext = null; if (m_syncContext != null) { previousSyncContext = SynchronizationContext.Current; SynchronizationContext.SetSynchronizationContext(m_syncContext); } try { m_perFrameData.Time = m_perFrameData.Time + updateState.UpdateTimeMilliseconds; if (m_perFrameData.Time > Constants.MAX_PER_FRAME_TIME_VALUE) { m_perFrameData.Time = m_perFrameData.Time % Constants.MAX_PER_FRAME_TIME_VALUE; } // Update all scene components first // These may trigger some further manipulation actions m_sceneComponents.UpdateSceneComponents(updateState); // Invoke all async action attached to this scene int asyncActionsBeforeUpdateCount = m_asyncInvokesBeforeUpdate.Count; if (asyncActionsBeforeUpdateCount > 0) { Action actAsyncAction = null; int actIndex = 0; while ((actIndex < asyncActionsBeforeUpdateCount) && m_asyncInvokesBeforeUpdate.Dequeue(out actAsyncAction)) { actAsyncAction(); actIndex++; } } // Render all renderable resources foreach (ResourceDictionary actResourceDict in m_registeredResourceDicts) { foreach (IRenderableResource actRenderableResource in actResourceDict.RenderableResources) { if (actRenderableResource.IsLoaded) { actRenderableResource.Update(updateState); } } } // Update all standard objects. foreach (SceneLayer actLayer in m_sceneLayers) { actLayer.Update(updateState); } } finally { // Discard local SynchronizationContext if (m_syncContext != null) { SynchronizationContext.SetSynchronizationContext(previousSyncContext); } } }
/// <summary> /// Updates this object for the given view. /// </summary> /// <param name="updateState">Current state of the update pass.</param> /// <param name="layerViewSubset">The layer view subset wich called this update method.</param> internal void UpdateForView(SceneRelatedUpdateState updateState, ViewRelatedSceneLayerSubset layerViewSubset) { UpdateForViewInternal(updateState, layerViewSubset); }
/// <summary> /// Update logic beside rendering. /// </summary> /// <param name="updateState">The update state.</param> /// <param name="sceneObjectsForSingleUpdateCall">A collection of scene objects for a single update call. These are normally a list of newly inserted static objects.</param> internal void UpdateBesideRender(SceneRelatedUpdateState updateState, Queue <SceneObject> sceneObjectsForSingleUpdateCall) { List <SceneObjectFilter> filters = m_viewInformation.Filters; m_tmpChangedVisibilities.Clear(); // Perform some pre-logic on filters bool anyFilterChanged = false; foreach (SceneObjectFilter actFilter in filters) { actFilter.SetEnvironmentData(m_sceneLayer, m_viewInformation); if (actFilter.ConfigurationChanged) { anyFilterChanged = true; } } // Check whether we have to update all objects bool refreshAllObjects = m_viewInformation.Camera.StateChanged || anyFilterChanged; // Perform viewbox culling for all standard objects List <SceneObject> allObjects = m_sceneLayer.ObjectsInternal; int allObjectsLength = allObjects.Count; if (allObjectsLength > 0) { SceneObject[] allObjectsArray = allObjects.GetBackingArray(); for (int loop = 0; loop < allObjectsLength; loop++) { SceneObject actObject = allObjectsArray[loop]; // Don't handle static objects here if we don't want to handle them if (!refreshAllObjects) { if (actObject.IsStatic) { continue; } if (!actObject.TransormationChanged) { continue; } } // Perform culling PerformViewboxCulling( actObject, filters, refreshAllObjects); } } // Update objects which are passed for a single update call (normally newly inserted static objects) int singleUpdateCallCount = sceneObjectsForSingleUpdateCall.Count; if ((!refreshAllObjects) && (singleUpdateCallCount > 0)) { SceneObject[] singleUpdateArray = sceneObjectsForSingleUpdateCall.GetBackingArray(); for (int loop = 0; loop < singleUpdateCallCount; loop++) { // Perform culling PerformViewboxCulling( singleUpdateArray[loop], filters, refreshAllObjects); } } // Handle changed visibility in standard update logic if (m_tmpChangedVisibilities.Count > 0) { Scene startingScene = m_scene; m_changedVisibilitiesAction = () => { if (m_disposed) { return; } if (startingScene != m_scene) { return; } foreach (var actChangedVisibility in m_tmpChangedVisibilities) { // Check whether this objet is still here.. if (actChangedVisibility.Item1.Scene != m_scene) { continue; } if (actChangedVisibility.Item1.SceneLayer != m_sceneLayer) { continue; } // Handle changed visibility HandleObjectVisibilityChanged( actChangedVisibility.Item1, actChangedVisibility.Item2, actChangedVisibility.Item3); } }; } }
/// <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!"); } } } }
/// <summary> /// This update method gets called on each update pass for each scenes /// this component is attached to. /// </summary> /// <param name="updateState">Current update state.</param> /// <param name="correspondingView">The view which attached this component (may be null).</param> protected virtual void Update(SceneRelatedUpdateState updateState, ViewInformation correspondingView) { }
/// <summary> /// Updates the object. /// </summary> /// <param name="updateState">Current update state.</param> protected abstract void UpdateInternal(SceneRelatedUpdateState updateState);
protected sealed override void UpdateForViewInternal(SceneRelatedUpdateState updateState, ViewRelatedSceneLayerSubset layerViewSubset) { // No resources, so nothing to be done }
/// <summary> /// Renders all given scenes using the different devices and performs "UpdateBesideRendering" step. /// </summary> /// <param name="registeredRenderLoops">The registered render loops on the current pass.</param> /// <param name="scenesToRender">All scenes to be updated / rendered.</param> /// <param name="devicesInUse">The rendering devices that are in use.</param> /// <param name="updateState">Current global update state.</param> private void RenderAndUpdateBeside( List <RenderLoop> registeredRenderLoops, List <Scene> scenesToRender, List <EngineDevice> devicesInUse, UpdateState updateState) { using (var perfToken = m_host.BeginMeasureActivityDuration(Constants.PERF_GLOBAL_RENDER_AND_UPDATE_BESIDE)) { ThreadSaveQueue <RenderLoop> invalidRenderLoops = new ThreadSaveQueue <RenderLoop>(); // Trigger all tasks for 'Update' pass Parallel.For(0, devicesInUse.Count + scenesToRender.Count, (actTaskIndex) => { if (actTaskIndex < devicesInUse.Count) { // Render all targets for the current device EngineDevice actDevice = devicesInUse[actTaskIndex]; using (var perfTokenInner = m_host.BeginMeasureActivityDuration(string.Format(Constants.PERF_GLOBAL_RENDER_DEVICE, actDevice.AdapterDescription))) { for (int loop = 0; loop < registeredRenderLoops.Count; loop++) { RenderLoop actRenderLoop = registeredRenderLoops[loop]; try { if (actRenderLoop.Device == actDevice) { actRenderLoop.Render(); } } catch (Exception) { // Mark this renderloop as invalid invalidRenderLoops.Enqueue(actRenderLoop); } } } } else { // Perform updates beside rendering for the current scene int sceneIndex = actTaskIndex - devicesInUse.Count; using (var perfTokenInner = m_host.BeginMeasureActivityDuration(string.Format(Constants.PERF_GLOBAL_UPDATE_BESIDE, sceneIndex))) { Scene actScene = scenesToRender[sceneIndex]; SceneRelatedUpdateState actUpdateState = actScene.CachedUpdateState; actUpdateState.OnStartSceneUpdate(actScene, updateState, null); actScene.UpdateBesideRender(actUpdateState); } } }); // Handle all invalid render loops if (invalidRenderLoops.HasAny()) { foreach (var actRenderLoop in invalidRenderLoops.DequeueAll()) { DeregisterRenderLoop(actRenderLoop); } } // Reset camera changed flags foreach (RenderLoop actRenderLoop in registeredRenderLoops) { actRenderLoop.Camera.StateChanged = false; } } }
/// <summary> /// Updates the scene's and prepares all views for rendering. /// </summary> /// <param name="renderingRenderLoops">The registered render loops on the current pass.</param> /// <param name="scenesToRender">All scenes to be updated / rendered.</param> /// <param name="devicesInUse">The rendering devices that are in use.</param> /// <param name="inputFrames">All InputFrames gathered during last render.</param> /// <param name="updateState">Current global update state.</param> private async Task UpdateAndPrepareRendering(List <RenderLoop> renderingRenderLoops, List <Scene> scenesToRender, List <EngineDevice> devicesInUse, IEnumerable <InputFrame> inputFrames, UpdateState updateState) { using (var perfToken = m_host.BeginMeasureActivityDuration(Constants.PERF_GLOBAL_UPDATE_AND_PREPARE)) { List <Action> additionalContinuationActions = new List <Action>(); object additionalContinuationActionsLock = new object(); // Trigger all tasks for preparing views List <Task <List <Action> > > prepareRenderTasks = new List <Task <List <Action> > >(renderingRenderLoops.Count); for (int actDeviceIndex = 0; actDeviceIndex < devicesInUse.Count; actDeviceIndex++) { EngineDevice actDevice = devicesInUse[actDeviceIndex]; for (int loop = 0; loop < renderingRenderLoops.Count; loop++) { RenderLoop actRenderLoop = renderingRenderLoops[loop]; if (actRenderLoop.Device == actDevice) { // Call prepare render and wait for the answer // => Error handling is a bit tricky.. // Errors are catched by the continuation action var actTask = actRenderLoop.PrepareRenderAsync(); prepareRenderTasks.Add(actTask.ContinueWith((givenTask) => { if (!givenTask.IsFaulted) { return(givenTask.Result); } else { // Deregister this RenderLoop lock (additionalContinuationActionsLock) { additionalContinuationActions.Add(() => { this.DeregisterRenderLoop(actRenderLoop); renderingRenderLoops.Remove(actRenderLoop); }); } return(new List <Action>()); } })); } } } // Handle initial configuration of render loops (=> No current device) for (int loop = 0; loop < renderingRenderLoops.Count; loop++) { RenderLoop actRenderLoop = renderingRenderLoops[loop]; if (actRenderLoop.Device == null) { try { Task <List <Action> > actPrepareRenderTask = actRenderLoop.PrepareRenderAsync(); await actPrepareRenderTask; lock (additionalContinuationActionsLock) { additionalContinuationActions.AddRange(actPrepareRenderTask.Result); } } catch (Exception) { // Deregister this RenderLoop lock (additionalContinuationActionsLock) { additionalContinuationActions.Add(() => { this.DeregisterRenderLoop(actRenderLoop); renderingRenderLoops.Remove(actRenderLoop); }); } } } } // Update all scenes ThreadSaveQueue <Exception> exceptionsDuringUpdate = new ThreadSaveQueue <Exception>(); Parallel.For(0, scenesToRender.Count, (actTaskIndex) => { try { using (var perfToken2 = m_host.BeginMeasureActivityDuration( string.Format(Constants.PERF_GLOBAL_UPDATE_SCENE, actTaskIndex))) { Scene actScene = scenesToRender[actTaskIndex]; SceneRelatedUpdateState actUpdateState = actScene.CachedUpdateState; actUpdateState.OnStartSceneUpdate(actScene, updateState, inputFrames); actScene.Update(actUpdateState); } } catch (Exception ex) { exceptionsDuringUpdate.Enqueue(ex); } }); // Await synchronizations with the view(s) if (prepareRenderTasks.Count > 0) { await Task.WhenAll(prepareRenderTasks.ToArray()); } // Throw exceptions if any occurred during scene update // => This would be a fatal exception, so throw up to main loop if (exceptionsDuringUpdate.HasAny()) { throw new AggregateException("Error(s) during Scene update!", exceptionsDuringUpdate.DequeueAll().ToArray()); } // Trigger all continuation actions returned by the previously executed prepare tasks foreach (var actPrepareTasks in prepareRenderTasks) { if (actPrepareTasks.IsFaulted || actPrepareTasks.IsCanceled) { continue; } foreach (Action actContinuationAction in actPrepareTasks.Result) { actContinuationAction(); } } foreach (var actAction in additionalContinuationActions) { actAction(); } // Reset all dummy flags before rendering foreach (var actRenderLoop in renderingRenderLoops) { actRenderLoop.ResetFlagsBeforeRendering(); } // Unload all derigistered RenderLoops await UpdateRenderLoopRegistrationsAsync(renderingRenderLoops); } }
/// <summary> /// Updates this object for the given view. /// </summary> /// <param name="updateState">Current state of the update pass.</param> /// <param name="layerViewSubset">The layer view subset wich called this update method.</param> protected abstract void UpdateForViewInternal(SceneRelatedUpdateState updateState, ViewRelatedSceneLayerSubset layerViewSubset);
/// <summary> /// Updates the object. /// </summary> /// <param name="updateState">Current update state.</param> protected override void UpdateInternal(SceneRelatedUpdateState updateState) { //Calculates local transform matrix (transforms local space to world space) bool doRecreateShaderParameters = false; base.TransormationChanged = m_transformParamsChanged || updateState.ForceTransformUpdatesOnChilds; // Update local transform matrix if transform values have changed if (m_transformParamsChanged || updateState.ForceTransformUpdatesOnChilds) { m_transformParamsChanged = false; m_forceTransformUpdateOnChilds = this.HasChilds; doRecreateShaderParameters = true; // Calculate new transformation matrix switch (m_transformationType) { case SpacialTransformationType.ScalingTranslationEulerAngles: m_transform = Matrix4x4.CreateScale(m_scaling) * Matrix4x4.CreateFromYawPitchRoll(m_rotation.Y, m_rotation.X, m_rotation.Z) * Matrix4x4.CreateTranslation(m_position) * updateState.World.Top; break; case SpacialTransformationType.ScalingTranslationQuaternion: m_transform = Matrix4x4.CreateScale(m_scaling) * Matrix4x4.CreateFromQuaternion(m_rotationQuaternion) * Matrix4x4.CreateTranslation(m_position) * updateState.World.Top; break; case SpacialTransformationType.ScalingTranslationDirection: m_transform = Matrix4x4.CreateScale(m_scaling) * Matrix4x4Ex.CreateRotationDirection(m_rotationUp, m_rotationForward) * Matrix4x4.CreateTranslation(m_position) * updateState.World.Top; break; case SpacialTransformationType.ScalingTranslation: m_transform = Matrix4x4.CreateScale(m_scaling) * Matrix4x4.CreateTranslation(m_position) * updateState.World.Top; break; case SpacialTransformationType.TranslationEulerAngles: m_transform = Matrix4x4.CreateFromYawPitchRoll(m_rotation.Y, m_rotation.X, m_rotation.Z) * Matrix4x4.CreateTranslation(m_position) * updateState.World.Top; break; case SpacialTransformationType.TranslationQuaternion: m_transform = Matrix4x4.CreateFromQuaternion(m_rotationQuaternion) * Matrix4x4.CreateTranslation(m_position) * updateState.World.Top; break; case SpacialTransformationType.TranslationDirection: m_transform = Matrix4x4Ex.CreateRotationDirection(m_rotationUp, m_rotationForward) * Matrix4x4.CreateTranslation(m_position) * updateState.World.Top; break; case SpacialTransformationType.Translation: m_transform = Matrix4x4.CreateTranslation(m_position) * updateState.World.Top; break; case SpacialTransformationType.CustomTransform: m_transform = m_customTransform * updateState.World.Top; break; case SpacialTransformationType.TakeFromOtherObject: if (m_transformSourceObject != null) { m_transform = m_transformSourceObject.m_transform; } else { m_transform = updateState.World.Top; } break; case SpacialTransformationType.None: m_transform = updateState.World.Top; break; } } // Trigger recreation of shader parameters if (doRecreateShaderParameters) { TriggerRecreateOfParameters(); } }
/// <summary> /// Update logic for per object updates. /// Be careful: This method is called in parallel with these methods on other objects. /// For methods that depend on other object, use UpdateOverall. /// </summary> /// <param name="updateState">Current update state of the scene.</param> public abstract void Update(SceneRelatedUpdateState updateState);
internal override void UpdateInternal(SceneRelatedUpdateState updateState, ViewInformation correspondingView, object componentContext) { this.Update(updateState, correspondingView); }
/// <summary> /// Update logic for overall updates. /// This method should be used for update logic that also depends on other object. /// UpdateOverall methods are called sequentially object by object. /// </summary> /// <param name="updateState">Current update state of the scene.</param> public abstract void UpdateOverall(SceneRelatedUpdateState updateState);
/// <summary> /// Updates this object for the given view. /// </summary> /// <param name="updateState">Current state of the update pass.</param> /// <param name="layerViewSubset">The layer view subset wich called this update method.</param> protected override void UpdateForViewInternal(SceneRelatedUpdateState updateState, ViewRelatedSceneLayerSubset layerViewSubset) { }
internal abstract void UpdateInternal(SceneRelatedUpdateState updateState, ViewInformation correspondingView, object componentContext);