コード例 #1
0
        /// <summary>
        /// Un-projects a 2D screen point.
        /// </summary>
        /// <param name="viewport">The viewport.</param>
        /// <param name="pointIn">The input point.</param>
        /// <param name="pointNear">The point at the near clipping plane.</param>
        /// <param name="pointFar">The point at the far clipping plane.</param>
        /// <returns>The ray.</returns>
        public static Ray UnProject(this Viewport3DX viewport, Vector2 point2d)//, out Vector3 pointNear, out Vector3 pointFar)
        {
            var camera = viewport.Camera as ProjectionCamera;

            if (camera != null)
            {
                var p = new Vector3((float)point2d.X, (float)point2d.Y, 1);


                //var wvp = GetViewProjectionMatrix(viewport);
                //Vector3 r = Vector3.Unproject(p, 0f, 0f, (float)viewport.ActualWidth, (float)viewport.ActualHeight, 0f, 1f, wvp);
                //r.Normalize();

                var     vp = GetScreenViewProjectionMatrix(viewport);
                var     vpi = Matrix.Invert(vp);
                Vector3 zn, zf;
                p.Z = 0;
                Vector3.TransformCoordinate(ref p, ref vpi, out zn);
                p.Z = 1;
                Vector3.TransformCoordinate(ref p, ref vpi, out zf);
                Vector3 r = zf - zn;
                r.Normalize();

                if (camera is PerspectiveCamera)
                {
                    return(new Ray(camera.Position.ToVector3(), r));
                }
                else if (camera is OrthographicCamera)
                {
                    return(new Ray(zn, r));
                }
            }
            throw new HelixToolkitException("Unproject camera error.");
        }
コード例 #2
0
        /// <summary>
        /// Initializes the 'turn-ball' rotation axes from the specified point.
        /// </summary>
        /// <param name="p1">
        /// The point.
        /// </param>
        private void InitTurnballRotationAxes(Vector2 p1)
        {
            double fx = p1.X / this.Viewport.ActualWidth;
            double fy = p1.Y / this.Viewport.ActualHeight;

            var up  = Vector3.Normalize(Camera.CameraInternal.UpDirection);
            var dir = Vector3.Normalize(Camera.CameraInternal.LookDirection);

            var right = Vector3.Normalize(Vector3.Cross(dir, up));

            this.rotationAxisX = up;
            this.rotationAxisY = right;
            if (fy > 0.8 || fy < 0.2)
            {
                // delta.Y = 0;
            }

            if (fx > 0.8)
            {
                // delta.X = 0;
                this.rotationAxisY = dir;
            }

            if (fx < 0.2)
            {
                // delta.X = 0;
                this.rotationAxisY = -dir;
            }
        }
