void EventManagerDragSample_Loaded(object sender, RoutedEventArgs e)
        {
            _eventManager = new Ab3d.Utilities.EventManager3D(Viewport3D1);

            // When using EventManager3D from Ab3d.PowerToys inside DXEngine,
            // it is recommended to set the CustomEventsSourceElement to the DXViewportView or its parent element (for example ViewportBorder).
            // If this is not done, then EventManager3D tries to find the DXViewportView and when found uses it as an element that used to subscribe to mouse events.
            _eventManager.CustomEventsSourceElement = ViewportBorder;


            // Exclude TransparentPlaneVisual3D from hit testing
            _eventManager.RegisterExcludedVisual3D(TransparentPlaneVisual3D);


            var multiEventSource3D = new Ab3d.Utilities.MultiVisualEventSource3D();

            multiEventSource3D.TargetVisuals3D = new Visual3D[] { LowerBoxVisual3D, PassageBoxVisual3D, UpperBoxVisual3D };
            multiEventSource3D.IsDragSurface   = true;

            _eventManager.RegisterEventSource3D(multiEventSource3D);


            var eventSource3D = new Ab3d.Utilities.VisualEventSource3D();

            eventSource3D.TargetVisual3D = MovableBoxVisual3D;
            eventSource3D.Name           = "Movable";
            eventSource3D.MouseEnter    += new Ab3d.Common.EventManager3D.Mouse3DEventHandler(eventSource3D_MouseEnter);
            eventSource3D.MouseLeave    += new Ab3d.Common.EventManager3D.Mouse3DEventHandler(eventSource3D_MouseLeave);
            eventSource3D.MouseClick    += new Ab3d.Common.EventManager3D.MouseButton3DEventHandler(movableEventSource3D_MouseClick);
            eventSource3D.MouseDrag     += new Ab3d.Common.EventManager3D.MouseDrag3DEventHandler(movableEventSource3D_MouseDrag);

            _eventManager.RegisterEventSource3D(eventSource3D);
        }
Пример #2
0
        // Creates EventManager3D and subscribes the 3d objects to events
        private void SubscribeEvents()
        {
            // Create EventManager3D with MainViewport as constructor parameter
            var eventManager = new Ab3d.Utilities.EventManager3D(MainViewport);


            // Create EventSource3D for the Landscape
            // Each 3D object that needs to participate in the events needs to be registered by EventSource3D
            // The Landscape object will not be subscribed to any event, but instead it is only registered as DragSurface
            // This means that other objects can be drag over this 3D model.
            var eventSource = new Ab3d.Utilities.ModelEventSource3D();

            eventSource.TargetModel3D = _landscapeModel;
            eventSource.IsDragSurface = true;

            // Register the Landscape's EventSource3D
            eventManager.RegisterEventSource3D(eventSource);


            // Now for each wind generator create its own EventSource3D object
            for (int i = 0; i < _windGenerators.Count; i++)
            {
                // Create new EventSource3D
                eventSource = new Ab3d.Utilities.ModelEventSource3D();

                // Set the target object to the 3D model
                eventSource.TargetModel3D = _windGenerators[i].Model;

                // We can assign any custom data (object) to the EventSource3D
                // This is very useful because in event handler we can access this custom data
                eventSource.CustomData = _windGenerators[i];

                // Each wind generator is subscribed to the following events:
                eventSource.MouseEnter += OnWindGeneratorMouseEnter;
                eventSource.MouseLeave += OnWindGeneratorMouseLeave;

                eventSource.BeginMouseDrag += OnWindGeneratorBeginMouseDrag;
                eventSource.MouseDrag      += OnWindGeneratorMouseDrag;
                eventSource.EndMouseDrag   += OnWindGeneratorEndMouseDrag;

                // Not used events:
                //eventSource.MouseClick += new eventSource_MouseClick;
                //eventSource.MouseDown += new eventSource_MouseDown;
                //eventSource.MouseUp += eventSource_MouseUp;


                // Register the EventSource3D to the EventManager3D
                eventManager.RegisterEventSource3D(eventSource);
            }
        }
        private void CreateRandomScene()
        {
            SceneObjectsContainer.Children.Clear();

            for (int i = 0; i < 10; i++)
            {
                var boxModel = new Ab3d.Visuals.BoxVisual3D()
                {
                    CenterPosition = new Point3D(_rnd.NextDouble() * 400 - 200, _rnd.NextDouble() * 40 - 20, _rnd.NextDouble() * 400 - 200),
                    Size           = new Size3D(50, 20, 50),
                    Material       = _normalMaterial
                };

                SceneObjectsContainer.Children.Add(boxModel);


                // Use EventManager from Ab3d.PowerToys to add support for click event on the box model
                var visualEventSource3D = new Ab3d.Utilities.VisualEventSource3D(boxModel);
                visualEventSource3D.MouseClick += delegate(object sender, MouseButton3DEventArgs e)
                {
                    var selectedBoxModel = e.HitObject as Ab3d.Visuals.BoxVisual3D;
                    SelectObject(selectedBoxModel);
                };

                _eventManager.RegisterEventSource3D(visualEventSource3D);


                // Automatically select first box
                if (_selectedBoxModel == null)
                {
                    SelectObject(boxModel);
                }
            }
        }
