/// <summary> /// Waits until the given object is visible. /// </summary> /// <param name="sceneObjects">The scene objects to check for.</param> /// <param name="viewInfo">The view on which to check for visibility.</param> /// <param name="cancelToken">The cancellation token.</param> public Task WaitUntilVisibleAsync(IEnumerable <SceneObject> sceneObjects, ViewInformation viewInfo, CancellationToken cancelToken = default(CancellationToken)) { sceneObjects.EnsureNotNull(nameof(sceneObjects)); viewInfo.EnsureNotNull(nameof(viewInfo)); TaskCompletionSource <object> taskComplSource = new TaskCompletionSource <object>(); // Define the poll action (polling is done inside scene update Action pollAction = null; pollAction = () => { if (AreAllObjectsVisible(sceneObjects, viewInfo)) { taskComplSource.SetResult(null); } else if (cancelToken.IsCancellationRequested) { taskComplSource.SetCanceled(); } else { m_asyncInvokesBeforeUpdate.Enqueue(pollAction); } }; // Register first call of the polling action m_asyncInvokesBeforeUpdate.Enqueue(pollAction); return(taskComplSource.Task); }
/// <summary> /// Deregisters the given view from this scene object. /// This method is meant to be called by RenderLoop class. /// </summary> /// <param name="viewInformation">The view to deregister.</param> internal void DeregisterView(ViewInformation viewInformation) { viewInformation.EnsureNotNull(nameof(viewInformation)); // Check for registration // If there is no one, then the caller made an error if (!m_registeredViews.Contains(viewInformation)) { throw new SeeingSharpGraphicsException("The given view is not registered on this scene!"); } // Deregister the view on this scene and all layers int viewIndex = m_registeredViews.IndexOf(viewInformation); m_registeredViews.RemoveObject(viewInformation); foreach (SceneLayer actLayer in m_sceneLayers) { actLayer.DeregisterView(viewIndex, viewInformation); } // Clear view index viewInformation.ViewIndex = -1; // Mark this scene for deletion if we don't have any other view registered if ((m_registeredViews.Count <= 0) && (!this.DiscardAutomaticUnload)) { GraphicsCore.Current.MainLoop.RegisterSceneForUnload(this); } }
/// <summary> /// Tries the get information about a currently attached component. /// </summary> private bool TryGetAttachedComponent( SceneComponentBase component, ViewInformation correspondingView, out SceneComponentInfo componentInfo, out int componentIndex) { int attachedComponentCount = m_attachedComponents.Count; for (int loop = 0; loop < m_attachedComponents.Count; loop++) { if (component.IsViewSpecific) { if ((component == m_attachedComponents[loop].Component) && (correspondingView != null) && (correspondingView == m_attachedComponents[loop].CorrespondingView)) { componentInfo = m_attachedComponents[loop]; componentIndex = loop; return(true); } } else { if (component == m_attachedComponents[loop].Component) { componentInfo = m_attachedComponents[loop]; componentIndex = loop; return(true); } } } componentInfo = default(SceneComponentInfo); componentIndex = -1; return(false); }
/// <summary> /// Tries to set the visibility of this object on the given view. /// This method can be used to force rendering on the next frame after adding /// an object to the scene. /// </summary> /// <param name="viewInfo">The view on which to set the visibility.</param> /// <param name="isVisible">The visibility state to set.</param> public bool TrySetInitialVisibility(ViewInformation viewInfo, bool isVisible) { if (viewInfo.ViewIndex < 0) { return(false); } VisibilityCheckData checkData = this.GetVisibilityCheckData(viewInfo); if (checkData.IsVisible) { return(true); } if ((checkData.IsVisible != isVisible) && (checkData.FilterStageData.Count == 0)) { checkData.IsVisible = isVisible; return(true); } else { return(false); } }
/// <summary> /// Pushes a new render target onto the render target stack. /// </summary> /// <param name="viewport">The viewport object.</param> /// <param name="renderTargets">A structure containing all relevant render targets.</param> /// <param name="camera">The camera for the new render target.</param> /// <param name="viewInformation">The view information.</param> /// <exception cref="System.ObjectDisposedException">RenderState</exception> internal void PushRenderTarget( RenderTargets renderTargets, SharpDX.Mathematics.Interop.RawViewportF viewport, Camera3DBase camera, ViewInformation viewInformation) { if (m_disposed) { throw new ObjectDisposedException("RenderState"); } //Build new render stack entry RenderStackEntry newEntry = new RenderStackEntry(); newEntry.Matrix4Stack = new Matrix4Stack(); newEntry.Camera = camera; newEntry.RenderTargets = renderTargets; newEntry.SingleViewport = viewport; newEntry.ViewInformation = viewInformation; //Overtake device settings newEntry.Apply(m_device.DeviceImmediateContextD3D11); //Push new entry onto the stack m_renderSettingsStack.Push(m_currentRenderSettings); m_currentRenderSettings = newEntry; }
/// <summary> /// Detaches all currently attached components. /// </summary> /// <param name="sourceView">The view from which we've to detach all components.</param> internal void DetachAllComponents(ViewInformation sourceView) { m_componentRequests.Enqueue(new SceneComponentRequest() { RequestType = SceneComponentRequestType.DetachAll, CorrespondingView = sourceView }); }
/// <summary> /// Waits until the given object is visible on the given view. /// </summary> /// <param name="sceneObject">The scene object to be checked.</param> /// <param name="viewInfo">The view on which to check.</param> /// <param name="cancelToken">The cancellation token.</param> public Task WaitUntilVisibleAsync(SceneObject sceneObject, ViewInformation viewInfo, CancellationToken cancelToken = default(CancellationToken)) { sceneObject.EnsureNotNull(nameof(sceneObject)); sceneObject.EnsureNotNull(nameof(viewInfo)); return(WaitUntilVisibleAsync( new SceneObject[] { sceneObject }, viewInfo, cancelToken)); }
/// <summary> /// Registers the given view on this layer. /// </summary> internal void RegisterView(int viewIndex, ViewInformation viewInformation, ResourceDictionary resourceDictionary) { ViewRelatedSceneLayerSubset newLayerViewSubset = new ViewRelatedSceneLayerSubset(this, viewInformation, resourceDictionary, viewIndex); m_viewSubsets.AddObject( newLayerViewSubset, viewIndex); newLayerViewSubset.RegisterObjectRange(m_sceneObjects.ToArray()); }
/// <summary> /// Initializes a new instance of the <see cref="RenderState"/> class. /// </summary> internal RenderState( EngineDevice device, PerformanceAnalyzer performanceCalculator, RenderTargets renderTargets, SharpDX.Mathematics.Interop.RawViewportF viewport, Camera3DBase camera, ViewInformation viewInformation) : this(device, performanceCalculator) { Reset(renderTargets, viewport, camera, viewInformation); }
/// <summary> /// Gets the data object used for visibility checking. /// </summary> /// <param name="viewInfo">The VisibilityCheckData for this object for the given view.</param> internal VisibilityCheckData GetVisibilityCheckData(ViewInformation viewInfo) { VisibilityCheckData checkData = m_visibilityData[viewInfo.ViewIndex]; if (checkData == null) { checkData = m_visibilityData.AddObject( new VisibilityCheckData(), viewInfo.ViewIndex); } return(checkData); }
/// <summary> /// Deregisters the given view on this layer. /// </summary> /// <param name="viewIndex">The index which this view has on the current scene.</param> /// <param name="viewInformation">The ViewInformation object describing the view.</param> internal void DeregisterView(int viewIndex, ViewInformation viewInformation) { // Dispose the layer subset (removes all its resources) ViewRelatedSceneLayerSubset viewSubset = m_viewSubsets[viewIndex]; if (viewSubset != null) { viewSubset.ClearAllSubscriptions(m_sceneObjects); viewSubset.Dispose(); } // Remote the subset m_viewSubsets.RemoveObject(viewIndex); }
/// <summary> /// Ares all given scene objects visible currently? /// </summary> /// <param name="sceneObjects">The scene objects.</param> /// <param name="viewInfo">The view information.</param> public bool AreAllObjectsVisible(IEnumerable <SceneObject> sceneObjects, ViewInformation viewInfo) { sceneObjects.EnsureNotNull(nameof(sceneObjects)); viewInfo.EnsureNotNull(nameof(viewInfo)); foreach (var actObject in sceneObjects) { if (!actObject.IsVisible(viewInfo)) { return(false); } } return(true); }
/// <summary> /// Detaches the given component from this scene. /// </summary> /// <param name="component">The component to be detached.</param> /// <param name="sourceView">The view which attached the component initially.</param> internal void DetachComponent(SceneComponentBase component, ViewInformation sourceView) { component.EnsureNotNull(nameof(component)); if (component.IsViewSpecific) { sourceView.EnsureNotNull(nameof(sourceView)); } m_componentRequests.Enqueue(new SceneComponentRequest() { RequestType = SceneComponentRequestType.Detach, Component = component, CorrespondingView = component.IsViewSpecific ? sourceView : null }); }
/// <summary> /// Checks for visibility of the given object. /// </summary> /// <param name="input">The object to be checked..</param> /// <param name="viewInfo">The view on which to check for visibility.</param> public override bool IsObjectVisible(SceneObject input, ViewInformation viewInfo) { if (m_viewInfo == null) { return(true); } // Perform viewbox clipping if (!input.IsInBoundingFrustum(m_viewInfo, ref m_boundingFrustum)) { return(false); } // Handle Y-Filter if ((m_enableYFilter) && (m_yFilterMin != m_yFilterMax) && (m_yFilterMax > m_yFilterMin) && (m_yFilterMax - m_yFilterMin > 0.1f)) { SceneSpacialObject spacialObject = input as SceneSpacialObject; if (spacialObject != null) { // Get the bounding box of the object BoundingBox boundingBox = spacialObject.TryGetBoundingBox(viewInfo); if (boundingBox.IsEmpty()) { boundingBox = new BoundingBox(spacialObject.Position, spacialObject.Position + new Vector3(0.1f, 0.1f, 0.1f)); } // Perform some checks based on the bounding box if (boundingBox.UpperA.Y < m_yFilterMin) { return(false); } if (boundingBox.LowerA.Y > m_yFilterMax) { return(false); } } } // Object is visible return(true); }
/// <summary> /// Resets the render state. /// </summary> /// <param name="viewport">The viewport.</param> /// <param name="camera">The camera for the new render target.</param> /// <param name="viewInformation">The view information.</param> /// <param name="renderTargets">The render targets used for rendering.</param> internal void Reset( RenderTargets renderTargets, SharpDX.Mathematics.Interop.RawViewportF viewport, Camera3DBase camera, ViewInformation viewInformation) { m_renderSettingsStack.Clear(); m_sceneStack.Clear(); m_currentScene = null; m_world = new Matrix4Stack(Matrix4x4.Identity); //Inititialize current render properties m_currentRenderSettings = new RenderStackEntry(); m_currentRenderSettings.Matrix4Stack = new Matrix4Stack(); m_currentRenderSettings.RenderTargets = renderTargets; m_currentRenderSettings.SingleViewport = viewport; m_currentRenderSettings.Camera = camera; m_currentRenderSettings.ViewInformation = viewInformation; //Apply initial render properties m_currentRenderSettings.Apply(m_device.DeviceImmediateContextD3D11); }
/// <summary> /// Registers the given view on this scene object. /// This method is meant to be called by RenderLoop class. /// </summary> /// <param name="viewInformation">The view to register.</param> internal void RegisterView(ViewInformation viewInformation) { viewInformation.EnsureNotNull(nameof(viewInformation)); bool isFirstView = m_registeredViews.Count == 0; InitializeResourceDictionaries(true); // Register device on this scene if not done before // -> This registration is forever, no deregister is made! EngineDevice givenDevice = viewInformation.Device; if (!m_registeredResourceDicts.HasObjectAt(givenDevice.DeviceIndex)) { throw new SeeingSharpGraphicsException("ResourceDictionary of device " + givenDevice.AdapterDescription + " not loaded in this scene!"); } // Check for already done registration of this view // If there is any, then caller made an error if (m_registeredViews.Contains(viewInformation)) { throw new SeeingSharpGraphicsException("The given view is already registered on this scene!"); } // Register this view on this scene and on all layers int viewIndex = m_registeredViews.AddObject(viewInformation); foreach (SceneLayer actLayer in m_sceneLayers) { actLayer.RegisterView(viewIndex, viewInformation, m_registeredResourceDicts[givenDevice.DeviceIndex]); } viewInformation.ViewIndex = viewIndex; // Mark this scene for deletion if we don't have any other view registered if (isFirstView) { GraphicsCore.Current.MainLoop.DeregisterSceneForUnload(this); } }
/// <summary> /// Picks an object in 3D space. /// </summary> internal List <SceneObject> Pick(Vector3 rayStart, Vector3 rayDirection, ViewInformation viewInformation, PickingOptions pickingOptions) { rayDirection.EnsureNormalized(nameof(rayDirection)); viewInformation.EnsureNotNull(nameof(viewInformation)); pickingOptions.EnsureNotNull(nameof(pickingOptions)); // Query for all objects below the cursor List <Tuple <SceneObject, float> > pickedObjects = new List <Tuple <SceneObject, float> >(); foreach (SceneLayer actLayer in m_sceneLayers) { foreach (SceneObject actObject in actLayer.Objects) { if (!actObject.IsVisible(viewInformation)) { continue; } if (!actObject.IsPickingTestVisible) { continue; } float actDistance = actObject.Pick(rayStart, rayDirection, viewInformation, pickingOptions); if (!float.IsNaN(actDistance)) { pickedObjects.Add(Tuple.Create(actObject, actDistance)); } } } // Return all picked object in correct order return(pickedObjects .OrderBy((actObject) => actObject.Item2) .Convert((actObject) => actObject.Item1) .ToList()); }
/// <summary> /// Initializes a new instance of the <see cref="ViewRelatedSceneLayerSubset" /> class. /// </summary> internal ViewRelatedSceneLayerSubset(SceneLayer sceneLayer, ViewInformation viewInformation, ResourceDictionary resources, int viewIndex) { m_scene = sceneLayer.Scene; m_sceneLayer = sceneLayer; m_viewInformation = viewInformation; m_device = ViewInformation.Device; m_resources = resources; ViewIndex = viewIndex; m_invalidObjects = new Dictionary <SceneObject, object>(); m_invalidObjectsToDeregister = new Queue <SceneObject>(); // Create temporary collections m_tmpChangedVisibilities = new List <Tuple <SceneObject, bool, bool> >(); // Create all specialized render pass lists m_objectsPassPlainRender = new PassSubscribionProperties(); m_objectsPassLineRender = new PassSubscribionProperties(); m_objectsPassTransparentRender = new PassSubscribionProperties(); m_objectsPassSpriteBatchRender = new PassSubscribionProperties(); m_objectsPass2DOverlay = new PassSubscribionProperties(); // Create dictionary for fast access to all render pass list m_objectsPerPassDict = new Dictionary <RenderPassInfo, PassSubscribionProperties>(); m_objectsPerPassDict[RenderPassInfo.PASS_PLAIN_RENDER] = m_objectsPassPlainRender; m_objectsPerPassDict[RenderPassInfo.PASS_LINE_RENDER] = m_objectsPassLineRender; m_objectsPerPassDict[RenderPassInfo.PASS_TRANSPARENT_RENDER] = m_objectsPassTransparentRender; m_objectsPerPassDict[RenderPassInfo.PASS_SPRITE_BATCH] = m_objectsPassSpriteBatchRender; m_objectsPerPassDict[RenderPassInfo.PASS_2D_OVERLAY] = m_objectsPass2DOverlay; m_objectsPerPass = new List <PassSubscribionProperties>(m_objectsPerPassDict.Values); m_anythingUnsubscribed = false; // Create and load all render pass relevant resources RefreshDeviceDependentResources(); }
/// <summary> /// Is this object visible in the given view? /// </summary> /// <param name="viewInfo">The view info to check.</param> public bool IsVisible(ViewInformation viewInfo) { if (viewInfo.ViewIndex < 0) { throw new SeeingSharpGraphicsException("Given ViewInformation object is not assoziated to any view!"); } if (viewInfo.Scene == null) { throw new SeeingSharpGraphicsException("Given ViewInformation object is not attached to any scene!"); } if (viewInfo.Scene != this.Scene) { throw new SeeingSharpGraphicsException("Given ViewInformation object is not attached to this scene!"); } VisibilityCheckData checkData = m_visibilityData[viewInfo.ViewIndex]; if (checkData == null) { return(false); } return(checkData.IsVisible); }
/// <summary> /// Tries to get the bounding box for the given render-loop. /// Returns BoundingBox.Empty if it is not available. /// </summary> /// <param name="viewInfo">The ViewInformation for which to get the BoundingBox.</param> public override BoundingBox TryGetBoundingBox(ViewInformation viewInfo) { return(BoundingBox.Empty); }
/// <summary> /// Tries to get the bounding sphere for the given render-loop. /// Returns BoundingSphere.Empty, if it is not available. /// </summary> /// <param name="viewInfo">The ViewInformation for which to get the BoundingSphere.</param> public override BoundingSphere TryGetBoundingSphere(ViewInformation viewInfo) { return(BoundingSphere.Empty); }
/// <summary> /// Sets current environment data. /// </summary> /// <param name="layerToFilter">The SceneLayer that gets filtered.</param> /// <param name="viewInformation">The information object of the corresponding view.</param> public override void SetEnvironmentData(SceneLayer layerToFilter, ViewInformation viewInformation) { m_viewInfo = viewInformation; m_boundingFrustum = viewInformation.CameraBoundingFrustum; }
/// <summary> /// Tries to get the bounding sphere for the given render-loop. /// Returns BoundingSphere.Empty, if it is not available. /// </summary> /// <param name="viewInfo">The ViewInformation for which to get the BoundingSphere.</param> public abstract BoundingSphere TryGetBoundingSphere(ViewInformation viewInfo);
/// <summary> /// Checks for visibility of the given object. /// </summary> /// <param name="input">The object to be checked..</param> /// <param name="viewInformation">A reference to the view on which to check for visibility.</param> public abstract bool IsObjectVisible(SceneObject input, ViewInformation viewInformation);
/// <summary> /// Sets some informational data telling the filter where it is used. /// </summary> /// <param name="layerToFilter">The SceneLayer that gets filtered.</param> /// <param name="viewInformation">The information object of the corresponding view.</param> public virtual void SetEnvironmentData(SceneLayer layerToFilter, ViewInformation viewInformation) { }
/// <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> /// Detaches this component from a scene. /// Be careful, this method gets called from a background thread of seeing#! /// It may also be called from multiple scenes in parallel. /// </summary> /// <param name="manipulator">The manipulator of the scene we attach to.</param> /// <param name="correspondingView">The view which attached this component.</param> protected abstract void Detach(SceneManipulator manipulator, ViewInformation correspondingView);
internal override void UpdateInternal(SceneRelatedUpdateState updateState, ViewInformation correspondingView, object componentContext) { this.Update(updateState, correspondingView); }
internal override void DetachInternal(SceneManipulator manipulator, ViewInformation correspondingView, object componentContext) { this.Detach(manipulator, correspondingView); }
internal override object AttachInternal(SceneManipulator manipulator, ViewInformation correspondingView) { this.Attach(manipulator, correspondingView); return(null); }