diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2018-02-05 13:01:09 +0000 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2018-02-05 15:42:29 +0000 |
commit | 0403ee45736241aa621eb3d38880a4fff571fd96 (patch) | |
tree | 94650145a3b7e2517dfcf29d33f97859933b518d /tests | |
parent | 04afcf1cb9e79697360baa01a97a26815237eba1 (diff) | |
parent | ceae743678d41a58154612781e896c04c87a8c4f (diff) |
Merge remote-tracking branch 'origin/5.9' into 5.10
Conflicts:
.qmake.conf
src/render/backend/trianglesvisitor.cpp
src/render/backend/uniform.cpp
src/render/jobs/calcboundingvolumejob.cpp
src/render/jobs/pickboundingvolumejob.cpp
src/render/jobs/pickboundingvolumeutils.cpp
Change-Id: Ib8305011c51710a3538c0b29f7022388f5244a38
Diffstat (limited to 'tests')
8 files changed, 843 insertions, 51 deletions
diff --git a/tests/auto/core/nodes/tst_nodes.cpp b/tests/auto/core/nodes/tst_nodes.cpp index 49618821c..4998e07d7 100644 --- a/tests/auto/core/nodes/tst_nodes.cpp +++ b/tests/auto/core/nodes/tst_nodes.cpp @@ -81,6 +81,7 @@ private slots: void checkConstructionSetParentMix(); // QTBUG-60612 void checkConstructionWithParent(); + void checkConstructionAsListElement(); void appendingComponentToEntity(); void appendingParentlessComponentToEntity(); @@ -240,6 +241,43 @@ public slots: emit nodePropertyChanged(node); } + void addAttribute(MyQNode *attribute) + { + Qt3DCore::QNodePrivate *d = Qt3DCore::QNodePrivate::get(this); + if (!m_attributes.contains(attribute)) { + m_attributes.append(attribute); + + // Ensures proper bookkeeping + d->registerDestructionHelper(attribute, &MyQNode::removeAttribute, m_attributes); + + // We need to add it as a child of the current node if it has been declared inline + // Or not previously added as a child of the current node so that + // 1) The backend gets notified about it's creation + // 2) When the current node is destroyed, it gets destroyed as well + if (!attribute->parent()) + attribute->setParent(this); + + if (d->m_changeArbiter != nullptr) { + const auto change = Qt3DCore::QPropertyNodeAddedChangePtr::create(id(), attribute); + change->setPropertyName("attribute"); + d->notifyObservers(change); + } + } + } + + void removeAttribute(MyQNode *attribute) + { + Qt3DCore::QNodePrivate *d = Qt3DCore::QNodePrivate::get(this); + if (d->m_changeArbiter != nullptr) { + const auto change = Qt3DCore::QPropertyNodeRemovedChangePtr::create(id(), attribute); + change->setPropertyName("attribute"); + d->notifyObservers(change); + } + m_attributes.removeOne(attribute); + // Remove bookkeeping connection + d->unregisterDestructionHelper(attribute); + } + signals: void customPropertyChanged(); void nodePropertyChanged(MyQNode *node); @@ -247,6 +285,7 @@ signals: protected: QString m_customProperty; MyQNode *m_nodeProperty; + QVector<MyQNode *> m_attributes; }; class MyQEntity : public Qt3DCore::QEntity @@ -921,6 +960,50 @@ void tst_Nodes::checkConstructionWithParent() QCOMPARE(propertyEvent->value().value<Qt3DCore::QNodeId>(), node->id()); } +void tst_Nodes::checkConstructionAsListElement() +{ + // GIVEN + ObserverSpy spy; + Qt3DCore::QScene scene; + QScopedPointer<MyQNode> root(new MyQNode()); + + // WHEN + root->setArbiterAndScene(&spy, &scene); + root->setSimulateBackendCreated(true); + + // THEN + QVERIFY(Qt3DCore::QNodePrivate::get(root.data())->scene() != nullptr); + + // WHEN we create a child and then set it as a Node* property + auto *node = new MyQNode(root.data()); + root->addAttribute(node); + + // THEN we should get one creation change, one child added change + // and one property change event, in that order. + QCoreApplication::processEvents(); + + QCOMPARE(root->children().count(), 1); + QCOMPARE(spy.events.size(), 3); // 1 creation change, 1 child added change, 1 property change + + // Ensure first event is child node's creation change + const auto creationEvent = spy.events.takeFirst().change().dynamicCast<Qt3DCore::QNodeCreatedChangeBase>(); + QVERIFY(!creationEvent.isNull()); + QCOMPARE(creationEvent->subjectId(), node->id()); + + const auto newChildEvent = spy.events.takeFirst().change().dynamicCast<Qt3DCore::QPropertyNodeAddedChange>(); + QVERIFY(!newChildEvent.isNull()); + QCOMPARE(newChildEvent->subjectId(), root->id()); + QCOMPARE(newChildEvent->propertyName(), "children"); + QCOMPARE(newChildEvent->addedNodeId(), node->id()); + + // Ensure second and last event is property set change + const auto propertyEvent = spy.events.takeFirst().change().dynamicCast<Qt3DCore::QPropertyNodeAddedChange>(); + QVERIFY(!propertyEvent.isNull()); + QCOMPARE(propertyEvent->subjectId(), root->id()); + QCOMPARE(propertyEvent->propertyName(), "attribute"); + QCOMPARE(newChildEvent->addedNodeId(), node->id()); +} + void tst_Nodes::appendingParentlessComponentToEntity() { // GIVEN @@ -958,15 +1041,22 @@ void tst_Nodes::appendingParentlessComponentToEntity() // return early in such a case. // Check that we received ComponentAdded - for (const auto event: { entitySpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentAddedChange>(), - componentSpy.events.takeLast().change().dynamicCast<Qt3DCore::QComponentAddedChange>() }) { + const auto event = entitySpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentAddedChange>(); QCOMPARE(event->type(), Qt3DCore::ComponentAdded); QCOMPARE(event->subjectId(), entity->id()); QCOMPARE(event->entityId(), entity->id()); QCOMPARE(event->componentId(), comp->id()); QCOMPARE(event->componentMetaObject(), comp->metaObject()); } + { + const auto event = componentSpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentAddedChange>(); + QCOMPARE(event->type(), Qt3DCore::ComponentAdded); + QCOMPARE(event->subjectId(), comp->id()); + QCOMPARE(event->entityId(), entity->id()); + QCOMPARE(event->componentId(), comp->id()); + QCOMPARE(event->componentMetaObject(), comp->metaObject()); + } } } @@ -997,15 +1087,22 @@ void tst_Nodes::appendingComponentToEntity() QVERIFY(comp->parentNode() == entity.data()); QCOMPARE(entitySpy.events.size(), 1); QVERIFY(entitySpy.events.first().wasLocked()); - for (const auto event: { entitySpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentAddedChange>(), - componentSpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentAddedChange>() }) { + const auto event = entitySpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentAddedChange>(); QCOMPARE(event->type(), Qt3DCore::ComponentAdded); QCOMPARE(event->subjectId(), entity->id()); QCOMPARE(event->entityId(), entity->id()); QCOMPARE(event->componentId(), comp->id()); QCOMPARE(event->componentMetaObject(), comp->metaObject()); } + { + const auto event = componentSpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentAddedChange>(); + QCOMPARE(event->type(), Qt3DCore::ComponentAdded); + QCOMPARE(event->subjectId(), comp->id()); + QCOMPARE(event->entityId(), entity->id()); + QCOMPARE(event->componentId(), comp->id()); + QCOMPARE(event->componentMetaObject(), comp->metaObject()); + } } } @@ -1040,14 +1137,22 @@ void tst_Nodes::removingComponentFromEntity() QCOMPARE(entitySpy.events.size(), 1); QVERIFY(entitySpy.events.first().wasLocked()); QCOMPARE(componentSpy.events.size(), 1); - for (const auto event: { entitySpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentRemovedChange>(), - componentSpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentRemovedChange>() }) { + { + const auto event = entitySpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentRemovedChange>(); QCOMPARE(event->type(), Qt3DCore::ComponentRemoved); QCOMPARE(event->subjectId(), entity->id()); QCOMPARE(event->entityId(), entity->id()); QCOMPARE(event->componentId(), comp->id()); QCOMPARE(event->componentMetaObject(), comp->metaObject()); } + { + const auto event = componentSpy.events.takeFirst().change().dynamicCast<Qt3DCore::QComponentRemovedChange>(); + QCOMPARE(event->type(), Qt3DCore::ComponentRemoved); + QCOMPARE(event->subjectId(), comp->id()); + QCOMPARE(event->entityId(), entity->id()); + QCOMPARE(event->componentId(), comp->id()); + QCOMPARE(event->componentMetaObject(), comp->metaObject()); + } } } diff --git a/tests/auto/render/boundingsphere/tst_boundingsphere.cpp b/tests/auto/render/boundingsphere/tst_boundingsphere.cpp index fcbfaf6ba..620c74641 100644 --- a/tests/auto/render/boundingsphere/tst_boundingsphere.cpp +++ b/tests/auto/render/boundingsphere/tst_boundingsphere.cpp @@ -65,6 +65,8 @@ #include <Qt3DExtras/qcuboidmesh.h> #include <Qt3DExtras/qplanemesh.h> +#include <qbackendnodetester.h> + QT_BEGIN_NAMESPACE namespace Qt3DRender { @@ -100,6 +102,7 @@ public: Qt3DRender::Render::FrameGraphNode *frameGraphRoot() const { return d_func()->m_renderer->frameGraphRoot(); } Qt3DRender::Render::RenderSettings *renderSettings() const { return d_func()->m_renderer->settings(); } Qt3DRender::Render::Entity *sceneRoot() const { return m_sceneRoot; } + Qt3DRender::Render::AbstractRenderer *renderer() const { return d_func()->m_renderer; } private: Render::Entity *m_sceneRoot; @@ -153,7 +156,7 @@ void runRequiredJobs(Qt3DRender::TestAspect *test) } // anonymous -class tst_BoundingSphere : public QObject +class tst_BoundingSphere : public Qt3DCore::QBackendNodeTester { Q_OBJECT private: @@ -194,6 +197,229 @@ private Q_SLOTS: QVERIFY(qAbs(boundingSphere->center().y() - sphereCenter.y()) < 0.000001f); QVERIFY(qAbs(boundingSphere->center().z() - sphereCenter.z()) < 0.000001f); } + + void checkCustomGeometry_data() + { + QTest::addColumn<int>("drawVertexCount"); + QTest::addColumn<int>("indexByteOffset"); + QTest::addColumn<QVector3D>("expectedCenter"); + QTest::addColumn<float>("expectedRadius"); + QTest::newRow("all") << 0 << 0 << QVector3D(-0.488892f, 0.0192147f, -75.4804f) << 25.5442f; + QTest::newRow("first only") << 3 << 0 << QVector3D(0, 1, -100) << 1.0f; + QTest::newRow("second only") << 3 << int(3 * sizeof(ushort)) << QVector3D(0, -1, -50) << 1.0f; + } + + void checkCustomGeometry() + { + QFETCH(int, drawVertexCount); + QFETCH(int, indexByteOffset); + QFETCH(QVector3D, expectedCenter); + QFETCH(float, expectedRadius); + + // two triangles with different Z, and an index buffer + QByteArray vdata; + vdata.resize(6 * 3 * sizeof(float)); + float *vp = reinterpret_cast<float *>(vdata.data()); + *vp++ = -1.0f; + *vp++ = 1.0f; + *vp++ = -100.0f; + *vp++ = 0.0f; + *vp++ = 0.0f; + *vp++ = -100.0f; + *vp++ = 1.0f; + *vp++ = 1.0f; + *vp++ = -100.0f; + + *vp++ = -1.0f; + *vp++ = -1.0f; + *vp++ = -50.0f; + *vp++ = 0.0f; + *vp++ = 0.0f; + *vp++ = -50.0f; + *vp++ = 1.0f; + *vp++ = -1.0f; + *vp++ = -50.0f; + + QByteArray idata; + idata.resize(6 * sizeof(ushort)); + ushort *ip = reinterpret_cast<ushort *>(idata.data()); + *ip++ = 0; + *ip++ = 1; + *ip++ = 2; + *ip++ = 3; + *ip++ = 4; + *ip++ = 5; + + QScopedPointer<Qt3DCore::QEntity> entity(new Qt3DCore::QEntity); + QScopedPointer<Qt3DRender::TestAspect> test(new Qt3DRender::TestAspect(entity.data())); + Qt3DRender::QBuffer *vbuffer = new Qt3DRender::QBuffer; + Qt3DRender::QBuffer *ibuffer = new Qt3DRender::QBuffer; + + vbuffer->setData(vdata); + Qt3DRender::Render::Buffer *vbufferBackend = test->nodeManagers()->bufferManager()->getOrCreateResource(vbuffer->id()); + vbufferBackend->setRenderer(test->renderer()); + vbufferBackend->setManager(test->nodeManagers()->bufferManager()); + simulateInitialization(vbuffer, vbufferBackend); + + ibuffer->setData(idata); + Qt3DRender::Render::Buffer *ibufferBackend = test->nodeManagers()->bufferManager()->getOrCreateResource(ibuffer->id()); + ibufferBackend->setRenderer(test->renderer()); + ibufferBackend->setManager(test->nodeManagers()->bufferManager()); + simulateInitialization(ibuffer, ibufferBackend); + + Qt3DRender::QGeometry *g = new Qt3DRender::QGeometry; + for (int i = 0; i < 2; ++i) + g->addAttribute(new Qt3DRender::QAttribute); + + const QVector<Qt3DRender::QAttribute *> attrs = g->attributes(); + Qt3DRender::QAttribute *attr = attrs[0]; + attr->setBuffer(vbuffer); + attr->setName(Qt3DRender::QAttribute::defaultPositionAttributeName()); + attr->setVertexBaseType(Qt3DRender::QAttribute::Float); + attr->setVertexSize(3); + attr->setCount(6); + attr->setByteOffset(0); + attr->setByteStride(3 * sizeof(float)); + + attr = attrs[1]; + attr->setBuffer(ibuffer); + attr->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); + attr->setVertexBaseType(Qt3DRender::QAttribute::UnsignedShort); + attr->setVertexSize(1); + attr->setCount(6); + attr->setByteOffset(indexByteOffset); + + Qt3DRender::QGeometryRenderer *gr = new Qt3DRender::QGeometryRenderer; + gr->setVertexCount(drawVertexCount); // when 0, indexAttribute->count() is used instead + gr->setGeometry(g); + entity->addComponent(gr); + + Qt3DRender::Render::Attribute *attr0Backend = test->nodeManagers()->attributeManager()->getOrCreateResource(attrs[0]->id()); + attr0Backend->setRenderer(test->renderer()); + simulateInitialization(attrs[0], attr0Backend); + Qt3DRender::Render::Attribute *attr1Backend = test->nodeManagers()->attributeManager()->getOrCreateResource(attrs[1]->id()); + attr1Backend->setRenderer(test->renderer()); + simulateInitialization(attrs[1], attr1Backend); + + Qt3DRender::Render::Geometry *gBackend = test->nodeManagers()->geometryManager()->getOrCreateResource(g->id()); + gBackend->setRenderer(test->renderer()); + simulateInitialization(g, gBackend); + + Qt3DRender::Render::GeometryRenderer *grBackend = test->nodeManagers()->geometryRendererManager()->getOrCreateResource(gr->id()); + grBackend->setRenderer(test->renderer()); + grBackend->setManager(test->nodeManagers()->geometryRendererManager()); + simulateInitialization(gr, grBackend); + + Qt3DRender::Render::Entity *entityBackend = test->nodeManagers()->renderNodesManager()->getOrCreateResource(entity->id()); + entityBackend->setRenderer(test->renderer()); + simulateInitialization(entity.data(), entityBackend); + + Qt3DRender::Render::CalculateBoundingVolumeJob calcBVolume; + calcBVolume.setManagers(test->nodeManagers()); + calcBVolume.setRoot(test->sceneRoot()); + calcBVolume.run(); + + Vector3D center = entityBackend->localBoundingVolume()->center(); + float radius = entityBackend->localBoundingVolume()->radius(); + qDebug() << radius << center; + + // truncate and compare integers only + QVERIFY(int(radius) == int(expectedRadius)); + QVERIFY(int(center.x()) == int(expectedCenter.x())); + QVERIFY(int(center.y()) == int(expectedCenter.y())); + QVERIFY(int(center.z()) == int(expectedCenter.z())); + } + + void checkCustomPackedGeometry() + { + int drawVertexCount = 6; + QVector3D expectedCenter(-0.488892f, 0.0192147f, -75.4804f); + float expectedRadius = 25.5442f; + + // two triangles with different Z + QByteArray vdata; + vdata.resize(6 * 3 * sizeof(float)); + float *vp = reinterpret_cast<float *>(vdata.data()); + *vp++ = -1.0f; + *vp++ = 1.0f; + *vp++ = -100.0f; + *vp++ = 0.0f; + *vp++ = 0.0f; + *vp++ = -100.0f; + *vp++ = 1.0f; + *vp++ = 1.0f; + *vp++ = -100.0f; + + *vp++ = -1.0f; + *vp++ = -1.0f; + *vp++ = -50.0f; + *vp++ = 0.0f; + *vp++ = 0.0f; + *vp++ = -50.0f; + *vp++ = 1.0f; + *vp++ = -1.0f; + *vp++ = -50.0f; + + QScopedPointer<Qt3DCore::QEntity> entity(new Qt3DCore::QEntity); + QScopedPointer<Qt3DRender::TestAspect> test(new Qt3DRender::TestAspect(entity.data())); + Qt3DRender::QBuffer *vbuffer = new Qt3DRender::QBuffer; + + vbuffer->setData(vdata); + Qt3DRender::Render::Buffer *vbufferBackend = test->nodeManagers()->bufferManager()->getOrCreateResource(vbuffer->id()); + vbufferBackend->setRenderer(test->renderer()); + vbufferBackend->setManager(test->nodeManagers()->bufferManager()); + simulateInitialization(vbuffer, vbufferBackend); + + Qt3DRender::QGeometry *g = new Qt3DRender::QGeometry; + g->addAttribute(new Qt3DRender::QAttribute); + + const QVector<Qt3DRender::QAttribute *> attrs = g->attributes(); + Qt3DRender::QAttribute *attr = attrs[0]; + attr->setBuffer(vbuffer); + attr->setName(Qt3DRender::QAttribute::defaultPositionAttributeName()); + attr->setVertexBaseType(Qt3DRender::QAttribute::Float); + attr->setVertexSize(3); + attr->setCount(6); + attr->setByteOffset(0); + attr->setByteStride(0); + + Qt3DRender::QGeometryRenderer *gr = new Qt3DRender::QGeometryRenderer; + gr->setVertexCount(drawVertexCount); + gr->setGeometry(g); + entity->addComponent(gr); + + Qt3DRender::Render::Attribute *attr0Backend = test->nodeManagers()->attributeManager()->getOrCreateResource(attrs[0]->id()); + attr0Backend->setRenderer(test->renderer()); + simulateInitialization(attrs[0], attr0Backend); + + Qt3DRender::Render::Geometry *gBackend = test->nodeManagers()->geometryManager()->getOrCreateResource(g->id()); + gBackend->setRenderer(test->renderer()); + simulateInitialization(g, gBackend); + + Qt3DRender::Render::GeometryRenderer *grBackend = test->nodeManagers()->geometryRendererManager()->getOrCreateResource(gr->id()); + grBackend->setRenderer(test->renderer()); + grBackend->setManager(test->nodeManagers()->geometryRendererManager()); + simulateInitialization(gr, grBackend); + + Qt3DRender::Render::Entity *entityBackend = test->nodeManagers()->renderNodesManager()->getOrCreateResource(entity->id()); + entityBackend->setRenderer(test->renderer()); + simulateInitialization(entity.data(), entityBackend); + + Qt3DRender::Render::CalculateBoundingVolumeJob calcBVolume; + calcBVolume.setManagers(test->nodeManagers()); + calcBVolume.setRoot(test->sceneRoot()); + calcBVolume.run(); + + Vector3D center = entityBackend->localBoundingVolume()->center(); + float radius = entityBackend->localBoundingVolume()->radius(); + qDebug() << radius << center; + + // truncate and compare integers only + QVERIFY(int(radius) == int(expectedRadius)); + QVERIFY(int(center.x()) == int(expectedCenter.x())); + QVERIFY(int(center.y()) == int(expectedCenter.y())); + QVERIFY(int(center.z()) == int(expectedCenter.z())); + } }; QTEST_MAIN(tst_BoundingSphere) diff --git a/tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc b/tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc index c2b0c7fff..feef480e2 100644 --- a/tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc +++ b/tests/auto/render/pickboundingvolumejob/pickboundingvolumejob.qrc @@ -8,5 +8,7 @@ <file>testscene_pickersdisabled.qml</file> <file>testscene_dragenabledoverlapping.qml</file> <file>testscene_parententity.qml</file> + <file>testscene_viewports.qml</file> + <file>testscene_cameraposition.qml</file> </qresource> </RCC> diff --git a/tests/auto/render/pickboundingvolumejob/testscene_cameraposition.qml b/tests/auto/render/pickboundingvolumejob/testscene_cameraposition.qml new file mode 100644 index 000000000..87e7a8aac --- /dev/null +++ b/tests/auto/render/pickboundingvolumejob/testscene_cameraposition.qml @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt3D.Core 2.0 +import Qt3D.Render 2.0 +import Qt3D.Extras 2.0 +import QtQuick.Window 2.0 + +Entity { + id: sceneRoot + + Window { + id: win + width: 600 + height: 600 + visible: true + } + + Camera { + id: camera + projectionType: CameraLens.PerspectiveProjection + fieldOfView: 45 + nearPlane : 0.1 + farPlane : 1000.0 + position: Qt.vector3d( 0.0, 0.0, -40.0 ) + upVector: Qt.vector3d( 0.0, 1.0, 0.0 ) + viewCenter: Qt.vector3d( 5.0, 3.0, 1.0 ) + } + + components: [ + RenderSettings { + Viewport { + normalizedRect: Qt.rect(0.0, 0.0, 1.0, 1.0) + + RenderSurfaceSelector { + + surface: win + + ClearBuffers { + buffers : ClearBuffers.ColorDepthBuffer + NoDraw {} + } + + CameraSelector { + camera: camera + } + } + } + } + ] + + CuboidMesh { id: cubeMesh } + PhongMaterial { id: material } + + Entity { + property ObjectPicker picker: ObjectPicker { + objectName: "Picker" + } + + property Transform transform: Transform { + translation: camera.viewCenter + scale: 2.0 + } + + components: [cubeMesh, material, picker, transform] + } + +} diff --git a/tests/auto/render/pickboundingvolumejob/testscene_viewports.qml b/tests/auto/render/pickboundingvolumejob/testscene_viewports.qml new file mode 100644 index 000000000..daafc0edd --- /dev/null +++ b/tests/auto/render/pickboundingvolumejob/testscene_viewports.qml @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt3D.Core 2.0 +import Qt3D.Render 2.0 +import Qt3D.Extras 2.0 +import QtQuick.Window 2.0 + +Entity { + id: sceneRoot + + Window { + id: _view + width: 600 + height: 600 + visible: true + } + + Camera { + id: camera + projectionType: CameraLens.PerspectiveProjection + fieldOfView: 45 + aspectRatio: _view.width / 2 / _view.height + nearPlane : 0.1 + farPlane : 1000.0 + position: Qt.vector3d( 0.0, 0.0, -10.0 ) + upVector: Qt.vector3d( 0.0, 1.0, 0.0 ) + viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 ) + } + + Camera { + id: camera2 + projectionType: CameraLens.PerspectiveProjection + fieldOfView: 45 + aspectRatio: _view.width / _view.height + nearPlane : 0.1 + farPlane : 1000.0 + position: Qt.vector3d( 0.0, 0.0, -20.0 ) + upVector: Qt.vector3d( 0.0, 1.0, 0.0 ) + viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 ) + } + + FirstPersonCameraController { + camera: camera + } + + DirectionalLight { + worldDirection: camera.viewVector.times(-1) + } + + // Draw 2 viewports + // one with the content, the other with content + debug volumes + components: [ + RenderSettings { + Viewport { + normalizedRect: Qt.rect(0.0, 0.0, 1.0, 1.0) + + RenderSurfaceSelector { + surface: _view + + Viewport { + normalizedRect: Qt.rect(0.0, 0.0, 0.5, 1.0) + ClearBuffers { + buffers : ClearBuffers.ColorDepthBuffer + clearColor: "white" + CameraSelector { + camera: camera + } + } + } + + Viewport { + normalizedRect: Qt.rect(0.5, 0.0, 0.5, 1.0) + CameraSelector { + camera: camera2 + } + } + } + } + } + ] + + CuboidMesh { id: cubeMesh } + + Entity { + readonly property ObjectPicker objectPicker: ObjectPicker { + onClicked: console.log("o1") + } + readonly property Transform transform: Transform { + scale: 3 + translation: Qt.vector3d(3, 0, 0) + } + readonly property PhongMaterial material: PhongMaterial { diffuse: "red" } + + components: [cubeMesh, transform, material, objectPicker ] + } + + Entity { + readonly property ObjectPicker objectPicker: ObjectPicker { + objectName: "Picker2" + onClicked: console.log("o2") + } + readonly property Transform transform: Transform { + scale: 3 + translation: Qt.vector3d(-3, 0, 0) + } + readonly property PhongMaterial material: PhongMaterial { diffuse: "green" } + + components: [cubeMesh, transform, material, objectPicker ] + } +} diff --git a/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp b/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp index a14bccefc..b86df05a4 100644 --- a/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp +++ b/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp @@ -234,7 +234,7 @@ private Q_SLOTS: // WHEN Qt3DRender::Render::PickingUtils::ViewportCameraAreaGatherer gatherer; - QVector<Qt3DRender::Render::PickingUtils::ViewportCameraAreaTriplet> results = gatherer.gather(test->frameGraphRoot()); + QVector<Qt3DRender::Render::PickingUtils::ViewportCameraAreaDetails> results = gatherer.gather(test->frameGraphRoot()); // THEN QCOMPARE(results.size(), 1); @@ -329,8 +329,8 @@ private Q_SLOTS: QVERIFY(pickBVJob.currentPicker().isNull()); // WHEN - QList<QMouseEvent> events; - events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + QList<QPair<QObject *,QMouseEvent>> events; + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); bool earlyReturn = !pickBVJob.runHelper(); @@ -343,7 +343,7 @@ private Q_SLOTS: // WHEN events.clear(); - events.push_back(QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); earlyReturn = !pickBVJob.runHelper(); @@ -353,7 +353,7 @@ private Q_SLOTS: // WHEN events.clear(); - events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(390.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(390.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); earlyReturn = !pickBVJob.runHelper(); @@ -366,7 +366,7 @@ private Q_SLOTS: // WHEN events.clear(); - events.push_back(QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(390.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(390.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); earlyReturn = !pickBVJob.runHelper(); @@ -425,8 +425,9 @@ private Q_SLOTS: QVERIFY(earlyReturn); // WHEN - QList<QMouseEvent> events; - events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(400.0f, 440.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + QList<QPair<QObject *, QMouseEvent>> events; + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(400.0f, 440.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); earlyReturn = !pickBVJob.runHelper(); @@ -474,8 +475,9 @@ private Q_SLOTS: Qt3DRender::Render::PickBoundingVolumeJob pickBVJob; initializePickBoundingVolumeJob(&pickBVJob, test.data()); - QList<QMouseEvent> events; - events.push_back(QMouseEvent(QMouseEvent::MouseMove, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + QList<QPair<QObject *, QMouseEvent>> events; + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseMove, QPointF(207.0f, 303.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); // THEN @@ -530,9 +532,9 @@ private Q_SLOTS: Qt3DRender::Render::PickBoundingVolumeJob pickBVJob; initializePickBoundingVolumeJob(&pickBVJob, test.data()); - QList<QMouseEvent> events; - events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), - Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + QList<QPair<QObject *, QMouseEvent>> events; + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); bool earlyReturn = !pickBVJob.runHelper(); @@ -580,8 +582,9 @@ private Q_SLOTS: Qt3DRender::Render::PickBoundingVolumeJob pickBVJob; initializePickBoundingVolumeJob(&pickBVJob, test.data()); - QList<QMouseEvent> events; - events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + QList<QPair<QObject *, QMouseEvent>> events; + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); bool earlyReturn = !pickBVJob.runHelper(); @@ -591,7 +594,8 @@ private Q_SLOTS: // WHEN events.clear(); - events.push_back(QMouseEvent(QMouseEvent::MouseMove, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseMove, QPointF(207.0f, 303.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); earlyReturn = !pickBVJob.runHelper(); @@ -639,8 +643,9 @@ private Q_SLOTS: Qt3DRender::Render::PickBoundingVolumeJob pickBVJob; initializePickBoundingVolumeJob(&pickBVJob, test.data()); - QList<QMouseEvent> events; - events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + QList<QPair<QObject *, QMouseEvent>> events; + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); bool earlyReturn = !pickBVJob.runHelper(); @@ -650,7 +655,8 @@ private Q_SLOTS: // WHEN events.clear(); - events.push_back(QMouseEvent(QMouseEvent::MouseMove, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseMove, QPointF(207.0f, 303.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); earlyReturn = !pickBVJob.runHelper(); @@ -698,8 +704,9 @@ private Q_SLOTS: Qt3DRender::Render::PickBoundingVolumeJob pickBVJob; initializePickBoundingVolumeJob(&pickBVJob, test.data()); - QList<QMouseEvent> events; - events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + QList<QPair<QObject *, QMouseEvent>> events; + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); const bool earlyReturn = !pickBVJob.runHelper(); @@ -764,8 +771,9 @@ private Q_SLOTS: Qt3DRender::Render::PickBoundingVolumeJob pickBVJob; initializePickBoundingVolumeJob(&pickBVJob, test.data()); - QList<QMouseEvent> events; - events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + QList<QPair<QObject *, QMouseEvent>> events; + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); bool earlyReturn = !pickBVJob.runHelper(); @@ -785,7 +793,8 @@ private Q_SLOTS: // WHEN -> Move on same object events.clear(); - events.push_back(QMouseEvent(QMouseEvent::MouseMove, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseMove, QPointF(207.0f, 303.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); earlyReturn = !pickBVJob.runHelper(); @@ -805,7 +814,8 @@ private Q_SLOTS: // WHEN -> Release on object events.clear(); - events.push_back(QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(207.0f, 303.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); earlyReturn = !pickBVJob.runHelper(); @@ -832,8 +842,10 @@ private Q_SLOTS: // WHEN -> Release outside of object events.clear(); - events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); - events.push_back(QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(0.0f, 0.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(0.0f, 0.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); earlyReturn = !pickBVJob.runHelper(); @@ -900,8 +912,9 @@ private Q_SLOTS: Qt3DRender::Render::PickBoundingVolumeJob pickBVJob; initializePickBoundingVolumeJob(&pickBVJob, test.data()); - QList<QMouseEvent> events; - events.push_back(QMouseEvent(QMouseEvent::HoverMove, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + QList<QPair<QObject *, QMouseEvent>> events; + events.push_back({nullptr, QMouseEvent(QMouseEvent::HoverMove, QPointF(207.0f, 303.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); bool earlyReturn = !pickBVJob.runHelper(); @@ -916,7 +929,8 @@ private Q_SLOTS: // WHEN -> HoverMove Out events.clear(); - events.push_back(QMouseEvent(QEvent::HoverMove, QPointF(20.0f, 40.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + events.push_back({nullptr, QMouseEvent(QEvent::HoverMove, QPointF(20.0f, 40.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); earlyReturn = !pickBVJob.runHelper(); @@ -931,8 +945,10 @@ private Q_SLOTS: // WHEN -> HoverMove In + Pressed other events.clear(); - events.push_back(QMouseEvent(QEvent::HoverMove, QPointF(207.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); - events.push_back(QMouseEvent(QEvent::MouseButtonPress, QPointF(0.0f, 0.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + events.push_back({nullptr, QMouseEvent(QEvent::HoverMove, QPointF(207.0f, 303.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); + events.push_back({nullptr, QMouseEvent(QEvent::MouseButtonPress, QPointF(0.0f, 0.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); earlyReturn = !pickBVJob.runHelper(); @@ -1001,8 +1017,9 @@ private Q_SLOTS: Qt3DRender::Render::PickBoundingVolumeJob pickBVJob; initializePickBoundingVolumeJob(&pickBVJob, test.data()); - QList<QMouseEvent> events; - events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(400.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + QList<QPair<QObject *, QMouseEvent>> events; + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(400.0f, 300.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); bool earlyReturn = !pickBVJob.runHelper(); @@ -1017,7 +1034,8 @@ private Q_SLOTS: // WHEN -> Move on same object events.clear(); - events.push_back(QMouseEvent(QMouseEvent::MouseMove, QPointF(400.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseMove, QPointF(400.0f, 300.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); earlyReturn = !pickBVJob.runHelper(); @@ -1032,7 +1050,8 @@ private Q_SLOTS: // WHEN -> Release on object events.clear(); - events.push_back(QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(400.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(400.0f, 300.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); earlyReturn = !pickBVJob.runHelper(); @@ -1049,8 +1068,10 @@ private Q_SLOTS: // WHEN -> Release outside of object events.clear(); - events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(400.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); - events.push_back(QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(0.0f, 0.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(400.0f, 300.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(0.0f, 0.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); earlyReturn = !pickBVJob.runHelper(); @@ -1126,8 +1147,9 @@ private Q_SLOTS: Qt3DRender::Render::PickBoundingVolumeJob pickBVJob; initializePickBoundingVolumeJob(&pickBVJob, test.data()); - QList<QMouseEvent> events; - events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(320.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + QList<QPair<QObject *, QMouseEvent>> events; + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(320.0f, 303.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); bool earlyReturn = !pickBVJob.runHelper(); @@ -1141,7 +1163,8 @@ private Q_SLOTS: // WHEN -> Move on next object, show stay on previous picker unless all picks are requested events.clear(); - events.push_back(QMouseEvent(QMouseEvent::MouseMove, QPointF(280.0f, 303.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseMove, QPointF(280.0f, 303.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); earlyReturn = !pickBVJob.runHelper(); @@ -1200,8 +1223,9 @@ private Q_SLOTS: Qt3DRender::Render::PickBoundingVolumeJob pickBVJob; initializePickBoundingVolumeJob(&pickBVJob, test.data()); - QList<QMouseEvent> events; - events.push_back(QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(400.0f, 300.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); + QList<QPair<QObject *, QMouseEvent>> events; + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(400.0f, 300.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); pickBVJob.setMouseEvents(events); bool earlyReturn = !pickBVJob.runHelper(); @@ -1212,6 +1236,155 @@ private Q_SLOTS: Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); QCOMPARE(change->propertyName(), "pressed"); } + + void checkPickerAndViewports() + { + // GIVEN + QmlSceneReader sceneReader(QUrl("qrc:/testscene_viewports.qml")); + QScopedPointer<Qt3DCore::QNode> root(qobject_cast<Qt3DCore::QNode *>(sceneReader.root())); + QVERIFY(root); + + QList<Qt3DRender::QRenderSettings *> renderSettings = root->findChildren<Qt3DRender::QRenderSettings *>(); + QCOMPARE(renderSettings.size(), 1); + Qt3DRender::QPickingSettings *settings = renderSettings.first()->pickingSettings(); + + settings->setPickMethod(Qt3DRender::QPickingSettings::TrianglePicking); + settings->setPickResultMode(Qt3DRender::QPickingSettings::NearestPick); + settings->setFaceOrientationPickingMode(Qt3DRender::QPickingSettings::FrontFace); + + QScopedPointer<Qt3DRender::TestAspect> test(new Qt3DRender::TestAspect(root.data())); + TestArbiter arbiter; + + // Runs Required jobs + runRequiredJobs(test.data()); + + // THEN + // object partially obscured by another viewport, make sure only visible portion is pickable + QList<Qt3DRender::QObjectPicker *> pickers = root->findChildren<Qt3DRender::QObjectPicker *>(); + QCOMPARE(pickers.size(), 2); + + Qt3DRender::QObjectPicker *picker = pickers.last(); + QCOMPARE(picker->objectName(), QLatin1String("Picker2")); + + Qt3DRender::Render::ObjectPicker *backendPicker = test->nodeManagers()->objectPickerManager()->lookupResource(picker->id()); + QVERIFY(backendPicker); + Qt3DCore::QBackendNodePrivate::get(backendPicker)->setArbiter(&arbiter); + + // WHEN -> Pressed on object in vp1 + Qt3DRender::Render::PickBoundingVolumeJob pickBVJob; + initializePickBoundingVolumeJob(&pickBVJob, test.data()); + + QList<QPair<QObject *, QMouseEvent>> events; + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(280.0f, 300.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); + pickBVJob.setMouseEvents(events); + bool earlyReturn = !pickBVJob.runHelper(); + + // THEN -> Pressed + QVERIFY(!earlyReturn); + QVERIFY(backendPicker->isPressed()); + QCOMPARE(arbiter.events.count(), 1); + Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "pressed"); + + // WHEN reset -> Presset on object in vp2 + backendPicker->cleanup(); + backendPicker->setEnabled(true); + events.clear(); + arbiter.events.clear(); + + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(320.0f, 300.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); + pickBVJob.setMouseEvents(events); + earlyReturn = !pickBVJob.runHelper(); + + // THEN -> Nothing happened + QVERIFY(!earlyReturn); + QVERIFY(!backendPicker->isPressed()); + QCOMPARE(arbiter.events.count(), 0); + } + + void checkMultipleRayDirections_data() + { + QTest::addColumn<QVector3D>("cameraOrigin"); + QTest::addColumn<QVector3D>("cameraUpVector"); + + int k = 0; + const int n = 10; + for (int j=0; j<n; j++) { + QMatrix4x4 m; + m.rotate(360.f / (float)n * (float)j, 0.f, 0.f, 1.f); + for (int i=0; i<n; i++) { + const double angle = M_PI * 2. / (double)n * i; + const double x = std::sin(angle) * 10.; + const double z = std::cos(angle) * 10.; + QVector3D pos(x, 0, z); + QVector3D up(0, 1, 0); + QTest::newRow(QString::number(k++).toLatin1().data()) << m * pos << m * up; + } + } + } + + void checkMultipleRayDirections() + { + // GIVEN + QmlSceneReader sceneReader(QUrl("qrc:/testscene_cameraposition.qml")); + QScopedPointer<Qt3DCore::QNode> root(qobject_cast<Qt3DCore::QNode *>(sceneReader.root())); + QVERIFY(root); + + QList<Qt3DRender::QRenderSettings *> renderSettings = root->findChildren<Qt3DRender::QRenderSettings *>(); + QCOMPARE(renderSettings.size(), 1); + Qt3DRender::QPickingSettings *settings = renderSettings.first()->pickingSettings(); + + settings->setPickMethod(Qt3DRender::QPickingSettings::TrianglePicking); + + QScopedPointer<Qt3DRender::TestAspect> test(new Qt3DRender::TestAspect(root.data())); + TestArbiter arbiter; + + QList<Qt3DRender::QCamera *> cameras = root->findChildren<Qt3DRender::QCamera *>(); + QCOMPARE(cameras.size(), 1); + Qt3DRender::QCamera *camera = cameras.first(); + + QFETCH(QVector3D, cameraUpVector); + camera->setUpVector(cameraUpVector); + + QFETCH(QVector3D, cameraOrigin); + camera->setPosition(cameraOrigin); + + // Runs Required jobs + runRequiredJobs(test.data()); + + // THEN + QList<Qt3DRender::QObjectPicker *> pickers = root->findChildren<Qt3DRender::QObjectPicker *>(); + QCOMPARE(pickers.size(), 1); + + Qt3DRender::QObjectPicker *picker = pickers.front(); + + Qt3DRender::Render::ObjectPicker *backendPicker = test->nodeManagers()->objectPickerManager()->lookupResource(picker->id()); + QVERIFY(backendPicker); + Qt3DCore::QBackendNodePrivate::get(backendPicker)->setArbiter(&arbiter); + + // WHEN -> Pressed on object + Qt3DRender::Render::PickBoundingVolumeJob pickBVJob; + initializePickBoundingVolumeJob(&pickBVJob, test.data()); + + QList<QPair<QObject *, QMouseEvent>> events; + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(303.0f, 303.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); + pickBVJob.setMouseEvents(events); + bool earlyReturn = !pickBVJob.runHelper(); + + // THEN -> Pressed + QVERIFY(!earlyReturn); + QVERIFY(backendPicker->isPressed()); + Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "pressed"); + Qt3DRender::QPickEventPtr pickEvent = change->value().value<Qt3DRender::QPickEventPtr>(); + QVERIFY(pickEvent); + + arbiter.events.clear(); + } + }; QTEST_MAIN(tst_PickBoundingVolumeJob) diff --git a/tests/auto/render/shadercache/tst_shadercache.cpp b/tests/auto/render/shadercache/tst_shadercache.cpp index 1c70d4405..49628ef0f 100644 --- a/tests/auto/render/shadercache/tst_shadercache.cpp +++ b/tests/auto/render/shadercache/tst_shadercache.cpp @@ -131,6 +131,19 @@ void tst_ShaderCache::value() auto dnaC = ProgramDNA(54321); auto uncachedProgram = cache.getShaderProgramAndAddRef(dnaC, nodeIdB); QVERIFY(uncachedProgram == nullptr); + + cache.clear(); + // Test inserting nullptr. + cache.insert(dnaA, nodeIdA, nullptr); + bool wasPresent = false; + cachedProgramA = cache.getShaderProgramAndAddRef(dnaA, nodeIdA, &wasPresent); + QCOMPARE(wasPresent, true); + QCOMPARE(cachedProgramA, nullptr); + cache.clear(); + // Test wasPresent==false. + cachedProgramB = cache.getShaderProgramAndAddRef(dnaB, nodeIdB, &wasPresent); + QCOMPARE(wasPresent, false); + QCOMPARE(cachedProgramB, nullptr); } void tst_ShaderCache::removeRef() diff --git a/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp b/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp index 6a9be5e13..4205d598e 100644 --- a/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp +++ b/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp @@ -194,7 +194,7 @@ private Q_SLOTS: positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); positionAttribute->setVertexSize(3); positionAttribute->setCount(6); - positionAttribute->setByteStride(3*4); + positionAttribute->setByteStride(0); positionAttribute->setByteOffset(0); positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); geometry->addAttribute(positionAttribute.data()); |