ndBody->SetMatrix() does not update AABB if body has 0 mass.

Report any bugs here and we'll post fixes

Moderators: Sascha Willems, Thomas

ndBody->SetMatrix() does not update AABB if body has 0 mass.

Postby MeltingPlastic » Wed Feb 16, 2022 12:07 pm

ndBody->SetMatrix() does not update AABB if body has 0 mass. Is there a way to tell the ndScene to rebuild the AABB?

I build a body, set its mass to 0, and then I call ndBody->SetMatrix(...) to move the body to a new transform in world space. the AABB is shown to still be at the old location, still has correct size. I suspect since the body has zero mass, the engine does not automatically update it?

I also looks like the collision is not actually moved as well.
MeltingPlastic
 
Posts: 237
Joined: Fri Feb 07, 2014 11:30 pm

Re: ndBody->SetMatrix() does not update AABB if body has 0 m

Postby Julio Jerez » Wed Feb 16, 2022 12:57 pm

this is the code for that function.
Code: Select all
void ndBody::SetMatrix(const ndMatrix& matrix)
{
   m_equilibrium = 0;
   m_transformIsDirty = 1;
   m_matrix = matrix;
   dAssert(m_matrix.TestOrthogonal(ndFloat32(1.0e-4f)));

   m_rotation = ndQuaternion(m_matrix);
   m_globalCentreOfMass = m_matrix.TransformVector(m_localCentreOfMass);
}


it is not supposed to change anything other that the matrix. if did it will make the body to no macth what is in the scene.

the matrix of a body used for very few this like the reference for joints
in that function there are two flags: m_equilibrium and m_transformIsDirty

they are set to let the net update know that the status of the body changed.
the first thing in an update is a call to function void ndScene::InitBodyArray()
it this will check those flags and determine if a boy need it aabb to be recalculated and reposition in the scene broad phase.
this happens at line 1350 if file C:....\newton-4.00\sdk\dCollision\ndScene.cpp

you will see that it calls
void ndScene::UpdateAabb(ndInt32, ndBodyKinematic* const body)

it does not check for body mass or anything.
set a break point there as see if after you set the matrix that that function is called.

like I said changing the aabb of a body is a big mistake. because it will try to modify element outside of the body in the scene, what is store in the scene is the aabb of the root shape. so that will also changed.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: ndBody->SetMatrix() does not update AABB if body has 0 m

Postby MeltingPlastic » Wed Feb 16, 2022 1:17 pm

Ok. The UpdateAABB() was not being called because there was no check to see if transform was dirty. I submitted a PR. This fixed my issue. If there is better fix just close it.
MeltingPlastic
 
Posts: 237
Joined: Fri Feb 07, 2014 11:30 pm

Re: ndBody->SetMatrix() does not update AABB if body has 0 m

Postby Julio Jerez » Wed Feb 16, 2022 1:31 pm

ah yes, very nice solution.
PR merged. thanks.

I am looking that the function and I see a legacy from 3.xx
Code: Select all
      for (ndInt32 i = 0; i < run.m_count; ++i)
      {
         ndBodyKinematic* const body = node->GetInfo();
         node = node->GetNext();
         dAssert(!body->GetCollisionShape().GetShape()->GetAsShapeNull());
         bool inScene = true;

// we should not do that on behand of the application.
         if (!body->GetSceneBodyNode())
         {
            ndScopeSpinLock lock(m_lock);
            inScene = AddBody(body);
         }
         dAssert(inScene && body->m_sceneNode);


in 3.xx bodies were assumed to be part of the scene, there has it root in 3.xx but in 4.00 is the application job to manage bodies.
I will revisit that and remove that part, especially now that we are using helper joints, that are no part of the scene, that code can cause serious side effect that are hard to fix.

I will put that in the list of things to do.
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 17 guests

cron