Exemplo n.º 1
0
        // This method is called approximately 60 times per second but only when RenderAt90Fps const is false
        private void CompositionTargetOnRendering(object sender, EventArgs eventArgs)
        {
            // It's possible for Rendering to call back twice in the same frame.
            // So only render when we haven't already rendered in this frame.
            var renderingEventArgs = eventArgs as System.Windows.Media.RenderingEventArgs;

            if (renderingEventArgs != null)
            {
                if (renderingEventArgs.RenderingTime == _lastRenderTime)
                {
                    return;
                }

                _lastRenderTime = renderingEventArgs.RenderingTime;
            }

            if (_dxViewportView == null || _dxViewportView.IsDisposed)
            {
                return; // Window closed
            }
            if (_oculusRiftVirtualRealityProvider != null && _oculusRiftVirtualRealityProvider.LastSessionStatus.ShouldQuit)
            {
                this.Close(); // Exit the application
            }
            if (_oculusRiftVirtualRealityProvider == null)
            {
                return;
            }


            UpdateScene();

            // Render the scene again
            _dxViewportView.Refresh();
        }
Exemplo n.º 2
0
        private void OnShowObjectOutlineCheckBoxCheckedChanged(object sender, RoutedEventArgs e)
        {
            if (!this.IsLoaded || _renderObjectOutlinesRenderingStep == null)
            {
                return;
            }

            _renderObjectOutlinesRenderingStep.IsEnabled = ShowObjectOutlineCheckBox.IsChecked ?? false;

            _mainDXViewportView.Refresh();
        }
