Update QScene2D to use direct sync

Change-Id: Iba2fa5ce9d295706fc50f904cac68f00bd8f02b7
Reviewed-by: Antti Määttä <antti.maatta@qt.io>
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
This commit is contained in:
Mike Krus 2019-10-11 14:03:41 +01:00
parent fd85ebb1e2
commit e8ef2e3e75
12 changed files with 230 additions and 170 deletions

View File

@ -81,6 +81,7 @@ protected:
template<class Frontend, bool supportsSyncing> template<class Frontend, bool supportsSyncing>
void registerBackendType(const QBackendNodeMapperPtr &functor); void registerBackendType(const QBackendNodeMapperPtr &functor);
void registerBackendType(const QMetaObject &obj, const QBackendNodeMapperPtr &functor); void registerBackendType(const QMetaObject &obj, const QBackendNodeMapperPtr &functor);
void registerBackendType(const QMetaObject &obj, const QBackendNodeMapperPtr &functor, bool supportsSyncing);
template<class Frontend> template<class Frontend>
void unregisterBackendType(); void unregisterBackendType();
void unregisterBackendType(const QMetaObject &); void unregisterBackendType(const QMetaObject &);
@ -88,7 +89,6 @@ protected:
private: private:
void syncDirtyFrontEndNodes(const QVector<QNode *> &nodes); void syncDirtyFrontEndNodes(const QVector<QNode *> &nodes);
void syncDirtyFrontEndSubNodes(const QVector<NodeRelationshipChange> &nodes); void syncDirtyFrontEndSubNodes(const QVector<NodeRelationshipChange> &nodes);
void registerBackendType(const QMetaObject &obj, const QBackendNodeMapperPtr &functor, bool supportsSyncing);
virtual QVariant executeCommand(const QStringList &args); virtual QVariant executeCommand(const QStringList &args);

View File

