From 2c591d2dca1192a672041a7b69d03c09ca340aba Mon Sep 17 00:00:00 2001 From: tpsiaki Date: Mon, 13 Jan 2020 13:22:49 -0800 Subject: [PATCH] Correct out-of-order transform instances (#2025) The current code only updates the order in the transaction commit if there's a single out-of-order node in the scene graph, but if multiple are out of order (or one swap doesn't fully fix the ordering), then we end up with out of order scenes, and incorrect world transforms. Additionally, when nodes are reparented outside of a transaction, the order is not updated. --- filament/src/components/TransformManager.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/filament/src/components/TransformManager.cpp b/filament/src/components/TransformManager.cpp index 842a1296ad..8ee9381810 100644 --- a/filament/src/components/TransformManager.cpp +++ b/filament/src/components/TransformManager.cpp @@ -65,6 +65,18 @@ void FTransformManager::setParent(Instance i, Instance parent) noexcept { removeNode(i); insertNode(i, parent); updateNodeTransform(i); + // Ensure that instances are still in order + if (!mLocalTransformTransactionOpen && i < parent) { + Instance end = manager.end(); + while (i != end) { + Instance iParent = Instance(manager[i].parent); + if (UTILS_UNLIKELY(iParent > i)) { + swapNode(i, iParent); + } else { + ++i; + } + } + } } } } @@ -176,7 +188,7 @@ void FTransformManager::commitLocalTransformTransaction() noexcept { mat4f const* const UTILS_RESTRICT world = manager.raw_array(); for (Instance i = manager.begin(), e = manager.end(); i != e; ++i) { // Ensure that children are always sorted after their parent. - if (UTILS_UNLIKELY(Instance(manager[i].parent) > i)) { + while (UTILS_UNLIKELY(Instance(manager[i].parent) > i)) { swapNode(i, manager[i].parent); } Instance parent = manager[i].parent;