Exemplo n.º 3
0
        private void CreateTestScene(int totalModelsCount)
        {
            Mouse.OverrideCursor = Cursors.Wait;

            // Creating Model3DGroup takes too much time when a lot of objects are created.
            // Therefore we are creating SceneNodes (MeshObjectNode) directly.

            //var model3DGroup = CreateModel3DGroup(boxMesh, new Point3D(0, 0, 0), new Size3D(400, 100, 400), 5, 40, 40, 40);
            //var model3DGroup = CreateModel3DGroup(boxMesh, new Point3D(0, 0, 0), new Size3D(400, 200, 400), 5, 40, 20, 40);
            //var model3DGroup = CreateModel3DGroup(boxMesh, new Point3D(0, 0, 0), new Size3D(400, 200, 400), 10, 10, 5, 10);
            //modelsCount = model3DGroup.Children.Count;

            //MainViewport.Children.Add(model3DGroup.CreateModelVisual3D());

            try
            {
                if (_sceneNodeVisual3D != null)
                {
                    _mainViewport3D.Children.Remove(_sceneNodeVisual3D);
                    _sceneNodeVisual3D.SceneNode.Dispose();
                }


                var boxMesh = new BoxMesh3D(new Point3D(0, 0, 0), new Size3D(1, 1, 1), 1, 1, 1).Geometry;

                int modelsXZCount = totalModelsCount < 2500 ? 10 : 50;
                int modelsYCount  = totalModelsCount / (modelsXZCount * modelsXZCount);

                var sceneNode = CreateSceneNodes(boxMesh, new Point3D(0, 0, 0), new Size3D(500, modelsYCount * 10, 500), 5, modelsXZCount, modelsYCount, modelsXZCount);

                _objectsCount = sceneNode.ChildNodesCount;

                _sceneNodeVisual3D = new SceneNodeVisual3D(sceneNode);
                _mainViewport3D.Children.Add(_sceneNodeVisual3D);

                _mainDXViewportView.Refresh();
            }
            finally
            {
                Mouse.OverrideCursor = null;
            }
        }
        private void CreateTestScene(int totalModelsCount)
        {
            Mouse.OverrideCursor = Cursors.Wait;

            // Creating Model3DGroup takes too much time when a lot of objects are created.
            // Therefore we are creating SceneNodes (MeshObjectNode) directly.

            //var model3DGroup = CreateModel3DGroup(boxMesh, new Point3D(0, 0, 0), new Size3D(400, 100, 400), 5, 40, 40, 40);
            //var model3DGroup = CreateModel3DGroup(boxMesh, new Point3D(0, 0, 0), new Size3D(400, 200, 400), 5, 40, 20, 40);
            //var model3DGroup = CreateModel3DGroup(boxMesh, new Point3D(0, 0, 0), new Size3D(400, 200, 400), 10, 10, 5, 10);
            //modelsCount = model3DGroup.Children.Count;

            //MainViewport.Children.Add(model3DGroup.CreateModelVisual3D());

            try
            {
                if (_disposables != null)
                {
                    _disposables.Dispose();
                }

                if (_sceneNodeVisual3D != null)
                {
                    _mainViewport3D.Children.Remove(_sceneNodeVisual3D);

                    _sceneNodeVisual3D.SceneNode.Dispose();
                    _sceneNodeVisual3D = null;
                }


                _disposables = new DisposeList();

                var boxMesh = new BoxMesh3D(new Point3D(0, 0, 0), new Size3D(1, 1, 1), 1, 1, 1).Geometry;

                int modelsXZCount = totalModelsCount < 2500 ? 10 : 50;
                int modelsYCount  = totalModelsCount / (modelsXZCount * modelsXZCount);

                bool useSingleColor = _currentObjectsType == ObjectsTypes.SingleColorBoxes || _currentObjectsType == ObjectsTypes.SingleColorLines;

                SceneNode sceneNode;

                if (_currentObjectsType == ObjectsTypes.MultiColorBoxes || _currentObjectsType == ObjectsTypes.SingleColorBoxes)
                {
                    sceneNode = CreateBoxSceneNodes(boxMesh, new Point3D(0, 0, 0), new Size3D(500, modelsYCount * 10, 500), 5, useSingleColor, modelsXZCount, modelsYCount, modelsXZCount);
                }
                else if (_currentObjectsType == ObjectsTypes.MultiColorLines || _currentObjectsType == ObjectsTypes.SingleColorLines)
                {
                    sceneNode = CreateLineSceneNodes(new Point3D(0, 0, 0), new Size3D(500, modelsYCount * 10, 500), useSingleColor, modelsXZCount, modelsYCount, modelsXZCount, _disposables);
                }
                else if (_currentObjectsType == ObjectsTypes.MultiColorBoxesAndLines)
                {
                    sceneNode = new SceneNode();
                    var sceneNode1 = CreateBoxSceneNodes(boxMesh, new Point3D(0, -modelsYCount * 2.5 - 10, 0), new Size3D(500, modelsYCount * 5, 500), 5, useSingleColor, modelsXZCount, modelsYCount / 2, modelsXZCount);
                    var sceneNode2 = CreateLineSceneNodes(new Point3D(0, modelsYCount * 2.5 + 10, 0), new Size3D(500, modelsYCount * 5, 500), useSingleColor, modelsXZCount, modelsYCount / 2, modelsXZCount, _disposables);

                    sceneNode.AddChild(sceneNode1);
                    sceneNode.AddChild(sceneNode2);
                }
                else
                {
                    sceneNode = null;
                }

                if (sceneNode == null)
                {
                    return;
                }

                _objectsCount = totalModelsCount;

                _sceneNodeVisual3D = new SceneNodeVisual3D(sceneNode);
                _mainViewport3D.Children.Add(_sceneNodeVisual3D);

                _mainDXViewportView.Refresh();
            }
            finally
            {
                Mouse.OverrideCursor = null;
            }
        }
 private void RenderSceneInternal()
 {
     dxViewportView.Refresh();
     isSceneDirty = false;
 }
