Esempio n. 1
0
        /// <summary>
        /// Computes a convex shape description for a ConvexHullShape.
        /// </summary>
        /// <param name="vertices">Vertices describing the convex hull shape.</param>
        /// <param name="collisionMargin">Collision margin of the shape.</param>
        /// <param name="center">Computed center of the convex hull shape. Used as the origin of the outputUniqueSurfaceVertices.</param>
        /// <param name="outputHullTriangleIndices">Computed list of indices into the input point set composing the triangulated surface of the convex hull.
        /// Each group of 3 indices represents a triangle on the surface of the hull.</param>
        /// <param name="outputUniqueSurfaceVertices">Computed nonredundant list of vertices composing the outer shell of the input point set. Recentered on the local origin.</param>
        /// <returns>Description required to define a convex shape.</returns>
        public static ConvexShapeDescription ComputeDescription(IList <Vector3> vertices, float collisionMargin, out Vector3 center, IList <int> outputHullTriangleIndices, IList <Vector3> outputUniqueSurfaceVertices)
        {
            if (outputHullTriangleIndices.Count != 0 || outputUniqueSurfaceVertices.Count != 0)
            {
                throw new ArgumentException("Output lists must start empty.");
            }


            ConvexShapeDescription description;

            ConvexHullHelper.GetConvexHull(vertices, outputHullTriangleIndices, outputUniqueSurfaceVertices);

            InertiaHelper.ComputeShapeDistribution(vertices, outputHullTriangleIndices, out center, out description.EntityShapeVolume.Volume, out description.EntityShapeVolume.VolumeDistribution);
            //Recenter the surface vertices.
            for (int i = 0; i < outputUniqueSurfaceVertices.Count; ++i)
            {
                outputUniqueSurfaceVertices[i] -= center;
            }

            description.MinimumRadius = InertiaHelper.ComputeMinimumRadius(vertices, outputHullTriangleIndices, ref center) + collisionMargin;
            description.MaximumRadius = ComputeMaximumRadius(outputUniqueSurfaceVertices, collisionMargin);

            description.CollisionMargin = collisionMargin;
            return(description);
        }
Esempio n. 2
0
        /// <summary>
        /// Computes and applies a convex shape description for this WrappedShape.
        /// </summary>
        /// <param name="center">Computed center of the shape before recentering.</param>
        public void UpdateConvexShapeInfo(out Vector3 center)
        {
            //Compute the volume distribution.
            var samples = CommonResources.GetVectorList();

            if (samples.Capacity < InertiaHelper.SampleDirections.Length)
            {
                samples.Capacity = InertiaHelper.SampleDirections.Length;
            }
            samples.Count = InertiaHelper.SampleDirections.Length;
            for (int i = 0; i < InertiaHelper.SampleDirections.Length; ++i)
            {
                GetLocalExtremePoint(InertiaHelper.SampleDirections[i], out samples.Elements[i]);
            }

            var triangles = CommonResources.GetIntList();

            ConvexHullHelper.GetConvexHull(samples, triangles);

            float volume;

            InertiaHelper.ComputeShapeDistribution(samples, triangles, out center, out volume, out volumeDistribution);
            Volume = volume;

            CommonResources.GiveBack(samples);
            CommonResources.GiveBack(triangles);

            //Now recenter the shape and compute the radii estimates.
            for (int i = 0; i < shapes.Count; i++)
            {
                shapes.WrappedList.Elements[i].Transform.Position -= center;
            }
            MinimumRadius = ComputeMinimumRadius();
            MaximumRadius = ComputeMaximumRadius();
        }
