Exemple #1
0
        public DucksLakeDemo()
        {
            InitializeComponent();

            MouseCameraControllerInfo1.AddCustomInfoLine(0, MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, "Select duck");


            _duckModel3D = LoadDuckModel();

            _eventManager3D = new Ab3d.Utilities.EventManager3D(MainViewport);
            _eventManager3D.CustomEventsSourceElement = ViewportBorder;


            this.Focusable       = true; // by default Page is not focusable and therefore does not receive keyDown event
            this.PreviewKeyDown += OnPreviewKeyDown;
            this.Focus();


            // We need to synchronize the Camera in OverlayViewport with the camera in the MainViewport
            Camera1.CameraChanged += delegate(object s, CameraChangedRoutedEventArgs args)
            {
                OverlayViewport.Camera = MainViewport.Camera;
            };

            this.Loaded += delegate(object sender, RoutedEventArgs args)
            {
                GenerateRandomDucks(10);

                ShowModelMover();
            };
        }
Exemple #2
0
        public ZoomToCustomPoint()
        {
            InitializeComponent();

            MouseCameraControllerInfo1.AddCustomInfoLine(0, MouseCameraController.MouseAndKeyboardConditions.MiddleMouseButtonPressed,
                                                         "Use mouse wheel to zoom or use pinch zoom on touch display");

            this.Loaded += delegate(object sender, RoutedEventArgs args)
            {
                UpdateCurrentZoomMode();
            };
        }
Exemple #3
0
        public MouseSelectionAndRotation()
        {
            InitializeComponent();

            _standardBoxMaterial = new DiffuseMaterial(Brushes.Silver);
            _standardBoxMaterial.Freeze();

            _mouseOverBoxMaterial = new DiffuseMaterial(Brushes.Orange);
            _mouseOverBoxMaterial.Freeze();

            _selectedBoxMaterial = new DiffuseMaterial(Brushes.Red);
            _selectedBoxMaterial.Freeze();



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

            // IMPORTANT !!!
            // To allow EventManager3D and MouseCameraController to both work with left mouse button,
            // we need to set UsePreviewEvents on EventManager3D to true.
            // This will make EventManager3D subscribe to Preview... events (PreviewMouseMove instead of MouseMove)
            // and therefore EventManager3D will get the mouse events before they can be handled by the MouseCameraController.
            eventManager3D.UsePreviewEvents = true;

            // 5 x 3 boxes
            for (int x = 0; x < 5; x++)
            {
                for (int y = 0; y < 3; y++)
                {
                    var boxVisual3D = new BoxVisual3D()
                    {
                        CenterPosition = new Point3D(-40 + x * 20, 5, -30 + y * 30),
                        Size           = new Size3D(10, 10, 10),
                        Material       = _standardBoxMaterial
                    };

                    MainViewport.Children.Add(boxVisual3D);

                    // Register mouse events on boxVisual3D
                    RegisterMouseEventsOnBoxVisual(boxVisual3D, eventManager3D);
                }
            }


            MouseCameraControllerInfo1.AddCustomInfoLine(0, MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, "Select Box");
        }
Exemple #4
0
        public StandardWpfHitTestingDemo()
        {
            InitializeComponent();

            _selectedMaterial = new DiffuseMaterial(Brushes.Yellow);
            _clickedMaterial  = new DiffuseMaterial(Brushes.Red);

            CreateTestScene();

            MouseCameraController1.RotationCursor = null;

            MainViewport.MouseDown  += OnMouseDown;
            MainViewport.MouseUp    += OnMouseUp;
            MainViewport.MouseMove  += OnMouseMove;
            MainViewport.MouseLeave += OnMouseLeave;

            MouseCameraControllerInfo1.AddCustomInfoLine(0, MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, "3D object click");
        }
        public MouseSelectionAndRotation()
        {
            InitializeComponent();

            UsePreviewEventsInfoControl.InfoText      = @"When checked then UsePreviewEvents property on EventManager3D is set to true. This will use PreviewMouseDown and other Preview... events so that EventManager3D will get events before MouseCameraController. In case of a click it will handle the events and prevent mouse rotation; if there will be no click then event will be passed to the MouseCameraController.";
            UseMouseMoveThresholdInfoControl.InfoText = @"When checked then MouseCameraController.MouseMoveThreshold to a value bigger then 0 (EventManager3D.UsePreviewEvents is false). This will start mouse rotation (and movement) only when the mouse is moved for the amount specified in MouseMoveThreshold. This way the EventManager3D can handle the click (when there is no mouse movement). But if the mouse is moved for the required distance then the MouseCameraController starts camera rotation.";


            CreateTestScene();

            // Start with using preview events
            SetupEventManager(usePreviewEvents: true);

            // we could also start with using MouseMoveThreshold
            //MouseCameraController1.MouseMoveThreshold = 3;
            //SetupEventManager(usePreviewEvents: false);

            MouseCameraControllerInfo1.AddCustomInfoLine(0, MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, "Select Box");
        }