コード例 #3
0
        /// <summary>
        /// Changes the camera distance.
        /// </summary>
        /// <param name="delta">The delta.</param>
        /// <param name="zoomAround">The zoom around point.</param>
        private bool ChangeCameraDistance(ref double delta, Vector3 zoomAround)
        {
            // Handle the 'zoomAround' point
            var target           = this.Camera.CameraInternal.Position + this.Camera.CameraInternal.LookDirection;
            var relativeTarget   = zoomAround - target;
            var relativePosition = zoomAround - this.Camera.CameraInternal.Position;

            if (relativePosition.Length() < 1e-4)
            {
                if (delta > 0) //If Zoom out from very close distance, increase the initial relativePosition
                {
                    relativePosition = Vector3.Normalize(relativePosition) / 10;
                }
                else//If Zoom in too close, stop it.
                {
                    return(false);
                }
            }
            var f = (float)Math.Pow(2.5, delta);
            var newRelativePosition = relativePosition * f;
            var newRelativeTarget   = relativeTarget * f;

            var newTarget   = zoomAround - newRelativeTarget;
            var newPosition = zoomAround - newRelativePosition;

            var newDistance = (newPosition - zoomAround).Length();
            var oldDistance = (this.Camera.CameraInternal.Position - zoomAround).Length();

            if (newDistance > this.Controller.ZoomDistanceLimitFar && (oldDistance < this.Controller.ZoomDistanceLimitFar || newDistance > oldDistance))
            {
                var ratio = (newDistance - (float)Controller.ZoomDistanceLimitFar) / newDistance;
                f *= 1 - ratio;
                newRelativePosition = relativePosition * f;
                newRelativeTarget   = relativeTarget * f;

                newTarget   = zoomAround - newRelativeTarget;
                newPosition = zoomAround - newRelativePosition;
                delta       = Math.Log(f) / Math.Log(2.5);
                // return false;
            }

            if (newDistance < this.Controller.ZoomDistanceLimitNear && (oldDistance > this.Controller.ZoomDistanceLimitNear || newDistance < oldDistance))
            {
                var ratio = ((float)Controller.ZoomDistanceLimitNear - newDistance) / newDistance;
                f *= (1 + ratio);
                newRelativePosition = relativePosition * f;
                newRelativeTarget   = relativeTarget * f;

                newTarget   = zoomAround - newRelativeTarget;
                newPosition = zoomAround - newRelativePosition;
                delta       = Math.Log(f) / Math.Log(2.5);
                // return false;
            }

            var newLookDirection = newTarget - newPosition;

            this.Camera.LookDirection = newLookDirection.ToVector3D();
            this.Camera.Position      = newPosition.ToPoint3D();
            return(true);
        }
コード例 #4
0
        /// <summary>
        /// Calculates the normal vectors.
        /// </summary>
        /// <param name="positions">
        /// The positions.
        /// </param>
        /// <param name="triangleIndices">
        /// The triangle indices.
        /// </param>
        /// <returns>
        /// Collection of normal vectors.
        /// </returns>
        public static Vector3DCollection CalculateNormals(IList <Point3D> positions, IList <int> triangleIndices)
        {
            var normals = new Vector3DCollection(positions.Count);

            for (int i = 0; i < positions.Count; i++)
            {
                normals.Add(new Vector3D());
            }

            for (int i = 0; i < triangleIndices.Count; i += 3)
            {
                int      index0 = triangleIndices[i];
                int      index1 = triangleIndices[i + 1];
                int      index2 = triangleIndices[i + 2];
                var      p0     = positions[index0];
                var      p1     = positions[index1];
                var      p2     = positions[index2];
                Vector3D u      = p1 - p0;
                Vector3D v      = p2 - p0;
                Vector3D w      = SharedFunctions.CrossProduct(ref u, ref v);
                w.Normalize();
                normals[index0] += w;
                normals[index1] += w;
                normals[index2] += w;
            }

            for (int i = 0; i < normals.Count; i++)
            {
                var n = normals[i];
                n.Normalize();
                normals[i] = n;
            }

            return(normals);
        }
