/// <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) { sceneObjects.EnsureNotNull(nameof(sceneObjects)); viewInfo.EnsureNotNull(nameof(viewInfo)); var taskComplSource = new TaskCompletionSource <object?>(TaskCreationOptions.RunContinuationsAsynchronously); // Define the poll action (polling is done inside scene update void PollAction() { if (this.AreAllObjectsVisible(sceneObjects, viewInfo)) { taskComplSource.SetResult(null); } else if (cancelToken.IsCancellationRequested) { taskComplSource.SetCanceled(); } else { _asyncInvokesBeforeUpdate.Enqueue(PollAction); } } // Register first call of the polling action _asyncInvokesBeforeUpdate.Enqueue(PollAction); return(taskComplSource.Task); }
/// <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) { sceneObject.EnsureNotNull(nameof(sceneObject)); sceneObject.EnsureNotNull(nameof(viewInfo)); return(this.WaitUntilVisibleAsync( new[] { sceneObject }, viewInfo, cancelToken)); }
/// <summary> /// Initializes a new instance of the <see cref="RenderState"/> class. /// </summary> internal RenderState( EngineDevice device, RenderTargets renderTargets, Viewport viewport, Camera3DBase camera, ViewInformation viewInformation) : this(device) { this.Reset(renderTargets, viewport, camera, viewInformation); }
/// <summary> /// Handles mouse or pointer input from the given view. /// </summary> /// <param name="viewInfo">The view for which to handle input.</param> /// <param name="inputHandlingAction">The action which reacts on input.</param> public void HandleMouseOrPointerInput(ViewInformation viewInfo, Action <MouseOrPointerState> inputHandlingAction) { foreach (var actInputFame in _inputFrames) { foreach (var actInputState in actInputFame.TryGetStates <MouseOrPointerState>(viewInfo)) { inputHandlingAction(actInputState); } } }
/// <summary> /// Handles keyboard input from the given view. /// </summary> /// <param name="viewInfo">The view for which to handle input.</param> /// <param name="inputHandlingAction">The action which reacts on input.</param> public void HandleKeyboardInput(ViewInformation viewInfo, Action <KeyboardState> inputHandlingAction) { foreach (var actInputFame in _inputFrames) { foreach (var actInputState in actInputFame.TryGetStates <KeyboardState>(viewInfo)) { inputHandlingAction(actInputState); } } }
/// <summary> /// Registers the given view on this layer. /// </summary> internal void RegisterView(int viewIndex, ViewInformation viewInformation, ResourceDictionary resourceDictionary) { var newLayerViewSubset = new ViewRelatedSceneLayerSubset(this, viewInformation, resourceDictionary, viewIndex); _viewSubsets.AddObject( newLayerViewSubset, viewIndex); newLayerViewSubset.RegisterObjectRange(this.ObjectsInternal); }
/// <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)); var isFirstView = _registeredViews.Count == 0; this.InitializeResourceDictionaries(); // Register device on this scene if not done before // -> This registration is forever, no deregister is made! var givenDevice = viewInformation.Device; var resourceDictionary = _registeredResourceDicts[givenDevice !.DeviceIndex];
/// <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> /// 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) var viewSubset = _viewSubsets[viewIndex]; if (viewSubset != null) { viewSubset.ClearAllSubscriptions(this.ObjectsInternal); viewSubset.Dispose(); } // Remote the subset _viewSubsets.RemoveObject(viewIndex); }
/// <summary> /// Initializes a new instance of the <see cref="ViewRelatedSceneLayerSubset" /> class. /// </summary> internal ViewRelatedSceneLayerSubset(SceneLayer sceneLayer, ViewInformation viewInformation, ResourceDictionary resources, int viewIndex) { _scene = sceneLayer.Scene; _sceneLayer = sceneLayer; this.ViewInformation = viewInformation; _device = this.ViewInformation.Device !; _resources = resources; ViewIndex = viewIndex; _invalidObjects = new Dictionary <SceneObject, object?>(); _invalidObjectsToDeregister = new Queue <SceneObject>(); // Create temporary collections _tmpChangedVisibilities = new List <Tuple <SceneObject, bool, bool> >(); // Create all specialized render pass lists _objectsPassPlainRender = new PassSubscriptionProperties(); _objectsPassLineRender = new PassSubscriptionProperties(); _objectsPassTransparentRender = new PassSubscriptionProperties(); _objectsPassSpriteBatchRender = new PassSubscriptionProperties(); _objectsPass2DOverlay = new PassSubscriptionProperties(); // Create dictionary for fast access to all render pass list _objectsPerPassDict = new Dictionary <RenderPassInfo, PassSubscriptionProperties> { [RenderPassInfo.PASS_PLAIN_RENDER] = _objectsPassPlainRender, [RenderPassInfo.PASS_LINE_RENDER] = _objectsPassLineRender, [RenderPassInfo.PASS_TRANSPARENT_RENDER] = _objectsPassTransparentRender, [RenderPassInfo.PASS_SPRITE_BATCH] = _objectsPassSpriteBatchRender, [RenderPassInfo.PASS_2D_OVERLAY] = _objectsPass2DOverlay }; _objectsPerPass = new List <PassSubscriptionProperties>(_objectsPerPassDict.Values); _anythingUnsubscribed = false; // Create and load all render pass relevant resources this.RefreshDeviceDependentResources(); }
/// <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 var pickedObjects = new List <Tuple <SceneObject, float> >(); foreach (var actLayer in _sceneLayers) { foreach (var actObject in actLayer.Objects) { if (!actObject.IsVisible(viewInformation)) { continue; } if (!actObject.IsPickingTestVisible) { continue; } var 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> /// 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(default);
/// <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> /// 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);