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

Post Reply
graphene9932
Posts: 1
Joined: Sun Jan 08, 2023 8:34 pm

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

Post 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
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

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

Post 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.
Post Reply