コード例 #5
0
        /// <summary>
        /// The rotate trackball.
        /// </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>
        private void RotateTrackball(Vector2 p1, Vector2 p2, Vector3 rotateAround)
        {
            // http://viewport3d.com/trackball.htm
            // http://www.codeplex.com/3DTools/Thread/View.aspx?ThreadId=22310
            var v1  = ProjectToTrackball(p1, this.Viewport.ActualWidth, this.Viewport.ActualHeight);
            var v2  = ProjectToTrackball(p2, this.Viewport.ActualWidth, this.Viewport.ActualHeight);
            var cUP = Camera.CameraInternal.UpDirection;
            // transform the trackball coordinates to view space
            var viewZ = Vector3.Normalize(Camera.CameraInternal.LookDirection * Inv);
            var viewX = Vector3.Normalize(Vector3.Cross(cUP, viewZ) * Inv);
            var viewY = Vector3.Normalize(Vector3.Cross(viewX, viewZ));
            var u1    = (viewZ * v1.Z) + (viewX * v1.X) + (viewY * v1.Y);
            var u2    = (viewZ * v2.Z) + (viewX * v2.X) + (viewY * v2.Y);

            // Could also use the Camera ViewMatrix
            // var vm = Viewport3DHelper.GetViewMatrix(this.ActualCamera);
            // vm.Invert();
            // var ct = new MatrixTransform3D(vm);
            // var u1 = ct.Transform(v1);
            // var u2 = ct.Transform(v2);

            // Find the rotation axis and angle
            var axis = Vector3.Cross(u1, u2);

            if (axis.LengthSquared() < 1e-8)
            {
                return;
            }

            var angle = VectorExtensions.AngleBetween(u1, u2);

            // Create the transform
            var rotate = Matrix.RotationAxis(Vector3.Normalize(axis), -angle * (float)RotationSensitivity * 5);

            // Find vectors relative to the rotate-around point
            var relativeTarget   = rotateAround - this.Camera.CameraInternal.Target;
            var relativePosition = rotateAround - this.Camera.CameraInternal.Position;

            // Rotate the relative vectors
            var newRelativeTarget   = Vector3.TransformCoordinate(relativeTarget, rotate);
            var newRelativePosition = Vector3.TransformCoordinate(relativePosition, rotate);
            var newUpDirection      = Vector3.TransformCoordinate(cUP, rotate);

            // Find new camera position
            var newTarget   = rotateAround - newRelativeTarget;
            var newPosition = rotateAround - newRelativePosition;

            this.Camera.LookDirection = (newTarget - newPosition).ToVector3D();
            if (this.CameraMode == CameraMode.Inspect)
            {
                this.Camera.Position = newPosition.ToPoint3D();
            }

            this.Camera.UpDirection = newUpDirection.ToVector3D();
        }
コード例 #6
0
        /// <summary>
        /// Moves the camera position.
        /// </summary>
        /// <param name="camera">The camera.</param>
        /// <param name="delta">The delta.</param>
        public static void MoveCameraPosition(this Camera camera, Vector3D delta)
        {
            var z = Vector3.Normalize(camera.CameraInternal.LookDirection);
            var x = Vector3.Cross(z, camera.CameraInternal.UpDirection);
            var y = Vector3.Normalize(Vector3.Cross(x, z));

            x = Vector3.Cross(z, y);

            // delta *= this.ZoomSensitivity;
            camera.Position += ((x * (float)delta.X) + (y * (float)delta.Y) + (z * (float)delta.Z)).ToVector3D();
        }
コード例 #7
0
        /// <summary>
        /// Finds the pan vector.
        /// </summary>
        /// <param name="dx">
        /// The delta x.
        /// </param>
        /// <param name="dy">
        /// The delta y.
        /// </param>
        /// <returns>
        /// The <see cref="Vector3"/> .
        /// </returns>
        private Vector3 FindPanVector(float dx, float dy)
        {
            var axis1 = Vector3.Normalize(Vector3.Cross(this.CameraLookDirection, this.CameraUpDirection));
            var axis2 = Vector3.Normalize(Vector3.Cross(axis1, this.CameraLookDirection));

            axis1 *= (ActualCamera.CreateLeftHandSystem ? -1 : 1);
            var l    = this.CameraLookDirection.Length();
            var f    = l * 0.001f;
            var move = (-axis1 * f * dx) + (axis2 * f * dy);

            // this should be dependent on distance to target?
            return(move);
        }
