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.
This commit is contained in:
@@ -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<WORLD>();
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user