Exemple #6
0
        public RectangularSelectionSample()
        {
            InitializeComponent();


            BoundsIn2DInfoControl.InfoText =
                @"The simplest technique to do rectangular selection is to convert the object's 3D bounds (axis aligned bounding box) into a 2D rectangle that represents the bounds on the screen. Then we can simply call IntersectsWith method that checks if the two 2D rectangles intersect.

Advantages:
- Very simple and fast when there is not a lot of 3D objects.
- Also selects the objects that are behind the objects closer to the camera.
- Can be used with only Ab3d.PowerToys (without Ab3d.DXEngine).

Disadvantages:
- Not accurate - the bounds of 3D objects and its bounds in 2D world are bigger then the the actual 3D object - selection is done before the user actually touches the 3D object.
- Slow when checking a lot of 3D objects.
- Cannot be used to select 3D lines.";


            ObjectIdMapInfoControl.InfoText =
                @"With Ab3d.DXEngine it is possible to render objects to a bitmap in such a way that each object is rendered with a different color where the color represents the object's id. When such a bitmap is rendered it is possible to get individual pixel colors and from that get the original object that was used to render the pixel.

Advantages:
- Pixel perfect accuracy.
- Fast when rendering a lot of objects.
- Can be used to select 3D lines.
- Can be extended to support some other selection types and not only rectangular selection.

Disadvantages:
- More complex (using custom rendering steps) than using simple bounding boxes.
- Slower when using simple 3D scene (DXEngine needs to set up the DirectX resources for another rendering pass; also much more memory is required).
- We need to find original WPF 3D object from DXEngine's RenderablePrimitive object.
- Cannot select objects that are behind some other objects that are closer to the camera.";


            MouseCameraControllerInfo1.AddCustomInfoLine(0, MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, "Rectangular selection");

            this.Cursor          = Cursors.Cross;
            OptionsBorder.Cursor = Cursors.Arrow;


            _selectedDiffuseMaterial = new DiffuseMaterial(Brushes.Red);

            _savedMaterials  = new Dictionary <GeometryModel3D, Material>();
            _savedLineColors = new Dictionary <BaseLineVisual3D, Color>();

            _disposables = new DisposeList();


            CreateTestScene();


            // Setup mouse events that will be used to show rectangular selection
            this.MouseLeftButtonDown += OnMouseLeftButtonDown;
            this.MouseMove           += OnMouseMove;
            this.MouseLeftButtonUp   += OnMouseLeftButtonUp;


            MainDXViewportView.DXSceneDeviceCreated += OnDxSceneDeviceCreated;

            this.Loaded += delegate(object sender, RoutedEventArgs args)
            {
                DXView.GetDpiScale(this, out _dpiScaleX, out _dpiScaleY);
            };

            this.Unloaded += delegate(object sender, RoutedEventArgs args)
            {
                if (_disposables != null)
                {
                    _disposables.Dispose();
                    _disposables = null;
                }

                MainDXViewportView.Dispose();
            };
        }