コード例 #8
0
        /// <summary>
        /// Zooms the camera to the specified rectangle.
        /// </summary>
        /// <param name="camera">
        /// The camera.
        /// </param>
        /// <param name="viewport">
        /// The viewport.
        /// </param>
        /// <param name="zoomRectangle">
        /// The zoom rectangle.
        /// </param>
        public static void ZoomToRectangle(this Camera camera, Viewport3DX viewport, Rect zoomRectangle)
        {
            var topLeftRay  = viewport.UnProjectToRay(zoomRectangle.TopLeft);
            var topRightRay = viewport.UnProjectToRay(zoomRectangle.TopRight);
            var centerRay   =
                viewport.UnProjectToRay(
                    new Point(
                        (zoomRectangle.Left + zoomRectangle.Right) * 0.5,
                        (zoomRectangle.Top + zoomRectangle.Bottom) * 0.5));

            if (topLeftRay == null || topRightRay == null || centerRay == null)
            {
                // could not invert camera matrix
                return;
            }

            var u = Vector3.Normalize(topLeftRay.Direction);
            var v = Vector3.Normalize(topRightRay.Direction);
            var w = Vector3.Normalize(centerRay.Direction);

            if (camera is IPerspectiveCameraModel perspectiveCamera)
            {
                var distance = camera.LookDirection.Length;

                // option 1: change distance
                var newDistance      = distance * zoomRectangle.Width / viewport.ActualWidth;
                var newLookDirection = (float)newDistance * w;
                var newPosition      = camera.CameraInternal.Position + ((float)(distance - newDistance) * w);
                var newTarget        = newPosition + newLookDirection;
                LookAt(camera, newTarget.ToPoint3D(), newLookDirection.ToVector3D(), 200);

                // option 2: change fov
                // double newFieldOfView = Math.Acos(Vector3D.DotProduct(u, v));
                // var newTarget = camera.Position + distance * w;
                // pcamera.FieldOfView = newFieldOfView * 180 / Math.PI;
                // LookAt(camera, newTarget, distance * w, 0);
            }
            else if (camera is IOrthographicCameraModel orthographicCamera)
            {
                orthographicCamera.Width *= zoomRectangle.Width / viewport.ActualWidth;
                var oldTarget = camera.CameraInternal.Position + camera.CameraInternal.LookDirection;
                var distance  = camera.CameraInternal.LookDirection.Length();
                var newTarget = centerRay.PlaneIntersection(oldTarget, w);
                if (newTarget != null)
                {
                    LookAt(orthographicCamera, newTarget.Value.ToPoint3D(), 200);
                }
            }
        }
コード例 #9
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(Vector2 p1, Vector2 p2, Vector3 rotateAround)
        {
            this.InitTurnballRotationAxes(p1);

            Vector2 delta = p2 - p1;

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

            float d = -1;

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

            d *= (float)RotationSensitivity;

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

            var     m              = Matrix.RotationQuaternion(q);
            Vector3 newLookDir     = Vector3.TransformNormal(this.Camera.CameraInternal.LookDirection, m);
            Vector3 newUpDirection = Vector3.TransformNormal(this.Camera.CameraInternal.UpDirection, m);

            Vector3 newRelativeTarget   = Vector3.TransformCoordinate(relativeTarget, m);
            Vector3 newRelativePosition = Vector3.TransformCoordinate(relativePosition, m);

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

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

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

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

            this.Camera.UpDirection = newUpDirection.ToVector3D();
        }