Exemplo n.º 6
0
        private void InitializeOvrAndDirectX()
        {
            if (UseOculusRift)
            {
                // Initializing Oculus VR is very simple when using OculusWrapVirtualRealityProvider
                // First we create an instance of OculusWrapVirtualRealityProvider
                _oculusRiftVirtualRealityProvider = new OculusWrapVirtualRealityProvider(_ovr, multisamplingCount: 4);

                try
                {
                    // Then we initialize Oculus OVR and create a new DXDevice that uses the same adapter (graphic card) as Oculus Rift
                    _dxDevice = _oculusRiftVirtualRealityProvider.InitializeOvrAndDXDevice(requestedOculusSdkMinorVersion: 17);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Failed to initialize the Oculus runtime library.\r\nError: " + ex.Message, "Oculus error", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                string ovrVersionString = _ovr.GetVersionString();
                _originalWindowTitle = string.Format("DXEngine OculusWrap Sample (OVR v{0})", ovrVersionString);
                this.Title           = _originalWindowTitle;


                // Reset tracking origin at startup
                _ovr.RecenterTrackingOrigin(_oculusRiftVirtualRealityProvider.SessionPtr);
            }
            else
            {
                // Create DXDevice that will be used to create DXViewportView
                var dxDeviceConfiguration = new DXDeviceConfiguration();
                dxDeviceConfiguration.DriverType             = DriverType.Hardware;
                dxDeviceConfiguration.SupportedFeatureLevels = new FeatureLevel[] { FeatureLevel.Level_11_0 }; // Oculus requires at least feature level 11.0

                _dxDevice = new DXDevice(dxDeviceConfiguration);
                _dxDevice.InitializeDevice();

                _originalWindowTitle = this.Title;
            }



            // Create WPF's Viewport3D
            _viewport3D = new Viewport3D();

            // Create DXViewportView - a control that will enable DirectX 11 rendering of standard WPF 3D content defined in Viewport3D.
            // We use a specified DXDevice that was created by the _oculusRiftVirtualRealityProvider.InitializeOvrAndDXDevice (this way the same adapter is used by Oculus and DXEngine).
            _dxViewportView = new DXViewportView(_dxDevice, _viewport3D);

            _dxViewportView.BackgroundColor = Colors.Aqua;

            // Currently DXEngine support showing Oculus mirror texture only with DirectXOverlay presentation type (not with DirectXImage)
            _dxViewportView.PresentationType = DXView.PresentationTypes.DirectXOverlay;

            if (UseOculusRift)
            {
                // The _dxViewportView will show Oculus mirrow window.
                // The mirror window can be any size, for this sample we use 1/2 the HMD resolution.
                _dxViewportView.Width  = _oculusRiftVirtualRealityProvider.HmdDescription.Resolution.Width / 2.0;
                _dxViewportView.Height = _oculusRiftVirtualRealityProvider.HmdDescription.Resolution.Height / 2.0;
            }


            // When the DXViewportView is initialized, we set the _oculusRiftVirtualRealityProvider to the DXScene object
            _dxViewportView.DXSceneInitialized += delegate(object sender, EventArgs args)
            {
                if (_dxViewportView.UsedGraphicsProfile.DriverType != GraphicsProfile.DriverTypes.Wpf3D &&
                    _dxViewportView.DXScene != null &&
                    _oculusRiftVirtualRealityProvider != null)
                {
                    // Initialize Virtual reality rendering
                    _dxViewportView.DXScene.InitializeVirtualRealityRendering(_oculusRiftVirtualRealityProvider);


                    // Initialized shadow rendering (see Ab3d.DXEngine.Wpf.Samples project - DXEngine/ShadowRenderingSample for more info
                    _varianceShadowRenderingProvider = new VarianceShadowRenderingProvider()
                    {
                        ShadowMapSize          = 1024,
                        ShadowDepthBluringSize = 2,
                        ShadowTreshold         = 0.2f
                    };

                    _dxViewportView.DXScene.InitializeShadowRendering(_varianceShadowRenderingProvider);
                }
            };


            // Enable collecting rendering statistics (see _dxViewportView.DXScene.Statistics class)
            DXDiagnostics.IsCollectingStatistics = true;

            // Subscribe to SceneRendered to collect FPS statistics
            _dxViewportView.SceneRendered += DXViewportViewOnSceneRendered;

            // Add _dxViewportView to the RootGrid
            // Before that we resize the window to be big enough to show the mirrored texture
            this.Width  = _dxViewportView.Width + 30;
            this.Height = _dxViewportView.Height + 50;

            RootGrid.Children.Add(_dxViewportView);


            // Create FirstPersonCamera
            _camera = new FirstPersonCamera()
            {
                TargetViewport3D = _viewport3D,
                Position         = new Point3D(0, 1, 4),
                Heading          = 0,
                Attitude         = 0,
                ShowCameraLight  = ShowCameraLightType.Never
            };

            RootGrid.Children.Add(_camera);


            // Initialize XBOX controller that will control the FirstPersonCamera
            _xInputCameraController = new XInputCameraController();
            _xInputCameraController.TargetCamera  = _camera;
            _xInputCameraController.MovementSpeed = 0.02;
            _xInputCameraController.MoveVerticallyWithDPadButtons = true;

            // We handle the rotation by ourself to prevent rotating the camera up and down - this is done only by HMD
            _xInputCameraController.RightThumbChanged += delegate(object sender, XInputControllerThumbChangedEventArgs e)
            {
                // Apply only horizontal rotation
                _camera.Heading += e.NormalizedX * _xInputCameraController.RotationSpeed;

                // Mark the event as handled
                e.IsHandled = true;
            };

            _xInputCameraController.StartCheckingController();


            // Now we can create our sample 3D scene
            CreateSceneObjects();

            // Add lights
            var lightsVisual3D = new ModelVisual3D();
            var lightsGroup    = new Model3DGroup();

            var directionalLight = new DirectionalLight(Colors.White, new Vector3D(0.5, -0.3, -0.3));

            directionalLight.SetDXAttribute(DXAttributeType.IsCastingShadow, true); // Set this light to cast shadow
            lightsGroup.Children.Add(directionalLight);

            var ambientLight = new AmbientLight(System.Windows.Media.Color.FromRgb(30, 30, 30));

            lightsGroup.Children.Add(ambientLight);

            lightsVisual3D.Content = lightsGroup;
            _viewport3D.Children.Add(lightsVisual3D);


            // Start rendering
            if (RenderAt90Fps)
            {
                // WPF do not support rendering at more the 60 FPS.
                // But with a trick where a rendering loop is created in a background thread, it is possible to achieve more than 60 FPS.
                // In case of sumbiting frames to Oculus Rift, the ovr.SubmitFrame method will limit rendering to 90 FPS.
                //
                // NOTE:
                // When using DXEngine, it is also possible to render the scene in a background thread.
                // This requires that the 3D scene is also created in the background thread and that the events and other messages are
                // passed between UI and background thread in a thread safe way. This is too complicated for this simple sample project.
                // To see one possible implementation of background rendering, see the BackgroundRenderingSample in the Ab3d.DXEngine.Wpf.Samples project.
                var backgroundWorker = new BackgroundWorker();
                backgroundWorker.DoWork += (object sender, DoWorkEventArgs args) =>
                {
                    // Create an action that will be called by Dispatcher
                    var refreshDXEngineAction = new Action(() =>
                    {
                        UpdateScene();

                        // Render DXEngine's 3D scene again
                        if (_dxViewportView != null)
                        {
                            _dxViewportView.Refresh();
                        }
                    });

                    while (_dxViewportView != null && !_dxViewportView.IsDisposed)                                                       // Render until window is closed
                    {
                        if (_oculusRiftVirtualRealityProvider != null && _oculusRiftVirtualRealityProvider.LastSessionStatus.ShouldQuit) // Stop rendering - this will call RunWorkerCompleted where we can quit the application
                        {
                            break;
                        }

                        // Sleep for 1 ms to allow WPF tasks to complete (for example handling XBOX controller events)
                        System.Threading.Thread.Sleep(1);

                        // Call Refresh to render the DXEngine's scene
                        // This is a synchronous call and will wait until the scene is rendered.
                        // Because Oculus is limited to 90 fps, the call to ovr.SubmitFrame will limit rendering to 90 FPS.
                        Dispatcher.Invoke(refreshDXEngineAction);
                    }
                };

                backgroundWorker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs args)
                {
                    if (_oculusRiftVirtualRealityProvider != null && _oculusRiftVirtualRealityProvider.LastSessionStatus.ShouldQuit)
                    {
                        this.Close(); // Exit the application
                    }
                };

                backgroundWorker.RunWorkerAsync();
            }
            else
            {
                // Subscribe to WPF rendering event (called approximately 60 times per second)
                CompositionTarget.Rendering += CompositionTargetOnRendering;
            }
        }
