Пример #1
0
        /// <summary>
        /// Detecta la colisión entre una caja y una colección de triángulos
        /// </summary>
        /// <param name="box">Caja</param>
        /// <param name="triangleSoup">Colección de triángulos</param>
        /// <param name="data">Datos de colisión a llenar</param>
        /// <returns>Devuelve verdadero si existe colisión, falso en el resto de los casos</returns>
        private static bool BoxAndTriangleSoup(CollisionBox box, CollisionTriangleSoup triangleSoup, ref CollisionData data)
        {
            //CollisionPlane plane = new CollisionPlane(triangleSoup.Triangles[0].Plane, triangleSoup.Mass);

            //return BoxAndHalfSpace(box, plane, ref data);

            return(BoxAndTriangleList(box, triangleSoup.Triangles, ref data));
        }
Пример #2
0
        /// <summary>
        /// Obtiene si hay intersección entre el rayo y la lista de triángulos
        /// </summary>
        /// <param name="triangleSoup">Lista de triángulos</param>
        /// <param name="ray">Rayo</param>
        /// <param name="triangle">Devuelve el triángulo de intersección si existe</param>
        /// <param name="intersectionPoint">Devuelve el punto de intersección con el triángulo</param>
        /// <param name="distanceToPoint">Devuelve la distancia desde el origen del ray al punto de intersección</param>
        /// <param name="findNearest">Indica si se debe testear la intersección hasta encontrar el más cercano</param>
        /// <returns>Devuelve verdadero si hay intersección o falso en el resto de los casos</returns>
        public static bool TriangleSoupAndRay(CollisionTriangleSoup triangleSoup, Ray ray, out Triangle?triangle, out Vector3?intersectionPoint, out float?distanceToPoint, bool findNearest)
        {
            triangle          = null;
            intersectionPoint = null;
            distanceToPoint   = null;

            // Primero ver si hay contacto con el bbox
            if (ray.Intersects(triangleSoup.AABB).HasValue)
            {
                return(TriangleListAndRay(
                           triangleSoup.Triangles,
                           ray,
                           out triangle,
                           out intersectionPoint,
                           out distanceToPoint,
                           findNearest));
            }

            return(false);
        }
Пример #3
0
        /// <summary>
        /// Detecta la colisión entre una esfera y una lista de triángulos
        /// </summary>
        /// <param name="sphere">Esfera</param>
        /// <param name="triangleSoup">Lista de triángulos</param>
        /// <param name="data">Datos de la colisión</param>
        /// <returns>Devuelve verdadero si hay colisión, o falso en el resto de los casos</returns>
        public static bool SphereAndTriangleSoup(CollisionSphere sphere, CollisionTriangleSoup triangleSoup, ref CollisionData data)
        {
            if (data.ContactsLeft <= 0)
            {
                // Si no hay más contactos disponibles se sale de la función.
                return(false);
            }

            foreach (Triangle triangle in triangleSoup.Triangles)
            {
                // Comprobar la intersección
                if (IntersectionTests.SphereAndTri(sphere, triangle, true))
                {
                    // Informar la colisión
                    if (CollisionDetector.SphereAndHalfSpace(sphere, new CollisionPlane(triangle.Plane), ref data))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #4
0
 /// <summary>
 /// Obtiene la primera intersección entre el rayo y la lista de triángulos
 /// </summary>
 /// <param name="triangleSoup">Lista de triángulos</param>
 /// <param name="ray">Rayo</param>
 /// <param name="triangle">Devuelve el triángulo de intersección si existe</param>
 /// <param name="intersectionPoint">Devuelve el punto de intersección con el triángulo</param>
 /// <param name="distanceToPoint">Devuelve la distancia desde el origen del ray al punto de intersección</param>
 /// <returns>Devuelve verdadero si hay intersección o falso en el resto de los casos</returns>
 public static bool TriangleSoupAndRay(CollisionTriangleSoup triangleSoup, Ray ray, out Triangle?triangle, out Vector3?intersectionPoint, out float?distanceToPoint)
 {
     return(TriangleSoupAndRay(triangleSoup, ray, out triangle, out intersectionPoint, out distanceToPoint, false));
 }
Пример #5
0
        /// <summary>
        /// Detecta la colisión entre una caja y una colección de triángulos
        /// </summary>
        /// <param name="box">Caja</param>
        /// <param name="triangleSoup">Colección de triángulos</param>
        /// <param name="data">Datos de colisión a llenar</param>
        /// <returns>Devuelve verdadero si existe colisión, falso en el resto de los casos</returns>
        public static bool BoxAndTriangleSoup(CollisionBox box, CollisionTriangleSoup triangleSoup, ref CollisionData data)
        {
            if (data.ContactsLeft <= 0)
            {
                // Si no hay más contactos disponibles se sale de la función.
                return(false);
            }

            bool intersection = false;
            int  contacts     = 0;

            foreach (Triangle triangle in triangleSoup.Triangles)
            {
                // Comprobar la intersección
                if (IntersectionTests.BoxAndTri(box, triangle))
                {
                    // Hay intersección, ahora hay que encontrar los puntos de intersección.
                    // Podemos hacerlo únicamente chequeando los vértices.
                    // Si la caja está descansando sobre el plano o un eje, se reportarán cuatro o dos puntos de contacto.

                    for (int i = 0; i < 8; i++)
                    {
                        // Calcular la positición de cada vértice
                        Vector3 vertexPos = box.GetCorner(i);
                        Plane   plane     = triangle.Plane;

                        // Calcular la distancia al plano
                        float distanceToPlane = Vector3.Dot(vertexPos, plane.Normal) + plane.D;

                        // Si la distancia es negativa está tras el plano. Si es 0, está en el plano
                        if (distanceToPlane <= 0f)
                        {
                            // Intersección entre línea y triángulo
                            Vector3 direction = vertexPos - box.Position;
                            if (IntersectionTests.TriAndRay(triangle, new Ray(box.Position, direction)))
                            {
                                intersection = true;
                                contacts++;

                                // Crear la información del contacto.

                                // El punto de contacto está a medio camino entre el vértice y el plano.
                                // Se obtiene multiplicando la dirección por la mitad de la distancia de separación, y añadiendo la posición del vértice.
                                Contact contact = data.CurrentContact;
                                contact.ContactPoint  = vertexPos;
                                contact.ContactNormal = plane.Normal;
                                contact.Penetration   = -distanceToPlane;

                                // Establecer los datos del contacto
                                RigidBody one = box.Body;
                                RigidBody two = null;
                                contact.SetBodyData(ref one, ref two, data.Friction, data.Restitution);

                                // Añadir contacto
                                data.AddContact();

                                if (data.ContactsLeft <= 0)
                                {
                                    return(true);
                                }

                                if (contacts > 4)
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }

            return(intersection);
        }
Пример #6
0
 /// <summary>
 /// Detecta la colisión entre una esfera y una lista de triángulos
 /// </summary>
 /// <param name="sphere">Esfera</param>
 /// <param name="triangleSoup">Lista de triángulos</param>
 /// <param name="data">Datos de la colisión</param>
 /// <returns>Devuelve verdadero si hay colisión, o falso en el resto de los casos</returns>
 private static bool SphereAndTriangleSoup(CollisionSphere sphere, CollisionTriangleSoup triangleSoup, ref CollisionData data)
 {
     return(SphereAndTriangleList(sphere, triangleSoup.Triangles, ref data));
 }