Пример #1
0
        /// <summary>
        /// Handles hit testing on mouse down.
        /// </summary>
        /// <param name="pt">The hit point.</param>
        /// <param name="originalInputEventArgs">
        /// The original input event (which mouse button pressed?)
        /// </param>
        private void MouseDownHitTest(Point pt, PointerRoutedEventArgs originalInputEventArgs = null)
        {
            if (!enableMouseButtonHitTest)
            {
                return;
            }

            if (this.FindHits(pt.ToVector2(), ref hits) && hits.Count > 0)
            {
                this.currentHit = hits.FirstOrDefault(x => x.IsValid);
                if (this.currentHit != null)
                {
                    if (currentHit.ModelHit is Element3D ele)
                    {
                        ele.RaiseMouseDownEvent(this.currentHit, pt, this, originalInputEventArgs);
                    }
                    else if (currentHit.ModelHit is SceneNode node)
                    {
                        node.RaiseMouseDownEvent(this, pt.ToVector2(), currentHit, originalInputEventArgs);
                    }
                }
            }
            else
            {
                currentHit = null;
            }
            this.OnMouse3DDown?.Invoke(this, new MouseDown3DEventArgs(currentHit, pt, this, originalInputEventArgs));
        }
Пример #2
0
        /// <summary>
        /// Rotate the camera around the specified point.
        /// </summary>
        /// <param name="p0">
        /// The p 0.
        /// </param>
        /// <param name="p1">
        /// The p 1.
        /// </param>
        /// <param name="rotateAround">
        /// The rotate around.
        /// </param>
        public void Rotate(Point p0, Point p1, Point3D rotateAround)
        {
            if (!this.Viewport.IsRotationEnabled)
            {
                return;
            }
            switch (this.Viewport.CameraRotationMode)
            {
            case CameraRotationMode.Trackball:
                this.RotateTrackball(p0, p1, rotateAround);
                break;

            case CameraRotationMode.Turntable:
                this.RotateTurntable(p1.ToVector2() - p0.ToVector2(), rotateAround);
                break;

            case CameraRotationMode.Turnball:
                this.RotateTurnball(p0, p1, rotateAround);
                break;
            }

            if (Math.Abs(this.Camera.UpDirection.Length() - 1) > 1e-8)
            {
                this.Camera.UpDirection.Normalize();
            }
        }
Пример #3
0
        /// <summary>
        /// Rotate the camera around the specified point.
        /// </summary>
        /// <param name="p0">
        /// The p 0.
        /// </param>
        /// <param name="p1">
        /// The p 1.
        /// </param>
        /// <param name="rotateAround">
        /// The rotate around.
        /// </param>
        /// <param name="stopOther">Stop other manipulation</param>
        public void Rotate(Point p0, Point p1, Point3D rotateAround, bool stopOther = true)
        {
            if (!this.Controller.IsRotationEnabled)
            {
                return;
            }
            if (stopOther)
            {
                Controller.StopZooming();
                Controller.StopPanning();
            }
            switch (this.Controller.CameraRotationMode)
            {
            case CameraRotationMode.Trackball:
                this.RotateTrackball(p0, p1, rotateAround);
                break;

            case CameraRotationMode.Turntable:
                this.RotateTurntable(p1.ToVector2() - p0.ToVector2(), rotateAround);
                break;

            case CameraRotationMode.Turnball:
                this.RotateTurnball(p0, p1, rotateAround);
                break;
            }

            if (Math.Abs(this.Camera.UpDirection.Length() - 1) > 1e-8)
            {
                this.Camera.UpDirection.Normalize();
            }
        }