Exemple #7
0
        public TwoDimensionalCameraLineEditor()
        {
            InitializeComponent();

            MouseCameraControllerInfo1.AddCustomInfoLine(0, MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, "Create new line");


            // NOTE: TwoDimensionalCamera class is available with full source in this samples project in the Common folder.

            // Create an instance of TwoDimensionalCamera.
            // TwoDimensionalCamera will internally create a TargetPositionCamera and MouseCameraController (when mouseEventsSourceElement is not null).
            // They will be used to show the 2D scene.
            _twoDimensionalCamera = new TwoDimensionalCamera(MainDXViewportView,
                                                             mouseEventsSourceElement: ViewportBorder,   // if mouseEventsSourceElement is null, then MouseCameraController will not be created by TwoDimensionalCamera
                                                             useScreenPixelUnits: false,                 // when false, then the size in device independent units is used (as size of DXViewportView); when true size in screen pixels is used (see SharpHorizontalAndVerticalLines sample)
                                                             coordinateSystemType: TwoDimensionalCamera.CoordinateSystemTypes.CenterOfViewOrigin)
            {
                MoveCameraConditions       = MouseCameraController.MouseAndKeyboardConditions.RightMouseButtonPressed,
                QuickZoomConditions        = MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed | MouseCameraController.MouseAndKeyboardConditions.RightMouseButtonPressed,
                ShowCameraLight            = ShowCameraLightType.Always,
                IsMouseAndTouchZoomEnabled = true,
            };

            // You can access the create TargetPositionCamera with UsedCamera property
            // and MouseCameraController with UsedMouseCameraController property.
            MouseCameraControllerInfo1.MouseCameraController = _twoDimensionalCamera.UsedMouseCameraController;

            // If we want to use LeftMouseButton for mouse movement, then we can also start new line with the same button with setting MouseMoveThreshold:
            //// Set MouseMoveThreshold so that mouse move starts after the mouse is moved
            //// for at least 3 pixels. This way we can use mouse click to start / end line drawing.
            //_twoDimensionalCamera.UsedMouseCameraController.MouseMoveThreshold = 3;


            _twoDimensionalCamera.CameraChanged += delegate(object sender, EventArgs args)
            {
                // When zoom is changed, we need to update all line markers
                if (!MathUtils.IsSame(_lastZoomFactor, _twoDimensionalCamera.ZoomFactor))
                {
                    // Update line markers size (we want that at each zoom level their WPF size is _positionMarkerWpfSize
                    _positionMarkerHalfSize = _twoDimensionalCamera.GetViewSizeFromWpfSize(_positionMarkerWpfSize) * 0.5;

                    if (double.IsNaN(_snappedViewPosition.X)) // Check if _snappedViewPosition is actually set
                    {
                        return;
                    }

                    // Reuse last position
                    var mousePosition = _twoDimensionalCamera.ToWpfPosition(_snappedViewPosition);
                    CheckPositionMarkers(mousePosition, updateExistingPositionMarkers: true); // _positionMarkerHalfSize is changed so we need to update all shown position markers

                    _lastZoomFactor = _twoDimensionalCamera.ZoomFactor;
                }
            };


            _twoDimensionalCamera.UsedMouseCameraController.CameraMoveStarted += delegate(object sender, EventArgs args)
            {
                _isMouseButtonPressed = false; // when we started mouse camera movement, we need to prevent creating the line when the mouse button is released
            };

            _twoDimensionalCamera.UsedMouseCameraController.CameraQuickZoomStarted += delegate(object sender, EventArgs args)
            {
                _isMouseButtonPressed = false; // when we started quick zoom, we need to prevent creating the line when the mouse button is released
            };


            // We store lines in our List of Points.
            // The main purpose of this is that we can have a very fast access to line positions.
            // (if we would read the Positions from MultiLineVisual3D this would be much slower because accessing DependencyProperties and Point3DCollection is very slow).
            _allPositions = new List <Point>();

            // _positionMarkers is a list that stores all created line markers. The size of array is the same as the size of _allPositions
            _positionMarkers = new List <PolyLineVisual3D>();


            // One MultiLineVisual3D will show fully created 3D lines (this is the much faster then creating individual LineVisual3D objects)
            _multiLineVisual3D = new MultiLineVisual3D()
            {
                Positions     = new Point3DCollection(),
                LineColor     = Colors.Black,
                LineThickness = 1
            };

            MainViewport.Children.Add(_multiLineVisual3D);


            // _creatingLine will show the line that is currently being created - user has not placed the end position yet.
            _creatingLine = new LineVisual3D()
            {
                LineColor     = Colors.Gray,
                LineThickness = 1,
                IsVisible     = false
            };

            MainViewport.Children.Add(_creatingLine);


            // _snappedPositionMarker will be shown over standard gray position marker and will indicate with its black color that mouse position is snapped to the marked position.
            _snappedPositionMarker = new PolyLineVisual3D()
            {
                Positions     = new Point3DCollection(5),
                LineColor     = Colors.Black,
                LineThickness = 1,
                IsVisible     = false
            };

            MainViewport.Children.Add(_snappedPositionMarker);


            _positionMarkerHalfSize = _twoDimensionalCamera.GetViewSizeFromWpfSize(_positionMarkerWpfSize) * 0.5;

            AddAxisLines();

            AddRandomLines(10);

            _snappedViewPosition = new Point(double.NaN, double.NaN); // Mark as invalid


            // We use ViewportBorder to get our mouse events
            ViewportBorder.MouseLeftButtonDown += delegate(object o, MouseButtonEventArgs args)
            {
                _isMouseButtonPressed = true; // we will start the line on mouse up
            };

            ViewportBorder.MouseLeftButtonUp += delegate(object sender, MouseButtonEventArgs args)
            {
                if (!_isMouseButtonPressed)
                {
                    return;
                }

                if (_creatingLine.IsVisible)
                {
                    CompleteNewLine();
                }
                else
                {
                    StartNewLine(_snappedViewPosition);
                }

                _isMouseButtonPressed = false;
            };

            ViewportBorder.MouseMove += delegate(object o, MouseEventArgs args)
            {
                var mousePosition = args.GetPosition(ViewportBorder);
                CheckPositionMarkers(mousePosition, updateExistingPositionMarkers: false);

                if (_creatingLine.IsVisible)
                {
                    UpdateLastLinePosition(_snappedViewPosition);
                }
            };


            this.Unloaded += delegate(object sender, RoutedEventArgs args)
            {
                MainDXViewportView.Dispose();
            };
        }
