/// <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;
            }
        }
Example #2
0
        /// <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);
            }
        }
Example #3
0
 /// <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);
     }
 }
Example #4
0
        /// <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);
            }
        }
Example #5
0
        /// <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;
            }
        }
Example #6
0
        /// <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();
            }
        }
Example #7
0
        /// <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);
            }
        }
Example #8
0
 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;
                }
            }
        }
Example #10
0
        /// <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);
                }
            }
        }
Example #11
0
 /// <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);
 }
Example #12
0
        /// <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);
                    }
                };
            }
        }
Example #13
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!");
                    }
                }
            }
        }
Example #14
0
 /// <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)
 {
 }
Example #15
0
 /// <summary>
 /// Updates the object.
 /// </summary>
 /// <param name="updateState">Current update state.</param>
 protected abstract void UpdateInternal(SceneRelatedUpdateState updateState);
Example #16
0
 protected sealed override void UpdateForViewInternal(SceneRelatedUpdateState updateState, ViewRelatedSceneLayerSubset layerViewSubset)
 {
     // No resources, so nothing to be done
 }
Example #17
0
        /// <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;
                }
            }
        }
Example #18
0
        /// <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);
            }
        }
Example #19
0
 /// <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);
Example #22
0
 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)
 {
 }
Example #25
0
 internal abstract void UpdateInternal(SceneRelatedUpdateState updateState, ViewInformation correspondingView, object componentContext);