Пример #4
0
        private void CreateRandomScene()
        {
            SceneObjectsContainer.Children.Clear();

            for (int i = 0; i < 10; i++)
            {
                // Create simple box that user will be able to rotate
                // In order to support rotation, we need to create the box at (0,0,0)
                // and then after performing rotation, translate the object to its final location.
                // If we would create the object at its final rotation (basically applying translation before rotation),
                // then the box would not be rotated around its center but around the coordinate axes center.
                var boxModel = new Ab3d.UIElements.BoxUIElement3D()
                {
                    CenterPosition = new Point3D(0, 0, 0),
                    Size           = new Size3D(50, 20, 50),
                    Material       = _normalMaterial
                };


                // Create a StandardTransform3D
                // StandardTransform3D is a class that generates a MatrixTransform3D based on the translate, rotate and scale transform.
                // Note that because it is not possible to derive from WPF's Transform3D, the StandardTransform3D is a standalone class
                // that provides its own MatrixTransform3D object that can be assigned to the 3D model.
                // Its static SetStandardTransform3D and GetStandardTransform3D use a custom StandardTransform3DProperty
                // to "attach" the StandardTransform3D object to Model3D or Visual3D. But this does not automatically set the
                // object's transformation.
                var standardTransform3D = new StandardTransform3D()
                {
                    TranslateX = _rnd.NextDouble() * 400 - 200,
                    TranslateY = _rnd.NextDouble() * 40 - 20,
                    TranslateZ = _rnd.NextDouble() * 400 - 200,
                };

                // SetStandardTransform3D method will set the StandardTransform3DProperty to the standardTransform3D
                // The updateTransform3D argument will also set the boxModel.Transform to standardTransform3D.Transform
                StandardTransform3D.SetStandardTransform3D(boxModel, standardTransform3D, updateTransform3D: true);


                SceneObjectsContainer.Children.Add(boxModel);


                // Use EventManager from Ab3d.PowerToys to add support for click event on the box model
                var visualEventSource3D = new Ab3d.Utilities.VisualEventSource3D(boxModel);
                visualEventSource3D.MouseClick += delegate(object sender, MouseButton3DEventArgs e)
                {
                    var selectedBoxModel = e.HitObject as Ab3d.UIElements.BoxUIElement3D;
                    SelectObject(selectedBoxModel);
                };

                _eventManager.RegisterEventSource3D(visualEventSource3D);


                // Automatically select first box
                if (_selectedBoxModel == null)
                {
                    boxModel.Refresh(); // Force creating the model
                    SelectObject(boxModel);
                }
            }
        }
Пример #5
0
        private void RegisterMouseEventsOnBoxVisual(BoxVisual3D boxVisual3D, Ab3d.Utilities.EventManager3D eventManager3D)
        {
            var visualEventSource3D = new VisualEventSource3D(boxVisual3D);

            visualEventSource3D.MouseEnter += delegate(object sender, Mouse3DEventArgs e)
            {
                ClearMouseOverBoxVisual();

                var hitBoxVisual3D = e.HitObject as BoxVisual3D;

                if (hitBoxVisual3D != null && !ReferenceEquals(hitBoxVisual3D, _currentlySelectedBoxVisual3D))
                {
                    _savedMouseOverMaterial = hitBoxVisual3D.Material;

                    hitBoxVisual3D.Material      = _mouseOverBoxMaterial;
                    _currentMouseOverBoxVisual3D = hitBoxVisual3D;
                }

                Mouse.OverrideCursor = Cursors.Hand;
            };

            visualEventSource3D.MouseLeave += delegate(object sender, Mouse3DEventArgs e)
            {
                var hitBoxVisual3D = e.HitObject as BoxVisual3D;

                if (!ReferenceEquals(hitBoxVisual3D, _currentlySelectedBoxVisual3D))
                {
                    ClearMouseOverBoxVisual();
                }
                else
                {
                    _currentMouseOverBoxVisual3D = null;
                }

                Mouse.OverrideCursor = null;
            };

            visualEventSource3D.MouseClick += delegate(object sender, MouseButton3DEventArgs e)
            {
                ClearSelectedBoxVisual();

                var hitBoxVisual3D = e.HitObject as BoxVisual3D;

                if (hitBoxVisual3D != null)
                {
                    hitBoxVisual3D.Material       = _selectedBoxMaterial;
                    _currentlySelectedBoxVisual3D = hitBoxVisual3D;

                    Camera1.RotationCenterPosition = hitBoxVisual3D.CenterPosition;
                }
            };


            eventManager3D.RegisterEventSource3D(visualEventSource3D);
        }
Пример #6
0
        public TouchManipulationsSample()
        {
            InitializeComponent();


            // First, create an instace of EventManager3D for MainViewport
            _eventManager = new Ab3d.Utilities.EventManager3D(MainViewport);

            // Setting CustomEventsSourceElement to a Border that has Background defind (can also be set to Transparent, but should not be null)
            // allows EventManager3D to get events even if touch is not over any 3D model.
            // For example when moving the model with touch, the model may move away from the fingers
            _eventManager.CustomEventsSourceElement = ViewportBorder;

            // IMPORTANT:
            // We need to manually enable the manipulation events.
            // Otherwise we will only get mouse events (also those mouse events that are created from touch events)
            //
            // NOTE:
            // When IsManipulationEnabled, the mouse events will not be created from touch events.
            _eventManager.IsManipulationEnabled = true;


            // Now create an instance of VisualEventSource3D
            // It will be used to define the TeapotVisual3D as source of touch events
            var visualEventSource3D = new VisualEventSource3D(TeapotVisual3D);

            // Now we can subscribe to manipulation events (we could also subscribe to mouse events)
            visualEventSource3D.ManipulationStarted += delegate(object o, Manipulation3DEventArgs <ManipulationStartedEventArgs> e)
            {
                TeapotVisual3D.DefaultMaterial = new DiffuseMaterial(Brushes.Red);
            };

            visualEventSource3D.ManipulationCompleted += delegate(object o, Manipulation3DEventArgs <ManipulationCompletedEventArgs> e)
            {
                TeapotVisual3D.DefaultMaterial = new DiffuseMaterial(Brushes.Silver);
            };

            visualEventSource3D.ManipulationDelta += VisualEventSource3DOnManipulationDelta;

            // Register the teapot as an event source on EventManager3D
            _eventManager.RegisterEventSource3D(visualEventSource3D);



            // Finally, we need to disable touch events on MouseCameraController
            // Otherwise both MouseCameraController and EventManager3D will handle the same events (also zooming and rotating the camera)
            MouseCameraController1.IsTouchMoveEnabled   = false;
            MouseCameraController1.IsTouchRotateEnabled = false;
            MouseCameraController1.IsTouchZoomEnabled   = false;
        }
