ndContactSolver::CalculateContacts

Report any bugs here and we'll post fixes

Moderators: Sascha Willems, Thomas

ndContactSolver::CalculateContacts

Postby Esharc » Thu Apr 28, 2022 4:15 am

Hello Julio.

I found a bug with the contact solver calculate contacts function.

In ndContactSolver.spp line 4286 - 4310, setting the global matrix of m_instance0 and m_instance1 after setting the matrix of bodyA and bodyB does not work. The shape instance of the body's global matrix does not get set since the shape is just a reference and not a pointer.

I changed it so that the global matrix of the shape instances are set before setting the collision shape of the bodies, and that works.
Esharc
 
Posts: 120
Joined: Tue Jan 10, 2017 5:23 am
Location: South Africa

Re: ndContactSolver::CalculateContacts

Postby Julio Jerez » Thu Apr 28, 2022 9:46 am

do you mean this function
void ndContactSolver::CalculateContacts(
const ndShapeInstance* const instanceA, const ndMatrix& matrixA, const ndVector& velocA,

I look at it, and I do not see it, the instance matrix is set after the shape is set.
can you list here the change? so that I can added it.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: ndContactSolver::CalculateContacts

Postby Esharc » Thu Apr 28, 2022 10:29 am

Hey Julio yeah sure:

Original Function
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 notification)
{
   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_instance1.SetShape(shapeB);
   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_instance0.SetGlobalMatrix(bodyA.GetMatrix());      // This is the problem, I moved this up
   m_instance1.SetGlobalMatrix(bodyB.GetMatrix());      // This is the problem, I moved this up

   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 = notification;
   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);
   }
}


With my changes
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 notification)
{
   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.SetGlobalMatrix(matrixA);      // Setting the global matrix before setting the collision shape of the body
   m_instance1.SetShape(shapeB);
   m_instance1.SetGlobalMatrix(matrixB);      // Setting the global matrix before setting the collision shape of the body
   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 = notification;
   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);
   }
}
Esharc
 
Posts: 120
Joined: Tue Jan 10, 2017 5:23 am
Location: South Africa

Re: ndContactSolver::CalculateContacts

Postby Julio Jerez » Thu Apr 28, 2022 12:14 pm

oh yes I see.
Done.
Thanks
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: ndContactSolver::CalculateContacts

Postby Esharc » Fri Apr 29, 2022 12:14 am

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

Re: ndContactSolver::CalculateContacts

Postby zak » Fri Apr 29, 2022 3:34 am

In Newton 3.14, when i assign matrix, linear and angular velocity to bodies i have to call NewtonInvalidateCache() otherwise the collisions will not work properly.
In the last year i passed to Newton 4.00 and I keep calling ClearCache() before update when I set matrix or velocities to bodies. In Newton 4.00 is it still necessary to do this?
zak
 
Posts: 87
Joined: Mon Dec 06, 2004 9:30 am

Re: ndContactSolver::CalculateContacts

Postby Julio Jerez » Fri Apr 29, 2022 8:36 am

I do not think we have clear cache in 4.0
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles


Return to Bugs and Fixes

Who is online

Users browsing this forum: No registered users and 22 guests