Exemple #8
0
        public DucksLakeDemo()
        {
            InitializeComponent();

            MouseCameraControllerInfo1.AddCustomInfoLine(0, MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, "Select duck");


            _duckModel3D = LoadDuckModel();

            _eventManager3D = new Ab3d.Utilities.EventManager3D(MainViewport);
            _eventManager3D.CustomEventsSourceElement = ViewportBorder;


            MainDXViewportView.DXSceneInitialized += delegate(object sender, EventArgs args)
            {
                if (MainDXViewportView.DXScene == null)
                {
                    return; // Probably WPF 3D rendering
                }
                // Setup shadow rendering
                _varianceShadowRenderingProvider = new VarianceShadowRenderingProvider();

                // Because we have a big green plane, we need to increase the shadow map size (increase this more to get a more detailed shadow).
                _varianceShadowRenderingProvider.ShadowMapSize = 1024;

                MainDXViewportView.DXScene.InitializeShadowRendering(_varianceShadowRenderingProvider);

                // Specify the light that cases shadow(note that point light is not supported - only DirectionalLight and SpotLight are supported).
                MainSceneLight.SetDXAttribute(DXAttributeType.IsCastingShadow, true);
            };


            this.Focusable       = true; // by default Page is not focusable and therefore does not receive keyDown event
            this.PreviewKeyDown += OnPreviewKeyDown;
            this.Focus();


            // We need to synchronize the Camera in OverlayViewport with the camera in the MainViewport
            Camera1.CameraChanged += delegate(object s, CameraChangedRoutedEventArgs args)
            {
                OverlayViewport.Camera = MainViewport.Camera;
            };

            this.Loaded += delegate(object sender, RoutedEventArgs args)
            {
                GenerateRandomDucks(10);

                ShowModelMover();
            };

            // 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 += delegate(object sender, RoutedEventArgs args)
            {
                if (_varianceShadowRenderingProvider != null)
                {
                    _varianceShadowRenderingProvider.Dispose();
                }

                MainDXViewportView.Dispose();
            };
        }