コード例 #10
0
        /// <summary>
        /// Rotates the specified p0.
        /// </summary>
        /// <param name="p0">The p0.</param>
        /// <param name="p1">The p1.</param>
        /// <param name="rotateAround">The rotate around.</param>
        /// <param name="stopOther">if set to <c>true</c> [stop other].</param>
        public void Rotate(Vector2 p0, Vector2 p1, Vector3 rotateAround, bool stopOther = true)
        {
            if (!this.Controller.IsRotationEnabled)
            {
                return;
            }
            if (stopOther)
            {
                Controller.StopZooming();
                Controller.StopPanning();
            }
            p0 = Vector2.Multiply(p0, Controller.AllowRotateXY);
            p1 = Vector2.Multiply(p1, Controller.AllowRotateXY);
            Vector3 newPos  = Camera.CameraInternal.Position;
            Vector3 newLook = Camera.CameraInternal.LookDirection;
            Vector3 newUp   = Vector3.Normalize(Camera.CameraInternal.UpDirection);

            switch (this.Controller.CameraRotationMode)
            {
            case CameraRotationMode.Trackball:
                CameraMath.RotateTrackball(CameraMode, ref p0, ref p1, ref rotateAround, (float)RotationSensitivity,
                                           Controller.Width, Controller.Height, Camera, Inv, out newPos, out newLook, out newUp);
                break;

            case CameraRotationMode.Turntable:
                var p = p1 - p0;
                CameraMath.RotateTurntable(CameraMode, ref p, ref rotateAround, (float)RotationSensitivity,
                                           Controller.Width, Controller.Height, Camera, Inv, ModelUpDirection, out newPos, out newLook, out newUp);
                break;

            case CameraRotationMode.Turnball:
                CameraMath.RotateTurnball(CameraMode, ref p0, ref p1, ref rotateAround, (float)RotationSensitivity,
                                          Controller.Width, Controller.Height, Camera, Inv, out newPos, out newLook, out newUp);
                break;

            default:
                break;
            }
            Camera.LookDirection = newLook.ToVector3D();
            Camera.Position      = newPos.ToPoint3D();
            Camera.UpDirection   = newUp.ToVector3D();
        }
コード例 #11
0
        /// <summary>
        /// Rotate camera using 'Turntable' rotation.
        /// </summary>
        /// <param name="delta">
        /// The relative change in position.
        /// </param>
        /// <param name="rotateAround">
        /// The point to rotate around.
        /// </param>
        public void RotateTurntable(Vector2 delta, Vector3 rotateAround)
        {
            var relativeTarget   = rotateAround - this.Camera.CameraInternal.Target;
            var relativePosition = rotateAround - this.Camera.CameraInternal.Position;
            var cUp   = Camera.CameraInternal.UpDirection;
            var up    = this.ModelUpDirection;
            var dir   = Vector3.Normalize(Camera.CameraInternal.LookDirection);
            var right = Vector3.Normalize(Vector3.Cross(dir, cUp));

            float d = -0.5f;

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

            d *= (float)this.RotationSensitivity;

            var        q1 = Quaternion.RotationAxis(up, d * Inv * delta.X / 180 * (float)Math.PI);
            var        q2 = Quaternion.RotationAxis(right, d * delta.Y / 180 * (float)Math.PI);
            Quaternion q  = q1 * q2;

            var m = Matrix.RotationQuaternion(q);

            var newUpDirection = Vector3.TransformNormal(cUp, m);

            var newRelativeTarget   = Vector3.TransformCoordinate(relativeTarget, m);
            var newRelativePosition = Vector3.TransformCoordinate(relativePosition, m);

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

            this.Camera.LookDirection = (newTarget - newPosition).ToVector3D();
            if (this.CameraMode == CameraMode.Inspect)
            {
                this.Camera.Position = newPosition.ToPoint3D();
            }

            this.Camera.UpDirection = newUpDirection.ToVector3D();
        }
コード例 #12
0
        /// <summary>
        /// Un-projects a 2D screen point.
        /// </summary>
        /// <param name="viewport">The viewport.</param>
        /// <param name="point2d">The input point.</param>
        /// <returns>The ray.</returns>
        public static Ray UnProject(this Viewport3DX viewport, Vector2 point2d)//, out Vector3 pointNear, out Vector3 pointFar)
        {
            var camera = viewport.CameraCore as ProjectionCameraCore;

            if (camera != null)
            {
                var px = (float)point2d.X;
                var py = (float)point2d.Y;

                var     viewMatrix = camera.GetViewMatrix();
                Vector3 v          = new Vector3();

                var   matrix      = MatrixExtensions.PsudoInvert(ref viewMatrix);
                float w           = (float)viewport.ActualWidth;
                float h           = (float)viewport.ActualHeight;
                var   aspectRatio = w / h;

                var     projMatrix = camera.GetProjectionMatrix(aspectRatio);
                Vector3 zn, zf;
                v.X = (2 * px / w - 1) / projMatrix.M11;
                v.Y = -(2 * py / h - 1) / projMatrix.M22;
                v.Z = 1 / projMatrix.M33;
                Vector3.TransformCoordinate(ref v, ref matrix, out zf);

                if (camera is PerspectiveCameraCore)
                {
                    zn = camera.Position;
                }
                else
                {
                    v.Z = 0;
                    Vector3.TransformCoordinate(ref v, ref matrix, out zn);
                }
                Vector3 r = zf - zn;
                r.Normalize();

                return(new Ray(zn + r * camera.NearPlaneDistance, r));
            }
            throw new HelixToolkitException("Unproject camera error.");
        }