Пример #7
0
        private void Setup3DObjects()
        {
            _eventManager3D = new Ab3d.Utilities.EventManager3D(MainViewport);


            var wireGridVisual3D = new Ab3d.Visuals.WireGridVisual3D()
            {
                Size             = new System.Windows.Size(1000, 1000),
                HeightCellsCount = 10,
                WidthCellsCount  = 10,
                LineThickness    = 3
            };

            MainViewport.Children.Add(wireGridVisual3D);


            // Create 7 x 7 boxes with different height
            for (int y = -3; y <= 3; y++)
            {
                for (int x = -3; x <= 3; x++)
                {
                    // Height is based on the distance from the center
                    double height = (5 - Math.Sqrt(x * x + y * y)) * 60;

                    // Create the 3D Box visual element

                    var boxVisual3D = new Ab3d.Visuals.BoxVisual3D()
                    {
                        CenterPosition = new Point3D(x * 100, height / 2, y * 100),
                        Size           = new Size3D(80, height, 80),
                        Material       = _normalMaterial
                    };

                    MainViewport.Children.Add(boxVisual3D);


                    var visualEventSource3D = new VisualEventSource3D(boxVisual3D);
                    visualEventSource3D.MouseEnter += BoxOnMouseEnter;
                    visualEventSource3D.MouseLeave += BoxOnMouseLeave;
                    visualEventSource3D.MouseClick += BoxOnMouseClick;

                    _eventManager3D.RegisterEventSource3D(visualEventSource3D);
                }
            }

            ToggleCameraAnimation(); // Start camer animation
        }
Пример #8
0
        private void CreateRandomScene()
        {
            SceneObjectsContainer.Children.Clear();

            for (int i = 0; i < 10; i++)
            {
                // Create simple box that user will be able to rotate
                // In order to support rotation, we need to create the box at (0,0,0)
                // and then after performing rotation, translate the object to its final location.
                // If we would create the object at its final rotation (basically applying translation before rotation),
                // then the box would not be rotated around its center but around the coordinate axes center.
                var boxModel = new Ab3d.UIElements.BoxUIElement3D()
                {
                    CenterPosition = new Point3D(0, 0, 0),
                    Size           = new Size3D(50, 20, 50),
                    Material       = _normalMaterial
                };

                // Create Transform3DGroup that will hold the
                var transform3DGroup = new Transform3DGroup();
                transform3DGroup.Children.Add(new TranslateTransform3D(_rnd.NextDouble() * 400 - 200, _rnd.NextDouble() * 40 - 20, _rnd.NextDouble() * 400 - 200));

                boxModel.Transform = transform3DGroup;

                SceneObjectsContainer.Children.Add(boxModel);


                // Use EventManager from Ab3d.PowerToys to add support for click event on the box model
                var visualEventSource3D = new Ab3d.Utilities.VisualEventSource3D(boxModel);
                visualEventSource3D.MouseClick += delegate(object sender, MouseButton3DEventArgs e)
                {
                    var selectedBoxModel = e.HitObject as Ab3d.UIElements.BoxUIElement3D;
                    SelectObject(selectedBoxModel);
                };

                _eventManager.RegisterEventSource3D(visualEventSource3D);


                // Automatically select first box
                if (_selectedBoxModel == null)
                {
                    boxModel.Refresh(); // Force creating the model
                    SelectObject(boxModel);
                }
            }
        }
        public ModelDecoratorSample()
        {
            InitializeComponent();

            // Use EventManager3D to subscribe to MouseMove and MouseLeave events on RobotArmModel
            _eventManager3D = new Ab3d.Utilities.EventManager3D(MainViewport);

            var visualEventSource3D = new VisualEventSource3D(RobotArmModel); // RobotArmModel is a source of events

            visualEventSource3D.MouseMove  += VisualEventSource3DOnMouseMove;
            visualEventSource3D.MouseLeave += VisualEventSource3DOnMouseLeave;

            _eventManager3D.RegisterEventSource3D(visualEventSource3D);

            // !!! IMPORTANT !!!
            // We need to exclude ModelDecorator from events
            // otherwise when mouse would be over line drawin with ModelDecorator we would get a MouseLeave event
            _eventManager3D.RegisterExcludedVisual3D(ModelDecorator);
        }
