btMotionstate called back too frequently

sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

btMotionstate called back too frequently

Post by sparkprime »

Unless I have done something wrong, it seems the btMotionState::setWorldTransform is called even when the rigidbody in question is sleeping. Is this the expected behaviour? Would it be possible to change the behaviour so that callbacks are only called if the object has moved?

At the moment I can do this by recording the old state inside the motion state and testing the 7 floats to see if any have changed. However, it would probably be faster if bullet could do this internally.

It might also be useful (for the purposes of moving bullet onto a CPU core of its own) upon the end of each external simulation step, to pick up a list of rigidbodies that have changed during the simulation, and update the rest of the application (i.e. the graphics) after the simulation. This would mean bullet was operating on completely disjoint memory and no synchronisation would be required. This would be easy if the callbacks were only called if there was a change, but I wonder if bullet does not already support this in some fashion, therefore needing no callbacks at all.

edit: I see that the callbacks occur at the end of the external simulation step anyway, so in theory I can synchronise in the first callback.
Last edited by sparkprime on Mon Jun 16, 2008 9:13 pm, edited 1 time in total.
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

Re: btMotionstate called back too frequently

Post by sparkprime »

from btDiscreteDynamicsWorld::synchronizeMotionStates()

Code: Select all

00265                                 //we need to call the update at least once, even for sleeping objects
00266                                 //otherwise the 'graphics' transform never updates properly
00267                                 //so todo: add 'dirty' flag
00268                                 //if (body->getActivationState() != ISLAND_SLEEPING)
I don't understand this, but I guess that sleeping objects still move? Until this "todo" becomes a "hasdone" I guess I'll just keep the last state around in the motion state then.
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

Re: btMotionstate called back too frequently

Post by sparkprime »

this is complicated because btMatrix3x3 and btTransform don't have operator==, as far as I can see.
ola
Posts: 169
Joined: Sun Jan 14, 2007 7:56 pm
Location: Norway

Re: btMotionstate called back too frequently

Post by ola »

Hi, I put this on the issue list earlier, it's being worked on!
http://code.google.com/p/bullet/issues/detail?id=58

Best regards,
Ola
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

Re: btMotionstate called back too frequently

Post by sparkprime »

Cool, thanks for pointing that out. The dirty flag does seem to be the way forward. I'm wasting a lot of CPU time on sleeping objects at the moment.

I tried testing if the transform had changed in the callback but obviously it keeps changing even when it shouldn't, because of what you describe.


Also look at this code from btDiscreteDynamicsWorld::stepSimulation

Code: Select all

00332         if (numSimulationSubSteps)
00333         {
00334 
...
00341 
00342                 for (int i=0;i<clampedSimulationSteps;i++)
00343                 {
...
00345                         synchronizeMotionStates();
00346                 }
00347 
00348         } 
00349 
00350         synchronizeMotionStates();
If n internal simulation steps are performed then n+1 callbacks per rigid body will be invoked. Why not just 1? I'm making this change locally, anyway. I've also uncommented the if block for the sleeping test, it seems to work fine so far.
User avatar
Carsten
Posts: 14
Joined: Thu Sep 25, 2008 1:36 pm
Location: Germany

Re: btMotionstate called back too frequently

Post by Carsten »

Hi all!

I'm new to Bullet, and this is my first post here. :) I've started to integrate it into the Ca3D-Engine, an all-purpose, modern 3D graphics engine and game development kit, and would like to let you know that Bullet is a great and excellent package, thank you all very much for it!! :-D

Using version 2.71, I see the same issue that sparkprime described in the first post of this topic: setWorldTransform() is called back even though the body is sleeping. That is, I experience cases where

Code: Select all

void EntRigidBodyT::setWorldTransform(const btTransform& worldTrans)
{
    // Update the transformation of our graphics object according to the physics world results.
    // [...]

    std::cout << m_RigidBody->isActive() << "\n";
}
is called over and over again, printing 0 (false) after the body has come to rest.

I'm unfortunately not yet experienced enough with Bullet to give more insight or details, but this thread made me wonder if http://code.google.com/p/bullet/issues/detail?id=58 actually fixed this or if I'm doing something wrong?
I've essentially implemented the "Hello World" code, and everything seems to work perfectly except this.
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

Re: btMotionstate called back too frequently

Post by sparkprime »

No the fix that erwin committed only fixed part of the problem, the rest is here

http://code.google.com/p/bullet/issues/detail?id=73

This contains 2 further problems that are easy to fix by hacking the stepSimulation function (I think) and synchronizeMotionStates or something like that. There is a commented out if statement in the code, with a remark about dirty flags.
User avatar
Carsten
Posts: 14
Joined: Thu Sep 25, 2008 1:36 pm
Location: Germany

Re: btMotionstate called back too frequently

Post by Carsten »

sparkprime, thanks!!
So it seems like I'm using the Bullet API right, that's good to know. :P