public void DrawLine(Vector3 start, Vector3 end, Color color, float width = 0.025f)
        {
            Vector3 dir = end - start;

            dir.Z = 0;

            Vector3 extDir1;
            Vector3 extDir2;

            if (dir.LengthSquared() > 0.0001f)
            {
                dir.Normalize();

                extDir1.X = -dir.Y;
                extDir1.Y = dir.X;
                extDir1.Z = 0;

                extDir2 = Vector3.Cross(dir, extDir1);
            }
            else
            {
                extDir1 = Vector3.UnitX;
                extDir2 = Vector3.UnitY;
            }

            _vertexBuffer[0] = new ColoredVertex(start + extDir1 * (width / 2), color);
            _vertexBuffer[1] = new ColoredVertex(start - extDir1 * (width / 2), color);
            _vertexBuffer[2] = new ColoredVertex(end + extDir1 * (width / 2), color);
            _vertexBuffer[3] = new ColoredVertex(end - extDir1 * (width / 2), color);

            _vertexBuffer[4] = new ColoredVertex(start + extDir2 * (width / 2), color);
            _vertexBuffer[5] = new ColoredVertex(start - extDir2 * (width / 2), color);
            _vertexBuffer[6] = new ColoredVertex(end + extDir2 * (width / 2), color);
            _vertexBuffer[7] = new ColoredVertex(end - extDir2 * (width / 2), color);

            _indexBuffer[0] = 0;
            _indexBuffer[1] = 1;
            _indexBuffer[2] = 2;

            _indexBuffer[3] = 1;
            _indexBuffer[4] = 2;
            _indexBuffer[5] = 3;

            _indexBuffer[6] = 4;
            _indexBuffer[7] = 5;
            _indexBuffer[8] = 6;

            _indexBuffer[9]  = 5;
            _indexBuffer[10] = 6;
            _indexBuffer[11] = 7;

            SetDeclaration();
            Device.DrawIndexedUserPrimitives(PrimitiveType.TriangleList, 0, 8, 4, _indexBuffer,
                                             Format.Index32, _vertexBuffer, ColoredVertex.Stride);
        }
        /// <summary>
        /// Creates a right-handed spherical billboard that rotates around a specified object position.
        /// </summary>
        /// <param name="objectPosition">The position of the object around which the billboard will rotate.</param>
        /// <param name="cameraPosition">The position of the camera.</param>
        /// <param name="cameraUpVector">The up vector of the camera.</param>
        /// <param name="cameraForwardVector">The forward vector of the camera.</param>
        public static Matrix BillboardLh(ref Vector3 objectPosition, ref Vector3 cameraPosition, ref Vector3 cameraUpVector, ref Vector3 cameraForwardVector)
        {
            var     result = new Matrix();
            Vector3 crossed;
            Vector3 final;
            Vector3 difference = cameraPosition - objectPosition;

            float lengthSq = difference.LengthSquared();

            if (IsZero(lengthSq))
            {
                difference = -cameraForwardVector;
            }
            else
            {
                difference *= (float)(1.0 / Math.Sqrt(lengthSq));
            }

            Vector3.Cross(ref cameraUpVector, ref difference, out crossed);
            crossed.Normalize();
            Vector3.Cross(ref difference, ref crossed, out final);

            result.M11 = crossed.X;
            result.M12 = crossed.Y;
            result.M13 = crossed.Z;
            result.M14 = 0.0f;

            result.M21 = final.X;
            result.M22 = final.Y;
            result.M23 = final.Z;
            result.M24 = 0.0f;

            result.M31 = difference.X;
            result.M32 = difference.Y;
            result.M33 = difference.Z;
            result.M34 = 0.0f;

            result.M41 = objectPosition.X;
            result.M42 = objectPosition.Y;
            result.M43 = objectPosition.Z;
            result.M44 = 1.0f;

            return(result);
        }
Exemple #3
0
        /// <summary>
        /// Creates the smallest <see cref="BoundingSphere"/> that can contain a specified list of points in 3D-space.
        /// </summary>
        /// <param name="points">List of point to create the sphere from.</param>
        /// <returns>The new <see cref="BoundingSphere"/>.</returns>
        public static BoundingSphere CreateFromPoints(IEnumerable <Vector3> points)
        {
            if (points == null)
            {
                throw new ArgumentNullException("points");
            }

            // From "Real-Time Collision Detection" (Page 89)

            Vector3 minx = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
            Vector3 maxx = -minx;
            Vector3 miny = minx;
            Vector3 maxy = -minx;
            Vector3 minz = minx;
            Vector3 maxz = -minx;

            // Find the most extreme points along the principle axis.
            int numPoints = 0;

            foreach (Vector3 pt in points)
            {
                numPoints += 1;

                if (pt.X < minx.X)
                {
                    minx = pt;
                }
                if (pt.X > maxx.X)
                {
                    maxx = pt;
                }
                if (pt.Y < miny.Y)
                {
                    miny = pt;
                }
                if (pt.Y > maxy.Y)
                {
                    maxy = pt;
                }
                if (pt.Z < minz.Z)
                {
                    minz = pt;
                }
                if (pt.Z > maxz.Z)
                {
                    maxz = pt;
                }
            }

            if (numPoints == 0)
            {
                throw new ArgumentException(
                          "You should have at least one point in points."
                          );
            }

            float sqDistX = Vector3.DistanceSquared(maxx, minx);
            float sqDistY = Vector3.DistanceSquared(maxy, miny);
            float sqDistZ = Vector3.DistanceSquared(maxz, minz);

            // Pick the pair of most distant points.
            Vector3 min = minx;
            Vector3 max = maxx;

            if (sqDistY > sqDistX && sqDistY > sqDistZ)
            {
                max = maxy;
                min = miny;
            }
            if (sqDistZ > sqDistX && sqDistZ > sqDistY)
            {
                max = maxz;
                min = minz;
            }

            Vector3 center = (min + max) * 0.5f;
            float   radius = Vector3.Distance(max, center);

            // Test every point and expand the sphere.
            // The current bounding sphere is just a good approximation and may not enclose all points.
            // From: Mathematics for 3D Game Programming and Computer Graphics, Eric Lengyel, Third Edition.
            // Page 218
            float sqRadius = radius * radius;

            foreach (Vector3 pt in points)
            {
                Vector3 diff   = (pt - center);
                float   sqDist = diff.LengthSquared();
                if (sqDist > sqRadius)
                {
                    float   distance  = (float)Math.Sqrt(sqDist);                   // equal to diff.Length();
                    Vector3 direction = diff / distance;
                    Vector3 G         = center - radius * direction;
                    center   = (G + pt) / 2;
                    radius   = Vector3.Distance(pt, center);
                    sqRadius = radius * radius;
                }
            }

            return(new BoundingSphere(center, radius));
        }