コード例 #1
0
        private void CreateScene(bool useDXEngineHitTesting)
        {
            ObjectsPlaceholder.Children.Clear();

            if (_dxEventManager3D != null)
            {
                _dxEventManager3D.ResetEventSources3D();
                _dxEventManager3D = null;
            }

            if (_wpfEventManager != null)
            {
                _wpfEventManager.ResetEventSources3D();
                _wpfEventManager = null;
            }

            if (_instancedMeshGeometryVisual3D != null)
            {
                _instancedMeshGeometryVisual3D.Dispose();
            }


            _stopwatch = new Stopwatch();
            _stopwatch.Start();

            Mouse.OverrideCursor = Cursors.Wait;


            // Create InstancedGeometryVisual3D
            _instancedMeshGeometryVisual3D = new InstancedMeshGeometryVisual3D(_instanceMeshGeometry3D);

            _instancedMeshGeometryVisual3D.InstancesData = _instancedData;


            // Setup hit testing
            if (useDXEngineHitTesting)
            {
                // Use DXEventManager3D from Ab3d.DXEngine - it has optimized hit testing for instanced objects
                _dxEventManager3D = new Ab3d.DirectX.Utilities.DXEventManager3D(MainDXViewportView);

                var visualEventSource3D = new Ab3d.DirectX.Utilities.VisualEventSource3D(_instancedMeshGeometryVisual3D);
                visualEventSource3D.MouseEnter += delegate(object sender, DirectX.Common.EventManager3D.Mouse3DEventArgs e)
                {
                    var dxRayInstancedHitTestResult = e.RayHitResult as DXRayInstancedHitTestResult;
                    if (dxRayInstancedHitTestResult != null)
                    {
                        ProcessMouseEnter(dxRayInstancedHitTestResult.HitInstanceIndex);
                    }
                };

                visualEventSource3D.MouseMove += delegate(object sender, DirectX.Common.EventManager3D.Mouse3DEventArgs e)
                {
                    var dxRayInstancedHitTestResult = e.RayHitResult as DXRayInstancedHitTestResult;
                    if (dxRayInstancedHitTestResult != null)
                    {
                        ProcessMouseMove(dxRayInstancedHitTestResult.HitInstanceIndex);
                    }
                };

                visualEventSource3D.MouseLeave += delegate(object sender, DirectX.Common.EventManager3D.Mouse3DEventArgs e)
                {
                    ProcessMouseLeave();
                };

                _dxEventManager3D.RegisterEventSource3D(visualEventSource3D);
            }
            else
            {
                //
                // IMPORTANT:
                //
                // To make WPF hit testing work (also used by EventManager3D), you need to set the IsWpfHitTestVisible to true.
                // This increases initialization time because WPF objects needs to be created for each instance, but this makes the WPF hit testing work.
                _instancedMeshGeometryVisual3D.IsWpfHitTestVisible = true;


                _wpfEventManager = new Ab3d.Utilities.EventManager3D(MainViewport);

                // Because Viewport3D is actually not shown, we need to specify different WPF's object for the source of mouse events - this could be MainDXViewportView or even better a parent Border
                _wpfEventManager.CustomEventsSourceElement = MainDXViewportView;

                var visualEventSource3D = new Ab3d.Utilities.VisualEventSource3D(_instancedMeshGeometryVisual3D);
                visualEventSource3D.MouseEnter += delegate(object sender, Mouse3DEventArgs e)
                {
                    if (e.RayHitResult == null || e.RayHitResult.ModelHit == null)
                    {
                        return; // This should not happen, but it is safer to have this check anyway
                    }
                    // Get instance index of the hit object
                    int hitInstanceIndex = GetHitInstanceIndex(e.RayHitResult);

                    ProcessMouseEnter(hitInstanceIndex);
                };

                visualEventSource3D.MouseMove += delegate(object sender, Mouse3DEventArgs e)
                {
                    if (e.RayHitResult == null || e.RayHitResult.ModelHit == null)
                    {
                        return; // This should not happen, but it is safer to have this check anyway
                    }
                    // Get instance index of the hit object
                    int hitInstanceIndex = GetHitInstanceIndex(e.RayHitResult);

                    ProcessMouseMove(hitInstanceIndex);
                };

                visualEventSource3D.MouseLeave += delegate(object sender, Mouse3DEventArgs e)
                {
                    ProcessMouseLeave();
                };

                _wpfEventManager.RegisterEventSource3D(visualEventSource3D);
            }



            ObjectsPlaceholder.Children.Add(_instancedMeshGeometryVisual3D);

            Mouse.OverrideCursor = null;

            // If we would only change the InstancedData we would need to call Update method (but here this is not needed because we have set the data for the first time)
            //_instancedGeometryVisual3D.Update();
        }