Пример #10
0
        private void SetModel(Model3D model)
        {
            Point3D center;
            double  size;

            GetModelCenterAndSize(model, out center, out size);

            Camera1.TargetPosition = center;
            Camera1.Distance       = size * 2;

            if (!(PreserveModelColorCheckBox.IsChecked ?? false))
            {
                if (model.IsFrozen)
                {
                    model = model.Clone();
                }

                Ab3d.Utilities.ModelUtils.ChangeMaterial(model, new DiffuseMaterial(Brushes.White), newBackMaterial: null);
            }

            _rootModel = model;

            OriginalModelVisual.Content = model;
            SelectObject(null);

            var modelEventSource3D = new ModelEventSource3D(model);

            modelEventSource3D.MouseLeave += ModelEventSource3DOnMouseLeave;
            modelEventSource3D.MouseMove  += ModelEventSource3DOnMouseMove;

            _eventManager3D.ResetEventSources3D();
            _eventManager3D.RegisterEventSource3D(modelEventSource3D);

            // Exclude WireframeVisual from hit testing
            _eventManager3D.RegisterExcludedVisual3D(WireframeVisual);
        }
        private void CreateSceneObjects()
        {
            for (int x = 0; x < 10; x++)
            {
                for (int y = 0; y < 4; y++)
                {
                    var boxVisual3D = new Ab3d.Visuals.BoxVisual3D()
                    {
                        CenterPosition = new Point3D(-100 + 20 * x, 50 + y * 30, 0),
                        Size           = new Size3D(10, 10, 10),
                        Material       = _standardMaterial
                    };

                    if (x == 4 && y == 2)
                    {
                        boxVisual3D.Material = _selectedMaterial;
                        _selectedModel       = boxVisual3D;
                    }

                    SelectionRootModelVisual3D.Children.Add(boxVisual3D);
                }
            }

            var eventManager3D = new Ab3d.Utilities.EventManager3D(MainViewport);

            var multiVisualEventSource3D = new MultiVisualEventSource3D(SelectionRootModelVisual3D.Children);

            multiVisualEventSource3D.MouseEnter += delegate(object sender, Mouse3DEventArgs args)
            {
                Mouse.OverrideCursor = Cursors.Hand;
            };

            multiVisualEventSource3D.MouseLeave += delegate(object sender, Mouse3DEventArgs args)
            {
                Mouse.OverrideCursor = null;
            };

            multiVisualEventSource3D.MouseClick += delegate(object sender, MouseButton3DEventArgs e)
            {
                if (_selectedModel != null)
                {
                    _selectedModel.Material = _standardMaterial;
                }

                var baseModelVisual3D = e.HitObject as Ab3d.Visuals.BaseModelVisual3D;
                if (baseModelVisual3D != null)
                {
                    baseModelVisual3D.Material = _selectedMaterial;
                    _selectedModel             = baseModelVisual3D;
                }
                else
                {
                    _selectedModel = null;
                }

                string logText = string.Format("Camera1.TurnTo(new Point3D({0:0}, {1:0}, {2:0})", e.FinalPointHit.X, e.FinalPointHit.Y, e.FinalPointHit.Z);

                if (AnimateCheckBox.IsChecked ?? false)
                {
                    // Animate the camera turn. Animation duration is 0.5 second and use QuadraticEaseInOutFunction for easing.
                    Camera1.TurnTo(position: e.FinalPointHit,
                                   animationDurationInMilliseconds: 500,
                                   easingFunction: Ab3d.Animation.EasingFunctions.QuadraticEaseInOutFunction);

                    logText += ", 500, QuadraticEaseInOutFunction)";
                }
                else
                {
                    Camera1.TurnTo(e.FinalPointHit); // Turn immediately
                    logText += ")";
                }

                LogCommandText(logText);

                // You can also call this with direction vector - for example:

                //var directionVector = e.FinalPointHit - Camera1.Position;
                //Camera1.TurnTo(directionVector);
            };

            eventManager3D.RegisterEventSource3D(multiVisualEventSource3D);
        }
        public void ShowData(List <SphereData> originalData)
        {
            // Now use original data to create our data view objects

            // All data will be displayed in a 3D box defined below:
            var displayedDataBounds = new Rect3D(-40, -20, -40, 80, 40, 80);

            _allPositionsData = new List <SphereDataView>(originalData.Count);

            foreach (var originalSphereData in originalData)
            {
                var sphereDataView = SphereDataView.Create(originalSphereData, displayedDataBounds, originalData.Count, _locationSize, _maxSize);

                sphereDataView.IsSelectedChanged += delegate(object sender, EventArgs args)
                {
                    var changedPositionDataView = (SphereDataView)sender;
                    if (changedPositionDataView.IsSelected)
                    {
                        DataListBox.SelectedItems.Add(changedPositionDataView);
                    }
                    else
                    {
                        DataListBox.SelectedItems.Remove(changedPositionDataView);
                    }

                    UpdateSelectedSpheresData();
                };

                _allPositionsData.Add(sphereDataView);
            }


            // Setup axis limits and shown values
            AxisWireBox.MinYValue = 0;
            AxisWireBox.MaxYValue = 10;

            AxisWireBox.YAxisValues = new double[] { 0, 2, 4, 6, 8, 10 };


            // Bind positions data to ListBox
            DataListBox.ItemsSource = _allPositionsData;


            // Create curve through all positions
            // This is done by first creating all points that define the curve (10 points between each position that define the curve)
            List <Point3D> allPositions = new List <Point3D>();

            foreach (var positionData in _allPositionsData)
            {
                allPositions.Add(positionData.Position);
            }

            BezierCurve       bezierCurve = Ab3d.Utilities.BezierCurve.CreateFromCurvePositions(allPositions);
            Point3DCollection curvePoints = bezierCurve.CreateBezierCurve(positionsPerSegment: 10); // How many points between each defined position in the curve

            // Create 3D Polyline from curvePoints
            Model3D curveModel = Ab3d.Models.Line3DFactory.CreatePolyLine3D(curvePoints, thickness: 2, color: Colors.Blue, isClosed: false, startLineCap: LineCap.Flat, endLineCap: LineCap.Flat, parentViewport3D: MainViewport);

            CurveModelVisual.Content = curveModel;


            // Now create 3D sphere objects for each position
            SpheresModelVisual.Children.Clear();

            // Each sphere will also need MouseEnter, MouseLeave and MouseClick event handlers
            // We use EventManager3D for that
            var eventManager3D = new Ab3d.Utilities.EventManager3D(MainViewport);


            // Add 3D sphere for each position
            foreach (var positionData in _allPositionsData)
            {
                SpheresModelVisual.Children.Add(positionData.ModelVisual3D); // Sphere Visual3D is created in SphereDataView object

                // Add event handlers (sphere Visual3D will be the source of the events)
                var visualEventSource3D = new VisualEventSource3D(positionData.ModelVisual3D);

                visualEventSource3D.MouseEnter += delegate(object sender, Mouse3DEventArgs e)
                {
                    if (_isSelecting)
                    {
                        return;
                    }

                    // Use hand cursor
                    Mouse.OverrideCursor = Cursors.Hand;

                    // Find selected position data
                    var selectedPositionData = _allPositionsData.FirstOrDefault(p => p.ModelVisual3D == e.HitObject);

                    SelectData(selectedPositionData, e.CurrentMousePosition);
                };

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

                    Mouse.OverrideCursor = null;

                    DataToolTipBorder.Visibility  = Visibility.Collapsed;
                    DataToolTipBorder.DataContext = null;

                    SelectedSphereLinesVisual.Children.Clear();
                };

                visualEventSource3D.MouseClick += delegate(object sender, MouseButton3DEventArgs e)
                {
                    // Select / deselect on mouse click
                    var clickedPositionData = _allPositionsData.FirstOrDefault(p => p.ModelVisual3D == e.HitObject);

                    if (clickedPositionData != null)
                    {
                        positionData.IsSelected = !clickedPositionData.IsSelected;
                    }
                };

                // Register the event source
                eventManager3D.RegisterEventSource3D(visualEventSource3D);
            }
        }
        private void AddTextBlockVisuals(Point3D startPosition, string text, string fontFamily = null)
        {
            Point3D  position = startPosition;
            Vector3D charAdvancementVector = new Vector3D(30, 0, 0);

            foreach (var oneChar in text)
            {
                var textBlockVisual3D = new TextBlockVisual3D()
                {
                    Text                   = oneChar.ToString(),
                    Position               = position,
                    PositionType           = PositionTypes.Center,
                    TextDirection          = new Vector3D(1, 0, 0),
                    UpDirection            = new Vector3D(0, 1, 0),
                    Size                   = new Size(20, 40),
                    Foreground             = Brushes.LightGray,
                    IsTwoSidedText         = true,
                    IsBackSidedTextFlipped = false
                };

                if (!string.IsNullOrEmpty(fontFamily))
                {
                    textBlockVisual3D.FontFamily = new FontFamily(fontFamily);
                }

                MainViewport.Children.Add(textBlockVisual3D);


                var visualEventSource3D = new VisualEventSource3D(textBlockVisual3D);
                visualEventSource3D.MouseEnter += delegate(object sender, Mouse3DEventArgs e)
                {
                    var hitTextBlockVisual3D = e.HitObject as TextBlockVisual3D;
                    if (hitTextBlockVisual3D != null && hitTextBlockVisual3D.Foreground != Brushes.Red)
                    {
                        hitTextBlockVisual3D.Foreground = Brushes.Orange;
                    }

                    Mouse.OverrideCursor = Cursors.Hand;
                };

                visualEventSource3D.MouseLeave += delegate(object sender, Mouse3DEventArgs e)
                {
                    var hitTextBlockVisual3D = e.HitObject as TextBlockVisual3D;
                    if (hitTextBlockVisual3D != null && hitTextBlockVisual3D.Foreground != Brushes.Red)
                    {
                        hitTextBlockVisual3D.Foreground = Brushes.LightGray;
                    }

                    Mouse.OverrideCursor = null;
                };

                visualEventSource3D.MouseClick += delegate(object sender, MouseButton3DEventArgs e)
                {
                    var hitTextBlockVisual3D = e.HitObject as TextBlockVisual3D;
                    if (hitTextBlockVisual3D != null)
                    {
                        if (hitTextBlockVisual3D.Foreground != Brushes.Red)
                        {
                            hitTextBlockVisual3D.Foreground = Brushes.Red;
                        }
                        else
                        {
                            hitTextBlockVisual3D.Foreground = Brushes.Orange;
                        }
                    }
                };

                _eventManager3D.RegisterEventSource3D(visualEventSource3D);


                position += charAdvancementVector;
            }
        }
