Example #1
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);
        }
Example #2
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;
        }
        private void Setup3DObjects()
        {
            // The event manager will be used to manage the mouse events on our boxes
            _eventManager3D = new Ab3d.Utilities.EventManager3D(_viewport3D);


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

            _viewport3D.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
                    };

                    _viewport3D.Children.Add(boxVisual3D);


                    // With EventManager we can subscribe to mouse events as we would have standard 2D controls:
                    var visualEventSource3D = new VisualEventSource3D(boxVisual3D);
                    visualEventSource3D.MouseEnter += BoxOnMouseEnter;
                    visualEventSource3D.MouseLeave += BoxOnMouseLeave;
                    visualEventSource3D.MouseClick += BoxOnMouseClick;

                    _eventManager3D.RegisterEventSource3D(visualEventSource3D);
                }
            }

            ToggleCameraAnimation(); // Start camer animation
        }
        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);
        }
        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;
            }
        }
        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);
            }
        }
        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);
        }
Example #8
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);
            }
        }
        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);
            }
        }