コード例 #13
0
        /// <summary>
        /// Zooms the camera to the specified rectangle.
        /// </summary>
        /// <param name="camera">
        /// The camera.
        /// </param>
        /// <param name="viewport">
        /// The viewport.
        /// </param>
        /// <param name="zoomRectangle">
        /// The zoom rectangle.
        /// </param>
        public static void ZoomToRectangle(this Camera camera, Viewport3DX viewport, Rect zoomRectangle)
        {
            if (viewport.UnProject(zoomRectangle.TopLeft.ToVector2(), out var topLeftRay) &&
                viewport.UnProject(zoomRectangle.TopRight.ToVector2(), out var topRightRay) &&
                viewport.UnProject(new global::SharpDX.Vector2(
                                       (float)(zoomRectangle.Left + zoomRectangle.Right) * 0.5f,
                                       (float)(zoomRectangle.Top + zoomRectangle.Bottom) * 0.5f), out var centerRay))
            {
                var u = Vector3.Normalize(topLeftRay.Direction);
                var v = Vector3.Normalize(topRightRay.Direction);
                var w = Vector3.Normalize(centerRay.Direction);
                if (camera is IPerspectiveCameraModel perspectiveCamera)
                {
                    var distance = camera.LookDirection.Length;

                    // option 1: change distance
                    var newDistance      = distance * zoomRectangle.Width / viewport.ActualWidth;
                    var newLookDirection = (float)newDistance * w;
                    var newPosition      = camera.CameraInternal.Position + ((float)(distance - newDistance) * w);
                    var newTarget        = newPosition + newLookDirection;
                    LookAt(camera, newTarget.ToPoint3D(), newLookDirection.ToVector3D(), 200);

                    // option 2: change fov
                    // double newFieldOfView = Math.Acos(Vector3D.DotProduct(u, v));
                    // var newTarget = camera.Position + distance * w;
                    // pcamera.FieldOfView = newFieldOfView * 180 / Math.PI;
                    // LookAt(camera, newTarget, distance * w, 0);
                }
                else if (camera is IOrthographicCameraModel orthographicCamera)
                {
                    orthographicCamera.Width *= zoomRectangle.Width / viewport.ActualWidth;
                    var oldTarget = camera.CameraInternal.Position + camera.CameraInternal.LookDirection;
                    var distance  = camera.CameraInternal.LookDirection.Length();
                    if (centerRay.PlaneIntersection(oldTarget, w, out var newTarget))
                    {
                        LookAt(orthographicCamera, newTarget.ToPoint3D(), 200);
                    }
                }
            }
        }
コード例 #14
0
        /// <summary>
        /// Changes the camera position by the specified vector.
        /// </summary>
        /// <param name="delta">The translation vector in camera space (z in look direction, y in up direction, and x perpendicular to the two others)</param>
        /// <param name="stopOther">Stop other manipulation</param>
        public void MoveCameraPosition(Vector3 delta, bool stopOther = true)
        {
            if (stopOther)
            {
                Controller.StopPanning();
                Controller.StopSpin();
            }
            var z = Vector3.Normalize(this.Camera.CameraInternal.LookDirection);
            var x = Vector3.Cross(this.Camera.CameraInternal.LookDirection, this.Camera.CameraInternal.UpDirection);
            var y = Vector3.Normalize(Vector3.Cross(x, z));

            x = Vector3.Cross(z, y);

            // delta *= this.ZoomSensitivity;
            switch (this.CameraMode)
            {
            case CameraMode.Inspect:
            case CameraMode.WalkAround:
                this.Camera.Position += ((x * delta.X) + (y * delta.Y) + (z * delta.Z)).ToVector3D();
                break;
            }
        }
