Пример #1
0
        /// <summary>
        /// Performs sphere-triangle intersection test.
        ///  Spheres can only collide with front side of  triangles.
        ///  The closest possible intersection position is returned,
        ///  which is always inside the triangle.
        /// </summary>
        /// <param name="position"></param>
        /// <param name="sphereRadius"></param>
        /// <param name="result"></param>
        private void TestSphereCollision(ref Vector3 position,
                                         float sphereRadius,
                                         ref CollisionResult result)
        {
            // Check side of plane
            float   dist;
            Vector3 v = position - verts[0];

            Vector3.Dot(ref v, ref faceNormal, out dist);

            // Wrong side of plane
            if (dist < 0)
            {
                return;
            }

            // Too far away for intersection
            if (dist > sphereRadius)
            {
                return;
            }

            // Test for collision point in triangle
            Vector3 collisionPoint = position - (dist * faceNormal);

            if (PointInTriangle(ref collisionPoint))
            {
                CollisionResult t;
                t.Hit             = true;
                t.DistanceSquared = (collisionPoint - position).LengthSquared();
                t.Normal          = faceNormal;
                t.Location        = collisionPoint;

                result.KeepClosest(t);
                return;
            }

            // Test edges
            for (int i = 0; i < 3; i++)
            {
                Vector3 E = verts[(i + 1) % 3] - verts[i];

                // Position relative to edge start
                Vector3 H = collisionPoint - verts[i];

                // Distance of P to edge plane
                float hn = Vector3.Dot(H, edgeNormals[i]);

                // Point is on same side of triangle from the edge plane
                if (hn < 0.0f)
                {
                    continue;
                }

                // Too far away from this edge plane
                if (hn > sphereRadius)
                {
                    return;
                }

                // Test intersection with polygon edge
                Vector3 intersectionPoint = new Vector3();
                if (SpherePartialEdgeCollide(ref position, ref verts[i], ref E, ref intersectionPoint))
                {
                    CollisionResult t;
                    t.Hit             = true;
                    t.DistanceSquared = (intersectionPoint - position).LengthSquared();
                    t.Normal          = faceNormal;
                    t.Location        = intersectionPoint;

                    result.KeepClosest(t);
                }
            }
        }