コード例 #2
0
        public DXEventManager3DSample()
        {
            InitializeComponent();


            Box1Visual3D.SetName("Box1Visual3D");
            BoxesGroupVisual3D.SetName("BoxesGroupVisual3D");
            Box2Visual3D.SetName("Box2Visual3D");
            Box3Visual3D.SetName("Box3Visual3D");
            Box4Visual3D.SetName("Box4Visual3D");
            Line1.SetName("Line1");
            Line2.SetName("Line2");
            Rectangle1.SetName("Rectangle1");


            var meshGeometry3D = new Ab3d.Meshes.SphereMesh3D(centerPosition: new Point3D(0, 0, 0), radius: 5, segments: 20, generateTextureCoordinates: false).Geometry;

            // The following method prepare InstanceData array with data for each instance (WorldMatrix and Color)
            InstanceData[] instancedData = CreateInstancesData(new Point3D(0, 0, 0), new Size3D(200, 50, 50), modelScaleFactor: 1f, xCount: 10, yCount: 3, zCount: 3, useTransparency: false);


            // Create InstancedGeometryVisual3D with selected meshGeometry and InstancesData
            _instancedMeshGeometryVisual3D = new InstancedMeshGeometryVisual3D(meshGeometry3D);
            _instancedMeshGeometryVisual3D.InstancesData = instancedData;
            _instancedMeshGeometryVisual3D.SetName("InstancedMeshGeometryVisual3D");
            _instancedMeshGeometryVisual3D.Transform = new TranslateTransform3D(0, 50, 0);

            MainViewport3D.Children.Add(_instancedMeshGeometryVisual3D);

            _selectedInstanceIndex = -1;


            var model3DGroup = new Model3DGroup();

            model3DGroup.SetName("Model3DGroup");

            var frozenModel3DGroup = new Model3DGroup();

            frozenModel3DGroup.SetName("FrozenModel3DGroup");

            var box1Material = new DiffuseMaterial(Brushes.LightPink);
            var box2Material = new DiffuseMaterial(Brushes.LightCyan);

            var boxModel3D = Ab3d.Models.Model3DFactory.CreateBox(new Point3D(-100, 2, 25), new Size3D(60, 4, 50), box2Material);

            frozenModel3DGroup.Children.Add(boxModel3D);

            var pyramidModel3D = Ab3d.Models.Model3DFactory.CreatePyramid(new Point3D(-100, 2, 20), new Size3D(20, 20, 20), box2Material);

            frozenModel3DGroup.Children.Add(pyramidModel3D);

            for (int i = 0; i < 5; i++)
            {
                var geometryModel3D = new GeometryModel3D(meshGeometry3D, box1Material);
                geometryModel3D.Transform = new TranslateTransform3D(-130 + i * 15, 5, 80);
                geometryModel3D.SetName("GroupedSphere_" + i.ToString());

                model3DGroup.Children.Add(geometryModel3D);

                geometryModel3D           = new GeometryModel3D(meshGeometry3D, box2Material);
                geometryModel3D.Transform = new TranslateTransform3D(-130 + i * 15, 10, 50);
                geometryModel3D.SetName("FrozenGroupedSphere_" + i.ToString());

                frozenModel3DGroup.Children.Add(geometryModel3D);
            }


            frozenModel3DGroup.Freeze();

            MainViewport3D.Children.Add(model3DGroup.CreateModelVisual3D());
            MainViewport3D.Children.Add(frozenModel3DGroup.CreateModelVisual3D());

            _dxEventManager3D = new DXEventManager3D(MainDXViewportView);

            RegisterEventSource(Box1Visual3D);
            RegisterEventSource(BoxesGroupVisual3D);
            RegisterEventSource(Line1);
            RegisterEventSource(Line2);
            RegisterEventSource(Rectangle1);
            RegisterEventSource(_instancedMeshGeometryVisual3D);

            RegisterEventSource(model3DGroup);
            RegisterEventSource(frozenModel3DGroup);


            // Prevent TransparentPlaneVisual3D to be used by hit-testing
            _dxEventManager3D.RegisterExcludedVisual3D(TransparentPlaneVisual3D);


            this.PreviewMouseMove += delegate(object sender, MouseEventArgs args)
            {
                var position = args.GetPosition(this);
                MousePositionTextBlock.Text = $"Mouse pos: {position.X:0} {position.Y:0}";
            };

            this.PreviewMouseDown += delegate(object sender, MouseButtonEventArgs e)
            {
                var position = e.GetPosition(this);
                if (position == _lastMouseDownPosition)
                {
                    return;
                }

                System.Diagnostics.Debug.WriteLine("Mouse position: " + position.ToString());

                _lastMouseDownPosition = position;
            };


            // IMPORTANT:
            // It is very important to call Dispose method on DXSceneView after the control is not used any more (see help file for more info)
            this.Unloaded += (sender, args) => MainDXViewportView.Dispose();
        }