/// <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> /// 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> /// 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> /// 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> /// Is the given view registered on this scene? /// </summary> /// <param name="viewInformation">The view to check for.</param> internal bool IsViewRegistered(ViewInformation viewInformation) { viewInformation.EnsureNotNull(nameof(viewInformation)); return(m_registeredViews.Contains(viewInformation)); }