Exemplo n.º 1
0
        public void CapsuleTest()
        {
            var s  = new CapsuleShape(1, 2);
            var v0 = s.GetVolume(0.001f, 10);

            var m  = s.GetMesh(0.001f, 10);
            var v1 = m.GetVolume();

            Assert.IsTrue(Numeric.AreEqual(v0, v1, 0.01f * (1 + v0))); // 1% error is allowed.
        }
Exemplo n.º 2
0
        /// <summary>
        /// Computes a minimum bounding shape that contains all given points.
        /// </summary>
        /// <param name="points">The points.</param>
        /// <returns>A minimum bounding shape that contains all given points.</returns>
        /// <remarks>
        /// The returned shape will be a <see cref="SphereShape"/>, a <see cref="CapsuleShape"/>,
        /// a <see cref="BoxShape"/>, or a <see cref="TransformedShape"/> (containing a sphere, capsule,
        /// or a box). The bounding shape is not guaranteed to be optimal, it is only guaranteed that
        /// the bounding shape includes all given points.
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="points"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// <paramref name="points"/> is empty.
        /// </exception>
        public static Shape CreateBoundingShape(IList <Vector3> points)
        {
            if (points == null)
            {
                throw new ArgumentNullException("points");
            }
            if (points.Count == 0)
            {
                throw new ArgumentException("The list of 'points' is empty.");
            }

            // Compute minimal sphere.
            Vector3 center;
            float   radius;

            ComputeBoundingSphere(points, out radius, out center);
            SphereShape sphere       = new SphereShape(radius);
            float       sphereVolume = sphere.GetVolume();

            // Compute minimal capsule.
            float height;
            Pose  capsulePose;

            ComputeBoundingCapsule(points, out radius, out height, out capsulePose);
            CapsuleShape capsule       = new CapsuleShape(radius, height);
            float        capsuleVolume = capsule.GetVolume();

            // Compute minimal box.
            Vector3 boxExtent;
            Pose    boxPose;

            ComputeBoundingBox(points, out boxExtent, out boxPose);
            var   box       = new BoxShape(boxExtent);
            float boxVolume = box.GetVolume();

            // Return the object with the smallest volume.
            // A TransformedShape is used if the shape needs to be translated or rotated.
            if (sphereVolume < boxVolume && sphereVolume < capsuleVolume)
            {
                if (center.IsNumericallyZero)
                {
                    return(sphere);
                }

                return(new TransformedShape(new GeometricObject(sphere, new Pose(center))));
            }
            else if (capsuleVolume < boxVolume)
            {
                if (!capsulePose.HasTranslation && !capsulePose.HasRotation)
                {
                    return(capsule);
                }

                return(new TransformedShape(new GeometricObject(capsule, capsulePose)));
            }
            else
            {
                if (!boxPose.HasTranslation && !boxPose.HasRotation)
                {
                    return(box);
                }

                return(new TransformedShape(new GeometricObject(box, boxPose)));
            }
        }