Page 1 of 1

Is it safe to retrieve objects transforms from one thread while stepSimulation is in other thread?

Posted: Mon Jan 09, 2023 6:53 am
by graphene9932
I do physical simulation and rendering in my program.
People recommend using fixed step simulation independently of rendering thread and framerate.

So I decided to call stepSimulation in, let's say, thread 0 and rendering in thread 1.
To render btRigidBody objects I need their transforms. As far as I know body->getWorldTransform() is the best way of doing it.

So, the question is following:
Is it safe to call getWorldTransform() while simulation is ongoing in other thread?

I heard that modifying state of rigid bodies is not thread safe, but I haven't seen anything about reading their states.

Sorry for my bad English

Re: Is it safe to retrieve objects transforms from one thread while stepSimulation is in other thread?

Posted: Tue Jan 10, 2023 10:40 pm
by drleviathan
Actually body->getWorldTransform() is not necessarily the best way to do it.

When your render rate is NOT the same as your simulation step rate you can get aliased results from body->getWorldTransform() which can sometimes produce a visible jitter in the motion of otherwise smoothly moving objects. What you want is a predicted transform of the object that includes an extrapolation for any not-yet-sub-stepped time between your render time and the physics world's simulation time. The typical way to do this is to use a btMotionState for each physical body that also has a render component.

btMotionState is a pure virtual class with two methods that must be overridden:

Code: Select all

    // simulation requests outside context for new world transform
    // called once per substep for active kinematic objects, but also once for all objects when body is first added to the world
   ·virtual void getWorldTransform(btTransform& worldTrans) const = 0;

    // simulation stores the extrapolated world transform
    // called once per substep for active dynamic objects
   ·virtual void setWorldTransform(const btTransform& worldTrans) = 0;
I added the extra comments above in an attempt to summarize how the Bullet simulation uses the btMotionState API.

Bullet provides one non-virtual class derived from btMotionState for you called btDefaultMotionState. That may suit your needs, or you can write your own if you need special behavior.