/// <summary> /// Aplica la fuerza del amortiguador al objeto especificado /// </summary> /// <param name="obj">Objeto</param> /// <param name="duration">Duración</param> public override void UpdateForce(ref IPhysicObject obj, float duration) { // Obtener el cuerpo del objeto CollisionPrimitive primitive = obj.Primitive; if (primitive != null) { // Calculate the two ends in world space Vector3 lws = primitive.GetPointInWorldSpace(m_ConnectionPoint); Vector3 ows = m_Other.GetPointInWorldSpace(m_OtherConnectionPoint); // Calculate the vector of the spring Vector3 force = lws - ows; // Calculate the magnitude of the force float magnitude = force.Length(); magnitude = Math.Abs(magnitude - m_RestLength); magnitude *= m_SpringConstant; // Calculate the final force and apply it force.Normalize(); force *= -magnitude; primitive.AddForceAtPoint(force, lws); } }
/// <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.HasFreeContacts()) { CollisionPrimitive objectOne = null; if (this.m_BodyOne != null) { objectOne = this.m_BodyOne.Primitive; } CollisionPrimitive objectTwo = null; if (this.m_BodyTwo != null) { objectTwo = this.m_BodyTwo.Primitive; } Vector3 positionOne = this.m_RelativePointOne; Vector3 positionOneWorld = this.m_RelativePointOne; if (objectOne != null) { positionOne = objectOne.Position; positionOneWorld = objectOne.GetPointInWorldSpace(this.m_RelativePointOne); } Vector3 positionTwo = this.m_RelativePointTwo; Vector3 positionTwoWorld = this.m_RelativePointTwo; if (objectTwo != null) { positionTwo = objectTwo.Position; positionTwoWorld = objectTwo.GetPointInWorldSpace(this.m_RelativePointTwo); } float currentLen = Vector3.Distance(positionOneWorld, positionTwoWorld); if (Math.Abs(currentLen) > this.m_Length) { Contact contact = contactData.CurrentContact; contact.Bodies[0] = objectOne; contact.Bodies[1] = objectTwo; contact.ContactNormal = Vector3.Normalize(positionTwoWorld - positionOneWorld); contact.ContactPoint = (positionOneWorld + positionTwoWorld) * 0.5f; contact.Penetration = currentLen - this.m_Length; 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.HasFreeContacts()) { CollisionPrimitive objectOne = null; if (this.m_BodyOne != null) { objectOne = this.m_BodyOne.Primitive; } CollisionPrimitive objectTwo = null; if (this.m_BodyTwo != null) { objectTwo = this.m_BodyTwo.Primitive; } // Encontrar la longitud actual Vector3 positionOne = this.m_RelativePointOne; Vector3 positionOneWorld = this.m_RelativePointOne; if (objectOne != null) { positionOne = objectOne.Position; positionOneWorld = objectOne.GetPointInWorldSpace(this.m_RelativePointOne); } Vector3 positionTwo = this.m_RelativePointTwo; Vector3 positionTwoWorld = this.m_RelativePointTwo; if (objectTwo != null) { positionTwo = objectTwo.Position; positionTwoWorld = objectTwo.GetPointInWorldSpace(this.m_RelativePointTwo); } float currentLen = Vector3.Distance(positionOneWorld, positionTwoWorld); // Comprobar si estamos en extensión correcta if (currentLen != m_Length) { // Rellenar el contacto Contact contact = contactData.CurrentContact; contact.Bodies[0] = objectOne; contact.Bodies[1] = objectTwo; contact.ContactPoint = (positionOneWorld + positionTwoWorld) * 0.5f; // Calcular la normal Vector3 normal = Vector3.Normalize(positionTwo - positionOne); // 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 = this.m_Length - currentLen; } // Siempre restitución 0 contact.Restitution = 0f; contactData.AddContact(); return(1); } } return(0); }