diff options
Diffstat (limited to 'src/runtime/dragon/jobs/dragontransformjobs.cpp')
-rw-r--r-- | src/runtime/dragon/jobs/dragontransformjobs.cpp | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/src/runtime/dragon/jobs/dragontransformjobs.cpp b/src/runtime/dragon/jobs/dragontransformjobs.cpp index 6d15796..2b84adc 100644 --- a/src/runtime/dragon/jobs/dragontransformjobs.cpp +++ b/src/runtime/dragon/jobs/dragontransformjobs.cpp @@ -46,25 +46,27 @@ namespace Qt3DRender { namespace Dragon { ValueContainer<Matrix4x4> calculateWorldTransforms(ValueContainer<Matrix4x4> worldTransforms, + const QHash<QNodeId, NodeTree::NodeInfo> hierarchy, const ValueContainer<Entity> &entities, const ValueContainer<Transform> &transforms, QNodeId rootEntityId) { worldTransforms.reset(); - if (!entities.anythingDirty() && !transforms.anythingDirty()) + // TODO remove false + if (!entities.anythingDirty() && !transforms.anythingDirty() && false) return worldTransforms; + worldTransforms = ValueContainer<Matrix4x4>(); + struct Data { Data() { } - Data(QNodeId entityId_, bool dirty_) : entityId(entityId_), dirty(dirty_) { } + Data(QNodeId entityId_, bool dirty_, int level_) : entityId(entityId_), dirty(dirty_), level(level_) { } QNodeId entityId; bool dirty = false; + int level = 0; }; - const auto &dirtyTransforms = transforms.dirtyOrNew(); - const auto &dirtyEntities = entities.dirtyOrNew(); - // If entities are dirty, a transform component may have changed and we set the entire tree to // be recalculated. Note that this could be optimized. bool rootDirty = entities.anythingDirty(); @@ -74,45 +76,63 @@ ValueContainer<Matrix4x4> calculateWorldTransforms(ValueContainer<Matrix4x4> wor worldTransforms[rootEntityId] = Matrix4x4{}; } else { const auto &transform = transforms[rootEntity->m_transformComponent]; - if (transforms.dirty().contains(rootEntity->m_transformComponent)) + if (transforms.hasDirty(rootEntity->m_transformComponent)) rootDirty = true; worldTransforms[rootEntityId] = transform->m_transformMatrix; } QStack<Data> stack; stack.reserve(10); - stack.push({ rootEntityId, rootDirty }); + stack.push({ rootEntityId, rootDirty, 0 }); while (!stack.isEmpty()) { auto currentItem = stack.pop(); QNodeId currentId = currentItem.entityId; - bool currentDirty = currentItem.dirty; + int level = currentItem.level; +// bool currentDirty = currentItem.dirty; + bool currentDirty = true; if (currentDirty) worldTransforms.markDirty(currentId); const auto ¤tWorldTransform = *worldTransforms[currentId]; - const auto &children = entities[currentId]->treeChildren(); + Q_ASSERT(hierarchy.contains(currentId)); + + const auto &children = hierarchy[currentId].childIds; // Iterate the children in reverse order (because the stack is last-in-first-out) // TODO use std::reverse_iterator once we have C++17 for (auto it = children.rbegin(); it != children.rend(); ++it) { const auto &childId = *it; + if (!entities.contains(childId)) { + // Skip past non-QEntity nodes + worldTransforms[childId] = currentWorldTransform; + stack.push({childId, currentDirty, level + 1}); + continue; + } const auto &childEntity = entities[childId]; - bool childDirty = currentDirty || dirtyEntities.contains(childId); + bool childDirty = currentDirty || entities.hasDirtyOrCreated(childId); if (!childEntity->m_transformComponent.isNull()) { const auto &transform = transforms[childEntity->m_transformComponent]; - childDirty |= dirtyTransforms.contains(childEntity->m_transformComponent); + childDirty |= transforms.hasDirtyOrCreated(childEntity->m_transformComponent); if (childDirty) worldTransforms[childId] = currentWorldTransform * transform->m_transformMatrix; } else { if (childDirty) worldTransforms[childId] = currentWorldTransform; } - stack.push({ childId, childDirty }); + stack.push({ childId, childDirty, level + 1 }); } } +#ifdef QT_DEBUG + // Verify that all exist in debug mode only + for (const auto &key : entities.keys()) { + Q_ASSERT_X(worldTransforms.contains(key), "calculateWorldTransforms", + QStringLiteral("ERROR: Key %1 missing").arg(key.id()).toStdString().c_str()); + } +#endif + return worldTransforms; }; |