google / filament

Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WebGL2
https://google.github.io/filament/
Apache License 2.0
17.36k stars 1.84k forks source link

Calling `getWorldPosition` after calling `setTransform` returns previous value #7827

Closed hannojg closed 1 month ago

hannojg commented 2 months ago

Describe the bug

In our code we try to change the position of an entity continuously by a game-pad input. First, we call getWorldTransform to get the current position, and then update it using setTransform. Visually we can tell that the entity is correctly updated and its position is changed. Then, on the next frame, we call the same code again, but this time getWorldTransform doesn't return the value we updated, but the previous one.

To Reproduce

Add an asset / entity to the scene (ie. it has no parent, and the entity you're changing is a direct child of the scene / world)

auto rootEntity = asset.getRoot();
auto rootInstance = transformManager.getInstance(rootEntity);

auto prev = transformManager.getWorldTransform(rootInstance) // [0, 0, 0]
transformManager.setTransform([0,1,0]) // (simplified)
auto updated = transformManager.getWorldTransform(rootInstance) // ⚠️ this is still [0, 0, 0]

Note: this behaviour is also true between frames. So when calling

auto prev = transformManager.getWorldTransform(...) // [0, 0, 0]
transformManager.setTransform([0,1,0])

engine->render(...)

auto updated = transformManager.getWorldTransform(...) // ⚠️ this is still [0, 0, 0]

Expected behavior

The world position be updated after calling setTransform

Screenshots n/a

Logs n/a

Desktop (please complete the following information):

Smartphone (please complete the following information):

Additional context n/a

pixelflinger commented 1 month ago

I wrote this simple test, which passes:

TEST(FilamentTest, TransformManagerSimple) {
    filament::FTransformManager tcm;
    EntityManager& em = EntityManager::get();
    Entity root = em.create();
    tcm.create(root);

    auto ti = tcm.getInstance(root);

    auto t = mat4f::translation(float3{ 1, 2, 3 });
    auto prev = tcm.getWorldTransform(ti);
    tcm.setTransform(ti, t);
    auto updated = tcm.getWorldTransform(ti);

    EXPECT_NE(prev, t);
    EXPECT_EQ(updated, t);
}

Are you sure you have not called openLocalTransformTransaction() ?

hannojg commented 1 month ago

Actually we don't (thanks for checking!). Let me try to build a reproduction in the filament samples - then it must be because of something else we are doing in our code!