Пример #14
0
        private void SubscribeEvents()
        {
            // Create an instance of EventManager3D for out Viewport3D

            // Important:
            // It is highly recommended not to have more than one EventManager3D object per Viewport3D.
            // Having multiple EventManager3D object can greatly reduce the performance because each time the Viewport3D camera is changed,
            // each EventManager3D must perform a full 3D hit testing from the current mouse position.
            // This operation is very CPU intensive and can affect performance when there are many 3D objects in the scene.
            // When multiple EventManager3D object are defined, then the 3D hit testing is performed multiple times.
            // Therefore it is recommended to have only one EventManager3D object per Viewport3D.
            //
            // It is also recommended to remove registered event sources after they are not used any more.
            // This can be done with RemoveEventSource3D method.

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

            // Create a NamedObjects dictionary and set it to eventManager.
            // This way we can use names on EventSource objects to identify Model3D or Visual3D.
            // This is very usefull if we read the 3d objects with Reader3ds or ReaderObj and already have the NamedObjects dictionry.
            // When names are used in EventSource objects, we get the HitModelName or HitVisualName property set so we can know which object was hit.
            var namedObjects = new Dictionary <string, object>();

            namedObjects.Add("Landscape", _landscapeModel);
            namedObjects.Add("Base", _windGenarator.BaseModel);
            namedObjects.Add("Blades", _windGenarator.BladesModel);
            namedObjects.Add("Turbine", _windGenarator.TurbineModel);

            _eventManager.NamedObjects = namedObjects;



            // subscribe the Landscape as the drag surface
            var modelEventSource = new Ab3d.Utilities.ModelEventSource3D();

            // Instead of using TargetModelName and NamedObjects, we could also specify the model with TargetModel3D
            //modelEventSource.TargetModel3D = _landscapeModel;

            modelEventSource.TargetModelName = "Landscape";
            modelEventSource.IsDragSurface   = true;

            _eventManager.RegisterEventSource3D(modelEventSource);


            // subscribe other objects
            var multiModelEventSource = new Ab3d.Utilities.MultiModelEventSource3D();

            // Instead of using TargetModelNames and NamedObjects, we could specify the models with model instances
            //multiModelEventSource.TargetModels3D = new Model3D[] { _windGenarator.BaseModel,
            //                                                       _windGenarator.BladesModel,
            //                                                       _windGenarator.TurbineModel };

            // Because we have set the NamedObjects dictionary to _eventManager we can simply specify the models by their names:
            multiModelEventSource.TargetModelNames = "Base, Blades, Turbine";
            multiModelEventSource.IsDragSurface    = false;

            // Subscribe to all events
            multiModelEventSource.MouseEnter       += eventSource_MouseEnter;
            multiModelEventSource.MouseLeave       += eventSource_MouseLeave;
            multiModelEventSource.MouseMove        += eventSource_MouseMove;
            multiModelEventSource.MouseUp          += eventSource_MouseUp;
            multiModelEventSource.MouseDown        += eventSource_MouseDown;
            multiModelEventSource.MouseClick       += eventSource_MouseClick;
            multiModelEventSource.MouseWheel       += multiModelEventSource_MouseWheel;
            multiModelEventSource.MouseDoubleClick += eventSource_MouseDoubleClick;
            multiModelEventSource.BeginMouseDrag   += eventSource_BeginMouseDrag;
            multiModelEventSource.MouseDrag        += eventSource_MouseDrag;
            multiModelEventSource.EndMouseDrag     += eventSource_EndMouseDrag;

            multiModelEventSource.TouchEnter += eventSource_TouchEnter;
            multiModelEventSource.TouchDown  += eventSource_TouchDown;
            multiModelEventSource.TouchMove  += eventSource_TouchMove;
            multiModelEventSource.TouchUp    += eventSource_TouchUp;
            multiModelEventSource.TouchLeave += eventSource_TouchLeave;

            // NOTE:
            // It is also possible to subscribe to touch manipulations events (pinch scale and rotate)
            // But this requires to set IsManipulationEnabled to true and that disables some other events
            // See the TouchManipulationsSample for more information

            _eventManager.RegisterEventSource3D(multiModelEventSource);
        }