Esempio n. 3
0
        public static void GetShapeMeshData(EntityCollidable collidable, List <VertexPositionNormalTexture> vertices, List <ushort> indices)
        {
            var convexHullShape = collidable.Shape as ConvexHullShape;

            if (convexHullShape == null)
            {
                throw new ArgumentException("Wrong shape type.");
            }

            var hullTriangleVertices = new List <Vector3>();
            var hullTriangleIndices  = new List <int>();

            ConvexHullHelper.GetConvexHull(convexHullShape.Vertices, hullTriangleIndices, hullTriangleVertices);
            //The hull triangle vertices are used as a dummy to get the unnecessary hull vertices, which are cleared afterwards.
            hullTriangleVertices.Clear();
            foreach (int i in hullTriangleIndices)
            {
                hullTriangleVertices.Add(convexHullShape.Vertices[i]);
            }

            var     toReturn = new VertexPositionNormalTexture[hullTriangleVertices.Count];
            Vector3 normal;

            for (ushort i = 0; i < hullTriangleVertices.Count; i += 3)
            {
                normal = Vector3.Normalize(Vector3.Cross(hullTriangleVertices[i + 2] - hullTriangleVertices[i], hullTriangleVertices[i + 1] - hullTriangleVertices[i]));
                vertices.Add(new VertexPositionNormalTexture(MathConverter.Convert(hullTriangleVertices[i]), MathConverter.Convert(normal), new Microsoft.Xna.Framework.Vector2(0, 0)));
                vertices.Add(new VertexPositionNormalTexture(MathConverter.Convert(hullTriangleVertices[i + 1]), MathConverter.Convert(normal), new Microsoft.Xna.Framework.Vector2(1, 0)));
                vertices.Add(new VertexPositionNormalTexture(MathConverter.Convert(hullTriangleVertices[i + 2]), MathConverter.Convert(normal), new Microsoft.Xna.Framework.Vector2(0, 1)));
                indices.Add(i);
                indices.Add((ushort)(i + 1));
                indices.Add((ushort)(i + 2));
            }
        }
        /// <summary>
        /// Computes a convex shape description for a TransformableShape and applies it.
        /// </summary>
        public void UpdateConvexShapeInfo()
        {
            //Compute the volume distribution.
            var samples = CommonResources.GetVectorList();

            if (samples.Capacity < InertiaHelper.SampleDirections.Length)
            {
                samples.Capacity = InertiaHelper.SampleDirections.Length;
            }
            samples.Count = InertiaHelper.SampleDirections.Length;
            for (int i = 0; i < InertiaHelper.SampleDirections.Length; ++i)
            {
                shape.GetLocalExtremePointWithoutMargin(ref InertiaHelper.SampleDirections[i], out samples.Elements[i]);
            }

            var triangles = CommonResources.GetIntList();

            ConvexHullHelper.GetConvexHull(samples, triangles);

            float volume;

            InertiaHelper.ComputeShapeDistribution(samples, triangles, out volume, out volumeDistribution);
            Volume = volume;

            //Estimate the minimum radius based on the surface mesh.
            MinimumRadius = InertiaHelper.ComputeMinimumRadius(samples, triangles, ref Toolbox.ZeroVector) + collisionMargin;
            MaximumRadius = ComputeMaximumRadius();
            CommonResources.GiveBack(samples);
            CommonResources.GiveBack(triangles);
        }
Esempio n. 5
0
        /// <summary>
        /// Computes and applies a convex shape description for this MinkowskiSumShape.
        /// </summary>
        /// <returns>Description required to define a convex shape.</returns>
        public void UpdateConvexShapeInfo()
        {
            //Compute the volume distribution.
            var samples = CommonResources.GetVectorList();

            if (samples.Capacity < InertiaHelper.SampleDirections.Length)
            {
                samples.Capacity = InertiaHelper.SampleDirections.Length;
            }
            samples.Count = InertiaHelper.SampleDirections.Length;
            for (int i = 0; i < InertiaHelper.SampleDirections.Length; ++i)
            {
                GetLocalExtremePoint(InertiaHelper.SampleDirections[i], out samples.Elements[i]);
            }

            var triangles = CommonResources.GetIntList();

            ConvexHullHelper.GetConvexHull(samples, triangles);

            float   volume;
            Vector3 center;

            InertiaHelper.ComputeShapeDistribution(samples, triangles, out center, out volume, out volumeDistribution);
            Volume = volume;

            //Recenter the shape.
            localOffset = -center;
            CommonResources.GiveBack(samples);
            CommonResources.GiveBack(triangles);

            //Compute the radii.
            float minRadius = 0, maxRadius = 0;

            for (int i = 0; i < shapes.Count; i++)
            {
                minRadius += shapes.WrappedList.Elements[i].CollisionShape.MinimumRadius;
                maxRadius += shapes.WrappedList.Elements[i].CollisionShape.MaximumRadius;
            }

            MinimumRadius = minRadius + collisionMargin;
            MaximumRadius = maxRadius + collisionMargin;
        }
