/// <summary> /// Genera los contactos requeridos para restaurar la unión si ha sido violada /// </summary> /// <param name="contactData">Información de contactos</param> /// <param name="limit">Límite de contactos a generar</param> /// <returns>Devuelve el número de contactos generados</returns> /// <remarks>Tan solo generará un contacto o ninguno</remarks> public override int AddContact(ref CollisionData contactData, int limit) { if (contactData.HasMoreContacts()) { // Calcular las posiciones de los puntos de conexión en coordenadas del mundo Vector3 positionOneWorld = this.m_BodyOne.GetPointInWorldSpace(this.m_PositionOne); Vector3 positionTwoWorld = this.m_BodyTwo.GetPointInWorldSpace(this.m_PositionTwo); // Calcular la longitud de la unión float length = Vector3.Distance(positionTwoWorld, positionOneWorld); // Check if it is violated if (Math.Abs(length) > m_Error) { Contact contact = contactData.CurrentContact; contact.Bodies[0] = this.m_BodyOne; contact.Bodies[1] = this.m_BodyTwo; contact.ContactNormal = Vector3.Normalize(positionTwoWorld - positionOneWorld); contact.ContactPoint = (positionOneWorld + positionTwoWorld) * 0.5f; contact.Penetration = length - m_Error; contact.Friction = 1.0f; contact.Restitution = 0; contactData.AddContact(); return(1); } } return(0); }
/// <summary> /// Añade los contactos necesarios para mantener unidos mediante la barra a los cuerpos /// </summary> /// <param name="contactData">Datos de colisión</param> /// <param name="limit">Límite de contactos a añadir</param> /// <returns>Devuelve el número de contacos añadidos</returns> /// <remarks>Sólo añade un contacto o ninguno</remarks> public override int AddContact(ref CollisionData contactData, int limit) { if (contactData.HasMoreContacts()) { // Encontrar la longitud actual Vector3 positionOneWorld = m_BodyOne.GetPointInWorldSpace(m_PositionOne); Vector3 positionTwoWorld = m_BodyTwo.GetPointInWorldSpace(m_PositionTwo); float currentLen = Vector3.Distance(positionOneWorld, positionTwoWorld); // Comprobar si estamos en extensión correcta if (currentLen == m_Length) { return(0); } // Rellenar el contacto Contact contact = contactData.CurrentContact; contact.Bodies[0] = m_BodyOne; contact.Bodies[1] = m_BodyTwo; contact.ContactPoint = (positionOneWorld + positionTwoWorld) * 0.5f; // Calcular la normal Vector3 normal = Vector3.Normalize(m_BodyTwo.Position - m_BodyOne.Position); // La normal de contacto depende de si hay que extender o contraer para conservar la longitud if (currentLen > m_Length) { contact.ContactNormal = normal; contact.Penetration = currentLen - m_Length; } else { contact.ContactNormal = Vector3.Negate(normal); contact.Penetration = m_Length - currentLen; } // Siempre restitución 0 contact.Restitution = 0f; contactData.AddContact(); return(1); } return(0); }