Esempio n. 1
0
        /// <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);
            }
        }
Esempio n. 2
0
        /// <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);
        }
Esempio n. 3
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);
        }