Embedded Objects ?

Started by
0 comments, last by Endemoniada 20 years, 8 months ago
Hi guys, Sometimes my objects become embedded and mess up my collision detection routines. I''m not sure how they get embedded without first registering a collision but it does happen occasionally. I guess it''s a good idea to first see if an object is embedded but what then ? Where should I replace it ? And then I have to check if the new position is embedded in another object, and so on. Any guidance is appreciated. Thanks.
Advertisement
That''s called a relaxation step for contacts, if I''m not mistaken. If objects are embedded, the collision system should return a best approximation of the closest points on the surfaces of the two embedded objects. What you then need to do, is try to make those points ''meet''. Of course, if you have several embedded objects, pushing one will possibly increase the embeddedness on the other contact. You can push the objects slightly from each other, over a few iterations. You need to keep track of the contact planes for a better result.

struct cEmbeddedContact{     Vector m_vNormal;     Vector m_vPoints[2];     cCollObject *m_pxCollObject[2];     cEmbeddedContact(const Vector& P0, const Vector& P1, cCollObject* pxObj0, cCollObject* pxObj1)     : m_vNormal((P0 - P1).UnitVector())     {          ......     }     bool Update(float fRelaxation=0.5f)     {         // how embedded the objects are         float d = (m_vPoints[0] - m_vPoints[1]) * m_vNormal;         // objects no longer in contact                  if (d < 0.0001f)             return false;         // Find which object to push the most (i.e. the lighter one)                  float fRatio = (m_pxCollObject[1]->GetMass()) / (m_pxCollObject[0]->GetMass() + m_pxCollObject[1]->GetMass());         float d0 = d * fRelaxation * fRatio;         float d1 = d * fRelaxation * (1.0f - fRatio);         // push the objects apart         m_pxCollObject[0]->Push(-d0 * m_vNormal);         m_pxCollObject[1]->Push( d1 * m_vNormal);         return true;     }};int m_iNumContacts = 0;cEmbeddedContact m_xEmbeddedContact[MAX_CONTACTS];m_iNumContacts = FindEmbeddedContacts(m_xEmbeddedContact, MAX_CONTACTS);for(int k = 0; k < 5; k ++) // run several times the relaxation loop{     // process all contacts one by one     for(int i = 0; i < m_iNumContacts; i++)     {          // push the objects appart.          m_xEmbeddedContact[i].Update(0.5f);     }}


this should push the embedded objects slightly apart. If the objects are deeply embedded, they will gently push apart over a few frames.

You can enforce a full resolution by stopping the relaxation loop only when all contacts are satisfied, but it might cause problems (like two opposite contacts, it would run indefinitely).

Everything is better with Metal.

This topic is closed to new replies.

Advertisement