Пример #15
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();
        }
        public void ShowData(List <SphereData> originalData, Rect3D displayedDataBounds, Rect xyDataRange)
        {
            // Now use original data to create our data view objects

            // All data will be displayed in a 3D box defined below:
            //var displayedDataBounds = new Rect3D(AxesBox.CenterPosition.X - AxesBox.Size.X * 0.5,
            //                                     AxesBox.CenterPosition.Y - AxesBox.Size.Y * 0.5,
            //                                     AxesBox.CenterPosition.Z - AxesBox.Size.Z * 0.5,
            //                                     AxesBox.Size.X,
            //                                     AxesBox.Size.Y,
            //                                     AxesBox.Size.Z);

            _allSpheresData = new List <SphereDataView>(originalData.Count);

            foreach (var originalSphereData in originalData)
            {
                // Set color of the sphere based on its y position
                // We choose the color from the gradient defined in EnsureGradientColorsArray
                double relativeY = (originalSphereData.Location.Y - xyDataRange.Y) / xyDataRange.Height;

                int   colorArrayIndex = (int)(relativeY * (_gradientColorsArray.Length - 1));
                Color color           = _gradientColorsArray[colorArrayIndex];


                var sphereDataView = SphereDataView.Create(originalSphereData, displayedDataBounds, originalData.Count, xyDataRange, color);

                sphereDataView.IsSelectedChanged += delegate(object sender, EventArgs args)
                {
                    var changedPositionDataView = (SphereDataView)sender;
                    if (changedPositionDataView.IsSelected)
                    {
                        DataListBox.SelectedItems.Add(changedPositionDataView);
                    }
                    else
                    {
                        DataListBox.SelectedItems.Remove(changedPositionDataView);
                    }

                    UpdateSelectedSpheresData();
                };

                _allSpheresData.Add(sphereDataView);
            }

            // Bind positions data to ListBox
            DataListBox.ItemsSource = _allSpheresData;


            // Create curve through all positions
            // This is done by first creating all points that define the curve (10 points between each position that define the curve)
            List <Point3D> allPositions = new List <Point3D>();

            foreach (var positionData in _allSpheresData)
            {
                allPositions.Add(positionData.Position);
            }

            BezierCurve       bezierCurve = Ab3d.Utilities.BezierCurve.CreateFromCurvePositions(allPositions);
            Point3DCollection curvePoints = bezierCurve.CreateBezierCurve(positionsPerSegment: 10); // How many points between each defined position in the curve

            // Create 3D Polyline from curvePoints
            Model3D curveModel = Ab3d.Models.Line3DFactory.CreatePolyLine3D(curvePoints, thickness: 2, color: Colors.Blue, isClosed: false, startLineCap: LineCap.Flat, endLineCap: LineCap.Flat, parentViewport3D: MainViewport);

            CurveModelVisual.Content = curveModel;


            // Now create 3D sphere objects for each position
            SpheresModelVisual.Children.Clear();

            // Each sphere will also need MouseEnter, MouseLeave and MouseClick event handlers
            // We use EventManager3D for that
            var eventManager3D = new Ab3d.Utilities.EventManager3D(MainViewport);


            // Add 3D sphere for each position
            foreach (var positionData in _allSpheresData)
            {
                SpheresModelVisual.Children.Add(positionData.ModelVisual3D); // Sphere Visual3D is created in SphereDataView object

                // Add event handlers (sphere Visual3D will be the source of the events)
                var visualEventSource3D = new VisualEventSource3D(positionData.ModelVisual3D);

                visualEventSource3D.MouseEnter += delegate(object sender, Mouse3DEventArgs e)
                {
                    if (_isSelecting)
                    {
                        return;
                    }

                    // Use hand cursor
                    Mouse.OverrideCursor = Cursors.Hand;

                    // Find selected position data
                    var selectedPositionData = _allSpheresData.FirstOrDefault(p => p.ModelVisual3D == e.HitObject);

                    SelectData(selectedPositionData, e.CurrentMousePosition);
                };

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

                    Mouse.OverrideCursor = null;

                    DataToolTipBorder.Visibility  = Visibility.Collapsed;
                    DataToolTipBorder.DataContext = null;

                    SelectedSphereLinesVisual.Children.Clear();
                };

                visualEventSource3D.MouseClick += delegate(object sender, MouseButton3DEventArgs e)
                {
                    // Select / deselect on mouse click
                    var clickedPositionData = _allSpheresData.FirstOrDefault(p => p.ModelVisual3D == e.HitObject);

                    if (clickedPositionData != null)
                    {
                        positionData.IsSelected = !clickedPositionData.IsSelected;
                    }
                };

                // Register the event source
                eventManager3D.RegisterEventSource3D(visualEventSource3D);
            }
        }
