/// <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)); }
/// <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); }
/// <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); }
/// <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)); }
/// <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); }
/// <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)); }