Contact Solver Not considering m_localMatrix

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Contact Solver Not considering m_localMatrix

Postby Esharc » Tue Apr 25, 2023 3:07 am

Good morning Julio,

In our system we set up a height field for our dynamic ground, but we offset the height field so that the origin of the height field is at the centre.

We then use a "ghost object" to determine if something is in contact with the dynamic ground. In the ghost object I use the ContactSolver's CalculateContacts to determine if the ghost object shape is intersecting with the height field. But I noticed that it misses a lot of the "collisions".

I them noticed that if I changed
Code: Select all
void ndContactSolver::CalculateContacts(
   const ndShapeInstance* const instanceA, const ndMatrix& matrixA, const ndVector& velocA,
   const ndShapeInstance* const instanceB, const ndMatrix& matrixB, const ndVector& velocB,
   ndFixSizeArray<ndContactPoint, 16>& contactOut, ndContactNotify* const contactNotify)
{
   ndContact contact;
   ndBodyKinematic bodyA;
   ndBodyKinematic bodyB;
   ndContactPoint contactBuffer[D_MAX_CONTATCS];

   ndShape* const shapeA = (ndShape*)(instanceA->GetShape());
   ndShape* const shapeB = (ndShape*)(instanceB->GetShape());

   m_instance0.SetShape(shapeA);
   m_instance0.SetMaterial(instanceA->GetMaterial());
   m_instance0.SetGlobalMatrix(matrixA);
   m_instance1.SetShape(shapeB);
   m_instance1.SetMaterial(instanceB->GetMaterial());
   m_instance1.SetGlobalMatrix(matrixB);
   bodyA.SetCollisionShape(m_instance0);
   bodyB.SetCollisionShape(m_instance1);

   bodyA.SetMatrix(matrixA);
   bodyB.SetMatrix(matrixB);
   bodyA.SetVelocity(velocA);
   bodyB.SetVelocity(velocB);

   if (!shapeA->GetAsShapeStaticMesh())
   {
      bodyA.SetMassMatrix(ndFloat32(1.0f), ndFloat32(1.0f), ndFloat32(1.0f), ndFloat32(1.0f));
   }
   if (!shapeB->GetAsShapeStaticMesh())
   {
      bodyB.SetMassMatrix(ndFloat32(1.0f), ndFloat32(1.0f), ndFloat32(1.0f), ndFloat32(1.0f));
   }
   contact.SetBodies(&bodyA, &bodyB);

   m_closestPoint0 = ndVector::m_zero;
   m_closestPoint1 = ndVector::m_zero;
   m_separatingVector = ndVector(ndFloat32(0.0f), ndFloat32(1.0f), ndFloat32(0.0f), ndFloat32(0.0f));
   m_contact = &contact;
   m_freeFace = nullptr;
   m_notification = contactNotify;
   m_contactBuffer = contactBuffer;
   m_timestep = ndFloat32 (1.0f);
   m_skinMargin = ndFloat32(0.0f);
   m_separationDistance = ndFloat32(1.0e10f);
   m_maxCount = D_MAX_CONTATCS;
   m_vertexIndex = 0;
   m_pruneContacts = 1;
   m_intersectionTestOnly = 0;

   const ndInt32 count = dMin (CalculateContactsDiscrete(), contactOut.GetCapacity());
   for (ndInt32 i = 0; i < count; ++i)
   {
      ndContactPoint& contactPoint = contactBuffer[i];
      contactPoint.m_body0 = nullptr;
      contactPoint.m_body1 = nullptr;
      contactPoint.m_shapeInstance0 = instanceA;
      contactPoint.m_shapeInstance1 = instanceB;
      contactOut.PushBack(contactPoint);
   }
}

