mirror of https://github.com/qt/qt3d.git
Update world transform job to use direct sync
Change-Id: Ie6cdb99332b5c99e583bdb7dfa5c4810ea5bba72 Reviewed-by: Mike Krus <mike.krus@kdab.com>
This commit is contained in:
parent
f29a8c502f
commit
48ff8579fe
|
|
@ -131,15 +131,6 @@ void Transform::syncFromFrontEnd(const QNode *frontEnd, bool firstTime)
|
|||
BackendNode::syncFromFrontEnd(frontEnd, firstTime);
|
||||
}
|
||||
|
||||
void Transform::notifyWorldTransformChanged(const Matrix4x4 &worldMatrix)
|
||||
{
|
||||
auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
|
||||
change->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes);
|
||||
change->setPropertyName("worldMatrix");
|
||||
change->setValue(convertToQMatrix4x4(worldMatrix));
|
||||
notifyObservers(change);
|
||||
}
|
||||
|
||||
void Transform::updateMatrix()
|
||||
{
|
||||
QMatrix4x4 m;
|
||||
|
|
|
|||
|
|
@ -78,7 +78,6 @@ public:
|
|||
|
||||
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
|
||||
void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) final;
|
||||
void notifyWorldTransformChanged(const Matrix4x4 &worldMatrix);
|
||||
|
||||
private:
|
||||
void updateMatrix();
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@
|
|||
|
||||
#include "updateworldtransformjob_p.h"
|
||||
|
||||
#include <Qt3DCore/qtransform.h>
|
||||
#include <Qt3DCore/private/qtransform_p.h>
|
||||
#include <Qt3DCore/private/qaspectmanager_p.h>
|
||||
#include <Qt3DRender/private/renderer_p.h>
|
||||
#include <Qt3DRender/private/entity_p.h>
|
||||
#include <Qt3DRender/private/transform_p.h>
|
||||
|
|
@ -56,10 +59,17 @@ namespace Render {
|
|||
|
||||
namespace {
|
||||
|
||||
void updateWorldTransformAndBounds(NodeManagers *manager, Entity *node, const Matrix4x4 &parentTransform)
|
||||
struct TransformUpdate
|
||||
{
|
||||
Qt3DCore::QNodeId peerId;
|
||||
QMatrix4x4 worldTransformMatrix;
|
||||
};
|
||||
|
||||
QVector<TransformUpdate> updateWorldTransformAndBounds(NodeManagers *manager, Entity *node, const Matrix4x4 &parentTransform)
|
||||
{
|
||||
Matrix4x4 worldTransform(parentTransform);
|
||||
Transform *nodeTransform = node->renderComponent<Transform>();
|
||||
QVector<TransformUpdate> updatedTransforms;
|
||||
|
||||
const bool hasTransformComponent = nodeTransform != nullptr && nodeTransform->isEnabled();
|
||||
if (hasTransformComponent)
|
||||
|
|
@ -68,21 +78,33 @@ void updateWorldTransformAndBounds(NodeManagers *manager, Entity *node, const Ma
|
|||
if (*(node->worldTransform()) != worldTransform) {
|
||||
*(node->worldTransform()) = worldTransform;
|
||||
if (hasTransformComponent)
|
||||
nodeTransform->notifyWorldTransformChanged(worldTransform);
|
||||
updatedTransforms.push_back({nodeTransform->peerId(), convertToQMatrix4x4(worldTransform)});
|
||||
}
|
||||
|
||||
const auto childrenHandles = node->childrenHandles();
|
||||
for (const HEntity &handle : childrenHandles) {
|
||||
Entity *child = manager->renderNodesManager()->data(handle);
|
||||
if (child)
|
||||
updateWorldTransformAndBounds(manager, child, worldTransform);
|
||||
updatedTransforms += updateWorldTransformAndBounds(manager, child, worldTransform);
|
||||
}
|
||||
return updatedTransforms;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Q_3DRENDERSHARED_PRIVATE_EXPORT UpdateWorldTransformJobPrivate : public Qt3DCore::QAspectJobPrivate
|
||||
{
|
||||
public:
|
||||
UpdateWorldTransformJobPrivate() {}
|
||||
~UpdateWorldTransformJobPrivate() override {}
|
||||
|
||||
void postFrame(Qt3DCore::QAspectManager *manager) override;
|
||||
|
||||
QVector<TransformUpdate> m_updatedTransforms;
|
||||
};
|
||||
|
||||
UpdateWorldTransformJob::UpdateWorldTransformJob()
|
||||
: Qt3DCore::QAspectJob()
|
||||
: Qt3DCore::QAspectJob(*new UpdateWorldTransformJobPrivate())
|
||||
, m_node(nullptr)
|
||||
, m_manager(nullptr)
|
||||
{
|
||||
|
|
@ -108,17 +130,32 @@ void UpdateWorldTransformJob::run()
|
|||
// TODO: Parallelise this on each level using a parallel_for
|
||||
// implementation.
|
||||
|
||||
Q_D(UpdateWorldTransformJob);
|
||||
qCDebug(Jobs) << "Entering" << Q_FUNC_INFO << QThread::currentThread();
|
||||
|
||||
Matrix4x4 parentTransform;
|
||||
Entity *parent = m_node->parent();
|
||||
if (parent != nullptr)
|
||||
parentTransform = *(parent->worldTransform());
|
||||
updateWorldTransformAndBounds(m_manager, m_node, parentTransform);
|
||||
d->m_updatedTransforms = updateWorldTransformAndBounds(m_manager, m_node, parentTransform);
|
||||
|
||||
qCDebug(Jobs) << "Exiting" << Q_FUNC_INFO << QThread::currentThread();
|
||||
}
|
||||
|
||||
void UpdateWorldTransformJobPrivate::postFrame(Qt3DCore::QAspectManager *manager)
|
||||
{
|
||||
const QVector<TransformUpdate> updatedTransforms = std::move(m_updatedTransforms);
|
||||
for (const TransformUpdate &t : updatedTransforms) {
|
||||
Qt3DCore::QTransform *node =
|
||||
qobject_cast<Qt3DCore::QTransform *>(manager->lookupNode(t.peerId));
|
||||
if (!node)
|
||||
continue;
|
||||
Qt3DCore::QTransformPrivate *dNode =
|
||||
static_cast<Qt3DCore::QTransformPrivate *>(Qt3DCore::QNodePrivate::get(node));
|
||||
dNode->setWorldMatrix(t.worldTransformMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Render
|
||||
} // namespace Qt3DRender
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ namespace Render {
|
|||
|
||||
class Entity;
|
||||
class NodeManagers;
|
||||
class UpdateWorldTransformJobPrivate;
|
||||
|
||||
class Q_3DRENDERSHARED_PRIVATE_EXPORT UpdateWorldTransformJob : public Qt3DCore::QAspectJob
|
||||
{
|
||||
|
|
@ -77,6 +78,7 @@ public:
|
|||
private:
|
||||
Entity *m_node;
|
||||
NodeManagers *m_manager;
|
||||
Q_DECLARE_PRIVATE(UpdateWorldTransformJob)
|
||||
};
|
||||
|
||||
typedef QSharedPointer<UpdateWorldTransformJob> UpdateWorldTransformJobPtr;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include <Qt3DCore/qtransform.h>
|
||||
#include <Qt3DCore/private/qtransform_p.h>
|
||||
#include <Qt3DRender/private/transform_p.h>
|
||||
#include <Qt3DRender/private/updateworldtransformjob_p.h>
|
||||
#include <Qt3DCore/qpropertyupdatedchange.h>
|
||||
#include <private/qbackendnode_p.h>
|
||||
#include "qbackendnodetester.h"
|
||||
|
|
@ -179,31 +180,6 @@ private Q_SLOTS:
|
|||
renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
|
||||
}
|
||||
}
|
||||
|
||||
void checkWorldTransformUpdate()
|
||||
{
|
||||
// GIVEN
|
||||
TestArbiter arbiter;
|
||||
Qt3DRender::Render::Transform backend;
|
||||
|
||||
Qt3DCore::QBackendNodePrivate::get(&backend)->setArbiter(&arbiter);
|
||||
|
||||
// WHEN
|
||||
const QMatrix4x4 expectedNewWorldMatrix(1.0f, 2.0f, 3.0f, 4.0f,
|
||||
5.0f, 6.0f, 7.0f, 8.0f,
|
||||
9.0f, 10.0f, 11.0f, 12.0f,
|
||||
13.0f, 14.0f, 15.0f, 16.0f);
|
||||
Matrix4x4 newWorldMatrix(expectedNewWorldMatrix);
|
||||
backend.notifyWorldTransformChanged(newWorldMatrix);
|
||||
|
||||
// THEN
|
||||
Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
|
||||
QCOMPARE(arbiter.events.count(), 1);
|
||||
QCOMPARE(change->propertyName(), "worldMatrix");
|
||||
QCOMPARE(change->value().value<QMatrix4x4>(), expectedNewWorldMatrix);
|
||||
|
||||
arbiter.events.clear();
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(tst_Transform)
|
||||
|
|
|
|||
Loading…
Reference in New Issue