Пример #4
0
        private bool ViewBoxHitTest(Point p)
        {
            if (!(Camera is ProjectionCamera camera))
            {
                return(false);
            }
            var vp = p.ToVector2();

            if (!this.UnProject(vp, out var ray))
            {
                return(false);
            }
            var hits = new List <HitTestResult>();

            if (viewCube.HitTest(new HitTestContext(RenderContext, ref ray, ref vp), ref hits))
            {
                var normal = hits[0].NormalAtHit;
                if (Vector3.Cross(normal, ModelUpDirection).LengthSquared() < 1e-5)
                {
                    var vecLeft = new Vector3(-normal.Y, -normal.Z, -normal.X);
                    ViewCubeClicked(hits[0].NormalAtHit, vecLeft);
                }
                else
                {
                    ViewCubeClicked(hits[0].NormalAtHit, ModelUpDirection);
                }
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #5
0
        public void Vector2FromPointTest()
        {
            var point = new Windows.Foundation.Point(23, 42);

            Vector2 result = point.ToVector2();

            Assert.AreEqual(23.0f, result.X);
            Assert.AreEqual(42.0f, result.Y);
        }
Пример #6
0
        /// <summary>
        /// Occurs when the manipulation is started.
        /// </summary>
        /// <param name="e">The <see cref="ManipulationEventArgs"/> instance containing the event data.</param>
        public override void Started(Point e)
        {
            base.Started(e);

            this.rotationPoint = new Vector2(
                this.Controller.Width / 2f, this.Controller.Height / 2f);
            this.rotationPoint3D = this.Camera.CameraInternal.Target;

            switch (this.CameraMode)
            {
            case CameraMode.WalkAround:
                this.rotationPoint   = this.MouseDownPoint;
                this.rotationPoint3D = this.Camera.CameraInternal.Position;
                break;

            default:
                if (Controller.Viewport.FixedRotationPointEnabled)
                {
                    this.rotationPoint3D = Controller.Viewport.FixedRotationPoint;
                }
                else if (this.changeLookAt && this.MouseDownNearestPoint3D != null)
                {
                    this.LookAt(this.MouseDownNearestPoint3D.Value, 0);
                    this.rotationPoint3D = this.Camera.CameraInternal.Target;
                }
                else if (this.Controller.RotateAroundMouseDownPoint && this.MouseDownNearestPoint3D != null)
                {
                    this.rotationPoint   = this.MouseDownPoint;
                    this.rotationPoint3D = this.MouseDownNearestPoint3D.Value;
                }

                break;
            }

            if (this.CameraMode == CameraMode.Inspect)
            {
                //this.Viewport.ShowTargetAdorner(this.rotationPoint);
            }

            switch (this.CameraRotationMode)
            {
            case CameraRotationMode.Trackball:
                break;

            case CameraRotationMode.Turntable:
                break;

            case CameraRotationMode.Turnball:
                CameraMath.InitTurnballRotationAxes(e.ToVector2(), Controller.Width, Controller.Height, Camera, out rotationAxisX, out rotationAxisY);
                break;
            }

            this.Controller.StopSpin();
        }
Пример #7
0
        /// <summary>
        /// Rotate around three axes.
        /// </summary>
        /// <param name="p1">
        /// The previous mouse position.
        /// </param>
        /// <param name="p2">
        /// The current mouse position.
        /// </param>
        /// <param name="rotateAround">
        /// The point to rotate around.
        /// </param>
        public void RotateTurnball(Point p1, Point p2, Point3D rotateAround)
        {
            this.InitTurnballRotationAxes(p1);

            Vector2 delta = p2.ToVector2() - p1.ToVector2();

            var relativeTarget   = rotateAround - this.Camera.Target;
            var relativePosition = rotateAround - this.Camera.Position;

            float d = -1f;

            if (this.CameraMode != CameraMode.Inspect)
            {
                d = 0.2f;
            }

            d *= (float)this.RotationSensitivity;

            var        q1 = Quaternion.RotationAxis(this.rotationAxisX, (float)(d * delta.X / 180 * Math.PI));
            var        q2 = Quaternion.RotationAxis(this.rotationAxisY, (float)(d * delta.Y / 180 * Math.PI));
            Quaternion q  = q1 * q2;

            var m = Matrix.RotationQuaternion(q);

            var newLookDir     = Vector3D.Transform(this.Camera.LookDirection, m).ToVector3();
            var newUpDirection = Vector3D.Transform(this.Camera.UpDirection, m).ToVector3();

            var newRelativeTarget   = Vector3D.Transform(relativeTarget, m).ToVector3();
            var newRelativePosition = Vector3D.Transform(relativePosition, m).ToVector3();

            var newRightVector = Vector3D.Cross(newLookDir, newUpDirection);

            newRightVector.Normalize();
            var modUpDir = Vector3D.Cross(newRightVector, newLookDir);

            modUpDir.Normalize();
            if ((newUpDirection - modUpDir).Length() > 1e-8)
            {
                newUpDirection = modUpDir;
            }

            var newTarget        = rotateAround - newRelativeTarget;
            var newPosition      = rotateAround - newRelativePosition;
            var newLookDirection = newTarget - newPosition;

            this.Camera.LookDirection = newLookDirection;
            if (this.CameraMode == CameraMode.Inspect)
            {
                this.Camera.Position = newPosition;
            }

            this.Camera.UpDirection = newUpDirection;
        }
Пример #8
0
 /// <summary>
 /// Handles hit testing on mouse move.
 /// </summary>
 /// <param name="pt">The hit point.</param>
 /// <param name="originalInputEventArgs">
 /// The original input (which mouse button pressed?)
 /// </param>
 private void MouseMoveHitTest(Point pt, PointerRoutedEventArgs originalInputEventArgs = null)
 {
     if (!enableMouseButtonHitTest)
     {
         return;
     }
     if (this.currentHit != null)
     {
         if (currentHit.ModelHit is Element3D ele)
         {
             ele.RaiseMouseMoveEvent(this.currentHit, pt, this, originalInputEventArgs);
         }
         else if (currentHit.ModelHit is SceneNode node)
         {
             node.RaiseMouseMoveEvent(this, pt.ToVector2(), currentHit, originalInputEventArgs);
         }
     }
     this.OnMouse3DMove?.Invoke(this, new MouseMove3DEventArgs(currentHit, pt, this, originalInputEventArgs));
 }
Пример #9
0
 /// <summary>
 /// Finds the nearest point and its normal.
 /// </summary>
 /// <param name="viewport">
 /// The viewport.
 /// </param>
 /// <param name="position">
 /// The position.
 /// </param>
 /// <param name="point">
 /// The point.
 /// </param>
 /// <param name="normal">
 /// The normal.
 /// </param>
 /// <param name="model">
 /// The model.
 /// </param>
 /// <param name="node"></param>
 /// <returns>
 /// The find nearest.
 /// </returns>
 public static bool FindNearest(this Viewport3DX viewport, Point position,
                                out Vector3 point, out Vector3 normal, out Element3D model, out SceneNode node)
 {
     model = null;
     node  = null;
     if (viewport.FindNearest(position.ToVector2(), out point, out normal, out var m))
     {
         if (m is Element3D ele)
         {
             model = ele;
             node  = ele.SceneNode;
         }
         else if (m is SceneNode nd)
         {
             node  = nd;
             model = null;
         }
         return(true);
     }
     return(false);
 }
Пример #10
0
        /// <summary>
        /// The on time step.
        /// </summary>
        /// <param name="ticks">
        /// The time.
        /// </param>
        public void OnTimeStep(long ticks)
        {
            if (lastTick == 0)
            {
                lastTick = ticks;
            }
            var time = (float)(ticks - this.lastTick) / Stopwatch.Frequency;
            // should be independent of time
            var  factor     = Viewport.IsInertiaEnabled ? (float)Clamp(Math.Pow(Viewport.CameraInertiaFactor, time / 0.02f), 0.1f, 1) : 0;
            bool needUpdate = false;

            if (this.rotationSpeed.LengthSquared() > 0.1)
            {
                this.rotateHandler.Rotate(
                    this.rotationPosition, (rotationPosition.ToVector2() + (rotationSpeed * time)).ToPoint(), this.rotationPoint3D);
                this.rotationSpeed *= factor;
                needUpdate          = true;
                this.spinningSpeed  = VectorZero;
            }
            else
            {
                this.rotationSpeed = VectorZero;
                if (this.isSpinning && this.spinningSpeed.LengthSquared() > 0.1)
                {
                    this.rotateHandler.Rotate(
                        this.spinningPosition, (spinningPosition.ToVector2() + (spinningSpeed * time)).ToPoint(), this.spinningPoint3D);
                    if (!Viewport.InfiniteSpin)
                    {
                        this.spinningSpeed *= factor;
                    }
                    needUpdate = true;
                }
                else
                {
                    this.spinningSpeed = VectorZero;
                }
            }

            if (this.panSpeed.LengthSquared() > 0.0001)
            {
                this.panHandler.Pan(this.panSpeed * time);
                this.panSpeed *= factor;
                needUpdate     = true;
            }
            else
            {
                this.panSpeed = Vector3DZero;
            }

            if (this.moveSpeed.LengthSquared() > 0.0001)
            {
                this.zoomHandler.MoveCameraPosition(this.moveSpeed * time);
                this.moveSpeed *= factor;
                needUpdate      = true;
            }
            else
            {
                this.moveSpeed = Vector3DZero;
            }

            if (Math.Abs(this.zoomSpeed) > 0.001)
            {
                this.zoomHandler.Zoom(this.zoomSpeed * time, this.zoomPoint3D);
                this.zoomSpeed *= factor;
                needUpdate      = true;
            }
            else
            {
                zoomSpeed = 0;
            }

            if (ActualCamera != null && ActualCamera.OnTimeStep())
            {
                needUpdate = true;
            }
            if (needUpdate)
            {
                lastTick = ticks;
                Viewport.InvalidateRender();
            }
            else
            {
                lastTick = 0;
            }
        }
Пример #11
0
 public static Vector3 ToVector3(this Point point)
 {
     return(new Vector3(point.ToVector2(), 0f));
 }
Пример #12
0
        public void Vector2FromPointTest()
        {
            var point = new Windows.Foundation.Point(23, 42);

            Vector2 result = point.ToVector2();

            Assert.AreEqual(23.0f, result.X);
            Assert.AreEqual(42.0f, result.Y);
        }
        /// <summary>
        /// Called when the <see cref="E:System.Windows.UIElement.ManipulationDelta"/> event occurs.
        /// </summary>
        /// <param name="e">
        /// The data for the event.
        /// </param>
        public void OnManipulationDelta(ManipulationDeltaRoutedEventArgs e)
        {
            // number of manipulators (fingers)
            if (Viewport.PointerCaptures == null)
            {
                return;
            }
            int n        = Viewport.PointerCaptures.Count();
            var position = new Point(touchPreviousPoint.X + e.Cumulative.Translation.X, touchPreviousPoint.Y + e.Cumulative.Translation.Y);

            // http://msdn.microsoft.com/en-us/library/system.windows.uielement.manipulationdelta.aspx

            //System.Diagnostics.Debug.WriteLine($"OnManipulationDelta: T={e.Cumulative.Translation}, S={e.Cumulative.Scale}, R={e.Cumulative.Rotation}, E={e.Cumulative.Expansion}");
            //// System.Diagnostics.Debug.WriteLine(n + " Delta:" + e.DeltaManipulation.Translation + " Origin:" + e.ManipulationOrigin + " pos:" + position);

            if (this.manipulatorCount != n)
            {
                // the number of manipulators has changed
                switch (this.manipulatorCount)
                {
                case 1:
                    this.rotateHandler.Completed(position);
                    break;

                case 2:
                    this.zoomHandler.Completed(e.Position);
                    break;

                case 3:
                    this.panHandler.Completed(position);
                    break;
                }

                switch (n)
                {
                case 1:
                    if (EnableTouchRotate)
                    {
                        this.rotateHandler.Started(position);
                        e.Handled = true;
                    }
                    break;

                case 2:
                    if (EnablePinchZoom)
                    {
                        this.zoomHandler.Started(e.Position);
                        e.Handled = true;
                    }
                    break;

                case 3:
                    if (EnableThreeFingerPan)
                    {
                        this.panHandler.Started(position);
                        e.Handled = true;
                    }
                    break;
                }

                // skip this event, the origin may have changed
                this.manipulatorCount = n;

                return;
            }
            else
            {
                switch (n)
                {
                case 1:
                    if (EnableTouchRotate)
                    {
                        this.rotateHandler.Delta(position.ToVector2());
                        e.Handled = true;
                    }
                    break;

                case 2:
                    if (EnablePinchZoom)
                    {
                        if (prevScale == 1)
                        {
                            prevScale = e.Cumulative.Scale;
                        }
                        else
                        {
                            if (PinchZoomAtCenter)
                            {
                                float s = e.Cumulative.Scale;
                                this.zoomHandler.Zoom((prevScale - s), CameraPosition + CameraLookDirection, true);
                                prevScale = s;
                            }
                            else
                            {
                                var zoomAroundPoint = this.zoomHandler.UnProject(
                                    e.Position, this.zoomHandler.Origin, this.CameraLookDirection);
                                if (zoomAroundPoint.HasValue)
                                {
                                    float s = e.Cumulative.Scale;
                                    this.zoomHandler.Zoom((prevScale - s), zoomAroundPoint.Value, true);
                                    prevScale = s;
                                }
                            }
                        }
                    }
                    e.Handled = true;
                    break;

                case 3:
                    if (EnableThreeFingerPan)
                    {
                        this.panHandler.Delta(position.ToVector2());
                        e.Handled = true;
                    }
                    break;
                }
            }
        }
Пример #14
0
 /// <summary>
 /// Finds the hits for a given 2D viewport position.
 /// </summary>
 /// <param name="viewport">
 /// The viewport.
 /// </param>
 /// <param name="position">
 /// The position.
 /// </param>
 /// <returns>
 /// List of hits, sorted with the nearest hit first.
 /// </returns>
 public static IList <HitTestResult> FindHits(this Viewport3DX viewport, Point position)
 {
     return(viewport.FindHits(position.ToVector2()));
 }
Пример #15
0
 /// <summary>
 /// Un-project a point from the screen (2D) to a point on plane (3D)
 /// </summary>
 /// <param name="viewport">
 /// The viewport.
 /// </param>
 /// <param name="p">
 /// The 2D point.
 /// </param>
 /// <param name="position">
 /// plane position
 /// </param>
 /// <param name="normal">
 /// plane normal
 /// </param>
 /// <returns>
 /// A 3D point.
 /// </returns>
 public static Vector3?UnProjectOnPlane(this Viewport3DX viewport, Point p, Vector3 position, Vector3 normal)
 {
     return(viewport.UnProjectOnPlane(p.ToVector2(), position, normal));
 }
Пример #16
0
 public static Ray UnProject(this Viewport3DX viewport, Point point2d)
 {
     return(UnProject(viewport, point2d.ToVector2()));
 }