Esempio n. 6
0
        public static void GetShapeMeshData(EntityCollidable collidable, List <VertexPositionNormalTexture> vertices, List <ushort> indices)
        {
            var shape = collidable.Shape as ConvexShape;

            if (shape == null)
            {
                throw new ArgumentException("Wrong shape type for this helper.");
            }
            var vertexPositions = new Vector3[SampleDirections.Length];

            for (int i = 0; i < SampleDirections.Length; ++i)
            {
                shape.GetLocalExtremePoint(SampleDirections[i], out vertexPositions[i]);
            }

            var hullIndices = new RawList <int>();

            ConvexHullHelper.GetConvexHull(vertexPositions, hullIndices);


            var hullTriangleVertices = new RawList <Vector3>();

            foreach (int i in hullIndices)
            {
                hullTriangleVertices.Add(vertexPositions[i]);
            }

            for (ushort i = 0; i < hullTriangleVertices.Count; i += 3)
            {
                Vector3 normal = Vector3.Normalize(Vector3.Cross(hullTriangleVertices[i + 2] - hullTriangleVertices[i], hullTriangleVertices[i + 1] - hullTriangleVertices[i]));
                vertices.Add(new VertexPositionNormalTexture(MathConverter.Convert(hullTriangleVertices[i]), MathConverter.Convert(normal), new Microsoft.Xna.Framework.Vector2(0, 0)));
                vertices.Add(new VertexPositionNormalTexture(MathConverter.Convert(hullTriangleVertices[i + 1]), MathConverter.Convert(normal), new Microsoft.Xna.Framework.Vector2(1, 0)));
                vertices.Add(new VertexPositionNormalTexture(MathConverter.Convert(hullTriangleVertices[i + 2]), MathConverter.Convert(normal), new Microsoft.Xna.Framework.Vector2(0, 1)));
                indices.Add(i);
                indices.Add((ushort)(i + 1));
                indices.Add((ushort)(i + 2));
            }
        }
Esempio n. 7
0
 private void UpdateSurfaceVertices()
 {
     hullVertices.Clear();
     if (Volume > 0)
     {
         ConvexHullHelper.GetConvexHull(triangleMesh.Data.vertices, hullVertices);
         var transformableData = triangleMesh.Data as TransformableMeshData;
         if (transformableData != null)
         {
             var transform = transformableData.worldTransform;
             for (int i = 0; i < hullVertices.Count; i++)
             {
                 AffineTransform.Transform(ref hullVertices.Elements[i], ref transform, out hullVertices.Elements[i]);
             }
         }
     }
     else
     {
         hullVertices.Clear();
         //A mobile mesh is allowed to have zero volume, so long as it isn't solid.
         //In this case, compute the bounding box of all points.
         BoundingBox box = new BoundingBox();
         for (int i = 0; i < triangleMesh.Data.vertices.Length; i++)
         {
             Vector3 v;
             triangleMesh.Data.GetVertexPosition(i, out v);
             if (v.X > box.Max.X)
             {
                 box.Max.X = v.X;
             }
             if (v.X < box.Min.X)
             {
                 box.Min.X = v.X;
             }
             if (v.Y > box.Max.Y)
             {
                 box.Max.Y = v.Y;
             }
             if (v.Y < box.Min.Y)
             {
                 box.Min.Y = v.Y;
             }
             if (v.Z > box.Max.Z)
             {
                 box.Max.Z = v.Z;
             }
             if (v.Z < box.Min.Z)
             {
                 box.Min.Z = v.Z;
             }
         }
         //Add the corners.  This will overestimate the size of the surface a bit.
         hullVertices.Add(box.Min);
         hullVertices.Add(box.Max);
         hullVertices.Add(new Vector3(box.Min.X, box.Min.Y, box.Max.Z));
         hullVertices.Add(new Vector3(box.Min.X, box.Max.Y, box.Min.Z));
         hullVertices.Add(new Vector3(box.Max.X, box.Min.Y, box.Min.Z));
         hullVertices.Add(new Vector3(box.Min.X, box.Max.Y, box.Max.Z));
         hullVertices.Add(new Vector3(box.Max.X, box.Max.Y, box.Min.Z));
         hullVertices.Add(new Vector3(box.Max.X, box.Min.Y, box.Max.Z));
     }
 }