Пример #1
0
        public static bool CollisionTest(Ray ray, IPhysical obj, PhysicsMesh mesh, out float dist)
        {
            Vector3 start = new Vector3(ray.X, ray.Y, ray.Z);
            Vector3 direction = new Vector3(ray.I, ray.J, ray.K);
            dist = Single.MaxValue;

            // Construct a matrix to transform to scene space
            Matrix4 transform = Matrix4.Identity;

            transform *= Matrix4.CreateScale(obj.Scale);
            transform *= Matrix4.CreateFromQuaternion(obj.RelativeRotation);
            transform *= Matrix4.CreateTranslation(obj.RelativePosition);

            ILinkable parent = obj.Parent;
            if (parent != null)
            {
                // Apply parent rotation and translation
                transform *= Matrix4.CreateFromQuaternion(parent.RelativeRotation);
                transform *= Matrix4.CreateTranslation(parent.RelativePosition);
            }

            // Iterate through all of the triangles in the mesh, doing a ray-triangle intersection
            for (int i = 0; i < mesh.Indices.Length; i += 3)
            {
                Vector3 point0 = mesh.Vertices[mesh.Indices[i + 0]] * transform;
                Vector3 point1 = mesh.Vertices[mesh.Indices[i + 1]] * transform;
                Vector3 point2 = mesh.Vertices[mesh.Indices[i + 2]] * transform;

                float thisDist;
                if (RayTriangle.CollisionTestCull(start, direction, point0, point1, point2, out thisDist))
                {
                    if (thisDist < dist)
                        dist = thisDist;
                }
            }

            return dist < Single.MaxValue;
        }
Пример #2
0
        /// <summary>
        /// Calculates the approximate volume of a scaled mesh
        /// </summary>
        /// <param name="mesh">Mesh data</param>
        /// <param name="scale">Object scale</param>
        /// <returns>Approximate volume of the mesh</returns>
        public static float GetMeshVolume(PhysicsMesh mesh, Vector3 scale)
        {
            const float OO_SIX = 1f / 6f;

            double volume = 0.0f;

            // Formula adapted from Stan Melax's algorithm: <http://www.melax.com/volint.html>
            for (int i = 0; i < mesh.Indices.Length; i += 3)
            {
                Vector3 v0 = mesh.Vertices[mesh.Indices[i + 0]];
                Vector3 v1 = mesh.Vertices[mesh.Indices[i + 1]];
                Vector3 v2 = mesh.Vertices[mesh.Indices[i + 2]];

                volume += Determinant3x3(v0, v1, v2);
            }

            return (float)(volume * OO_SIX) * scale.X * scale.Y * scale.Z;
        }