Пример #17
0
        private void CreateSceneObjects()
        {
            for (int y = 0; y < 5; y++)
            {
                for (int x = 0; x < 6; x++)
                {
                    var boxVisual3D = new Ab3d.Visuals.BoxVisual3D()
                    {
                        CenterPosition = new Point3D(40 * x - 100, 6, y * 40 - 80),
                        Size           = new Size3D(10, 10, 10),
                        Material       = _standardMaterial
                    };

                    SelectionRootModelVisual3D.Children.Add(boxVisual3D);
                }
            }

            // Use EventManager3D to handle clicking on selected boxes
            var eventManager3D = new Ab3d.Utilities.EventManager3D(MainViewport);

            var multiVisualEventSource3D = new MultiVisualEventSource3D(SelectionRootModelVisual3D.Children);

            multiVisualEventSource3D.MouseEnter += delegate(object sender, Mouse3DEventArgs e)
            {
                Mouse.OverrideCursor = Cursors.Hand;

                var hitBoxVisual3D = e.HitObject as Ab3d.Visuals.BoxVisual3D;
                if (hitBoxVisual3D != null)
                {
                    _wireBoxVisual3D.CenterPosition = hitBoxVisual3D.CenterPosition;
                    _wireBoxVisual3D.Size           = hitBoxVisual3D.Size;

                    MainViewport.Children.Add(_wireBoxVisual3D);
                }
            };

            multiVisualEventSource3D.MouseLeave += delegate(object sender, Mouse3DEventArgs e)
            {
                Mouse.OverrideCursor = null;

                if (_wireBoxVisual3D != null)
                {
                    MainViewport.Children.Remove(_wireBoxVisual3D);
                }
            };

            multiVisualEventSource3D.MouseClick += delegate(object sender, MouseButton3DEventArgs e)
            {
                if (_selectedBoxVisual3D != null)
                {
                    _selectedBoxVisual3D.Material = _standardMaterial;
                }

                var hitBoxVisual3D = e.HitObject as Ab3d.Visuals.BoxVisual3D;
                if (hitBoxVisual3D != null)
                {
                    hitBoxVisual3D.Material = _selectedMaterial;
                    _selectedBoxVisual3D    = hitBoxVisual3D;

                    if (_wireBoxVisual3D != null)
                    {
                        MainViewport.Children.Remove(_wireBoxVisual3D);
                    }

                    MoveCameraTo(hitBoxVisual3D);
                }
                else
                {
                    _selectedBoxVisual3D = null;
                }
            };

            eventManager3D.RegisterEventSource3D(multiVisualEventSource3D);

            // Exclude _wireBoxVisual3D from receiving mouse events
            eventManager3D.RegisterExcludedVisual3D(_wireBoxVisual3D);
        }
        private void SetupMouseEventHandlers(Visual3D targetModelVisual3D)
        {
            var visualEventSource3D = new VisualEventSource3D(targetModelVisual3D);

            visualEventSource3D.MouseEnter += delegate(object sender, Mouse3DEventArgs e)
            {
                Mouse.OverrideCursor = Cursors.Cross;
            };

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

            visualEventSource3D.MouseMove += delegate(object sender, Mouse3DEventArgs e)
            {
                if (e.MouseData.LeftButton != MouseButtonState.Pressed)
                {
                    return;
                }

                // Calculte the position inside texture where the mouse is
                Point hitPosition;
                var   success = GetRelativeHitTexturePosition(e.RayHitResult, out hitPosition);

                if (!success)
                {
                    return; // Cannot get the position
                }
                // The position was now relative (1 was bottom right)
                // Now adjust the position for the size of target Canvas
                double xPos = hitPosition.X * DrawingCanvas.Width;
                double yPos = hitPosition.Y * DrawingCanvas.Height;


                double strokeThickness     = _settings.CurrentStrokeThickness;
                double halfStrokeThickness = strokeThickness / 2;

                // Prevent drawing over the "edge" of Canvas
                // This would increase the size of Canvas and produce white areas on the model
                // Set xPos to be between halfStrokeThickness and DrawingCanvas.Width - halfStrokeThickness
                xPos = Math.Max(halfStrokeThickness, Math.Min(xPos, DrawingCanvas.Width - halfStrokeThickness));
                yPos = Math.Max(halfStrokeThickness, Math.Min(yPos, DrawingCanvas.Height - halfStrokeThickness));

                // Check if the change of position is significant
                if (Math.Abs(_lastXPos - xPos) < 1 && Math.Abs(_lastYPos - yPos) < 1)
                {
                    return;
                }


                _lastXPos = xPos;
                _lastYPos = yPos;

                var ellipse = new Ellipse()
                {
                    Width  = strokeThickness,
                    Height = strokeThickness,
                    Fill   = _settings.CurrentStrokeBrush
                };

                Canvas.SetLeft(ellipse, xPos - halfStrokeThickness);
                Canvas.SetTop(ellipse, yPos - halfStrokeThickness);

                DrawingCanvas.Children.Add(ellipse);
            };

            _eventManager3D.ResetEventSources3D(); // Clear all previously registered event sources
            _eventManager3D.RegisterEventSource3D(visualEventSource3D);
        }