Exemplo n.º 7
0
        private DXViewportView AddNewDXViewportView(DXViewportView masterDXViewportView, int rowIndex, int columnIndex, RenderingTypes renderingType, bool addToRootGrid = true, bool addDrawSelectionComboBox = true)
        {
            TargetPositionCamera  targetPositionCamera;
            MouseCameraController mouseCameraController;
            DXViewportView        dxViewportView = CreateSimpleDXSceneViewFromCode(masterDXViewportView, renderingType, out targetPositionCamera, out mouseCameraController);

            // Set random BackgroundColor - but do not make it to dark so start with 128
            dxViewportView.BackgroundColor = Color.FromRgb((byte)(_rnd.Next(128) + 128), (byte)(_rnd.Next(128) + 128), (byte)(_rnd.Next(128) + 128));

            _dxViewportViews.Add(dxViewportView);


            if (addToRootGrid)
            {
                var viewRootGrid = new Grid();

                var border = new Border()
                {
                    Background = Brushes.Transparent,
                    Margin     = new Thickness(1, 1, 3, 3)
                };

                border.Child = dxViewportView;
                mouseCameraController.EventsSourceElement = border;

                viewRootGrid.Children.Add(border);
                viewRootGrid.Children.Add(targetPositionCamera);
                viewRootGrid.Children.Add(mouseCameraController);

                Grid.SetColumn(viewRootGrid, columnIndex);
                Grid.SetRow(viewRootGrid, rowIndex);

                ViewsGrid.Children.Add(viewRootGrid);


                var textBlock = new TextBlock()
                {
                    HorizontalAlignment = HorizontalAlignment.Left,
                    VerticalAlignment   = VerticalAlignment.Top,
                    Margin = new Thickness(5, 5, 0, 0)
                };

                textBlock.Text = masterDXViewportView == null ? "Master DXScene:" : "Child DXScene:";
                viewRootGrid.Children.Add(textBlock);


                if (addDrawSelectionComboBox)
                {
                    var comboBox = new ComboBox()
                    {
                        HorizontalAlignment = HorizontalAlignment.Right,
                        VerticalAlignment   = VerticalAlignment.Top,
                        Margin = new Thickness(0, 3, 5, 0)
                    };

                    comboBox.ItemsSource   = RenderingTypeStrings;
                    comboBox.SelectedIndex = (int)renderingType;

                    if (masterDXViewportView == null)
                    {
                        comboBox.IsEditable = false; // Lock Standard for master view
                    }
                    comboBox.SelectionChanged += delegate(object sender, SelectionChangedEventArgs args)
                    {
                        var newRenderingType = (RenderingTypes)comboBox.SelectedIndex;
                        SetSpecialRenderingType(dxViewportView, newRenderingType);

                        dxViewportView.Refresh(); // Render the scene again
                    };

                    viewRootGrid.Children.Add(comboBox);
                }
            }

            return(dxViewportView);
        }