@ -96,7 +96,7 @@ bool Scene2DPlugin::registerBackendTypes(QRenderAspect *aspect,
{ {
registerBackendType(aspect, Qt3DRender::Quick::QScene2D::staticMetaObject, registerBackendType(aspect, Qt3DRender::Quick::QScene2D::staticMetaObject,
QSharedPointer<Scene2DBackendNodeMapper<Render::Quick::Scene2D> > QSharedPointer<Scene2DBackendNodeMapper<Render::Quick::Scene2D> >
::create(renderer, m_scene2dNodeManager)); ::create(renderer, m_scene2dNodeManager), true);
return true; return true;
} }
bool Scene2DPlugin::unregisterBackendTypes(QRenderAspect *aspect) bool Scene2DPlugin::unregisterBackendTypes(QRenderAspect *aspect)

View File

@ -42,8 +42,6 @@
#include "scene2devent_p.h" #include "scene2devent_p.h"
#include <Qt3DCore/qentity.h> #include <Qt3DCore/qentity.h>
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -190,15 +188,6 @@ QScene2DPrivate::~QScene2DPrivate()
delete m_renderManager; delete m_renderManager;
} }
void QScene2DPrivate::setScene(Qt3DCore::QScene *scene)
{
Q_Q(QScene2D);
QNodePrivate::setScene(scene);
const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(q->id());
change->setPropertyName("sceneInitialized");
notifyObservers(change);
}
/*! /*!
The constructor creates a new QScene2D instance with the specified \a parent. The constructor creates a new QScene2D instance with the specified \a parent.
@ -310,6 +299,15 @@ QVector<Qt3DCore::QEntity*> QScene2D::entities()
return d->m_entities; return d->m_entities;
} }
/*!
Retrieve entities associated with the QScene2D.
*/
QVector<Qt3DCore::QEntity*> QScene2D::entities() const
{
Q_D(const QScene2D);
return d->m_entities;
}
/*! /*!
Adds an \a entity to the the QScene2D object. If the entities have QObjectPicker, Adds an \a entity to the the QScene2D object. If the entities have QObjectPicker,
the pick events from that entity are sent to QScene2D and converted to mouse events. the pick events from that entity are sent to QScene2D and converted to mouse events.
@ -321,12 +319,7 @@ void QScene2D::addEntity(Qt3DCore::QEntity *entity)
d->m_entities.append(entity); d->m_entities.append(entity);
d->registerDestructionHelper(entity, &QScene2D::removeEntity, d->m_entities); d->registerDestructionHelper(entity, &QScene2D::removeEntity, d->m_entities);
d->updateNode(entity, "entities", PropertyValueAdded);
if (d->m_changeArbiter != nullptr) {
const auto change = Qt3DCore::QPropertyNodeAddedChangePtr::create(id(), entity);
change->setPropertyName("entities");
d->notifyObservers(change);
}
} }
} }
@ -340,12 +333,7 @@ void QScene2D::removeEntity(Qt3DCore::QEntity *entity)
d->m_entities.removeAll(entity); d->m_entities.removeAll(entity);
d->unregisterDestructionHelper(entity); d->unregisterDestructionHelper(entity);
d->updateNode(entity, "entities", PropertyValueRemoved);
if (d->m_changeArbiter != nullptr) {
const auto change = Qt3DCore::QPropertyNodeRemovedChangePtr::create(id(), entity);
change->setPropertyName("entities");
d->notifyObservers(change);
}
} }
} }

View File

@ -86,7 +86,8 @@ public:
QQuickItem *item() const; QQuickItem *item() const;
bool isMouseEnabled() const; bool isMouseEnabled() const;
QVector<Qt3DCore::QEntity *> entities(); Q_DECL_DEPRECATED QVector<Qt3DCore::QEntity *> entities();
QVector<Qt3DCore::QEntity *> entities() const;
void addEntity(Qt3DCore::QEntity *entity); void addEntity(Qt3DCore::QEntity *entity);
void removeEntity(Qt3DCore::QEntity *entity); void removeEntity(Qt3DCore::QEntity *entity);

View File

@ -74,8 +74,6 @@ public:
QScene2DPrivate(); QScene2DPrivate();
~QScene2DPrivate(); ~QScene2DPrivate();
void setScene(Qt3DCore::QScene *scene) override;
Scene2DManager *m_renderManager; Scene2DManager *m_renderManager;
QMetaObject::Connection m_textureDestroyedConnection; QMetaObject::Connection m_textureDestroyedConnection;
Qt3DRender::QRenderTargetOutput *m_output; Qt3DRender::QRenderTargetOutput *m_output;

View File

@ -37,6 +37,7 @@
#include <Qt3DCore/qpropertyupdatedchange.h> #include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/qpropertynodeaddedchange.h> #include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h> #include <Qt3DCore/qpropertynoderemovedchange.h>
#include <Qt3DCore/private/qscene_p.h>
#include <Qt3DQuickScene2D/qscene2d.h> #include <Qt3DQuickScene2D/qscene2d.h>
#include <Qt3DRender/qpicktriangleevent.h> #include <Qt3DRender/qpicktriangleevent.h>
#include <Qt3DRender/qobjectpicker.h> #include <Qt3DRender/qobjectpicker.h>
@ -58,6 +59,7 @@
#include <private/qbackendnode_p.h> #include <private/qbackendnode_p.h>
#include <private/qobjectpicker_p.h> #include <private/qobjectpicker_p.h>
#include <private/qpickevent_p.h> #include <private/qpickevent_p.h>
#include <private/qpicktriangleevent_p.h>
#include <private/entity_p.h> #include <private/entity_p.h>
#include <private/platformsurfacefilter_p.h> #include <private/platformsurfacefilter_p.h>
#include <private/trianglesvisitor_p.h> #include <private/trianglesvisitor_p.h>
@ -130,7 +132,9 @@ Scene2D::Scene2D()
Scene2D::~Scene2D() Scene2D::~Scene2D()
{ {
stopGrabbing(); for (auto connection: qAsConst(m_connections))
QObject::disconnect(connection);
m_connections.clear();
} }
void Scene2D::setOutput(Qt3DCore::QNodeId outputId) void Scene2D::setOutput(Qt3DCore::QNodeId outputId)
@ -141,12 +145,9 @@ void Scene2D::setOutput(Qt3DCore::QNodeId outputId)
void Scene2D::initializeSharedObject() void Scene2D::initializeSharedObject()
{ {
if (!m_initialized) { if (!m_initialized) {
// bail out if we're running autotests // bail out if we're running autotests
if (!m_sharedObject->m_renderManager if (!qgetenv("QT3D_SCENE2D_DISABLE_RENDERING").isEmpty())
|| m_sharedObject->m_renderManager->thread() == QThread::currentThread()) {
return; return;
}
renderThreadClientCount->fetchAndAddAcquire(1); renderThreadClientCount->fetchAndAddAcquire(1);
@ -171,76 +172,50 @@ void Scene2D::initializeSharedObject()
} }
} }
void Scene2D::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) void Scene2D::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime)
{ {
const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QScene2DData>>(change); Qt3DRender::Render::BackendNode::syncFromFrontEnd(frontEnd, firstTime);
const auto &data = typedChange->data; const QScene2D *node = qobject_cast<const QScene2D *>(frontEnd);
m_renderPolicy = data.renderPolicy; if (!node)
setSharedObject(data.sharedObject); return;
setOutput(data.output); const QScene2DPrivate *dnode = static_cast<const QScene2DPrivate *>(QScene2DPrivate::get(node));
m_entities = data.entityIds;
m_mouseEnabled = data.mouseEnabled;
}
void Scene2D::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) if (m_mouseEnabled != node->isMouseEnabled()) {
{ m_mouseEnabled = node->isMouseEnabled();
switch (e->type()) { if (!firstTime && m_mouseEnabled && m_cachedPickEvent) {
handlePickEvent(QEvent::MouseButtonPress, m_cachedPickEvent.data());
case Qt3DCore::PropertyUpdated: {
Qt3DCore::QPropertyUpdatedChangePtr propertyChange
= qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(e);
if (propertyChange->propertyName() == QByteArrayLiteral("renderPolicy")) {
m_renderPolicy = propertyChange->value().value<QScene2D::RenderPolicy>();
} else if (propertyChange->propertyName() == QByteArrayLiteral("output")) {
Qt3DCore::QNodeId outputId = propertyChange->value().value<Qt3DCore::QNodeId>();
setOutput(outputId);
} else if (propertyChange->propertyName() == QByteArrayLiteral("pressed")) {
QObjectPickerEvent ev = propertyChange->value().value<QObjectPickerEvent>();
QPickEventPtr pickEvent = ev.event;
handlePickEvent(QEvent::MouseButtonPress, pickEvent);
} else if (propertyChange->propertyName() == QByteArrayLiteral("released")) {
QObjectPickerEvent ev = propertyChange->value().value<QObjectPickerEvent>();
QPickEventPtr pickEvent = ev.event;
handlePickEvent(QEvent::MouseButtonRelease, pickEvent);
} else if (propertyChange->propertyName() == QByteArrayLiteral("moved")) {
QObjectPickerEvent ev = propertyChange->value().value<QObjectPickerEvent>();
QPickEventPtr pickEvent = ev.event;
handlePickEvent(QEvent::MouseMove, pickEvent);
} else if (propertyChange->propertyName() == QByteArrayLiteral("mouseEnabled")) {
m_mouseEnabled = propertyChange->value().toBool();
if (m_mouseEnabled && !m_cachedPickEvent.isNull()) {
handlePickEvent(QEvent::MouseButtonPress, m_cachedPickEvent);
m_cachedPickEvent.clear(); m_cachedPickEvent.clear();
} }
} else if (propertyChange->propertyName() == QByteArrayLiteral("sceneInitialized")) {
startGrabbing();
}
break;
} }
case Qt3DCore::PropertyValueAdded: { m_renderPolicy = node->renderPolicy();
const auto change = qSharedPointerCast<Qt3DCore::QPropertyNodeAddedChange>(e); auto id = Qt3DCore::qIdForNode(node->output());
if (change->propertyName() == QByteArrayLiteral("entities")) { if (id != m_outputId)
m_entities.push_back(change->addedNodeId()); setOutput(id);
registerObjectPickerEvents(change->addedNodeId());
}
break;
}
case Qt3DCore::PropertyValueRemoved: { auto ids = Qt3DCore::qIdsForNodes(node->entities());
const auto change = qSharedPointerCast<Qt3DCore::QPropertyNodeRemovedChange>(e); std::sort(std::begin(ids), std::end(ids));
if (change->propertyName() == QByteArrayLiteral("entities")) { Qt3DCore::QNodeIdVector addedEntities;
m_entities.removeOne(change->removedNodeId()); Qt3DCore::QNodeIdVector removedEntities;
unregisterObjectPickerEvents(change->removedNodeId()); std::set_difference(std::begin(ids), std::end(ids),
} std::begin(m_entities), std::end(m_entities),
break; std::inserter(addedEntities, addedEntities.end()));
} std::set_difference(std::begin(m_entities), std::end(m_entities),
std::begin(ids), std::end(ids),
std::inserter(removedEntities, removedEntities.end()));
for (const auto &id: addedEntities) {
Qt3DCore::QEntity *entity = qobject_cast<Qt3DCore::QEntity *>(dnode->m_scene->lookupNode(id));
if (!entity)
return;
default: registerObjectPickerEvents(entity);
break;
} }
BackendNode::sceneChangeEvent(e); for (const auto &id: removedEntities)
unregisterObjectPickerEvents(id);
m_entities = ids;
if (firstTime)
setSharedObject(dnode->m_renderManager->m_sharedObject);
} }
void Scene2D::setSharedObject(Qt3DRender::Quick::Scene2DSharedObjectPtr sharedObject) void Scene2D::setSharedObject(Qt3DRender::Quick::Scene2DSharedObjectPtr sharedObject)
@ -449,19 +424,31 @@ void Scene2D::cleanup()
} }
bool Scene2D::registerObjectPickerEvents(Qt3DCore::QNodeId entityId) bool Scene2D::registerObjectPickerEvents(Qt3DCore::QEntity *qentity)
{ {
Entity *entity = nullptr; Entity *entity = nullptr;
if (!resourceAccessor()->accessResource(RenderBackendResourceAccessor::EntityHandle, if (!resourceAccessor()->accessResource(RenderBackendResourceAccessor::EntityHandle,
entityId, (void**)&entity, nullptr)) { qentity->id(), (void**)&entity, nullptr))
return false; return false;
}
if (!entity->containsComponentsOfType<ObjectPicker>() || if (!entity->containsComponentsOfType<ObjectPicker>() ||
!entity->containsComponentsOfType<GeometryRenderer>()) { !entity->containsComponentsOfType<GeometryRenderer>()) {
qCWarning(Qt3DRender::Quick::Scene2D) << Q_FUNC_INFO qCWarning(Qt3DRender::Quick::Scene2D) << Q_FUNC_INFO
<< "Entity does not contain required components: ObjectPicker and GeometryRenderer"; << "Entity does not contain required components: ObjectPicker and GeometryRenderer";
return false; return false;
} }
QObjectPicker *picker = qentity->componentsOfType<QObjectPicker>().front();
m_connections << QObject::connect(picker, &QObjectPicker::pressed, qentity, [this](Qt3DRender::QPickEvent *pick) {
handlePickEvent(QEvent::MouseButtonPress, pick);
});
m_connections << QObject::connect(picker, &QObjectPicker::released, qentity, [this](Qt3DRender::QPickEvent *pick) {
handlePickEvent(QEvent::MouseButtonRelease, pick);
});
m_connections << QObject::connect(picker, &QObjectPicker::moved, qentity, [this](Qt3DRender::QPickEvent *pick) {
handlePickEvent(QEvent::MouseMove, pick);
});
Qt3DCore::QBackendNodePrivate *priv = Qt3DCore::QBackendNodePrivate::get(this); Qt3DCore::QBackendNodePrivate *priv = Qt3DCore::QBackendNodePrivate::get(this);
Qt3DCore::QChangeArbiter *arbiter = static_cast<Qt3DCore::QChangeArbiter*>(priv->m_arbiter); Qt3DCore::QChangeArbiter *arbiter = static_cast<Qt3DCore::QChangeArbiter*>(priv->m_arbiter);
arbiter->registerObserver(d_ptr, entity->componentUuid<ObjectPicker>()); arbiter->registerObserver(d_ptr, entity->componentUuid<ObjectPicker>());
@ -472,26 +459,27 @@ void Scene2D::unregisterObjectPickerEvents(Qt3DCore::QNodeId entityId)
{ {
Entity *entity = nullptr; Entity *entity = nullptr;
if (!resourceAccessor()->accessResource(RenderBackendResourceAccessor::EntityHandle, if (!resourceAccessor()->accessResource(RenderBackendResourceAccessor::EntityHandle,
entityId, (void**)&entity, nullptr)) { entityId, (void**)&entity, nullptr))
return; return;
}
Qt3DCore::QBackendNodePrivate *priv = Qt3DCore::QBackendNodePrivate::get(this); Qt3DCore::QBackendNodePrivate *priv = Qt3DCore::QBackendNodePrivate::get(this);
Qt3DCore::QChangeArbiter *arbiter = static_cast<Qt3DCore::QChangeArbiter*>(priv->m_arbiter); Qt3DCore::QChangeArbiter *arbiter = static_cast<Qt3DCore::QChangeArbiter*>(priv->m_arbiter);
arbiter->unregisterObserver(d_ptr, entity->componentUuid<ObjectPicker>()); arbiter->unregisterObserver(d_ptr, entity->componentUuid<ObjectPicker>());
} }
void Scene2D::handlePickEvent(int type, const Qt3DRender::QPickEventPtr &ev) void Scene2D::handlePickEvent(int type, const Qt3DRender::QPickEvent *ev)
{ {
if (!isEnabled()) if (!isEnabled())
return; return;
if (m_mouseEnabled) { if (m_mouseEnabled) {
QPickTriangleEvent *pickTriangle = static_cast<QPickTriangleEvent *>(ev.data()); const QPickTriangleEvent *pickTriangle = static_cast<const QPickTriangleEvent *>(ev);
Q_ASSERT(pickTriangle->entity());
Entity *entity = nullptr; Entity *entity = nullptr;
if (!resourceAccessor()->accessResource(RenderBackendResourceAccessor::EntityHandle, if (!resourceAccessor()->accessResource(RenderBackendResourceAccessor::EntityHandle,
QPickEventPrivate::get(pickTriangle)->m_entity, Qt3DCore::qIdForNode(pickTriangle->entity()),
(void**)&entity, nullptr)) { (void**)&entity, nullptr))
return; return;
}
CoordinateReader reader(renderer()->nodeManagers()); CoordinateReader reader(renderer()->nodeManagers());
if (reader.setGeometry(entity->renderComponent<GeometryRenderer>(), if (reader.setGeometry(entity->renderComponent<GeometryRenderer>(),
QAttribute::defaultTextureCoordinateAttributeName())) { QAttribute::defaultTextureCoordinateAttributeName())) {
@ -515,24 +503,14 @@ void Scene2D::handlePickEvent(int type, const Qt3DRender::QPickEventPtr &ev)
QCoreApplication::postEvent(m_sharedObject->m_quickWindow, mouseEvent); QCoreApplication::postEvent(m_sharedObject->m_quickWindow, mouseEvent);
} }
} else if (type == QEvent::MouseButtonPress) { } else if (type == QEvent::MouseButtonPress) {
m_cachedPickEvent = ev; const QPickTriangleEvent *pickTriangle = static_cast<const QPickTriangleEvent *>(ev);
const QPickTriangleEventPrivate *dpick = QPickTriangleEventPrivate::get(pickTriangle);
m_cachedPickEvent = QPickEventPtr(dpick->clone());
} else { } else {
m_cachedPickEvent.clear(); m_cachedPickEvent.clear();
} }
} }
void Scene2D::startGrabbing()
{
for (Qt3DCore::QNodeId e : qAsConst(m_entities))
registerObjectPickerEvents(e);
}
void Scene2D::stopGrabbing()
{
for (Qt3DCore::QNodeId e : qAsConst(m_entities))
unregisterObjectPickerEvents(e);
}
} // namespace Quick } // namespace Quick
} // namespace Render } // namespace Render
} // namespace Qt3DRender } // namespace Qt3DRender

View File

@ -94,16 +94,13 @@ public:
void setOutput(Qt3DCore::QNodeId outputId); void setOutput(Qt3DCore::QNodeId outputId);
void initializeSharedObject(); void initializeSharedObject();
void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) override; void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override;
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override;
bool updateFbo(QOpenGLTexture *texture); bool updateFbo(QOpenGLTexture *texture);
void syncRenderControl(); void syncRenderControl();
void startGrabbing(); bool registerObjectPickerEvents(Qt3DCore::QEntity *qentity);
void stopGrabbing();
bool registerObjectPickerEvents(Qt3DCore::QNodeId entityId);
void unregisterObjectPickerEvents(Qt3DCore::QNodeId entityId); void unregisterObjectPickerEvents(Qt3DCore::QNodeId entityId);
void handlePickEvent(int type, const Qt3DRender::QPickEventPtr &ev); void handlePickEvent(int type, const QPickEvent *ev);
QOpenGLContext *m_context; QOpenGLContext *m_context;
QOpenGLContext *m_shareContext; QOpenGLContext *m_shareContext;
@ -126,6 +123,7 @@ public:
#ifdef QT_OPENGL_ES_2_ANGLE #ifdef QT_OPENGL_ES_2_ANGLE
bool m_usingAngle; bool m_usingAngle;
#endif #endif
QVector<QMetaObject::Connection> m_connections;
}; };
} // Quick } // Quick

View File

@ -75,6 +75,10 @@ protected:
{ {
aspect->registerBackendType(obj, functor); aspect->registerBackendType(obj, functor);
} }
void registerBackendType(QRenderAspect *aspect, const QMetaObject &obj, const Qt3DCore::QBackendNodeMapperPtr &functor, bool supportsSyncing)
{
aspect->registerBackendType(obj, functor, supportsSyncing);
}
void unregisterBackendType(QRenderAspect *aspect, const QMetaObject &obj) void unregisterBackendType(QRenderAspect *aspect, const QMetaObject &obj)
{ {
aspect->unregisterBackendType(obj); aspect->unregisterBackendType(obj);

View File

@ -7,6 +7,7 @@ HEADERS += \
$$PWD/qpicklineevent.h \ $$PWD/qpicklineevent.h \
$$PWD/qpickpointevent.h \ $$PWD/qpickpointevent.h \
$$PWD/qpicktriangleevent.h \ $$PWD/qpicktriangleevent.h \
$$PWD/qpicktriangleevent_p.h \
$$PWD/objectpicker_p.h \ $$PWD/objectpicker_p.h \
$$PWD/pickeventfilter_p.h \ $$PWD/pickeventfilter_p.h \
$$PWD/qobjectpicker_p.h \ $$PWD/qobjectpicker_p.h \

View File

@ -38,6 +38,7 @@
****************************************************************************/ ****************************************************************************/
#include "qpicktriangleevent.h" #include "qpicktriangleevent.h"
#include "qpicktriangleevent_p.h"
#include "qpickevent_p.h" #include "qpickevent_p.h"
#include <private/qobject_p.h> #include <private/qobject_p.h>
@ -45,10 +46,8 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender { namespace Qt3DRender {
class QPickTriangleEventPrivate : public QPickEventPrivate
{ Qt3DRender::QPickTriangleEventPrivate::QPickTriangleEventPrivate()
public:
QPickTriangleEventPrivate()
: QPickEventPrivate() : QPickEventPrivate()
, m_triangleIndex(0) , m_triangleIndex(0)
, m_vertex1Index(0) , m_vertex1Index(0)
@ -57,12 +56,32 @@ public:
{ {
} }
uint m_triangleIndex; const QPickTriangleEventPrivate *QPickTriangleEventPrivate::get(const QPickTriangleEvent *ev)
uint m_vertex1Index; {
uint m_vertex2Index; return ev->d_func();
uint m_vertex3Index; }
QVector3D m_uvw;
}; QPickTriangleEvent *QPickTriangleEventPrivate::clone() const
{
auto res = new QPickTriangleEvent();
res->d_func()->m_accepted = m_accepted;
res->d_func()->m_position = m_position;
res->d_func()->m_worldIntersection = m_worldIntersection;
res->d_func()->m_localIntersection = m_localIntersection;
res->d_func()->m_distance = m_distance;
res->d_func()->m_button = m_button;
res->d_func()->m_buttons = m_buttons;
res->d_func()->m_modifiers = m_modifiers;
res->d_func()->m_entity = m_entity;
res->d_func()->m_entityPtr = m_entityPtr;
res->d_func()->m_viewport = m_viewport;
res->d_func()->m_triangleIndex = m_triangleIndex;
res->d_func()->m_vertex1Index = m_vertex1Index;
res->d_func()->m_vertex2Index = m_vertex2Index;
res->d_func()->m_vertex3Index = m_vertex3Index;
return res;
}
/*! /*!
\class Qt3DRender::QPickTriangleEvent \class Qt3DRender::QPickTriangleEvent

View File

@ -0,0 +1,69 @@
/****************************************************************************
**
** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QT3DRENDER_QPICKTRIANGLEEVENT_P_H
#define QT3DRENDER_QPICKTRIANGLEEVENT_P_H
#include <Qt3DRender/private/qpickevent_p.h>
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
class QPickTriangleEvent;
class Q_3DRENDERSHARED_PRIVATE_EXPORT QPickTriangleEventPrivate : public QPickEventPrivate
{
public:
QPickTriangleEventPrivate();
static const QPickTriangleEventPrivate *get(const QPickTriangleEvent *ev);
QPickTriangleEvent *clone() const;
uint m_triangleIndex;
uint m_vertex1Index;
uint m_vertex2Index;
uint m_vertex3Index;
QVector3D m_uvw;
};
} // Qt3DRender
QT_END_NAMESPACE
#endif // QT3DRENDER_QPICKTRIANGLEEVENT_P_H

View File

@ -128,7 +128,7 @@ private Q_SLOTS:
// WHEN // WHEN
QScopedPointer<Scene2D> backendScene2d(new Scene2D()); QScopedPointer<Scene2D> backendScene2d(new Scene2D());
backendScene2d->setRenderer(&renderer); backendScene2d->setRenderer(&renderer);
simulateInitialization(&frontend, backendScene2d.data()); simulateInitializationSync(&frontend, backendScene2d.data());
// THEN // THEN
QCOMPARE(backendScene2d->isEnabled(), true); QCOMPARE(backendScene2d->isEnabled(), true);
@ -144,7 +144,7 @@ private Q_SLOTS:
QScopedPointer<Scene2D> backendScene2d(new Scene2D()); QScopedPointer<Scene2D> backendScene2d(new Scene2D());
frontend.setEnabled(false); frontend.setEnabled(false);
backendScene2d->setRenderer(&renderer); backendScene2d->setRenderer(&renderer);
simulateInitialization(&frontend, backendScene2d.data()); simulateInitializationSync(&frontend, backendScene2d.data());
// THEN // THEN
QCOMPARE(backendScene2d->peerId(), frontend.id()); QCOMPARE(backendScene2d->peerId(), frontend.id());
@ -156,18 +156,18 @@ private Q_SLOTS:
void checkSceneChangeEvents() void checkSceneChangeEvents()
{ {
// GIVEN // GIVEN
Qt3DRender::Quick::QScene2D frontend;
QScopedPointer<Scene2D> backendScene2d(new Scene2D()); QScopedPointer<Scene2D> backendScene2d(new Scene2D());
TestRenderer renderer; TestRenderer renderer;
QScopedPointer<Qt3DRender::QRenderTargetOutput> output(new Qt3DRender::QRenderTargetOutput()); QScopedPointer<Qt3DRender::QRenderTargetOutput> output(new Qt3DRender::QRenderTargetOutput());
backendScene2d->setRenderer(&renderer); backendScene2d->setRenderer(&renderer);
simulateInitializationSync(&frontend, backendScene2d.data());
{ {
// WHEN // WHEN
const bool newValue = false; const bool newValue = false;
const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); frontend.setEnabled(false);
change->setPropertyName("enabled"); backendScene2d->syncFromFrontEnd(&frontend, false);
change->setValue(newValue);
backendScene2d->sceneChangeEvent(change);
// THEN // THEN
QCOMPARE(backendScene2d->isEnabled(), newValue); QCOMPARE(backendScene2d->isEnabled(), newValue);
@ -175,10 +175,8 @@ private Q_SLOTS:
{ {
// WHEN // WHEN
const Qt3DCore::QNodeId newValue = output.data()->id(); const Qt3DCore::QNodeId newValue = output.data()->id();
const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); frontend.setOutput(output.data());
change->setPropertyName("output"); backendScene2d->syncFromFrontEnd(&frontend, false);
change->setValue(QVariant::fromValue(newValue));
backendScene2d->sceneChangeEvent(change);
// THEN // THEN
QCOMPARE(backendScene2d->m_outputId, newValue); QCOMPARE(backendScene2d->m_outputId, newValue);
@ -186,10 +184,8 @@ private Q_SLOTS:
{ {
// WHEN // WHEN
const QScene2D::RenderPolicy newValue = QScene2D::SingleShot; const QScene2D::RenderPolicy newValue = QScene2D::SingleShot;
const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); frontend.setRenderPolicy(newValue);
change->setPropertyName("renderPolicy"); backendScene2d->syncFromFrontEnd(&frontend, false);
change->setValue(QVariant::fromValue(newValue));
backendScene2d->sceneChangeEvent(change);
// THEN // THEN
QCOMPARE(backendScene2d->m_renderPolicy, newValue); QCOMPARE(backendScene2d->m_renderPolicy, newValue);
@ -197,10 +193,7 @@ private Q_SLOTS:
{ {
// WHEN // WHEN
const bool newValue = false; const bool newValue = false;
const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); frontend.setMouseEnabled(newValue);
change->setPropertyName("mouseEnabled");
change->setValue(newValue);
backendScene2d->sceneChangeEvent(change);
// THEN // THEN
QCOMPARE(backendScene2d->isEnabled(), newValue); QCOMPARE(backendScene2d->isEnabled(), newValue);
@ -209,10 +202,11 @@ private Q_SLOTS:
backendScene2d->cleanup(); backendScene2d->cleanup();
} }
void testCoordinateCalculation() void testCoordinateCalculation()
{ {
// GIVEN // GIVEN
qputenv("QT3D_SCENE2D_DISABLE_RENDERING", "1");
QScopedPointer<TestWindow> testWindow(new TestWindow()); QScopedPointer<TestWindow> testWindow(new TestWindow());
Scene2DSharedObjectPtr sharedObject(new Scene2DSharedObject(nullptr)); Scene2DSharedObjectPtr sharedObject(new Scene2DSharedObject(nullptr));
QScopedPointer<Scene2D> scene2d(new Scene2D()); QScopedPointer<Scene2D> scene2d(new Scene2D());
@ -336,7 +330,8 @@ private Q_SLOTS:
QVector3D uvw(1.0, 0.0f, 0.0f); QVector3D uvw(1.0, 0.0f, 0.0f);
Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(0, 0, 1, 2, uvw)); Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(0, 0, 1, 2, uvw));
Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id(); Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id();
scene2d->handlePickEvent(QEvent::MouseButtonPress, ev); Qt3DRender::QPickEventPrivate::get(ev.data())->m_entityPtr = entity.data();
scene2d->handlePickEvent(QEvent::MouseButtonPress, ev.data());
QCoreApplication::processEvents(); QCoreApplication::processEvents();
@ -350,7 +345,8 @@ private Q_SLOTS:
QVector3D uvw(0.0, 1.0f, 0.0f); QVector3D uvw(0.0, 1.0f, 0.0f);
Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(0, 0, 1, 2, uvw)); Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(0, 0, 1, 2, uvw));
Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id(); Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id();
scene2d->handlePickEvent(QEvent::MouseButtonPress, ev); Qt3DRender::QPickEventPrivate::get(ev.data())->m_entityPtr = entity.data();
scene2d->handlePickEvent(QEvent::MouseButtonPress, ev.data());
QCoreApplication::processEvents(); QCoreApplication::processEvents();
@ -364,7 +360,8 @@ private Q_SLOTS:
QVector3D uvw(0.0, 0.0f, 1.0f); QVector3D uvw(0.0, 0.0f, 1.0f);
Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(0, 0, 1, 2, uvw)); Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(0, 0, 1, 2, uvw));
Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id(); Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id();
scene2d->handlePickEvent(QEvent::MouseButtonPress, ev); Qt3DRender::QPickEventPrivate::get(ev.data())->m_entityPtr = entity.data();
scene2d->handlePickEvent(QEvent::MouseButtonPress, ev.data());
QCoreApplication::processEvents(); QCoreApplication::processEvents();
@ -378,7 +375,8 @@ private Q_SLOTS:
QVector3D uvw(1.0, 0.0f, 0.0f); QVector3D uvw(1.0, 0.0f, 0.0f);
Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(1, 3, 4, 5, uvw)); Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(1, 3, 4, 5, uvw));
Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id(); Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id();
scene2d->handlePickEvent(QEvent::MouseButtonPress, ev); Qt3DRender::QPickEventPrivate::get(ev.data())->m_entityPtr = entity.data();
scene2d->handlePickEvent(QEvent::MouseButtonPress, ev.data());
QCoreApplication::processEvents(); QCoreApplication::processEvents();
@ -392,7 +390,8 @@ private Q_SLOTS:
QVector3D uvw(0.0, 1.0f, 0.0f); QVector3D uvw(0.0, 1.0f, 0.0f);
Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(1, 3, 4, 5, uvw)); Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(1, 3, 4, 5, uvw));
Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id(); Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id();
scene2d->handlePickEvent(QEvent::MouseButtonPress, ev); Qt3DRender::QPickEventPrivate::get(ev.data())->m_entityPtr = entity.data();
scene2d->handlePickEvent(QEvent::MouseButtonPress, ev.data());
QCoreApplication::processEvents(); QCoreApplication::processEvents();
@ -406,7 +405,8 @@ private Q_SLOTS:
QVector3D uvw(0.0, 0.0f, 1.0f); QVector3D uvw(0.0, 0.0f, 1.0f);
Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(1, 3, 4, 5, uvw)); Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(1, 3, 4, 5, uvw));
Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id(); Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id();
scene2d->handlePickEvent(QEvent::MouseButtonPress, ev); Qt3DRender::QPickEventPrivate::get(ev.data())->m_entityPtr = entity.data();
scene2d->handlePickEvent(QEvent::MouseButtonPress, ev.data());
QCoreApplication::processEvents(); QCoreApplication::processEvents();
@ -420,12 +420,13 @@ private Q_SLOTS:
QVector3D uvw(0.5f, 0.25f, 0.25f); QVector3D uvw(0.5f, 0.25f, 0.25f);
Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(0, 0, 1, 2, uvw)); Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(0, 0, 1, 2, uvw));
Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id(); Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id();
scene2d->handlePickEvent(QEvent::MouseButtonPress, ev); Qt3DRender::QPickEventPrivate::get(ev.data())->m_entityPtr = entity.data();
scene2d->handlePickEvent(QEvent::MouseButtonPress, ev.data());
QCoreApplication::processEvents(); QCoreApplication::processEvents();
// THEN // THEN
QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(512.0f, 768.0f))); QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(512.0, 768.0)));
testWindow->clear(); testWindow->clear();
} }
@ -434,14 +435,17 @@ private Q_SLOTS:
QVector3D uvw(0.875f, 0.09375f, 0.03125f); QVector3D uvw(0.875f, 0.09375f, 0.03125f);
Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(1, 3, 4, 5, uvw)); Qt3DRender::QPickEventPtr ev = Qt3DRender::QPickEventPtr(PICK_TRIANGLE(1, 3, 4, 5, uvw));
Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id(); Qt3DRender::QPickEventPrivate::get(ev.data())->m_entity = entity->id();
scene2d->handlePickEvent(QEvent::MouseButtonPress, ev); Qt3DRender::QPickEventPrivate::get(ev.data())->m_entityPtr = entity.data();
scene2d->handlePickEvent(QEvent::MouseButtonPress, ev.data());
QCoreApplication::processEvents(); QCoreApplication::processEvents();
// THEN // THEN
QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(96.0f, 896.0f))); QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(96.0, 896.0)));
testWindow->clear(); testWindow->clear();
} }
scene2d.reset();
} }
}; };