Пример #19
0
        private void GenerateRandomDucks(int ducksCount)
        {
            var rnd = new Random();

            double  lakeRadius = LakeCircleVisual3D.Radius;
            Point3D lakeCenter = LakeCircleVisual3D.CenterPosition;

            _duckModels = new List <ModelVisual3D>(ducksCount);
            RootDucksVisual3D.Children.Clear();

            for (int i = 0; i < ducksCount; i++)
            {
                bool findNewPosition;

                do
                {
                    var position = new Point3D(rnd.NextDouble() * lakeRadius * 2 - lakeRadius,
                                               0,
                                               rnd.NextDouble() * lakeRadius * 2 - lakeRadius);

                    // If position is outside of 80% of lake radius
                    double distanceToLakeCenter = (position - lakeCenter).Length;
                    findNewPosition = distanceToLakeCenter > (lakeRadius * 0.8);

                    if (!findNewPosition)
                    {
                        // Now check if too close to any other duck
                        foreach (var duckModel in _duckModels)
                        {
                            var standardTransform3D = StandardTransform3D.GetStandardTransform3D(duckModel);

                            var distanceToDuck = (position - standardTransform3D.GetTranslateVector3D().ToPoint3D()).Length;
                            if (distanceToDuck < DuckSize * 4)
                            {
                                findNewPosition = true;
                                break;
                            }
                        }
                    }

                    if (!findNewPosition)
                    {
                        // The position is ok

                        double scale = rnd.NextDouble() + 1;

                        var standardTransform3D = new StandardTransform3D()
                        {
                            TranslateX = position.X,
                            TranslateY = position.Y,
                            TranslateZ = position.Z,

                            RotateY = rnd.NextDouble() * 360,

                            ScaleX = scale,
                            ScaleY = scale,
                            ScaleZ = scale
                        };

                        var duckVisual3D = new ModelVisual3D()
                        {
                            Content = _duckModel3D,
                        };

                        StandardTransform3D.SetStandardTransform3D(duckVisual3D, standardTransform3D, updateTransform3D: true);


                        _duckModels.Add(duckVisual3D);
                        RootDucksVisual3D.Children.Add(duckVisual3D);


                        var visualEventSource3D = new VisualEventSource3D(duckVisual3D);
                        visualEventSource3D.MouseEnter += OnDuckMouseEnter;
                        visualEventSource3D.MouseLeave += OnDuckMouseLeave;
                        visualEventSource3D.MouseDown  += OnDuckMouseDown;
                        visualEventSource3D.MouseUp    += OnDuckMouseUp;

                        _eventManager3D.RegisterEventSource3D(visualEventSource3D);
                    }
                } while (findNewPosition);
            }
        }