to this
Code: Select all
void ndContactSolver::CalculateContacts(
   const ndShapeInstance* const instanceA, const ndMatrix& matrixA, const ndVector& velocA,
   const ndShapeInstance* const instanceB, const ndMatrix& matrixB, const ndVector& velocB,
   ndFixSizeArray<ndContactPoint, 16>& contactOut, ndContactNotify* const contactNotify)
{
   ndContact contact;
   ndBodyKinematic bodyA;
   ndBodyKinematic bodyB;
   ndContactPoint contactBuffer[D_MAX_CONTATCS];

   ndShape* const shapeA = (ndShape*)(instanceA->GetShape());
   ndShape* const shapeB = (ndShape*)(instanceB->GetShape());

   m_instance0.SetShape(shapeA);
   m_instance0.SetMaterial(instanceA->GetMaterial());
   m_instance0.SetGlobalMatrix(instanceA->GetLocalMatrix() * matrixA);
   m_instance1.SetShape(shapeB);
   m_instance1.SetMaterial(instanceB->GetMaterial());
   m_instance1.SetGlobalMatrix(instanceB->GetLocalMatrix() * matrixB);
   bodyA.SetCollisionShape(m_instance0);
   bodyB.SetCollisionShape(m_instance1);

   bodyA.SetMatrix(matrixA);
   bodyB.SetMatrix(matrixB);
   bodyA.SetVelocity(velocA);
   bodyB.SetVelocity(velocB);

   if (!shapeA->GetAsShapeStaticMesh())
   {
      bodyA.SetMassMatrix(ndFloat32(1.0f), ndFloat32(1.0f), ndFloat32(1.0f), ndFloat32(1.0f));
   }
   if (!shapeB->GetAsShapeStaticMesh())
   {
      bodyB.SetMassMatrix(ndFloat32(1.0f), ndFloat32(1.0f), ndFloat32(1.0f), ndFloat32(1.0f));
   }
   contact.SetBodies(&bodyA, &bodyB);

   m_closestPoint0 = ndVector::m_zero;
   m_closestPoint1 = ndVector::m_zero;
   m_separatingVector = ndVector(ndFloat32(0.0f), ndFloat32(1.0f), ndFloat32(0.0f), ndFloat32(0.0f));
   m_contact = &contact;
   m_freeFace = nullptr;
   m_notification = contactNotify;
   m_contactBuffer = contactBuffer;
   m_timestep = ndFloat32 (1.0f);
   m_skinMargin = ndFloat32(0.0f);
   m_separationDistance = ndFloat32(1.0e10f);
   m_maxCount = D_MAX_CONTATCS;
   m_vertexIndex = 0;
   m_pruneContacts = 1;
   m_intersectionTestOnly = 0;

   const ndInt32 count = dMin (CalculateContactsDiscrete(), contactOut.GetCapacity());
   for (ndInt32 i = 0; i < count; ++i)
   {
      ndContactPoint& contactPoint = contactBuffer[i];
      contactPoint.m_body0 = nullptr;
      contactPoint.m_body1 = nullptr;
      contactPoint.m_shapeInstance0 = instanceA;
      contactPoint.m_shapeInstance1 = instanceB;
      contactOut.PushBack(contactPoint);
   }
}

the collisions are detected correctly.
Notice the
Code: Select all
m_instance0.SetGlobalMatrix(instanceA->GetLocalMatrix() * matrixA);

and
Code: Select all
m_instance1.SetGlobalMatrix(instanceB->GetLocalMatrix() * matrixB);

change.
Esharc
 
Posts: 120
Joined: Tue Jan 10, 2017 5:23 am
Location: South Africa

Re: Contact Solver Not considering m_localMatrix

Postby Julio Jerez » Tue Apr 25, 2023 10:15 am

oh yes, it will only work for identity. Good finding, thanks

fixed.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Contact Solver Not considering m_localMatrix

Postby Esharc » Tue Apr 25, 2023 10:32 am

Thanks
Esharc
 
Posts: 120
Joined: Tue Jan 10, 2017 5:23 am
Location: South Africa

Re: Contact Solver Not considering m_localMatrix

Postby Esharc » Thu May 04, 2023 12:38 am

Good morning Julio,

In the process of updating Newton, I noticed that you have the local matrices as

Code: Select all
m_instance0.SetGlobalMatrix(m_instance0->GetLocalMatrix() * matrixA);

Code: Select all
m_instance1.SetGlobalMatrix(m_instance1->GetLocalMatrix() * matrixA);


but it shouldn't it rather be the local matrices of the passed in shape instances instead?

Code: Select all
m_instance0.SetGlobalMatrix(instanceA->GetLocalMatrix() * matrixA);

Code: Select all
m_instance1.SetGlobalMatrix(instanceB->GetLocalMatrix() * matrixA);
Esharc
 
Posts: 120
Joined: Tue Jan 10, 2017 5:23 am
Location: South Africa

Re: Contact Solver Not considering m_localMatrix

Postby Julio Jerez » Thu May 04, 2023 9:31 am

ah, I think the problem was because I never set the local matrices.

I set up like this, please see if that works.
Code: Select all
   m_instance0.SetShape(shapeA);
   m_instance0.SetLocalMatrix(instanceA->GetLocalMatrix());
   //Setting the global matrix before setting the collision shape of the body
   m_instance0.SetGlobalMatrix(m_instance0.GetLocalMatrix() * matrixA);
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Contact Solver Not considering m_localMatrix

Postby Esharc » Thu May 04, 2023 10:48 am

Yes thanks, that solved the problem
Esharc
 
Posts: 120
Joined: Tue Jan 10, 2017 5:23 am
Location: South Africa


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 49 guests