コード例 #15
0
        private bool Flipped(ref Vector3D p, int i0, int i1, ref Vertex v0, ref Vertex v1, IList <bool> deleted)
        {
            for (int i = 0; i < v0.tCount; ++i)
            {
                var t = triangles[refs[v0.tStart + i].tid];
                if (t.deleted)
                {
                    continue;
                }
                int s   = refs[v0.tStart + i].tvertex;
                int id1 = t.v[(s + 1) % 3];
                int id2 = t.v[(s + 2) % 3];
                if (id1 == i1 || id2 == i1)
                {
                    deleted[i] = true;
                    continue;
                }

                Vector3D d1 = vertices[id1].p - p;
                d1.Normalize();
                Vector3D d2 = vertices[id2].p - p;
                d2.Normalize();
                if (SharedFunctions.DotProduct(ref d1, ref d2) > 0.999)
                {
                    return(true);
                }
                var n = SharedFunctions.CrossProduct(ref d1, ref d2);
                n.Normalize();
                deleted[i] = false;
                if (SharedFunctions.DotProduct(ref n, ref t.normal) < 0.2)
                {
                    return(true);
                }
            }
            return(false);
        }
コード例 #16
0
ファイル: MeshBuilder.cs プロジェクト: BEEden/Diplomarbeit
        /// <summary>
        /// Adds an extruded surface of the specified curve.
        /// </summary>
        /// <param name="points">
        /// The 2D points describing the curve to extrude.
        /// </param>
        /// <param name="xaxis">
        /// The x-axis.
        /// </param>
        /// <param name="p0">
        /// The start origin of the extruded surface.
        /// </param>
        /// <param name="p1">
        /// The end origin of the extruded surface.
        /// </param>
        /// <remarks>
        /// The y-axis is determined by the cross product between the specified x-axis and the p1-p0 vector.
        /// </remarks>
        public void AddExtrudedGeometry(IList<Point> points, Vector3D xaxis, Point3D p0, Point3D p1)
        {
            var ydirection = Vector3D.Cross(p1 - p0, xaxis);
            ydirection.Normalize();
            xaxis.Normalize();

            int index0 = this.positions.Count;
            int np = 2 * points.Count;
            foreach (var p in points)
            {
                var v = (xaxis * p.X) + (ydirection * p.Y);

                this.positions.Add(p0 + v);
                this.positions.Add(p1 + v);
            }

            int ii = 0;
            for (int i = 0; i < points.Count - 1; i++, ii += 2)
            {
                int i0 = index0 + ii;
                int i1 = i0 + 1;
                int i2 = i0 + 2;
                int i3 = i0 + 3;


                this.triangleIndices.Add(i1);
                this.triangleIndices.Add(i2);
                this.triangleIndices.Add(i0);

                this.triangleIndices.Add(i1);
                this.triangleIndices.Add(i3);
                this.triangleIndices.Add(i2);
            }
            if (this.textureCoordinates != null)
            {
                for (int i = 0; i < np; i++)
                {
                    this.textureCoordinates.Add(new Point());
                }
            }

            //foreach (var p in points)
            //{                
            //    if (this.normals != null)
            //    {                    
            //        //this.normals.Add(Vector3D.UnitZ);
            //        //this.normals.Add(Vector3D.UnitZ);
            //    }

            //    if (this.textureCoordinates != null)
            //    {
            //        this.textureCoordinates.Add(new Point(0, 0));
            //        this.textureCoordinates.Add(new Point(1, 0));
            //    }

            //    int i1 = index0 + 1;
            //    int i2 = (index0 + 2) % np;
            //    int i3 = ((index0 + 2) % np) + 1;

            //    this.triangleIndices.Add(i1);
            //    this.triangleIndices.Add(i2);
            //    this.triangleIndices.Add(index0);

            //    this.triangleIndices.Add(i1);
            //    this.triangleIndices.Add(i3);
            //    this.triangleIndices.Add(i2);
            //}

            Vector3D[] normals;
            ComputeNormals(this.positions, this.triangleIndices, out normals);
            this.normals = normals.ToList();
        }
