Report any bugs here and we'll post fixes
Moderators: Sascha Willems, Thomas
by 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
by 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
-
- Posts: 12249
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by 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
by Julio Jerez » Thu Apr 28, 2022 12:14 pm
oh yes I see.
Done.
Thanks
-
Julio Jerez
- Moderator
-
- Posts: 12249
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by 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
by 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
by Julio Jerez » Fri Apr 29, 2022 8:36 am
I do not think we have clear cache in 4.0
-
Julio Jerez
- 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 1 guest