コード例 #17
0
ファイル: MeshBuilder.cs プロジェクト: BEEden/Diplomarbeit
        /// <summary>
        /// Adds a surface of revolution.
        /// </summary>
        /// <param name="points">
        /// The points (y coordinates are radius, x coordinates are distance from the origin along the axis of revolution)
        /// </param>
        /// <param name="origin">
        /// The origin of the revolution axis.
        /// </param>
        /// <param name="direction">
        /// The direction of the revolution axis.
        /// </param>
        /// <param name="thetaDiv">
        /// The number of divisions around the mesh.
        /// </param>
        /// <remarks>
        /// See http://en.wikipedia.org/wiki/Surface_of_revolution.
        /// </remarks>
        public void AddRevolvedGeometry(IList<Point> points, Point3D origin, Vector3D direction, int thetaDiv)
        {
            direction.Normalize();

            // Find two unit vectors orthogonal to the specified direction
            var u = direction.FindAnyPerpendicular();
            var v = Vector3D.Cross(direction, u);

            u.Normalize();
            v.Normalize();

            var circle = GetCircle(thetaDiv);

            int index0 = this.positions.Count;
            int n = points.Count;

            int totalNodes = (points.Count - 1) * 2 * thetaDiv;
            int rowNodes = (points.Count - 1) * 2;

            for (int i = 0; i < thetaDiv; i++)
            {
                var w = (v * circle[i].X) + (u * circle[i].Y);

                for (int j = 0; j + 1 < n; j++)
                {
                    // Add segment
                    var q1 = origin + (direction * points[j].X) + (w * points[j].Y);
                    var q2 = origin + (direction * points[j + 1].X) + (w * points[j + 1].Y);

                    // todo:should not add segment if q1==q2 (corner point)
                    // const double eps = 1e-6;
                    // if (Point3D.Subtract(q1, q2).LengthSquared < eps)
                    // continue;
                    float tx = points[j + 1].X - points[j].X;
                    float ty = points[j + 1].Y - points[j].Y;

                    var normal = (-direction * ty) + (w * tx);
                    normal.Normalize();

                    this.positions.Add(q1);
                    this.positions.Add(q2);

                    if (this.normals != null)
                    {
                        this.normals.Add(normal);
                        this.normals.Add(normal);
                    }

                    if (this.textureCoordinates != null)
                    {
                        this.textureCoordinates.Add(new Point((float)i / (thetaDiv - 1), (float)j / (n - 1)));
                        this.textureCoordinates.Add(new Point((float)i / (thetaDiv - 1), (float)(j + 1) / (n - 1)));
                    }

                    int i0 = index0 + (i * rowNodes) + (j * 2);
                    int i1 = i0 + 1;
                    int i2 = index0 + ((((i + 1) * rowNodes) + (j * 2)) % totalNodes);
                    int i3 = i2 + 1;

                    this.triangleIndices.Add(i1);
                    this.triangleIndices.Add(i0);
                    this.triangleIndices.Add(i2);

                    this.triangleIndices.Add(i1);
                    this.triangleIndices.Add(i2);
                    this.triangleIndices.Add(i3);
                }
            }
        }
コード例 #18
0
ファイル: Vector3DExtensions.cs プロジェクト: alir14/3DModel
 public static global::SharpDX.Vector3 Normalized(this global::SharpDX.Vector3 vector)
 {
     vector.Normalize();
     return(vector);
 }