From c0c856168efa470d31d7261324dc1e94d4d99612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A4=C3=A4tt=C3=A4=20Antti?= Date: Thu, 6 Apr 2017 09:45:31 +0300 Subject: Fix rendercapture-cpp example crash when using continuous capture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Disallow multiple simultanious captures. Task-number: QTBUG-59456 Change-Id: Ice7cb854a9a7090664ff5a24f332cb28eba6359e Reviewed-by: Paul Lemire Reviewed-by: Juan José Casafranca Reviewed-by: Antti Määttä --- tests/manual/rendercapture-cpp/mycapture.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/manual/rendercapture-cpp/mycapture.h b/tests/manual/rendercapture-cpp/mycapture.h index e142a5453..fea1abe46 100644 --- a/tests/manual/rendercapture-cpp/mycapture.h +++ b/tests/manual/rendercapture-cpp/mycapture.h @@ -89,9 +89,11 @@ public slots: void capture() { - m_reply = m_capture->requestCapture(); - connection = QObject::connect(m_reply, &Qt3DRender::QRenderCaptureReply::completed, - this, &MyCapture::onCompleted); + if (!m_reply) { + m_reply = m_capture->requestCapture(); + connection = QObject::connect(m_reply, &Qt3DRender::QRenderCaptureReply::completed, + this, &MyCapture::onCompleted); + } } private: -- cgit v1.2.3 From ba060af041dc866c80f89b64a2bf87d6085f995f Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 18 Apr 2017 14:34:55 +0200 Subject: tst_GraphicsHelperGL3_3::blitFramebuffer(): check how many samples are supported We can't just generate a multisampled 2D texture with 4 samples per texel; we need to check the implementation-defined maximum amount of samples. Lacking glGetInternalformat*, query GL_MAX_SAMPLES. Since OpenGL does not mandate a minimum, getting 0 is actually allowed; glTexImage2DMultisample however does not accept 0 as number of samples, hence skip the test in that case. Change-Id: Id1b0c9705aed0665093aae44983eac8b656b676f Task-number: QTBUG-59828 Reviewed-by: Sean Harmer --- tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp b/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp index 293750dbf..58c12fcc9 100644 --- a/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp +++ b/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp @@ -1967,6 +1967,11 @@ private Q_SLOTS: if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 3.3 Core functions not supported"); + GLint maxSamples; + m_func->glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); + if (maxSamples < 1) + QSKIP("This test requires an implementation that supports multisampled textures"); + // GIVEN GLuint fbos[2]; GLuint fboTextures[2]; @@ -1975,7 +1980,7 @@ private Q_SLOTS: m_func->glGenTextures(2, fboTextures); m_func->glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, fboTextures[0]); - m_func->glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, 10, 10, true); + m_func->glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, maxSamples, GL_RGBA8, 10, 10, true); m_func->glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); m_func->glBindTexture(GL_TEXTURE_2D, fboTextures[1]); -- cgit v1.2.3 From 50712f797527b6519ec22e5f1a4b5a939152c798 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 18 Apr 2017 14:34:55 +0200 Subject: tst_GraphicsHelperGL3_3: remove blacklist of blitFramebuffer Got fixed in the meanwhile. Change-Id: I3efccd988b39b77bebab628bbf637b302a247cef Task-number: QTBUG-59828 Reviewed-by: Sean Harmer --- tests/auto/render/graphicshelpergl3_3/BLACKLIST | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 tests/auto/render/graphicshelpergl3_3/BLACKLIST diff --git a/tests/auto/render/graphicshelpergl3_3/BLACKLIST b/tests/auto/render/graphicshelpergl3_3/BLACKLIST deleted file mode 100644 index 1d6233cd7..000000000 --- a/tests/auto/render/graphicshelpergl3_3/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[blitFramebuffer] -ubuntu-16.04 -- cgit v1.2.3 From 30abb904d42de5423749170c0de6e497d2aaf76e Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 18 Apr 2017 15:40:16 +0200 Subject: tst_GraphicsHelperGL3_2::blitFramebuffer(): check how many samples are supported Apply the same fix as tst_GraphicsHelperGL3_3. Unblacklist the test, since it now passes. Change-Id: I72bde506c3c6c802ed30acf40e10013f01e69de3 Task-number: QTBUG-59921 Reviewed-by: Sean Harmer --- tests/auto/render/graphicshelpergl3_2/BLACKLIST | 2 -- tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp | 7 ++++++- 2 files changed, 6 insertions(+), 3 deletions(-) delete mode 100644 tests/auto/render/graphicshelpergl3_2/BLACKLIST diff --git a/tests/auto/render/graphicshelpergl3_2/BLACKLIST b/tests/auto/render/graphicshelpergl3_2/BLACKLIST deleted file mode 100644 index 1d6233cd7..000000000 --- a/tests/auto/render/graphicshelpergl3_2/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[blitFramebuffer] -ubuntu-16.04 diff --git a/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp b/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp index fb0265427..7e24d22c7 100644 --- a/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp +++ b/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp @@ -1867,6 +1867,11 @@ private Q_SLOTS: if (!m_initializationSuccessful) QSKIP("Initialization failed, OpenGL 3.2 Core functions not supported"); + GLint maxSamples; + m_func->glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); + if (maxSamples < 1) + QSKIP("This test requires an implementation that supports multisampled textures"); + // GIVEN GLuint fbos[2]; GLuint fboTextures[2]; @@ -1875,7 +1880,7 @@ private Q_SLOTS: m_func->glGenTextures(2, fboTextures); m_func->glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, fboTextures[0]); - m_func->glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, 10, 10, true); + m_func->glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, maxSamples, GL_RGBA8, 10, 10, true); m_func->glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); m_func->glBindTexture(GL_TEXTURE_2D, fboTextures[1]); -- cgit v1.2.3 From a2b7483fa18e109011246fba5e7963338a77af56 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 18 Apr 2017 12:11:01 +0200 Subject: Try to investigate why tst_GraphicsHelperGL3_3::blitFramebuffer() fails Change-Id: Ide10e84479bdcfea71c29cd46b8a29199574d856 Task-number: QTBUG-59828 Reviewed-by: Sean Harmer --- tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp b/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp index 58c12fcc9..cdca5676b 100644 --- a/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp +++ b/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp @@ -1991,13 +1991,13 @@ private Q_SLOTS: m_func->glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, fboTextures[1], 0); GLenum status = m_func->glCheckFramebufferStatus(GL_FRAMEBUFFER); - QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); + QCOMPARE(status, GLenum(GL_FRAMEBUFFER_COMPLETE)); m_func->glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]); m_func->glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, fboTextures[0], 0); status = m_func->glCheckFramebufferStatus(GL_FRAMEBUFFER); - QVERIFY(status == GL_FRAMEBUFFER_COMPLETE); + QCOMPARE(status, GLenum(GL_FRAMEBUFFER_COMPLETE)); m_func->glEnable(GL_MULTISAMPLE); m_func->glClearColor(0.2f, 0.2f, 0.2f, 0.2f); -- cgit v1.2.3 From df4b063c5b988a63d871d4ac101c77a928791f43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A4=C3=A4tt=C3=A4=20Antti?= Date: Thu, 20 Apr 2017 08:52:14 +0300 Subject: Add config_help.txt to Qt3D Add config help to specify what configurations Qt3D uses and what do they do. Change-Id: I280f5702d304a0f60111389a991778a0616f7fc2 Reviewed-by: Paul Lemire --- config_help.txt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 config_help.txt diff --git a/config_help.txt b/config_help.txt new file mode 100644 index 000000000..8aeed3007 --- /dev/null +++ b/config_help.txt @@ -0,0 +1,5 @@ +Qt3D options: + + -assimp .............. Select used assimp library [system/qt/no] + -qt3d-profile-jobs ... Enable jobs profiling [no] + -qt3d-profile-gl ..... Enable OpenGL profiling [no] -- cgit v1.2.3 From 21d891722cbaa18f6352804d5b4a3d4cf6911c41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Casafranca?= Date: Mon, 24 Apr 2017 12:32:45 +0200 Subject: Verify a texture is valid before update Texture images may be deleted before the texture it references to them. This happens when the texture is added and removed very fast. Verify all the texture images that the texture reference still exist before updating the texture. Task-number: QTBUG-59418 Change-Id: Idacbdd1a45eb0fa5b871d57688e9d02b823f7b5f Reviewed-by: Paul Lemire --- src/render/backend/renderer.cpp | 5 +++++ src/render/texture/texture.cpp | 10 ++++++++++ src/render/texture/texture_p.h | 1 + 3 files changed, 16 insertions(+) diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp index 0fda6e5b4..42909d8be 100644 --- a/src/render/backend/renderer.cpp +++ b/src/render/backend/renderer.cpp @@ -1061,6 +1061,11 @@ void Renderer::updateGLResources() // Render Thread void Renderer::updateTexture(Texture *texture) { + // Check that the current texture images are still in place, if not, do not update + const bool isValid = texture->isValid(); + if (!isValid) + return; + // For implementing unique, non-shared, non-cached textures. // for now, every texture is shared by default diff --git a/src/render/texture/texture.cpp b/src/render/texture/texture.cpp index 8dd9ad229..13991ec4a 100644 --- a/src/render/texture/texture.cpp +++ b/src/render/texture/texture.cpp @@ -246,6 +246,16 @@ void Texture::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) BackendNode::sceneChangeEvent(e); } +bool Texture::isValid() const +{ + for (const auto handle : m_textureImages) { + TextureImage *img = m_textureImageManager->data(handle); + if (img == nullptr) + return false; + } + return true; +} + void Texture::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) { const auto typedChange = qSharedPointerCast>(change); diff --git a/src/render/texture/texture_p.h b/src/render/texture/texture_p.h index f99d1d38b..4fe4e2c7c 100644 --- a/src/render/texture/texture_p.h +++ b/src/render/texture/texture_p.h @@ -157,6 +157,7 @@ public: inline const QVector& textureImages() const { return m_textureImages; } inline const QTextureGeneratorPtr& dataGenerator() const { return m_dataFunctor; } + bool isValid() const; private: void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL; -- cgit v1.2.3 From 85f2562428de462ad05516c754956d65faae7b78 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Tue, 25 Apr 2017 08:30:38 +0200 Subject: simplecustommaterial: add GL2 shader variant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ie55724be1872f98660093b0fd5cea54d7e0eae11 Task-number: QTBUG-60289 Reviewed-by: Antti Määttä --- examples/qt3d/simplecustommaterial/SimpleMaterial.qml | 13 +++++++++++++ examples/qt3d/simplecustommaterial/main.cpp | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/examples/qt3d/simplecustommaterial/SimpleMaterial.qml b/examples/qt3d/simplecustommaterial/SimpleMaterial.qml index 0ad045e25..22cc028b0 100644 --- a/examples/qt3d/simplecustommaterial/SimpleMaterial.qml +++ b/examples/qt3d/simplecustommaterial/SimpleMaterial.qml @@ -99,6 +99,19 @@ Material { shaderProgram: gl3Shader } }, + // OpenGL 2.0 + Technique { + filterKeys: [forward] + graphicsApiFilter { + api: GraphicsApiFilter.OpenGL + profile: GraphicsApiFilter.NoProfile + majorVersion: 2 + minorVersion: 0 + } + renderPasses: RenderPass { + shaderProgram: es2Shader + } + }, // ES 2.0 Technique { filterKeys: [forward] diff --git a/examples/qt3d/simplecustommaterial/main.cpp b/examples/qt3d/simplecustommaterial/main.cpp index 392fe50ee..d841e7d19 100644 --- a/examples/qt3d/simplecustommaterial/main.cpp +++ b/examples/qt3d/simplecustommaterial/main.cpp @@ -50,9 +50,28 @@ #include #include +#include + +void setSurfaceFormat() +{ + QSurfaceFormat format; +#ifdef QT_OPENGL_ES_2 + format.setRenderableType(QSurfaceFormat::OpenGLES); +#else + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { + format.setVersion(4, 3); + format.setProfile(QSurfaceFormat::CoreProfile); + } +#endif + format.setDepthBufferSize(24); + format.setSamples(4); + format.setStencilBufferSize(8); + QSurfaceFormat::setDefaultFormat(format); +} int main(int argc, char **argv) { + setSurfaceFormat(); QGuiApplication app(argc, argv); QQuickView view; -- cgit v1.2.3 From 56d83515f6d4546d8d5bf0ec603fa49f40c51a9d Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Tue, 25 Apr 2017 08:54:55 +0200 Subject: advancedcustommaterial: request proper GL format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I9a4f1882805892248aa9f6a4cf8d83a49acaeb0b Task-number: QTBUG-60288 Reviewed-by: Antti Määttä --- .../qt3d/advancedcustommaterial/WaterMaterial.qml | 4 ++-- examples/qt3d/advancedcustommaterial/main.cpp | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/examples/qt3d/advancedcustommaterial/WaterMaterial.qml b/examples/qt3d/advancedcustommaterial/WaterMaterial.qml index 5278d8752..2c5410bea 100644 --- a/examples/qt3d/advancedcustommaterial/WaterMaterial.qml +++ b/examples/qt3d/advancedcustommaterial/WaterMaterial.qml @@ -228,7 +228,7 @@ Material { } }, - // OpenGL 2.1 + // OpenGL 2.0 Technique { filterKeys: [ forward ] graphicsApiFilter { @@ -238,7 +238,7 @@ Material { minorVersion: 0 } renderPasses: RenderPass { - shaderProgram: gl3Shader + shaderProgram: esShader renderStates: [ alphaCoverage ] } }, diff --git a/examples/qt3d/advancedcustommaterial/main.cpp b/examples/qt3d/advancedcustommaterial/main.cpp index 8b76e100c..9338ab4f4 100644 --- a/examples/qt3d/advancedcustommaterial/main.cpp +++ b/examples/qt3d/advancedcustommaterial/main.cpp @@ -50,9 +50,28 @@ #include #include +#include + +void setSurfaceFormat() +{ + QSurfaceFormat format; +#ifdef QT_OPENGL_ES_2 + format.setRenderableType(QSurfaceFormat::OpenGLES); +#else + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { + format.setVersion(4, 3); + format.setProfile(QSurfaceFormat::CoreProfile); + } +#endif + format.setDepthBufferSize(24); + format.setSamples(4); + format.setStencilBufferSize(8); + QSurfaceFormat::setDefaultFormat(format); +} int main(int argc, char **argv) { + setSurfaceFormat(); QGuiApplication app(argc, argv); QQuickView view; -- cgit v1.2.3 From 13e578738cc0e5efa08130d7d595d078b5423ffc Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Tue, 25 Apr 2017 10:26:12 +0200 Subject: Improve QEffect documentation Change-Id: I7dd333b512238474c6a789486327beeedc4ed4f1 Reviewed-by: Kevin Ottens --- src/render/materialsystem/qeffect.cpp | 60 +++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/render/materialsystem/qeffect.cpp b/src/render/materialsystem/qeffect.cpp index 7778b5621..b611657c4 100644 --- a/src/render/materialsystem/qeffect.cpp +++ b/src/render/materialsystem/qeffect.cpp @@ -67,6 +67,35 @@ QEffectPrivate::QEffectPrivate() The QEffect class combines a set of techniques and parameters used by those techniques to produce a rendering effect for a material. + An QEffect instance should be shared among several QMaterial instances when possible. + + \code + QEffect *effect = new QEffect(); + + // Create technique, render pass and shader + QTechnique *gl3Technique = new QTechnique(); + QRenderPass *gl3Pass = new QRenderPass(); + QShaderProgram *glShader = new QShaderProgram(); + + // Set the shader on the render pass + gl3Pass->setShaderProgram(glShader); + + // Add the pass to the technique + gl3Technique->addRenderPass(gl3Pass); + + // Set the targeted GL version for the technique + gl3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL); + gl3Technique->graphicsApiFilter()->setMajorVersion(3); + gl3Technique->graphicsApiFilter()->setMinorVersion(1); + gl3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile); + + // Add the technique to the effect + effect->addTechnique(gl3Technique); + \endcode + + A QParameter defined on an Effect is overridden by a QParameter (of the same + name) defined in a QMaterial, QTechniqueFilter, QRenderPassFilter. + \sa QMaterial, QTechnique, QParameter */ @@ -81,6 +110,37 @@ QEffectPrivate::QEffectPrivate() The Effect type combines a set of techniques and parameters used by those techniques to produce a rendering effect for a material. + An Effect instance should be shared among several Material instances when possible. + + A Parameter defined on an Effect is overridden by a QParameter (of the same + name) defined in a Material, TechniqueFilter, RenderPassFilter. + + \code + Effect { + id: effect + + technique: [ + Technique { + id: gl3Technique + graphicsApiFilter { + api: GraphicsApiFilter.OpenGL + profile: GraphicsApiFilter.CoreProfile + majorVersion: 3 + minorVersion: 1 + } + renderPasses: [ + RenderPass { + id: gl3Pass + shaderProgram: ShaderProgram { + ... + } + } + ] + } + ] + } + \endcode + \sa Material, Technique, Parameter */ -- cgit v1.2.3 From 77bfd22a2d78ddd916b9a9fc01a07f97c02309f7 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Tue, 25 Apr 2017 11:46:53 +0200 Subject: Improve documentation for QRenderPass Change-Id: I0983cf703a1b1c6ae0398269ceb1d46ff48395de Reviewed-by: Kevin Ottens --- src/render/materialsystem/qrenderpass.cpp | 89 ++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 7 deletions(-) diff --git a/src/render/materialsystem/qrenderpass.cpp b/src/render/materialsystem/qrenderpass.cpp index 6f5949781..61f844be3 100644 --- a/src/render/materialsystem/qrenderpass.cpp +++ b/src/render/materialsystem/qrenderpass.cpp @@ -72,9 +72,40 @@ QRenderPassPrivate::QRenderPassPrivate() a list of FilterKey objects, a list of RenderState objects and a list of \l Parameter objects. - RenderPass executes the ShaderProgram using the given render states and parameters - when its filter keys match the filter keys in RenderPassFilter or when no filter - keys are specified and no RenderPassFilter is present in the FrameGraph. + RenderPass executes the ShaderProgram using the given RenderState and + Parameter nodes when at least one of FilterKey nodes being referenced + matches any of the FilterKey nodes in RenderPassFilter or when no FilterKey + nodes are specified and no RenderPassFilter is present in the FrameGraph. + + If the RenderPass defines a Parameter, it will be overridden by a Parameter + with the same name if it exists in any of the Technique, Effect, Material, + TechniqueFilter, RenderPassFilter associated with the pass at runtime. This + still can be useful to define sane default values. + + At render time, for each leaf node of the FrameGraph a base render state is + recorded by accumulating states defined by all RenderStateSet nodes in the + FrameGraph branch. Each RenderPass can overload this base render state by + specifying its own RenderState nodes. + + \code + RenderPass { + id: pass + shaderProgram: ShaderProgram { + ... + } + parameters: [ + Parameters { name: "color"; value: "red" } + ] + filterKeys: [ + FilterKey { name: "name"; value: "zFillPass" } + ] + renderStates: [ + DepthTest { } + ] + } + \endcode + + \sa RenderPassFilter, FilterKey, Parameter, RenderState, Effect, Technique */ /*! @@ -88,10 +119,54 @@ QRenderPassPrivate::QRenderPassPrivate() of a Qt3DRender::QShaderProgram and a list of Qt3DRender::QFilterKey objects, a list of Qt3DRender::QRenderState objects and a list of Qt3DRender::QParameter objects. - QRenderPass executes the QShaderProgram using the given render states and parameters - when its filter keys match the filter keys in Qt3DRender::QRenderPassFilter or - when no filter keys are specified and no QRenderPassFilter is present - in the FrameGraph. + QRenderPass executes the QShaderProgram using the given QRenderState and + QParameter nodes when at least one of QFilterKey nodes being referenced + matches any of the QFilterKey nodes in QRenderPassFilter or when no + QFilterKey nodes are specified and no QRenderPassFilter is present in the + FrameGraph. + + If the QRenderPass defines a QParameter, it will be overridden by a + QParameter with the same name if it exists in any of the QTechnique, + QEffect, QMaterial, QTechniqueFilter, QRenderPassFilter associated with the + pass at runtime. This still can be useful to define sane default values. + + At render time, for each leaf node of the FrameGraph a base render state is + recorded by accumulating states defined by all QRenderStateSet nodes in the + FrameGraph branch. Each QRenderPass can overload this base render state by + specifying its own QRenderState nodes. + + \code + // Create the render passes + QRenderPass *pass = new QRenderPass(); + + // Create shader program + QShaderProgram *glShader = new QShaderProgram(); + + // Set the shader on the render pass + pass->setShaderProgram(glShader); + + // Create a FilterKey + QFilterKey *filterKey = new QFilterKey(); + filterKey->setName(QStringLiteral("name")); + fitlerKey->setValue(QStringLiteral("zFillPass")); + + // Add the FilterKey to the pass + pass->addFilterKey(filterKey); + + // Create a QParameter + QParameter *colorParameter = new QParameter(QStringLiteral("color"), QColor::fromRgbF(0.0f, 0.0f, 1.0f, 1.0f)); + + // Add parameter to pass + pass->addParameter(colorParameter); + + // Create a QRenderState + QDepthTest *depthTest = new QDepthTest(); + + // Add the render state to the pass + pass->addRenderState(depthTest); + \endcode + + \sa QRenderPassFilter, QFilterKey, QParameter, QRenderState, QEffect, QTechnique */ /*! \typedef ParameterList -- cgit v1.2.3 From 0f8e09748c8724350c2e353b7b849e062316992c Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Tue, 25 Apr 2017 10:22:27 +0200 Subject: Improve documentation for QMaterial Change-Id: Ied1053afa5cde7ce376ba6232d20a03b6edb05b6 Reviewed-by: Kevin Ottens --- src/render/materialsystem/qmaterial.cpp | 102 +++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 2 deletions(-) diff --git a/src/render/materialsystem/qmaterial.cpp b/src/render/materialsystem/qmaterial.cpp index ca0f86463..c6913441e 100644 --- a/src/render/materialsystem/qmaterial.cpp +++ b/src/render/materialsystem/qmaterial.cpp @@ -60,7 +60,58 @@ sound should reflect off an element, the temperature of a surface, and so on. - \sa Effect + In itself, a Material doesn't do anything. It's only when it references an + Effect node that a Material becomes useful. + + In practice, it often happens that a single Effect is being referenced by + several Material components. This allows to only create the effect, + techniques, passes and shaders once while allowing to specify the material + by adding Parameter instances. + + A Parameter defined on a Material is overridden by a Parameter (of the same + name) defined in a TechniqueFilter or a RenderPassFilter. + + \code + Effect { + id: effect + + technique: [ + Technique { + id: gl3Technique + graphicsApiFilter { + api: GraphicsApiFilter.OpenGL + profile: GraphicsApiFilter.CoreProfile + majorVersion: 3 + minorVersion: 1 + } + renderPasses: [ + RenderPass { + id: gl3Pass + shaderProgram: ShaderProgram { + ... + } + } + ] + } + ] + } + + Material { + id: material1 + parameters: [ + Parameter { name: "color"; value: "green" } + ] + } + + Material { + id: material2 + parameters: [ + Parameter { name: "color"; value: "white" } + ] + } + \endcode + + \sa Effect, Technique, Parameter */ /*! @@ -77,7 +128,54 @@ sound should reflect off an element, the temperature of a surface, and so on. - \sa QEffect + In itself, a QMaterial doesn't do anything. It's only when it references a + QEffect node that a QMaterial becomes useful. + + In practice, it often happens that a single QEffect is being referenced by + several QMaterial components. This allows to only create the effect, + techniques, passes and shaders once while allowing to specify the material + by adding QParameter instances. + + A QParameter defined on a QMaterial is overridden by a QParameter (of the same + name) defined in a QTechniqueFilter or a QRenderPassFilter. + + \code + QMaterial *material1 = new QMaterial(); + QMaterial *material2 = new QMaterial(); + + // Create effect, technique, render pass and shader + QEffect *effect = new QEffect(); + QTechnique *gl3Technique = new QTechnique(); + QRenderPass *gl3Pass = new QRenderPass(); + QShaderProgram *glShader = new QShaderProgram(); + + // Set the shader on the render pass + gl3Pass->setShaderProgram(glShader); + + // Add the pass to the technique + gl3Technique->addRenderPass(gl3Pass); + + // Set the targeted GL version for the technique + gl3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL); + gl3Technique->graphicsApiFilter()->setMajorVersion(3); + gl3Technique->graphicsApiFilter()->setMinorVersion(1); + gl3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile); + + // Add the technique to the effect + effect->addTechnique(gl3Technique); + + // Set the effect on the materials + material1->setEffect(effect); + material2->setEffect(effect); + + // Set different parameters on the materials + const QString parameterName = QStringLiteral("color"); + material1->addParameter(new QParameter(parameterName, QColor::fromRgbF(0.0f, 1.0f, 0.0f, 1.0f); + material2->addParameter(new QParameter(parameterName, QColor::fromRgbF(1.0f, 1.0f, 1.0f, 1.0f); + + \endcode + + \sa QEffect, QTechnique, QParameter */ QT_BEGIN_NAMESPACE -- cgit v1.2.3 From 5e87e5beee5cfeffaa344ea165fba59ea46f4c57 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Tue, 25 Apr 2017 12:58:13 +0200 Subject: Remove last bits of qsortcriterion QSortCriterion was replaced with QSortPolicy, somehow some files were still around. Change-Id: Ic41fe557eb77c0b8d9d701a875598a7850a92b62 Task-number: QTBUG-55952 Reviewed-by: Kevin Ottens --- src/render/framegraph/qsortcriterion.cpp | 82 ------------ src/render/framegraph/qsortcriterion.h | 85 ------------- .../render/qsortcriterion/tst_qsortcriterion.cpp | 138 --------------------- 3 files changed, 305 deletions(-) delete mode 100644 src/render/framegraph/qsortcriterion.cpp delete mode 100644 src/render/framegraph/qsortcriterion.h delete mode 100644 tests/auto/render/qsortcriterion/tst_qsortcriterion.cpp diff --git a/src/render/framegraph/qsortcriterion.cpp b/src/render/framegraph/qsortcriterion.cpp deleted file mode 100644 index f5252b1f7..000000000 --- a/src/render/framegraph/qsortcriterion.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 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$ -** -****************************************************************************/ - -#include "qsortcriterion.h" -#include "qsortcriterion_p.h" -#include - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -QSortCriterionPrivate::QSortCriterionPrivate() - : QNodePrivate() - , m_sort(QSortCriterion::StateChangeCost) -{ -} - -QSortCriterion::QSortCriterion(QNode *parent) - : QNode(*new QSortCriterionPrivate, parent) -{ -} - -QSortCriterion::SortType QSortCriterion::sort() const -{ - Q_D(const QSortCriterion); - return d->m_sort; -} - -void QSortCriterion::setSort(QSortCriterion::SortType sort) -{ - Q_D(QSortCriterion); - if (d->m_sort != sort) { - d->m_sort = sort; - emit sortChanged(sort); - } -} - -/*! \internal */ -QSortCriterion::QSortCriterion(QSortCriterionPrivate &dd, QNode *parent) - : QNode(dd, parent) -{ -} - -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/framegraph/qsortcriterion.h b/src/render/framegraph/qsortcriterion.h deleted file mode 100644 index 230f111f9..000000000 --- a/src/render/framegraph/qsortcriterion.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 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_QSORTCRITERION_H -#define QT3DRENDER_QSORTCRITERION_H - -#include -#include - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -class QSortCriterionPrivate; - -class QT3DRENDERSHARED_EXPORT QSortCriterion : public Qt3DCore::QNode -{ - Q_OBJECT - Q_PROPERTY(Qt3DRender::QSortCriterion::SortType sort READ sort WRITE setSort NOTIFY sortChanged) -public: - explicit QSortCriterion(Qt3DCore::QNode *parent = Q_NULLPTR); - - enum SortType { - StateChangeCost = (1 << 0), - BackToFront = (1 << 1), - Material = (1 << 2) - }; - Q_ENUM(SortType) // LCOV_EXCL_LINE - - SortType sort() const; - -public Q_SLOTS: - void setSort(SortType sort); - -Q_SIGNALS: - void sortChanged(SortType sort); - -protected: - QSortCriterion(QSortCriterionPrivate &dd, Qt3DCore::QNode *parent = Q_NULLPTR); - -private: - Q_DECLARE_PRIVATE(QSortCriterion) -}; - -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QSORTCRITERION_H diff --git a/tests/auto/render/qsortcriterion/tst_qsortcriterion.cpp b/tests/auto/render/qsortcriterion/tst_qsortcriterion.cpp deleted file mode 100644 index bac9fb3e8..000000000 --- a/tests/auto/render/qsortcriterion/tst_qsortcriterion.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the S module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** 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-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include - -#include -#include - -#include "testpostmanarbiter.h" - -class tst_QSortCriterion: public QObject -{ - Q_OBJECT - -private Q_SLOTS: - - void checkCloning_data() - { - QTest::addColumn("sortCriterion"); - QTest::addColumn("sortType"); - - Qt3DRender::QSortCriterion *defaultConstructed = new Qt3DRender::QSortCriterion(); - QTest::newRow("defaultConstructed") << defaultConstructed << Qt3DRender::QSortCriterion::StateChangeCost; - - Qt3DRender::QSortCriterion *backToFrontSort = new Qt3DRender::QSortCriterion(); - backToFrontSort->setSort(Qt3DRender::QSortCriterion::BackToFront); - QTest::newRow("backToFrontSort") << backToFrontSort << Qt3DRender::QSortCriterion::BackToFront; - - Qt3DRender::QSortCriterion *materialSort = new Qt3DRender::QSortCriterion(); - materialSort->setSort(Qt3DRender::QSortCriterion::Material); - QTest::newRow("materialSort") << materialSort << Qt3DRender::QSortCriterion::Material; - } - - void checkCloning() - { - // GIVEN - QFETCH(Qt3DRender::QSortCriterion *, sortCriterion); - QFETCH(Qt3DRender::QSortCriterion::SortType, sortType); - - // THEN - QCOMPARE(sortCriterion->sort(), sortType); - -// TO DO: Add creation change -// // WHEN -// Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(sortCriterion); -// QVector creationChanges = creationChangeGenerator.creationChanges(); - -// // THEN -// QCOMPARE(creationChanges.size(), 1); - -// const Qt3DCore::QNodeCreatedChangePtr creationChangeData = -// qSharedPointerCast>(creationChanges.first()); -// const Qt3DRender::QCameraSelectorData &cloneData = creationChangeData->data; - - -// // THEN -// QCOMPARE(sortCriterion->id(), creationChangeData->subjectId()); -// QCOMPARE(sortCriterion->isEnabled(), creationChangeData->isNodeEnabled()); -// QCOMPARE(sortCriterion->metaObject(), creationChangeData->metaObject()); -// QCOMPARE(sortCriterion->sort(), cloneData.sort); - - delete sortCriterion; - } - - void checkPropertyUpdates() - { - // GIVEN - QScopedPointer sortCriterion(new Qt3DRender::QSortCriterion()); - TestArbiter arbiter(sortCriterion.data()); - - // WHEN - sortCriterion->setSort(Qt3DRender::QSortCriterion::BackToFront); - QCoreApplication::processEvents(); - - // THEN - QCOMPARE(arbiter.events.size(), 1); - Qt3DCore::QNodePropertyChangePtr change = arbiter.events.first().staticCast(); - QCOMPARE(change->propertyName(), "sort"); - QCOMPARE(change->subjectId(), sortCriterion->id()); - QCOMPARE(change->value().value(), Qt3DRender::QSortCriterion::BackToFront); - QCOMPARE(change->type(), Qt3DCore::NodeUpdated); - - arbiter.events.clear(); - - // WHEN - sortCriterion->setSort(Qt3DRender::QSortCriterion::BackToFront); - QCoreApplication::processEvents(); - - // THEN - QCOMPARE(arbiter.events.size(), 0); - - // WHEN - sortCriterion->setSort(Qt3DRender::QSortCriterion::Material); - QCoreApplication::processEvents(); - - // THEN - QCOMPARE(arbiter.events.size(), 1); - change = arbiter.events.first().staticCast(); - QCOMPARE(change->propertyName(), "sort"); - QCOMPARE(change->subjectId(), sortCriterion->id()); - QCOMPARE(change->value().value(), Qt3DRender::QSortCriterion::Material); - QCOMPARE(change->type(), Qt3DCore::NodeUpdated); - - arbiter.events.clear(); - } -}; - -QTEST_MAIN(tst_QSortCriterion) - -#include "tst_qsortcriterion.moc" -- cgit v1.2.3 From 7bddeeef303d0b2c100f2b2a7c01bf311ab07335 Mon Sep 17 00:00:00 2001 From: Mike Krus Date: Mon, 24 Apr 2017 21:36:12 +0100 Subject: Send move events when hover is enabled Change-Id: I3bea4f27361dd4f51f8547c6d9d45c964f4fb5d3 Task-number: QTBUG-58607 Reviewed-by: Kevin Ottens --- src/render/jobs/pickboundingvolumejob.cpp | 2 +- tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp index 7bd45587c..f6c469912 100644 --- a/src/render/jobs/pickboundingvolumejob.cpp +++ b/src/render/jobs/pickboundingvolumejob.cpp @@ -378,7 +378,7 @@ void PickBoundingVolumeJob::dispatchPickEvents(const QMouseEvent &event, } case QEvent::MouseMove: { - if (objectPicker->isPressed() && objectPicker->isDragEnabled()) { + if ((objectPicker->isPressed() || objectPicker->isHoverEnabled()) && objectPicker->isDragEnabled()) { objectPicker->onMoved(pickEvent); } // fallthrough diff --git a/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp b/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp index 07055d810..1d391101e 100644 --- a/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp +++ b/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp @@ -1145,7 +1145,10 @@ private Q_SLOTS: change = arbiter1.events.first().staticCast(); QCOMPARE(change->propertyName(), "moved"); } else { + QVERIFY(arbiter2.events.size() > 1); change = arbiter2.events.first().staticCast(); + QCOMPARE(change->propertyName(), "moved"); + change = arbiter2.events.at(1).staticCast(); QCOMPARE(change->propertyName(), "entered"); } -- cgit v1.2.3 From deeca0dd4895eb7c013e53123187782486615b6c Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Tue, 25 Apr 2017 11:03:58 +0200 Subject: Improve QTechnique documentation Change-Id: I4fc3ff7256854968ae6a31fb30f4ad1721787e03 Reviewed-by: Kevin Ottens --- src/render/materialsystem/qtechnique.cpp | 128 +++++++++++++++++++++++++++---- 1 file changed, 111 insertions(+), 17 deletions(-) diff --git a/src/render/materialsystem/qtechnique.cpp b/src/render/materialsystem/qtechnique.cpp index 74505bfbd..df142cdee 100644 --- a/src/render/materialsystem/qtechnique.cpp +++ b/src/render/materialsystem/qtechnique.cpp @@ -68,14 +68,61 @@ QTechniquePrivate::~QTechniquePrivate() \since 5.7 \brief Encapsulates a Technique. - A Technique specifies a set of RenderPass objects, FilterKey objects, Parameter objects - and a GraphicsApiFilter, which together define a rendering technique the given - graphics API can render. The filter keys are used by TechniqueFilter - to select specific techinques at specific parts of the FrameGraph. - If the same parameter is specified both in Technique and RenderPass, the one - in Technique overrides the one used in the RenderPass. - - \sa Qt3D.Render::Effect + A Technique specifies a set of RenderPass objects, FilterKey objects, + Parameter objects and a GraphicsApiFilter, which together define a + rendering technique the given graphics API can render. The filter keys are + used by TechniqueFilter to select specific techniques at specific parts of + the FrameGraph. If two Parameter instances with the same name are specified + in a Technique and a RenderPass, the one in Technique overrides the one + used in the RenderPass. + + When creating an Effect that targets several versions of a graphics API, it + is useful to create several Technique nodes each with a graphicsApiFilter + set to match one of the targeted versions. At runtime, the Qt3D renderer + will select the most appropriate Technique based on which graphics API + versions are supported and (if specified) the FilterKey nodes that satisfy + a given TechniqueFilter in the FrameGraph. + + \note When using OpenGL as the graphics API for rendering, Qt3D relies on + the QSurfaceFormat returned by QSurfaceFormat::defaultFormat() at runtime + to decide what is the most appropriate GL version available. If you need to + customize the QSurfaceFormat, do not forget to apply it with + QSurfaceFormat::setDefaultFormat(). Setting the QSurfaceFormat on the view + will likely have no effect on Qt3D related rendering. + + \code + Technique { + id: gl3Technique + parameters: [ + Parameter { name: "color"; value: "orange" } + ] + filterKeys: [ + FilterKey { name: "name"; value: "zFillTechnique" } + ] + graphicsApiFilter { + api: GraphicsApiFilter.OpenGL + profile: GraphicsApiFilter.CoreProfile + majorVersion: 3 + minorVersion: 1 + } + renderPasses: [ + RenderPass { + id: firstPass + shaderProgram: ShaderProgram { + ... + } + }, + RenderPass { + id: secondPass + shaderProgram: ShaderProgram { + ... + } + } + ] + } + \endcode + + \sa Effect, RenderPass, TechniqueFilter */ /*! @@ -85,15 +132,62 @@ QTechniquePrivate::~QTechniquePrivate() \since 5.7 \brief Encapsulates a Technique. - A Qt3DRender::QTechnique specifies a set of Qt3DRender::QRenderPass objects, - Qt3DRender::QFilterKey objects, Qt3DRender::QParameter objects and - a Qt3DRender::QGraphicsApiFilter, which together define a rendering technique the given - graphics API can render. The filter keys are used by Qt3DRender::QTechniqueFilter - to select specific techinques at specific parts of the FrameGraph. - If the same parameter is specified both in QTechnique and QRenderPass, the one - in QTechnique overrides the one used in the QRenderPass. - - \sa Qt3DRender::QEffect + A Qt3DRender::QTechnique specifies a set of Qt3DRender::QRenderPass + objects, Qt3DRender::QFilterKey objects, Qt3DRender::QParameter objects and + a Qt3DRender::QGraphicsApiFilter, which together define a rendering + technique the given graphics API can render. The filter keys are used by + Qt3DRender::QTechniqueFilter to select specific techniques at specific + parts of the FrameGraph. If two QParameter instances with the same name are + specified in a QTechnique and a QRenderPass, the one in Technique overrides + the one used in the QRenderPass. + + When creating an QEffect that targets several versions of a graphics API, + it is useful to create several QTechnique nodes each with a + graphicsApiFilter set to match one of the targeted GL versions. At runtime, + the Qt3D renderer will select the most appropriate QTechnique based on + which graphics API versions are supported and (if specified) the QFilterKey + nodes that satisfy a given QTechniqueFilter in the FrameGraph. + + \note When using OpenGL as the graphics API for rendering, Qt3D relies on + the QSurfaceFormat returned by QSurfaceFormat::defaultFormat() at runtime + to decide what is the most appropriate GL version available. If you need to + customize the QSurfaceFormat, do not forget to apply it with + QSurfaceFormat::setDefaultFormat(). Setting the QSurfaceFormat on the view + will likely have no effect on Qt3D related rendering. + + \code + QTechnique *gl3Technique = new QTechnique(); + + // Create the render passes + QRenderPass *firstPass = new QRenderPass(); + QRenderPass *secondPass = new QRenderPass(); + + // Add the passes to the technique + gl3Technique->addRenderPass(firstPass); + gl3Technique->addRenderPass(secondPass); + + // Set the targeted GL version for the technique + gl3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL); + gl3Technique->graphicsApiFilter()->setMajorVersion(3); + gl3Technique->graphicsApiFilter()->setMinorVersion(1); + gl3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile); + + // Create a FilterKey + QFilterKey *filterKey = new QFilterKey(); + filterKey->setName(QStringLiteral("name")); + fitlerKey->setValue(QStringLiteral("zFillPass")); + + // Add the FilterKey to the Technique + gl3Technique->addFilterKey(filterKey); + + // Create a QParameter + QParameter *colorParameter = new QParameter(QStringLiteral("color"), QColor::fromRgbF(0.0f, 0.0f, 1.0f, 1.0f)); + + // Add parameter to technique + gl3Technique->addParameter(colorParameter); + \endcode + + \sa QEffect, QRenderPass, QTechniqueFilter */ /*! -- cgit v1.2.3 From 5110969b84bf82f8b218762b7c409f3c4ee54707 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Tue, 25 Apr 2017 12:45:14 +0200 Subject: Improve QParameter documentation Change-Id: I0b9cbd4d24120c9aa7c4186be26ff5e1c42c3299 Reviewed-by: Kevin Ottens --- src/render/materialsystem/qparameter.cpp | 127 ++++++++++++++++++++++++++++--- 1 file changed, 118 insertions(+), 9 deletions(-) diff --git a/src/render/materialsystem/qparameter.cpp b/src/render/materialsystem/qparameter.cpp index 8f83fd02e..2ca7d176b 100644 --- a/src/render/materialsystem/qparameter.cpp +++ b/src/render/materialsystem/qparameter.cpp @@ -45,18 +45,127 @@ /*! - * \qmltype Parameter - * \instantiates Qt3DRender::QParameter - * \inqmlmodule Qt3D.Render - * \brief Provides storage for a name and value pair. + \qmltype Parameter + \instantiates Qt3DRender::QParameter + \inqmlmodule Qt3D.Render + \brief Provides storage for a name and value pair. This maps to a shader uniform. + + A Parameter can be referenced by a RenderPass, Technique, Effect, Material, + TechniqueFilter, RenderPassFilter. At runtime, depending on which shader is + selected for a given step of the rendering, the value contained in a + Parameter will be converted and uploaded if the shader contains a uniform + with a name matching that of the Parameter. + + \code + Parameter { + name: "diffuseColor" + value: "blue" + } + + // Works with the following GLSL uniform shader declarations + // uniform vec4 diffuseColor; + // uniform vec3 diffuseColor; + // uniform vec2 diffuseColor; + // uniform float diffuseColor; + \endcode + + \note some care must be taken to ensure the value wrapped by a Parameter + can actually be converted to what the real uniform expect. Giving a value + stored as an int where the actual shader uniform is of type float could + result in undefined behaviors. + + \note when the targeted uniform is an array, the name should be the name + of the uniform with [0] appended to it. + + \code + Parameter { + name: "diffuseValues[0]" + value: [0.0, 1.0. 2.0, 3.0, 4.0, 883.0, 1340.0, 1584.0] + } + + // Matching GLSL shader uniform declaration + // uniform float diffuseValues[8]; + \endcode + + When it comes to texture support, the Parameter value should be set to the + appropriate Texture subclass that matches the sampler type of the shader + uniform. + + \code + Parameter { + name: "diffuseTexture" + value: Texture2D { ... } + } + + // Works with the following GLSL uniform shader declaration + // uniform sampler2D diffuseTexture + \endcode + + \sa Texture */ /*! - * \class Qt3DRender::QParameter - * \inheaderfile Qt3DRender/QParameter - * \inmodule Qt3DRender - * - * \brief Provides storage for a name and value pair. + \class Qt3DRender::QParameter + \inheaderfile Qt3DRender/QParameter + \inmodule Qt3DRender + \brief Provides storage for a name and value pair. This maps to a shader uniform. + + A QParameter can be referenced by a QRenderPass, QTechnique, QEffect, QMaterial, + QTechniqueFilter, QRenderPassFilter. At runtime, depending on which shader is + selected for a given step of the rendering, the value contained in a + QParameter will be converted and uploaded if the shader contains a uniform + with a name matching that of the QParameter. + + \code + QParameter *param = new QParameter(); + param->setName(QStringLiteral("diffuseColor")); + param->setValue(QColor::fromRgbF(0.0f, 0.0f, 1.0f, 1.0f)); + + // Alternatively you can create and set a QParameter this way + QParameter *param2 = new QParameter(QStringLiteral("diffuseColor"), QColor::fromRgbF(0.0f, 0.0f, 1.0f, 1.0f)); + + // Such QParameters will work with the following GLSL uniform shader declarations + // uniform vec4 diffuseColor; + // uniform vec3 diffuseColor; + // uniform vec2 diffuseColor; + // uniform float diffuseColor; + \endcode + + \note some care must be taken to ensure the value wrapped by a QParameter + can actually be converted to what the real uniform expect. Giving a value + stored as an int where the actual shader uniform is of type float could + result in undefined behaviors. + + \note when the targeted uniform is an array, the name should be the name + of the uniform with [0] appended to it. + + \code + QParameter *param = new QParameter(); + QVariantList values = QVariantList() << 0.0f << 1.0f << 2.0f << 3.0f << 4.0f << 883.0f << 1340.0f << 1584.0f; + + param->setName(QStringLiteral("diffuseValues[0]")); + param->setValue(values); + + // Matching GLSL shader uniform declaration + // uniform float diffuseValues[8]; + \endcode + + When it comes to texture support, the QParameter value should be set to the + appropriate QAbstractTexture subclass that matches the sampler type of the shader + uniform. + + \code + QTexture2D *texture = new QTexture2D(); + ... + QParameter *param = new QParameter(); + param->setName(QStringLiteral("diffuseTexture")); + param->setValue(QVariant::fromValue(texture)); + + // Works with the following GLSL uniform shader declaration + // uniform sampler2D diffuseTexture + \endcode + + \sa QAbstractTexture */ QT_BEGIN_NAMESPACE -- cgit v1.2.3 From 51c1d5bdfe4da07b9408af2290e2e7b3c9010fcd Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Wed, 26 Apr 2017 10:57:56 +0200 Subject: Add unit tests for FrameGraphVisitor Change-Id: I1ef3c275649fe874d2dc4c6caf81082729aca360 Reviewed-by: Kevin Ottens --- .../render/framegraphvisitor/framegraphvisitor.pro | 13 ++ .../framegraphvisitor/tst_framegraphvisitor.cpp | 174 +++++++++++++++++++++ tests/auto/render/render.pro | 3 +- 3 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 tests/auto/render/framegraphvisitor/framegraphvisitor.pro create mode 100644 tests/auto/render/framegraphvisitor/tst_framegraphvisitor.cpp diff --git a/tests/auto/render/framegraphvisitor/framegraphvisitor.pro b/tests/auto/render/framegraphvisitor/framegraphvisitor.pro new file mode 100644 index 000000000..2c9a0028e --- /dev/null +++ b/tests/auto/render/framegraphvisitor/framegraphvisitor.pro @@ -0,0 +1,13 @@ +TEMPLATE = app + +TARGET = tst_framegraphvisitor + +QT += core-private 3dcore 3dcore-private 3drender 3drender-private testlib + +CONFIG += testcase + +SOURCES += tst_framegraphvisitor.cpp + +CONFIG += useCommonTestAspect + +include(../commons/commons.pri) diff --git a/tests/auto/render/framegraphvisitor/tst_framegraphvisitor.cpp b/tests/auto/render/framegraphvisitor/tst_framegraphvisitor.cpp new file mode 100644 index 000000000..5344d7eb3 --- /dev/null +++ b/tests/auto/render/framegraphvisitor/tst_framegraphvisitor.cpp @@ -0,0 +1,174 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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$ +** +****************************************************************************/ + + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "testaspect.h" + +namespace { + + + +} // anonymous + +using FGIdType = QPair; +using BranchIdsAndTypes = QVector; + +Q_DECLARE_METATYPE(QVector) + +class tst_FrameGraphVisitor : public QObject +{ + Q_OBJECT +private Q_SLOTS: + + void visitFGTree_data() + { + QTest::addColumn("rootEntity"); + QTest::addColumn("fgRoot"); + QTest::addColumn>("fgNodeIdsPerBranch"); + + { + Qt3DCore::QEntity *entity = new Qt3DCore::QEntity(); + Qt3DRender::QTechniqueFilter *techniqueFilter = new Qt3DRender::QTechniqueFilter(entity); + + QTest::newRow("singleNode") << entity + << static_cast(techniqueFilter) + << (QVector() + << (BranchIdsAndTypes() << FGIdType(techniqueFilter->id(), Qt3DRender::Render::FrameGraphNode::TechniqueFilter)) + ); + } + + { + Qt3DCore::QEntity *entity = new Qt3DCore::QEntity(); + Qt3DRender::QTechniqueFilter *techniqueFilter = new Qt3DRender::QTechniqueFilter(entity); + Qt3DRender::QFrustumCulling *frustumCulling = new Qt3DRender::QFrustumCulling(techniqueFilter); + Qt3DRender::QNoDraw *noDraw = new Qt3DRender::QNoDraw(frustumCulling); + + QTest::newRow("singleBranch") << entity + << static_cast(techniqueFilter) + << (QVector() + << (BranchIdsAndTypes() + << FGIdType(noDraw->id(), Qt3DRender::Render::FrameGraphNode::NoDraw) + << FGIdType(frustumCulling->id(), Qt3DRender::Render::FrameGraphNode::FrustumCulling) + << FGIdType(techniqueFilter->id(), Qt3DRender::Render::FrameGraphNode::TechniqueFilter) + ) + ); + } + { + Qt3DCore::QEntity *entity = new Qt3DCore::QEntity(); + Qt3DRender::QTechniqueFilter *techniqueFilter = new Qt3DRender::QTechniqueFilter(entity); + Qt3DRender::QFrustumCulling *frustumCulling = new Qt3DRender::QFrustumCulling(techniqueFilter); + Qt3DRender::QNoDraw *noDraw = new Qt3DRender::QNoDraw(frustumCulling); + Qt3DRender::QViewport *viewPort = new Qt3DRender::QViewport(frustumCulling); + + QTest::newRow("dualBranch") << entity + << static_cast(techniqueFilter) + << (QVector() + << (BranchIdsAndTypes() + << FGIdType(noDraw->id(), Qt3DRender::Render::FrameGraphNode::NoDraw) + << FGIdType(frustumCulling->id(), Qt3DRender::Render::FrameGraphNode::FrustumCulling) + << FGIdType(techniqueFilter->id(), Qt3DRender::Render::FrameGraphNode::TechniqueFilter) + ) + << (BranchIdsAndTypes() + << FGIdType(viewPort->id(), Qt3DRender::Render::FrameGraphNode::Viewport) + << FGIdType(frustumCulling->id(), Qt3DRender::Render::FrameGraphNode::FrustumCulling) + << FGIdType(techniqueFilter->id(), Qt3DRender::Render::FrameGraphNode::TechniqueFilter) + ) + ); + } + + } + + void visitFGTree() + { + // GIVEN + QFETCH(Qt3DCore::QEntity *, rootEntity); + QFETCH(Qt3DRender::QFrameGraphNode *, fgRoot); + QFETCH(QVector, fgNodeIdsPerBranch); + QScopedPointer aspect(new Qt3DRender::TestAspect(rootEntity)); + + // THEN + Qt3DRender::Render::FrameGraphManager *fgManager = aspect->nodeManagers()->frameGraphManager(); + Qt3DRender::Render::FrameGraphNode *backendFGRoot = fgManager->lookupNode(fgRoot->id()); + QVERIFY(backendFGRoot != nullptr); + + + // WHEN + Qt3DRender::Render::FrameGraphVisitor visitor(fgManager); + const QVector fgNodes = visitor.traverse(backendFGRoot); + + // THEN + QCOMPARE(fgNodeIdsPerBranch.size(), fgNodes.size()); + + for (int i = 0; i < fgNodeIdsPerBranch.size(); ++i) { + const BranchIdsAndTypes brandIdsAndTypes = fgNodeIdsPerBranch.at(i); + + Qt3DRender::Render::FrameGraphNode *fgNode = fgNodes.at(i); + for (int j = 0; j < brandIdsAndTypes.size(); ++j) { + const FGIdType idAndType = brandIdsAndTypes.at(j); + QVERIFY(fgNode != nullptr); + QCOMPARE(fgNode->peerId(), idAndType.first); + QCOMPARE(fgNode->nodeType(), idAndType.second); + fgNode = fgNode->parent(); + } + + QVERIFY(fgNode == nullptr); + } + + delete rootEntity; + } +}; + +QTEST_MAIN(tst_FrameGraphVisitor) + +#include "tst_framegraphvisitor.moc" diff --git a/tests/auto/render/render.pro b/tests/auto/render/render.pro index bf464cf6b..8eea3d032 100644 --- a/tests/auto/render/render.pro +++ b/tests/auto/render/render.pro @@ -106,7 +106,8 @@ qtConfig(private_tests) { qshaderprogram \ qscene2d \ scene2d \ - coordinatereader + coordinatereader \ + framegraphvisitor !macos: SUBDIRS += graphicshelpergl4 } -- cgit v1.2.3 From 7442d9cd770a5a2e30734b0e242883bac7802226 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Tue, 28 Mar 2017 13:04:05 +0200 Subject: Render: make FrameGraphVisitor return a vector of FG nodes Adjust the Renderer to be the one creating the RenderViewBuilder jobs. This removes a bit of coupling that will be needed to later only execute some jobs on demand. Change-Id: Ia5f1c6e6d40ee39595c661e177a08054ebc92a18 Reviewed-by: Kevin Ottens --- src/render/backend/renderer.cpp | 13 ++++++++++--- src/render/framegraph/framegraphvisitor.cpp | 26 ++++++++------------------ src/render/framegraph/framegraphvisitor_p.h | 14 ++++---------- 3 files changed, 22 insertions(+), 31 deletions(-) diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp index 42909d8be..e40d5d68e 100644 --- a/src/render/backend/renderer.cpp +++ b/src/render/backend/renderer.cpp @@ -86,6 +86,7 @@ #include #include #include +#include #include #include @@ -1435,11 +1436,17 @@ QVector Renderer::renderBinJobs() // populate the RenderView with a set of RenderCommands that get // their details from the RenderNodes that are visible to the // Camera selected by the framegraph configuration - FrameGraphVisitor visitor(this, m_nodesManager->frameGraphManager()); - visitor.traverse(frameGraphRoot(), &renderBinJobs); + FrameGraphVisitor visitor(m_nodesManager->frameGraphManager()); + const QVector fgLeaves = visitor.traverse(frameGraphRoot()); + + const int fgBranchCount = fgLeaves.size(); + for (int i = 0; i < fgBranchCount; ++i) { + RenderViewBuilder builder(fgLeaves.at(i), i, this); + renderBinJobs.append(builder.buildJobHierachy()); + } // Set target number of RenderViews - m_renderQueue->setTargetRenderViewCount(visitor.leafNodeCount()); + m_renderQueue->setTargetRenderViewCount(fgBranchCount); return renderBinJobs; } diff --git a/src/render/framegraph/framegraphvisitor.cpp b/src/render/framegraph/framegraphvisitor.cpp index d31e9cddd..cd8b08219 100644 --- a/src/render/framegraph/framegraphvisitor.cpp +++ b/src/render/framegraph/framegraphvisitor.cpp @@ -43,7 +43,6 @@ #include "framegraphnode_p.h" #include #include -#include #include QT_BEGIN_NAMESPACE @@ -53,24 +52,16 @@ using namespace Qt3DCore; namespace Qt3DRender { namespace Render { -FrameGraphVisitor::FrameGraphVisitor(Renderer *renderer, - const FrameGraphManager *manager) - : m_renderer(renderer) - , m_manager(manager) - , m_jobs(nullptr) - , m_renderviewIndex(0) - +FrameGraphVisitor::FrameGraphVisitor(const FrameGraphManager *manager) + : m_manager(manager) { + m_leaves.reserve(8); } -void FrameGraphVisitor::traverse(FrameGraphNode *root, - QVector *jobs) +QVector FrameGraphVisitor::traverse(FrameGraphNode *root) { - m_jobs = jobs; - m_renderviewIndex = 0; + m_leaves.clear(); - Q_ASSERT(m_renderer); - Q_ASSERT(m_jobs); Q_ASSERT_X(root, Q_FUNC_INFO, "The FrameGraphRoot is null"); // Kick off the traversal @@ -78,6 +69,7 @@ void FrameGraphVisitor::traverse(FrameGraphNode *root, if (node == nullptr) qCritical() << Q_FUNC_INFO << "FrameGraph is null"; visit(node); + return m_leaves; } void FrameGraphVisitor::visit(Render::FrameGraphNode *node) @@ -97,10 +89,8 @@ void FrameGraphVisitor::visit(Render::FrameGraphNode *node) // Leaf node - create a RenderView ready to be populated // TODO: Pass in only framegraph config that has changed from previous // index RenderViewJob. - if (fgChildIds.empty()) { - RenderViewBuilder builder(node, m_renderviewIndex++, m_renderer); - m_jobs->append(builder.buildJobHierachy()); - } + if (fgChildIds.empty()) + m_leaves.push_back(node); } } // namespace Render diff --git a/src/render/framegraph/framegraphvisitor_p.h b/src/render/framegraph/framegraphvisitor_p.h index af8f4caab..f4c0d7796 100644 --- a/src/render/framegraph/framegraphvisitor_p.h +++ b/src/render/framegraph/framegraphvisitor_p.h @@ -66,24 +66,18 @@ class FrameGraphNode; class Renderer; class FrameGraphManager; -class FrameGraphVisitor +class Q_AUTOTEST_EXPORT FrameGraphVisitor { public: - explicit FrameGraphVisitor(Renderer *renderer, - const FrameGraphManager *nodeManager); + explicit FrameGraphVisitor(const FrameGraphManager *nodeManager); - void traverse(FrameGraphNode *root, - QVector *jobs); - - inline int leafNodeCount() Q_DECL_NOTHROW { return m_renderviewIndex; } + QVector traverse(FrameGraphNode *root); private: void visit(Render::FrameGraphNode *node); - Renderer *m_renderer; const FrameGraphManager *m_manager; - QVector *m_jobs; - int m_renderviewIndex; + QVector m_leaves; }; } // namespace Render -- cgit v1.2.3 From 4cbb05ca90ad675fdc2411c396eca15042847abe Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Wed, 26 Apr 2017 11:05:20 +0200 Subject: AssimpRawTextureImage: fix creation of QTextureImageDataPtr Change-Id: Idefb37f5b52acb3400f08d9bb6488d9339738b53 Task-number: QTBUG-59362 Reviewed-by: Kevin Ottens --- src/plugins/sceneparsers/assimp/assimpimporter.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/sceneparsers/assimp/assimpimporter.cpp b/src/plugins/sceneparsers/assimp/assimpimporter.cpp index 7e8681981..5d5593585 100644 --- a/src/plugins/sceneparsers/assimp/assimpimporter.cpp +++ b/src/plugins/sceneparsers/assimp/assimpimporter.cpp @@ -1297,8 +1297,9 @@ AssimpRawTextureImage::AssimpRawTextureImageFunctor::AssimpRawTextureImageFuncto QTextureImageDataPtr AssimpRawTextureImage::AssimpRawTextureImageFunctor::operator()() { - QTextureImageDataPtr dataPtr; - dataPtr->setData(m_data, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8); + QTextureImageDataPtr dataPtr = QTextureImageDataPtr::create(); + // Note: we assume 4 components per pixel and not compressed for now + dataPtr->setData(m_data, 4, false); return dataPtr; } -- cgit v1.2.3 From 9272c77091b58399e05d2843d4e627186f906507 Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Thu, 20 Apr 2017 09:21:12 +0200 Subject: Fix build for -no-feature-commandlineparser Change-Id: Ib84385167b2d71e460de87fbda58d59173385258 Reviewed-by: Kevin Ottens Reviewed-by: Sean Harmer --- tools/tools.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/tools.pro b/tools/tools.pro index 9c384630e..4dbd7496a 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -1,2 +1,2 @@ TEMPLATE = subdirs -!android:SUBDIRS += qgltf +qtConfig(commandlineparser):!android:SUBDIRS += qgltf -- cgit v1.2.3 From a6e9441c0fec1819b80cc69429de83d89680cf0a Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Thu, 20 Apr 2017 09:18:47 +0200 Subject: Fix warnings for -no-feature-library Change-Id: I5a6713fe6081c36fdae9dcb7b7671403f737e4c0 Reviewed-by: Kevin Ottens Reviewed-by: Sean Harmer --- src/input/frontend/qinputdeviceintegrationfactory.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/input/frontend/qinputdeviceintegrationfactory.cpp b/src/input/frontend/qinputdeviceintegrationfactory.cpp index 052f2d2b2..957b33542 100644 --- a/src/input/frontend/qinputdeviceintegrationfactory.cpp +++ b/src/input/frontend/qinputdeviceintegrationfactory.cpp @@ -74,6 +74,7 @@ QStringList QInputDeviceIntegrationFactory::keys(const QString &pluginPath) list.append(loader()->keyMap().values()); return list; #else + Q_UNUSED(pluginPath); return QStringList(); #endif } @@ -88,6 +89,10 @@ QInputDeviceIntegration *QInputDeviceIntegrationFactory::create(const QString &n } if (QInputDeviceIntegration *ret = qLoadPlugin(loader(), name, args)) return ret; +#else + Q_UNUSED(name); + Q_UNUSED(args); + Q_UNUSED(pluginPath); #endif return nullptr; } -- cgit v1.2.3 From c5108cb5300a32ac3dd0c2c1e42dcf1d35c1ac2f Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Thu, 20 Apr 2017 09:27:43 +0200 Subject: Fix build for -no-feature-temporaryfile Change-Id: I9e5bfc7636c10d0f0e39faf18b0b97bfb70f67d3 Reviewed-by: Kevin Ottens Reviewed-by: Sean Harmer --- src/plugins/sceneparsers/sceneparsers.pro | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/sceneparsers/sceneparsers.pro b/src/plugins/sceneparsers/sceneparsers.pro index befe08e41..bba802393 100644 --- a/src/plugins/sceneparsers/sceneparsers.pro +++ b/src/plugins/sceneparsers/sceneparsers.pro @@ -2,4 +2,9 @@ TEMPLATE = subdirs # QNX is not supported, and Linux GCC 4.9 on ARM chokes on the assimp # sources (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66964). config_assimp|!cross_compile: SUBDIRS += assimp -SUBDIRS += gltf gltfexport + +SUBDIRS += gltf + +qtConfig(temporaryfile) { + SUBDIRS += gltfexport +} -- cgit v1.2.3 From 34b3ea85829076b5d668c3940b1d1d7acc4b16d9 Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Thu, 20 Apr 2017 13:11:00 +0200 Subject: Fix build without quick module Change-Id: I5a2a5ac0d498e8ab5568d57cd2c16e83d947fe47 Reviewed-by: Kevin Ottens Reviewed-by: Sean Harmer --- src/src.pro | 160 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 84 insertions(+), 76 deletions(-) diff --git a/src/src.pro b/src/src.pro index 86a885e51..46c205849 100644 --- a/src/src.pro +++ b/src/src.pro @@ -23,63 +23,65 @@ src_extras.subdir = $$PWD/extras src_extras.target = src_extras src_extras.depends = src_render src_input src_logic -# Quick3D libs -src_quick3d_core.subdir = $$PWD/quick3d/quick3d -src_quick3d_core.target = sub-quick3d-core -src_quick3d_core.depends = src_core src_input - -src_quick3d_render.subdir = $$PWD/quick3d/quick3drender -src_quick3d_render.target = sub-quick3d-render -src_quick3d_render.depends = src_render src_quick3d_core - -src_quick3d_input.subdir = $$PWD/quick3d/quick3dinput -src_quick3d_input.target = sub-quick3d-input -src_quick3d_input.depends = src_input src_quick3d_core - -src_quick3d_animation.subdir = $$PWD/quick3d/quick3danimation -src_quick3d_animation.target = sub-quick3d-animation -src_quick3d_animation.depends = src_animation src_quick3d_core src_quick3d_render - -src_quick3d_extras.subdir = $$PWD/quick3d/quick3dextras -src_quick3d_extras.target = sub-quick3d-extras -src_quick3d_extras.depends = src_render src_logic src_input src_extras src_quick3d_core - -src_quick3d_scene2d.subdir = $$PWD/quick3d/quick3dscene2d -src_quick3d_scene2d.target = sub-quick3d-scene2d -src_quick3d_scene2d.depends = src_render src_logic src_input src_quick3d_core - -# Quick3D imports -src_quick3d_core_imports.file = $$PWD/quick3d/imports/core/importscore.pro -src_quick3d_core_imports.target = sub-quick3d-imports-core -src_quick3d_core_imports.depends = src_quick3d_core - -src_quick3d_imports_render.file = $$PWD/quick3d/imports/render/importsrender.pro -src_quick3d_imports_render.target = sub-quick3d-imports-render -src_quick3d_imports_render.depends = src_quick3d_render - -src_quick3d_imports_scene3d.file = $$PWD/quick3d/imports/scene3d/importsscene3d.pro -src_quick3d_imports_scene3d.target = sub-quick3d-imports-scene3d -src_quick3d_imports_scene3d.depends = src_quick3d_render src_input - -src_quick3d_imports_input.file = $$PWD/quick3d/imports/input/importsinput.pro -src_quick3d_imports_input.target = sub-quick3d-imports-input -src_quick3d_imports_input.depends = src_input src_quick3d_input - -src_quick3d_imports_logic.file = $$PWD/quick3d/imports/logic/importslogic.pro -src_quick3d_imports_logic.target = sub-quick3d-imports-logic -src_quick3d_imports_logic.depends = src_logic - -src_quick3d_imports_animation.file = $$PWD/quick3d/imports/animation/importsanimation.pro -src_quick3d_imports_animation.target = sub-quick3d-imports-animation -src_quick3d_imports_animation.depends = src_animation src_quick3d_animation - -src_quick3d_imports_extras.file = $$PWD/quick3d/imports/extras/importsextras.pro -src_quick3d_imports_extras.target = sub-quick3d-imports-extras -src_quick3d_imports_extras.depends = src_extras src_quick3d_extras - -src_quick3d_imports_scene2d.file = $$PWD/quick3d/imports/scene2d/importsscene2d.pro -src_quick3d_imports_scene2d.target = sub-quick3d-imports-scene2d -src_quick3d_imports_scene2d.depends = src_quick3d_scene2d +qtHaveModule(quick) { + # Quick3D libs + src_quick3d_core.subdir = $$PWD/quick3d/quick3d + src_quick3d_core.target = sub-quick3d-core + src_quick3d_core.depends = src_core src_input + + src_quick3d_render.subdir = $$PWD/quick3d/quick3drender + src_quick3d_render.target = sub-quick3d-render + src_quick3d_render.depends = src_render src_quick3d_core + + src_quick3d_input.subdir = $$PWD/quick3d/quick3dinput + src_quick3d_input.target = sub-quick3d-input + src_quick3d_input.depends = src_input src_quick3d_core + + src_quick3d_animation.subdir = $$PWD/quick3d/quick3danimation + src_quick3d_animation.target = sub-quick3d-animation + src_quick3d_animation.depends = src_animation src_quick3d_core src_quick3d_render + + src_quick3d_extras.subdir = $$PWD/quick3d/quick3dextras + src_quick3d_extras.target = sub-quick3d-extras + src_quick3d_extras.depends = src_render src_logic src_input src_extras src_quick3d_core + + src_quick3d_scene2d.subdir = $$PWD/quick3d/quick3dscene2d + src_quick3d_scene2d.target = sub-quick3d-scene2d + src_quick3d_scene2d.depends = src_render src_logic src_input src_quick3d_core + + # Quick3D imports + src_quick3d_core_imports.file = $$PWD/quick3d/imports/core/importscore.pro + src_quick3d_core_imports.target = sub-quick3d-imports-core + src_quick3d_core_imports.depends = src_quick3d_core + + src_quick3d_imports_render.file = $$PWD/quick3d/imports/render/importsrender.pro + src_quick3d_imports_render.target = sub-quick3d-imports-render + src_quick3d_imports_render.depends = src_quick3d_render + + src_quick3d_imports_scene3d.file = $$PWD/quick3d/imports/scene3d/importsscene3d.pro + src_quick3d_imports_scene3d.target = sub-quick3d-imports-scene3d + src_quick3d_imports_scene3d.depends = src_quick3d_render src_input + + src_quick3d_imports_input.file = $$PWD/quick3d/imports/input/importsinput.pro + src_quick3d_imports_input.target = sub-quick3d-imports-input + src_quick3d_imports_input.depends = src_input src_quick3d_input + + src_quick3d_imports_logic.file = $$PWD/quick3d/imports/logic/importslogic.pro + src_quick3d_imports_logic.target = sub-quick3d-imports-logic + src_quick3d_imports_logic.depends = src_logic + + src_quick3d_imports_animation.file = $$PWD/quick3d/imports/animation/importsanimation.pro + src_quick3d_imports_animation.target = sub-quick3d-imports-animation + src_quick3d_imports_animation.depends = src_animation src_quick3d_animation + + src_quick3d_imports_extras.file = $$PWD/quick3d/imports/extras/importsextras.pro + src_quick3d_imports_extras.target = sub-quick3d-imports-extras + src_quick3d_imports_extras.depends = src_extras src_quick3d_extras + + src_quick3d_imports_scene2d.file = $$PWD/quick3d/imports/scene2d/importsscene2d.pro + src_quick3d_imports_scene2d.target = sub-quick3d-imports-scene2d + src_quick3d_imports_scene2d.depends = src_quick3d_scene2d +} # Qt3D Scene Parser plugins src_plugins_sceneparsers.file = $$PWD/plugins/sceneparsers/sceneparsers.pro @@ -91,10 +93,12 @@ src_plugins_geometryloaders.file = $$PWD/plugins/geometryloaders/geometryloaders src_plugins_geometryloaders.target = sub-plugins-geometryloaders src_plugins_geometryloaders.depends = src_render src_extras -# Qt3D Render plugins -src_plugins_render.file = $$PWD/plugins/renderplugins/renderplugins.pro -src_plugins_render.target = sub-plugins-render -src_plugins_render.depends = src_render src_extras src_quick3d_render src_quick3d_scene2d +qtHaveModule(quick) { + # Qt3D Render plugins + src_plugins_render.file = $$PWD/plugins/renderplugins/renderplugins.pro + src_plugins_render.target = sub-plugins-render + src_plugins_render.depends = src_render src_extras src_quick3d_render src_quick3d_scene2d +} SUBDIRS += \ src_core \ @@ -103,21 +107,25 @@ SUBDIRS += \ src_input \ src_animation \ src_extras \ - src_quick3d_core \ - src_quick3d_core_imports \ - src_quick3d_render \ - src_quick3d_input \ - src_quick3d_animation \ - src_quick3d_extras \ - src_quick3d_imports_render \ - src_quick3d_imports_scene3d \ - src_quick3d_imports_input \ - src_quick3d_imports_logic \ - src_quick3d_imports_animation \ - src_quick3d_imports_extras \ src_plugins_sceneparsers \ src_plugins_geometryloaders \ - src_plugins_render \ - src_quick3d_scene2d \ - src_quick3d_imports_scene2d \ doc + +qtHaveModule(quick) { + SUBDIRS += \ + src_quick3d_core \ + src_quick3d_core_imports \ + src_quick3d_render \ + src_quick3d_input \ + src_quick3d_animation \ + src_quick3d_extras \ + src_quick3d_imports_render \ + src_quick3d_imports_scene3d \ + src_quick3d_imports_input \ + src_quick3d_imports_logic \ + src_quick3d_imports_animation \ + src_quick3d_imports_extras \ + src_plugins_render \ + src_quick3d_scene2d \ + src_quick3d_imports_scene2d +} -- cgit v1.2.3 From a6164a44f2c9ec0fac50060847ff91dcaa993d4a Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Thu, 20 Apr 2017 09:24:44 +0200 Subject: Fix build for -no-feature-shortcut Change-Id: I1ddd01924fc1d5667be7e0bba2540e24c2272bc3 Reviewed-by: Kevin Ottens Reviewed-by: Sean Harmer --- src/input/frontend/qkeyevent.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/input/frontend/qkeyevent.h b/src/input/frontend/qkeyevent.h index 23fed5545..e028438ce 100644 --- a/src/input/frontend/qkeyevent.h +++ b/src/input/frontend/qkeyevent.h @@ -78,7 +78,9 @@ public: inline bool isAccepted() const { return m_event.isAccepted(); } inline void setAccepted(bool accepted) { m_event.setAccepted(accepted); } inline QEvent::Type type() const { return m_event.type(); } +#if QT_CONFIG(shortcut) Q_INVOKABLE bool matches(QKeySequence::StandardKey key_) const { return m_event.matches(key_); } +#endif private: QT_PREPEND_NAMESPACE(QKeyEvent) m_event; -- cgit v1.2.3 From 7a79da942468621c58251f6daca1a00ca99d970a Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Thu, 20 Apr 2017 09:31:27 +0200 Subject: Fix build for -no-feature-gestures Change-Id: Ib0f0d7f21bf32b09f8dc6d3a4859d037b4e39af7 Reviewed-by: Kevin Ottens Reviewed-by: Tasuku Suzuki Reviewed-by: Sean Harmer --- src/input/frontend/qmouseevent.h | 8 +++++++- src/input/frontend/qmousehandler.cpp | 2 ++ src/render/jobs/pickboundingvolumejob.cpp | 4 ++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/input/frontend/qmouseevent.h b/src/input/frontend/qmouseevent.h index 043f1023d..de11c84a2 100644 --- a/src/input/frontend/qmouseevent.h +++ b/src/input/frontend/qmouseevent.h @@ -85,7 +85,13 @@ public: inline int x() const { return m_event.x(); } inline int y() const { return m_event.y(); } - inline bool wasHeld() const { return static_cast(m_event.type()) == Qt::TapAndHoldGesture; } + inline bool wasHeld() const { +#if QT_CONFIG(gestures) + return static_cast(m_event.type()) == Qt::TapAndHoldGesture; +#else + return false; +#endif + } Buttons button() const; int buttons() const; Modifiers modifiers() const; diff --git a/src/input/frontend/qmousehandler.cpp b/src/input/frontend/qmousehandler.cpp index 750251be9..fef56810c 100644 --- a/src/input/frontend/qmousehandler.cpp +++ b/src/input/frontend/qmousehandler.cpp @@ -83,9 +83,11 @@ void QMouseHandlerPrivate::mouseEvent(const QMouseEventPtr &event) m_pressAndHoldTimer->stop(); emit q->released(event.data()); break; +#if QT_CONFIG(gestures) case Qt::TapGesture: emit q->clicked(event.data()); break; +#endif case QEvent::MouseButtonDblClick: emit q->doubleClicked(event.data()); break; diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp index f6c469912..f9c7a390c 100644 --- a/src/render/jobs/pickboundingvolumejob.cpp +++ b/src/render/jobs/pickboundingvolumejob.cpp @@ -371,12 +371,12 @@ void PickBoundingVolumeJob::dispatchPickEvents(const QMouseEvent &event, } break; } - +#if QT_CONFIG(gestures) case Qt::TapGesture: { objectPicker->onClicked(pickEvent); break; } - +#endif case QEvent::MouseMove: { if ((objectPicker->isPressed() || objectPicker->isHoverEnabled()) && objectPicker->isDragEnabled()) { objectPicker->onMoved(pickEvent); -- cgit v1.2.3 From 9b478e9179522315ea53fe10ec1278a1f77753f8 Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Thu, 20 Apr 2017 10:30:24 +0200 Subject: Fix build for -no-feature-wheelevent Change-Id: I72591f43c0e2c4cc6e3e589f8d8e52fbb1041666 Reviewed-by: Kevin Ottens Reviewed-by: Tasuku Suzuki Reviewed-by: Sean Harmer --- src/input/backend/inputhandler.cpp | 20 ++++++++++++++++---- src/input/backend/inputhandler_p.h | 4 ++++ src/input/backend/mousedevice.cpp | 2 ++ src/input/backend/mousedevice_p.h | 2 ++ src/input/backend/mouseeventdispatcherjob.cpp | 11 +++++++++-- src/input/backend/mouseeventdispatcherjob_p.h | 9 +++++++-- src/input/backend/mouseeventfilter.cpp | 2 ++ src/input/backend/mousehandler.cpp | 2 ++ src/input/backend/mousehandler_p.h | 2 ++ src/input/frontend/qmouseevent.cpp | 2 ++ src/input/frontend/qmouseevent.h | 5 +++++ src/input/frontend/qmousehandler.cpp | 2 ++ src/input/frontend/qmousehandler.h | 2 ++ src/quick3d/imports/input/qt3dquick3dinputplugin.cpp | 2 ++ 14 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/input/backend/inputhandler.cpp b/src/input/backend/inputhandler.cpp index 985d67470..525a45b6c 100644 --- a/src/input/backend/inputhandler.cpp +++ b/src/input/backend/inputhandler.cpp @@ -163,6 +163,7 @@ void InputHandler::clearPendingMouseEvents() m_pendingMouseEvents.clear(); } +#if QT_CONFIG(wheelevent) void InputHandler::appendWheelEvent(const QT_PREPEND_NAMESPACE(QWheelEvent) &event) { QMutexLocker lock(&m_mutex); @@ -180,7 +181,7 @@ void InputHandler::clearPendingWheelEvents() QMutexLocker lock(&m_mutex); m_pendingWheelEvents.clear(); } - +#endif void InputHandler::appendKeyboardDevice(HKeyboardDevice device) { @@ -249,15 +250,23 @@ QVector InputHandler::mouseJobs() { QVector jobs; const QList mouseEvents = pendingMouseEvents(); +#if QT_CONFIG(wheelevent) const QList wheelEvents = pendingWheelEvents(); +#endif for (const HMouseDevice cHandle : qAsConst(m_activeMouseDevices)) { MouseDevice *controller = m_mouseDeviceManager->data(cHandle); controller->updateMouseEvents(mouseEvents); +#if QT_CONFIG(wheelevent) controller->updateWheelEvents(wheelEvents); +#endif // Event dispacthing job - if (!mouseEvents.isEmpty() || !wheelEvents.empty()) { + if (!mouseEvents.isEmpty() +#if QT_CONFIG(wheelevent) + || !wheelEvents.empty() +#endif + ) { // Send the events to the mouse handlers that have for sourceDevice controller const QVector activeMouseHandlers = m_mouseInputManager->activeHandles(); for (HMouseHandler mouseHandlerHandle : activeMouseHandlers) { @@ -267,8 +276,11 @@ QVector InputHandler::mouseJobs() if (mouseHandler->mouseDevice() == controller->peerId()) { MouseEventDispatcherJob *job = new MouseEventDispatcherJob(mouseHandler->peerId(), - mouseEvents, - wheelEvents); + mouseEvents +#if QT_CONFIG(wheelevent) + , wheelEvents +#endif + ); job->setInputHandler(this); jobs.append(QAspectJobPtr(job)); } diff --git a/src/input/backend/inputhandler_p.h b/src/input/backend/inputhandler_p.h index e80441f1a..a2a38262d 100644 --- a/src/input/backend/inputhandler_p.h +++ b/src/input/backend/inputhandler_p.h @@ -127,9 +127,11 @@ public: QList pendingMouseEvents(); void clearPendingMouseEvents(); +#if QT_CONFIG(wheelevent) void appendWheelEvent(const QT_PREPEND_NAMESPACE(QWheelEvent) &event); QList pendingWheelEvents(); void clearPendingWheelEvents(); +#endif void appendKeyboardDevice(HKeyboardDevice device); void removeKeyboardDevice(HKeyboardDevice device); @@ -170,7 +172,9 @@ private: QList m_pendingKeyEvents; QList m_pendingMouseEvents; +#if QT_CONFIG(wheelevent) QList m_pendingWheelEvents; +#endif mutable QMutex m_mutex; AxisManager *m_axisManager; diff --git a/src/input/backend/mousedevice.cpp b/src/input/backend/mousedevice.cpp index 1d329252d..128988637 100644 --- a/src/input/backend/mousedevice.cpp +++ b/src/input/backend/mousedevice.cpp @@ -135,6 +135,7 @@ float MouseDevice::sensitivity() const return m_sensitivity; } +#if QT_CONFIG(wheelevent) void MouseDevice::updateWheelEvents(const QList &events) { // Reset axis values before we accumulate new values for this frame @@ -147,6 +148,7 @@ void MouseDevice::updateWheelEvents(const QList &events) { diff --git a/src/input/backend/mousedevice_p.h b/src/input/backend/mousedevice_p.h index 0b95c6183..a085194ff 100644 --- a/src/input/backend/mousedevice_p.h +++ b/src/input/backend/mousedevice_p.h @@ -99,7 +99,9 @@ public: bool isButtonPressed(int buttonIdentifier) const Q_DECL_OVERRIDE; void updateMouseEvents(const QList &events); +#if QT_CONFIG(wheelevent) void updateWheelEvents(const QList &events); +#endif MouseState mouseState() const; QPointF previousPos() const; diff --git a/src/input/backend/mouseeventdispatcherjob.cpp b/src/input/backend/mouseeventdispatcherjob.cpp index 77eb69712..11653d8a8 100644 --- a/src/input/backend/mouseeventdispatcherjob.cpp +++ b/src/input/backend/mouseeventdispatcherjob.cpp @@ -50,13 +50,18 @@ namespace Qt3DInput { namespace Input { MouseEventDispatcherJob::MouseEventDispatcherJob(Qt3DCore::QNodeId input, - const QList &mouseEvents, - const QList &wheelEvents) + const QList &mouseEvents +#if QT_CONFIG(wheelevent) + , const QList &wheelEvents +#endif + ) : QAspectJob() , m_inputHandler(nullptr) , m_mouseInput(input) , m_mouseEvents(mouseEvents) +#if QT_CONFIG(wheelevent) , m_wheelEvents(wheelEvents) +#endif { SET_JOB_RUN_STAT_TYPE(this, JobTypes::MouseEventDispatcher, 0); } @@ -73,8 +78,10 @@ void MouseEventDispatcherJob::run() // Send mouse and wheel events to frontend for (const QT_PREPEND_NAMESPACE(QMouseEvent) &e : m_mouseEvents) input->mouseEvent(QMouseEventPtr(new QMouseEvent(e))); +#if QT_CONFIG(wheelevent) for (const QT_PREPEND_NAMESPACE(QWheelEvent) &e : m_wheelEvents) input->wheelEvent(QWheelEventPtr(new QWheelEvent(e))); +#endif } } diff --git a/src/input/backend/mouseeventdispatcherjob_p.h b/src/input/backend/mouseeventdispatcherjob_p.h index ebf1538e4..366774005 100644 --- a/src/input/backend/mouseeventdispatcherjob_p.h +++ b/src/input/backend/mouseeventdispatcherjob_p.h @@ -66,8 +66,11 @@ class MouseEventDispatcherJob : public Qt3DCore::QAspectJob { public: explicit MouseEventDispatcherJob(Qt3DCore::QNodeId input, - const QList &mouseEvents, - const QList &wheelEvents); + const QList &mouseEvents +#if QT_CONFIG(wheelevent) + , const QList &wheelEvents +#endif + ); void setInputHandler(InputHandler *handler); void run() Q_DECL_FINAL; @@ -75,7 +78,9 @@ private: InputHandler *m_inputHandler; const Qt3DCore::QNodeId m_mouseInput; const QList m_mouseEvents; +#if QT_CONFIG(wheelevent) const QList m_wheelEvents; +#endif }; } // namespace Input diff --git a/src/input/backend/mouseeventfilter.cpp b/src/input/backend/mouseeventfilter.cpp index bc2473a33..618a64b15 100644 --- a/src/input/backend/mouseeventfilter.cpp +++ b/src/input/backend/mouseeventfilter.cpp @@ -80,10 +80,12 @@ bool MouseEventFilter::eventFilter(QObject *obj, QEvent *e) // Creates copy and store event to be processed later on in an InputAspect job m_inputHandler->appendMouseEvent(QMouseEvent(*static_cast(e))); break; +#if QT_CONFIG(wheelevent) case QEvent::Wheel: // Creates copy and store event to be processed later on in an InputAspect job m_inputHandler->appendWheelEvent(QWheelEvent(*static_cast(e))); break; +#endif default: break; } diff --git a/src/input/backend/mousehandler.cpp b/src/input/backend/mousehandler.cpp index a0619aaf2..c492dcf28 100644 --- a/src/input/backend/mousehandler.cpp +++ b/src/input/backend/mousehandler.cpp @@ -91,6 +91,7 @@ void MouseHandler::mouseEvent(const QMouseEventPtr &event) notifyObservers(e); } +#if QT_CONFIG(wheelevent) void MouseHandler::wheelEvent(const QWheelEventPtr &event) { auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); @@ -99,6 +100,7 @@ void MouseHandler::wheelEvent(const QWheelEventPtr &event) e->setValue(QVariant::fromValue(event)); notifyObservers(e); } +#endif void MouseHandler::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) { diff --git a/src/input/backend/mousehandler_p.h b/src/input/backend/mousehandler_p.h index 867764017..ae484d8d6 100644 --- a/src/input/backend/mousehandler_p.h +++ b/src/input/backend/mousehandler_p.h @@ -70,7 +70,9 @@ public: Qt3DCore::QNodeId mouseDevice() const; void setInputHandler(InputHandler *handler); void mouseEvent(const QMouseEventPtr &event); +#if QT_CONFIG(wheelevent) void wheelEvent(const QWheelEventPtr &event); +#endif protected: void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE; diff --git a/src/input/frontend/qmouseevent.cpp b/src/input/frontend/qmouseevent.cpp index b1574f623..62f7a097e 100644 --- a/src/input/frontend/qmouseevent.cpp +++ b/src/input/frontend/qmouseevent.cpp @@ -455,6 +455,7 @@ QMouseEvent::Modifiers QMouseEvent::modifiers() const * Returns the QEvent::Type of the event. */ +#if QT_CONFIG(wheelevent) /*! * Constructs a new QWheelEvent instance from the QWheelEvent \a e. */ @@ -497,6 +498,7 @@ QWheelEvent::Modifiers QWheelEvent::modifiers() const return QWheelEvent::NoModifier; } } +#endif // QT_CONFIG(wheelevent) } // namespace Qt3DInput diff --git a/src/input/frontend/qmouseevent.h b/src/input/frontend/qmouseevent.h index de11c84a2..63786ac28 100644 --- a/src/input/frontend/qmouseevent.h +++ b/src/input/frontend/qmouseevent.h @@ -106,6 +106,7 @@ private: typedef QSharedPointer QMouseEventPtr; +#if QT_CONFIG(wheelevent) class QT3DINPUTSHARED_EXPORT QWheelEvent : public QObject { Q_OBJECT @@ -154,12 +155,16 @@ private: }; typedef QSharedPointer QWheelEventPtr; +#endif } // namespace Qt3DInput QT_END_NAMESPACE Q_DECLARE_METATYPE(Qt3DInput::QMouseEvent*) // LCOV_EXCL_LINE + +#if QT_CONFIG(wheelevent) Q_DECLARE_METATYPE(Qt3DInput::QWheelEvent*) // LCOV_EXCL_LINE +#endif #endif // QT3DINPUT_QMOUSEEVENT_H diff --git a/src/input/frontend/qmousehandler.cpp b/src/input/frontend/qmousehandler.cpp index fef56810c..419052d8a 100644 --- a/src/input/frontend/qmousehandler.cpp +++ b/src/input/frontend/qmousehandler.cpp @@ -313,9 +313,11 @@ void QMouseHandler::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) if (e->propertyName() == QByteArrayLiteral("mouse")) { QMouseEventPtr ev = e->value().value(); d->mouseEvent(ev); +#if QT_CONFIG(wheelevent) } else if (e->propertyName() == QByteArrayLiteral("wheel")) { QWheelEventPtr ev = e->value().value(); emit wheel(ev.data()); +#endif } } } diff --git a/src/input/frontend/qmousehandler.h b/src/input/frontend/qmousehandler.h index 750ed394d..ef4267c5c 100644 --- a/src/input/frontend/qmousehandler.h +++ b/src/input/frontend/qmousehandler.h @@ -82,7 +82,9 @@ Q_SIGNALS: void pressAndHold(Qt3DInput::QMouseEvent *mouse); void positionChanged(Qt3DInput::QMouseEvent *mouse); +#if QT_CONFIG(wheelevent) void wheel(Qt3DInput::QWheelEvent *wheel); +#endif protected: void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) Q_DECL_OVERRIDE; diff --git a/src/quick3d/imports/input/qt3dquick3dinputplugin.cpp b/src/quick3d/imports/input/qt3dquick3dinputplugin.cpp index 9d83f964f..5719a2b98 100644 --- a/src/quick3d/imports/input/qt3dquick3dinputplugin.cpp +++ b/src/quick3d/imports/input/qt3dquick3dinputplugin.cpp @@ -81,7 +81,9 @@ void Qt3DQuick3DInputPlugin::registerTypes(const char *uri) qmlRegisterType(uri, 2, 0, "InputSettings"); qmlRegisterUncreatableType(uri, 2, 0, "MouseEvent", QStringLiteral("Events cannot be created")); +#if QT_CONFIG(wheelevent) qmlRegisterUncreatableType(uri, 2, 0, "WheelEvent", QStringLiteral("Events cannot be created")); +#endif qmlRegisterType(uri, 2, 0, "MouseHandler"); qmlRegisterType(uri, 2, 0, "MouseDevice"); -- cgit v1.2.3 From 16e3a51154651e2ce08dfce2944bc37ea3165b6b Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Mon, 17 Apr 2017 20:39:21 +0100 Subject: Document the QAbstractClipAnimator class Change-Id: I731946acd392a3c164e71513b431e4d7e2a7034a Reviewed-by: Paul Lemire --- src/animation/frontend/qabstractclipanimator.cpp | 96 ++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/src/animation/frontend/qabstractclipanimator.cpp b/src/animation/frontend/qabstractclipanimator.cpp index 307f2d2f3..d032e3afe 100644 --- a/src/animation/frontend/qabstractclipanimator.cpp +++ b/src/animation/frontend/qabstractclipanimator.cpp @@ -53,6 +53,57 @@ QAbstractClipAnimatorPrivate::QAbstractClipAnimatorPrivate() { } +/*! + \qmltype AbsractClipAnimator + \instantiates Qt3DAnimation::QAbstractClipAnimator + \inqmlmodule Qt3D.Animation + \since 5.9 + + \brief AbstractClipAnimator is the base class for types providing animation playback + capabilities. + + Subclasses of AbstractClipAnimator can be aggregated by an Entity to + provide animation capabilities. The animator components provide an + interface for controlling the animation (e.g. start, stop). Each animator + type requires some form of animation data such as an AbstractAnimationClip + as well as a ChannelMapper which describes how the channels in the + animation clip should be mapped onto the properties of the objects you wish + to animate. + + The following subclasses are available: + + \list + \li Qt3D.Animation.ClipAnimator + \li Qt3D.Animation.BlendedClipAnimator + \endlist +*/ + +/*! + \class Qt3DAnimation::QAbstractClipAnimator + \inherits Qt3DCore::QComponent + + \inmodule Qt3DAnimation + \since 5.9 + + \brief QAbstractClipAnimator is the base class for types providing animation playback + capabilities. + + Subclasses of QAbstractClipAnimator can be aggregated by a QEntity to + provide animation capabilities. The animator components provide an + interface for controlling the animation (e.g. start, stop). Each animator + type requires some form of animation data such as a QAbstractAnimationClip + as well as a QChannelMapper which describes how the channels in the + animation clip should be mapped onto the properties of the objects you wish + to animate. + + The following subclasses are available: + + \list + \li Qt3DAnimation::QClipAnimator + \li Qt3DAnimation::QBlendedClipAnimator + \endlist +*/ + QAbstractClipAnimator::QAbstractClipAnimator(Qt3DCore::QNode *parent) : Qt3DCore::QComponent(*new QAbstractClipAnimatorPrivate, parent) { @@ -67,18 +118,63 @@ QAbstractClipAnimator::~QAbstractClipAnimator() { } +/*! + \qmlproperty bool running + + This property holds whether the animation is currently running. +*/ + +/*! + \property running + + This property holds whether the animation is currently running. +*/ bool QAbstractClipAnimator::isRunning() const { Q_D(const QAbstractClipAnimator); return d->m_running; } +/*! + \property ChannelMapper channelMapper + + This property holds the ChannelMapper that controls how the channels in + the animation clip map onto the properties of the target objects. +*/ + +/*! + \property channelMapper + + This property holds the QChannelMapper that controls how the channels in + the animation clip map onto the properties of the target objects. +*/ QChannelMapper *QAbstractClipAnimator::channelMapper() const { Q_D(const QAbstractClipAnimator); return d->m_mapper; } +/*! + \qmlproperty int loops + + This property holds the number of times the animation should play. + + By default, loops is 1: the animation will play through once and then stop. + + If set to QAbstractClipAnimator::Infinite, the animation will continuously + repeat until it is explicitly stopped. +*/ + +/*! + \property loops + + This property holds the number of times the animation should play. + + By default, loops is 1: the animation will play through once and then stop. + + If set to QAbstractClipAnimator::Infinite, the animation will continuously + repeat until it is explicitly stopped. +*/ int QAbstractClipAnimator::loopCount() const { Q_D(const QAbstractClipAnimator); -- cgit v1.2.3 From 311261ea1faf6e4a9928d3a97cbca3190703cf04 Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Mon, 17 Apr 2017 20:47:03 +0100 Subject: Add imperative slots to control animator running property Change-Id: I6fc8a5860421eb881a1b7d299f771ad88a278027 Reviewed-by: Paul Lemire --- src/animation/frontend/qabstractclipanimator.cpp | 16 ++++++++++++++++ src/animation/frontend/qabstractclipanimator.h | 3 +++ 2 files changed, 19 insertions(+) diff --git a/src/animation/frontend/qabstractclipanimator.cpp b/src/animation/frontend/qabstractclipanimator.cpp index d032e3afe..0d215b470 100644 --- a/src/animation/frontend/qabstractclipanimator.cpp +++ b/src/animation/frontend/qabstractclipanimator.cpp @@ -220,6 +220,22 @@ void QAbstractClipAnimator::setLoopCount(int loops) emit loopCountChanged(loops); } +/*! + Starts the animation. +*/ +void QAbstractClipAnimator::start() +{ + setRunning(true); +} + +/*! + Stops the animation. +*/ +void QAbstractClipAnimator::stop() +{ + setRunning(false); +} + } // namespace Qt3DAnimation QT_END_NAMESPACE diff --git a/src/animation/frontend/qabstractclipanimator.h b/src/animation/frontend/qabstractclipanimator.h index 805fcb2b3..bd38fd68b 100644 --- a/src/animation/frontend/qabstractclipanimator.h +++ b/src/animation/frontend/qabstractclipanimator.h @@ -73,6 +73,9 @@ public Q_SLOTS: void setChannelMapper(Qt3DAnimation::QChannelMapper *channelMapper); void setLoopCount(int loops); + void start(); + void stop(); + Q_SIGNALS: void runningChanged(bool running); void channelMapperChanged(Qt3DAnimation::QChannelMapper *channelMapper); -- cgit v1.2.3 From 14c00da0a623a74f01337cb5dd8c7fa506197014 Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Wed, 19 Apr 2017 18:43:17 +0100 Subject: Document QClipAnimator Change-Id: Iac75f836033e07c2d525c495e4cf0656a5ab11f5 Reviewed-by: Paul Lemire --- src/animation/frontend/qclipanimator.cpp | 62 ++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/animation/frontend/qclipanimator.cpp b/src/animation/frontend/qclipanimator.cpp index 4dcc4b578..eb6c80aee 100644 --- a/src/animation/frontend/qclipanimator.cpp +++ b/src/animation/frontend/qclipanimator.cpp @@ -52,11 +52,59 @@ QClipAnimatorPrivate::QClipAnimatorPrivate() { } +/*! + \qmltype ClipAnimator + \instantiates Qt3DAnimation::QClipAnimator + \inqmlmodule Qt3D.Animation + \since 5.9 + + \brief ClipAnimator is a component providing simple animation playback capabilities. + + An instance of ClipAnimator can be aggregated by an Entity to add the ability to play back + animation clips and to apply the calculated animation values to properties of QObjects. + + The animation key frame data is provided via the clip property. This can be created + programmatically with AnimationClip or loaded from file with AnimationClipLoader. + + In order to apply the values played back from the channels of data in the animation clip, the + clip animator needs to have a ChannelMapper object assigned to the channelMapper property. + + The properties for controlling the animator are provided by the AbstractClipAnimator base + class. + + \sa AbstractClipAnimator, AbstractAnimationClip, ChannelMapper, BlendedClipAnimator +*/ + +/*! + \class Qt3DAnimation::QClipAnimator + \inherits Qt3DAnimation::QAbstractClipAnimator + + \inmodule Qt3DAnimation + \since 5.9 + + \brief QClipAnimator is a component providing simple animation playback capabilities. + + An instance of QClipAnimator can be aggregated by a QEntity to add the ability to play back + animation clips and to apply the calculated animation values to properties of QObjects. + + The animation key frame data is provided via the clip property. This can be created + programmatically with QAnimationClip or loaded from file with QAnimationClipLoader. + + In order to apply the values played back from the channels of data in the animation clip, the + clip animator needs to have a QChannelMapper object assigned to the channelMapper property. + + The properties for controlling the animator are provided by the QAbstractClipAnimator base + class. + + \sa QAbstractClipAnimator, QAbstractAnimationClip, QChannelMapper, QBlendedClipAnimator +*/ + QClipAnimator::QClipAnimator(Qt3DCore::QNode *parent) : Qt3DAnimation::QAbstractClipAnimator(*new QClipAnimatorPrivate, parent) { } +/*! \internal */ QClipAnimator::QClipAnimator(QClipAnimatorPrivate &dd, Qt3DCore::QNode *parent) : Qt3DAnimation::QAbstractClipAnimator(dd, parent) { @@ -66,6 +114,19 @@ QClipAnimator::~QClipAnimator() { } +/*! + \qmlproperty AbstractAnimationClip clip + + This property holds the animation clip which contains the key frame data to be played back. + The key frame data can be specified in either an AnimationClip or AnimationClipLoader. +*/ + +/*! + \property clip + + This property holds the animation clip which contains the key frame data to be played back. + The key frame data can be specified in either a QAnimationClip or QAnimationClipLoader. +*/ QAbstractAnimationClip *QClipAnimator::clip() const { Q_D(const QClipAnimator); @@ -91,6 +152,7 @@ void QClipAnimator::setClip(QAbstractAnimationClip *clip) emit clipChanged(clip); } +/*! \internal */ Qt3DCore::QNodeCreatedChangeBasePtr QClipAnimator::createNodeCreationChange() const { auto creationChange = Qt3DCore::QNodeCreatedChangePtr::create(this); -- cgit v1.2.3 From 6ccffde7abdfbddf6768293a813a382527ad591b Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Wed, 19 Apr 2017 19:27:58 +0100 Subject: Document QBlendedClipAnimator Change-Id: Ic2505c1f2bfbcf3790f38634cf58b41c219c3525 Reviewed-by: Paul Lemire --- src/animation/frontend/qblendedclipanimator.cpp | 208 +++++++++++++++++++++++- 1 file changed, 199 insertions(+), 9 deletions(-) diff --git a/src/animation/frontend/qblendedclipanimator.cpp b/src/animation/frontend/qblendedclipanimator.cpp index 971f4e1e7..e6b127bf1 100644 --- a/src/animation/frontend/qblendedclipanimator.cpp +++ b/src/animation/frontend/qblendedclipanimator.cpp @@ -55,32 +55,208 @@ QBlendedClipAnimatorPrivate::QBlendedClipAnimatorPrivate() \qmltype BlendedClipAnimator \instantiates Qt3DAnimation::QBlendedClipAnimator \inqmlmodule Qt3D.Animation + \since 5.9 - \brief Performs an animation based on a tree of blend nodes + \brief BlendedClipAnimator is a component providing animation playback capabilities of a tree + of blend nodes. - \note The blend node tree should only be edited when the clip is not - running + An instance of BlendedClipAnimator can be aggregated by an Entity to add the ability to play + back animation clips and to apply the calculated animation values to properties of QObjects. - \since 5.9 + Whereas a ClipAnimator gets its animation data from a single animation clip, + BlendedClipAnimator can blend together multiple clips. The animation data is obtained by + evaluating a so called \e {blend tree}. A blend tree is a hierarchical tree structure where the + leaf nodes are value nodes that encapsulate an animation clip (AbstractAnimationClip); and the + internal nodes represent blending operations that operate on the nodes pointed to by their + operand properties. + + To associate a blend tree with a BlendedClipAnimator, set the animator's blendTree property to + point at the root node of your blend tree: + + \badcode + BlendedClipAnimator { + blendTree: AdditiveClipBlend { + .... + } + } + \endcode + + A blend tree can be constructed from the following node types: + + \note The blend node tree should only be edited when the animator is not running. + + \list + \li Qt3D.Animation.ClipBlendValue + \li Qt3D.Animation.LerpClipBlend + \li Qt3D.Animation.AdditiveClipBlend + \endlist + + Additional node types will be added over time. + + As an example consider the following blend tree: + + \badcode + Clip0---- + | + Lerp Node---- + | | + Clip1---- Additive Node + | + Clip2---- + \endcode + + This can be created and used as follows: + + \badcode + BlendedClipAnimator { + blendTree: AdditiveClipBlend { + baseClip: LerpClipBlend { + startClip: ClipBlendValue { + clip: AnimationClipLoader { source: "walk.json" } + } + + endClip: ClipBlendValue { + clip: AnimationClipLoader { source: "run.json" } + } + } + + additiveClip: ClipBlendValue { + clip: AnimationClipLoader { source: "wave-arm.json" } + } + } + + channelMapper: ChannelMapper {...} + running: true + } + \endcode + + By authoring a set of animation clips and blending between them dynamically at runtime with a + blend tree, we open up a huge set of possible resulting animations. As some simple examples of + the above blend tree, where alpha is the additive factor and beta is the lerp blend factor we + can get a 2D continuum of possible animations: + + \badcode + (alpha = 0, beta = 1) Running, No arm waving --- (alpha = 1, beta = 1) Running, Arm waving + | | + | | + | | + (alpha = 0, beta = 0) Walking, No arm waving --- (alpha = 0, beta = 1) Running, No arm waving + \endcode + + More complex blend trees offer even more flexibility for combining your animation clips. Note + that the values used to control the blend tree (alpha and beta above) are simple properties on + the blend nodes. This means, that these properties themselves can also be controlled by + the animation framework. */ /*! \class Qt3DAnimation::QBlendedClipAnimator + \inherits Qt3DAnimation::QAbstractClipAnimator + \inmodule Qt3DAnimation - \inherits Qt3DCore::QComponent + \since 5.9 - \brief Performs an animation based on a tree of blend nodes + \brief QBlendedClipAnimator is a component providing animation playback capabilities of a tree + of blend nodes. - \note The blend node tree should only be edited when the clip is not - running + An instance of QBlendedClipAnimator can be aggregated by a QEntity to add the ability to play + back animation clips and to apply the calculated animation values to properties of QObjects. + + Whereas a QClipAnimator gets its animation data from a single animation clip, + QBlendedClipAnimator can blend together multiple clips. The animation data is obtained by + evaluating a so called \e {blend tree}. A blend tree is a hierarchical tree structure where the + leaf nodes are value nodes that encapsulate an animation clip (QAbstractAnimationClip); and the + internal nodes represent blending operations that operate on the nodes pointed to by their + operand properties. + + To associate a blend tree with a QBlendedClipAnimator, set the animator's blendTree property to + point at the root node of your blend tree: + + \badcode + auto blendTreeRoot = new QAdditiveClipBlend(); + ... + auto animator = new QBlendedClipAnimator(); + animator->setBlendTree(blendTreeRoot); + \endcode + + A blend tree can be constructed from the following node types: + + \note The blend node tree should only be edited when the animator is not running. + + \list + \li Qt3DAnimation::QClipBlendValue + \li Qt3DAnimation::QLerpClipBlend + \li Qt3DAnimation::QAdditiveClipBlend + \endlist + + Additional node types will be added over time. + + As an example consider the following blend tree: + + \badcode + Clip0---- + | + Lerp Node---- + | | + Clip1---- Additive Node + | + Clip2---- + \endcode + + This can be created and used as follows: + + \code + // Create leaf nodes of blend tree + auto clip0 = new QClipBlendValue( + new QAnimationClipLoader(QUrl::fromLocalFile("walk.json"))); + auto clip1 = new QClipBlendValue( + new QAnimationClipLoader(QUrl::fromLocalFile("run.json"))); + auto clip2 = new QClipBlendValue( + new QAnimationClipLoader(QUrl::fromLocalFile("wave-arm.json"))); + + // Create blend tree inner nodes + auto lerpNode = new QLerpClipBlend(); + lerpNode->setStartClip(clip0); + lerpNode->setEndClip(clip1); + lerpNode->setBlendFactor(0.5f); // Half-walk, half-run + + auto additiveNode = new QAdditiveClipBlend(); + additiveNode->setBaseClip(lerpNode); // Comes from lerp sub-tree + additiveNode->setAdditiveClip(clip2); + additiveNode->setAdditiveFactor(1.0f); // Wave arm fully + + // Run the animator + auto animator = new QBlendedClipAnimator(); + animator->setBlendTree(additiveNode); + animator->setChannelMapper(...); + animator->setRunning(true); + \endcode + + By authoring a set of animation clips and blending between them dynamically at runtime with a + blend tree, we open up a huge set of possible resulting animations. As some simple examples of + the above blend tree, where alpha is the additive factor and beta is the lerp blend factor we + can get a 2D continuum of possible animations: + + \badcode + (alpha = 0, beta = 1) Running, No arm waving --- (alpha = 1, beta = 1) Running, Arm waving + | | + | | + | | + (alpha = 0, beta = 0) Walking, No arm waving --- (alpha = 0, beta = 1) Running, No arm waving + \endcode + + More complex blend trees offer even more flexibility for combining your animation clips. Note + that the values used to control the blend tree (alpha and beta above) are simple properties on + the blend nodes. This means, that these properties themselves can also be controlled by + the animation framework. - \since 5.9 */ QBlendedClipAnimator::QBlendedClipAnimator(Qt3DCore::QNode *parent) : Qt3DAnimation::QAbstractClipAnimator(*new QBlendedClipAnimatorPrivate, parent) { } +/*! \internal */ QBlendedClipAnimator::QBlendedClipAnimator(QBlendedClipAnimatorPrivate &dd, Qt3DCore::QNode *parent) : Qt3DAnimation::QAbstractClipAnimator(dd, parent) { @@ -90,6 +266,19 @@ QBlendedClipAnimator::~QBlendedClipAnimator() { } +/*! + \qmlproperty AbstractClipBlendNode blendTree + + This property holds the root of the animation blend tree that will be evaluated before being + interpolated by the animator. +*/ + +/*! + \property blendTree + + This property holds the root of the animation blend tree that will be evaluated before being + interpolated by the animator. +*/ QAbstractClipBlendNode *QBlendedClipAnimator::blendTree() const { Q_D(const QBlendedClipAnimator); @@ -116,6 +305,7 @@ void QBlendedClipAnimator::setBlendTree(QAbstractClipBlendNode *blendTree) emit blendTreeChanged(blendTree); } +/*! \internal */ Qt3DCore::QNodeCreatedChangeBasePtr QBlendedClipAnimator::createNodeCreationChange() const { auto creationChange = Qt3DCore::QNodeCreatedChangePtr::create(this); -- cgit v1.2.3 From f8862fac6366853d4b204a1e3c9e948ae5ba309b Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Sat, 22 Apr 2017 11:49:20 +0100 Subject: Document QAbstractClipBlendNode Change-Id: I15a95fed8500824e0eb0a5294c4725e6263a247c Reviewed-by: Paul Lemire --- src/animation/frontend/qabstractclipblendnode.cpp | 71 +++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/src/animation/frontend/qabstractclipblendnode.cpp b/src/animation/frontend/qabstractclipblendnode.cpp index 9cc6f3de6..9860e969f 100644 --- a/src/animation/frontend/qabstractclipblendnode.cpp +++ b/src/animation/frontend/qabstractclipblendnode.cpp @@ -46,11 +46,82 @@ QAbstractClipBlendNodePrivate::QAbstractClipBlendNodePrivate() { } +/*! + \qmltype AbstractClipBlendNode + \instantiates Qt3DAnimation::QAbstractClipBlendNode + \inqmlmodule Qt3D.Animation + \since 5.9 + + \brief AbstractClipBlendNode is the base class for types used to construct animation blend + trees. + + Animation blend trees are used with a BlendedClipAnimator to dynamically blend a set of + animation clips together. The way in which the blending of animation clips is performed is + controlled by the structure of the blend tree and the properties on the nodes it contains. + + The leaf nodes in a blend tree are containers for the input animation clips. These clips can be + baked clips read from file via AnimationClipLoader, or they can be clips that you build within + your application with AnimatitonClip and AnimationClipData. To include a clip in your blend + tree, wrap it in a ClipBlendValue node. + + The interior nodes of a blend tree represent blending operations that will be applied to their + arguments which hold the input clips or even entire sub-trees of other blend tree nodes. + + At present, the Qt 3D Animation module provides the following blend tree node types: + + \list + \li Qt3D.Animation.ClipBlendValue + \li Qt3D.Animation.LerpClipBlend + \li Qt3D.Animation.QAdditiveClipBlend + \endlist + + Additional node types representing other blending operations will be added in the future. + + \sa BlendedClipAnimator +*/ + +/*! + \class Qt3DAnimation::QAbstractClipBlendNode + \inherits Qt3DCore::QNode + + \inmodule Qt3DAnimation + \since 5.9 + + \brief QAbstractClipBlendNode is the base class for types used to construct animation blend + trees. + + Animation blend trees are used with a QBlendedClipAnimator to dynamically blend a set of + animation clips together. The way in which the blending of animation clips is performed is + controlled by the structure of the blend tree and the properties on the nodes it contains. + + The leaf nodes in a blend tree are containers for the input animation clips. These clips can be + baked clips read from file via QAnimationClipLoader, or they can be clips that you build within + your application with QAnimatitonClip and QAnimationClipData. To include a clip in your blend + tree, wrap it in a QClipBlendValue node. + + The interior nodes of a blend tree represent blending operations that will be applied to their + arguments which hold the input clips or even entire sub-trees of other blend tree nodes. + + At present, the Qt 3D Animation module provides the following blend tree node types: + + \list + \li Qt3DAnimation::QClipBlendValue + \li Qt3DAnimation::QLerpClipBlend + \li Qt3DAnimation::QAdditiveClipBlend + \endlist + + Additional node types representing other blending operations will be added in the future. + + \sa QBlendedClipAnimator +*/ + +/*! \internal */ QAbstractClipBlendNode::QAbstractClipBlendNode(Qt3DCore::QNode *parent) : Qt3DCore::QNode(*new QAbstractClipBlendNodePrivate(), parent) { } +/*! \internal */ QAbstractClipBlendNode::QAbstractClipBlendNode(QAbstractClipBlendNodePrivate &dd, Qt3DCore::QNode *parent) : Qt3DCore::QNode(dd, parent) { -- cgit v1.2.3 From cf29e6c74aa8e65480110df65086346485a90803 Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Mon, 24 Apr 2017 14:07:37 +0100 Subject: Document QAdditiveClipBlend Change-Id: I8cc48899e31a32f6c1dd9f4f56e3a5fa846bd8f4 Reviewed-by: Paul Lemire --- src/animation/frontend/qadditiveclipblend.cpp | 123 ++++++++++++++++---------- 1 file changed, 74 insertions(+), 49 deletions(-) diff --git a/src/animation/frontend/qadditiveclipblend.cpp b/src/animation/frontend/qadditiveclipblend.cpp index ee207eb42..58ef5e577 100644 --- a/src/animation/frontend/qadditiveclipblend.cpp +++ b/src/animation/frontend/qadditiveclipblend.cpp @@ -48,39 +48,67 @@ namespace Qt3DAnimation { \instantiates Qt3DAnimation::QAdditiveClipBlend \inqmlmodule Qt3D.Animation - \brief Performs an addition of two animation clips based on a - normalized factor - \since 5.9 - AdditiveClipBlend can be useful to create advanced animation effects based on - individual animation clips. For instance, given a player character, additive - blending could be used to combine a walking animation clip with an injured - animation clip based on a blend factor that increases the more the player - gets injured. This would then allow with blend factor == 0 to have a non - injured walking player, with blend factor == 1 a fully injured player, with - blend factor == 0.5 a partially walking and injured player. + \brief Performs an additive blend of two animation clips based on an additive factor. + + QAdditiveClipBlend can be useful to create advanced animation effects based on + individual animation clips. For example, if you: + + \list + \li set the baseClip property to a normal walk cycle animation clip and + \li set the additiveClip property to a shaking head difference clip, + \endlist + + then adjusting the additiveFactor property will control how much of the additiveClip gets added + on to the baseClip. This has he effect that with an additiveFactor of zero, this blend node will + yield the original walk cycle clip. With an additiveFactor of 1, it will yield the walk cycle + including a shaking head animation. + + The blending operation implemented by this class is: + + \badcode + resultClip = baseClip + additiveFactor * additiveClip + \endcode + + There is nothing stopping you from using values for the additiveFacor property outside the 0 to + 1 range, but please be aware that the input animation clips may not be authored in such a way + for this to make sense. \sa BlendedClipAnimator */ /*! \class Qt3DAnimation::QAdditiveClipBlend - \inmodule Qt3DAnimation \inherits Qt3DAnimation::QAbstractClipBlendNode - \brief Performs an addition of two animation clips based on a - normalized factor - + \inmodule Qt3DAnimation \since 5.9 + \brief Performs an additive blend of two animation clips based on an additive factor. + QAdditiveClipBlend can be useful to create advanced animation effects based on - individual animation clips. For instance, given a player character, additive - blending could be used to combine a walking animation clip with an injured - animation clip based on a blend factor that increases the more the player - gets injured. This would then allow with blend factor == 0 to have a non - injured walking player, with blend factor == 1 a fully injured player, with - blend factor == 0.5 a partially walking and injured player. + individual animation clips. For example, if you: + + \list + \li set the baseClip property to a normal walk cycle animation clip and + \li set the additiveClip property to a shaking head difference clip, + \endlist + + then adjusting the additiveFactor property will control how much of the additiveClip gets added + on to the baseClip. This has he effect that with an additiveFactor of zero, this blend node will + yield the original walk cycle clip. With an additiveFactor of 1, it will yield the walk cycle + including a shaking head animation. + + The blending operation implemented by this class is: + + \badcode + resultClip = baseClip + additiveFactor * additiveClip + \endcode + + There is nothing stopping you from using values for the additiveFacor property outside the 0 to + 1 range, but please be aware that the input animation clips may not be authored in such a way + for this to make sense. \sa QBlendedClipAnimator */ @@ -121,13 +149,13 @@ Qt3DCore::QNodeCreatedChangeBasePtr QAdditiveClipBlend::createNodeCreationChange /*! \qmlproperty real AdditiveClipBlend::additiveFactor - Specifies the blending factor between 0 and 1 to control the blending of + Specifies the blending factor, typically between 0 and 1, to control the blending of two animation clips. */ /*! \property QAdditiveClipBlend::additiveFactor - Specifies the blending factor between 0 and 1 to control the blending of + Specifies the blending factor, typically between 0 and 1, to control the blending of two animation clips. */ float QAdditiveClipBlend::additiveFactor() const @@ -136,12 +164,36 @@ float QAdditiveClipBlend::additiveFactor() const return d->m_additiveFactor; } +/*! + \qmlproperty AbstractClipBlendNode baseClip + + This property holds the base animation clip. When the additiveFacgtor is zero the baseClip will + also be the resulting clip of this blend node. +*/ +/*! + \property baseClip + + This property holds the base animation clip. When the additiveFacgtor is zero the baseClip will + also be the resulting clip of this blend node. +*/ QAbstractClipBlendNode *QAdditiveClipBlend::baseClip() const { Q_D(const QAdditiveClipBlend); return d->m_baseClip; } +/*! + \qmlproperty AbstractClipBlendNode additiveClip + + This property holds the additive clip to be blended with the baseClip. The amount of blending + is controlled by the additiveFactor property. +*/ +/*! + \property additiveClip + + This property holds the additive clip to be blended with the baseClip. The amount of blending + is controlled by the additiveFactor property. +*/ QAbstractClipBlendNode *QAdditiveClipBlend::additiveClip() const { Q_D(const QAdditiveClipBlend); @@ -197,33 +249,6 @@ void QAdditiveClipBlend::setAdditiveClip(QAbstractClipBlendNode *additiveClip) emit additiveClipChanged(additiveClip); } -/*! - \qmlproperty list AdditiveClipBlend::clips - - Holds the list of AnimationClip nodes against which the blending is performed. - - \note Only the two first AnimationClip are used, subsequent ones are ignored -*/ - - -/*! - \fn void QAdditiveClipBlend::addClip(QAnimationClip *clip); - Adds a \a clip to the blending node's clips list. - - \note Only the two first AnimationClip are used, subsequent ones are ignored - */ - -/*! - \fn void QAdditiveClipBlend::removeClip(QAnimationClip *clip); - Removes a \a clip from the blending node's clips list. - */ - -/*! - \fn QVector QAdditiveClipBlend::clips() const; - Returns the list of QAnimationClip against which the blending is performed. - */ - - } // Qt3DAnimation QT_END_NAMESPACE -- cgit v1.2.3 From e138c89c5f75e62c873dfe77e1e4c2e39b7b5f6c Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Thu, 20 Apr 2017 09:29:05 +0200 Subject: Fix build for -no-feature-regularexpression Change-Id: Icff3f2bb2886ba4e077fb43f9a406592435f6fff Reviewed-by: Kevin Ottens Reviewed-by: Sean Harmer --- src/plugins/geometryloaders/geometryloaders.pro | 2 +- src/plugins/sceneparsers/sceneparsers.pro | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/geometryloaders/geometryloaders.pro b/src/plugins/geometryloaders/geometryloaders.pro index 8dd99deb5..764c615da 100644 --- a/src/plugins/geometryloaders/geometryloaders.pro +++ b/src/plugins/geometryloaders/geometryloaders.pro @@ -1,4 +1,4 @@ TEMPLATE = subdirs -SUBDIRS += default +qtConfig(regularexpression) : SUBDIRS += default SUBDIRS += gltf qtConfig(qt3d-fbxsdk) : SUBDIRS += fbx diff --git a/src/plugins/sceneparsers/sceneparsers.pro b/src/plugins/sceneparsers/sceneparsers.pro index bba802393..7b50f654e 100644 --- a/src/plugins/sceneparsers/sceneparsers.pro +++ b/src/plugins/sceneparsers/sceneparsers.pro @@ -5,6 +5,6 @@ config_assimp|!cross_compile: SUBDIRS += assimp SUBDIRS += gltf -qtConfig(temporaryfile) { +qtConfig(temporaryfile):qtConfig(regularexpression) { SUBDIRS += gltfexport } -- cgit v1.2.3 From 873caffc95b6e279d68851cc0a8ed738980ebd0c Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Thu, 27 Apr 2017 14:03:48 +0100 Subject: Fix -Werror=unused-parameter issue Change-Id: Ibc77241e8d369224eda790b8dcfd900f330bed37 Reviewed-by: Paul Lemire --- src/extras/text/qdistancefieldglyphcache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extras/text/qdistancefieldglyphcache.cpp b/src/extras/text/qdistancefieldglyphcache.cpp index aacccc7dc..9c997013e 100644 --- a/src/extras/text/qdistancefieldglyphcache.cpp +++ b/src/extras/text/qdistancefieldglyphcache.cpp @@ -61,7 +61,7 @@ namespace Qt3DExtras { class StoredGlyph { public: StoredGlyph() = default; - StoredGlyph(const StoredGlyph &other) = default; + StoredGlyph(const StoredGlyph &) = default; StoredGlyph(const QRawFont &font, quint32 glyph, bool doubleResolution); int refCount() const { return m_ref; } -- cgit v1.2.3 From 80e4d6db6b5636b839cef7e79b2b8ff528329ad6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A4=C3=A4tt=C3=A4=20Antti?= Date: Tue, 18 Apr 2017 10:09:47 +0300 Subject: Modify configure to build with no assimp Add -no-assimp configure to build without assimp. Task-number: QTBUG-60128 Change-Id: I2ca7bb68d3b659e18bd79039beb5cb6623473859 Reviewed-by: Sean Harmer --- src/core/configure.json | 2 +- src/plugins/sceneparsers/sceneparsers.pro | 5 +++-- tools/tools.pro | 4 +++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/core/configure.json b/src/core/configure.json index 86b31223f..47a726d82 100644 --- a/src/core/configure.json +++ b/src/core/configure.json @@ -4,7 +4,7 @@ "commandline": { "options": { - "assimp": { "type": "enum", "values": [ "qt", "system" ] }, + "assimp": { "type": "enum", "values": [ "qt", "system", "no" ] }, "qt3d-profile-jobs": "boolean", "qt3d-profile-gl": "boolean" } diff --git a/src/plugins/sceneparsers/sceneparsers.pro b/src/plugins/sceneparsers/sceneparsers.pro index 7b50f654e..cb274b472 100644 --- a/src/plugins/sceneparsers/sceneparsers.pro +++ b/src/plugins/sceneparsers/sceneparsers.pro @@ -1,8 +1,9 @@ TEMPLATE = subdirs # QNX is not supported, and Linux GCC 4.9 on ARM chokes on the assimp # sources (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66964). -config_assimp|!cross_compile: SUBDIRS += assimp - +QT_FOR_CONFIG += 3dcore-private +qtConfig(assimp):if(qtConfig(system-assimp)|!cross_compile): \ + SUBDIRS += assimp SUBDIRS += gltf qtConfig(temporaryfile):qtConfig(regularexpression) { diff --git a/tools/tools.pro b/tools/tools.pro index 4dbd7496a..8e973aecb 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -1,2 +1,4 @@ TEMPLATE = subdirs -qtConfig(commandlineparser):!android:SUBDIRS += qgltf +QT_FOR_CONFIG += 3dcore-private +!android:qtConfig(assimp):qtConfig(commandlineparser): \ + SUBDIRS += qgltf -- cgit v1.2.3 From b5800ac037321e161d31ee362688aef179c8d9d2 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Thu, 27 Apr 2017 10:43:29 +0200 Subject: Renderer: fix OnDemand rendering Note: this is a risky change For some reason the renderer assumed that a RenderQueue would never have a size of 0. This prevented the renderer from calling proceedToNextFrame() on the vsync advance service as it somehow felt that it was a case of rendering with a RenderQueue not yet ready. In the case of OnDemand rendering it is perfectly valid to have a RenderQueue of 0 (nothing has changed that requires rendering) but we still need to call proceedToNextFrame() otherwise syncChanges() is never called and we end up never updating the aspects ever again. The renderer was updated to 1) check if a RenderQueue is complete 2) check if the RenderQueue is empty. (a RenderQueue can be complete but empty (OnDemand case)) 3) Proceed to next frame if RenderQueue is complete or RenderQueue is empty. Change-Id: I27ae778831c9b136db1e1a69892f6fde291fd965 Task-number: QTBUG-59696 Task-number: QTBUG-54900 Reviewed-by: Sean Harmer --- src/render/backend/renderer.cpp | 145 +++++++++++----------- src/render/backend/renderer_p.h | 4 +- src/render/backend/renderqueue.cpp | 6 +- src/render/backend/renderqueue_p.h | 4 + tests/auto/render/renderqueue/tst_renderqueue.cpp | 6 + 5 files changed, 89 insertions(+), 76 deletions(-) diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp index e40d5d68e..4080a72eb 100644 --- a/src/render/backend/renderer.cpp +++ b/src/render/backend/renderer.cpp @@ -536,17 +536,26 @@ void Renderer::render() void Renderer::doRender() { - bool submissionSucceeded = false; - bool hasCleanedQueueAndProceeded = false; Renderer::ViewSubmissionResultData submissionData; + bool hasCleanedQueueAndProceeded = false; bool preprocessingComplete = false; - - if (isReadyToSubmit()) { - - // Lock the mutex to protect access to m_surface and check if we are still set - // to the running state and that we have a valid surface on which to draw - // TO DO: Is that still needed given the surface changes - QMutexLocker locker(&m_mutex); + bool beganDrawing = false; + const bool canSubmit = isReadyToSubmit(); + + // Lock the mutex to protect access to the renderQueue while we look for its state + QMutexLocker locker(&m_renderQueueMutex); + const bool queueIsComplete = m_renderQueue->isFrameQueueComplete(); + const bool queueIsEmpty = m_renderQueue->targetRenderViewCount() == 0; + + // When using synchronous rendering (QtQuick) + // We are not sure that the frame queue is actually complete + // Since a call to render may not be synched with the completions + // of the RenderViewJobs + // In such a case we return early, waiting for a next call with + // the frame queue complete at this point + + // RenderQueue is complete (but that means it may be of size 0) + if (canSubmit && (queueIsComplete && !queueIsEmpty)) { const QVector renderViews = m_renderQueue->nextFrameQueue(); #ifdef QT3D_JOBS_RUN_STATS @@ -561,8 +570,7 @@ void Renderer::doRender() submissionStatsPart2.jobId.typeAndInstance[1] = 0; submissionStatsPart2.threadId = reinterpret_cast(QThread::currentThreadId()); #endif - - if (canRender() && (submissionSucceeded = renderViews.size() > 0) == true) { + if (canRender()) { // Clear all dirty flags but Compute so that // we still render every frame when a compute shader is used in a scene BackendNodeDirtySet changesToUnset = m_changeSet; @@ -584,7 +592,8 @@ void Renderer::doRender() // Reset state for each draw if we don't have complete control of the context if (!m_ownedContext) m_graphicsContext->setCurrentStateSet(nullptr); - if (m_graphicsContext->beginDrawing(surface)) { + beganDrawing = m_graphicsContext->beginDrawing(surface); + if (beganDrawing) { // 1) Execute commands for buffer uploads, texture updates, shader loading first updateGLResources(); // 2) Update VAO and copy data into commands to allow concurrent submission @@ -595,6 +604,7 @@ void Renderer::doRender() } // 2) Proceed to next frame and start preparing frame n + 1 m_renderQueue->reset(); + locker.unlock(); // Done protecting RenderQueue m_vsyncFrameAdvanceService->proceedToNextFrame(); hasCleanedQueueAndProceeded = true; @@ -638,61 +648,57 @@ void Renderer::doRender() #endif } - // Note: submissionSucceeded is false when - // * we cannot render because a shutdown has been scheduled - // * the renderqueue is incomplete (only when rendering with a Scene3D) - // Otherwise returns true even for cases like - // * No render view - // * No surface set - // * OpenGLContext failed to be set current - // This behavior is important as we need to - // call proceedToNextFrame despite rendering errors that aren't fatal - // Only reset renderQueue and proceed to next frame if the submission - // succeeded or it we are using a render thread and that is wasn't performed + // succeeded or if we are using a render thread and that is wasn't performed // already - // If submissionSucceeded isn't true this implies that something went wrong + // If hasCleanedQueueAndProceeded isn't true this implies that something went wrong // with the rendering and/or the renderqueue is incomplete from some reason // (in the case of scene3d the render jobs may be taking too long ....) - if (m_renderThread || submissionSucceeded) { - - if (!hasCleanedQueueAndProceeded) { - // Reset the m_renderQueue so that we won't try to render - // with a queue used by a previous frame with corrupted content - // if the current queue was correctly submitted - m_renderQueue->reset(); - - // We allow the RenderTickClock service to proceed to the next frame - // In turn this will allow the aspect manager to request a new set of jobs - // to be performed for each aspect - m_vsyncFrameAdvanceService->proceedToNextFrame(); - } + // or alternatively it could be complete but empty (RenderQueue of size 0) + if (!hasCleanedQueueAndProceeded && + (m_renderThread || queueIsComplete || queueIsEmpty)) { + // RenderQueue was full but something bad happened when + // trying to render it and therefore proceedToNextFrame was not called + // Note: in this case the renderQueue mutex is still locked + + // Reset the m_renderQueue so that we won't try to render + // with a queue used by a previous frame with corrupted content + // if the current queue was correctly submitted + m_renderQueue->reset(); + + // We allow the RenderTickClock service to proceed to the next frame + // In turn this will allow the aspect manager to request a new set of jobs + // to be performed for each aspect + m_vsyncFrameAdvanceService->proceedToNextFrame(); + } - // Perform the last swapBuffers calls after the proceedToNextFrame - // as this allows us to gain a bit of time for the preparation of the - // next frame + // Perform the last swapBuffers calls after the proceedToNextFrame + // as this allows us to gain a bit of time for the preparation of the + // next frame + // Finish up with last surface used in the list of RenderViews + if (beganDrawing) { + SurfaceLocker surfaceLock(submissionData.surface); // Finish up with last surface used in the list of RenderViews - if (submissionSucceeded) { - SurfaceLocker surfaceLock(submissionData.surface); - // Finish up with last surface used in the list of RenderViews - m_graphicsContext->endDrawing(submissionData.lastBoundFBOId == m_graphicsContext->defaultFBO() && surfaceLock.isSurfaceValid()); - } + m_graphicsContext->endDrawing(submissionData.lastBoundFBOId == m_graphicsContext->defaultFBO() && surfaceLock.isSurfaceValid()); } } // Called by RenderViewJobs +// When the frameQueue is complete and we are using a renderThread +// we allow the render thread to proceed void Renderer::enqueueRenderView(Render::RenderView *renderView, int submitOrder) { - QMutexLocker locker(&m_mutex); // Prevent out of order execution + QMutexLocker locker(&m_renderQueueMutex); // Prevent out of order execution // We cannot use a lock free primitive here because: // - QVector is not thread safe // - Even if the insert is made correctly, the isFrameComplete call // could be invalid since depending on the order of execution // the counter could be complete but the renderview not yet added to the // buffer depending on whichever order the cpu decides to process this - - if (m_renderQueue->queueRenderView(renderView, submitOrder)) { + const bool isQueueComplete = m_renderQueue->queueRenderView(renderView, submitOrder); + locker.unlock(); // We're done protecting the queue at this point + if (isQueueComplete) { if (m_renderThread && m_running.load()) Q_ASSERT(m_submitRenderViewsSemaphore.available() == 0); m_submitRenderViewsSemaphore.release(1); @@ -731,16 +737,6 @@ bool Renderer::isReadyToSubmit() // something to render // The case of shutdown should have been handled just before Q_ASSERT(m_renderQueue->isFrameQueueComplete()); - } else { - // When using synchronous rendering (QtQuick) - // We are not sure that the frame queue is actually complete - // Since a call to render may not be synched with the completions - // of the RenderViewJobs - // In such a case we return early, waiting for a next call with - // the frame queue complete at this point - QMutexLocker locker(&m_mutex); - if (!m_renderQueue->isFrameQueueComplete()) - return false; } return true; } @@ -1431,22 +1427,25 @@ QVector Renderer::renderBinJobs() renderBinJobs.push_back(m_textureGathererJob); renderBinJobs.push_back(m_shaderGathererJob); - // Traverse the current framegraph. For each leaf node create a - // RenderView and set its configuration then create a job to - // populate the RenderView with a set of RenderCommands that get - // their details from the RenderNodes that are visible to the - // Camera selected by the framegraph configuration - FrameGraphVisitor visitor(m_nodesManager->frameGraphManager()); - const QVector fgLeaves = visitor.traverse(frameGraphRoot()); - - const int fgBranchCount = fgLeaves.size(); - for (int i = 0; i < fgBranchCount; ++i) { - RenderViewBuilder builder(fgLeaves.at(i), i, this); - renderBinJobs.append(builder.buildJobHierachy()); - } + QMutexLocker lock(&m_renderQueueMutex); + if (m_renderQueue->wasReset()) { // Have we rendered yet? (Scene3D case) + // Traverse the current framegraph. For each leaf node create a + // RenderView and set its configuration then create a job to + // populate the RenderView with a set of RenderCommands that get + // their details from the RenderNodes that are visible to the + // Camera selected by the framegraph configuration + FrameGraphVisitor visitor(m_nodesManager->frameGraphManager()); + const QVector fgLeaves = visitor.traverse(frameGraphRoot()); + + const int fgBranchCount = fgLeaves.size(); + for (int i = 0; i < fgBranchCount; ++i) { + RenderViewBuilder builder(fgLeaves.at(i), i, this); + renderBinJobs.append(builder.buildJobHierachy()); + } - // Set target number of RenderViews - m_renderQueue->setTargetRenderViewCount(fgBranchCount); + // Set target number of RenderViews + m_renderQueue->setTargetRenderViewCount(fgBranchCount); + } return renderBinJobs; } diff --git a/src/render/backend/renderer_p.h b/src/render/backend/renderer_p.h index 9df24ef2c..af10108e9 100644 --- a/src/render/backend/renderer_p.h +++ b/src/render/backend/renderer_p.h @@ -259,7 +259,7 @@ public: ViewSubmissionResultData submitRenderViews(const QVector &renderViews); - QMutex* mutex() { return &m_mutex; } + QMutex* mutex() { return &m_renderQueueMutex; } #ifdef QT3D_RENDER_UNIT_TESTS @@ -290,7 +290,7 @@ private: QScopedPointer m_renderThread; QScopedPointer m_vsyncFrameAdvanceService; - QMutex m_mutex; + QMutex m_renderQueueMutex; QSemaphore m_submitRenderViewsSemaphore; QSemaphore m_waitForInitializationToBeCompleted; diff --git a/src/render/backend/renderqueue.cpp b/src/render/backend/renderqueue.cpp index 6ec7da464..2fa1cb7d2 100644 --- a/src/render/backend/renderqueue.cpp +++ b/src/render/backend/renderqueue.cpp @@ -49,6 +49,7 @@ namespace Render { RenderQueue::RenderQueue() : m_noRender(false) + , m_wasReset(true) , m_targetRenderViewCount(0) , m_currentRenderViewCount(0) , m_currentWorkQueue(1) @@ -70,6 +71,7 @@ void RenderQueue::reset() m_targetRenderViewCount = 0; m_currentWorkQueue.clear(); m_noRender = false; + m_wasReset = true; } void RenderQueue::setNoRender() @@ -88,6 +90,7 @@ bool RenderQueue::queueRenderView(RenderView *renderView, uint submissionOrderIn Q_ASSERT(!m_noRender); m_currentWorkQueue[submissionOrderIndex] = renderView; ++m_currentRenderViewCount; + Q_ASSERT(m_currentRenderViewCount <= m_targetRenderViewCount); return isFrameQueueComplete(); } @@ -109,6 +112,7 @@ void RenderQueue::setTargetRenderViewCount(int targetRenderViewCount) Q_ASSERT(!m_noRender); m_targetRenderViewCount = targetRenderViewCount; m_currentWorkQueue.resize(targetRenderViewCount); + m_wasReset = false; } /*! @@ -119,7 +123,7 @@ void RenderQueue::setTargetRenderViewCount(int targetRenderViewCount) bool RenderQueue::isFrameQueueComplete() const { return (m_noRender - || (m_targetRenderViewCount && m_targetRenderViewCount == currentRenderViewCount())); + || (m_targetRenderViewCount > 0 && m_targetRenderViewCount == m_currentRenderViewCount)); } } // namespace Render diff --git a/src/render/backend/renderqueue_p.h b/src/render/backend/renderqueue_p.h index 49316049b..611f5849a 100644 --- a/src/render/backend/renderqueue_p.h +++ b/src/render/backend/renderqueue_p.h @@ -77,9 +77,13 @@ public: void reset(); void setNoRender(); + inline bool isNoRender() const { return m_noRender; } + + inline bool wasReset() const { return m_wasReset; } private: bool m_noRender; + bool m_wasReset; int m_targetRenderViewCount; int m_currentRenderViewCount; QVector m_currentWorkQueue; diff --git a/tests/auto/render/renderqueue/tst_renderqueue.cpp b/tests/auto/render/renderqueue/tst_renderqueue.cpp index 2d25cbe57..163a699c1 100644 --- a/tests/auto/render/renderqueue/tst_renderqueue.cpp +++ b/tests/auto/render/renderqueue/tst_renderqueue.cpp @@ -55,10 +55,14 @@ void tst_RenderQueue::setRenderViewCount() // GIVEN Qt3DRender::Render::RenderQueue renderQueue; + // THEN + QCOMPARE(renderQueue.wasReset(), true); + // WHEN renderQueue.setTargetRenderViewCount(7); // THEN + QCOMPARE(renderQueue.wasReset(), false); QVERIFY(renderQueue.targetRenderViewCount() == 7); QVERIFY(renderQueue.currentRenderViewCount()== 0); } @@ -214,6 +218,7 @@ void tst_RenderQueue::resetQueue() // WHEN renderQueue.setTargetRenderViewCount(5); // THEN + QCOMPARE(renderQueue.wasReset(), false); QVERIFY(renderQueue.currentRenderViewCount() == 0); // WHEN @@ -227,6 +232,7 @@ void tst_RenderQueue::resetQueue() // WHEN renderQueue.reset(); + QCOMPARE(renderQueue.wasReset(), true); // THEN QVERIFY(renderQueue.currentRenderViewCount() == 0); } -- cgit v1.2.3 From 54b097b495ca483123bf38966232428267428944 Mon Sep 17 00:00:00 2001 From: Mike Krus Date: Mon, 1 May 2017 13:38:43 +0100 Subject: Add missing Q_OBJECT (clazy reports) Change-Id: I0bc49e1b391c610a8f8f649a45391b31f9283302 Reviewed-by: Sean Harmer --- src/core/services/qabstractframeadvanceservice_p.h | 1 + src/core/services/qeventfilterservice_p.h | 1 + src/core/services/qopenglinformationservice_p.h | 1 + src/core/services/qsysteminformationservice_p.h | 1 + src/core/services/qtickclockservice_p.h | 1 + src/render/raycasting/qabstractcollisionqueryservice_p.h | 1 + 6 files changed, 6 insertions(+) diff --git a/src/core/services/qabstractframeadvanceservice_p.h b/src/core/services/qabstractframeadvanceservice_p.h index a5f635710..dac72a98d 100644 --- a/src/core/services/qabstractframeadvanceservice_p.h +++ b/src/core/services/qabstractframeadvanceservice_p.h @@ -64,6 +64,7 @@ class QAbstractFrameAdvanceServicePrivate; class QT3DCORESHARED_EXPORT QAbstractFrameAdvanceService : public QAbstractServiceProvider { + Q_OBJECT public: virtual qint64 waitForNextFrame() = 0; virtual void start() = 0; diff --git a/src/core/services/qeventfilterservice_p.h b/src/core/services/qeventfilterservice_p.h index 5f779c9cd..58b87d9cc 100644 --- a/src/core/services/qeventfilterservice_p.h +++ b/src/core/services/qeventfilterservice_p.h @@ -63,6 +63,7 @@ class QEventFilterServicePrivate; class QT3DCORESHARED_EXPORT QEventFilterService : public QAbstractServiceProvider { + Q_OBJECT public: QEventFilterService(); ~QEventFilterService(); diff --git a/src/core/services/qopenglinformationservice_p.h b/src/core/services/qopenglinformationservice_p.h index c84c5ed10..2adf73307 100644 --- a/src/core/services/qopenglinformationservice_p.h +++ b/src/core/services/qopenglinformationservice_p.h @@ -65,6 +65,7 @@ class QOpenGLInformationServicePrivate; class QT3DCORESHARED_EXPORT QOpenGLInformationService : public QAbstractServiceProvider { + Q_OBJECT public: virtual QSurfaceFormat format() const = 0; diff --git a/src/core/services/qsysteminformationservice_p.h b/src/core/services/qsysteminformationservice_p.h index 0ab737817..01e976b77 100644 --- a/src/core/services/qsysteminformationservice_p.h +++ b/src/core/services/qsysteminformationservice_p.h @@ -64,6 +64,7 @@ class QSystemInformationServicePrivate; class QT3DCORESHARED_EXPORT QSystemInformationService : public QAbstractServiceProvider { + Q_OBJECT public: virtual QStringList aspectNames() const = 0; virtual int threadPoolThreadCount() const = 0; diff --git a/src/core/services/qtickclockservice_p.h b/src/core/services/qtickclockservice_p.h index 53f3cf310..6f02643f4 100644 --- a/src/core/services/qtickclockservice_p.h +++ b/src/core/services/qtickclockservice_p.h @@ -61,6 +61,7 @@ class QTickClockServicePrivate; class QTickClockService : public QAbstractFrameAdvanceService { + Q_OBJECT public: QTickClockService(); ~QTickClockService(); diff --git a/src/render/raycasting/qabstractcollisionqueryservice_p.h b/src/render/raycasting/qabstractcollisionqueryservice_p.h index 806c33d5b..1c1261937 100644 --- a/src/render/raycasting/qabstractcollisionqueryservice_p.h +++ b/src/render/raycasting/qabstractcollisionqueryservice_p.h @@ -79,6 +79,7 @@ public: class QT3DRENDERSHARED_EXPORT QAbstractCollisionQueryService : public Qt3DCore::QAbstractServiceProvider { + Q_OBJECT public: enum QueryMode { FirstHit, -- cgit v1.2.3 From 1cf81a67af6540d496439deeb43dab4028ff4bfb Mon Sep 17 00:00:00 2001 From: Mike Krus Date: Mon, 1 May 2017 13:39:56 +0100 Subject: Add missing emit (clazy reports) Change-Id: I3e893a8dff15f4822ba1cde102a50d16daf042ee Reviewed-by: Sean Harmer --- src/render/frontend/qlevelofdetail.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/frontend/qlevelofdetail.cpp b/src/render/frontend/qlevelofdetail.cpp index df169876e..07dcdf82e 100644 --- a/src/render/frontend/qlevelofdetail.cpp +++ b/src/render/frontend/qlevelofdetail.cpp @@ -442,7 +442,7 @@ void QLevelOfDetail::setThresholds(const QVector &thresholds) Q_D(QLevelOfDetail); if (d->m_thresholds != thresholds) { d->m_thresholds = thresholds; - thresholdsChanged(d->m_thresholds); + emit thresholdsChanged(d->m_thresholds); } } -- cgit v1.2.3 From cb7dbc2e40f8258e92a79e8ac46d99a3b65c2a8c Mon Sep 17 00:00:00 2001 From: Mike Krus Date: Mon, 1 May 2017 14:00:48 +0100 Subject: Add missing reference in range-for with non trivial type (clazy reports) Change-Id: Ib014b4ad7adc6604e600afc489e3dafaf0e299c1 Reviewed-by: Sean Harmer --- src/animation/backend/animationclip_p.h | 2 +- src/animation/backend/animationutils.cpp | 2 +- src/animation/backend/fcurve_p.h | 2 +- src/plugins/sceneparsers/gltf/gltfimporter.cpp | 4 +-- .../sceneparsers/gltfexport/gltfexporter.cpp | 34 +++++++++++----------- src/render/backend/renderviewbuilder.cpp | 18 ++++++------ src/render/framegraph/rendercapture.cpp | 2 +- src/render/frontend/qrenderaspect.cpp | 2 +- 8 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/animation/backend/animationclip_p.h b/src/animation/backend/animationclip_p.h index 286ec38c0..7ff79c01a 100644 --- a/src/animation/backend/animationclip_p.h +++ b/src/animation/backend/animationclip_p.h @@ -127,7 +127,7 @@ inline QDebug operator<<(QDebug dbg, const AnimationClip &animationClip) << "Channels:" << endl; const QVector channels = animationClip.channels(); - for (const auto channel : channels) { + for (const auto &channel : channels) { dbg << channel; } diff --git a/src/animation/backend/animationutils.cpp b/src/animation/backend/animationutils.cpp index c9c7c29d4..1f675f271 100644 --- a/src/animation/backend/animationutils.cpp +++ b/src/animation/backend/animationutils.cpp @@ -197,7 +197,7 @@ ClipResults evaluateClipAtLocalTime(AnimationClip *clip, float localTime) const QVector &channels = clip->channels(); int i = 0; for (const Channel &channel : channels) { - for (const auto channelComponent : qAsConst(channel.channelComponents)) + for (const auto &channelComponent : qAsConst(channel.channelComponents)) channelResults[i++] = channelComponent.fcurve.evaluateAtTime(localTime); } return channelResults; diff --git a/src/animation/backend/fcurve_p.h b/src/animation/backend/fcurve_p.h index 7bc6ccccb..7ab1593d1 100644 --- a/src/animation/backend/fcurve_p.h +++ b/src/animation/backend/fcurve_p.h @@ -146,7 +146,7 @@ inline QDebug operator<<(QDebug dbg, const Channel &channel) dbg << "Channel Name: " << channel.name << endl << "Channels:" << channel.channelComponents.size() << endl; - for (const auto channelComponent : qAsConst(channel.channelComponents)) { + for (const auto &channelComponent : qAsConst(channel.channelComponents)) { dbg << channelComponent; } return dbg; diff --git a/src/plugins/sceneparsers/gltf/gltfimporter.cpp b/src/plugins/sceneparsers/gltf/gltfimporter.cpp index 916589ffa..5c209aa8a 100644 --- a/src/plugins/sceneparsers/gltf/gltfimporter.cpp +++ b/src/plugins/sceneparsers/gltf/gltfimporter.cpp @@ -1072,7 +1072,7 @@ void GLTFImporter::cleanup() m_shaderPaths.clear(); delete_if_without_parent(m_programs); m_programs.clear(); - for (auto params : m_techniqueParameters.values()) + for (const auto ¶ms : m_techniqueParameters.values()) delete_if_without_parent(params); m_techniqueParameters.clear(); delete_if_without_parent(m_techniques); @@ -1546,7 +1546,7 @@ void GLTFImporter::processJSONExtensions(const QString &id, const QJsonObject &j // level GLTF item. if (id == KEY_COMMON_MAT) { const auto lights = jsonObject.value(KEY_LIGHTS).toObject(); - for (auto lightKey : lights.keys()) { + for (const auto &lightKey : lights.keys()) { const auto light = lights.value(lightKey).toObject(); auto lightType = light.value(KEY_TYPE).toString(); const auto lightValues = light.value(lightType).toObject(); diff --git a/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp b/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp index b2fd9ce5b..373bdf4f4 100644 --- a/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp +++ b/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp @@ -370,7 +370,7 @@ bool GLTFExporter::exportScene(QEntity *sceneRoot, const QString &outDir, QFile::Permissions targetPermissions = gltfFile.permissions(); // Copy exported scene to actual export directory - for (auto sourceFileStr : m_exportedFiles) { + for (const auto &sourceFileStr : m_exportedFiles) { QFileInfo fiSource(m_exportDir + sourceFileStr); QFileInfo fiDestination(finalExportDir + sourceFileStr); if (fiDestination.exists()) { @@ -524,7 +524,7 @@ void GLTFExporter::copyTextures() void GLTFExporter::createShaders() { qCDebug(GLTFExporterLog, "Creating shaders..."); - for (auto si : m_shaderInfo) { + for (const auto &si : m_shaderInfo) { const QString fileName = m_exportDir + si.uri; QFile f(fileName); if (f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { @@ -940,11 +940,11 @@ void GLTFExporter::parseMeshes() qCDebug(GLTFExporterLog, " Vertex buffer size (bytes): %i", vertexBuf.size()); qCDebug(GLTFExporterLog, " Index buffer size (bytes): %i", indexBuf.size()); QStringList sl; - for (auto bv : meshInfo.views) + for (const auto &bv : meshInfo.views) sl << bv.name; qCDebug(GLTFExporterLog) << " buffer views:" << sl; sl.clear(); - for (auto acc : meshInfo.accessors) + for (const auto &acc : meshInfo.accessors) sl << acc.name; qCDebug(GLTFExporterLog) << " accessors:" << sl; qCDebug(GLTFExporterLog, " material: '%ls'", @@ -1129,7 +1129,7 @@ QString GLTFExporter::addShaderInfo(QShaderProgram::ShaderType type, QByteArray if (code.isEmpty()) return QString(); - for (auto si : m_shaderInfo) { + for (const auto &si : m_shaderInfo) { if (si.type == QShaderProgram::Vertex && code == si.code) return si.name; } @@ -1153,10 +1153,10 @@ bool GLTFExporter::saveScene() QVector bvList; QVector accList; - for (auto mi : m_meshInfo.values()) { - for (auto v : mi.views) + for (auto &mi : m_meshInfo.values()) { + for (auto &v : mi.views) bvList << v; - for (auto acc : mi.accessors) + for (auto &acc : mi.accessors) accList << acc; } @@ -1193,7 +1193,7 @@ bool GLTFExporter::saveScene() m_obj["buffers"] = buffers; QJsonObject bufferViews; - for (auto bv : bvList) { + for (const auto &bv : bvList) { QJsonObject bufferView; bufferView["buffer"] = QStringLiteral("buf"); bufferView["byteLength"] = int(bv.length); @@ -1206,7 +1206,7 @@ bool GLTFExporter::saveScene() m_obj["bufferViews"] = bufferViews; QJsonObject accessors; - for (auto acc : accList) { + for (const auto &acc : accList) { QJsonObject accessor; accessor["bufferView"] = acc.bufferView; accessor["byteOffset"] = int(acc.offset); @@ -1220,7 +1220,7 @@ bool GLTFExporter::saveScene() m_obj["accessors"] = accessors; QJsonObject meshes; - for (auto meshInfo : m_meshInfo.values()) { + for (const auto &meshInfo : m_meshInfo.values()) { QJsonObject mesh; mesh["name"] = meshInfo.originalName; if (meshInfo.meshType != TypeNone) { @@ -1234,7 +1234,7 @@ bool GLTFExporter::saveScene() QJsonObject prim; prim["mode"] = 4; // triangles QJsonObject attrs; - for (auto acc : meshInfo.accessors) { + for (const auto &acc : meshInfo.accessors) { if (acc.usage != QStringLiteral("INDEX")) attrs[acc.usage] = acc.name; else @@ -1251,7 +1251,7 @@ bool GLTFExporter::saveScene() m_obj["meshes"] = meshes; QJsonObject cameras; - for (auto camInfo : m_cameraInfo.values()) { + for (const auto &camInfo : m_cameraInfo.values()) { QJsonObject camera; QJsonObject proj; proj["znear"] = camInfo.znear; @@ -1305,7 +1305,7 @@ bool GLTFExporter::saveScene() // Lights must be declared as extensions to the top-level glTF object QJsonObject lights; - for (auto lightInfo : m_lightInfo.values()) { + for (const auto &lightInfo : m_lightInfo.values()) { QJsonObject light; QJsonObject lightDetails; QString type; @@ -1406,7 +1406,7 @@ bool GLTFExporter::saveScene() if (!gFilter->vendor().isEmpty()) graphicsApiFilterObj["vendor"] = gFilter->vendor(); QJsonArray extensions; - for (auto extName : gFilter->extensions()) + for (const auto &extName : gFilter->extensions()) extensions << extName; if (!extensions.isEmpty()) graphicsApiFilterObj["extensions"] = extensions; @@ -1485,7 +1485,7 @@ bool GLTFExporter::saveScene() // Save shaders for custom materials QJsonObject shaders; - for (auto si : m_shaderInfo) { + for (const auto &si : m_shaderInfo) { QJsonObject shaderObj; shaderObj["uri"] = si.uri; shaders[si.name] = shaderObj; @@ -1572,7 +1572,7 @@ bool GLTFExporter::saveScene() QByteArray pre = "\n"; QByteArray post = "\n"; f.write(pre); - for (auto file : m_exportedFiles) { + for (const auto &file : m_exportedFiles) { QString line = QString(QStringLiteral(" %1\n")).arg(file); f.write(line.toUtf8()); } diff --git a/src/render/backend/renderviewbuilder.cpp b/src/render/backend/renderviewbuilder.cpp index f1355d27e..0aab31b86 100644 --- a/src/render/backend/renderviewbuilder.cpp +++ b/src/render/backend/renderviewbuilder.cpp @@ -66,14 +66,14 @@ public: RenderView *rv = m_renderViewJob->renderView(); int totalCommandCount = 0; - for (const auto renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) + for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) totalCommandCount += renderViewCommandBuilder->commands().size(); QVector commands; commands.reserve(totalCommandCount); // Reduction - for (const auto renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) + for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) commands += std::move(renderViewCommandBuilder->commands()); rv->setCommands(commands); @@ -139,13 +139,13 @@ public: m_filterEntityByLayerJob->setLayers(rv->layerFilter()); // Material Parameter building - for (const auto materialGatherer : qAsConst(m_materialGathererJobs)) { + for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) { materialGatherer->setRenderPassFilter(const_cast(rv->renderPassFilter())); materialGatherer->setTechniqueFilter(const_cast(rv->techniqueFilter())); } // Command builders - for (const auto renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) + for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) renderViewCommandBuilder->setRenderView(rv); // Set whether frustum culling is enabled or not @@ -225,7 +225,7 @@ public: // Reduction QHash> params; - for (const auto materialGatherer : qAsConst(m_materialGathererJobs)) + for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) params.unite(materialGatherer->materialToPassAndParameter()); // Set all required data on the RenderView for final processing rv->setMaterialParameterTable(std::move(params)); @@ -425,7 +425,7 @@ QVector RenderViewBuilder::buildJobHierachy() const m_filterEntityByLayerJob->addDependency(m_renderer->updateTreeEnabledJob()); m_syncRenderCommandBuildingJob->addDependency(m_syncRenderViewInitializationJob); - for (const auto materialGatherer : qAsConst(m_materialGathererJobs)) { + for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) { materialGatherer->addDependency(m_syncRenderViewInitializationJob); materialGatherer->addDependency(m_renderer->filterCompatibleTechniqueJob()); m_syncRenderCommandBuildingJob->addDependency(materialGatherer); @@ -436,7 +436,7 @@ QVector RenderViewBuilder::buildJobHierachy() const m_syncRenderCommandBuildingJob->addDependency(m_lightGathererJob); m_syncRenderCommandBuildingJob->addDependency(m_frustumCullingJob); - for (const auto renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) { + for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) { renderViewCommandBuilder->addDependency(m_syncRenderCommandBuildingJob); m_syncRenderViewCommandBuildersJob->addDependency(renderViewCommandBuilder); } @@ -458,13 +458,13 @@ QVector RenderViewBuilder::buildJobHierachy() const jobs.push_back(m_filterEntityByLayerJob); // Step 3 jobs.push_back(m_setClearDrawBufferIndexJob); // Step 3 - for (const auto materialGatherer : qAsConst(m_materialGathererJobs)) // Step3 + for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) // Step3 jobs.push_back(materialGatherer); jobs.push_back(m_frustumCullingJob); // Step 4 jobs.push_back(m_syncRenderCommandBuildingJob); // Step 4 - for (const auto renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) // Step 5 + for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) // Step 5 jobs.push_back(renderViewCommandBuilder); jobs.push_back(m_syncRenderViewCommandBuildersJob); // Step 6 diff --git a/src/render/framegraph/rendercapture.cpp b/src/render/framegraph/rendercapture.cpp index 1d3117c0d..dea1cf565 100644 --- a/src/render/framegraph/rendercapture.cpp +++ b/src/render/framegraph/rendercapture.cpp @@ -92,7 +92,7 @@ void RenderCapture::sendRenderCaptures() { QMutexLocker lock(&m_mutex); - for (const RenderCaptureDataPtr data : qAsConst(m_renderCaptureData)) { + for (const RenderCaptureDataPtr &data : qAsConst(m_renderCaptureData)) { auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); e->setPropertyName("renderCaptureData"); diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index a135c34e4..ca79f6fde 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -255,7 +255,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType(QSharedPointer >::create(m_renderer)); // Plugins - for (QString plugin : m_pluginConfig) + for (const QString &plugin : m_pluginConfig) loadRenderPlugin(plugin); } -- cgit v1.2.3 From 348956c8e270d0c38f495201b99b21634c75b0fa Mon Sep 17 00:00:00 2001 From: Mike Krus Date: Mon, 1 May 2017 14:19:09 +0100 Subject: Add qAsConst, range-loop might detach Qt container (clazy reports) Change-Id: I5d541cd0d08f17c25cbb839c111417130d133c3c Reviewed-by: Sean Harmer --- src/animation/backend/buildblendtreesjob.cpp | 2 +- src/animation/frontend/qanimationcontroller.cpp | 4 ++-- src/animation/frontend/qanimationgroup.cpp | 2 +- src/animation/frontend/qkeyframeanimation.cpp | 2 +- src/animation/frontend/qmorphinganimation.cpp | 2 +- src/animation/frontend/qmorphtarget.cpp | 4 ++-- src/plugins/geometryloaders/default/objgeometryloader.cpp | 2 +- src/plugins/sceneparsers/assimp/assimpimporter.cpp | 6 +++--- src/plugins/sceneparsers/gltfexport/gltfexporter.cpp | 8 ++++---- src/quick3d/quick3dscene2d/items/scene2d.cpp | 4 ++-- src/render/frontend/qrenderaspect.cpp | 2 +- 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/animation/backend/buildblendtreesjob.cpp b/src/animation/backend/buildblendtreesjob.cpp index ac95808bc..fe56099a2 100644 --- a/src/animation/backend/buildblendtreesjob.cpp +++ b/src/animation/backend/buildblendtreesjob.cpp @@ -63,7 +63,7 @@ void BuildBlendTreesJob::setBlendedClipAnimators(const QVectorblendedClipAnimatorManager()->data(blendedClipAnimatorHandle); Q_ASSERT(blendClipAnimator); diff --git a/src/animation/frontend/qanimationcontroller.cpp b/src/animation/frontend/qanimationcontroller.cpp index 5df2c713a..d4c3c4005 100644 --- a/src/animation/frontend/qanimationcontroller.cpp +++ b/src/animation/frontend/qanimationcontroller.cpp @@ -182,7 +182,7 @@ float QAnimationControllerPrivate::scaledPosition(float position) const QAnimationGroup *QAnimationControllerPrivate::findGroup(const QString &name) { - for (QAnimationGroup *g : m_animationGroups) { + for (QAnimationGroup *g : qAsConst(m_animationGroups)) { if (g->name() == name) return g; } @@ -211,7 +211,7 @@ void QAnimationControllerPrivate::extractAnimations() } void QAnimationControllerPrivate::clearAnimations() { - for (Qt3DAnimation::QAnimationGroup *a : m_animationGroups) + for (Qt3DAnimation::QAnimationGroup *a : qAsConst(m_animationGroups)) a->deleteLater(); m_animationGroups.clear(); m_activeAnimationGroup = 0; diff --git a/src/animation/frontend/qanimationgroup.cpp b/src/animation/frontend/qanimationgroup.cpp index 07d0fadc5..365745662 100644 --- a/src/animation/frontend/qanimationgroup.cpp +++ b/src/animation/frontend/qanimationgroup.cpp @@ -109,7 +109,7 @@ QAnimationGroupPrivate::QAnimationGroupPrivate() void QAnimationGroupPrivate::updatePosition(float position) { m_position = position; - for (QAbstractAnimation *aa : m_animations) + for (QAbstractAnimation *aa : qAsConst(m_animations)) aa->setPosition(position); } diff --git a/src/animation/frontend/qkeyframeanimation.cpp b/src/animation/frontend/qkeyframeanimation.cpp index 0b17265a6..1affc737b 100644 --- a/src/animation/frontend/qkeyframeanimation.cpp +++ b/src/animation/frontend/qkeyframeanimation.cpp @@ -190,7 +190,7 @@ void QKeyframeAnimation::setFramePositions(const QVector &positions) d->m_minposition = d->m_framePositions.first(); d->m_maxposition = d->m_framePositions.last(); float lastPos = d->m_minposition; - for (float p : d->m_framePositions) { + for (float p : qAsConst(d->m_framePositions)) { if (p < lastPos || p > d->m_maxposition) qWarning() << "positions not ordered correctly"; lastPos = p; diff --git a/src/animation/frontend/qmorphinganimation.cpp b/src/animation/frontend/qmorphinganimation.cpp index e8f440c45..3824b8d64 100644 --- a/src/animation/frontend/qmorphinganimation.cpp +++ b/src/animation/frontend/qmorphinganimation.cpp @@ -179,7 +179,7 @@ QMorphingAnimationPrivate::QMorphingAnimationPrivate() QMorphingAnimationPrivate::~QMorphingAnimationPrivate() { - for (QVector *weights : m_weights) + for (QVector *weights : qAsConst(m_weights)) delete weights; } diff --git a/src/animation/frontend/qmorphtarget.cpp b/src/animation/frontend/qmorphtarget.cpp index e16dd8698..9dc30b8ba 100644 --- a/src/animation/frontend/qmorphtarget.cpp +++ b/src/animation/frontend/qmorphtarget.cpp @@ -99,7 +99,7 @@ QMorphTargetPrivate::QMorphTargetPrivate() void QMorphTargetPrivate::updateAttributeNames() { m_attributeNames.clear(); - for (const Qt3DRender::QAttribute *attr : m_targetAttributes) + for (const Qt3DRender::QAttribute *attr : qAsConst(m_targetAttributes)) m_attributeNames.push_back(attr->name()); } @@ -148,7 +148,7 @@ void QMorphTarget::setAttributes(const QVector &attrib void QMorphTarget::addAttribute(Qt3DRender::QAttribute *attribute) { Q_D(QMorphTarget); - for (const Qt3DRender::QAttribute *attr : d->m_targetAttributes) { + for (const Qt3DRender::QAttribute *attr : qAsConst(d->m_targetAttributes)) { if (attr->name() == attribute->name()) return; } diff --git a/src/plugins/geometryloaders/default/objgeometryloader.cpp b/src/plugins/geometryloaders/default/objgeometryloader.cpp index 0f22acc66..a6c635190 100644 --- a/src/plugins/geometryloaders/default/objgeometryloader.cpp +++ b/src/plugins/geometryloaders/default/objgeometryloader.cpp @@ -231,7 +231,7 @@ bool ObjGeometryLoader::doLoad(QIODevice *ioDev, const QString &subMesh) const int indexCount = faceIndexVector.size(); m_indices.clear(); m_indices.reserve(indexCount); - for (const FaceIndices faceIndices : faceIndexVector) { + for (const FaceIndices faceIndices : qAsConst(faceIndexVector)) { const unsigned int i = faceIndexMap.value(faceIndices); m_indices.append(i); } diff --git a/src/plugins/sceneparsers/assimp/assimpimporter.cpp b/src/plugins/sceneparsers/assimp/assimpimporter.cpp index 5d5593585..565c61234 100644 --- a/src/plugins/sceneparsers/assimp/assimpimporter.cpp +++ b/src/plugins/sceneparsers/assimp/assimpimporter.cpp @@ -428,7 +428,7 @@ Qt3DCore::QEntity *AssimpImporter::scene(const QString &id) if (m_scene->m_animations.size() > 0) { qWarning() << "No target found for " << m_scene->m_animations.size() << " animations!"; - for (Qt3DAnimation::QKeyframeAnimation *anim : m_scene->m_animations) + for (Qt3DAnimation::QKeyframeAnimation *anim : qAsConst(m_scene->m_animations)) delete anim; m_scene->m_animations.clear(); } @@ -490,7 +490,7 @@ Qt3DCore::QEntity *AssimpImporter::node(aiNode *node) animations, aiStringToQString(node->mName)); const auto morphTargetList = morphingAnimations.at(0)->morphTargetList(); - for (Qt3DAnimation::QMorphingAnimation *anim : animations) { + for (Qt3DAnimation::QMorphingAnimation *anim : qAsConst(animations)) { anim->setParent(entityNode); anim->setTarget(mesh); anim->setMorphTargets(morphTargetList); @@ -543,7 +543,7 @@ Qt3DCore::QEntity *AssimpImporter::node(aiNode *node) animations, aiStringToQString(node->mName)); - for (Qt3DAnimation::QKeyframeAnimation *anim : animations) { + for (Qt3DAnimation::QKeyframeAnimation *anim : qAsConst(animations)) { anim->setTarget(transform); anim->setParent(entityNode); } diff --git a/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp b/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp index 373bdf4f4..fce7d5881 100644 --- a/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp +++ b/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp @@ -1283,7 +1283,7 @@ bool GLTFExporter::saveScene() if (m_rootNodeEmpty) { // Don't export the root node if it is there just to group the scene, so we don't get // an extra empty node when we import the scene back. - for (auto c : m_rootNode->children) + for (auto c : qAsConst(m_rootNode->children)) sceneNodes << exportNodes(c, nodes); } else { sceneNodes << exportNodes(m_rootNode, nodes); @@ -1572,7 +1572,7 @@ bool GLTFExporter::saveScene() QByteArray pre = "\n"; QByteArray post = "\n"; f.write(pre); - for (const auto &file : m_exportedFiles) { + for (const auto &file : qAsConst(m_exportedFiles)) { QString line = QString(QStringLiteral(" %1\n")).arg(file); f.write(line.toUtf8()); } @@ -1594,7 +1594,7 @@ void GLTFExporter::delNode(GLTFExporter::Node *n) { if (!n) return; - for (auto *c : n->children) + for (auto *c : qAsConst(n->children)) delNode(c); delete n; } @@ -1604,7 +1604,7 @@ QString GLTFExporter::exportNodes(GLTFExporter::Node *n, QJsonObject &nodes) QJsonObject node; node["name"] = n->name; QJsonArray children; - for (auto c : n->children) + for (auto c : qAsConst(n->children)) children << exportNodes(c, nodes); node["children"] = children; if (auto transform = m_transformMap.value(n)) diff --git a/src/quick3d/quick3dscene2d/items/scene2d.cpp b/src/quick3d/quick3dscene2d/items/scene2d.cpp index ded595b36..13165c280 100644 --- a/src/quick3d/quick3dscene2d/items/scene2d.cpp +++ b/src/quick3d/quick3dscene2d/items/scene2d.cpp @@ -501,13 +501,13 @@ void Scene2D::handlePickEvent(int type, const Qt3DRender::QPickEventPtr &ev) void Scene2D::startGrabbing() { - for (Qt3DCore::QNodeId e : m_entities) + for (Qt3DCore::QNodeId e : qAsConst(m_entities)) registerObjectPickerEvents(e); } void Scene2D::stopGrabbing() { - for (Qt3DCore::QNodeId e : m_entities) + for (Qt3DCore::QNodeId e : qAsConst(m_entities)) unregisterObjectPickerEvents(e); } diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index ca79f6fde..1f88cb006 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -595,7 +595,7 @@ void QRenderAspectPrivate::configurePlugin(const QString &plugin) if (!m_pluginConfig.contains(plugin)) { m_pluginConfig.append(plugin); - for (QRenderAspectPrivate *instance : m_instances) + for (QRenderAspectPrivate *instance : qAsConst(m_instances)) instance->loadRenderPlugin(plugin); } } -- cgit v1.2.3 From 5e86850397399d6fbd11173c428e2dac8a4c1682 Mon Sep 17 00:00:00 2001 From: Mike Krus Date: Mon, 1 May 2017 14:45:51 +0100 Subject: Remove unneeded temporary container (clazy reports) Change-Id: I2a7a94d7b2791382699b39dda1189bc78ce0ff06 Reviewed-by: Sean Harmer --- src/core/qscene.cpp | 8 +++++++- src/plugins/sceneparsers/gltf/gltfimporter.cpp | 4 ++-- src/plugins/sceneparsers/gltfexport/gltfexporter.cpp | 12 ++++++++---- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/core/qscene.cpp b/src/core/qscene.cpp index 33841574e..043b3f11b 100644 --- a/src/core/qscene.cpp +++ b/src/core/qscene.cpp @@ -222,7 +222,13 @@ bool QScene::hasEntityForComponent(QNodeId componentUuid, QNodeId entityUuid) { Q_D(QScene); QReadLocker lock(&d->m_lock); - return d->m_componentToEntities.values(componentUuid).contains(entityUuid); + auto it = d->m_componentToEntities.find(componentUuid); + while (it != d->m_componentToEntities.end() && it.key() == componentUuid) { + if (it.value() == entityUuid) + return true; + ++it; + } + return false; } QScene::NodePropertyTrackData QScene::lookupNodePropertyTrackData(QNodeId id) const diff --git a/src/plugins/sceneparsers/gltf/gltfimporter.cpp b/src/plugins/sceneparsers/gltf/gltfimporter.cpp index 5c209aa8a..6f61d2ed9 100644 --- a/src/plugins/sceneparsers/gltf/gltfimporter.cpp +++ b/src/plugins/sceneparsers/gltf/gltfimporter.cpp @@ -1072,8 +1072,8 @@ void GLTFImporter::cleanup() m_shaderPaths.clear(); delete_if_without_parent(m_programs); m_programs.clear(); - for (const auto ¶ms : m_techniqueParameters.values()) - delete_if_without_parent(params); + for (auto it = m_techniqueParameters.begin(); it != m_techniqueParameters.end(); ++it) + delete_if_without_parent(it.value()); m_techniqueParameters.clear(); delete_if_without_parent(m_techniques); m_techniques.clear(); diff --git a/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp b/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp index fce7d5881..571607fc4 100644 --- a/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp +++ b/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp @@ -1153,7 +1153,8 @@ bool GLTFExporter::saveScene() QVector bvList; QVector accList; - for (auto &mi : m_meshInfo.values()) { + for (auto it = m_meshInfo.begin(); it != m_meshInfo.end(); ++it) { + auto &mi = it.value(); for (auto &v : mi.views) bvList << v; for (auto &acc : mi.accessors) @@ -1220,7 +1221,8 @@ bool GLTFExporter::saveScene() m_obj["accessors"] = accessors; QJsonObject meshes; - for (const auto &meshInfo : m_meshInfo.values()) { + for (auto it = m_meshInfo.begin(); it != m_meshInfo.end(); ++it) { + auto &meshInfo = it.value(); QJsonObject mesh; mesh["name"] = meshInfo.originalName; if (meshInfo.meshType != TypeNone) { @@ -1251,7 +1253,8 @@ bool GLTFExporter::saveScene() m_obj["meshes"] = meshes; QJsonObject cameras; - for (const auto &camInfo : m_cameraInfo.values()) { + for (auto it = m_cameraInfo.begin(); it != m_cameraInfo.end(); ++it) { + const auto &camInfo = it.value(); QJsonObject camera; QJsonObject proj; proj["znear"] = camInfo.znear; @@ -1305,7 +1308,8 @@ bool GLTFExporter::saveScene() // Lights must be declared as extensions to the top-level glTF object QJsonObject lights; - for (const auto &lightInfo : m_lightInfo.values()) { + for (auto it = m_lightInfo.begin(); it != m_lightInfo.end(); ++it) { + const auto &lightInfo = it.value(); QJsonObject light; QJsonObject lightDetails; QString type; -- cgit v1.2.3 From f649a4c527c9685e1d30aa3048994ec4e7632990 Mon Sep 17 00:00:00 2001 From: Mike Krus Date: Mon, 1 May 2017 14:55:47 +0100 Subject: Use multi-arg where possible (clazy reports) Change-Id: I333e65e3173077c53ffae8cff3c2c1c37da6bd26 Reviewed-by: Sean Harmer --- tools/qgltf/qgltf.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/qgltf/qgltf.cpp b/tools/qgltf/qgltf.cpp index bc011eaa7..e5f49bdc6 100644 --- a/tools/qgltf/qgltf.cpp +++ b/tools/qgltf/qgltf.cpp @@ -1964,13 +1964,13 @@ void GltfExporter::exportTechniques(QJsonObject &obj, const QString &basename) if (newName.isEmpty()) newName = newShaderName(); QString key = basename + QStringLiteral("_") + newName + QStringLiteral("_v"); - QString fn = QString(QStringLiteral("%1.%2")).arg(key).arg("vert"); + QString fn = QString(QStringLiteral("%1.vert")).arg(key); vertexShader["uri"] = fn; writeShader(prog->vertShader, fn, m_subst_es2); if (opts.genCore) { QJsonObject coreVertexShader; QString coreKey = QString(QStringLiteral("%1_core").arg(key)); - fn = QString(QStringLiteral("%1.%2")).arg(coreKey).arg("vert"); + fn = QString(QStringLiteral("%1.vert")).arg(coreKey); coreVertexShader["type"] = 35633; coreVertexShader["uri"] = fn; writeShader(prog->vertShader, fn, m_subst_core); @@ -1986,13 +1986,13 @@ void GltfExporter::exportTechniques(QJsonObject &obj, const QString &basename) if (newName.isEmpty()) newName = newShaderName(); QString key = basename + QStringLiteral("_") + newName + QStringLiteral("_f"); - QString fn = QString(QStringLiteral("%1.%2")).arg(key).arg("frag"); + QString fn = QString(QStringLiteral("%1.frag")).arg(key); fragmentShader["uri"] = fn; writeShader(prog->fragShader, fn, m_subst_es2); if (opts.genCore) { QJsonObject coreFragmentShader; QString coreKey = QString(QStringLiteral("%1_core").arg(key)); - fn = QString(QStringLiteral("%1.%2")).arg(coreKey).arg("frag"); + fn = QString(QStringLiteral("%1.frag")).arg(coreKey); coreFragmentShader["type"] = 35632; coreFragmentShader["uri"] = fn; writeShader(prog->fragShader, fn, m_subst_core); -- cgit v1.2.3 From 629e5ed81b9b584196beafdddccdd85365510975 Mon Sep 17 00:00:00 2001 From: Mike Krus Date: Mon, 1 May 2017 15:06:59 +0100 Subject: Use non-template version of QVariant::value (clazy reports) Change-Id: I998507edff792cfbdcdf2e36e29792fab3c734cf Reviewed-by: Sean Harmer --- src/core/nodes/qbackendnode.cpp | 2 +- src/plugins/sceneparsers/gltfexport/gltfexporter.cpp | 2 +- src/render/framegraph/viewportnode.cpp | 2 +- src/render/geometry/attribute.cpp | 2 +- src/render/geometry/buffer.cpp | 2 +- src/render/geometry/geometryrenderer.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/nodes/qbackendnode.cpp b/src/core/nodes/qbackendnode.cpp index e3963b202..dc751cb93 100644 --- a/src/core/nodes/qbackendnode.cpp +++ b/src/core/nodes/qbackendnode.cpp @@ -233,7 +233,7 @@ void QBackendNode::sceneChangeEvent(const QSceneChangePtr &e) switch (e->type()) { case PropertyUpdated: { if (propertyChange->propertyName() == QByteArrayLiteral("enabled")) - d->m_enabled = propertyChange->value().value(); + d->m_enabled = propertyChange->value().toBool(); break; } default: diff --git a/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp b/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp index 571607fc4..4b1d0fb40 100644 --- a/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp +++ b/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp @@ -2064,7 +2064,7 @@ void GLTFExporter::setVarToJSonObject(QJsonObject &jsObj, const QString &key, co jsObj[key] = var.value(); break; case QMetaType::QSize: - jsObj[key] = size2jsvec(var.value()); + jsObj[key] = size2jsvec(var.toSize()); break; case QMetaType::QVector2D: jsObj[key] = vec2jsvec(var.value()); diff --git a/src/render/framegraph/viewportnode.cpp b/src/render/framegraph/viewportnode.cpp index c16a660b0..b68f7b55b 100644 --- a/src/render/framegraph/viewportnode.cpp +++ b/src/render/framegraph/viewportnode.cpp @@ -123,7 +123,7 @@ void ViewportNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) if (e->type() == PropertyUpdated) { QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(e); if (propertyChange->propertyName() == QByteArrayLiteral("normalizedRect")) { - QRectF normalizedRect = propertyChange->value().value(); + QRectF normalizedRect = propertyChange->value().toRectF(); setXMin(normalizedRect.x()); setYMin(normalizedRect.y()); setXMax(normalizedRect.width()); diff --git a/src/render/geometry/attribute.cpp b/src/render/geometry/attribute.cpp index 7e1ea79dd..6c8c0113a 100644 --- a/src/render/geometry/attribute.cpp +++ b/src/render/geometry/attribute.cpp @@ -108,7 +108,7 @@ void Attribute::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) QByteArray propertyName = propertyChange->propertyName(); if (propertyName == QByteArrayLiteral("name")) { - m_name = propertyChange->value().value(); + m_name = propertyChange->value().toString(); m_nameId = StringToInt::lookupId(m_name); m_attributeDirty = true; } else if (propertyName == QByteArrayLiteral("vertexBaseType")) { diff --git a/src/render/geometry/buffer.cpp b/src/render/geometry/buffer.cpp index 1133b8e5e..44d84f75a 100644 --- a/src/render/geometry/buffer.cpp +++ b/src/render/geometry/buffer.cpp @@ -133,7 +133,7 @@ void Buffer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(e); QByteArray propertyName = propertyChange->propertyName(); if (propertyName == QByteArrayLiteral("data")) { - QByteArray newData = propertyChange->value().value(); + QByteArray newData = propertyChange->value().toByteArray(); m_bufferDirty |= m_data != newData; m_data = newData; } else if (propertyName == QByteArrayLiteral("updateData")) { diff --git a/src/render/geometry/geometryrenderer.cpp b/src/render/geometry/geometryrenderer.cpp index 54fe61831..4f5432e1d 100644 --- a/src/render/geometry/geometryrenderer.cpp +++ b/src/render/geometry/geometryrenderer.cpp @@ -153,7 +153,7 @@ void GeometryRenderer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) m_verticesPerPatch = propertyChange->value().value(); m_dirty = true; } else if (propertyName == QByteArrayLiteral("primitiveRestartEnabled")) { - m_primitiveRestartEnabled = propertyChange->value().value(); + m_primitiveRestartEnabled = propertyChange->value().toBool(); m_dirty = true; } else if (propertyName == QByteArrayLiteral("primitiveType")) { m_primitiveType = static_cast(propertyChange->value().value()); -- cgit v1.2.3 From d947ef04bc162d9f1816afb6188e8ef0a30c5143 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Tue, 21 Mar 2017 12:23:27 +0100 Subject: Doc: correct several link errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qkeyframeanimation.cpp:61: warning: Can't link to 'Qt3D.Render::Transform' levelofdetailloader.qdoc:40: warning: Can't link to 'minimum' levelofdetailloader.qdoc:40: warning: Can't link to 'maximum' qlevelofdetail.cpp:201: warning: Can't link to 'Qt3DRender::QLevelOfDetail::SizeProxyMode' qlevelofdetailswitch.cpp:62: warning: Can't link to 'LevelOfDetailSwitch::currentIndex' Plus a minor language correction Change-Id: I26096ec74880a406ada27fb3d867983845611410 Reviewed-by: Venugopal Shivashankar Reviewed-by: Topi Reiniö --- src/animation/frontend/qkeyframeanimation.cpp | 2 +- src/doc/src/levelofdetailloader.qdoc | 2 +- src/render/frontend/qlevelofdetail.cpp | 31 +-------------------------- src/render/frontend/qlevelofdetailswitch.cpp | 8 ++++++- 4 files changed, 10 insertions(+), 33 deletions(-) diff --git a/src/animation/frontend/qkeyframeanimation.cpp b/src/animation/frontend/qkeyframeanimation.cpp index 0b17265a6..19069a8ed 100644 --- a/src/animation/frontend/qkeyframeanimation.cpp +++ b/src/animation/frontend/qkeyframeanimation.cpp @@ -68,7 +68,7 @@ namespace Qt3DAnimation { A KeyframeAnimation type implements simple keyframe animation that can be used to animate \l Transform. The keyframes consists of multiple - timed \l {Qt3D.Render::Transform}{Transforms}, which are interpolated and applied + timed \l {Qt3D.Core::Transform}s, which are interpolated and applied to the target Transform. EasingCurve is used between keyframes to control the interpolator. RepeatMode can be set for when the position set to the KeyframeAnimation is less or or greater than the values defined in the keyframe positions. diff --git a/src/doc/src/levelofdetailloader.qdoc b/src/doc/src/levelofdetailloader.qdoc index 65fda072a..6294e4735 100644 --- a/src/doc/src/levelofdetailloader.qdoc +++ b/src/doc/src/levelofdetailloader.qdoc @@ -40,12 +40,12 @@ /*! \qmltype LevelOfDetailLoader \inqmlmodule Qt3D.Render + \inherits Entity \since 5.9 \brief An entity loader that changes depending on distance to camera or screen size A LevelOfDetailLoader will load the entity matching the \l LevelOfDetail::currentIndex. The source is selected from the \l sources property. - The range is specified using the \l {minimum} and the \l{maximum} values. \sa LevelOfDetail */ diff --git a/src/render/frontend/qlevelofdetail.cpp b/src/render/frontend/qlevelofdetail.cpp index df169876e..4d6b07d4b 100644 --- a/src/render/frontend/qlevelofdetail.cpp +++ b/src/render/frontend/qlevelofdetail.cpp @@ -77,7 +77,7 @@ QLevelOfDetailPrivate::QLevelOfDetailPrivate() The currentIndex property can then be used, for example, to enable or disable entities, change material, etc. - The LevelOfDetail component is not shareable between multiple Entity's. + The LevelOfDetail component is not shareable between multiple \l [QML]{Entity}{entities}. \code #include @@ -185,35 +185,6 @@ QLevelOfDetailPrivate::QLevelOfDetailPrivate() * \sa Qt3DRender::QLevelOfDetail::ThresholdType */ - -/*! - * \enum Qt3DRender::QLevelOfDetail::SizeProxyMode - * - * Specifies what is used as a proxy for the entity when computing distance - * or size. - * - * \value LevelOfDetailBoundingSphere use the bounding sphere specified by the center - * and radius properties. - * \value Children LevelOfDetailBoundingSphere use the bounding sphere of the entity the - * component is attached to. - */ - -/*! - * \qmlproperty enumeration LevelOfDetail::SizeProxyMode - * - * Specifies what is used as a proxy for the entity when computing distance - * or size. - * - * \list - * \li LevelOfDetailBoundingSphere use the bounding sphere specified by the center - * and radius properties. - * \li Children LevelOfDetailBoundingSphere use the bounding sphere of the entity the - * component is attached to. - * \endlist - * \sa Qt3DRender::QLevelOfDetail::SizeProxyMode - */ - - /*! * \qmlproperty Camera LevelOfDetail::camera * diff --git a/src/render/frontend/qlevelofdetailswitch.cpp b/src/render/frontend/qlevelofdetailswitch.cpp index a6d2b1530..845fdd5a6 100644 --- a/src/render/frontend/qlevelofdetailswitch.cpp +++ b/src/render/frontend/qlevelofdetailswitch.cpp @@ -69,11 +69,17 @@ namespace Qt3DRender { This component is assigned to an entity. When the entity changes distance relative to the camera, the LevelOfDetailSwitch will disable all the child entities except - the one matching index \l LevelOfDetailSwitch::currentIndex. + the one matching index \l currentIndex. \sa LevelOfDetail */ +/*! + \qmlproperty int LevelOfDetailSwitch::currentIndex + + The index of the presently selected child entity. +*/ + /*! \fn Qt3DRender::QLevelOfDetailSwitch::QLevelOfDetailSwitch(Qt3DCore::QNode *parent) Constructs a new QLevelOfDetailSwitch with the specified \a parent. */ -- cgit v1.2.3 From 1d3ffb4cadfd43e163bf977c03a48f3b9cbb1f30 Mon Sep 17 00:00:00 2001 From: Mike Krus Date: Tue, 2 May 2017 19:15:38 +0100 Subject: Correct shader typo for rendering and fix shader selection Task-number: QTBUG-60288 Change-Id: I320f787c3b245cc52df80d89c75f856aeacf649d Reviewed-by: Sean Harmer --- examples/qt3d/advancedcustommaterial/WaterMaterial.qml | 5 ++--- examples/qt3d/advancedcustommaterial/shaders/gl3/water.frag | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/qt3d/advancedcustommaterial/WaterMaterial.qml b/examples/qt3d/advancedcustommaterial/WaterMaterial.qml index 2c5410bea..b67e8322c 100644 --- a/examples/qt3d/advancedcustommaterial/WaterMaterial.qml +++ b/examples/qt3d/advancedcustommaterial/WaterMaterial.qml @@ -228,12 +228,11 @@ Material { } }, - // OpenGL 2.0 + // OpenGLES 2.0 Technique { filterKeys: [ forward ] graphicsApiFilter { - api: GraphicsApiFilter.OpenGL - profile: GraphicsApiFilter.NoProfile + api: GraphicsApiFilter.OpenGLES majorVersion: 2 minorVersion: 0 } diff --git a/examples/qt3d/advancedcustommaterial/shaders/gl3/water.frag b/examples/qt3d/advancedcustommaterial/shaders/gl3/water.frag index ae40bdf37..9657cc63a 100644 --- a/examples/qt3d/advancedcustommaterial/shaders/gl3/water.frag +++ b/examples/qt3d/advancedcustommaterial/shaders/gl3/water.frag @@ -39,7 +39,7 @@ void main() vec2 waveMovCoord = waveTexCoord; waveMovCoord.x += offsetx; waveMovCoord.y -= offsety; - vec4 wave = texture2D(waveTexture, waveMovCoord); + vec4 wave = texture(waveTexture, waveMovCoord); //Wiggle the newCoord by r and b colors of waveTexture vec2 newCoord = texCoord; -- cgit v1.2.3 From ffe79d7f634ef34a4133c608cb3b5978dfff1fe7 Mon Sep 17 00:00:00 2001 From: Mike Krus Date: Tue, 2 May 2017 20:47:35 +0100 Subject: Update manual tests for changes in API Change-Id: Ia9b5ccf8faed1c22c4fe4054c04a149ff12c6675 Reviewed-by: Sean Harmer --- tests/manual/custom-mesh-update-data-qml/main.qml | 6 +++--- tests/manual/dynamic-model-loader-qml/CuboidEntity.qml | 2 +- tests/manual/gltf/main.qml | 2 +- tests/manual/loader-qml/CuboidEntity.qml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/manual/custom-mesh-update-data-qml/main.qml b/tests/manual/custom-mesh-update-data-qml/main.qml index e95c05a26..909dbf9ca 100644 --- a/tests/manual/custom-mesh-update-data-qml/main.qml +++ b/tests/manual/custom-mesh-update-data-qml/main.qml @@ -224,7 +224,7 @@ Entity { byteOffset: 0 byteStride: 9 * 4 count: 4 - name: defaultPositionAttributeName() + name: defaultPositionAttributeName buffer: vertexBuffer } @@ -235,7 +235,7 @@ Entity { byteOffset: 3 * 4 byteStride: 9 * 4 count: 4 - name: defaultNormalAttributeName() + name: defaultNormalAttributeName buffer: vertexBuffer } @@ -246,7 +246,7 @@ Entity { byteOffset: 6 * 4 byteStride: 9 * 4 count: 4 - name: defaultColorAttributeName() + name: defaultColorAttributeName buffer: vertexBuffer } diff --git a/tests/manual/dynamic-model-loader-qml/CuboidEntity.qml b/tests/manual/dynamic-model-loader-qml/CuboidEntity.qml index 8555b6903..d9b33c511 100644 --- a/tests/manual/dynamic-model-loader-qml/CuboidEntity.qml +++ b/tests/manual/dynamic-model-loader-qml/CuboidEntity.qml @@ -76,7 +76,7 @@ Entity { QQ2.ColorAnimation { target: phongMaterial - property: "warmColor" + property: "warm" from: "red" to: "blue" duration: 2500 diff --git a/tests/manual/gltf/main.qml b/tests/manual/gltf/main.qml index 1afb8c48e..39fbb9acf 100644 --- a/tests/manual/gltf/main.qml +++ b/tests/manual/gltf/main.qml @@ -79,7 +79,7 @@ Entity { buffers : ClearBuffers.ColorDepthBuffer clearColor: "black" SortPolicy { - sortTypes: [ SortType.BackToFront ] + sortTypes: [ SortPolicy.BackToFront ] } } } diff --git a/tests/manual/loader-qml/CuboidEntity.qml b/tests/manual/loader-qml/CuboidEntity.qml index 8555b6903..d9b33c511 100644 --- a/tests/manual/loader-qml/CuboidEntity.qml +++ b/tests/manual/loader-qml/CuboidEntity.qml @@ -76,7 +76,7 @@ Entity { QQ2.ColorAnimation { target: phongMaterial - property: "warmColor" + property: "warm" from: "red" to: "blue" duration: 2500 -- cgit v1.2.3 From 6fb72aa81e454b31e042472144db672d39c3c311 Mon Sep 17 00:00:00 2001 From: Mike Krus Date: Tue, 2 May 2017 20:50:37 +0100 Subject: Unregister event filter when surface to close Prevents crash in two window manual test where the object is deleted when PlatformSurfaceFilter destructor tries to remove the event filter Change-Id: I1a37a3cb9088be462957ffbd4412ae5e5241f2df Reviewed-by: Sean Harmer --- src/render/backend/platformsurfacefilter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/render/backend/platformsurfacefilter.cpp b/src/render/backend/platformsurfacefilter.cpp index 891e30c44..7458f607d 100644 --- a/src/render/backend/platformsurfacefilter.cpp +++ b/src/render/backend/platformsurfacefilter.cpp @@ -107,6 +107,10 @@ bool PlatformSurfaceFilter::eventFilter(QObject *obj, QEvent *e) // If we remove it, the call to isSurfaceValid will // implicitely return false PlatformSurfaceFilter::m_surfacesValidity.remove(m_surface); + if (m_obj) { + m_obj->removeEventFilter(this); + m_obj = nullptr; + } break; } -- cgit v1.2.3 From ba2974a8abdf0048d2c8ecc821d369c74598e39f Mon Sep 17 00:00:00 2001 From: Mike Krus Date: Tue, 2 May 2017 09:31:04 +0100 Subject: Update qmltypes files Task-number: QTBUG-60514 Change-Id: Idc42a21109abef5563e6e8cda1a338147bb8dfce Reviewed-by: Sean Harmer --- src/quick3d/imports/animation/plugins.qmltypes | 670 +++++++++++++++++++++++++ src/quick3d/imports/core/plugins.qmltypes | 82 ++- src/quick3d/imports/extras/plugins.qmltypes | 394 +++++++-------- src/quick3d/imports/input/plugins.qmltypes | 86 +++- src/quick3d/imports/logic/plugins.qmltypes | 27 +- src/quick3d/imports/render/plugins.qmltypes | 438 +++++++++++++++- 6 files changed, 1453 insertions(+), 244 deletions(-) create mode 100644 src/quick3d/imports/animation/plugins.qmltypes diff --git a/src/quick3d/imports/animation/plugins.qmltypes b/src/quick3d/imports/animation/plugins.qmltypes new file mode 100644 index 000000000..08879ee52 --- /dev/null +++ b/src/quick3d/imports/animation/plugins.qmltypes @@ -0,0 +1,670 @@ +import QtQuick.tooling 1.2 + +// This file describes the plugin-supplied types contained in the library. +// It is used for QML tooling purposes only. +// +// This file was auto-generated by: +// 'qmlplugindump -nonrelocatable Qt3D.Animation 2.9' + +Module { + dependencies: ["QtQuick 2.8"] + Component { + name: "Qt3DAnimation::Animation::Quick::Quick3DChannelMapper" + defaultProperty: "mappings" + prototype: "Qt3DAnimation::QChannelMapper" + exports: ["Qt3D.Animation/ChannelMapper 2.9"] + exportMetaObjectRevisions: [0] + Property { + name: "mappings" + type: "Qt3DAnimation::QChannelMapping" + isList: true + isReadonly: true + } + } + Component { + name: "Qt3DAnimation::QAbstractAnimation" + prototype: "QObject" + exports: ["Qt3D.Animation/AbstractAnimation 2.9"] + isCreatable: false + exportMetaObjectRevisions: [0] + Enum { + name: "AnimationType" + values: { + "KeyframeAnimation": 1, + "MorphingAnimation": 2, + "VertexBlendAnimation": 3 + } + } + Property { name: "animationName"; type: "string" } + Property { name: "animationType"; type: "QAbstractAnimation::AnimationType"; isReadonly: true } + Property { name: "position"; type: "float" } + Property { name: "duration"; type: "float"; isReadonly: true } + Signal { + name: "animationNameChanged" + Parameter { name: "name"; type: "string" } + } + Signal { + name: "positionChanged" + Parameter { name: "position"; type: "float" } + } + Signal { + name: "durationChanged" + Parameter { name: "duration"; type: "float" } + } + Method { + name: "setAnimationName" + Parameter { name: "name"; type: "string" } + } + Method { + name: "setPosition" + Parameter { name: "position"; type: "float" } + } + } + Component { + name: "Qt3DAnimation::QAbstractAnimationClip" + prototype: "Qt3DCore::QNode" + exports: ["Qt3D.Animation/AbstractAnimationClip 2.9"] + isCreatable: false + exportMetaObjectRevisions: [0] + Property { name: "duration"; type: "float"; isReadonly: true } + Signal { + name: "durationChanged" + Parameter { name: "duration"; type: "float" } + } + } + Component { + name: "Qt3DAnimation::QAbstractClipAnimator" + prototype: "Qt3DCore::QComponent" + exports: ["Qt3D.Animation/AbstractClipAnimator 2.9"] + isCreatable: false + exportMetaObjectRevisions: [0] + Enum { + name: "Loops" + values: { + "Infinite": -1 + } + } + Property { name: "running"; type: "bool" } + Property { name: "loops"; type: "int" } + Property { name: "channelMapper"; type: "Qt3DAnimation::QChannelMapper"; isPointer: true } + Signal { + name: "runningChanged" + Parameter { name: "running"; type: "bool" } + } + Signal { + name: "channelMapperChanged" + Parameter { name: "channelMapper"; type: "Qt3DAnimation::QChannelMapper"; isPointer: true } + } + Signal { + name: "loopCountChanged" + Parameter { name: "loops"; type: "int" } + } + Method { + name: "setRunning" + Parameter { name: "running"; type: "bool" } + } + Method { + name: "setChannelMapper" + Parameter { name: "channelMapper"; type: "Qt3DAnimation::QChannelMapper"; isPointer: true } + } + Method { + name: "setLoopCount" + Parameter { name: "loops"; type: "int" } + } + } + Component { + name: "Qt3DAnimation::QAbstractClipBlendNode" + prototype: "Qt3DCore::QNode" + exports: ["Qt3D.Animation/AbstractClipBlendNode 2.9"] + isCreatable: false + exportMetaObjectRevisions: [0] + } + Component { + name: "Qt3DAnimation::QAdditiveClipBlend" + prototype: "Qt3DAnimation::QAbstractClipBlendNode" + exports: ["Qt3D.Animation/AdditiveClipBlend 2.9"] + exportMetaObjectRevisions: [0] + Property { name: "baseClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true } + Property { + name: "additiveClip" + type: "Qt3DAnimation::QAbstractClipBlendNode" + isPointer: true + } + Property { name: "additiveFactor"; type: "float" } + Signal { + name: "additiveFactorChanged" + Parameter { name: "additiveFactor"; type: "float" } + } + Signal { + name: "baseClipChanged" + Parameter { name: "baseClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true } + } + Signal { + name: "additiveClipChanged" + Parameter { + name: "additiveClip" + type: "Qt3DAnimation::QAbstractClipBlendNode" + isPointer: true + } + } + Method { + name: "setAdditiveFactor" + Parameter { name: "additiveFactor"; type: "float" } + } + Method { + name: "setBaseClip" + Parameter { name: "baseClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true } + } + Method { + name: "setAdditiveClip" + Parameter { + name: "additiveClip" + type: "Qt3DAnimation::QAbstractClipBlendNode" + isPointer: true + } + } + } + Component { + name: "Qt3DAnimation::QAnimationClip" + prototype: "Qt3DAnimation::QAbstractAnimationClip" + exports: ["Qt3D.Animation/AnimationClip 2.9"] + exportMetaObjectRevisions: [0] + Property { name: "clipData"; type: "Qt3DAnimation::QAnimationClipData" } + Signal { + name: "clipDataChanged" + Parameter { name: "clipData"; type: "Qt3DAnimation::QAnimationClipData" } + } + Method { + name: "setClipData" + Parameter { name: "clipData"; type: "Qt3DAnimation::QAnimationClipData" } + } + } + Component { + name: "Qt3DAnimation::QAnimationClipLoader" + prototype: "Qt3DAnimation::QAbstractAnimationClip" + exports: ["Qt3D.Animation/AnimationClipLoader 2.9"] + exportMetaObjectRevisions: [0] + Enum { + name: "Status" + values: { + "NotReady": 0, + "Ready": 1, + "Error": 2 + } + } + Property { name: "source"; type: "QUrl" } + Property { name: "status"; type: "Status"; isReadonly: true } + Signal { + name: "sourceChanged" + Parameter { name: "source"; type: "QUrl" } + } + Signal { + name: "statusChanged" + Parameter { name: "status"; type: "Status" } + } + Method { + name: "setSource" + Parameter { name: "source"; type: "QUrl" } + } + } + Component { + name: "Qt3DAnimation::QAnimationController" + prototype: "QObject" + Property { name: "activeAnimationGroup"; type: "int" } + Property { name: "position"; type: "float" } + Property { name: "positionScale"; type: "float" } + Property { name: "positionOffset"; type: "float" } + Property { name: "entity"; type: "Qt3DCore::QEntity"; isPointer: true } + Property { name: "recursive"; type: "bool" } + Signal { + name: "activeAnimationGroupChanged" + Parameter { name: "index"; type: "int" } + } + Signal { + name: "positionChanged" + Parameter { name: "position"; type: "float" } + } + Signal { + name: "positionScaleChanged" + Parameter { name: "scale"; type: "float" } + } + Signal { + name: "positionOffsetChanged" + Parameter { name: "offset"; type: "float" } + } + Signal { + name: "entityChanged" + Parameter { name: "entity"; type: "Qt3DCore::QEntity"; isPointer: true } + } + Signal { + name: "recursiveChanged" + Parameter { name: "recursive"; type: "bool" } + } + Method { + name: "setActiveAnimationGroup" + Parameter { name: "index"; type: "int" } + } + Method { + name: "setPosition" + Parameter { name: "position"; type: "float" } + } + Method { + name: "setPositionScale" + Parameter { name: "scale"; type: "float" } + } + Method { + name: "setPositionOffset" + Parameter { name: "offset"; type: "float" } + } + Method { + name: "setEntity" + Parameter { name: "entity"; type: "Qt3DCore::QEntity"; isPointer: true } + } + Method { + name: "setRecursive" + Parameter { name: "recursive"; type: "bool" } + } + Method { + name: "getAnimationIndex" + type: "int" + Parameter { name: "name"; type: "string" } + } + Method { + name: "getGroup" + type: "Qt3DAnimation::QAnimationGroup*" + Parameter { name: "index"; type: "int" } + } + } + Component { + name: "Qt3DAnimation::QAnimationGroup" + prototype: "QObject" + Property { name: "name"; type: "string" } + Property { name: "position"; type: "float" } + Property { name: "duration"; type: "float"; isReadonly: true } + Signal { + name: "nameChanged" + Parameter { name: "name"; type: "string" } + } + Signal { + name: "positionChanged" + Parameter { name: "position"; type: "float" } + } + Signal { + name: "durationChanged" + Parameter { name: "duration"; type: "float" } + } + Method { + name: "setName" + Parameter { name: "name"; type: "string" } + } + Method { + name: "setPosition" + Parameter { name: "position"; type: "float" } + } + } + Component { + name: "Qt3DAnimation::QBlendedClipAnimator" + prototype: "Qt3DAnimation::QAbstractClipAnimator" + exports: ["Qt3D.Animation/BlendedClipAnimator 2.9"] + exportMetaObjectRevisions: [0] + Property { name: "blendTree"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true } + Signal { + name: "blendTreeChanged" + Parameter { name: "blendTree"; type: "QAbstractClipBlendNode"; isPointer: true } + } + Method { + name: "setBlendTree" + Parameter { name: "blendTree"; type: "QAbstractClipBlendNode"; isPointer: true } + } + } + Component { name: "Qt3DAnimation::QChannelMapper"; prototype: "Qt3DCore::QNode" } + Component { + name: "Qt3DAnimation::QChannelMapping" + prototype: "Qt3DCore::QNode" + exports: ["Qt3D.Animation/ChannelMapping 2.9"] + exportMetaObjectRevisions: [0] + Property { name: "channelName"; type: "string" } + Property { name: "target"; type: "Qt3DCore::QNode"; isPointer: true } + Property { name: "property"; type: "string" } + Signal { + name: "channelNameChanged" + Parameter { name: "channelName"; type: "string" } + } + Signal { + name: "targetChanged" + Parameter { name: "target"; type: "Qt3DCore::QNode"; isPointer: true } + } + Signal { + name: "propertyChanged" + Parameter { name: "property"; type: "string" } + } + Method { + name: "setChannelName" + Parameter { name: "channelName"; type: "string" } + } + Method { + name: "setTarget" + Parameter { name: "target"; type: "Qt3DCore::QNode"; isPointer: true } + } + Method { + name: "setProperty" + Parameter { name: "property"; type: "string" } + } + } + Component { + name: "Qt3DAnimation::QClipAnimator" + prototype: "Qt3DAnimation::QAbstractClipAnimator" + exports: ["Qt3D.Animation/ClipAnimator 2.9"] + exportMetaObjectRevisions: [0] + Property { name: "clip"; type: "Qt3DAnimation::QAbstractAnimationClip"; isPointer: true } + Signal { + name: "clipChanged" + Parameter { name: "clip"; type: "Qt3DAnimation::QAbstractAnimationClip"; isPointer: true } + } + Method { + name: "setClip" + Parameter { name: "clip"; type: "Qt3DAnimation::QAbstractAnimationClip"; isPointer: true } + } + } + Component { + name: "Qt3DAnimation::QClipBlendValue" + prototype: "Qt3DAnimation::QAbstractClipBlendNode" + exports: ["Qt3D.Animation/ClipBlendValue 2.9"] + exportMetaObjectRevisions: [0] + Property { name: "clip"; type: "Qt3DAnimation::QAbstractAnimationClip"; isPointer: true } + Signal { + name: "clipChanged" + Parameter { name: "clip"; type: "Qt3DAnimation::QAbstractAnimationClip"; isPointer: true } + } + Method { + name: "setClip" + Parameter { name: "clip"; type: "Qt3DAnimation::QAbstractAnimationClip"; isPointer: true } + } + } + Component { + name: "Qt3DAnimation::QKeyframeAnimation" + prototype: "Qt3DAnimation::QAbstractAnimation" + Enum { + name: "RepeatMode" + values: { + "None": 0, + "Constant": 1, + "Repeat": 2 + } + } + Property { name: "framePositions"; type: "QVector" } + Property { name: "target"; type: "Qt3DCore::QTransform"; isPointer: true } + Property { name: "easing"; type: "QEasingCurve" } + Property { name: "targetName"; type: "string" } + Property { name: "startMode"; type: "QKeyframeAnimation::RepeatMode" } + Property { name: "endMode"; type: "QKeyframeAnimation::RepeatMode" } + Signal { + name: "framePositionsChanged" + Parameter { name: "positions"; type: "QVector" } + } + Signal { + name: "targetChanged" + Parameter { name: "target"; type: "Qt3DCore::QTransform"; isPointer: true } + } + Signal { + name: "easingChanged" + Parameter { name: "easing"; type: "QEasingCurve" } + } + Signal { + name: "targetNameChanged" + Parameter { name: "name"; type: "string" } + } + Signal { + name: "startModeChanged" + Parameter { name: "startMode"; type: "QKeyframeAnimation::RepeatMode" } + } + Signal { + name: "endModeChanged" + Parameter { name: "endMode"; type: "QKeyframeAnimation::RepeatMode" } + } + Method { + name: "setFramePositions" + Parameter { name: "positions"; type: "QVector" } + } + Method { + name: "setTarget" + Parameter { name: "target"; type: "Qt3DCore::QTransform"; isPointer: true } + } + Method { + name: "setEasing" + Parameter { name: "easing"; type: "QEasingCurve" } + } + Method { + name: "setTargetName" + Parameter { name: "name"; type: "string" } + } + Method { + name: "setStartMode" + Parameter { name: "mode"; type: "RepeatMode" } + } + Method { + name: "setEndMode" + Parameter { name: "mode"; type: "RepeatMode" } + } + } + Component { + name: "Qt3DAnimation::QLerpClipBlend" + prototype: "Qt3DAnimation::QAbstractClipBlendNode" + exports: ["Qt3D.Animation/LerpClipBlend 2.9"] + exportMetaObjectRevisions: [0] + Property { name: "startClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true } + Property { name: "endClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true } + Property { name: "blendFactor"; type: "float" } + Signal { + name: "blendFactorChanged" + Parameter { name: "blendFactor"; type: "float" } + } + Signal { + name: "startClipChanged" + Parameter { name: "startClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true } + } + Signal { + name: "endClipChanged" + Parameter { name: "endClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true } + } + Method { + name: "setBlendFactor" + Parameter { name: "blendFactor"; type: "float" } + } + Method { + name: "setStartClip" + Parameter { name: "startClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true } + } + Method { + name: "setEndClip" + Parameter { name: "endClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true } + } + } + Component { + name: "Qt3DAnimation::QMorphTarget" + prototype: "QObject" + Property { name: "attributeNames"; type: "QStringList"; isReadonly: true } + Signal { + name: "attributeNamesChanged" + Parameter { name: "attributeNames"; type: "QStringList" } + } + Method { + name: "fromGeometry" + type: "QMorphTarget*" + Parameter { name: "geometry"; type: "Qt3DRender::QGeometry"; isPointer: true } + Parameter { name: "attributes"; type: "QStringList" } + } + } + Component { + name: "Qt3DAnimation::QMorphingAnimation" + prototype: "Qt3DAnimation::QAbstractAnimation" + Enum { + name: "Method" + values: { + "Normalized": 0, + "Relative": 1 + } + } + Property { name: "targetPositions"; type: "QVector" } + Property { name: "interpolator"; type: "float"; isReadonly: true } + Property { name: "target"; type: "Qt3DRender::QGeometryRenderer"; isPointer: true } + Property { name: "targetName"; type: "string" } + Property { name: "method"; type: "QMorphingAnimation::Method" } + Property { name: "easing"; type: "QEasingCurve" } + Signal { + name: "targetPositionsChanged" + Parameter { name: "targetPositions"; type: "QVector" } + } + Signal { + name: "interpolatorChanged" + Parameter { name: "interpolator"; type: "float" } + } + Signal { + name: "targetChanged" + Parameter { name: "target"; type: "Qt3DRender::QGeometryRenderer"; isPointer: true } + } + Signal { + name: "targetNameChanged" + Parameter { name: "name"; type: "string" } + } + Signal { + name: "methodChanged" + Parameter { name: "method"; type: "QMorphingAnimation::Method" } + } + Signal { + name: "easingChanged" + Parameter { name: "easing"; type: "QEasingCurve" } + } + Method { + name: "setTargetPositions" + Parameter { name: "targetPositions"; type: "QVector" } + } + Method { + name: "setTarget" + Parameter { name: "target"; type: "Qt3DRender::QGeometryRenderer"; isPointer: true } + } + Method { + name: "setTargetName" + Parameter { name: "name"; type: "string" } + } + Method { + name: "setMethod" + Parameter { name: "method"; type: "QMorphingAnimation::Method" } + } + Method { + name: "setEasing" + Parameter { name: "easing"; type: "QEasingCurve" } + } + } + Component { + name: "Qt3DAnimation::Quick::QQuick3DAnimationController" + prototype: "Qt3DAnimation::QAnimationController" + exports: ["Qt3D.Animation/AnimationController 2.9"] + exportMetaObjectRevisions: [0] + Property { + name: "animationGroups" + type: "Qt3DAnimation::QAnimationGroup" + isList: true + isReadonly: true + } + } + Component { + name: "Qt3DAnimation::Quick::QQuick3DAnimationGroup" + prototype: "Qt3DAnimation::QAnimationGroup" + exports: ["Qt3D.Animation/AnimationGroup 2.9"] + exportMetaObjectRevisions: [0] + Property { + name: "animations" + type: "Qt3DAnimation::QAbstractAnimation" + isList: true + isReadonly: true + } + } + Component { + name: "Qt3DAnimation::Quick::QQuick3DKeyframeAnimation" + prototype: "Qt3DAnimation::QKeyframeAnimation" + exports: ["Qt3D.Animation/KeyframeAnimation 2.9"] + exportMetaObjectRevisions: [0] + Property { name: "keyframes"; type: "Qt3DCore::QTransform"; isList: true; isReadonly: true } + } + Component { + name: "Qt3DAnimation::Quick::QQuick3DMorphTarget" + prototype: "Qt3DAnimation::QMorphTarget" + exports: ["Qt3D.Animation/MorphTarget 2.9"] + exportMetaObjectRevisions: [0] + Property { name: "attributes"; type: "Qt3DRender::QAttribute"; isList: true; isReadonly: true } + } + Component { + name: "Qt3DAnimation::Quick::QQuick3DMorphingAnimation" + prototype: "Qt3DAnimation::QMorphingAnimation" + exports: ["Qt3D.Animation/MorphingAnimation 2.9"] + exportMetaObjectRevisions: [0] + Property { + name: "morphTargets" + type: "Qt3DAnimation::QMorphTarget" + isList: true + isReadonly: true + } + } + Component { + name: "Qt3DCore::QComponent" + prototype: "Qt3DCore::QNode" + Property { name: "isShareable"; type: "bool" } + Signal { + name: "shareableChanged" + Parameter { name: "isShareable"; type: "bool" } + } + Signal { + name: "addedToEntity" + Parameter { name: "entity"; type: "QEntity"; isPointer: true } + } + Signal { + name: "removedFromEntity" + Parameter { name: "entity"; type: "QEntity"; isPointer: true } + } + Method { + name: "setShareable" + Parameter { name: "isShareable"; type: "bool" } + } + } + Component { + name: "Qt3DCore::QNode" + prototype: "QObject" + Enum { + name: "PropertyTrackingMode" + values: { + "TrackFinalValues": 0, + "DontTrackValues": 1, + "TrackAllValues": 2 + } + } + Property { name: "parent"; type: "Qt3DCore::QNode"; isPointer: true } + Property { name: "enabled"; type: "bool" } + Property { name: "defaultPropertyTrackingMode"; revision: 9; type: "PropertyTrackingMode" } + Signal { + name: "parentChanged" + Parameter { name: "parent"; type: "QObject"; isPointer: true } + } + Signal { + name: "enabledChanged" + Parameter { name: "enabled"; type: "bool" } + } + Signal { + name: "defaultPropertyTrackingModeChanged" + Parameter { name: "mode"; type: "PropertyTrackingMode" } + } + Signal { name: "nodeDestroyed" } + Method { + name: "setParent" + Parameter { name: "parent"; type: "QNode"; isPointer: true } + } + Method { + name: "setEnabled" + Parameter { name: "isEnabled"; type: "bool" } + } + Method { + name: "setDefaultPropertyTrackingMode" + Parameter { name: "mode"; type: "PropertyTrackingMode" } + } + } +} diff --git a/src/quick3d/imports/core/plugins.qmltypes b/src/quick3d/imports/core/plugins.qmltypes index ed06f8e0c..87cdac04c 100644 --- a/src/quick3d/imports/core/plugins.qmltypes +++ b/src/quick3d/imports/core/plugins.qmltypes @@ -4,29 +4,41 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -nonrelocatable Qt3D.Core 2.0' +// 'qmlplugindump -nonrelocatable Qt3D.Core 2.9' Module { - dependencies: ["QtQuick 2.7"] + dependencies: ["QtQuick 2.8"] Component { name: "Qt3DCore::QComponent" - prototype: "Qt3DCore::QNode" - Property { name: "isShareable"; type: "bool" } + defaultProperty: "data" + prototype: "Qt3DCore::QComponent" + Property { name: "propertyTrackingOverrides"; type: "QJSValue" } + Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } + Property { name: "childNodes"; type: "Qt3DCore::QNode"; isList: true; isReadonly: true } Signal { - name: "shareableChanged" - Parameter { name: "isShareable"; type: "bool" } + name: "propertyTrackingOverridesChanged" + Parameter { name: "value"; type: "QJSValue" } } - Method { - name: "setShareable" - Parameter { name: "isShareable"; type: "bool" } + Signal { + name: "propertyTrackingOverridesChanged" + Parameter { name: "value"; type: "QJSValue" } } } Component { name: "Qt3DCore::QEntity"; prototype: "Qt3DCore::QNode" } Component { name: "Qt3DCore::QNode" prototype: "QObject" + Enum { + name: "PropertyTrackingMode" + values: { + "TrackFinalValues": 0, + "DontTrackValues": 1, + "TrackAllValues": 2 + } + } Property { name: "parent"; type: "Qt3DCore::QNode"; isPointer: true } Property { name: "enabled"; type: "bool" } + Property { name: "defaultPropertyTrackingMode"; revision: 9; type: "PropertyTrackingMode" } Signal { name: "parentChanged" Parameter { name: "parent"; type: "QObject"; isPointer: true } @@ -35,6 +47,10 @@ Module { name: "enabledChanged" Parameter { name: "enabled"; type: "bool" } } + Signal { + name: "defaultPropertyTrackingModeChanged" + Parameter { name: "mode"; type: "PropertyTrackingMode" } + } Signal { name: "nodeDestroyed" } Method { name: "setParent" @@ -44,11 +60,14 @@ Module { name: "setEnabled" Parameter { name: "isEnabled"; type: "bool" } } + Method { + name: "setDefaultPropertyTrackingMode" + Parameter { name: "mode"; type: "PropertyTrackingMode" } + } } Component { name: "Qt3DCore::QTransform" prototype: "Qt3DCore::QComponent" - exports: ["Qt3D.Core/Transform 2.0"] Property { name: "matrix"; type: "QMatrix4x4" } Property { name: "scale"; type: "float" } Property { name: "scale3D"; type: "QVector3D" } @@ -230,10 +249,8 @@ Module { Component { name: "Qt3DCore::Quick::Quick3DEntityLoader" defaultProperty: "data" - prototype: "Qt3DCore::QEntity" - exports: ["Qt3D.Core/EntityLoader 2.0"] - Property { name: "entity"; type: "Qt3DCore::QEntity"; isPointer: true; isReadonly: true } - Property { name: "source"; type: "QUrl" } + prototype: "Qt3DCore::Quick::Quick3DEntityLoader" + Property { name: "components"; type: "Qt3DCore::QComponent"; isList: true; isReadonly: true } } Component { name: "Qt3DCore::Quick::Quick3DNode" @@ -248,13 +265,36 @@ Module { Component { name: "Qt3DCore::Quick::Quick3DNodeInstantiator" defaultProperty: "delegate" + prototype: "Qt3DCore::Quick::Quick3DNodeInstantiator" + Property { name: "propertyTrackingOverrides"; type: "QJSValue" } + Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } + Property { name: "childNodes"; type: "Qt3DCore::QNode"; isList: true; isReadonly: true } + Signal { + name: "propertyTrackingOverridesChanged" + Parameter { name: "value"; type: "QJSValue" } + } + Signal { + name: "propertyTrackingOverridesChanged" + Parameter { name: "value"; type: "QJSValue" } + } + } + Component { + name: "Qt3DCore::Quick::Quick3DNodeV9" + defaultProperty: "data" prototype: "Qt3DCore::QNode" - exports: ["Qt3D.Core/NodeInstantiator 2.0"] - Property { name: "active"; type: "bool" } - Property { name: "asynchronous"; type: "bool" } - Property { name: "model"; type: "QVariant" } - Property { name: "count"; type: "int"; isReadonly: true } - Property { name: "delegate"; type: "QQmlComponent" } - Property { name: "object"; type: "QObject"; isReadonly: true } + exports: ["Qt3D.Core/Node 2.9"] + isCreatable: false + exportMetaObjectRevisions: [9] + Property { name: "propertyTrackingOverrides"; type: "QJSValue" } + Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } + Property { name: "childNodes"; type: "Qt3DCore::QNode"; isList: true; isReadonly: true } + Signal { + name: "propertyTrackingOverridesChanged" + Parameter { name: "value"; type: "QJSValue" } + } + Signal { + name: "propertyTrackingOverridesChanged" + Parameter { name: "value"; type: "QJSValue" } + } } } diff --git a/src/quick3d/imports/extras/plugins.qmltypes b/src/quick3d/imports/extras/plugins.qmltypes index cbe12c9ad..a623f385c 100644 --- a/src/quick3d/imports/extras/plugins.qmltypes +++ b/src/quick3d/imports/extras/plugins.qmltypes @@ -4,68 +4,30 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -nonrelocatable Qt3D.Extras 2.0' +// 'qmlplugindump -nonrelocatable Qt3D.Extras 2.9' Module { - dependencies: [] - Component { - name: "Qt3DCore::QComponent" - prototype: "Qt3DCore::QNode" - Property { name: "isShareable"; type: "bool" } - Signal { - name: "shareableChanged" - Parameter { name: "isShareable"; type: "bool" } - } - Signal { - name: "addedToEntity" - Parameter { name: "entity"; type: "QEntity"; isPointer: true } - } - Signal { - name: "removedFromEntity" - Parameter { name: "entity"; type: "QEntity"; isPointer: true } - } - Method { - name: "setShareable" - Parameter { name: "isShareable"; type: "bool" } - } - } + dependencies: ["Qt3D.Logic 2.0"] Component { name: "Qt3DCore::QEntity"; prototype: "Qt3DCore::QNode" } - Component { - name: "Qt3DCore::QNode" - prototype: "QObject" - Property { name: "parent"; type: "Qt3DCore::QNode"; isPointer: true } - Property { name: "enabled"; type: "bool" } - Signal { - name: "parentChanged" - Parameter { name: "parent"; type: "QObject"; isPointer: true } - } - Signal { - name: "enabledChanged" - Parameter { name: "enabled"; type: "bool" } - } - Signal { name: "nodeDestroyed" } - Method { - name: "setParent" - Parameter { name: "parent"; type: "QNode"; isPointer: true } - } - Method { - name: "setEnabled" - Parameter { name: "isEnabled"; type: "bool" } - } - } Component { name: "Qt3DExtras::Extras::Quick::Quick3DLevelOfDetailLoader" prototype: "Qt3DCore::QEntity" - exports: ["Qt3D.Extras/LevelOfDetailLoader 2.2"] + exports: ["Qt3D.Extras/LevelOfDetailLoader 2.9"] exportMetaObjectRevisions: [0] Property { name: "sources"; type: "QVariantList" } Property { name: "camera"; type: "Qt3DRender::QCamera"; isPointer: true } Property { name: "currentIndex"; type: "int" } Property { name: "thresholdType"; type: "Qt3DRender::QLevelOfDetail::ThresholdType" } Property { name: "thresholds"; type: "QVector" } - Property { name: "volumeOverride"; type: "Qt3DRender::QBoundingSphere"; isPointer: true } + Property { name: "volumeOverride"; type: "Qt3DRender::QLevelOfDetailBoundingSphere" } Property { name: "entity"; type: "QObject"; isReadonly: true; isPointer: true } Property { name: "source"; type: "QUrl"; isReadonly: true } + Method { + name: "createBoundingSphere" + type: "Qt3DRender::QLevelOfDetailBoundingSphere" + Parameter { name: "center"; type: "QVector3D" } + Parameter { name: "radius"; type: "float" } + } } Component { name: "Qt3DExtras::QConeGeometry" @@ -589,6 +551,90 @@ Module { Parameter { name: "textureScale"; type: "float" } } } + Component { + name: "Qt3DExtras::QExtrudedTextGeometry" + prototype: "Qt3DRender::QGeometry" + exports: ["Qt3D.Extras/ExtrudedTextGeometry 2.9"] + exportMetaObjectRevisions: [0] + Property { name: "text"; type: "string" } + Property { name: "font"; type: "QFont" } + Property { name: "extrusionLength"; type: "float" } + Property { + name: "positionAttribute" + type: "Qt3DRender::QAttribute" + isReadonly: true + isPointer: true + } + Property { + name: "normalAttribute" + type: "Qt3DRender::QAttribute" + isReadonly: true + isPointer: true + } + Property { + name: "indexAttribute" + type: "Qt3DRender::QAttribute" + isReadonly: true + isPointer: true + } + Signal { + name: "textChanged" + Parameter { name: "text"; type: "string" } + } + Signal { + name: "fontChanged" + Parameter { name: "font"; type: "QFont" } + } + Signal { + name: "depthChanged" + Parameter { name: "extrusionLength"; type: "float" } + } + Method { + name: "setText" + Parameter { name: "text"; type: "string" } + } + Method { + name: "setFont" + Parameter { name: "font"; type: "QFont" } + } + Method { + name: "setDepth" + Parameter { name: "extrusionLength"; type: "float" } + } + } + Component { + name: "Qt3DExtras::QExtrudedTextMesh" + prototype: "Qt3DRender::QGeometryRenderer" + exports: ["Qt3D.Extras/ExtrudedTextMesh 2.9"] + exportMetaObjectRevisions: [0] + Property { name: "text"; type: "string" } + Property { name: "font"; type: "QFont" } + Property { name: "depth"; type: "float" } + Signal { + name: "textChanged" + Parameter { name: "text"; type: "string" } + } + Signal { + name: "fontChanged" + Parameter { name: "font"; type: "QFont" } + } + Signal { + name: "depthChanged" + Parameter { name: "depth"; type: "float" } + } + Method { + name: "setText" + Parameter { name: "text"; type: "string" } + } + Method { + name: "setFont" + Parameter { name: "font"; type: "QFont" } + } + Method { + name: "setDepth" + Parameter { name: "depth"; type: "float" } + } + } Component { name: "Qt3DExtras::QFirstPersonCameraController" prototype: "Qt3DCore::QEntity" @@ -599,6 +645,14 @@ Module { Property { name: "lookSpeed"; type: "float" } Property { name: "acceleration"; type: "float" } Property { name: "deceleration"; type: "float" } + Signal { + name: "accelerationChanged" + Parameter { name: "acceleration"; type: "float" } + } + Signal { + name: "decelerationChanged" + Parameter { name: "deceleration"; type: "float" } + } } Component { name: "Qt3DExtras::QForwardRenderer" @@ -612,6 +666,7 @@ Module { Property { name: "camera"; type: "Qt3DCore::QEntity"; isPointer: true } Property { name: "externalRenderTargetSize"; type: "QSize" } Property { name: "frustumCulling"; type: "bool" } + Property { name: "gamma"; revision: 9; type: "float" } Signal { name: "viewportRectChanged" Parameter { name: "viewportRect"; type: "QRectF" } @@ -636,6 +691,10 @@ Module { name: "frustumCullingEnabledChanged" Parameter { name: "enabled"; type: "bool" } } + Signal { + name: "gammaChanged" + Parameter { name: "gamma"; type: "float" } + } Method { name: "setViewportRect" Parameter { name: "viewportRect"; type: "QRectF" } @@ -660,6 +719,10 @@ Module { name: "setFrustumCullingEnabled" Parameter { name: "enabled"; type: "bool" } } + Method { + name: "setGamma" + Parameter { name: "gamma"; type: "float" } + } } Component { name: "Qt3DExtras::QGoochMaterial" @@ -733,18 +796,11 @@ Module { Component { name: "Qt3DExtras::QMetalRoughMaterial" prototype: "Qt3DRender::QMaterial" - exports: ["Qt3D.Extras/MetalRoughMaterial 2.2"] + exports: ["Qt3D.Extras/MetalRoughMaterial 2.9"] exportMetaObjectRevisions: [0] Property { name: "baseColor"; type: "QColor" } Property { name: "metalness"; type: "float" } Property { name: "roughness"; type: "float" } - Property { - name: "environmentIrradiance" - type: "Qt3DRender::QAbstractTexture" - isPointer: true - } - Property { name: "environmentSpecular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } - Property { name: "exposure"; type: "float" } Signal { name: "baseColorChanged" Parameter { name: "baseColor"; type: "QColor" } @@ -757,22 +813,6 @@ Module { name: "roughnessChanged" Parameter { name: "roughness"; type: "float" } } - Signal { - name: "environmentIrradianceChanged" - Parameter { - name: "environmentIrradiance" - type: "Qt3DRender::QAbstractTexture" - isPointer: true - } - } - Signal { - name: "environmentSpecularChanged" - Parameter { name: "environmentSpecular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } - } - Signal { - name: "exposureChanged" - Parameter { name: "exposure"; type: "float" } - } Method { name: "setBaseColor" Parameter { name: "baseColor"; type: "QColor" } @@ -785,21 +825,56 @@ Module { name: "setRoughness" Parameter { name: "roughness"; type: "float" } } + } + Component { + name: "Qt3DExtras::QMorphPhongMaterial" + prototype: "Qt3DRender::QMaterial" + exports: ["Qt3D.Extras/MorphPhongMaterial 2.9"] + exportMetaObjectRevisions: [0] + Property { name: "ambient"; type: "QColor" } + Property { name: "diffuse"; type: "QColor" } + Property { name: "specular"; type: "QColor" } + Property { name: "shininess"; type: "float" } + Property { name: "interpolator"; type: "float" } + Signal { + name: "ambientChanged" + Parameter { name: "ambient"; type: "QColor" } + } + Signal { + name: "diffuseChanged" + Parameter { name: "diffuse"; type: "QColor" } + } + Signal { + name: "specularChanged" + Parameter { name: "specular"; type: "QColor" } + } + Signal { + name: "shininessChanged" + Parameter { name: "shininess"; type: "float" } + } + Signal { + name: "interpolatorChanged" + Parameter { name: "interpolator"; type: "float" } + } Method { - name: "setEnvironmentIrradiance" - Parameter { - name: "environmentIrradiance" - type: "Qt3DRender::QAbstractTexture" - isPointer: true - } + name: "setAmbient" + Parameter { name: "ambient"; type: "QColor" } + } + Method { + name: "setDiffuse" + Parameter { name: "diffuse"; type: "QColor" } } Method { - name: "setEnvironmentSpecular" - Parameter { name: "environmentSpecular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } + name: "setSpecular" + Parameter { name: "specular"; type: "QColor" } } Method { - name: "setExposure" - Parameter { name: "exposure"; type: "float" } + name: "setShininess" + Parameter { name: "shininess"; type: "float" } + } + Method { + name: "setInterpolator" + Parameter { name: "interpolator"; type: "float" } } } Component { @@ -1194,6 +1269,7 @@ Module { exportMetaObjectRevisions: [0] Property { name: "baseName"; type: "string" } Property { name: "extension"; type: "string" } + Property { name: "gammaCorrect"; revision: 9; type: "bool" } Signal { name: "baseNameChanged" Parameter { name: "path"; type: "string" } @@ -1202,6 +1278,22 @@ Module { name: "extensionChanged" Parameter { name: "extension"; type: "string" } } + Signal { + name: "gammaCorrectEnabledChanged" + Parameter { name: "enabled"; type: "bool" } + } + Method { + name: "setBaseName" + Parameter { name: "path"; type: "string" } + } + Method { + name: "setExtension" + Parameter { name: "extension"; type: "string" } + } + Method { + name: "setGammaCorrectEnabled" + Parameter { name: "enabled"; type: "bool" } + } } Component { name: "Qt3DExtras::QSphereGeometry" @@ -1318,105 +1410,34 @@ Module { } } Component { - name: "Qt3DExtras::QText3DGeometry" - prototype: "Qt3DRender::QGeometry" - exports: ["Qt3D.Extras/Text3DGeometry 2.2"] + name: "Qt3DExtras::QText2DEntity" + prototype: "Qt3DCore::QEntity" + exports: ["Qt3D.Extras/Text2DEntity 2.9"] exportMetaObjectRevisions: [0] - Property { name: "text"; type: "string" } Property { name: "font"; type: "QFont" } - Property { name: "depth"; type: "float" } - Property { name: "edgeSplitAngle"; type: "float" } - Property { - name: "positionAttribute" - type: "Qt3DRender::QAttribute" - isReadonly: true - isPointer: true - } - Property { - name: "normalAttribute" - type: "Qt3DRender::QAttribute" - isReadonly: true - isPointer: true - } - Property { - name: "indexAttribute" - type: "Qt3DRender::QAttribute" - isReadonly: true - isPointer: true - } - Signal { - name: "textChanged" - Parameter { name: "text"; type: "string" } - } + Property { name: "text"; type: "string" } + Property { name: "color"; type: "QColor" } + Property { name: "width"; type: "float" } + Property { name: "height"; type: "float" } Signal { name: "fontChanged" Parameter { name: "font"; type: "QFont" } } Signal { - name: "depthChanged" - Parameter { name: "depth"; type: "float" } - } - Signal { - name: "edgeSplitAngleChanged" - Parameter { name: "edgeSplitAngle"; type: "float" } - } - Method { - name: "setText" - Parameter { name: "text"; type: "string" } - } - Method { - name: "setFont" - Parameter { name: "font"; type: "QFont" } - } - Method { - name: "setDepth" - Parameter { name: "depth"; type: "float" } - } - Method { - name: "setEdgeSplitAngle" - Parameter { name: "edgeSplitAngle"; type: "float" } + name: "colorChanged" + Parameter { name: "color"; type: "QColor" } } - } - Component { - name: "Qt3DExtras::QText3DMesh" - prototype: "Qt3DRender::QGeometryRenderer" - exports: ["Qt3D.Extras/Text3DMesh 2.2"] - exportMetaObjectRevisions: [0] - Property { name: "text"; type: "string" } - Property { name: "font"; type: "QFont" } - Property { name: "depth"; type: "float" } - Property { name: "edgeSplitAngle"; type: "float" } Signal { name: "textChanged" Parameter { name: "text"; type: "string" } } Signal { - name: "fontChanged" - Parameter { name: "font"; type: "QFont" } - } - Signal { - name: "depthChanged" - Parameter { name: "depth"; type: "float" } + name: "widthChanged" + Parameter { name: "width"; type: "float" } } Signal { - name: "edgeSplitAngleChanged" - Parameter { name: "edgeSplitAngle"; type: "float" } - } - Method { - name: "setText" - Parameter { name: "text"; type: "string" } - } - Method { - name: "setFont" - Parameter { name: "font"; type: "QFont" } - } - Method { - name: "setDepth" - Parameter { name: "depth"; type: "float" } - } - Method { - name: "setEdgeSplitAngle" - Parameter { name: "edgeSplitAngle"; type: "float" } + name: "heightChanged" + Parameter { name: "height"; type: "float" } } } Component { @@ -1446,20 +1467,13 @@ Module { Component { name: "Qt3DExtras::QTexturedMetalRoughMaterial" prototype: "Qt3DRender::QMaterial" - exports: ["Qt3D.Extras/TexturedMetalRoughMaterial 2.2"] + exports: ["Qt3D.Extras/TexturedMetalRoughMaterial 2.9"] exportMetaObjectRevisions: [0] Property { name: "baseColor"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } Property { name: "metalness"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } Property { name: "roughness"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } Property { name: "ambientOcclusion"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } Property { name: "normal"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } - Property { - name: "environmentIrradiance" - type: "Qt3DRender::QAbstractTexture" - isPointer: true - } - Property { name: "environmentSpecular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } - Property { name: "exposure"; type: "float" } Signal { name: "baseColorChanged" Parameter { name: "baseColor"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } @@ -1480,22 +1494,6 @@ Module { name: "normalChanged" Parameter { name: "normal"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } } - Signal { - name: "environmentIrradianceChanged" - Parameter { - name: "environmentIrradiance" - type: "Qt3DRender::QAbstractTexture" - isPointer: true - } - } - Signal { - name: "environmentSpecularChanged" - Parameter { name: "environmentSpecular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } - } - Signal { - name: "exposureChanged" - Parameter { name: "exposure"; type: "float" } - } Method { name: "setBaseColor" Parameter { name: "baseColor"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } @@ -1516,22 +1514,6 @@ Module { name: "setNormal" Parameter { name: "normal"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } } - Method { - name: "setEnvironmentIrradiance" - Parameter { - name: "environmentIrradiance" - type: "Qt3DRender::QAbstractTexture" - isPointer: true - } - } - Method { - name: "setEnvironmentSpecular" - Parameter { name: "environmentSpecular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } - } - Method { - name: "setExposure" - Parameter { name: "exposure"; type: "float" } - } } Component { name: "Qt3DExtras::QTorusGeometry" diff --git a/src/quick3d/imports/input/plugins.qmltypes b/src/quick3d/imports/input/plugins.qmltypes index 860ab4d68..24655977e 100644 --- a/src/quick3d/imports/input/plugins.qmltypes +++ b/src/quick3d/imports/input/plugins.qmltypes @@ -4,10 +4,10 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -nonrelocatable Qt3D.Input 2.0' +// 'qmlplugindump -nonrelocatable Qt3D.Input 2.1' Module { - dependencies: ["QtQuick 2.7"] + dependencies: ["QtQuick 2.8"] Component { name: "Qt3DCore::QComponent" prototype: "Qt3DCore::QNode" @@ -16,6 +16,14 @@ Module { name: "shareableChanged" Parameter { name: "isShareable"; type: "bool" } } + Signal { + name: "addedToEntity" + Parameter { name: "entity"; type: "QEntity"; isPointer: true } + } + Signal { + name: "removedFromEntity" + Parameter { name: "entity"; type: "QEntity"; isPointer: true } + } Method { name: "setShareable" Parameter { name: "isShareable"; type: "bool" } @@ -24,8 +32,17 @@ Module { Component { name: "Qt3DCore::QNode" prototype: "QObject" + Enum { + name: "PropertyTrackingMode" + values: { + "TrackFinalValues": 0, + "DontTrackValues": 1, + "TrackAllValues": 2 + } + } Property { name: "parent"; type: "Qt3DCore::QNode"; isPointer: true } Property { name: "enabled"; type: "bool" } + Property { name: "defaultPropertyTrackingMode"; revision: 9; type: "PropertyTrackingMode" } Signal { name: "parentChanged" Parameter { name: "parent"; type: "QObject"; isPointer: true } @@ -34,6 +51,10 @@ Module { name: "enabledChanged" Parameter { name: "enabled"; type: "bool" } } + Signal { + name: "defaultPropertyTrackingModeChanged" + Parameter { name: "mode"; type: "PropertyTrackingMode" } + } Signal { name: "nodeDestroyed" } Method { name: "setParent" @@ -43,6 +64,10 @@ Module { name: "setEnabled" Parameter { name: "isEnabled"; type: "bool" } } + Method { + name: "setDefaultPropertyTrackingMode" + Parameter { name: "mode"; type: "PropertyTrackingMode" } + } } Component { name: "Qt3DInput::Input::Quick::Quick3DAction" @@ -101,6 +126,7 @@ Module { name: "Qt3DInput::Input::Quick::Quick3DPhysicalDevice" prototype: "Qt3DInput::QAbstractPhysicalDevice" exports: ["Qt3D.Input/QAbstractPhysicalDevice 2.0"] + isCreatable: false exportMetaObjectRevisions: [0] Property { name: "axisSettings"; type: "Qt3DInput::QAxisSetting"; isList: true; isReadonly: true } } @@ -185,6 +211,56 @@ Module { Parameter { name: "value"; type: "float" } } } + Component { + name: "Qt3DInput::QAxisAccumulator" + prototype: "Qt3DCore::QComponent" + exports: ["Qt3D.Input/AxisAccumulator 2.1"] + exportMetaObjectRevisions: [0] + Enum { + name: "SourceAxisType" + values: { + "Velocity": 0, + "Acceleration": 1 + } + } + Property { name: "sourceAxis"; type: "Qt3DInput::QAxis"; isPointer: true } + Property { name: "sourceAxisType"; type: "SourceAxisType" } + Property { name: "scale"; type: "float" } + Property { name: "value"; type: "float"; isReadonly: true } + Property { name: "velocity"; type: "float"; isReadonly: true } + Signal { + name: "sourceAxisChanged" + Parameter { name: "sourceAxis"; type: "Qt3DInput::QAxis"; isPointer: true } + } + Signal { + name: "sourceAxisTypeChanged" + Parameter { name: "sourceAxisType"; type: "QAxisAccumulator::SourceAxisType" } + } + Signal { + name: "valueChanged" + Parameter { name: "value"; type: "float" } + } + Signal { + name: "velocityChanged" + Parameter { name: "value"; type: "float" } + } + Signal { + name: "scaleChanged" + Parameter { name: "scale"; type: "float" } + } + Method { + name: "setSourceAxis" + Parameter { name: "sourceAxis"; type: "Qt3DInput::QAxis"; isPointer: true } + } + Method { + name: "setSourceAxisType" + Parameter { name: "sourceAxisType"; type: "QAxisAccumulator::SourceAxisType" } + } + Method { + name: "setScale" + Parameter { name: "scale"; type: "float" } + } + } Component { name: "Qt3DInput::QAxisSetting" prototype: "Qt3DCore::QNode" @@ -337,7 +413,6 @@ Module { Component { name: "Qt3DInput::QKeyboardDevice" prototype: "Qt3DInput::QAbstractPhysicalDevice" - exports: ["Qt3D.Input/KeyboardDevice 2.0"] Property { name: "activeInput" type: "Qt3DInput::QKeyboardHandler" @@ -537,12 +612,13 @@ Module { Component { name: "Qt3DInput::QMouseDevice" prototype: "Qt3DInput::QAbstractPhysicalDevice" - exports: ["Qt3D.Input/MouseDevice 2.0"] Enum { name: "Axis" values: { "X": 0, - "Y": 1 + "Y": 1, + "WheelX": 2, + "WheelY": 3 } } Property { name: "sensitivity"; type: "float" } diff --git a/src/quick3d/imports/logic/plugins.qmltypes b/src/quick3d/imports/logic/plugins.qmltypes index 0c0ccc847..61b67ca73 100644 --- a/src/quick3d/imports/logic/plugins.qmltypes +++ b/src/quick3d/imports/logic/plugins.qmltypes @@ -7,7 +7,7 @@ import QtQuick.tooling 1.2 // 'qmlplugindump -nonrelocatable Qt3D.Logic 2.0' Module { - dependencies: ["QtQuick 2.7"] + dependencies: ["QtQuick 2.8"] Component { name: "Qt3DCore::QComponent" prototype: "Qt3DCore::QNode" @@ -16,6 +16,14 @@ Module { name: "shareableChanged" Parameter { name: "isShareable"; type: "bool" } } + Signal { + name: "addedToEntity" + Parameter { name: "entity"; type: "QEntity"; isPointer: true } + } + Signal { + name: "removedFromEntity" + Parameter { name: "entity"; type: "QEntity"; isPointer: true } + } Method { name: "setShareable" Parameter { name: "isShareable"; type: "bool" } @@ -24,8 +32,17 @@ Module { Component { name: "Qt3DCore::QNode" prototype: "QObject" + Enum { + name: "PropertyTrackingMode" + values: { + "TrackFinalValues": 0, + "DontTrackValues": 1, + "TrackAllValues": 2 + } + } Property { name: "parent"; type: "Qt3DCore::QNode"; isPointer: true } Property { name: "enabled"; type: "bool" } + Property { name: "defaultPropertyTrackingMode"; revision: 9; type: "PropertyTrackingMode" } Signal { name: "parentChanged" Parameter { name: "parent"; type: "QObject"; isPointer: true } @@ -34,6 +51,10 @@ Module { name: "enabledChanged" Parameter { name: "enabled"; type: "bool" } } + Signal { + name: "defaultPropertyTrackingModeChanged" + Parameter { name: "mode"; type: "PropertyTrackingMode" } + } Signal { name: "nodeDestroyed" } Method { name: "setParent" @@ -43,6 +64,10 @@ Module { name: "setEnabled" Parameter { name: "isEnabled"; type: "bool" } } + Method { + name: "setDefaultPropertyTrackingMode" + Parameter { name: "mode"; type: "PropertyTrackingMode" } + } } Component { name: "Qt3DLogic::QFrameAction" diff --git a/src/quick3d/imports/render/plugins.qmltypes b/src/quick3d/imports/render/plugins.qmltypes index 9e6e5fe38..aa0272430 100644 --- a/src/quick3d/imports/render/plugins.qmltypes +++ b/src/quick3d/imports/render/plugins.qmltypes @@ -4,10 +4,10 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -nonrelocatable Qt3D.Render 2.0' +// 'qmlplugindump -nonrelocatable Qt3D.Render 2.9' Module { - dependencies: ["QtQuick 2.7"] + dependencies: ["QtQuick 2.8"] Component { name: "QWindow" prototype: "QObject" @@ -25,6 +25,13 @@ Module { "FullScreen": 5 } } + Enum { + name: "AncestorMode" + values: { + "ExcludeTransients": 0, + "IncludeTransients": 1 + } + } Property { name: "title"; type: "string" } Property { name: "modality"; type: "Qt::WindowModality" } Property { name: "flags"; type: "Qt::WindowFlags" } @@ -178,6 +185,14 @@ Module { name: "shareableChanged" Parameter { name: "isShareable"; type: "bool" } } + Signal { + name: "addedToEntity" + Parameter { name: "entity"; type: "QEntity"; isPointer: true } + } + Signal { + name: "removedFromEntity" + Parameter { name: "entity"; type: "QEntity"; isPointer: true } + } Method { name: "setShareable" Parameter { name: "isShareable"; type: "bool" } @@ -187,8 +202,17 @@ Module { Component { name: "Qt3DCore::QNode" prototype: "QObject" + Enum { + name: "PropertyTrackingMode" + values: { + "TrackFinalValues": 0, + "DontTrackValues": 1, + "TrackAllValues": 2 + } + } Property { name: "parent"; type: "Qt3DCore::QNode"; isPointer: true } Property { name: "enabled"; type: "bool" } + Property { name: "defaultPropertyTrackingMode"; revision: 9; type: "PropertyTrackingMode" } Signal { name: "parentChanged" Parameter { name: "parent"; type: "QObject"; isPointer: true } @@ -197,6 +221,10 @@ Module { name: "enabledChanged" Parameter { name: "enabled"; type: "bool" } } + Signal { + name: "defaultPropertyTrackingModeChanged" + Parameter { name: "mode"; type: "PropertyTrackingMode" } + } Signal { name: "nodeDestroyed" } Method { name: "setParent" @@ -206,6 +234,10 @@ Module { name: "setEnabled" Parameter { name: "isEnabled"; type: "bool" } } + Method { + name: "setDefaultPropertyTrackingMode" + Parameter { name: "mode"; type: "PropertyTrackingMode" } + } } Component { name: "Qt3DCore::Quick::Quick3DNode" @@ -404,7 +436,8 @@ Module { "CubeMapPositiveY": 34071, "CubeMapNegativeY": 34072, "CubeMapPositiveZ": 34073, - "CubeMapNegativeZ": 34074 + "CubeMapNegativeZ": 34074, + "AllFaces": 34075 } } Enum { @@ -446,6 +479,7 @@ Module { Property { name: "comparisonFunction"; type: "ComparisonFunction" } Property { name: "comparisonMode"; type: "ComparisonMode" } Property { name: "layers"; type: "int" } + Property { name: "samples"; type: "int" } Signal { name: "formatChanged" Parameter { name: "format"; type: "TextureFormat" } @@ -494,6 +528,10 @@ Module { name: "layersChanged" Parameter { name: "layers"; type: "int" } } + Signal { + name: "samplesChanged" + Parameter { name: "samples"; type: "int" } + } Method { name: "setFormat" Parameter { name: "format"; type: "TextureFormat" } @@ -538,6 +576,10 @@ Module { name: "setLayers" Parameter { name: "layers"; type: "int" } } + Method { + name: "setSamples" + Parameter { name: "samples"; type: "int" } + } } Component { name: "Qt3DRender::QAbstractTextureImage" @@ -625,7 +667,8 @@ Module { name: "AttributeType" values: { "VertexAttribute": 0, - "IndexAttribute": 1 + "IndexAttribute": 1, + "DrawIndirectAttribute": 2 } } Enum { @@ -651,6 +694,11 @@ Module { Property { name: "byteOffset"; type: "uint" } Property { name: "divisor"; type: "uint" } Property { name: "attributeType"; type: "AttributeType" } + Property { name: "defaultPositionAttributeName"; type: "string"; isReadonly: true } + Property { name: "defaultNormalAttributeName"; type: "string"; isReadonly: true } + Property { name: "defaultColorAttributeName"; type: "string"; isReadonly: true } + Property { name: "defaultTextureCoordinateAttributeName"; type: "string"; isReadonly: true } + Property { name: "defaultTangentAttributeName"; type: "string"; isReadonly: true } Signal { name: "bufferChanged" Parameter { name: "buffer"; type: "QBuffer"; isPointer: true } @@ -659,6 +707,14 @@ Module { name: "nameChanged" Parameter { name: "name"; type: "string" } } + Signal { + name: "vertexBaseTypeChanged" + Parameter { name: "vertexBaseType"; type: "VertexBaseType" } + } + Signal { + name: "vertexSizeChanged" + Parameter { name: "vertexSize"; type: "uint" } + } Signal { name: "dataTypeChanged" Parameter { name: "vertexBaseType"; type: "VertexBaseType" } @@ -695,6 +751,14 @@ Module { name: "setName" Parameter { name: "name"; type: "string" } } + Method { + name: "setVertexBaseType" + Parameter { name: "type"; type: "VertexBaseType" } + } + Method { + name: "setVertexSize" + Parameter { name: "size"; type: "uint" } + } Method { name: "setDataType" Parameter { name: "type"; type: "VertexBaseType" } @@ -780,7 +844,8 @@ Module { "OneMinusConstantColor": 32770, "OneMinusConstantAlpha": 32772, "OneMinusSource1Alpha": 32773, - "OneMinusSource1Color": 32774 + "OneMinusSource1Color": 32774, + "OneMinusSource1Color0": 32774 } } Property { name: "sourceRgb"; type: "Blending" } @@ -848,6 +913,9 @@ Module { Component { name: "Qt3DRender::QBuffer" prototype: "Qt3DCore::QNode" + exports: ["Qt3D.Render/BufferBase 2.0", "Qt3D.Render/BufferBase 2.9"] + isCreatable: false + exportMetaObjectRevisions: [0, 9] Enum { name: "BufferType" values: { @@ -856,7 +924,8 @@ Module { "PixelPackBuffer": 35051, "PixelUnpackBuffer": 35052, "UniformBuffer": 35345, - "ShaderStorageBuffer": 37074 + "ShaderStorageBuffer": 37074, + "DrawIndirectBuffer": 36671 } } Enum { @@ -873,9 +942,18 @@ Module { "DynamicCopy": 35050 } } + Enum { + name: "AccessType" + values: { + "Write": 1, + "Read": 2, + "ReadWrite": 3 + } + } Property { name: "type"; type: "BufferType" } Property { name: "usage"; type: "UsageType" } Property { name: "syncData"; type: "bool" } + Property { name: "accessType"; revision: 9; type: "AccessType" } Signal { name: "dataChanged" Parameter { name: "bytes"; type: "QByteArray" } @@ -892,6 +970,11 @@ Module { name: "syncDataChanged" Parameter { name: "syncData"; type: "bool" } } + Signal { + name: "accessTypeChanged" + Parameter { name: "access"; type: "AccessType" } + } + Signal { name: "dataAvailable" } Method { name: "setType" Parameter { name: "type"; type: "BufferType" } @@ -904,6 +987,21 @@ Module { name: "setSyncData" Parameter { name: "syncData"; type: "bool" } } + Method { + name: "setAccessType" + Parameter { name: "access"; type: "AccessType" } + } + Method { + name: "updateData" + Parameter { name: "offset"; type: "int" } + Parameter { name: "bytes"; type: "QByteArray" } + } + } + Component { + name: "Qt3DRender::QBufferCapture" + prototype: "Qt3DRender::QFrameGraphNode" + exports: ["Qt3D.Render/BufferCapture 2.9"] + exportMetaObjectRevisions: [0] } Component { name: "Qt3DRender::QCamera" @@ -927,6 +1025,7 @@ Module { Property { name: "bottom"; type: "float" } Property { name: "top"; type: "float" } Property { name: "projectionMatrix"; type: "QMatrix4x4" } + Property { name: "exposure"; revision: 9; type: "float" } Property { name: "position"; type: "QVector3D" } Property { name: "upVector"; type: "QVector3D" } Property { name: "viewCenter"; type: "QVector3D" } @@ -972,6 +1071,10 @@ Module { name: "projectionMatrixChanged" Parameter { name: "projectionMatrix"; type: "QMatrix4x4" } } + Signal { + name: "exposureChanged" + Parameter { name: "exposure"; type: "float" } + } Signal { name: "positionChanged" Parameter { name: "position"; type: "QVector3D" } @@ -1028,6 +1131,10 @@ Module { name: "setProjectionMatrix" Parameter { name: "projectionMatrix"; type: "QMatrix4x4" } } + Method { + name: "setExposure" + Parameter { name: "exposure"; type: "float" } + } Method { name: "setPosition" Parameter { name: "position"; type: "QVector3D" } @@ -1146,6 +1253,7 @@ Module { Property { name: "bottom"; type: "float" } Property { name: "top"; type: "float" } Property { name: "projectionMatrix"; type: "QMatrix4x4" } + Property { name: "exposure"; revision: 9; type: "float" } Signal { name: "projectionTypeChanged" Parameter { name: "projectionType"; type: "QCameraLens::ProjectionType" } @@ -1186,6 +1294,10 @@ Module { name: "projectionMatrixChanged" Parameter { name: "projectionMatrix"; type: "QMatrix4x4" } } + Signal { + name: "exposureChanged" + Parameter { name: "exposure"; type: "float" } + } Method { name: "setProjectionType" Parameter { name: "projectionType"; type: "ProjectionType" } @@ -1226,6 +1338,10 @@ Module { name: "setProjectionMatrix" Parameter { name: "projectionMatrix"; type: "QMatrix4x4" } } + Method { + name: "setExposure" + Parameter { name: "exposure"; type: "float" } + } } Component { name: "Qt3DRender::QCameraSelector" @@ -1495,6 +1611,34 @@ Module { exportMetaObjectRevisions: [0] } Component { name: "Qt3DRender::QEffect"; prototype: "Qt3DCore::QNode" } + Component { + name: "Qt3DRender::QEnvironmentLight" + prototype: "Qt3DCore::QComponent" + exports: ["Qt3D.Render/EnvironmentLight 2.9"] + exportMetaObjectRevisions: [0] + Property { name: "irradiance"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } + Property { name: "specular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } + Signal { + name: "irradianceChanged" + Parameter { + name: "environmentIrradiance" + type: "Qt3DRender::QAbstractTexture" + isPointer: true + } + } + Signal { + name: "specularChanged" + Parameter { name: "environmentSpecular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } + } + Method { + name: "setIrradiance" + Parameter { name: "irradiance"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } + } + Method { + name: "setSpecular" + Parameter { name: "specular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true } + } + } Component { name: "Qt3DRender::QFilterKey" prototype: "Qt3DCore::QNode" @@ -1523,7 +1667,6 @@ Module { name: "Qt3DRender::QFrameGraphNode" prototype: "Qt3DCore::QNode" exports: ["Qt3D.Render/FrameGraphNode 2.0"] - isCreatable: false exportMetaObjectRevisions: [0] } Component { @@ -1775,6 +1918,76 @@ Module { exportMetaObjectRevisions: [0] } Component { name: "Qt3DRender::QLayerFilter"; prototype: "Qt3DRender::QFrameGraphNode" } + Component { + name: "Qt3DRender::QLevelOfDetail" + prototype: "Qt3DCore::QComponent" + exports: ["Qt3D.Render/LevelOfDetail 2.9"] + exportMetaObjectRevisions: [0] + Enum { + name: "ThresholdType" + values: { + "DistanceToCameraThreshold": 0, + "ProjectedScreenPixelSizeThreshold": 1 + } + } + Property { name: "camera"; type: "Qt3DRender::QCamera"; isPointer: true } + Property { name: "currentIndex"; type: "int" } + Property { name: "thresholdType"; type: "ThresholdType" } + Property { name: "thresholds"; type: "QVector" } + Property { name: "volumeOverride"; type: "Qt3DRender::QLevelOfDetailBoundingSphere" } + Signal { + name: "cameraChanged" + Parameter { name: "camera"; type: "QCamera"; isPointer: true } + } + Signal { + name: "currentIndexChanged" + Parameter { name: "currentIndex"; type: "int" } + } + Signal { + name: "thresholdTypeChanged" + Parameter { name: "thresholdType"; type: "ThresholdType" } + } + Signal { + name: "thresholdsChanged" + Parameter { name: "thresholds"; type: "QVector" } + } + Signal { + name: "volumeOverrideChanged" + Parameter { name: "volumeOverride"; type: "QLevelOfDetailBoundingSphere" } + } + Method { + name: "setCamera" + Parameter { name: "camera"; type: "QCamera"; isPointer: true } + } + Method { + name: "setCurrentIndex" + Parameter { name: "currentIndex"; type: "int" } + } + Method { + name: "setThresholdType" + Parameter { name: "thresholdType"; type: "ThresholdType" } + } + Method { + name: "setThresholds" + Parameter { name: "thresholds"; type: "QVector" } + } + Method { + name: "setVolumeOverride" + Parameter { name: "volumeOverride"; type: "QLevelOfDetailBoundingSphere" } + } + Method { + name: "createBoundingSphere" + type: "QLevelOfDetailBoundingSphere" + Parameter { name: "center"; type: "QVector3D" } + Parameter { name: "radius"; type: "float" } + } + } + Component { + name: "Qt3DRender::QLevelOfDetailSwitch" + prototype: "Qt3DRender::QLevelOfDetail" + exports: ["Qt3D.Render/LevelOfDetailSwitch 2.9"] + exportMetaObjectRevisions: [0] + } Component { name: "Qt3DRender::QMaterial" prototype: "Qt3DCore::QComponent" @@ -1788,6 +2001,39 @@ Module { Parameter { name: "effect"; type: "QEffect"; isPointer: true } } } + Component { + name: "Qt3DRender::QMemoryBarrier" + prototype: "Qt3DRender::QFrameGraphNode" + Enum { + name: "Operation" + values: { + "None": 0, + "VertexAttributeArray": 1, + "ElementArray": 2, + "Uniform": 4, + "TextureFetch": 8, + "ShaderImageAccess": 16, + "Command": 32, + "PixelBuffer": 64, + "TextureUpdate": 128, + "BufferUpdate": 256, + "FrameBuffer": 512, + "TransformFeedback": 1024, + "AtomicCounter": 2048, + "ShaderStorage": 4096, + "QueryBuffer": 8192, + "All": -1 + } + } + Signal { + name: "waitOperationsChanged" + Parameter { name: "barrierTypes"; type: "QMemoryBarrier::Operations" } + } + Method { + name: "setWaitOperations" + Parameter { name: "operations"; type: "QMemoryBarrier::Operations" } + } + } Component { name: "Qt3DRender::QMesh" prototype: "Qt3DRender::QGeometryRenderer" @@ -1913,11 +2159,35 @@ Module { exports: ["Qt3D.Render/PickEvent 2.0"] isCreatable: false exportMetaObjectRevisions: [0] + Enum { + name: "Buttons" + values: { + "LeftButton": 1, + "RightButton": 2, + "MiddleButton": 4, + "BackButton": 8, + "NoButton": 0 + } + } + Enum { + name: "Modifiers" + values: { + "NoModifier": 0, + "ShiftModifier": 33554432, + "ControlModifier": 67108864, + "AltModifier": 134217728, + "MetaModifier": 268435456, + "KeypadModifier": 536870912 + } + } Property { name: "accepted"; type: "bool" } Property { name: "position"; type: "QPointF"; isReadonly: true } Property { name: "distance"; type: "float"; isReadonly: true } Property { name: "localIntersection"; type: "QVector3D"; isReadonly: true } Property { name: "worldIntersection"; type: "QVector3D"; isReadonly: true } + Property { name: "button"; type: "Qt3DRender::QPickEvent::Buttons"; isReadonly: true } + Property { name: "buttons"; type: "int"; isReadonly: true } + Property { name: "modifiers"; type: "int"; isReadonly: true } Signal { name: "acceptedChanged" Parameter { name: "accepted"; type: "bool" } @@ -1946,8 +2216,17 @@ Module { "AllPicks": 1 } } + Enum { + name: "FaceOrientationPickingMode" + values: { + "FrontFace": 1, + "BackFace": 2, + "FrontAndBackFace": 3 + } + } Property { name: "pickMethod"; type: "PickMethod" } Property { name: "pickResultMode"; type: "PickResultMode" } + Property { name: "faceOrientationPickingMode"; type: "FaceOrientationPickingMode" } Signal { name: "pickMethodChanged" Parameter { name: "pickMethod"; type: "QPickingSettings::PickMethod" } @@ -1956,6 +2235,13 @@ Module { name: "pickResultModeChanged" Parameter { name: "pickResult"; type: "QPickingSettings::PickResultMode" } } + Signal { + name: "faceOrientationPickingModeChanged" + Parameter { + name: "faceOrientationPickingMode" + type: "QPickingSettings::FaceOrientationPickingMode" + } + } Method { name: "setPickMethod" Parameter { name: "pickMethod"; type: "PickMethod" } @@ -1964,6 +2250,10 @@ Module { name: "setPickResultMode" Parameter { name: "pickResultMode"; type: "PickResultMode" } } + Method { + name: "setFaceOrientationPickingMode" + Parameter { name: "faceOrientationPickingMode"; type: "FaceOrientationPickingMode" } + } } Component { name: "Qt3DRender::QPointLight" @@ -2053,6 +2343,42 @@ Module { Parameter { name: "depthSteps"; type: "float" } } } + Component { + name: "Qt3DRender::QRenderCapture" + prototype: "Qt3DRender::QFrameGraphNode" + exports: ["Qt3D.Render/RenderCapture 2.1"] + exportMetaObjectRevisions: [0] + Method { + name: "requestCapture" + type: "Qt3DRender::QRenderCaptureReply*" + Parameter { name: "captureId"; type: "int" } + } + Method { name: "requestCapture"; revision: 9; type: "Qt3DRender::QRenderCaptureReply*" } + } + Component { + name: "Qt3DRender::QRenderCaptureReply" + prototype: "QObject" + exports: ["Qt3D.Render/RenderCaptureReply 2.1"] + isCreatable: false + exportMetaObjectRevisions: [0] + Property { name: "image"; type: "QImage"; isReadonly: true } + Property { name: "captureId"; type: "int"; isReadonly: true } + Property { name: "complete"; type: "bool"; isReadonly: true } + Signal { + name: "completeChanged" + Parameter { name: "isComplete"; type: "bool" } + } + Signal { name: "completed" } + Method { + name: "saveImage" + type: "bool" + Parameter { name: "fileName"; type: "string" } + } + Method { + name: "saveToFile" + Parameter { name: "fileName"; type: "string" } + } + } Component { name: "Qt3DRender::QRenderPass" prototype: "Qt3DCore::QNode" @@ -2119,7 +2445,7 @@ Module { exports: ["Qt3D.Render/RenderSurfaceSelector 2.0"] exportMetaObjectRevisions: [0] Property { name: "surface"; type: "QObject"; isPointer: true } - Property { name: "externalRenderTargetSize"; type: "QSize"; isReadonly: true } + Property { name: "externalRenderTargetSize"; type: "QSize" } Property { name: "surfacePixelRatio"; type: "float" } Signal { name: "surfaceChanged" @@ -2141,6 +2467,10 @@ Module { name: "setSurfacePixelRatio" Parameter { name: "ratio"; type: "float" } } + Method { + name: "setExternalRenderTargetSize" + Parameter { name: "size"; type: "QSize" } + } } Component { name: "Qt3DRender::QRenderTarget"; prototype: "Qt3DCore::QComponent" } Component { @@ -2176,7 +2506,7 @@ Module { Property { name: "texture"; type: "QAbstractTexture"; isPointer: true } Property { name: "mipLevel"; type: "int" } Property { name: "layer"; type: "int" } - Property { name: "face"; type: "QAbstractTexture::CubeMapFace" } + Property { name: "face"; type: "Qt3DRender::QAbstractTexture::CubeMapFace" } Signal { name: "attachmentPointChanged" Parameter { name: "attachmentPoint"; type: "AttachmentPoint" } @@ -2243,6 +2573,17 @@ Module { "Error": 3 } } + Enum { + name: "ComponentType" + values: { + "UnknownComponent": 0, + "GeometryRendererComponent": 1, + "TransformComponent": 2, + "MaterialComponent": 3, + "LightComponent": 4, + "CameraLensComponent": 5 + } + } Property { name: "source"; type: "QUrl" } Property { name: "status"; type: "Status"; isReadonly: true } Signal { @@ -2261,6 +2602,20 @@ Module { name: "setStatus" Parameter { name: "status"; type: "Status" } } + Method { + name: "entity" + revision: 9 + type: "Qt3DCore::QEntity*" + Parameter { name: "entityName"; type: "string" } + } + Method { name: "entityNames"; revision: 9; type: "QStringList" } + Method { + name: "component" + revision: 9 + type: "Qt3DCore::QComponent*" + Parameter { name: "entityName"; type: "string" } + Parameter { name: "componentType"; type: "ComponentType" } + } } Component { name: "Qt3DRender::QScissorTest" @@ -2333,12 +2688,22 @@ Module { "Compute": 5 } } + Enum { + name: "Status" + values: { + "NotReady": 0, + "Ready": 1, + "Error": 2 + } + } Property { name: "vertexShaderCode"; type: "QByteArray" } Property { name: "tessellationControlShaderCode"; type: "QByteArray" } Property { name: "tessellationEvaluationShaderCode"; type: "QByteArray" } Property { name: "geometryShaderCode"; type: "QByteArray" } Property { name: "fragmentShaderCode"; type: "QByteArray" } Property { name: "computeShaderCode"; type: "QByteArray" } + Property { name: "log"; revision: 9; type: "string"; isReadonly: true } + Property { name: "status"; revision: 9; type: "Status"; isReadonly: true } Signal { name: "vertexShaderCodeChanged" Parameter { name: "vertexShaderCode"; type: "QByteArray" } @@ -2363,6 +2728,14 @@ Module { name: "computeShaderCodeChanged" Parameter { name: "computeShaderCode"; type: "QByteArray" } } + Signal { + name: "logChanged" + Parameter { name: "log"; type: "string" } + } + Signal { + name: "statusChanged" + Parameter { name: "status"; type: "Status" } + } Method { name: "setVertexShaderCode" Parameter { name: "vertexShaderCode"; type: "QByteArray" } @@ -2701,6 +3074,7 @@ Module { } Property { name: "source"; type: "QUrl" } Property { name: "status"; type: "Status"; isReadonly: true } + Property { name: "mirrored"; type: "bool" } Signal { name: "sourceChanged" Parameter { name: "source"; type: "QUrl" } @@ -2709,23 +3083,40 @@ Module { name: "statusChanged" Parameter { name: "status"; type: "Status" } } + Signal { + name: "mirroredChanged" + Parameter { name: "mirrored"; type: "bool" } + } Method { name: "setSource" Parameter { name: "source"; type: "QUrl" } } + Method { + name: "setMirrored" + Parameter { name: "mirrored"; type: "bool" } + } } Component { name: "Qt3DRender::QTextureLoader" prototype: "Qt3DRender::QAbstractTexture" Property { name: "source"; type: "QUrl" } + Property { name: "mirrored"; type: "bool" } Signal { name: "sourceChanged" Parameter { name: "source"; type: "QUrl" } } + Signal { + name: "mirroredChanged" + Parameter { name: "mirrored"; type: "bool" } + } Method { name: "setSource" Parameter { name: "source"; type: "QUrl" } } + Method { + name: "setMirrored" + Parameter { name: "mirrored"; type: "bool" } + } } Component { name: "Qt3DRender::QTextureRectangle"; prototype: "Qt3DRender::QAbstractTexture" } Component { @@ -2774,14 +3165,23 @@ Module { name: "Qt3DRender::QViewport" prototype: "Qt3DRender::QFrameGraphNode" Property { name: "normalizedRect"; type: "QRectF" } + Property { name: "gamma"; revision: 9; type: "float" } Signal { name: "normalizedRectChanged" Parameter { name: "normalizedRect"; type: "QRectF" } } + Signal { + name: "gammaChanged" + Parameter { name: "gamma"; type: "float" } + } Method { name: "setNormalizedRect" Parameter { name: "normalizedRect"; type: "QRectF" } } + Method { + name: "setGamma" + Parameter { name: "gamma"; type: "float" } + } } Component { name: "Qt3DRender::Render::Quick::Quick3DBuffer" @@ -2790,7 +3190,16 @@ Module { exportMetaObjectRevisions: [0] Property { name: "data"; type: "QVariant" } Signal { name: "bufferDataChanged" } - Signal { name: "bufferDataChanged" } + Method { + name: "updateData" + Parameter { name: "offset"; type: "int" } + Parameter { name: "bytes"; type: "QVariant" } + } + Method { + name: "readBinaryFile" + type: "QVariant" + Parameter { name: "fileUrl"; type: "QUrl" } + } } Component { name: "Qt3DRender::Render::Quick::Quick3DEffect" @@ -2822,6 +3231,13 @@ Module { exportMetaObjectRevisions: [0] Property { name: "parameters"; type: "Qt3DRender::QParameter"; isList: true; isReadonly: true } } + Component { + name: "Qt3DRender::Render::Quick::Quick3DMemoryBarrier" + prototype: "Qt3DRender::QMemoryBarrier" + exports: ["Qt3D.Render/MemoryBarrier 2.9"] + exportMetaObjectRevisions: [0] + Property { name: "waitFor"; type: "int" } + } Component { name: "Qt3DRender::Render::Quick::Quick3DParameter" prototype: "Qt3DRender::QParameter" @@ -2921,7 +3337,7 @@ Module { Component { name: "Qt3DRender::Render::Quick::Quick3DTextureExtension" defaultProperty: "textureImages" - prototype: "Qt3DRender::QTextureLoader" + prototype: "Qt3DRender::QTextureRectangle" exports: [ "Qt3D.Render/Texture1D 2.0", "Qt3D.Render/Texture1DArray 2.0", -- cgit v1.2.3 From d8caeb4bbe91f950d645bd339c573ee9d0869737 Mon Sep 17 00:00:00 2001 From: Daniel Bulla Date: Mon, 1 May 2017 16:49:46 +0200 Subject: fixed graphicscontext applyUniform for uint uniform types. Change-Id: I20e4146ba004a9b7f0cd823aa5ceaf2ed4a7103a Reviewed-by: Paul Lemire --- src/render/graphicshelpers/graphicscontext.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp index 6fa081552..6e585c0a2 100644 --- a/src/render/graphicshelpers/graphicscontext.cpp +++ b/src/render/graphicshelpers/graphicscontext.cpp @@ -1320,16 +1320,16 @@ void GraphicsContext::applyUniform(const ShaderUniform &description, const Unifo break; case UniformType::UInt: - applyUniformHelper(description.m_location, description.m_size, v); + applyUniformHelper(description.m_location, description.m_size, v); break; case UniformType::UIVec2: - applyUniformHelper(description.m_location, description.m_size, v); + applyUniformHelper(description.m_location, description.m_size, v); break; case UniformType::UIVec3: - applyUniformHelper(description.m_location, description.m_size, v); + applyUniformHelper(description.m_location, description.m_size, v); break; case UniformType::UIVec4: - applyUniformHelper(description.m_location, description.m_size, v); + applyUniformHelper(description.m_location, description.m_size, v); break; case UniformType::Bool: -- cgit v1.2.3 From 46e4a33fe90b7ff21baffcb08194ef4c7b346df7 Mon Sep 17 00:00:00 2001 From: Oleg Evseev Date: Wed, 26 Apr 2017 13:03:42 +0300 Subject: Optimize partial data update support for QBuffer Now both QBuffer setData/functor and partial data update can be called without unexpected behavior. Optimize applying sequential updates. Change-Id: I5d3a8bcb7eb6eeb3ae33f0fbedbb34acedd1c000 Reviewed-by: Oleg Evseev Reviewed-by: Dmitry Volosnykh Reviewed-by: Paul Lemire --- src/render/geometry/buffer.cpp | 9 ++++++- src/render/graphicshelpers/graphicscontext.cpp | 36 ++++++++++++++++++-------- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/render/geometry/buffer.cpp b/src/render/geometry/buffer.cpp index 1133b8e5e..ae5ede731 100644 --- a/src/render/geometry/buffer.cpp +++ b/src/render/geometry/buffer.cpp @@ -134,7 +134,14 @@ void Buffer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) QByteArray propertyName = propertyChange->propertyName(); if (propertyName == QByteArrayLiteral("data")) { QByteArray newData = propertyChange->value().value(); - m_bufferDirty |= m_data != newData; + bool dirty = m_data != newData; + m_bufferDirty |= dirty; + if (dirty) { + QBufferUpdate updateNewData; + updateNewData.offset = -1; + m_bufferUpdates.clear(); //previous updates are pointless + m_bufferUpdates.push_back(updateNewData); + } m_data = newData; } else if (propertyName == QByteArrayLiteral("updateData")) { Qt3DRender::QBufferUpdate updateData = propertyChange->value().value(); diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp index 6e585c0a2..65414e220 100644 --- a/src/render/graphicshelpers/graphicscontext.cpp +++ b/src/render/graphicshelpers/graphicscontext.cpp @@ -1528,21 +1528,35 @@ void GraphicsContext::uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool rel // * setData was called changing the whole data or functor (or the usage pattern) // * partial buffer updates where received - // Note: we assume the case where both setData/functor and updates are called to be a misuse - // with unexpected behavior - const QVector updates = std::move(buffer->pendingBufferUpdates()); - if (!updates.empty()) { - for (const Qt3DRender::QBufferUpdate &update : updates) { + // TO DO: Handle usage pattern + QVector updates = std::move(buffer->pendingBufferUpdates()); + for (auto it = updates.begin(); it != updates.end(); ++it) { + auto update = it; + if (update->offset >= 0) { + //accumulate sequential updates as single one + int bufferSize = update->data.size(); + auto it2 = it + 1; + while ((it2 != updates.end()) + && (it2->offset - update->offset == bufferSize)) { + bufferSize += it2->data.size(); + ++it2; + } + update->data.resize(bufferSize); + while (it + 1 != it2) { + ++it; + update->data.replace(it->offset - update->offset, it->data.size(), it->data); + it->data.clear(); + } // TO DO: based on the number of updates .., it might make sense to // sometime use glMapBuffer rather than glBufferSubData - b->update(this, update.data.constData(), update.data.size(), update.offset); + b->update(this, update->data.constData(), update->data.size(), update->offset); + } else { + const int bufferSize = buffer->data().size(); + b->allocate(this, bufferSize, false); // orphan the buffer + b->allocate(this, buffer->data().constData(), bufferSize, false); } - } else { - const int bufferSize = buffer->data().size(); - // TO DO: Handle usage pattern - b->allocate(this, bufferSize, false); // orphan the buffer - b->allocate(this, buffer->data().constData(), bufferSize, false); } + if (releaseBuffer) { b->release(this); if (bufferTypeToGLBufferType(buffer->type()) == GLBuffer::ArrayBuffer) -- cgit v1.2.3 From 6fd0fc4217fe689092957e0bad8a927acb4aa09a Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 4 May 2017 15:23:41 +0200 Subject: Apply layer filter to light sources Cannot just take all entities with light components: the layer filter must be applied as usual. Task-number: QTBUG-60573 Change-Id: I361fab88745113c1b24b68cbff52051139046d9c Reviewed-by: Sean Harmer --- src/render/backend/renderviewbuilder.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/render/backend/renderviewbuilder.cpp b/src/render/backend/renderviewbuilder.cpp index 0aab31b86..f47c6f419 100644 --- a/src/render/backend/renderviewbuilder.cpp +++ b/src/render/backend/renderviewbuilder.cpp @@ -188,8 +188,6 @@ public: RenderView *rv = m_renderViewJob->renderView(); if (!rv->noDraw()) { - // Set the light sources - rv->setLightSources(std::move(m_lightGathererJob->lights())); rv->setEnvironmentLight(m_lightGathererJob->takeEnvironmentLight()); // We sort the vector so that the removal can then be performed linearly @@ -208,6 +206,14 @@ public: QVector filteredEntities = m_filterEntityByLayerJob->filteredEntities(); RenderViewBuilder::removeEntitiesNotInSubset(renderableEntities, filteredEntities); + // Set the light sources, with layer filters applied. + QVector lightSources = m_lightGathererJob->lights(); + for (int i = 0; i < lightSources.count(); ++i) { + if (!filteredEntities.contains(lightSources[i].entity)) + lightSources.removeAt(i--); + } + rv->setLightSources(lightSources); + // Filter out frustum culled entity for drawable entities if (isDraw && rv->frustumCulling()) RenderViewBuilder::removeEntitiesNotInSubset(renderableEntities, m_frustumCullingJob->visibleEntities()); -- cgit v1.2.3 From 043b8bc956eafcf63da88ef011e73bb5dbcc6683 Mon Sep 17 00:00:00 2001 From: Kevin Ottens Date: Thu, 4 May 2017 13:00:16 +0200 Subject: Add a new mirrored property to QPlane(Mesh|Geometry) This is regularly necessary to be able to flip vertically the UV coordinates on the plane mesh depending if we are using a texture in model space coords or in window coords. Especially necessary now with Scene2D which outputs textures in window coords. This property is necessary to make it usable. Change-Id: I0fe7d3fdc125f1791492cf39ebe908bbc20f1db2 Reviewed-by: Sean Harmer --- src/extras/geometries/qplanegeometry.cpp | 47 ++++++++++++++++++---- src/extras/geometries/qplanegeometry.h | 4 ++ src/extras/geometries/qplanegeometry_p.h | 1 + src/extras/geometries/qplanemesh.cpp | 24 +++++++++++ src/extras/geometries/qplanemesh.h | 4 ++ .../imports/extras/qt3dquick3dextrasplugin.cpp | 2 + 6 files changed, 75 insertions(+), 7 deletions(-) diff --git a/src/extras/geometries/qplanegeometry.cpp b/src/extras/geometries/qplanegeometry.cpp index f6eba9e61..14ddb25e6 100644 --- a/src/extras/geometries/qplanegeometry.cpp +++ b/src/extras/geometries/qplanegeometry.cpp @@ -54,7 +54,7 @@ namespace Qt3DExtras { namespace { -QByteArray createPlaneVertexData(float w, float h, const QSize &resolution) +QByteArray createPlaneVertexData(float w, float h, const QSize &resolution, bool mirrored) { Q_ASSERT(w > 0.0f); Q_ASSERT(h > 0.0f); @@ -95,7 +95,7 @@ QByteArray createPlaneVertexData(float w, float h, const QSize &resolution) // texture coordinates *fptr++ = u; - *fptr++ = v; + *fptr++ = mirrored ? 1.0f - v : v; // normal *fptr++ = 0.0f; @@ -149,17 +149,18 @@ QByteArray createPlaneIndexData(const QSize &resolution) class PlaneVertexBufferFunctor : public QBufferDataGenerator { public: - explicit PlaneVertexBufferFunctor(float w, float h, const QSize &resolution) + explicit PlaneVertexBufferFunctor(float w, float h, const QSize &resolution, bool mirrored) : m_width(w) , m_height(h) , m_resolution(resolution) + , m_mirrored(mirrored) {} ~PlaneVertexBufferFunctor() {} QByteArray operator()() Q_DECL_FINAL { - return createPlaneVertexData(m_width, m_height, m_resolution); + return createPlaneVertexData(m_width, m_height, m_resolution, m_mirrored); } bool operator ==(const QBufferDataGenerator &other) const Q_DECL_FINAL @@ -168,7 +169,8 @@ public: if (otherFunctor != nullptr) return (otherFunctor->m_width == m_width && otherFunctor->m_height == m_height && - otherFunctor->m_resolution == m_resolution); + otherFunctor->m_resolution == m_resolution && + otherFunctor->m_mirrored == m_mirrored); return false; } @@ -178,6 +180,7 @@ public: float m_width; float m_height; QSize m_resolution; + bool m_mirrored; }; class PlaneIndexBufferFunctor : public QBufferDataGenerator @@ -236,6 +239,13 @@ public: * Holds the plane resolution. */ +/*! + * \qmlproperty bool PlaneGeometry::mirrored + * \since 5.9 + * + * Controls if the UV coordinates of the plane should be flipped vertically. + */ + /*! * \qmlproperty Attribute PlaneGeometry::positionAttribute * @@ -318,7 +328,7 @@ void QPlaneGeometry::updateVertices() d->m_normalAttribute->setCount(nVerts); d->m_texCoordAttribute->setCount(nVerts); d->m_tangentAttribute->setCount(nVerts); - d->m_vertexBuffer->setDataGenerator(QSharedPointer::create(d->m_width, d->m_height, d->m_meshResolution)); + d->m_vertexBuffer->setDataGenerator(QSharedPointer::create(d->m_width, d->m_height, d->m_meshResolution, d->m_mirrored)); } /*! @@ -365,6 +375,16 @@ void QPlaneGeometry::setHeight(float height) emit heightChanged(height); } +void QPlaneGeometry::setMirrored(bool mirrored) +{ + Q_D(QPlaneGeometry); + if (mirrored == d->m_mirrored) + return; + d->m_mirrored = mirrored; + updateVertices(); + emit mirroredChanged(mirrored); +} + /*! * \property QPlaneGeometry::resolution * @@ -398,6 +418,18 @@ float QPlaneGeometry::height() const return d->m_height; } +/*! + * \property QPlaneGeometry::mirrored + * \since 5.9 + * + * Controls if the UV coordinates of the plane should be flipped vertically. + */ +bool QPlaneGeometry::mirrored() const +{ + Q_D(const QPlaneGeometry); + return d->m_mirrored; +} + /*! * \property QPlaneGeometry::positionAttribute * @@ -458,6 +490,7 @@ QPlaneGeometryPrivate::QPlaneGeometryPrivate() , m_width(1.0f) , m_height(1.0f) , m_meshResolution(QSize(2, 2)) + , m_mirrored(false) , m_positionAttribute(nullptr) , m_normalAttribute(nullptr) , m_texCoordAttribute(nullptr) @@ -525,7 +558,7 @@ void QPlaneGeometryPrivate::init() // Each primitive has 3 vertives m_indexAttribute->setCount(faces * 3); - m_vertexBuffer->setDataGenerator(QSharedPointer::create(m_width, m_height, m_meshResolution)); + m_vertexBuffer->setDataGenerator(QSharedPointer::create(m_width, m_height, m_meshResolution, m_mirrored)); m_indexBuffer->setDataGenerator(QSharedPointer::create(m_meshResolution)); q->addAttribute(m_positionAttribute); diff --git a/src/extras/geometries/qplanegeometry.h b/src/extras/geometries/qplanegeometry.h index 694e04e82..4a4efe6eb 100644 --- a/src/extras/geometries/qplanegeometry.h +++ b/src/extras/geometries/qplanegeometry.h @@ -62,6 +62,7 @@ class QT3DEXTRASSHARED_EXPORT QPlaneGeometry : public Qt3DRender::QGeometry Q_PROPERTY(float width READ width WRITE setWidth NOTIFY widthChanged) Q_PROPERTY(float height READ height WRITE setHeight NOTIFY heightChanged) Q_PROPERTY(QSize resolution READ resolution WRITE setResolution NOTIFY resolutionChanged) + Q_PROPERTY(bool mirrored READ mirrored WRITE setMirrored NOTIFY mirroredChanged REVISION 9) Q_PROPERTY(Qt3DRender::QAttribute *positionAttribute READ positionAttribute CONSTANT) Q_PROPERTY(Qt3DRender::QAttribute *normalAttribute READ normalAttribute CONSTANT) Q_PROPERTY(Qt3DRender::QAttribute *texCoordAttribute READ texCoordAttribute CONSTANT) @@ -78,6 +79,7 @@ public: QSize resolution() const; float width() const; float height() const; + bool mirrored() const; Qt3DRender::QAttribute *positionAttribute() const; Qt3DRender::QAttribute *normalAttribute() const; @@ -89,11 +91,13 @@ public Q_SLOTS: void setResolution(const QSize &resolution); void setWidth(float width); void setHeight(float height); + void setMirrored(bool mirrored); Q_SIGNALS: void resolutionChanged(const QSize &resolution); void widthChanged(float width); void heightChanged(float height); + void mirroredChanged(bool mirrored); protected: QPlaneGeometry(QPlaneGeometryPrivate &dd, QNode *parent = nullptr); diff --git a/src/extras/geometries/qplanegeometry_p.h b/src/extras/geometries/qplanegeometry_p.h index cfde6da1c..68d979895 100644 --- a/src/extras/geometries/qplanegeometry_p.h +++ b/src/extras/geometries/qplanegeometry_p.h @@ -75,6 +75,7 @@ public: float m_width; float m_height; QSize m_meshResolution; + bool m_mirrored; Qt3DRender::QAttribute *m_positionAttribute; Qt3DRender::QAttribute *m_normalAttribute; Qt3DRender::QAttribute *m_texCoordAttribute; diff --git a/src/extras/geometries/qplanemesh.cpp b/src/extras/geometries/qplanemesh.cpp index 5991c5397..4804df024 100644 --- a/src/extras/geometries/qplanemesh.cpp +++ b/src/extras/geometries/qplanemesh.cpp @@ -72,6 +72,13 @@ namespace Qt3DExtras { * the mesh in the respective dimensions. */ +/*! + * \qmlproperty bool PlaneMesh::mirrored + * \since 5.9 + * + * Controls if the UV coordinates of the plane should be flipped vertically. + */ + /*! * \class Qt3DExtras::QPlaneMesh * \inheaderfile Qt3DExtras/QPlaneMesh @@ -92,6 +99,7 @@ QPlaneMesh::QPlaneMesh(QNode *parent) QObject::connect(geometry, &QPlaneGeometry::widthChanged, this, &QPlaneMesh::widthChanged); QObject::connect(geometry, &QPlaneGeometry::heightChanged, this, &QPlaneMesh::heightChanged); QObject::connect(geometry, &QPlaneGeometry::resolutionChanged, this, &QPlaneMesh::meshResolutionChanged); + QObject::connect(geometry, &QPlaneGeometry::mirroredChanged, this, &QPlaneMesh::mirroredChanged); QGeometryRenderer::setGeometry(geometry); } @@ -147,6 +155,22 @@ QSize QPlaneMesh::meshResolution() const return static_cast(geometry())->resolution(); } +void QPlaneMesh::setMirrored(bool mirrored) +{ + static_cast(geometry())->setMirrored(mirrored); +} + +/*! + * \property QPlaneMesh::mirrored + * \since 5.9 + * + * Controls if the UV coordinates of the plane should be flipped vertically. + */ +bool QPlaneMesh::mirrored() const +{ + return static_cast(geometry())->mirrored(); +} + } // namespace Qt3DExtras QT_END_NAMESPACE diff --git a/src/extras/geometries/qplanemesh.h b/src/extras/geometries/qplanemesh.h index d68774ca0..1cf2ae79e 100644 --- a/src/extras/geometries/qplanemesh.h +++ b/src/extras/geometries/qplanemesh.h @@ -54,6 +54,7 @@ class QT3DEXTRASSHARED_EXPORT QPlaneMesh : public Qt3DRender::QGeometryRenderer Q_PROPERTY(float width READ width WRITE setWidth NOTIFY widthChanged) Q_PROPERTY(float height READ height WRITE setHeight NOTIFY heightChanged) Q_PROPERTY(QSize meshResolution READ meshResolution WRITE setMeshResolution NOTIFY meshResolutionChanged) + Q_PROPERTY(bool mirrored READ mirrored WRITE setMirrored NOTIFY mirroredChanged REVISION 9) public: explicit QPlaneMesh(Qt3DCore::QNode *parent = nullptr); @@ -62,16 +63,19 @@ public: float width() const; float height() const; QSize meshResolution() const; + bool mirrored() const; public Q_SLOTS: void setWidth(float width); void setHeight(float height); void setMeshResolution(const QSize &resolution); + void setMirrored(bool mirrored); Q_SIGNALS: void meshResolutionChanged(const QSize &meshResolution); void widthChanged(float width); void heightChanged(float height); + void mirroredChanged(bool mirrored); private: // As this is a default provided geometry renderer, no one should be able diff --git a/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp b/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp index 647eb003b..879b79294 100644 --- a/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp +++ b/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp @@ -116,7 +116,9 @@ void Qt3DQuick3DExtrasPlugin::registerTypes(const char *uri) qmlRegisterType(uri, 2, 0, "CylinderMesh"); qmlRegisterType(uri, 2, 0, "CylinderGeometry"); qmlRegisterType(uri, 2, 0, "PlaneMesh"); + qmlRegisterRevision(uri, 2, 9); qmlRegisterType(uri, 2, 0, "PlaneGeometry"); + qmlRegisterRevision(uri, 2, 9); qmlRegisterType(uri, 2, 0, "TorusMesh"); qmlRegisterType(uri, 2, 0, "TorusGeometry"); qmlRegisterType(uri, 2, 0, "SphereMesh"); -- cgit v1.2.3 From 6e5acfcce3c287c30bab4cdc6fc5f7545a15255e Mon Sep 17 00:00:00 2001 From: Kevin Ottens Date: Thu, 4 May 2017 13:30:43 +0200 Subject: Scene2D: put picking coordinates back in window coordinates We get the picking coordinates in model local tex coords which have a different convention than the mouse events in window coordinates. So flip them vertically to pass them in the right convention. Change-Id: I558cc62c7c820677407730eead8011193a4b967c Reviewed-by: Sean Harmer --- src/quick3d/quick3dscene2d/items/scene2d.cpp | 2 +- tests/auto/render/scene2d/tst_scene2d.cpp | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/quick3d/quick3dscene2d/items/scene2d.cpp b/src/quick3d/quick3dscene2d/items/scene2d.cpp index 13165c280..88b4d9e86 100644 --- a/src/quick3d/quick3dscene2d/items/scene2d.cpp +++ b/src/quick3d/quick3dscene2d/items/scene2d.cpp @@ -486,7 +486,7 @@ void Scene2D::handlePickEvent(int type, const Qt3DRender::QPickEventPtr &ev) ci.setW(1.0f); const QSize size = m_sharedObject->m_quickWindow->size(); - QPointF pos = QPointF(ci.x() * size.width(), ci.y() * size.height()); + QPointF pos = QPointF(ci.x() * size.width(), (1.0f - ci.y()) * size.height()); QMouseEvent *mouseEvent = new QMouseEvent(static_cast(type), pos, pos, pos, diff --git a/tests/auto/render/scene2d/tst_scene2d.cpp b/tests/auto/render/scene2d/tst_scene2d.cpp index d0bd5ca9d..a4810ce66 100644 --- a/tests/auto/render/scene2d/tst_scene2d.cpp +++ b/tests/auto/render/scene2d/tst_scene2d.cpp @@ -341,7 +341,7 @@ private Q_SLOTS: QCoreApplication::processEvents(); // THEN - QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(0,0))); + QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(0,1024))); testWindow->clear(); } @@ -355,7 +355,7 @@ private Q_SLOTS: QCoreApplication::processEvents(); // THEN - QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(1024,0))); + QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(1024,1024))); testWindow->clear(); } @@ -369,7 +369,7 @@ private Q_SLOTS: QCoreApplication::processEvents(); // THEN - QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(1024,1024))); + QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(1024,0))); testWindow->clear(); } @@ -383,7 +383,7 @@ private Q_SLOTS: QCoreApplication::processEvents(); // THEN - QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(0,0))); + QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(0,1024))); testWindow->clear(); } @@ -397,7 +397,7 @@ private Q_SLOTS: QCoreApplication::processEvents(); // THEN - QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(1024,1024))); + QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(1024,0))); testWindow->clear(); } @@ -411,7 +411,7 @@ private Q_SLOTS: QCoreApplication::processEvents(); // THEN - QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(0,1024))); + QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(0,0))); testWindow->clear(); } @@ -425,7 +425,7 @@ private Q_SLOTS: QCoreApplication::processEvents(); // THEN - QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(512.0f, 256.0f))); + QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(512.0f, 768.0f))); testWindow->clear(); } @@ -439,7 +439,7 @@ private Q_SLOTS: QCoreApplication::processEvents(); // THEN - QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(96.0f, 128.0f))); + QVERIFY(testWindow->verifyEventPos(0, QEvent::MouseButtonPress, QPointF(96.0f, 896.0f))); testWindow->clear(); } } -- cgit v1.2.3 From a6a4c3e4c12af537b1af390ef18bf0af646a8c11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A4=C3=A4tt=C3=A4=20Antti?= Date: Fri, 5 May 2017 09:52:36 +0300 Subject: Update multiviewport example image Rendered content has changed so change the example image to reflect that. Task-number: QTBUG-60287 Change-Id: I5d06ed980ffddfec150b7e3914a79fb4c597cf73 Reviewed-by: Sean Harmer --- .../doc/images/multiviewport-qml-example.jpg | Bin 0 -> 30344 bytes .../doc/images/multiviewport-qml-example.png | Bin 21447 -> 0 bytes examples/qt3d/multiviewport/doc/src/multiviewport.qdoc | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 examples/qt3d/multiviewport/doc/images/multiviewport-qml-example.jpg delete mode 100644 examples/qt3d/multiviewport/doc/images/multiviewport-qml-example.png diff --git a/examples/qt3d/multiviewport/doc/images/multiviewport-qml-example.jpg b/examples/qt3d/multiviewport/doc/images/multiviewport-qml-example.jpg new file mode 100644 index 000000000..524e8747a Binary files /dev/null and b/examples/qt3d/multiviewport/doc/images/multiviewport-qml-example.jpg differ diff --git a/examples/qt3d/multiviewport/doc/images/multiviewport-qml-example.png b/examples/qt3d/multiviewport/doc/images/multiviewport-qml-example.png deleted file mode 100644 index 75c13ffcd..000000000 Binary files a/examples/qt3d/multiviewport/doc/images/multiviewport-qml-example.png and /dev/null differ diff --git a/examples/qt3d/multiviewport/doc/src/multiviewport.qdoc b/examples/qt3d/multiviewport/doc/src/multiviewport.qdoc index 86212c4c6..be3e240fa 100644 --- a/examples/qt3d/multiviewport/doc/src/multiviewport.qdoc +++ b/examples/qt3d/multiviewport/doc/src/multiviewport.qdoc @@ -32,7 +32,7 @@ \brief A QML example that demonstrates rendering a Scenegraph from multiple viewports. - \image multiviewport-qml-example.png + \image multiviewport-qml-example.jpg \e {Multi Viewport} renders a Scenegraph from the point of view of four virtual cameras into the four quadrants of a window. This is a common -- cgit v1.2.3 From 4baec347253b14a934cb9f6bcba420adbb09ee35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A4=C3=A4tt=C3=A4=20Antti?= Date: Fri, 5 May 2017 11:49:20 +0300 Subject: Add documentation for simplecustommaterial example Task-number: QTBUG-60287 Change-Id: Id167ddd190b7aa5468bc6590c9f9f4fea234430b Reviewed-by: Sean Harmer --- .../qt3d/simplecustommaterial/SimpleMaterial.qml | 11 +++ .../doc/images/simple-custom-material.jpg | Bin 0 -> 10433 bytes .../doc/src/simplecustommaterial.qdoc | 86 +++++++++++++++++++++ src/doc/qt3d.qdocconf | 3 +- 4 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 examples/qt3d/simplecustommaterial/doc/images/simple-custom-material.jpg create mode 100644 examples/qt3d/simplecustommaterial/doc/src/simplecustommaterial.qdoc diff --git a/examples/qt3d/simplecustommaterial/SimpleMaterial.qml b/examples/qt3d/simplecustommaterial/SimpleMaterial.qml index 22cc028b0..2419362b6 100644 --- a/examples/qt3d/simplecustommaterial/SimpleMaterial.qml +++ b/examples/qt3d/simplecustommaterial/SimpleMaterial.qml @@ -54,6 +54,7 @@ import Qt3D.Render 2.0 Material { id: root + //! [0] property color maincolor: Qt.rgba(0.0, 0.0, 0.0, 1.0) parameters: [ @@ -63,18 +64,24 @@ Material { } ] + //! [0] + effect: Effect { + //! [1] property string vertex: "qrc:/shaders/gl3/simpleColor.vert" property string fragment: "qrc:/shaders/gl3/simpleColor.frag" property string vertexES: "qrc:/shaders/es2/simpleColor.vert" property string fragmentES: "qrc:/shaders/es2/simpleColor.frag" + //! [1] FilterKey { id: forward name: "renderingStyle" value: "forward" } + + //! [2] ShaderProgram { id: gl3Shader vertexShaderCode: loadSource(parent.vertex) @@ -85,7 +92,10 @@ Material { vertexShaderCode: loadSource(parent.vertexES) fragmentShaderCode: loadSource(parent.fragmentES) } + //! [2] + techniques: [ + //! [3] // OpenGL 3.1 Technique { filterKeys: [forward] @@ -99,6 +109,7 @@ Material { shaderProgram: gl3Shader } }, + //! [3] // OpenGL 2.0 Technique { filterKeys: [forward] diff --git a/examples/qt3d/simplecustommaterial/doc/images/simple-custom-material.jpg b/examples/qt3d/simplecustommaterial/doc/images/simple-custom-material.jpg new file mode 100644 index 000000000..d218e5bc8 Binary files /dev/null and b/examples/qt3d/simplecustommaterial/doc/images/simple-custom-material.jpg differ diff --git a/examples/qt3d/simplecustommaterial/doc/src/simplecustommaterial.qdoc b/examples/qt3d/simplecustommaterial/doc/src/simplecustommaterial.qdoc new file mode 100644 index 000000000..678a8f2d7 --- /dev/null +++ b/examples/qt3d/simplecustommaterial/doc/src/simplecustommaterial.qdoc @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example simplecustommaterial + \title Qt 3D: Simple custom material QML Example + \ingroup qt3d-examples-qml + \brief Demonstrates creating a custom material in Qt3D + + \image simple-custom-material.jpg + + \e This example demonstrates creating a simple custom material. + + \include examples-run.qdocinc + + \section1 Specifying the scene + + The example uses \l Scene3D to render a scene which will use the custom material. + The scene contains a plane model, which uses the custom material. + + \quotefromfile simplecustommaterial/PlaneModel.qml + \skipto Entity + \printto + + \section1 Specifying the material + + The material is specified in \l{simplecustommaterial/SimpleMaterial.qml}{SimpleMaterial.qml} + using \l Material type. First the material specifies parameters, + which are mapped to the corresponding uniforms in the shaders so that they can be + changed from the qml. + + \snippet simplecustommaterial/SimpleMaterial.qml 0 + + Next we specify which shaders are loaded. Separate versions of the shaders are provided + for OpenGL ES 2 and OpenGL renderers. + + \snippet simplecustommaterial/SimpleMaterial.qml 1 + + In the vertex shader we simply transform the position by the transformation matrices. + + \quotefromfile simplecustommaterial/shaders/gl3/simpleColor.vert + \skipto void main() + \printto + + In the fragment shader we simply set the fragment color to be the maincolor specified + in the material. + + \quotefromfile simplecustommaterial/shaders/gl3/simpleColor.frag + \skipto uniform vec3 maincolor; + \printuntil ; + \skipto void main() + \printto + + Next, we create \l {ShaderProgram}{ShaderPrograms} from the shaders. + + \snippet simplecustommaterial/SimpleMaterial.qml 2 + + Finally the shader programs are used in the Techniques corresponding to a specific + Api profile. + + \snippet simplecustommaterial/SimpleMaterial.qml 3 +*/ diff --git a/src/doc/qt3d.qdocconf b/src/doc/qt3d.qdocconf index 8c1508fa4..aa39112d2 100644 --- a/src/doc/qt3d.qdocconf +++ b/src/doc/qt3d.qdocconf @@ -80,7 +80,8 @@ imagedirs += images \ ../../examples/qt3d/basicshapes-cpp/doc/images \ ../../examples/qt3d/planets-qml/doc/images \ ../../examples/qt3d/wireframe/doc/images \ - ../../examples/qt3d/audio-visualizer-qml/doc/images + ../../examples/qt3d/audio-visualizer-qml/doc/images \ + ../../examples/qt3d/simplecustommaterial/doc/images Cpp.ignoretokens += QT3DINPUTSHARED_EXPORT \ QT3DCORESHARED_EXPORT \ -- cgit v1.2.3 From 8b45682dfb5bff49c6a7e9ed7b1bbe56e5801585 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Fri, 5 May 2017 17:05:34 +0200 Subject: AssimpImporter: properly handle texture wrapping By default the wrap mode is Repeat. If specified it is changed to the appropriate value. Note: This changes also shows that each material could be definining the same texture with different wrap modes. Therefore we cannot store textures only based on their file path like we used to. Change-Id: Ic543c466d7c5cc7cd7e26d1738006952a8ce746b Task-number: QTBUG-59531 Reviewed-by: Sean Harmer --- src/plugins/sceneparsers/assimp/assimpimporter.cpp | 47 +++++++++++++++++----- src/plugins/sceneparsers/assimp/assimpimporter.h | 1 - 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/plugins/sceneparsers/assimp/assimpimporter.cpp b/src/plugins/sceneparsers/assimp/assimpimporter.cpp index 5d5593585..196e1d22f 100644 --- a/src/plugins/sceneparsers/assimp/assimpimporter.cpp +++ b/src/plugins/sceneparsers/assimp/assimpimporter.cpp @@ -142,7 +142,7 @@ QMatrix4x4 aiMatrix4x4ToQMatrix4x4(const aiMatrix4x4 &matrix) Q_DECL_NOTHROW /*! * Returns a QString from \a str; */ -static inline QString aiStringToQString(const aiString &str) +inline QString aiStringToQString(const aiString &str) { return QString::fromUtf8(str.data, int(str.length)); } @@ -246,6 +246,21 @@ QAttribute *createAttribute(QBuffer *buffer, return attribute; } +QTextureWrapMode::WrapMode wrapModeFromaiTextureMapMode(int mode) +{ + switch (mode) { + case aiTextureMapMode_Wrap: + return QTextureWrapMode::Repeat; + case aiTextureMapMode_Mirror: + return QTextureWrapMode::MirroredRepeat; + case aiTextureMapMode_Decal: + return QTextureWrapMode::ClampToBorder; + case aiTextureMapMode_Clamp: + default: + return QTextureWrapMode::ClampToEdge; + } +} + } // anonymous QStringList AssimpImporter::assimpSupportedFormatsList = AssimpImporter::assimpSupportedFormats(); @@ -1237,18 +1252,28 @@ void AssimpImporter::copyMaterialTextures(QMaterial *material, aiMaterial *assim for (unsigned int i = 0; i < sizeof(textureType)/sizeof(textureType[0]); i++) { aiString path; if (assimpMaterial->GetTexture(textureType[i], 0, &path) == AI_SUCCESS) { - QString fullPath = m_sceneDir.absoluteFilePath(texturePath(path)); + const QString fullPath = m_sceneDir.absoluteFilePath(texturePath(path)); // Load texture if not already loaded - if (!m_scene->m_materialTextures.contains(fullPath)) { - QAbstractTexture *tex = QAbstractNodeFactory::createNode("QTexture2D"); - QTextureImage *texImage = QAbstractNodeFactory::createNode("QTextureImage"); - texImage->setSource(QUrl::fromLocalFile(fullPath)); - tex->addTextureImage(texImage); - m_scene->m_materialTextures.insert(fullPath, tex); - qCDebug(AssimpImporterLog) << Q_FUNC_INFO << " Loaded Texture " << fullPath; - } + QAbstractTexture *tex = QAbstractNodeFactory::createNode("QTexture2D"); + QTextureImage *texImage = QAbstractNodeFactory::createNode("QTextureImage"); + texImage->setSource(QUrl::fromLocalFile(fullPath)); + tex->addTextureImage(texImage); + + // Set proper wrapping mode + QTextureWrapMode wrapMode(QTextureWrapMode::Repeat); + int xMode = 0; + int yMode = 0; + + if (assimpMaterial->Get(AI_MATKEY_MAPPINGMODE_U(textureType[i], 0), xMode) == aiReturn_SUCCESS) + wrapMode.setX(wrapModeFromaiTextureMapMode(xMode)); + if (assimpMaterial->Get(AI_MATKEY_MAPPINGMODE_V(textureType[i], 0), yMode) == aiReturn_SUCCESS) + wrapMode.setY(wrapModeFromaiTextureMapMode(yMode)); + + tex->setWrapMode(wrapMode); + + qCDebug(AssimpImporterLog) << Q_FUNC_INFO << " Loaded Texture " << fullPath; setParameterValue(m_scene->m_textureToParameterName[textureType[i]], - material, QVariant::fromValue(m_scene->m_materialTextures[fullPath])); + material, QVariant::fromValue(tex)); } } } diff --git a/src/plugins/sceneparsers/assimp/assimpimporter.h b/src/plugins/sceneparsers/assimp/assimpimporter.h index 7335830f5..e37950981 100644 --- a/src/plugins/sceneparsers/assimp/assimpimporter.h +++ b/src/plugins/sceneparsers/assimp/assimpimporter.h @@ -143,7 +143,6 @@ private: QMap m_materials; QMap m_effects; QMap m_embeddedTextures; - QMap m_materialTextures; QMap m_cameras; QHash m_textureToParameterName; QVector m_animations; -- cgit v1.2.3 From 20ac249e7b408d37f70d0a5455c38606546bb9c3 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Fri, 5 May 2017 12:07:15 +0200 Subject: Logic: only execute FrameActions which are enabled Change-Id: Ib89f6a4eae1b875a17c124337e0e4283d5d62b9e Task-number: QTBUG-60584 Reviewed-by: Sean Harmer --- src/logic/executor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logic/executor.cpp b/src/logic/executor.cpp index ab4ac154d..6134e801e 100644 --- a/src/logic/executor.cpp +++ b/src/logic/executor.cpp @@ -96,7 +96,7 @@ void Executor::processLogicFrameUpdates(float dt) const QVector nodes = m_scene->lookupNodes(m_nodeIds); for (QNode *node : nodes) { QFrameAction *frameAction = qobject_cast(node); - if (frameAction) + if (frameAction && frameAction->isEnabled()) frameAction->onTriggered(dt); } -- cgit v1.2.3 From bb0f4b48390b5ddc9758f04f6ecd692072fb279f Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Fri, 5 May 2017 11:23:46 +0200 Subject: Scene3DRenderer: fix race condition When the window geometry changes, the Scene3DRenderer was updating a Qt3D frontend node's property from the QSGRenderThread. This resulted in the QPostman::notifyBackend being called from possibly two threads at the same time, resulting in a race condition where the changes would never be submitted again to the backend. Change-Id: I842aaa54637d85d4d45eb54620749efb36168e2a Task-number: QTBUG-54900 Reviewed-by: Sean Harmer Reviewed-by: Oleg Evseev --- src/quick3d/imports/scene3d/scene3ditem.cpp | 2 +- src/quick3d/imports/scene3d/scene3ditem_p.h | 2 +- src/quick3d/imports/scene3d/scene3drenderer.cpp | 18 ++++++++++++++++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/quick3d/imports/scene3d/scene3ditem.cpp b/src/quick3d/imports/scene3d/scene3ditem.cpp index 6c285e133..c31f4aa97 100644 --- a/src/quick3d/imports/scene3d/scene3ditem.cpp +++ b/src/quick3d/imports/scene3d/scene3ditem.cpp @@ -223,7 +223,7 @@ void Scene3DItem::setWindowSurface(QObject *rootObject) } } -void Scene3DItem::setItemArea(const QSize &area) +void Scene3DItem::setItemArea(QSize area) { Qt3DRender::QRenderSurfaceSelector *surfaceSelector = Qt3DRender::QRenderSurfaceSelectorPrivate::find(m_entity); if (surfaceSelector) diff --git a/src/quick3d/imports/scene3d/scene3ditem_p.h b/src/quick3d/imports/scene3d/scene3ditem_p.h index eb14645c3..e0ce3addc 100644 --- a/src/quick3d/imports/scene3d/scene3ditem_p.h +++ b/src/quick3d/imports/scene3d/scene3ditem_p.h @@ -88,7 +88,7 @@ public: bool multisample() const; void setMultisample(bool enable); - void setItemArea(const QSize &area); + Q_INVOKABLE void setItemArea(QSize area); bool isHoverEnabled() const; enum CameraAspectRatioMode { diff --git a/src/quick3d/imports/scene3d/scene3drenderer.cpp b/src/quick3d/imports/scene3d/scene3drenderer.cpp index 88f3be3c1..b32191391 100644 --- a/src/quick3d/imports/scene3d/scene3drenderer.cpp +++ b/src/quick3d/imports/scene3d/scene3drenderer.cpp @@ -57,6 +57,17 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { +namespace { + +inline QMetaMethod setItemAreaMethod() +{ + const int idx = Scene3DItem::staticMetaObject.indexOfMethod("setItemArea(QSize)"); + Q_ASSERT(idx != -1); + return Scene3DItem::staticMetaObject.method(idx); +} + +} // anonymous + class ContextSaver { public: @@ -250,8 +261,11 @@ void Scene3DRenderer::render() const bool multisampleHasChanged = m_multisample != m_lastMultisample; const bool forceRecreate = sizeHasChanged || multisampleHasChanged; - if (sizeHasChanged) - m_item->setItemArea(boundingRectSize); + if (sizeHasChanged) { + // We are in the QSGRenderThread (doing a direct call would result in a race) + static const QMetaMethod setItemArea = setItemAreaMethod(); + setItemArea.invoke(m_item, Qt::QueuedConnection, Q_ARG(QSize, boundingRectSize)); + } // Rebuild FBO and textures if never created or a resize has occurred if ((m_multisampledFBO.isNull() || forceRecreate) && m_multisample) { -- cgit v1.2.3 From fc57d48db93830b92fd0b4a3bebfae55081e9d55 Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Sat, 6 May 2017 09:33:52 +0100 Subject: Revert to using new window for each test Now that the underlying problem from QTBUG-58107 in the macOS QPA is fixed we can go back to using a fresh window for each test function. Task-number: QTBUG-58107 Change-Id: If77fa7dbcb5b8b1a7e096e262832297ce871313d Reviewed-by: Paul Lemire --- tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp | 4 ++-- tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp | 4 ++-- tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp | 4 ++-- tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp b/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp index 58e2373f5..473e43d09 100644 --- a/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp +++ b/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp @@ -124,7 +124,7 @@ class tst_GraphicsHelperGL2 : public QObject Q_OBJECT private Q_SLOTS: - void initTestCase() + void init() { m_window.reset(new QWindow); m_window->setSurfaceType(QWindow::OpenGLSurface); @@ -160,7 +160,7 @@ private Q_SLOTS: } } - void cleanupTestCase() + void cleanup() { m_glContext.doneCurrent(); } diff --git a/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp b/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp index 7e24d22c7..b66192835 100644 --- a/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp +++ b/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp @@ -177,7 +177,7 @@ class tst_GraphicsHelperGL3_2 : public QObject Q_OBJECT private Q_SLOTS: - void initTestCase() + void init() { m_window.reset(new QWindow); m_window->setSurfaceType(QWindow::OpenGLSurface); @@ -209,7 +209,7 @@ private Q_SLOTS: } } - void cleanupTestCase() + void cleanup() { m_glContext.doneCurrent(); } diff --git a/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp b/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp index cdca5676b..b7cc1cdac 100644 --- a/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp +++ b/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp @@ -176,7 +176,7 @@ class tst_GraphicsHelperGL3_3 : public QObject Q_OBJECT private Q_SLOTS: - void initTestCase() + void init() { m_window.reset(new QWindow); m_window->setSurfaceType(QWindow::OpenGLSurface); @@ -209,7 +209,7 @@ private Q_SLOTS: } } - void cleanupTestCase() + void cleanup() { m_glContext.doneCurrent(); } diff --git a/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp b/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp index c6a306910..0ee14841c 100644 --- a/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp +++ b/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp @@ -201,7 +201,7 @@ class tst_GraphicsHelperGL4 : public QObject { Q_OBJECT private Q_SLOTS: - void initTestCase() + void init() { m_window.reset(new QWindow); m_window->setSurfaceType(QWindow::OpenGLSurface); @@ -234,7 +234,7 @@ private Q_SLOTS: } } - void cleanupTestCase() + void cleanup() { m_glContext.doneCurrent(); } -- cgit v1.2.3 From 4a2d8d6ee54976e3a8e2218bc8e97c857688cdfe Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Thu, 4 May 2017 13:13:23 +0200 Subject: Fix Buffer uploading We used to load buffer data when creating it. This led to cases where we would not take into account immediately buffer updates after creation. This would then results in artifacts that would pop up on screen as actual buffer data and count would be different Change-Id: I5a2fad4fb5d7c1e1542cd0bf87ded16a111bc613 Task-number: QTBUG-60429 Reviewed-by: Oleg Evseev Reviewed-by: Laszlo Agocs --- src/render/backend/renderer.cpp | 5 ++--- src/render/geometry/buffer.cpp | 26 ++++++++++++++++++++------ src/render/geometry/buffer_p.h | 1 + src/render/graphicshelpers/graphicscontext.cpp | 6 ++++-- tests/auto/render/buffer/tst_buffer.cpp | 9 +++++++++ 5 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp index 4080a72eb..bd8687d5e 100644 --- a/src/render/backend/renderer.cpp +++ b/src/render/backend/renderer.cpp @@ -1013,12 +1013,11 @@ void Renderer::updateGLResources() const QVector dirtyBufferHandles = std::move(m_dirtyBuffers); for (HBuffer handle: dirtyBufferHandles) { Buffer *buffer = m_nodesManager->bufferManager()->data(handle); - // Perform data upload // Forces creation if it doesn't exit if (!m_graphicsContext->hasGLBufferForBuffer(buffer)) m_graphicsContext->glBufferForRenderBuffer(buffer); - else if (buffer->isDirty()) // Otherwise update the glBuffer - m_graphicsContext->updateBuffer(buffer); + // Update the glBuffer data + m_graphicsContext->updateBuffer(buffer); buffer->unsetDirty(); } } diff --git a/src/render/geometry/buffer.cpp b/src/render/geometry/buffer.cpp index ae5ede731..82dbbcc1b 100644 --- a/src/render/geometry/buffer.cpp +++ b/src/render/geometry/buffer.cpp @@ -88,6 +88,9 @@ void Buffer::executeFunctor() { Q_ASSERT(m_functor); m_data = (*m_functor)(); + // Request data to be loaded + forceDataUpload(); + if (m_syncData) { // Send data back to the frontend auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); @@ -101,6 +104,8 @@ void Buffer::executeFunctor() //Called from th sendBufferJob void Buffer::updateDataFromGPUToCPU(QByteArray data) { + // Note: when this is called, data is what's currently in GPU memory + // so m_data shouldn't be reuploaded m_data = data; // Send data back to the frontend auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); @@ -121,12 +126,25 @@ void Buffer::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &chang m_access = data.access; m_bufferDirty = true; + if (!m_data.isEmpty()) + forceDataUpload(); + m_functor = data.functor; Q_ASSERT(m_manager); if (m_functor) m_manager->addDirtyBuffer(peerId()); } +void Buffer::forceDataUpload() +{ + // We push back an update with offset = -1 + // As this is the way to force data to be loaded + QBufferUpdate updateNewData; + updateNewData.offset = -1; + m_bufferUpdates.clear(); //previous updates are pointless + m_bufferUpdates.push_back(updateNewData); +} + void Buffer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) { if (e->type() == PropertyUpdated) { @@ -136,13 +154,9 @@ void Buffer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) QByteArray newData = propertyChange->value().value(); bool dirty = m_data != newData; m_bufferDirty |= dirty; - if (dirty) { - QBufferUpdate updateNewData; - updateNewData.offset = -1; - m_bufferUpdates.clear(); //previous updates are pointless - m_bufferUpdates.push_back(updateNewData); - } m_data = newData; + if (dirty) + forceDataUpload(); } else if (propertyName == QByteArrayLiteral("updateData")) { Qt3DRender::QBufferUpdate updateData = propertyChange->value().value(); m_bufferUpdates.push_back(updateData); diff --git a/src/render/geometry/buffer_p.h b/src/render/geometry/buffer_p.h index 9d9606eb0..691d6cc60 100644 --- a/src/render/geometry/buffer_p.h +++ b/src/render/geometry/buffer_p.h @@ -90,6 +90,7 @@ public: private: void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL; + void forceDataUpload(); QBuffer::BufferType m_type; QBuffer::UsageType m_usage; diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp index 65414e220..80e8267da 100644 --- a/src/render/graphicshelpers/graphicscontext.cpp +++ b/src/render/graphicshelpers/graphicscontext.cpp @@ -1501,8 +1501,6 @@ HGLBuffer GraphicsContext::createGLBufferFor(Buffer *buffer) if (!bindGLBuffer(b, bufferTypeToGLBufferType(buffer->type()))) qCWarning(Render::Io) << Q_FUNC_INFO << "buffer binding failed"; - // TO DO: Handle usage pattern - b->allocate(this, buffer->data().constData(), buffer->data().size(), false); return m_renderer->nodeManagers()->glBufferManager()->lookupHandle(buffer->peerId()); } @@ -1532,6 +1530,7 @@ void GraphicsContext::uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool rel QVector updates = std::move(buffer->pendingBufferUpdates()); for (auto it = updates.begin(); it != updates.end(); ++it) { auto update = it; + // We have a partial update if (update->offset >= 0) { //accumulate sequential updates as single one int bufferSize = update->data.size(); @@ -1551,6 +1550,9 @@ void GraphicsContext::uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool rel // sometime use glMapBuffer rather than glBufferSubData b->update(this, update->data.constData(), update->data.size(), update->offset); } else { + // We have an update that was done by calling QBuffer::setData + // which is used to resize or entirely clear the buffer + // Note: we use the buffer data directly in that case const int bufferSize = buffer->data().size(); b->allocate(this, bufferSize, false); // orphan the buffer b->allocate(this, buffer->data().constData(), bufferSize, false); diff --git a/tests/auto/render/buffer/tst_buffer.cpp b/tests/auto/render/buffer/tst_buffer.cpp index 7f7c0adb9..8049aaf37 100644 --- a/tests/auto/render/buffer/tst_buffer.cpp +++ b/tests/auto/render/buffer/tst_buffer.cpp @@ -89,6 +89,8 @@ private Q_SLOTS: QCOMPARE(renderBuffer.data(), buffer.data()); QCOMPARE(renderBuffer.dataGenerator(), buffer.dataGenerator()); QVERIFY(*renderBuffer.dataGenerator() == *buffer.dataGenerator()); + QCOMPARE(renderBuffer.pendingBufferUpdates().size(), 1); + QCOMPARE(renderBuffer.pendingBufferUpdates().first().offset, -1); } void checkInitialAndCleanedUpState() @@ -195,7 +197,10 @@ private Q_SLOTS: // THEN QCOMPARE(renderBuffer.data(), QByteArrayLiteral("LS9")); QVERIFY(renderBuffer.isDirty()); + QCOMPARE(renderBuffer.pendingBufferUpdates().size(), 1); + QCOMPARE(renderBuffer.pendingBufferUpdates().first().offset, -1); + renderBuffer.pendingBufferUpdates().clear(); renderBuffer.unsetDirty(); QVERIFY(!renderBuffer.isDirty()); @@ -233,8 +238,11 @@ private Q_SLOTS: Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast(); QCOMPARE(change->propertyName(), "data"); QCOMPARE(change->value().toByteArray(), QByteArrayLiteral("454")); + QCOMPARE(renderBuffer.pendingBufferUpdates().size(), 1); + QCOMPARE(renderBuffer.pendingBufferUpdates().first().offset, -1); arbiter.events.clear(); + renderBuffer.pendingBufferUpdates().clear(); // WHEN updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); @@ -247,6 +255,7 @@ private Q_SLOTS: // THEN QVERIFY(!renderBuffer.pendingBufferUpdates().empty()); + QCOMPARE(renderBuffer.pendingBufferUpdates().first().offset, 2); QVERIFY(renderBuffer.isDirty()); renderBuffer.unsetDirty(); -- cgit v1.2.3 From 540f11b0b3f1639990383e2a4c72f858b0ac01b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A4=C3=A4tt=C3=A4=20Antti?= Date: Wed, 12 Apr 2017 14:26:41 +0300 Subject: Scene2D cleanup - remove qml engine and source MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove QQmlEngine constructor and source property. Update unit tests and manual tests accordingly. Task-number: QTBUG-58876 Change-Id: Ide06bb1381f48efa5378f9a008476734a33089c1 Reviewed-by: Sean Harmer Reviewed-by: Antti Määttä --- src/quick3d/quick3dscene2d/items/qscene2d.cpp | 78 -------------- src/quick3d/quick3dscene2d/items/qscene2d.h | 12 --- .../quick3dscene2d/items/scene2dmanager.cpp | 112 ++------------------- .../quick3dscene2d/items/scene2dmanager_p.h | 12 --- tests/auto/render/qscene2d/tst_qscene2d.cpp | 55 ---------- tests/manual/render-qml-to-texture/main.cpp | 8 +- 6 files changed, 15 insertions(+), 262 deletions(-) diff --git a/src/quick3d/quick3dscene2d/items/qscene2d.cpp b/src/quick3d/quick3dscene2d/items/qscene2d.cpp index 3470ac9d8..cc8c0b4fe 100644 --- a/src/quick3d/quick3dscene2d/items/qscene2d.cpp +++ b/src/quick3d/quick3dscene2d/items/qscene2d.cpp @@ -90,21 +90,11 @@ namespace Quick { Holds the RenderTargetOutput, which specifies where the Scene2D is rendering to. */ -/*! - \qmlproperty QUrl Qt3D.Render::Scene2D::source - Holds the qml source url. - */ - /*! \qmlproperty enumeration Qt3D.Render::Scene2D::renderPolicy Holds the render policy of this Scene2D. */ -/*! - \qmlproperty bool Qt3D.Render::Scene2D::loaded - Holds whether the source has been loaded. - */ - QScene2DPrivate::QScene2DPrivate() : Qt3DCore::QNodePrivate() , m_renderManager(new Scene2DManager(this)) @@ -125,56 +115,6 @@ QScene2DPrivate::~QScene2DPrivate() QScene2D::QScene2D(Qt3DCore::QNode *parent) : Qt3DCore::QNode(*new QScene2DPrivate, parent) { - Q_D(QScene2D); - connect(d->m_renderManager, &Scene2DManager::onLoadedChanged, - this, &QScene2D::sourceLoaded); -} - -QScene2D::QScene2D(QQmlEngine *engine, Qt3DCore::QNode *parent) - : Qt3DCore::QNode(*new QScene2DPrivate, parent) -{ - Q_D(QScene2D); - connect(d->m_renderManager, &Scene2DManager::onLoadedChanged, - this, &QScene2D::sourceLoaded); - d->m_renderManager->setEngine(engine); -} - -QScene2D::~QScene2D() -{ -} - -bool QScene2D::loaded() const -{ - Q_D(const QScene2D); - return d->m_renderManager->m_initialized; -} - -/*! - \property QScene2D::source - \brief Specifies the url for the qml. - - This property specifies the url to the qml being rendered to the texture. - The source must specify QQuickItem as a root. The item must specify width - and height. The rendered qml is scaled to the texture size. - The property can not be changed after the rendering has been initialized. - */ -QUrl QScene2D::source() const -{ - Q_D(const QScene2D); - return d->m_renderManager->m_source; -} - -void QScene2D::setSource(const QUrl &url) -{ - Q_D(QScene2D); - if (d->m_renderManager->m_initialized) { - qWarning() << "Unable to set source after initialization."; - return; - } - if (d->m_renderManager->m_source != url) { - d->m_renderManager->setSource(url); - emit sourceChanged(url); - } } QQuickItem* QScene2D::item() const @@ -260,30 +200,12 @@ bool QScene2D::event(QEvent *event) return true; } -/*! - Returns the qml engine used by the QScene2D. - */ -QQmlEngine *QScene2D::engine() const -{ - Q_D(const QScene2D); - return d->m_renderManager->m_qmlEngine; -} - bool QScene2D::isGrabMouseEnabled() const { Q_D(const QScene2D); return d->m_renderManager->m_grabMouse; } -/*! - \internal - */ -void QScene2D::sourceLoaded() -{ - emit loadedChanged(true); -} - - QVector QScene2D::entities() { Q_D(const QScene2D); diff --git a/src/quick3d/quick3dscene2d/items/qscene2d.h b/src/quick3d/quick3dscene2d/items/qscene2d.h index 2c982668a..b40cff536 100644 --- a/src/quick3d/quick3dscene2d/items/qscene2d.h +++ b/src/quick3d/quick3dscene2d/items/qscene2d.h @@ -60,9 +60,7 @@ class QT3DQUICKSCENE2DSHARED_EXPORT QScene2D : public Qt3DCore::QNode Q_OBJECT Q_PROPERTY(Qt3DRender::QRenderTargetOutput *output READ output WRITE setOutput NOTIFY outputChanged) - Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) Q_PROPERTY(QScene2D::RenderPolicy renderPolicy READ renderPolicy WRITE setRenderPolicy NOTIFY renderPolicyChanged) - Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged) Q_PROPERTY(QQuickItem *item READ item WRITE setItem NOTIFY itemChanged) Q_PROPERTY(bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled NOTIFY grabMouseChanged) @@ -77,15 +75,10 @@ public: Q_ENUM(RenderPolicy) explicit QScene2D(Qt3DCore::QNode *parent = nullptr); - QScene2D(QQmlEngine *engine, Qt3DCore::QNode *parent = nullptr); - ~QScene2D(); Qt3DRender::QRenderTargetOutput *output() const; - QUrl source() const; - bool loaded() const; QScene2D::RenderPolicy renderPolicy() const; QQuickItem *item() const; - QQmlEngine *engine() const; bool isGrabMouseEnabled() const; bool event(QEvent *event) Q_DECL_OVERRIDE; @@ -96,15 +89,12 @@ public: public Q_SLOTS: void setOutput(Qt3DRender::QRenderTargetOutput *output); - void setSource(const QUrl &url); void setRenderPolicy(QScene2D::RenderPolicy policy); void setItem(QQuickItem *item); void setGrabMouseEnabled(bool grab); Q_SIGNALS: void outputChanged(Qt3DRender::QRenderTargetOutput *output); - void sourceChanged(const QUrl &url); - void loadedChanged(bool loaded); void renderPolicyChanged(QScene2D::RenderPolicy policy); void itemChanged(QQuickItem *item); void grabMouseChanged(bool grab); @@ -114,8 +104,6 @@ protected: private: Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const Q_DECL_OVERRIDE; - - void sourceLoaded(); }; } // namespace Quick diff --git a/src/quick3d/quick3dscene2d/items/scene2dmanager.cpp b/src/quick3d/quick3dscene2d/items/scene2dmanager.cpp index f0d6a6e34..3a83a36fd 100644 --- a/src/quick3d/quick3dscene2d/items/scene2dmanager.cpp +++ b/src/quick3d/quick3dscene2d/items/scene2dmanager.cpp @@ -72,9 +72,7 @@ QWindow *RenderControl::renderWindow(QPoint *offset) Constructs qml render manager. */ Scene2DManager::Scene2DManager(QScene2DPrivate *priv) - : m_qmlEngine(nullptr) - , m_qmlComponent(nullptr) - , m_rootItem(nullptr) + : m_rootItem(nullptr) , m_item(nullptr) , m_priv(priv) , m_sharedObject(new Scene2DSharedObject(this)) @@ -83,8 +81,6 @@ Scene2DManager::Scene2DManager(QScene2DPrivate *priv) , m_initialized(false) , m_renderSyncRequested(false) , m_backendInitialized(false) - , m_noSourceMode(false) - , m_ownEngine(false) , m_grabMouse(false) { m_sharedObject->m_surface = new QOffscreenSurface; @@ -135,38 +131,17 @@ void Scene2DManager::requestRenderSync() void Scene2DManager::startIfInitialized() { - if (!m_initialized && m_backendInitialized) { - if (m_source.isValid() && !m_noSourceMode) { - // Create a QML engine. - if (!m_qmlEngine) { - m_qmlEngine = new QQmlEngine; - if (!m_qmlEngine->incubationController()) { - m_qmlEngine->setIncubationController(m_sharedObject->m_quickWindow - ->incubationController()); - } - } - - // create component - m_ownEngine = true; - m_qmlComponent = new QQmlComponent(m_qmlEngine, m_source); - if (m_qmlComponent->isLoading()) { - connect(m_qmlComponent, &QQmlComponent::statusChanged, - this, &Scene2DManager::run); - } else { - run(); - } - } else if (m_item != nullptr) { - m_rootItem = m_item; + if (!m_initialized && m_backendInitialized && m_item != nullptr) { + m_rootItem = m_item; - // Associate root item with the window. - m_rootItem->setParentItem(m_sharedObject->m_quickWindow->contentItem()); + // Associate root item with the window. + m_rootItem->setParentItem(m_sharedObject->m_quickWindow->contentItem()); - // Update window size. - updateSizes(); + // Update window size. + updateSizes(); - m_initialized = true; - m_sharedObject->setInitialized(); - } + m_initialized = true; + m_sharedObject->setInitialized(); } } @@ -177,52 +152,7 @@ void Scene2DManager::stopAndClean() m_sharedObject->requestQuit(); m_sharedObject->wait(); m_sharedObject->cleanup(); - if (m_ownEngine) { - QObject::disconnect(m_connection); - delete m_qmlEngine; - } - delete m_qmlComponent; - m_qmlEngine = nullptr; - m_qmlComponent = nullptr; - } -} - -void Scene2DManager::run() -{ - disconnect(m_qmlComponent, &QQmlComponent::statusChanged, this, &Scene2DManager::run); - - if (m_qmlComponent->isError()) { - QList errorList = m_qmlComponent->errors(); - for (const QQmlError &error: errorList) - qWarning() << error.url() << error.line() << error; - return; - } - - QObject *rootObject = m_qmlComponent->create(); - if (m_qmlComponent->isError()) { - QList errorList = m_qmlComponent->errors(); - for (const QQmlError &error: errorList) - qWarning() << error.url() << error.line() << error; - return; - } - - m_rootItem = qobject_cast(rootObject); - if (!m_rootItem) { - qWarning("QScene2D: Root item is not a QQuickItem."); - delete rootObject; - return; } - - // The root item is ready. Associate it with the window. - m_rootItem->setParentItem(m_sharedObject->m_quickWindow->contentItem()); - - // Update window size. - updateSizes(); - - m_initialized = true; - m_sharedObject->setInitialized(); - - emit onLoadedChanged(); } void Scene2DManager::updateSizes() @@ -236,15 +166,8 @@ void Scene2DManager::updateSizes() m_sharedObject->m_quickWindow->setGeometry(0, 0, width, height); } -void Scene2DManager::setSource(const QUrl &url) -{ - m_source = url; - startIfInitialized(); -} - void Scene2DManager::setItem(QQuickItem *item) { - m_noSourceMode = true; m_item = item; startIfInitialized(); } @@ -346,23 +269,6 @@ void Scene2DManager::cleanup() stopAndClean(); } -void Scene2DManager::setEngine(QQmlEngine *engine) -{ - m_qmlEngine = engine; - m_ownEngine = false; - if (engine) { - m_connection = QObject::connect(engine, &QObject::destroyed, - this, &Scene2DManager::engineDestroyed); - } -} - -void Scene2DManager::engineDestroyed() -{ - QObject::disconnect(m_connection); - m_qmlEngine = nullptr; - m_ownEngine = false; -} - } // namespace Quick } // namespace Qt3DRender diff --git a/src/quick3d/quick3dscene2d/items/scene2dmanager_p.h b/src/quick3d/quick3dscene2d/items/scene2dmanager_p.h index d3c3a60a2..5f199969e 100644 --- a/src/quick3d/quick3dscene2d/items/scene2dmanager_p.h +++ b/src/quick3d/quick3dscene2d/items/scene2dmanager_p.h @@ -75,25 +75,19 @@ public: Scene2DManager(QScene2DPrivate *priv); ~Scene2DManager(); - QQmlEngine *m_qmlEngine; - QQmlComponent *m_qmlComponent; QQuickItem *m_rootItem; QQuickItem *m_item; QScene2DPrivate *m_priv; QSharedPointer m_sharedObject; - QUrl m_source; Qt3DCore::QNodeId m_id; - QMetaObject::Connection m_connection; QScene2D::RenderPolicy m_renderPolicy; bool m_requested; bool m_initialized; bool m_renderSyncRequested; bool m_backendInitialized; - bool m_noSourceMode; - bool m_ownEngine; bool m_grabMouse; void requestRender(); @@ -101,20 +95,14 @@ public: void doRenderSync(); void startIfInitialized(); void stopAndClean(); - void run(); void updateSizes(); - void setSource(const QUrl &url); void setItem(QQuickItem *item); bool event(QEvent *e) Q_DECL_OVERRIDE; bool forwardEvent(QEvent *event); - Q_SIGNAL void onLoadedChanged(); - void cleanup(); - void setEngine(QQmlEngine *engine); - void engineDestroyed(); }; } // namespace Quick diff --git a/tests/auto/render/qscene2d/tst_qscene2d.cpp b/tests/auto/render/qscene2d/tst_qscene2d.cpp index f0ff2db1e..61ac893e4 100644 --- a/tests/auto/render/qscene2d/tst_qscene2d.cpp +++ b/tests/auto/render/qscene2d/tst_qscene2d.cpp @@ -58,9 +58,7 @@ private Q_SLOTS: // THEN QCOMPARE(scene2d.output(), nullptr); - QCOMPARE(scene2d.source(), QUrl(QStringLiteral(""))); QCOMPARE(scene2d.renderPolicy(), QScene2D::Continuous); - QCOMPARE(scene2d.loaded(), false); QCOMPARE(scene2d.item(), nullptr); } @@ -90,25 +88,6 @@ private Q_SLOTS: QCOMPARE(scene2d.output(), newValue); QCOMPARE(spy.count(), 0); } - { - // WHEN - QSignalSpy spy(&scene2d, SIGNAL(sourceChanged(QUrl))); - const QUrl newValue = QUrl(QStringLiteral("qrc://source.qml")); - scene2d.setSource(newValue); - - // THEN - QVERIFY(spy.isValid()); - QCOMPARE(scene2d.source(), newValue); - QCOMPARE(spy.count(), 1); - - // WHEN - spy.clear(); - scene2d.setSource(newValue); - - // THEN - QCOMPARE(scene2d.source(), newValue); - QCOMPARE(spy.count(), 0); - } { // WHEN QSignalSpy spy(&scene2d, SIGNAL(renderPolicyChanged(QScene2D::RenderPolicy))); @@ -156,7 +135,6 @@ private Q_SLOTS: QScopedPointer output(new Qt3DRender::QRenderTargetOutput()); scene2d.setOutput(output.data()); - scene2d.setSource(QUrl(QStringLiteral("qrc://source.qml"))); scene2d.setRenderPolicy(QScene2D::SingleShot); // WHEN @@ -242,39 +220,6 @@ private Q_SLOTS: } - void checkSourceUpdate() - { - // GIVEN - TestArbiter arbiter; - Qt3DRender::Quick::QScene2D scene2d; - arbiter.setArbiterOnNode(&scene2d); - - { - // WHEN - scene2d.setSource(QUrl(QStringLiteral("qrc://source.qml"))); - QCoreApplication::processEvents(); - - // THEN - QCOMPARE(arbiter.events.size(), 1); - auto change = arbiter.events.first().staticCast(); - QCOMPARE(change->propertyName(), "source"); - QCOMPARE(change->value().value(), scene2d.source()); - QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); - - arbiter.events.clear(); - } - - { - // WHEN - scene2d.setSource(QUrl(QStringLiteral("qrc://source.qml"))); - QCoreApplication::processEvents(); - - // THEN - QCOMPARE(arbiter.events.size(), 0); - } - - } - void checkRenderPolicyUpdate() { // GIVEN diff --git a/tests/manual/render-qml-to-texture/main.cpp b/tests/manual/render-qml-to-texture/main.cpp index a2fc6ed09..2420c8560 100644 --- a/tests/manual/render-qml-to-texture/main.cpp +++ b/tests/manual/render-qml-to-texture/main.cpp @@ -37,6 +37,8 @@ #include #include #include +#include +#include #include #include @@ -87,7 +89,7 @@ int main(int argc, char *argv[]) while (frameGraphNode->childNodes().size() > 0) frameGraphNode = (Qt3DRender::QFrameGraphNode*)frameGraphNode->childNodes().at(0); view.defaultFrameGraph()->setClearColor(QColor::fromRgbF(1.0f, 1.0f, 1.0f)); - Qt3DRender::Quick::QScene2D* qmlTextureRenderer = new Qt3DRender::Quick::QScene2D(frameGraphNode); + Qt3DRender::Quick::QScene2D *qmlTextureRenderer = new Qt3DRender::Quick::QScene2D(frameGraphNode); Qt3DRender::QTexture2D* offscreenTexture = new Qt3DRender::QTexture2D(qmlTextureRenderer); offscreenTexture->setSize(1024, 1024); @@ -102,7 +104,9 @@ int main(int argc, char *argv[]) output->setTexture(offscreenTexture); qmlTextureRenderer->setOutput(output); - qmlTextureRenderer->setSource(QUrl(QStringLiteral("qrc:/OffscreenGui.qml"))); + QQmlEngine engine; + QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/OffscreenGui.qml"))); + qmlTextureRenderer->setItem(static_cast(component.create())); Qt3DCore::QEntity* planeEntity = new Qt3DCore::QEntity(sceneRoot); Qt3DExtras::QPlaneMesh* planeMesh = new Qt3DExtras::QPlaneMesh(planeEntity); -- cgit v1.2.3 From 1178d7538bced76d1475b214cd591d86609239f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antti=20M=C3=A4=C3=A4tt=C3=A4?= Date: Wed, 8 Feb 2017 10:20:46 +0200 Subject: Add autotests for new animation classes Change-Id: Id657443693009455c9307b51e862d43f41255f1d Reviewed-by: Sean Harmer --- tests/auto/animation/animation.pro | 12 +- .../qabstractanimation/qabstractanimation.pro | 10 + .../qabstractanimation/tst_qabstractanimation.cpp | 117 ++++++++ .../qanimationcontroller/qanimationcontroller.pro | 10 + .../tst_qanimationcontroller.cpp | 302 ++++++++++++++++++++ .../animation/qanimationgroup/qanimationgroup.pro | 10 + .../qanimationgroup/tst_qanimationgroup.cpp | 100 +++++++ .../qkeyframeanimation/qkeyframeanimation.pro | 10 + .../qkeyframeanimation/tst_qkeyframeanimation.cpp | 285 +++++++++++++++++++ .../qmorphinganimation/qmorphinganimation.pro | 10 + .../qmorphinganimation/tst_qmorphinganimation.cpp | 309 +++++++++++++++++++++ tests/auto/animation/qmorphtarget/qmorphtarget.pro | 10 + .../animation/qmorphtarget/tst_qmorphtarget.cpp | 123 ++++++++ .../qvertexblendanimation.pro | 10 + .../tst_qvertexblendanimation.cpp | 102 +++++++ 15 files changed, 1418 insertions(+), 2 deletions(-) create mode 100644 tests/auto/animation/qabstractanimation/qabstractanimation.pro create mode 100644 tests/auto/animation/qabstractanimation/tst_qabstractanimation.cpp create mode 100644 tests/auto/animation/qanimationcontroller/qanimationcontroller.pro create mode 100644 tests/auto/animation/qanimationcontroller/tst_qanimationcontroller.cpp create mode 100644 tests/auto/animation/qanimationgroup/qanimationgroup.pro create mode 100644 tests/auto/animation/qanimationgroup/tst_qanimationgroup.cpp create mode 100644 tests/auto/animation/qkeyframeanimation/qkeyframeanimation.pro create mode 100644 tests/auto/animation/qkeyframeanimation/tst_qkeyframeanimation.cpp create mode 100644 tests/auto/animation/qmorphinganimation/qmorphinganimation.pro create mode 100644 tests/auto/animation/qmorphinganimation/tst_qmorphinganimation.cpp create mode 100644 tests/auto/animation/qmorphtarget/qmorphtarget.pro create mode 100644 tests/auto/animation/qmorphtarget/tst_qmorphtarget.cpp create mode 100644 tests/auto/animation/qvertexblendanimation/qvertexblendanimation.pro create mode 100644 tests/auto/animation/qvertexblendanimation/tst_qvertexblendanimation.cpp diff --git a/tests/auto/animation/animation.pro b/tests/auto/animation/animation.pro index 969f477e7..d3ef37a61 100644 --- a/tests/auto/animation/animation.pro +++ b/tests/auto/animation/animation.pro @@ -7,7 +7,14 @@ SUBDIRS += \ qblendedclipanimator \ qchannelmapping \ qchannelmapper \ - qclipblendvalue + qclipblendvalue \ + qanimationcontroller \ + qanimationgroup \ + qkeyframeanimation \ + qmorphinganimation \ + qmorphtarget \ + qvertexblendanimation \ + qanimationcontroller qtConfig(private_tests) { SUBDIRS += \ @@ -27,5 +34,6 @@ qtConfig(private_tests) { qadditiveclipblend \ additiveclipblend \ clipblendvalue \ - animationutils + animationutils \ + qabstractanimation } diff --git a/tests/auto/animation/qabstractanimation/qabstractanimation.pro b/tests/auto/animation/qabstractanimation/qabstractanimation.pro new file mode 100644 index 000000000..be37677b6 --- /dev/null +++ b/tests/auto/animation/qabstractanimation/qabstractanimation.pro @@ -0,0 +1,10 @@ +TEMPLATE = app + +TARGET = tst_qabstractanimation + +QT += 3dcore 3dcore-private 3drender 3drender-private 3danimation 3danimation-private testlib + +CONFIG += testcase + +SOURCES += tst_qabstractanimation.cpp + diff --git a/tests/auto/animation/qabstractanimation/tst_qabstractanimation.cpp b/tests/auto/animation/qabstractanimation/tst_qabstractanimation.cpp new file mode 100644 index 000000000..90349fb28 --- /dev/null +++ b/tests/auto/animation/qabstractanimation/tst_qabstractanimation.cpp @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include + +class TestAnimation : public Qt3DAnimation::QAbstractAnimation +{ +public: + explicit TestAnimation(Qt3DCore::QNode *parent = nullptr) + : Qt3DAnimation::QAbstractAnimation( + *new Qt3DAnimation::QAbstractAnimationPrivate( + Qt3DAnimation::QAbstractAnimation::KeyframeAnimation), parent) + { + + } +}; + +class tst_QAbstractAnimation : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + + void checkDefaultConstruction() + { + // GIVEN + TestAnimation abstractAnimation; + + // THEN + QCOMPARE(abstractAnimation.animationName(), QString()); + QCOMPARE(abstractAnimation.animationType(), + Qt3DAnimation::QAbstractAnimation::KeyframeAnimation); + QCOMPARE(abstractAnimation.position(), 0.0f); + QCOMPARE(abstractAnimation.duration(), 0.0f); + } + + void checkPropertyChanges() + { + // GIVEN + TestAnimation abstractAnimation; + + { + // WHEN + QSignalSpy spy(&abstractAnimation, SIGNAL(animationNameChanged(QString))); + const QString newValue = QString("test"); + abstractAnimation.setAnimationName(newValue); + + // THEN + QCOMPARE(abstractAnimation.animationName(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + abstractAnimation.setAnimationName(newValue); + + // THEN + QCOMPARE(abstractAnimation.animationName(), newValue); + QCOMPARE(spy.count(), 0); + + } + { + // WHEN + QSignalSpy spy(&abstractAnimation, SIGNAL(positionChanged(float))); + const float newValue = 1.0f; + abstractAnimation.setPosition(newValue); + + // THEN + QCOMPARE(abstractAnimation.position(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + abstractAnimation.setPosition(newValue); + + // THEN + QCOMPARE(abstractAnimation.position(), newValue); + QCOMPARE(spy.count(), 0); + + } + } + +}; + +QTEST_APPLESS_MAIN(tst_QAbstractAnimation) + +#include "tst_qabstractanimation.moc" diff --git a/tests/auto/animation/qanimationcontroller/qanimationcontroller.pro b/tests/auto/animation/qanimationcontroller/qanimationcontroller.pro new file mode 100644 index 000000000..ff5348d47 --- /dev/null +++ b/tests/auto/animation/qanimationcontroller/qanimationcontroller.pro @@ -0,0 +1,10 @@ +TEMPLATE = app + +TARGET = tst_qanimationcontroller + +QT += 3dcore 3dcore-private 3drender 3drender-private 3danimation testlib + +CONFIG += testcase + +SOURCES += tst_qanimationcontroller.cpp + diff --git a/tests/auto/animation/qanimationcontroller/tst_qanimationcontroller.cpp b/tests/auto/animation/qanimationcontroller/tst_qanimationcontroller.cpp new file mode 100644 index 000000000..4774dc8ba --- /dev/null +++ b/tests/auto/animation/qanimationcontroller/tst_qanimationcontroller.cpp @@ -0,0 +1,302 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +class tst_QAnimationController : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + + void checkDefaultConstruction() + { + // GIVEN + Qt3DAnimation::QAnimationController animationController; + + // THEN + QCOMPARE(animationController.activeAnimationGroup(), 0); + QCOMPARE(animationController.position(), 0.0f); + QCOMPARE(animationController.positionScale(), 1.0f); + QCOMPARE(animationController.positionOffset(), 0.0f); + QCOMPARE(animationController.entity(), nullptr); + QCOMPARE(animationController.recursive(), true); + } + + void checkPropertyChanges() + { + // GIVEN + Qt3DAnimation::QAnimationController animationController; + + { + // WHEN + QSignalSpy spy(&animationController, SIGNAL(activeAnimationGroupChanged(int))); + const int newValue = 1; + animationController.setActiveAnimationGroup(newValue); + + // THEN + QCOMPARE(animationController.activeAnimationGroup(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + animationController.setActiveAnimationGroup(newValue); + + // THEN + QCOMPARE(animationController.activeAnimationGroup(), newValue); + QCOMPARE(spy.count(), 0); + + } + { + // WHEN + QSignalSpy spy(&animationController, SIGNAL(positionChanged(float))); + const float newValue = 2.0f; + animationController.setPosition(newValue); + + // THEN + QCOMPARE(animationController.position(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + animationController.setPosition(newValue); + + // THEN + QCOMPARE(animationController.position(), newValue); + QCOMPARE(spy.count(), 0); + + } + { + // WHEN + QSignalSpy spy(&animationController, SIGNAL(positionScaleChanged(float))); + const float newValue = 3.0f; + animationController.setPositionScale(newValue); + + // THEN + QCOMPARE(animationController.positionScale(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + animationController.setPositionScale(newValue); + + // THEN + QCOMPARE(animationController.positionScale(), newValue); + QCOMPARE(spy.count(), 0); + + } + { + // WHEN + QSignalSpy spy(&animationController, SIGNAL(positionOffsetChanged(float))); + const float newValue = -1.0f; + animationController.setPositionOffset(newValue); + + // THEN + QCOMPARE(animationController.positionOffset(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + animationController.setPositionOffset(newValue); + + // THEN + QCOMPARE(animationController.positionOffset(), newValue); + QCOMPARE(spy.count(), 0); + + } + { + // WHEN + QScopedPointer entity(new Qt3DCore::QEntity); + QSignalSpy spy(&animationController, SIGNAL(entityChanged(Qt3DCore::QEntity *))); + Qt3DCore::QEntity * newValue = entity.data(); + animationController.setEntity(newValue); + + // THEN + QCOMPARE(animationController.entity(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + animationController.setEntity(newValue); + + // THEN + QCOMPARE(animationController.entity(), newValue); + QCOMPARE(spy.count(), 0); + + } + { + // WHEN + QSignalSpy spy(&animationController, SIGNAL(recursiveChanged(bool))); + const bool newValue = false; + animationController.setRecursive(newValue); + + // THEN + QCOMPARE(animationController.recursive(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + animationController.setRecursive(newValue); + + // THEN + QCOMPARE(animationController.recursive(), newValue); + QCOMPARE(spy.count(), 0); + + } + } + + void testSetEntity() + { + // GIVEN + Qt3DAnimation::QAnimationController animationController; + Qt3DAnimation::QKeyframeAnimation *keyframeAnimation; + Qt3DAnimation::QKeyframeAnimation *keyframeAnimation2; + Qt3DAnimation::QMorphingAnimation *morphingAnimation; + + QScopedPointer entity(new Qt3DCore::QEntity); + keyframeAnimation = new Qt3DAnimation::QKeyframeAnimation(entity.data()); + keyframeAnimation2 = new Qt3DAnimation::QKeyframeAnimation(entity.data()); + morphingAnimation = new Qt3DAnimation::QMorphingAnimation(entity.data()); + + const QString animName1 = QString("animation1"); + const QString animName2 = QString("animation2"); + morphingAnimation->setAnimationName(animName1); + keyframeAnimation->setAnimationName(animName1); + keyframeAnimation2->setAnimationName(animName2); + + { + // WHEN + animationController.setEntity(entity.data()); + + // THEN + QVector list = animationController.animationGroupList(); + QCOMPARE(list.size(), 2); + + QCOMPARE(list.at(0)->name(), animName1); + QCOMPARE(list.at(1)->name(), animName2); + + QCOMPARE(list.at(0)->animationList().size(), 2); + QCOMPARE(list.at(1)->animationList().size(), 1); + } + } + + void testSetEntityRecursive() + { + // GIVEN + Qt3DAnimation::QAnimationController animationController; + Qt3DAnimation::QKeyframeAnimation *keyframeAnimation; + Qt3DAnimation::QMorphingAnimation *morphingAnimation; + + QScopedPointer entity(new Qt3DCore::QEntity); + keyframeAnimation = new Qt3DAnimation::QKeyframeAnimation(entity.data()); + Qt3DCore::QEntity *childEntity = new Qt3DCore::QEntity(entity.data()); + morphingAnimation = new Qt3DAnimation::QMorphingAnimation(childEntity); + + const QString animName1 = QString("animation1"); + const QString animName2 = QString("animation2"); + + keyframeAnimation->setAnimationName(animName1); + morphingAnimation->setAnimationName(animName2); + + { + // WHEN + animationController.setEntity(entity.data()); + + // THEN + QVector list = animationController.animationGroupList(); + QCOMPARE(list.size(), 2); + + QCOMPARE(list.at(0)->name(), animName1); + QCOMPARE(list.at(1)->name(), animName2); + + QCOMPARE(list.at(0)->animationList().size(), 1); + QCOMPARE(list.at(1)->animationList().size(), 1); + + animationController.setEntity(nullptr); + } + + { + // WHEN + animationController.setRecursive(false); + animationController.setEntity(entity.data()); + + // THEN + QVector list = animationController.animationGroupList(); + QCOMPARE(list.size(), 1); + + QCOMPARE(list.at(0)->name(), animName1); + + QCOMPARE(list.at(0)->animationList().size(), 1); + } + } + + + void testPropagatePosition() + { + // GIVEN + Qt3DAnimation::QAnimationController animationController; + Qt3DAnimation::QKeyframeAnimation *keyframeAnimation; + + QScopedPointer entity(new Qt3DCore::QEntity); + keyframeAnimation = new Qt3DAnimation::QKeyframeAnimation(entity.data()); + + const QString animName1 = QString("animation1"); + keyframeAnimation->setAnimationName(animName1); + + { + // WHEN + animationController.setEntity(entity.data()); + animationController.setPosition(2.0f); + + // THEN + QCOMPARE(animationController.animationGroupList().at(0)->position(), 2.0f); + QCOMPARE(keyframeAnimation->position(), 2.0f); + } + + { + // WHEN + animationController.setPositionOffset(1.0); + animationController.setPositionScale(2.0f); + animationController.setPosition(2.0f); + + // THEN + QCOMPARE(animationController.animationGroupList().at(0)->position(), 5.0f); + QCOMPARE(keyframeAnimation->position(), 5.0f); + } + } + +}; + +QTEST_APPLESS_MAIN(tst_QAnimationController) + +#include "tst_qanimationcontroller.moc" diff --git a/tests/auto/animation/qanimationgroup/qanimationgroup.pro b/tests/auto/animation/qanimationgroup/qanimationgroup.pro new file mode 100644 index 000000000..5c39fa539 --- /dev/null +++ b/tests/auto/animation/qanimationgroup/qanimationgroup.pro @@ -0,0 +1,10 @@ +TEMPLATE = app + +TARGET = tst_qanimationgroup + +QT += 3dcore 3dcore-private 3drender 3drender-private 3danimation testlib + +CONFIG += testcase + +SOURCES += tst_qanimationgroup.cpp + diff --git a/tests/auto/animation/qanimationgroup/tst_qanimationgroup.cpp b/tests/auto/animation/qanimationgroup/tst_qanimationgroup.cpp new file mode 100644 index 000000000..0c7a66222 --- /dev/null +++ b/tests/auto/animation/qanimationgroup/tst_qanimationgroup.cpp @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include + +class tst_QAnimationGroup : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + + void checkDefaultConstruction() + { + // GIVEN + Qt3DAnimation::QAnimationGroup animationGroup; + + // THEN + QCOMPARE(animationGroup.name(), QString()); + QCOMPARE(animationGroup.position(), 0.0f); + QCOMPARE(animationGroup.duration(), 0.0f); + } + + void checkPropertyChanges() + { + // GIVEN + Qt3DAnimation::QAnimationGroup animationGroup; + + { + // WHEN + QSignalSpy spy(&animationGroup, SIGNAL(nameChanged(QString))); + const QString newValue = QString("group"); + animationGroup.setName(newValue); + + // THEN + QCOMPARE(animationGroup.name(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + animationGroup.setName(newValue); + + // THEN + QCOMPARE(animationGroup.name(), newValue); + QCOMPARE(spy.count(), 0); + + } + { + // WHEN + QSignalSpy spy(&animationGroup, SIGNAL(positionChanged(float))); + const float newValue = 2.0f; + animationGroup.setPosition(newValue); + + // THEN + QCOMPARE(animationGroup.position(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + animationGroup.setPosition(newValue); + + // THEN + QCOMPARE(animationGroup.position(), newValue); + QCOMPARE(spy.count(), 0); + + } + } + +}; + +QTEST_APPLESS_MAIN(tst_QAnimationGroup) + +#include "tst_qanimationgroup.moc" diff --git a/tests/auto/animation/qkeyframeanimation/qkeyframeanimation.pro b/tests/auto/animation/qkeyframeanimation/qkeyframeanimation.pro new file mode 100644 index 000000000..994d8d0d9 --- /dev/null +++ b/tests/auto/animation/qkeyframeanimation/qkeyframeanimation.pro @@ -0,0 +1,10 @@ +TEMPLATE = app + +TARGET = tst_qkeyframeanimation + +QT += 3dcore 3dcore-private 3drender 3drender-private 3danimation testlib + +CONFIG += testcase + +SOURCES += tst_qkeyframeanimation.cpp + diff --git a/tests/auto/animation/qkeyframeanimation/tst_qkeyframeanimation.cpp b/tests/auto/animation/qkeyframeanimation/tst_qkeyframeanimation.cpp new file mode 100644 index 000000000..33bbebc52 --- /dev/null +++ b/tests/auto/animation/qkeyframeanimation/tst_qkeyframeanimation.cpp @@ -0,0 +1,285 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include + +class tst_QKeyframeAnimation : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + + void initTestCase() + { + qRegisterMetaType( + "QKeyframeAnimation::RepeatMode"); + } + + void checkDefaultConstruction() + { + // GIVEN + Qt3DAnimation::QKeyframeAnimation keyframeAnimation; + + // THEN + QCOMPARE(keyframeAnimation.target(), nullptr); + QCOMPARE(keyframeAnimation.easing(), QEasingCurve()); + QCOMPARE(keyframeAnimation.targetName(), QString()); + QCOMPARE(keyframeAnimation.startMode(), Qt3DAnimation::QKeyframeAnimation::Constant); + QCOMPARE(keyframeAnimation.endMode(), Qt3DAnimation::QKeyframeAnimation::Constant); + } + + void checkPropertyChanges() + { + // GIVEN + Qt3DAnimation::QKeyframeAnimation keyframeAnimation; + + { + // WHEN + QScopedPointer transform(new Qt3DCore::QTransform); + QSignalSpy spy(&keyframeAnimation, SIGNAL(targetChanged(Qt3DCore::QTransform *))); + Qt3DCore::QTransform * newValue = transform.data(); + keyframeAnimation.setTarget(newValue); + + // THEN + QCOMPARE(keyframeAnimation.target(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + keyframeAnimation.setTarget(newValue); + + // THEN + QCOMPARE(keyframeAnimation.target(), newValue); + QCOMPARE(spy.count(), 0); + + } + { + // WHEN + QSignalSpy spy(&keyframeAnimation, SIGNAL(easingChanged(const QEasingCurve &))); + const QEasingCurve newValue = QEasingCurve(QEasingCurve::CosineCurve); + keyframeAnimation.setEasing(newValue); + + // THEN + QCOMPARE(keyframeAnimation.easing(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + keyframeAnimation.setEasing(newValue); + + // THEN + QCOMPARE(keyframeAnimation.easing(), newValue); + QCOMPARE(spy.count(), 0); + + } + { + // WHEN + QSignalSpy spy(&keyframeAnimation, SIGNAL(targetNameChanged(QString))); + const QString newValue = QString("target"); + keyframeAnimation.setTargetName(newValue); + + // THEN + QCOMPARE(keyframeAnimation.targetName(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + keyframeAnimation.setTargetName(newValue); + + // THEN + QCOMPARE(keyframeAnimation.targetName(), newValue); + QCOMPARE(spy.count(), 0); + + } + { + // WHEN + QSignalSpy spy(&keyframeAnimation, + SIGNAL(startModeChanged(QKeyframeAnimation::RepeatMode))); + const Qt3DAnimation::QKeyframeAnimation::RepeatMode newValue + = Qt3DAnimation::QKeyframeAnimation::Repeat; + keyframeAnimation.setStartMode(newValue); + + // THEN + QCOMPARE(keyframeAnimation.startMode(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + keyframeAnimation.setStartMode(newValue); + + // THEN + QCOMPARE(keyframeAnimation.startMode(), newValue); + QCOMPARE(spy.count(), 0); + + } + { + // WHEN + QSignalSpy spy(&keyframeAnimation, + SIGNAL(endModeChanged(QKeyframeAnimation::RepeatMode))); + const Qt3DAnimation::QKeyframeAnimation::RepeatMode newValue + = Qt3DAnimation::QKeyframeAnimation::Repeat; + keyframeAnimation.setEndMode(newValue); + + // THEN + QCOMPARE(keyframeAnimation.endMode(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + keyframeAnimation.setEndMode(newValue); + + // THEN + QCOMPARE(keyframeAnimation.endMode(), newValue); + QCOMPARE(spy.count(), 0); + + } + } + + void testAnimating() + { + // GIVEN + Qt3DAnimation::QKeyframeAnimation keyframeAnimation; + Qt3DCore::QTransform targetTransform; + keyframeAnimation.setTarget(&targetTransform); + + const float positions[3] = {0.0f, 1.0f, 2.0f}; + + Qt3DCore::QTransform keyframes[3]; + keyframes[0].setScale(1.0f); + keyframes[1].setScale(2.0f); + keyframes[2].setScale(3.0f); + + keyframes[0].setTranslation(QVector3D(0.0f, 0.0f, 0.0f)); + keyframes[1].setTranslation(QVector3D(1.0f, 1.0f, 0.0f)); + keyframes[2].setTranslation(QVector3D(2.0f, 0.0f, 2.0f)); + + keyframes[0].setRotationX(0.0f); + keyframes[1].setRotationY(45.0f); + keyframes[2].setRotationZ(90.0f); + + QVector framePositions; + framePositions.push_back(positions[0]); + framePositions.push_back(positions[1]); + framePositions.push_back(positions[2]); + + QVector frames; + frames.push_back(&keyframes[0]); + frames.push_back(&keyframes[1]); + frames.push_back(&keyframes[2]); + + keyframeAnimation.setFramePositions(framePositions); + keyframeAnimation.setKeyframes(frames); + + { + // WHEN + keyframeAnimation.setPosition(0.0f); + + // THEN + QVERIFY(qFuzzyCompare(targetTransform.scale3D(), QVector3D(1.0f, 1.0f, 1.0f))); + QVERIFY(qFuzzyCompare(targetTransform.translation(), QVector3D(0.0f, 0.0f, 0.0f))); + QVERIFY(qFuzzyCompare(targetTransform.rotation(), + QQuaternion::fromEulerAngles(QVector3D(0.0f, 0.0f, 0.0f)))); + + // WHEN + keyframeAnimation.setPosition(1.0f); + + // THEN + QVERIFY(qFuzzyCompare(targetTransform.scale3D(), QVector3D(2.0f, 2.0f, 2.0f))); + QVERIFY(qFuzzyCompare(targetTransform.translation(), QVector3D(1.0f, 1.0f, 0.0f))); + QVERIFY(qFuzzyCompare(targetTransform.rotation(), + QQuaternion::fromEulerAngles(QVector3D(0.0f, 45.0f, 0.0f)))); + + // WHEN + keyframeAnimation.setPosition(2.0f); + + // THEN + QVERIFY(qFuzzyCompare(targetTransform.scale3D(), QVector3D(3.0f, 3.0f, 3.0f))); + QVERIFY(qFuzzyCompare(targetTransform.translation(), QVector3D(2.0f, 0.0f, 2.0f))); + QVERIFY(qFuzzyCompare(targetTransform.rotation(), + QQuaternion::fromEulerAngles(QVector3D(0.0f, 0.0f, 90.0f)))); + + // WHEN + keyframeAnimation.setPosition(3.0f); + + // THEN + QVERIFY(qFuzzyCompare(targetTransform.scale3D(), QVector3D(3.0f, 3.0f, 3.0f))); + QVERIFY(qFuzzyCompare(targetTransform.translation(), QVector3D(2.0f, 0.0f, 2.0f))); + QVERIFY(qFuzzyCompare(targetTransform.rotation(), + QQuaternion::fromEulerAngles(QVector3D(0.0f, 0.0f, 90.0f)))); + + // WHEN + keyframeAnimation.setStartMode(Qt3DAnimation::QKeyframeAnimation::None); + keyframeAnimation.setEndMode(Qt3DAnimation::QKeyframeAnimation::None); + keyframeAnimation.setPosition(-1.0f); + + // THEN + QVERIFY(qFuzzyCompare(targetTransform.scale3D(), QVector3D(3.0f, 3.0f, 3.0f))); + QVERIFY(qFuzzyCompare(targetTransform.translation(), QVector3D(2.0f, 0.0f, 2.0f))); + QVERIFY(qFuzzyCompare(targetTransform.rotation(), + QQuaternion::fromEulerAngles(QVector3D(0.0f, 0.0f, 90.0f)))); + + // WHEN + keyframeAnimation.setPosition(5.0f); + + // THEN + QVERIFY(qFuzzyCompare(targetTransform.scale3D(), QVector3D(3.0f, 3.0f, 3.0f))); + QVERIFY(qFuzzyCompare(targetTransform.translation(), QVector3D(2.0f, 0.0f, 2.0f))); + QVERIFY(qFuzzyCompare(targetTransform.rotation(), + QQuaternion::fromEulerAngles(QVector3D(0.0f, 0.0f, 90.0f)))); + + // WHEN + keyframeAnimation.setStartMode(Qt3DAnimation::QKeyframeAnimation::Repeat); + keyframeAnimation.setEndMode(Qt3DAnimation::QKeyframeAnimation::Repeat); + keyframeAnimation.setPosition(-1.0f); + + // THEN + QVERIFY(qFuzzyCompare(targetTransform.scale3D(), QVector3D(2.0f, 2.0f, 2.0f))); + QVERIFY(qFuzzyCompare(targetTransform.translation(), QVector3D(1.0f, 1.0f, 0.0f))); + QVERIFY(qFuzzyCompare(targetTransform.rotation(), + QQuaternion::fromEulerAngles(QVector3D(0.0f, 45.0f, 0.0f)))); + + // WHEN + keyframeAnimation.setStartMode(Qt3DAnimation::QKeyframeAnimation::Repeat); + keyframeAnimation.setEndMode(Qt3DAnimation::QKeyframeAnimation::Repeat); + keyframeAnimation.setPosition(4.0f); + + // THEN + QVERIFY(qFuzzyCompare(targetTransform.scale3D(), QVector3D(1.0f, 1.0f, 1.0f))); + QVERIFY(qFuzzyCompare(targetTransform.translation(), QVector3D(0.0f, 0.0f, 0.0f))); + QVERIFY(qFuzzyCompare(targetTransform.rotation(), + QQuaternion::fromEulerAngles(QVector3D(0.0f, 0.0f, 0.0f)))); + } + } +}; + +QTEST_APPLESS_MAIN(tst_QKeyframeAnimation) + +#include "tst_qkeyframeanimation.moc" diff --git a/tests/auto/animation/qmorphinganimation/qmorphinganimation.pro b/tests/auto/animation/qmorphinganimation/qmorphinganimation.pro new file mode 100644 index 000000000..aaad3b763 --- /dev/null +++ b/tests/auto/animation/qmorphinganimation/qmorphinganimation.pro @@ -0,0 +1,10 @@ +TEMPLATE = app + +TARGET = tst_qmorphinganimation + +QT += 3dcore 3dcore-private 3drender 3drender-private 3danimation testlib + +CONFIG += testcase + +SOURCES += tst_qmorphinganimation.cpp + diff --git a/tests/auto/animation/qmorphinganimation/tst_qmorphinganimation.cpp b/tests/auto/animation/qmorphinganimation/tst_qmorphinganimation.cpp new file mode 100644 index 000000000..77ff01851 --- /dev/null +++ b/tests/auto/animation/qmorphinganimation/tst_qmorphinganimation.cpp @@ -0,0 +1,309 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include + +class tst_QMorphingAnimation : public QObject +{ + Q_OBJECT + + bool verifyAttribute(Qt3DRender::QGeometry *geometry, QString name, + Qt3DRender::QAttribute *attribute) + { + const QVector attributes = geometry->attributes(); + for (const Qt3DRender::QAttribute *attr : attributes) { + if (attr->name() == name) { + if (attr == attribute) + return true; + return false; + } + } + return false; + } + +private Q_SLOTS: + + void initTestCase() + { + qRegisterMetaType("QMorphingAnimation::Method"); + } + + void checkDefaultConstruction() + { + // GIVEN + Qt3DAnimation::QMorphingAnimation morphingAnimation; + + // THEN + QCOMPARE(morphingAnimation.interpolator(), 0.0f); + QCOMPARE(morphingAnimation.target(), nullptr); + QCOMPARE(morphingAnimation.targetName(), QString()); + QCOMPARE(morphingAnimation.method(), Qt3DAnimation::QMorphingAnimation::Relative); + QCOMPARE(morphingAnimation.easing(), QEasingCurve()); + } + + void checkPropertyChanges() + { + // GIVEN + Qt3DAnimation::QMorphingAnimation morphingAnimation; + + { + // WHEN + QScopedPointer gr(new Qt3DRender::QGeometryRenderer); + QSignalSpy spy(&morphingAnimation, + SIGNAL(targetChanged(Qt3DRender::QGeometryRenderer *))); + Qt3DRender::QGeometryRenderer *newValue = gr.data(); + morphingAnimation.setTarget(newValue); + + // THEN + QCOMPARE(morphingAnimation.target(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + morphingAnimation.setTarget(newValue); + + // THEN + QCOMPARE(morphingAnimation.target(), newValue); + QCOMPARE(spy.count(), 0); + + } + { + // WHEN + QSignalSpy spy(&morphingAnimation, SIGNAL(targetNameChanged(QString))); + const QString newValue = QString("target"); + morphingAnimation.setTargetName(newValue); + + // THEN + QCOMPARE(morphingAnimation.targetName(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + morphingAnimation.setTargetName(newValue); + + // THEN + QCOMPARE(morphingAnimation.targetName(), newValue); + QCOMPARE(spy.count(), 0); + + } + { + // WHEN + QSignalSpy spy(&morphingAnimation, SIGNAL(methodChanged(QMorphingAnimation::Method))); + const Qt3DAnimation::QMorphingAnimation::Method newValue + = Qt3DAnimation::QMorphingAnimation::Normalized; + morphingAnimation.setMethod(newValue); + + // THEN + QCOMPARE(morphingAnimation.method(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + morphingAnimation.setMethod(newValue); + + // THEN + QCOMPARE(morphingAnimation.method(), newValue); + QCOMPARE(spy.count(), 0); + + } + { + // WHEN + QSignalSpy spy(&morphingAnimation, SIGNAL(easingChanged(QEasingCurve))); + const QEasingCurve newValue = QEasingCurve(QEasingCurve::InBounce); + morphingAnimation.setEasing(newValue); + + // THEN + QCOMPARE(morphingAnimation.easing(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + morphingAnimation.setEasing(newValue); + + // THEN + QCOMPARE(morphingAnimation.easing(), newValue); + QCOMPARE(spy.count(), 0); + + } + } + + void testAnimation() + { + // GIVEN + const QString baseName("position"); + const QString targetName("positionTarget"); + Qt3DAnimation::QMorphingAnimation morphingAnimation; + Qt3DRender::QAttribute *base = new Qt3DRender::QAttribute; + + Qt3DRender::QGeometry *geometry = new Qt3DRender::QGeometry; + Qt3DAnimation::QMorphTarget *mt1 = new Qt3DAnimation::QMorphTarget(&morphingAnimation); + Qt3DAnimation::QMorphTarget *mt2 = new Qt3DAnimation::QMorphTarget(&morphingAnimation); + Qt3DAnimation::QMorphTarget *mt3 = new Qt3DAnimation::QMorphTarget(&morphingAnimation); + Qt3DRender::QAttribute *a1 = new Qt3DRender::QAttribute(geometry); + Qt3DRender::QAttribute *a2 = new Qt3DRender::QAttribute(geometry); + Qt3DRender::QAttribute *a3 = new Qt3DRender::QAttribute(geometry); + Qt3DRender::QGeometryRenderer gr; + + base->setName(baseName); + geometry->addAttribute(base); + gr.setGeometry(geometry); + morphingAnimation.setTarget(&gr); + a1->setName(baseName); + a2->setName(baseName); + a3->setName(baseName); + mt1->addAttribute(a1); + mt2->addAttribute(a2); + mt3->addAttribute(a3); + morphingAnimation.addMorphTarget(mt1); + morphingAnimation.addMorphTarget(mt2); + morphingAnimation.addMorphTarget(mt3); + + QVector positions; + QVector weights; + positions.push_back(0.0f); + positions.push_back(1.0f); + positions.push_back(2.0f); + positions.push_back(3.0f); + positions.push_back(4.0f); + morphingAnimation.setTargetPositions(positions); + + weights.resize(3); + + weights[0] = 1.0f; + weights[1] = 0.0f; + weights[2] = 0.0f; + morphingAnimation.setWeights(0, weights); + weights[0] = 0.0f; + weights[1] = 0.0f; + weights[2] = 0.0f; + morphingAnimation.setWeights(1, weights); + weights[0] = 0.0f; + weights[1] = 1.0f; + weights[2] = 0.0f; + morphingAnimation.setWeights(2, weights); + weights[0] = 0.0f; + weights[1] = 0.0f; + weights[2] = 0.0f; + morphingAnimation.setWeights(3, weights); + weights[0] = 0.0f; + weights[1] = 0.0f; + weights[2] = 1.0f; + morphingAnimation.setWeights(4, weights); + + morphingAnimation.setMethod(Qt3DAnimation::QMorphingAnimation::Relative); + { + // WHEN + morphingAnimation.setPosition(0.0f); + + // THEN + QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), -1.0f)); + QVERIFY(verifyAttribute(geometry, baseName, base)); + QVERIFY(verifyAttribute(geometry, targetName, a1)); + + // WHEN + morphingAnimation.setPosition(0.5f); + + // THEN + QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), -0.5f)); + QVERIFY(verifyAttribute(geometry, baseName, base)); + QVERIFY(verifyAttribute(geometry, targetName, a1)); + + // WHEN + morphingAnimation.setPosition(1.0f); + + // THEN + QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), -0.0f)); + QVERIFY(verifyAttribute(geometry, baseName, base)); + + // WHEN + morphingAnimation.setPosition(1.5f); + + // THEN + QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), -0.5f)); + QVERIFY(verifyAttribute(geometry, baseName, base)); + QVERIFY(verifyAttribute(geometry, targetName, a2)); + + // WHEN + morphingAnimation.setPosition(4.0f); + + // THEN + QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), -1.0f)); + QVERIFY(verifyAttribute(geometry, baseName, base)); + QVERIFY(verifyAttribute(geometry, targetName, a3)); + } + + morphingAnimation.setMethod(Qt3DAnimation::QMorphingAnimation::Normalized); + { + // WHEN + morphingAnimation.setPosition(0.0f); + + // THEN + QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), 1.0f)); + QVERIFY(verifyAttribute(geometry, baseName, base)); + QVERIFY(verifyAttribute(geometry, targetName, a1)); + + // WHEN + morphingAnimation.setPosition(0.5f); + + // THEN + QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), 0.5f)); + QVERIFY(verifyAttribute(geometry, baseName, base)); + QVERIFY(verifyAttribute(geometry, targetName, a1)); + + // WHEN + morphingAnimation.setPosition(1.0f); + + // THEN + QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), 0.0f)); + QVERIFY(verifyAttribute(geometry, baseName, base)); + + // WHEN + morphingAnimation.setPosition(1.5f); + + // THEN + QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), 0.5f)); + QVERIFY(verifyAttribute(geometry, baseName, base)); + QVERIFY(verifyAttribute(geometry, targetName, a2)); + + // WHEN + morphingAnimation.setPosition(4.0f); + + // THEN + QVERIFY(qFuzzyCompare(morphingAnimation.interpolator(), 1.0f)); + QVERIFY(verifyAttribute(geometry, baseName, base)); + QVERIFY(verifyAttribute(geometry, targetName, a3)); + } + } +}; + +QTEST_APPLESS_MAIN(tst_QMorphingAnimation) + +#include "tst_qmorphinganimation.moc" diff --git a/tests/auto/animation/qmorphtarget/qmorphtarget.pro b/tests/auto/animation/qmorphtarget/qmorphtarget.pro new file mode 100644 index 000000000..bb38aad19 --- /dev/null +++ b/tests/auto/animation/qmorphtarget/qmorphtarget.pro @@ -0,0 +1,10 @@ +TEMPLATE = app + +TARGET = tst_qmorphtarget + +QT += 3dcore 3dcore-private 3drender 3drender-private 3danimation testlib + +CONFIG += testcase + +SOURCES += tst_qmorphtarget.cpp + diff --git a/tests/auto/animation/qmorphtarget/tst_qmorphtarget.cpp b/tests/auto/animation/qmorphtarget/tst_qmorphtarget.cpp new file mode 100644 index 000000000..2cba9ba2a --- /dev/null +++ b/tests/auto/animation/qmorphtarget/tst_qmorphtarget.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include + +class tst_QMorphTarget : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + + void checkDefaultConstruction() + { + // GIVEN + Qt3DAnimation::QMorphTarget morphTarget; + + // THEN + QCOMPARE(morphTarget.attributeNames(), QStringList()); + } + + void testSetAttributes() + { + // GIVEN + Qt3DAnimation::QMorphTarget morphTarget; + Qt3DRender::QAttribute attribute1; + Qt3DRender::QAttribute attribute2; + + attribute1.setName(Qt3DRender::QAttribute::defaultPositionAttributeName()); + attribute2.setName(Qt3DRender::QAttribute::defaultNormalAttributeName()); + + { + // WHEN + morphTarget.addAttribute(&attribute1); + + // THEN + QStringList names = morphTarget.attributeNames(); + QCOMPARE(names.size(), 1); + QCOMPARE(names.at(0), Qt3DRender::QAttribute::defaultPositionAttributeName()); + } + + { + // WHEN + morphTarget.addAttribute(&attribute2); + + // THEN + QStringList names = morphTarget.attributeNames(); + QCOMPARE(names.size(), 2); + QCOMPARE(names.at(1), Qt3DRender::QAttribute::defaultNormalAttributeName()); + } + } + + void testFromGeometry() + { + // GIVEN + Qt3DRender::QGeometry geometry; + Qt3DRender::QAttribute *attribute1 = new Qt3DRender::QAttribute; + Qt3DRender::QAttribute *attribute2 = new Qt3DRender::QAttribute; + attribute1->setName(Qt3DRender::QAttribute::defaultPositionAttributeName()); + attribute2->setName(Qt3DRender::QAttribute::defaultTextureCoordinateAttributeName()); + geometry.addAttribute(attribute1); + geometry.addAttribute(attribute2); + + QStringList attributes; + attributes.push_back(Qt3DRender::QAttribute::defaultPositionAttributeName()); + + { + // WHEN + QScopedPointer morphTarget( + Qt3DAnimation::QMorphTarget::fromGeometry(&geometry, attributes)); + + // THEN + QStringList names = morphTarget->attributeNames(); + QCOMPARE(names.size(), 1); + QCOMPARE(names.at(0), Qt3DRender::QAttribute::defaultPositionAttributeName()); + } + + { + // WHEN + attributes.push_back(Qt3DRender::QAttribute::defaultTextureCoordinateAttributeName()); + QScopedPointer morphTarget( + Qt3DAnimation::QMorphTarget::fromGeometry(&geometry, attributes)); + + // THEN + QStringList names = morphTarget->attributeNames(); + QCOMPARE(names.size(), 2); + QCOMPARE(names.at(0), Qt3DRender::QAttribute::defaultPositionAttributeName()); + QCOMPARE(names.at(1), Qt3DRender::QAttribute::defaultTextureCoordinateAttributeName()); + } + } + +}; + +QTEST_APPLESS_MAIN(tst_QMorphTarget) + +#include "tst_qmorphtarget.moc" diff --git a/tests/auto/animation/qvertexblendanimation/qvertexblendanimation.pro b/tests/auto/animation/qvertexblendanimation/qvertexblendanimation.pro new file mode 100644 index 000000000..8079ebf15 --- /dev/null +++ b/tests/auto/animation/qvertexblendanimation/qvertexblendanimation.pro @@ -0,0 +1,10 @@ +TEMPLATE = app + +TARGET = tst_qvertexblendanimation + +QT += 3dcore 3dcore-private 3drender 3drender-private 3danimation testlib + +CONFIG += testcase + +SOURCES += tst_qvertexblendanimation.cpp + diff --git a/tests/auto/animation/qvertexblendanimation/tst_qvertexblendanimation.cpp b/tests/auto/animation/qvertexblendanimation/tst_qvertexblendanimation.cpp new file mode 100644 index 000000000..dc27e4a7e --- /dev/null +++ b/tests/auto/animation/qvertexblendanimation/tst_qvertexblendanimation.cpp @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include + +class tst_QVertexBlendAnimation : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + + void checkDefaultConstruction() + { + // GIVEN + Qt3DAnimation::QVertexBlendAnimation vertexBlendAnimation; + + // THEN + QCOMPARE(vertexBlendAnimation.interpolator(), 0.0f); + QCOMPARE(vertexBlendAnimation.target(), nullptr); + QCOMPARE(vertexBlendAnimation.targetName(), QString()); + } + + void checkPropertyChanges() + { + // GIVEN + Qt3DAnimation::QVertexBlendAnimation vertexBlendAnimation; + + { + // WHEN + QScopedPointer gm(new Qt3DRender::QGeometryRenderer); + QSignalSpy spy(&vertexBlendAnimation, + SIGNAL(targetChanged(Qt3DRender::QGeometryRenderer *))); + Qt3DRender::QGeometryRenderer *newValue = gm.data(); + vertexBlendAnimation.setTarget(newValue); + + // THEN + QCOMPARE(vertexBlendAnimation.target(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + vertexBlendAnimation.setTarget(newValue); + + // THEN + QCOMPARE(vertexBlendAnimation.target(), newValue); + QCOMPARE(spy.count(), 0); + + } + { + // WHEN + QSignalSpy spy(&vertexBlendAnimation, SIGNAL(targetNameChanged(QString))); + const QString newValue = QString("target"); + vertexBlendAnimation.setTargetName(newValue); + + // THEN + QCOMPARE(vertexBlendAnimation.targetName(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + vertexBlendAnimation.setTargetName(newValue); + + // THEN + QCOMPARE(vertexBlendAnimation.targetName(), newValue); + QCOMPARE(spy.count(), 0); + + } + } + +}; + +QTEST_APPLESS_MAIN(tst_QVertexBlendAnimation) + +#include "tst_qvertexblendanimation.moc" -- cgit v1.2.3 From 337bc59bb3a162d1a64b05d1dc82b5ec4b99049d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antti=20M=C3=A4=C3=A4tt=C3=A4?= Date: Mon, 13 Mar 2017 09:32:53 +0200 Subject: Scene2D cleanup - register pick events when scene is initialized MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current model where mouseGrab is connected to picker signal doesn't work. The pressed event is not sent to scene2d item, because it is already lost when scene2d gets the grabMouse message where it registers to the picker events. This breaks the mouse event sequence (press-move-release) for the quick item. Instead hook to setScene of the node to message scene2d when the scene gets initialized and always register to the picker events. Task-number: QTBUG-58876 Change-Id: Ic9ca4b0899a030336ef20ff2cffbe10b567c36f5 Reviewed-by: Antti Määttä --- src/core/aspects/qaspectengine.cpp | 2 +- src/quick3d/quick3dscene2d/items/qscene2d.cpp | 46 ++++++--- src/quick3d/quick3dscene2d/items/qscene2d.h | 10 +- src/quick3d/quick3dscene2d/items/qscene2d_p.h | 7 ++ src/quick3d/quick3dscene2d/items/scene2d.cpp | 104 ++++++++++----------- src/quick3d/quick3dscene2d/items/scene2d_p.h | 2 + .../quick3dscene2d/items/scene2dmanager.cpp | 29 +----- .../quick3dscene2d/items/scene2dmanager_p.h | 3 +- tests/auto/render/qscene2d/tst_qscene2d.cpp | 55 +++++++++++ tests/auto/render/scene2d/tst_scene2d.cpp | 20 ++-- tests/manual/render-qml-to-texture-qml/main.qml | 3 +- 11 files changed, 167 insertions(+), 114 deletions(-) diff --git a/src/core/aspects/qaspectengine.cpp b/src/core/aspects/qaspectengine.cpp index a3fda90b0..b9c9d2283 100644 --- a/src/core/aspects/qaspectengine.cpp +++ b/src/core/aspects/qaspectengine.cpp @@ -103,8 +103,8 @@ QAspectEnginePrivate::~QAspectEnginePrivate() */ void QAspectEnginePrivate::initNode(QNode *node) { - QNodePrivate::get(node)->setScene(m_scene); m_scene->addObservable(node); + QNodePrivate::get(node)->setScene(m_scene); } void QAspectEnginePrivate::initEntity(QEntity *entity) diff --git a/src/quick3d/quick3dscene2d/items/qscene2d.cpp b/src/quick3d/quick3dscene2d/items/qscene2d.cpp index cc8c0b4fe..c96509252 100644 --- a/src/quick3d/quick3dscene2d/items/qscene2d.cpp +++ b/src/quick3d/quick3dscene2d/items/qscene2d.cpp @@ -95,6 +95,15 @@ namespace Quick { Holds the render policy of this Scene2D. */ +/*! + \qmlproperty bool Qt3D.Render::Scene2D::mouseEnabled + Holds whether mouse events are enabled for the rendered item. The mouse events are + generated from object picking events of the entities added to the QScene2D. + Mouse is enabled by default. + + \note Events are delayed by one frame due to object picking happening in the backend. + */ + QScene2DPrivate::QScene2DPrivate() : Qt3DCore::QNodePrivate() , m_renderManager(new Scene2DManager(this)) @@ -108,6 +117,15 @@ QScene2DPrivate::~QScene2DPrivate() 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. @@ -190,20 +208,14 @@ Qt3DCore::QNodeCreatedChangeBasePtr QScene2D::createNodeCreationChange() const data.output = d->m_output ? d->m_output->id() : Qt3DCore::QNodeId(); for (Qt3DCore::QEntity *e : d->m_entities) data.entityIds.append(e->id()); + data.mouseEnabled = d->m_renderManager->m_mouseEnabled; return creationChange; } -bool QScene2D::event(QEvent *event) -{ - Q_D(QScene2D); - d->m_renderManager->forwardEvent(event); - return true; -} - -bool QScene2D::isGrabMouseEnabled() const +bool QScene2D::isMouseEnabled() const { Q_D(const QScene2D); - return d->m_renderManager->m_grabMouse; + return d->m_renderManager->m_mouseEnabled; } QVector QScene2D::entities() @@ -244,12 +256,20 @@ void QScene2D::removeEntity(Qt3DCore::QEntity *entity) } } -void QScene2D::setGrabMouseEnabled(bool grab) +/*! + \property QScene2D::mouseEnabled + Holds whether mouse events are enabled for the rendered item. The mouse events are + generated from object picking events of the entities added to the QScene2D. + Mouse is enabled by default. + + \note Events are delayed by one frame due to object picking happening in the backend. + */ +void QScene2D::setMouseEnabled(bool enabled) { Q_D(QScene2D); - if (d->m_renderManager->m_grabMouse != grab) { - d->m_renderManager->m_grabMouse = grab; - emit grabMouseChanged(grab); + if (d->m_renderManager->m_mouseEnabled != enabled) { + d->m_renderManager->m_mouseEnabled = enabled; + emit mouseEnabledChanged(enabled); } } diff --git a/src/quick3d/quick3dscene2d/items/qscene2d.h b/src/quick3d/quick3dscene2d/items/qscene2d.h index b40cff536..73322a9e9 100644 --- a/src/quick3d/quick3dscene2d/items/qscene2d.h +++ b/src/quick3d/quick3dscene2d/items/qscene2d.h @@ -62,7 +62,7 @@ class QT3DQUICKSCENE2DSHARED_EXPORT QScene2D : public Qt3DCore::QNode Q_PROPERTY(Qt3DRender::QRenderTargetOutput *output READ output WRITE setOutput NOTIFY outputChanged) Q_PROPERTY(QScene2D::RenderPolicy renderPolicy READ renderPolicy WRITE setRenderPolicy NOTIFY renderPolicyChanged) Q_PROPERTY(QQuickItem *item READ item WRITE setItem NOTIFY itemChanged) - Q_PROPERTY(bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled NOTIFY grabMouseChanged) + Q_PROPERTY(bool mouseEnabled READ isMouseEnabled WRITE setMouseEnabled NOTIFY mouseEnabledChanged) Q_CLASSINFO("DefaultProperty", "item") @@ -79,9 +79,7 @@ public: Qt3DRender::QRenderTargetOutput *output() const; QScene2D::RenderPolicy renderPolicy() const; QQuickItem *item() const; - bool isGrabMouseEnabled() const; - - bool event(QEvent *event) Q_DECL_OVERRIDE; + bool isMouseEnabled() const; QVector entities(); void addEntity(Qt3DCore::QEntity *entity); @@ -91,13 +89,13 @@ public Q_SLOTS: void setOutput(Qt3DRender::QRenderTargetOutput *output); void setRenderPolicy(QScene2D::RenderPolicy policy); void setItem(QQuickItem *item); - void setGrabMouseEnabled(bool grab); + void setMouseEnabled(bool enabled); Q_SIGNALS: void outputChanged(Qt3DRender::QRenderTargetOutput *output); void renderPolicyChanged(QScene2D::RenderPolicy policy); void itemChanged(QQuickItem *item); - void grabMouseChanged(bool grab); + void mouseEnabledChanged(bool enabled); protected: Q_DECLARE_PRIVATE(QScene2D) diff --git a/src/quick3d/quick3dscene2d/items/qscene2d_p.h b/src/quick3d/quick3dscene2d/items/qscene2d_p.h index e40d3d6a9..217058f5c 100644 --- a/src/quick3d/quick3dscene2d/items/qscene2d_p.h +++ b/src/quick3d/quick3dscene2d/items/qscene2d_p.h @@ -55,6 +55,10 @@ QT_BEGIN_NAMESPACE +namespace Qt3DCore { +class QScene; +} + namespace Qt3DRender { namespace Quick { @@ -70,6 +74,8 @@ public: QScene2DPrivate(); ~QScene2DPrivate(); + void setScene(Qt3DCore::QScene *scene) Q_DECL_OVERRIDE; + Scene2DManager *m_renderManager; QMetaObject::Connection m_textureDestroyedConnection; Qt3DRender::QRenderTargetOutput *m_output; @@ -82,6 +88,7 @@ struct QScene2DData Scene2DSharedObjectPtr sharedObject; Qt3DCore::QNodeId output; QVector entityIds; + bool mouseEnabled; }; } // namespace Quick diff --git a/src/quick3d/quick3dscene2d/items/scene2d.cpp b/src/quick3d/quick3dscene2d/items/scene2d.cpp index 88b4d9e86..b0c58c6c5 100644 --- a/src/quick3d/quick3dscene2d/items/scene2d.cpp +++ b/src/quick3d/quick3dscene2d/items/scene2d.cpp @@ -118,6 +118,7 @@ Scene2D::Scene2D() , m_rbo(0) , m_initialized(false) , m_renderInitialized(false) + , m_mouseEnabled(true) , m_renderPolicy(Qt3DRender::Quick::QScene2D::Continuous) { renderThreadClientCount->fetchAndAddAcquire(1); @@ -125,12 +126,7 @@ Scene2D::Scene2D() Scene2D::~Scene2D() { - // this gets called from aspect thread. Wait for the render thread then delete it. - // TODO: render thread deletion -// if (m_renderThread) { -// m_renderThread->wait(1000); -// delete m_renderThread; -// } + stopGrabbing(); } void Scene2D::setOutput(Qt3DCore::QNodeId outputId) @@ -177,6 +173,7 @@ void Scene2D::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &chan setSharedObject(data.sharedObject); setOutput(data.output); m_entities = data.entityIds; + m_mouseEnabled = data.mouseEnabled; } void Scene2D::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) @@ -192,49 +189,42 @@ void Scene2D::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) } else if (propertyChange->propertyName() == QByteArrayLiteral("output")) { Qt3DCore::QNodeId outputId = propertyChange->value().value(); setOutput(outputId); - } else if (propertyChange->propertyName() == QByteArrayLiteral("sharedObject")) { - const Scene2DSharedObjectPtr sharedObject - = propertyChange->value().value(); - setSharedObject(sharedObject); } else if (propertyChange->propertyName() == QByteArrayLiteral("pressed")) { QPickEventPtr ev = propertyChange->value().value(); handlePickEvent(QEvent::MouseButtonPress, ev); } else if (propertyChange->propertyName() == QByteArrayLiteral("released")) { QPickEventPtr ev = propertyChange->value().value(); handlePickEvent(QEvent::MouseButtonRelease, ev); - } else if (propertyChange->propertyName() == QByteArrayLiteral("clicked")) { - QPickEventPtr ev = propertyChange->value().value(); - handlePickEvent(QEvent::MouseButtonDblClick, ev); } else if (propertyChange->propertyName() == QByteArrayLiteral("moved")) { QPickEventPtr ev = propertyChange->value().value(); handlePickEvent(QEvent::MouseMove, ev); - } else if (propertyChange->propertyName() == QByteArrayLiteral("grabMouse")) { - if (propertyChange->value().toBool()) { - startGrabbing(); - } else { - stopGrabbing(); + } 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(); } + } else if (propertyChange->propertyName() == QByteArrayLiteral("sceneInitialized")) { + startGrabbing(); } - /* TODO: handle these? - else if (propertyChange->propertyName() == QByteArrayLiteral("entered")) { - - } else if (propertyChange->propertyName() == QByteArrayLiteral("exited")) { - - }*/ break; } case Qt3DCore::PropertyValueAdded: { const auto change = qSharedPointerCast(e); - if (change->propertyName() == QByteArrayLiteral("entities")) + if (change->propertyName() == QByteArrayLiteral("entities")) { m_entities.push_back(change->addedNodeId()); + registerObjectPickerEvents(change->addedNodeId()); + } break; } case Qt3DCore::PropertyValueRemoved: { const auto change = qSharedPointerCast(e); - if (change->propertyName() == QByteArrayLiteral("entities")) + if (change->propertyName() == QByteArrayLiteral("entities")) { m_entities.removeOne(change->removedNodeId()); + unregisterObjectPickerEvents(change->removedNodeId()); + } break; } @@ -468,34 +458,42 @@ void Scene2D::unregisterObjectPickerEvents(Qt3DCore::QNodeId entityId) void Scene2D::handlePickEvent(int type, const Qt3DRender::QPickEventPtr &ev) { - QPickTriangleEvent *pickTriangle = static_cast(ev.data()); - Entity *entity = nullptr; - if (!resourceAccessor()->accessResource(RenderBackendResourceAccessor::EntityHandle, - QPickEventPrivate::get(pickTriangle)->m_entity, - (void**)&entity, nullptr)) { + if (!isEnabled()) return; - } - CoordinateReader reader(renderer()->nodeManagers()); - if (reader.setGeometry(entity->renderComponent(), - QAttribute::defaultTextureCoordinateAttributeName())) { - QVector4D c0 = reader.getCoordinate(pickTriangle->vertex1Index()); - QVector4D c1 = reader.getCoordinate(pickTriangle->vertex2Index()); - QVector4D c2 = reader.getCoordinate(pickTriangle->vertex3Index()); - QVector4D ci = c0 * pickTriangle->uvw().x() - + c1 * pickTriangle->uvw().y() + c2 * pickTriangle->uvw().z(); - ci.setW(1.0f); - - const QSize size = m_sharedObject->m_quickWindow->size(); - QPointF pos = QPointF(ci.x() * size.width(), (1.0f - ci.y()) * size.height()); - QMouseEvent *mouseEvent - = new QMouseEvent(static_cast(type), - pos, pos, pos, - static_cast(pickTriangle->button()), - static_cast(pickTriangle->buttons()), - static_cast(pickTriangle->modifiers()), - Qt::MouseEventSynthesizedByApplication); - - QCoreApplication::postEvent(m_sharedObject->m_quickWindow, mouseEvent); + if (m_mouseEnabled) { + QPickTriangleEvent *pickTriangle = static_cast(ev.data()); + Entity *entity = nullptr; + if (!resourceAccessor()->accessResource(RenderBackendResourceAccessor::EntityHandle, + QPickEventPrivate::get(pickTriangle)->m_entity, + (void**)&entity, nullptr)) { + return; + } + CoordinateReader reader(renderer()->nodeManagers()); + if (reader.setGeometry(entity->renderComponent(), + QAttribute::defaultTextureCoordinateAttributeName())) { + QVector4D c0 = reader.getCoordinate(pickTriangle->vertex1Index()); + QVector4D c1 = reader.getCoordinate(pickTriangle->vertex2Index()); + QVector4D c2 = reader.getCoordinate(pickTriangle->vertex3Index()); + QVector4D ci = c0 * pickTriangle->uvw().x() + + c1 * pickTriangle->uvw().y() + c2 * pickTriangle->uvw().z(); + ci.setW(1.0f); + + const QSize size = m_sharedObject->m_quickWindow->size(); + QPointF pos = QPointF(ci.x() * size.width(), (1.0f - ci.y()) * size.height()); + QMouseEvent *mouseEvent + = new QMouseEvent(static_cast(type), + pos, pos, pos, + static_cast(pickTriangle->button()), + static_cast(pickTriangle->buttons()), + static_cast(pickTriangle->modifiers()), + Qt::MouseEventSynthesizedByApplication); + + QCoreApplication::postEvent(m_sharedObject->m_quickWindow, mouseEvent); + } + } else if (type == QEvent::MouseButtonPress) { + m_cachedPickEvent = ev; + } else { + m_cachedPickEvent.clear(); } } diff --git a/src/quick3d/quick3dscene2d/items/scene2d_p.h b/src/quick3d/quick3dscene2d/items/scene2d_p.h index d2845d847..b42089306 100644 --- a/src/quick3d/quick3dscene2d/items/scene2d_p.h +++ b/src/quick3d/quick3dscene2d/items/scene2d_p.h @@ -119,8 +119,10 @@ public: bool m_initialized; bool m_renderInitialized; + bool m_mouseEnabled; Qt3DRender::Quick::QScene2D::RenderPolicy m_renderPolicy; QVector m_entities; + Qt3DRender::QPickEventPtr m_cachedPickEvent; }; } // Quick diff --git a/src/quick3d/quick3dscene2d/items/scene2dmanager.cpp b/src/quick3d/quick3dscene2d/items/scene2dmanager.cpp index 3a83a36fd..20c080dec 100644 --- a/src/quick3d/quick3dscene2d/items/scene2dmanager.cpp +++ b/src/quick3d/quick3dscene2d/items/scene2dmanager.cpp @@ -81,7 +81,7 @@ Scene2DManager::Scene2DManager(QScene2DPrivate *priv) , m_initialized(false) , m_renderSyncRequested(false) , m_backendInitialized(false) - , m_grabMouse(false) + , m_mouseEnabled(true) { m_sharedObject->m_surface = new QOffscreenSurface; m_sharedObject->m_surface->setFormat(QSurfaceFormat::defaultFormat()); @@ -225,33 +225,6 @@ bool Scene2DManager::event(QEvent *e) return QObject::event(e); } -bool Scene2DManager::forwardEvent(QEvent *event) -{ - switch (event->type()) { - - case QEvent::MouseMove: - case QEvent::MouseButtonDblClick: - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: { - QMouseEvent* me = static_cast(event); - QPointF pos = me->localPos(); - pos = QPointF(pos.x() * m_rootItem->width(), pos.y() * m_rootItem->height()); - QMouseEvent nme = QMouseEvent(me->type(), pos, pos, pos, me->button(), me->buttons(), - me->modifiers(), Qt::MouseEventSynthesizedByApplication); - QCoreApplication::sendEvent(m_sharedObject->m_quickWindow, &nme); - } break; - - case QEvent::KeyPress: - case QEvent::KeyRelease: { - QCoreApplication::sendEvent(m_sharedObject->m_quickWindow, event); - } break; - - default: - break; - } - return false; -} - void Scene2DManager::doRenderSync() { QMutexLocker lock(&m_sharedObject->m_mutex); diff --git a/src/quick3d/quick3dscene2d/items/scene2dmanager_p.h b/src/quick3d/quick3dscene2d/items/scene2dmanager_p.h index 5f199969e..821616f47 100644 --- a/src/quick3d/quick3dscene2d/items/scene2dmanager_p.h +++ b/src/quick3d/quick3dscene2d/items/scene2dmanager_p.h @@ -88,7 +88,7 @@ public: bool m_initialized; bool m_renderSyncRequested; bool m_backendInitialized; - bool m_grabMouse; + bool m_mouseEnabled; void requestRender(); void requestRenderSync(); @@ -100,7 +100,6 @@ public: void setItem(QQuickItem *item); bool event(QEvent *e) Q_DECL_OVERRIDE; - bool forwardEvent(QEvent *event); void cleanup(); }; diff --git a/tests/auto/render/qscene2d/tst_qscene2d.cpp b/tests/auto/render/qscene2d/tst_qscene2d.cpp index 61ac893e4..846207456 100644 --- a/tests/auto/render/qscene2d/tst_qscene2d.cpp +++ b/tests/auto/render/qscene2d/tst_qscene2d.cpp @@ -60,6 +60,7 @@ private Q_SLOTS: QCOMPARE(scene2d.output(), nullptr); QCOMPARE(scene2d.renderPolicy(), QScene2D::Continuous); QCOMPARE(scene2d.item(), nullptr); + QCOMPARE(scene2d.isMouseEnabled(), true); } void checkPropertyChanges() @@ -126,6 +127,26 @@ private Q_SLOTS: QCOMPARE(scene2d.item(), newValue); QCOMPARE(spy.count(), 0); } + + { + // WHEN + QSignalSpy spy(&scene2d, SIGNAL(mouseEnabledChanged(bool))); + bool newValue = false; + scene2d.setMouseEnabled(newValue); + + // THEN + QVERIFY(spy.isValid()); + QCOMPARE(scene2d.isMouseEnabled(), newValue); + QCOMPARE(spy.count(), 1); + + // WHEN + spy.clear(); + scene2d.setMouseEnabled(newValue); + + // THEN + QCOMPARE(scene2d.isMouseEnabled(), newValue); + QCOMPARE(spy.count(), 0); + } } void checkCreationData() @@ -159,6 +180,7 @@ private Q_SLOTS: QCOMPARE(scene2d.isEnabled(), true); QCOMPARE(scene2d.isEnabled(), creationChangeData->isNodeEnabled()); QCOMPARE(scene2d.metaObject(), creationChangeData->metaObject()); + QCOMPARE(scene2d.isMouseEnabled(), cloneData.mouseEnabled); } // WHEN @@ -254,6 +276,39 @@ private Q_SLOTS: } + void checkMouseEnabledUpdate() + { + // GIVEN + TestArbiter arbiter; + Qt3DRender::Quick::QScene2D scene2d; + arbiter.setArbiterOnNode(&scene2d); + + { + // WHEN + scene2d.setMouseEnabled(false); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + auto change = arbiter.events.first().staticCast(); + QCOMPARE(change->propertyName(), "mouseEnabled"); + QCOMPARE(change->value().toBool(), scene2d.isMouseEnabled()); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + } + + { + // WHEN + scene2d.setMouseEnabled(false); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + } + + } + }; QTEST_MAIN(tst_QScene2D) diff --git a/tests/auto/render/scene2d/tst_scene2d.cpp b/tests/auto/render/scene2d/tst_scene2d.cpp index a4810ce66..a78ed0ab1 100644 --- a/tests/auto/render/scene2d/tst_scene2d.cpp +++ b/tests/auto/render/scene2d/tst_scene2d.cpp @@ -114,6 +114,7 @@ private Q_SLOTS: QCOMPARE(backendScene2d.m_initialized, false); QCOMPARE(backendScene2d.m_renderInitialized, false); QCOMPARE(backendScene2d.m_renderPolicy, QScene2D::Continuous); + QCOMPARE(backendScene2d.m_mouseEnabled, true); backendScene2d.cleanup(); } @@ -135,6 +136,7 @@ private Q_SLOTS: QCOMPARE(backendScene2d->m_outputId, Qt3DCore::QNodeId()); QVERIFY(backendScene2d->m_sharedObject.data() != nullptr); QCOMPARE(backendScene2d->m_renderPolicy, QScene2D::Continuous); + QCOMPARE(backendScene2d->m_mouseEnabled, true); backendScene2d->cleanup(); } { @@ -183,28 +185,25 @@ private Q_SLOTS: } { // WHEN - const QSharedPointer newValue - = QSharedPointer( - new Qt3DRender::Quick::Scene2DSharedObject(nullptr)); + const QScene2D::RenderPolicy newValue = QScene2D::SingleShot; const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("sharedObject"); + change->setPropertyName("renderPolicy"); change->setValue(QVariant::fromValue(newValue)); backendScene2d->sceneChangeEvent(change); // THEN - QCOMPARE(backendScene2d->m_sharedObject, newValue); - QCOMPARE(backendScene2d->m_sharedObject.data(), newValue.data()); + QCOMPARE(backendScene2d->m_renderPolicy, newValue); } { // WHEN - const QScene2D::RenderPolicy newValue = QScene2D::SingleShot; + const bool newValue = false; const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("renderPolicy"); - change->setValue(QVariant::fromValue(newValue)); + change->setPropertyName("mouseEnabled"); + change->setValue(newValue); backendScene2d->sceneChangeEvent(change); // THEN - QCOMPARE(backendScene2d->m_renderPolicy, newValue); + QCOMPARE(backendScene2d->isEnabled(), newValue); } backendScene2d->cleanup(); @@ -228,6 +227,7 @@ private Q_SLOTS: TestRenderer renderer; renderer.setNodeManagers(nodeManagers.data()); scene2d->setRenderer(&renderer); + scene2d->setEnabled(true); sharedObject->m_quickWindow = testWindow.data(); scene2d->setSharedObject(sharedObject); testWindow->setGeometry(0,0,1024,1024); diff --git a/tests/manual/render-qml-to-texture-qml/main.qml b/tests/manual/render-qml-to-texture-qml/main.qml index 748e14f6e..65a0a8783 100644 --- a/tests/manual/render-qml-to-texture-qml/main.qml +++ b/tests/manual/render-qml-to-texture-qml/main.qml @@ -91,7 +91,8 @@ QQ2.Item { } entities: [plane1] - grabMouse: plane1.picker.pressed + + mouseEnabled: plane1.picker.pressed InteractiveGui { -- cgit v1.2.3 From f516fab44ea9c548485e9e9e5cd58c5c8a1da3e0 Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Fri, 28 Apr 2017 12:11:25 +0100 Subject: Add scene 2d example to showcase new feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ife2ead8fc2f0e0cb6dea18f8a74593847e25ff98 Reviewed-by: Antti Määttä --- examples/qt3d/qt3d.pro | 3 +- examples/qt3d/scene2d/LogoControls.qml | 242 ++ examples/qt3d/scene2d/Qt_logo.obj | 4071 ++++++++++++++++++++++++++++++++ examples/qt3d/scene2d/main.cpp | 64 + examples/qt3d/scene2d/main.qml | 177 ++ examples/qt3d/scene2d/scene2d.pro | 14 + examples/qt3d/scene2d/scene2d.qrc | 7 + 7 files changed, 4577 insertions(+), 1 deletion(-) create mode 100644 examples/qt3d/scene2d/LogoControls.qml create mode 100644 examples/qt3d/scene2d/Qt_logo.obj create mode 100644 examples/qt3d/scene2d/main.cpp create mode 100644 examples/qt3d/scene2d/main.qml create mode 100644 examples/qt3d/scene2d/scene2d.pro create mode 100644 examples/qt3d/scene2d/scene2d.qrc diff --git a/examples/qt3d/qt3d.pro b/examples/qt3d/qt3d.pro index dc5ba5a7e..7ac55bfd2 100644 --- a/examples/qt3d/qt3d.pro +++ b/examples/qt3d/qt3d.pro @@ -19,7 +19,8 @@ SUBDIRS += \ 3d-text \ qardboard \ advancedcustommaterial \ - simplecustommaterial + simplecustommaterial \ + scene2d qtHaveModule(multimedia): SUBDIRS += audio-visualizer-qml diff --git a/examples/qt3d/scene2d/LogoControls.qml b/examples/qt3d/scene2d/LogoControls.qml new file mode 100644 index 000000000..a71cd0e8d --- /dev/null +++ b/examples/qt3d/scene2d/LogoControls.qml @@ -0,0 +1,242 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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 QtQuick 2.0 +import QtQuick.Scene2D 2.9 +import QtQuick.Controls 1.4 +import QtQuick.Layouts 1.2 + +Rectangle { + id: root + color: "white" + focus: true + border.color: "black" + enabled: false + + property alias colorR: color_r.value + property alias colorG: color_g.value + property alias colorB: color_b.value + property alias shininess: shining.value + + property alias rotationX: rotation_x.value + property alias rotationY: rotation_y.value + property alias rotationZ: rotation_z.value + + property alias logoCentreZ: logoCenter_z.value + + + QtObject { + id: d + property real rotationValue: 0 + property color textColor: root.enabled ? "black" : "gray" + } + + SequentialAnimation { + running: true + paused: !animation.checked + loops: Animation.Infinite + + NumberAnimation { + target: d + property: "rotationValue" + easing.type: Easing.OutQuad + duration: 1000 + from: 0 + to: 45 + } + NumberAnimation { + target: d + property: "rotationValue" + easing.type: Easing.InOutQuad + duration: 1000 + from: 45 + to: -45 + } + NumberAnimation { + target: d + property: "rotationValue" + easing.type: Easing.InQuad + duration: 1000 + from: -45 + to: 0 + } + } + + ColumnLayout { + id: tipLayout + anchors.left: parent.left + anchors.leftMargin: 15 + anchors.right: parent.right + anchors.rightMargin: 15 + anchors.top: root.top + spacing: 5 + + Text { text: "Middle click to (de)activate"; font.bold: true } + } + + ColumnLayout { + id: colorLayout + anchors.left: parent.left + anchors.leftMargin: 15 + anchors.right: parent.right + anchors.rightMargin: 15 + anchors.top: tipLayout.bottom + anchors.topMargin: 20 + spacing: 5 + + Text { text: "Appearance"; font.bold: true; color: d.textColor } + Text { text: "Ambient color RGB"; color: d.textColor } + RowLayout { + Text { text: "R"; color: d.textColor } + Slider { + id: color_r + Layout.fillWidth: true + minimumValue: 0 + maximumValue: 255 + value: 128 + } + } + RowLayout { + Text { text: "G"; color: d.textColor } + Slider { + id: color_g + Layout.fillWidth: true + minimumValue: 0 + maximumValue: 255 + value: 195 + } + } + RowLayout { + Text { text: "B"; color: d.textColor } + Slider { + id: color_b + Layout.fillWidth: true + minimumValue: 0 + maximumValue: 255 + value: 66 + } + } + Text { text: "Shininess"; color: d.textColor } + Slider { + id: shining + Layout.fillWidth: true + minimumValue: 30 + maximumValue: 90 + value: 50 + } + } + + ColumnLayout { + id: transformLayout + + anchors.left: colorLayout.left + anchors.right: colorLayout.right + anchors.top: colorLayout.bottom + anchors.topMargin: 10 + spacing: 5 + + Text { text: "Item transform"; font.bold: true; color: d.textColor } + Text { text: "Rotation"; color: d.textColor } + RowLayout { + Text { text: "X"; color: d.textColor } + Slider { + id: rotation_x + Layout.fillWidth: true + minimumValue: -45 + maximumValue: 45 + value: d.rotationValue + } + } + RowLayout { + Text { text: "Y"; color: d.textColor } + Slider { + id: rotation_y + Layout.fillWidth: true + minimumValue: -45 + maximumValue: 45 + value: d.rotationValue + } + } + RowLayout { + Text { text: "Z"; color: d.textColor } + Slider { + id: rotation_z + Layout.fillWidth: true + minimumValue: -45 + maximumValue: 45 + value: d.rotationValue + } + } + + RowLayout { + CheckBox { id: animation; text: "Animation"; checked: false } + } + } + + ColumnLayout { + id: cameraLayout + + anchors.left: colorLayout.left + anchors.right: colorLayout.right + anchors.top: transformLayout.bottom + anchors.topMargin: 10 + spacing: 5 + + Text { text: "Object"; font.bold: true; color: d.textColor } + Text { text: "Logo Center Z"; color: d.textColor } + Slider { + id: logoCenter_z + Layout.fillWidth: true + minimumValue: -10 + maximumValue: 8 + value: 0 + } + } +} diff --git a/examples/qt3d/scene2d/Qt_logo.obj b/examples/qt3d/scene2d/Qt_logo.obj new file mode 100644 index 000000000..71f566661 --- /dev/null +++ b/examples/qt3d/scene2d/Qt_logo.obj @@ -0,0 +1,4071 @@ +# Blender v2.76 (sub 0) OBJ File: 'Qt_Logo_cutout2.blend' +# www.blender.org +mtllib Qt_logo.mtl +o Curve.001_Mesh +v 1.624641 -1.318420 -0.182387 +v 1.624641 -1.318420 0.182387 +v 1.604945 -1.374372 0.182387 +v 1.604945 -1.374372 -0.182387 +v 1.580433 -1.427071 0.182387 +v -0.981784 -0.203307 -0.182387 +v -0.972293 -0.281231 -0.182387 +v -1.543393 -0.228187 -0.182387 +v 0.724135 -0.831789 -0.182387 +v 0.262260 -0.831150 -0.182387 +v 0.711830 -0.814225 -0.182387 +v 1.639159 -1.259835 -0.182387 +v 1.639159 -1.259835 0.182387 +v 1.304468 -1.652686 0.182386 +v 1.551467 -1.475895 0.182387 +v 0.945710 -0.926501 0.182387 +v -1.543393 0.165341 0.182387 +v -0.997645 0.052952 0.182387 +v -0.998706 0.145841 0.182387 +v 1.580433 -1.427071 -0.182387 +v 1.121240 -0.657773 -0.182387 +v 1.121898 -0.657740 -0.182387 +v 1.121898 -0.657740 0.182387 +v 1.120596 -0.657802 -0.182387 +v 1.121240 -0.657773 0.182387 +v 1.119957 -0.657828 -0.182387 +v 1.120596 -0.657802 0.182387 +v 1.119311 -0.657849 -0.182387 +v 1.119957 -0.657828 0.182387 +v 1.118648 -0.657866 -0.182387 +v 1.119311 -0.657849 0.182387 +v 1.117959 -0.657879 -0.182387 +v 1.118648 -0.657866 0.182387 +v 1.117232 -0.657886 -0.182387 +v 1.117959 -0.657879 0.182387 +v 1.116459 -0.657889 -0.182387 +v 1.117232 -0.657886 0.182387 +v 1.108379 -0.657669 -0.182387 +v 1.116459 -0.657889 0.182387 +v 1.100785 -0.657008 -0.182387 +v 1.108379 -0.657669 0.182387 +v 1.093652 -0.655907 -0.182387 +v 1.100785 -0.657008 0.182387 +v 1.086952 -0.654363 -0.182387 +v 1.093652 -0.655907 0.182387 +v 1.080662 -0.652376 -0.182387 +v 1.086952 -0.654363 0.182387 +v 1.074757 -0.649945 -0.182387 +v 1.080662 -0.652376 0.182387 +v 1.069211 -0.647069 -0.182387 +v 1.074757 -0.649945 0.182387 +v 1.063999 -0.643748 -0.182387 +v 1.069211 -0.647069 0.182387 +v 1.059095 -0.639980 -0.182387 +v 1.063999 -0.643748 0.182387 +v 1.054475 -0.635764 -0.182387 +v 1.059095 -0.639980 0.182387 +v 1.050114 -0.631101 -0.182387 +v 1.054475 -0.635764 0.182387 +v 1.045986 -0.625988 -0.182387 +v 1.050114 -0.631101 0.182387 +v 1.041773 -0.619568 -0.182387 +v 1.045986 -0.625988 0.182387 +v 1.038066 -0.611957 -0.182387 +v 1.041773 -0.619568 0.182387 +v 1.034837 -0.603155 -0.182387 +v 1.038066 -0.611957 0.182387 +v 1.032062 -0.593160 -0.182387 +v 1.034837 -0.603155 0.182387 +v 1.029713 -0.581973 -0.182387 +v 1.032062 -0.593160 0.182387 +v 1.027764 -0.569593 -0.182387 +v 1.029713 -0.581973 0.182387 +v 1.026187 -0.556018 -0.182387 +v 1.027764 -0.569593 0.182387 +v 1.024956 -0.541250 -0.182387 +v 1.026187 -0.556018 0.182387 +v 1.024046 -0.525286 -0.182387 +v 1.024956 -0.541250 0.182387 +v 1.023428 -0.508127 -0.182387 +v 1.024046 -0.525286 0.182387 +v 1.023077 -0.489772 -0.182387 +v 1.023428 -0.508127 0.182387 +v 1.022966 -0.470221 -0.182387 +v 1.023077 -0.489772 0.182387 +v 1.022966 -0.457888 -0.182387 +v 1.022966 -0.470221 0.182387 +v 1.022966 -0.423033 -0.182387 +v 1.022966 -0.457888 0.182387 +v 1.022966 -0.368875 -0.182387 +v 1.022966 -0.423033 0.182387 +v 1.022966 -0.298629 -0.182387 +v 1.022966 -0.368875 0.182387 +v 1.022966 -0.215515 -0.182387 +v 1.022966 -0.298629 0.182387 +v 1.022966 -0.122748 -0.182387 +v 1.022966 -0.215515 0.182387 +v 1.022966 -0.023547 -0.182387 +v 1.022966 -0.122748 0.182387 +v 1.022966 0.078872 -0.182387 +v 1.022966 -0.023547 0.182387 +v 1.022966 0.181290 -0.182387 +v 1.022966 0.078872 0.182387 +v 1.022966 0.280492 -0.182387 +v 1.022966 0.181290 0.182387 +v 1.022966 0.373259 -0.182387 +v 1.022966 0.280492 0.182387 +v 1.022966 0.456373 -0.182387 +v 1.022966 0.373259 0.182387 +v 1.263622 0.444411 -0.182387 +v 1.022966 0.456373 0.182387 +v 1.263622 0.697952 -0.182387 +v 1.263622 0.444411 0.182387 +v 1.022966 0.716351 -0.182387 +v 1.263622 0.697952 0.182387 +v 1.022966 1.120478 -0.182387 +v 1.022966 0.716351 0.182387 +v 0.788843 1.145252 -0.182387 +v 1.022966 1.120478 0.182387 +v 0.693403 0.739209 -0.182387 +v 0.788843 1.145252 0.182387 +v 0.541780 0.750073 -0.182387 +v 0.693403 0.739209 0.182387 +v 0.541780 0.478384 -0.182387 +v 0.541780 0.750073 0.182387 +v 0.648683 0.472763 -0.182387 +v 0.541780 0.478384 0.182387 +v 0.648683 -0.554368 -0.182387 +v 0.648683 0.472763 0.182387 +v 0.649385 -0.587227 -0.182387 +v 0.648683 -0.554368 0.182387 +v 0.651461 -0.618561 -0.182387 +v 0.649385 -0.587227 0.182387 +v 0.654864 -0.648369 -0.182387 +v 0.651461 -0.618561 0.182387 +v 0.659545 -0.676652 -0.182387 +v 0.654864 -0.648369 0.182387 +v 0.665458 -0.703407 -0.182387 +v 0.659545 -0.676652 0.182387 +v 0.672554 -0.728633 -0.182387 +v 0.665458 -0.703407 0.182387 +v 0.680787 -0.752329 -0.182387 +v 0.672554 -0.728633 0.182387 +v 0.690109 -0.774494 -0.182387 +v 0.680787 -0.752329 0.182387 +v 0.700473 -0.795126 -0.182387 +v 0.690109 -0.774494 0.182387 +v 0.700473 -0.795126 0.182387 +v 0.711830 -0.814225 0.182387 +v 0.737338 -0.847817 -0.182387 +v 0.724135 -0.831789 0.182387 +v 0.749557 -0.860433 -0.182387 +v 0.737338 -0.847817 0.182387 +v 0.762797 -0.871939 -0.182387 +v 0.749557 -0.860433 0.182387 +v 0.777034 -0.882338 -0.182387 +v 0.762797 -0.871939 0.182387 +v 0.792240 -0.891632 -0.182387 +v 0.777034 -0.882338 0.182387 +v 0.808392 -0.899824 -0.182387 +v 0.792240 -0.891632 0.182387 +v 0.825461 -0.906916 -0.182387 +v 0.808392 -0.899824 0.182387 +v 0.843423 -0.912910 -0.182387 +v 0.825461 -0.906916 0.182387 +v 0.862251 -0.917809 -0.182387 +v 0.843423 -0.912910 0.182387 +v 0.881920 -0.921615 -0.182387 +v 0.862251 -0.917809 0.182387 +v 0.902404 -0.924331 -0.182387 +v 0.881920 -0.921615 0.182387 +v 0.923676 -0.925959 -0.182387 +v 0.902404 -0.924331 0.182387 +v 0.945710 -0.926501 -0.182387 +v 0.923676 -0.925959 0.182387 +v 1.211767 -0.874782 -0.182387 +v 1.237589 -0.865408 -0.182387 +v 1.651209 -0.996532 -0.182387 +v 1.651209 0.500221 -0.182387 +v 1.651209 0.805648 0.182387 +v 1.651209 0.500221 0.182387 +v 1.651209 -1.100473 -0.182387 +v 1.651209 -1.100473 0.182387 +v 1.651209 -1.137252 0.182387 +v 1.651209 -1.137252 -0.182387 +v 1.648136 -1.199239 0.182387 +v 1.648136 -1.199239 -0.182387 +v 1.551467 -1.475895 -0.182387 +v 1.518411 -1.520223 0.182387 +v 1.518411 -1.520223 -0.182387 +v 1.481627 -1.559434 0.182386 +v 1.481627 -1.559434 -0.182388 +v 1.441478 -1.592906 0.182386 +v 1.441478 -1.592906 -0.182388 +v 1.398327 -1.620021 0.182386 +v 1.398327 -1.620021 -0.182388 +v 1.352536 -1.640154 0.182386 +v 1.352536 -1.640154 -0.182388 +v 1.304468 -1.652686 -0.182388 +v -1.543393 -2.132013 0.182386 +v -1.543393 -0.634479 -0.182387 +v -1.543393 -1.040770 -0.182387 +v -1.543393 -1.040770 0.182387 +v -1.543393 1.494827 -0.182387 +v -1.543393 1.494827 0.182387 +v -1.543393 1.543752 0.182388 +v -1.543393 1.543752 -0.182386 +v -1.538053 1.625037 0.182388 +v -1.538053 1.625037 -0.182386 +v -1.522528 1.701349 0.182388 +v -1.522528 1.701349 -0.182386 +v -1.497558 1.772077 0.182388 +v -1.497558 1.772077 -0.182386 +v -1.463884 1.836608 0.182388 +v -1.463884 1.836608 -0.182386 +v -1.422248 1.894331 0.182388 +v -1.422248 1.894331 -0.182386 +v -1.373390 1.944634 0.182388 +v -1.373390 1.944634 -0.182386 +v -1.318050 1.986905 0.182388 +v -1.318050 1.986905 -0.182386 +v -1.256971 2.020532 0.182388 +v -1.256971 2.020532 -0.182386 +v -1.190891 2.044903 0.182388 +v -1.190891 2.044903 -0.182386 +v -1.120553 2.059406 0.182388 +v -1.120553 2.059406 -0.182386 +v -1.046697 2.063429 0.182388 +v -1.046697 2.063429 -0.182386 +v -0.970064 2.056361 0.182388 +v -0.970064 2.056361 -0.182386 +v -0.935175 2.050632 0.182388 +v -0.935175 2.050632 -0.182386 +v -0.836574 2.034443 0.182388 +v 0.873018 1.753752 -0.182386 +v 0.583283 1.801322 -0.182386 +v 0.583283 1.801322 0.182388 +v 1.290285 -0.632343 -0.182387 +v 1.290285 -0.655661 -0.182387 +v 1.290285 -0.655661 0.182387 +v 1.290285 -0.611451 -0.182387 +v 1.290285 -0.632343 0.182387 +v 1.276783 -0.618072 -0.182387 +v 1.290285 -0.611451 0.182387 +v 1.263028 -0.624200 -0.182387 +v 1.276783 -0.618072 0.182387 +v 1.249080 -0.629828 -0.182387 +v 1.263028 -0.624200 0.182387 +v 1.235000 -0.634956 -0.182387 +v 1.249080 -0.629828 0.182387 +v 1.220848 -0.639580 -0.182387 +v 1.235000 -0.634956 0.182387 +v 1.206685 -0.643697 -0.182387 +v 1.220848 -0.639580 0.182387 +v 1.192572 -0.647303 -0.182387 +v 1.206685 -0.643697 0.182387 +v 1.178569 -0.650396 -0.182387 +v 1.192572 -0.647303 0.182387 +v 1.164738 -0.652973 -0.182387 +v 1.178569 -0.650396 0.182387 +v 1.151138 -0.655030 -0.182387 +v 1.164738 -0.652973 0.182387 +v 1.137830 -0.656565 -0.182387 +v 1.151138 -0.655030 0.182387 +v 1.124875 -0.657574 -0.182387 +v 1.137830 -0.656565 0.182387 +v 1.124058 -0.657620 -0.182387 +v 1.124875 -0.657574 0.182387 +v 1.123296 -0.657663 -0.182387 +v 1.124058 -0.657620 0.182387 +v 1.122580 -0.657703 -0.182387 +v 1.123296 -0.657663 0.182387 +v 1.122580 -0.657703 0.182387 +v 1.651209 -0.996532 0.182387 +v 1.651209 -0.835023 0.182387 +v 1.290285 -0.844363 0.182387 +v 0.949063 -0.926488 -0.182387 +v 0.973284 -0.925691 -0.182387 +v 0.969757 -0.925878 -0.182387 +v 0.969757 -0.925878 0.182387 +v 0.976827 -0.925481 -0.182387 +v 0.973284 -0.925691 0.182387 +v 0.980386 -0.925247 -0.182387 +v 0.976827 -0.925481 0.182387 +v 0.983958 -0.924990 -0.182387 +v 0.980386 -0.925247 0.182387 +v 0.987542 -0.924711 -0.182387 +v 0.983958 -0.924990 0.182387 +v 1.012237 -0.922225 -0.182387 +v 0.987542 -0.924711 0.182387 +v 1.036888 -0.918973 -0.182387 +v 1.012237 -0.922225 0.182387 +v 1.061538 -0.914956 -0.182387 +v 1.036888 -0.918973 0.182387 +v 1.086227 -0.910174 -0.182387 +v 1.061538 -0.914956 0.182387 +v 1.111001 -0.904626 -0.182387 +v 1.086227 -0.910174 0.182387 +v 1.135899 -0.898313 -0.182387 +v 1.111001 -0.904626 0.182387 +v 1.160964 -0.891235 -0.182387 +v 1.135899 -0.898313 0.182387 +v 1.186239 -0.883391 -0.182387 +v 1.160964 -0.891235 0.182387 +v 1.186239 -0.883391 0.182387 +v 1.211767 -0.874782 0.182387 +v 1.263747 -0.855268 -0.182387 +v 1.237589 -0.865408 0.182387 +v 1.290285 -0.844363 -0.182387 +v 1.263747 -0.855268 0.182387 +v 1.290285 -0.841263 -0.182387 +v 1.290285 -0.832502 -0.182387 +v 1.290285 -0.841263 0.182387 +v 1.290285 -0.818888 -0.182387 +v 1.290285 -0.832502 0.182387 +v 1.290285 -0.801231 -0.182387 +v 1.290285 -0.818888 0.182387 +v 1.290285 -0.780339 -0.182387 +v 1.290285 -0.801231 0.182387 +v 1.290285 -0.757021 -0.182387 +v 1.290285 -0.780339 0.182387 +v 1.290285 -0.732085 -0.182387 +v 1.290285 -0.757021 0.182387 +v 1.290285 -0.706341 -0.182387 +v 1.290285 -0.732085 0.182387 +v 1.290285 -0.680596 -0.182387 +v 1.290285 -0.706341 0.182387 +v 1.290285 -0.680596 0.182387 +v 0.952447 -0.926449 -0.182387 +v 0.949063 -0.926488 0.182387 +v 0.955859 -0.926385 -0.182387 +v 0.952447 -0.926449 0.182387 +v 0.959298 -0.926295 -0.182387 +v 0.955859 -0.926385 0.182387 +v 0.962762 -0.926181 -0.182387 +v 0.959298 -0.926295 0.182387 +v 0.966249 -0.926042 -0.182387 +v 0.962762 -0.926181 0.182387 +v 0.966249 -0.926042 0.182387 +v 0.426419 -0.445305 -0.182387 +v 0.412138 -0.503110 -0.182387 +v 0.412138 -0.503110 0.182387 +v 0.439008 -0.384638 -0.182387 +v 0.426419 -0.445305 0.182387 +v 0.396163 -0.558060 -0.182387 +v 0.396163 -0.558060 0.182387 +v 0.449909 -0.321098 -0.182387 +v 0.439008 -0.384638 0.182387 +v 0.378490 -0.610163 -0.182387 +v 0.378490 -0.610163 0.182387 +v 0.459124 -0.254677 -0.182387 +v 0.449909 -0.321098 0.182387 +v 0.359117 -0.659430 -0.182387 +v 0.359117 -0.659430 0.182387 +v 0.466657 -0.185367 -0.182387 +v 0.459124 -0.254677 0.182387 +v 0.337635 -0.706565 -0.182387 +v 0.337635 -0.706565 0.182387 +v 0.472510 -0.113159 -0.182387 +v 0.466657 -0.185367 0.182387 +v 0.314338 -0.750899 -0.182387 +v 0.314338 -0.750899 0.182387 +v 0.476688 -0.038043 -0.182387 +v 0.472510 -0.113159 0.182387 +v 0.289217 -0.792428 -0.182387 +v 0.289217 -0.792428 0.182387 +v 0.479192 0.039988 -0.182387 +v 0.476688 -0.038043 0.182387 +v 0.262260 -0.831150 0.182387 +v 0.480026 0.120943 -0.182387 +v 0.479192 0.039988 0.182387 +v 0.233457 -0.867059 -0.182387 +v 0.233457 -0.867059 0.182387 +v 0.478892 0.209136 -0.182387 +v 0.480026 0.120943 0.182387 +v 0.202799 -0.900153 -0.182387 +v 0.202799 -0.900153 0.182387 +v 0.475486 0.293762 -0.182387 +v 0.478892 0.209136 0.182387 +v 0.170275 -0.930427 -0.182387 +v 0.170275 -0.930427 0.182387 +v 0.469801 0.374832 -0.182387 +v 0.475486 0.293762 0.182387 +v 0.135875 -0.957879 -0.182387 +v 0.135875 -0.957879 0.182387 +v 0.461829 0.452356 -0.182387 +v 0.469801 0.374832 0.182387 +v 0.099588 -0.982504 -0.182387 +v 0.099588 -0.982504 0.182387 +v 0.451565 0.526344 -0.182387 +v 0.461829 0.452356 0.182387 +v 0.061404 -1.004298 -0.182387 +v 0.061404 -1.004298 0.182387 +v 0.438999 0.596807 -0.182387 +v 0.451565 0.526344 0.182387 +v 0.021314 -1.023258 -0.182387 +v 0.021314 -1.023258 0.182387 +v 0.424126 0.663755 -0.182387 +v 0.438999 0.596807 0.182387 +v -0.020694 -1.039381 -0.182387 +v -0.020694 -1.039381 0.182387 +v 0.406938 0.727197 -0.182387 +v 0.424126 0.663755 0.182387 +v -0.016169 -1.061018 -0.182387 +v -0.016169 -1.061018 0.182387 +v 0.387429 0.787144 -0.182387 +v 0.406938 0.727197 0.182387 +v -0.011276 -1.081441 -0.182387 +v -0.011276 -1.081441 0.182387 +v 0.365590 0.843607 -0.182387 +v 0.387429 0.787144 0.182387 +v -0.006016 -1.100653 -0.182387 +v -0.006016 -1.100653 0.182387 +v 0.341416 0.896596 -0.182387 +v 0.365590 0.843607 0.182387 +v -0.000390 -1.118659 -0.182387 +v -0.000390 -1.118659 0.182387 +v 0.314899 0.946121 -0.182387 +v 0.341416 0.896596 0.182387 +v 0.005602 -1.135461 -0.182387 +v 0.005602 -1.135461 0.182387 +v 0.285433 0.993262 -0.182387 +v 0.314899 0.946121 0.182387 +v 0.011959 -1.151064 -0.182387 +v 0.011959 -1.151064 0.182387 +v 0.253428 1.036951 -0.182387 +v 0.285433 0.993262 0.182387 +v 0.018682 -1.165471 -0.182387 +v 0.018682 -1.165471 0.182387 +v 0.218864 1.077179 -0.182387 +v 0.253428 1.036951 0.182387 +v 0.025769 -1.178687 -0.182387 +v 0.025769 -1.178687 0.182387 +v 0.181722 1.113937 -0.182387 +v 0.218864 1.077179 0.182387 +v 0.033220 -1.190714 -0.182387 +v 0.033220 -1.190714 0.182387 +v 0.141985 1.147215 -0.182387 +v 0.181722 1.113937 0.182387 +v 0.041036 -1.201556 -0.182387 +v 0.041036 -1.201556 0.182387 +v 0.099634 1.177004 -0.182387 +v 0.141985 1.147215 0.182387 +v 0.049214 -1.211217 -0.182387 +v 0.049214 -1.211217 0.182387 +v 0.054650 1.203293 -0.182387 +v 0.099634 1.177004 0.182387 +v 0.057755 -1.219701 -0.182387 +v 0.057755 -1.219701 0.182387 +v 0.007014 1.226074 -0.182387 +v 0.054650 1.203293 0.182387 +v 0.062803 -1.223925 -0.182387 +v 0.062803 -1.223925 0.182387 +v -0.043291 1.245338 -0.182387 +v 0.007014 1.226074 0.182387 +v 0.068176 -1.227869 -0.182387 +v 0.068176 -1.227869 0.182387 +v -0.096284 1.261074 -0.182387 +v -0.043291 1.245338 0.182387 +v 0.073872 -1.231538 -0.182387 +v 0.073872 -1.231538 0.182387 +v -0.151985 1.273272 -0.182387 +v -0.096284 1.261074 0.182387 +v 0.079888 -1.234935 -0.182387 +v 0.079888 -1.234935 0.182387 +v -0.210411 1.281925 -0.182387 +v -0.151985 1.273272 0.182387 +v 0.086222 -1.238063 -0.182387 +v 0.086222 -1.238063 0.182387 +v -0.219049 1.282895 -0.182387 +v -0.210411 1.281925 0.182387 +v 0.092870 -1.240926 -0.182387 +v 0.092870 -1.240926 0.182387 +v -0.227645 1.283780 -0.182387 +v -0.219049 1.282895 0.182387 +v 0.099831 -1.243528 -0.182387 +v 0.099831 -1.243528 0.182387 +v -0.236197 1.284580 -0.182387 +v -0.227645 1.283780 0.182387 +v 0.107101 -1.245871 -0.182387 +v 0.107101 -1.245871 0.182387 +v -0.244706 1.285296 -0.182387 +v -0.236197 1.284580 0.182387 +v 0.114677 -1.247959 -0.182387 +v 0.114677 -1.247959 0.182387 +v -0.253173 1.285927 -0.182387 +v -0.244706 1.285296 0.182387 +v 0.122558 -1.249797 -0.182387 +v 0.122558 -1.249797 0.182387 +v -0.261597 1.286474 -0.182387 +v -0.253173 1.285927 0.182387 +v 0.130740 -1.251386 -0.182387 +v 0.130740 -1.251386 0.182387 +v -0.269979 1.286936 -0.182387 +v -0.261597 1.286474 0.182387 +v 0.139220 -1.252732 -0.182387 +v 0.139220 -1.252732 0.182387 +v -0.278318 1.287314 -0.182387 +v -0.269979 1.286936 0.182387 +v 0.139392 -1.252755 -0.182387 +v 0.139392 -1.252755 0.182387 +v -0.286614 1.287608 -0.182387 +v -0.278318 1.287314 0.182387 +v 0.139563 -1.252762 -0.182387 +v 0.139563 -1.252762 0.182387 +v -0.294869 1.287817 -0.182387 +v -0.286614 1.287608 0.182387 +v 0.139734 -1.252757 -0.182387 +v 0.139734 -1.252757 0.182387 +v -0.303082 1.287943 -0.182387 +v -0.294869 1.287817 0.182387 +v 0.139905 -1.252744 -0.182387 +v 0.139905 -1.252744 0.182387 +v -0.311252 1.287985 -0.182387 +v -0.303082 1.287943 0.182387 +v 0.140076 -1.252724 -0.182387 +v 0.140076 -1.252724 0.182387 +v -0.361180 1.286331 -0.182387 +v -0.311252 1.287985 0.182387 +v 0.140248 -1.252701 -0.182387 +v 0.140248 -1.252701 0.182387 +v -0.409360 1.281363 -0.182387 +v -0.361180 1.286331 0.182387 +v 0.140422 -1.252678 -0.182387 +v 0.140422 -1.252678 0.182387 +v -0.455776 1.273071 -0.182387 +v -0.409360 1.281363 0.182387 +v 0.140597 -1.252657 -0.182387 +v 0.140597 -1.252657 0.182387 +v -0.500415 1.261445 -0.182387 +v -0.455776 1.273071 0.182387 +v 0.140774 -1.252644 -0.182387 +v 0.140774 -1.252644 0.182387 +v -0.543260 1.246475 -0.182387 +v -0.500415 1.261445 0.182387 +v 0.140954 -1.252639 -0.182387 +v 0.140954 -1.252639 0.182387 +v -0.584298 1.228152 -0.182387 +v -0.543260 1.246475 0.182387 +v 0.141137 -1.252646 -0.182387 +v 0.141137 -1.252646 0.182387 +v -0.623514 1.206466 -0.182387 +v -0.584298 1.228152 0.182387 +v 0.141324 -1.252669 -0.182387 +v 0.141324 -1.252669 0.182387 +v -0.660894 1.181408 -0.182387 +v -0.623514 1.206466 0.182387 +v 0.141785 -1.252711 -0.182387 +v 0.141785 -1.252711 0.182387 +v -0.696421 1.152968 -0.182387 +v -0.660894 1.181408 0.182387 +v 0.142256 -1.252718 -0.182387 +v 0.142256 -1.252718 0.182387 +v -0.730083 1.121135 -0.182387 +v -0.696421 1.152968 0.182387 +v 0.142734 -1.252694 -0.182387 +v 0.142734 -1.252694 0.182387 +v -0.761863 1.085901 -0.182387 +v -0.730083 1.121135 0.182387 +v 0.143219 -1.252649 -0.182387 +v 0.143219 -1.252649 0.182387 +v -0.791747 1.047255 -0.182387 +v -0.761863 1.085901 0.182387 +v 0.143707 -1.252589 -0.182387 +v 0.143707 -1.252589 0.182387 +v -0.824643 0.997153 -0.182387 +v -0.791747 1.047255 0.182387 +v 0.144198 -1.252520 -0.182387 +v 0.144198 -1.252520 0.182387 +v -0.854719 0.942465 -0.182387 +v -0.824643 0.997153 0.182387 +v 0.144688 -1.252450 -0.182387 +v 0.144688 -1.252450 0.182387 +v -0.881969 0.883201 -0.182387 +v -0.854719 0.942465 0.182387 +v 0.145176 -1.252385 -0.182387 +v 0.145176 -1.252385 0.182387 +v -0.906384 0.819374 -0.182387 +v -0.881969 0.883201 0.182387 +v 0.145661 -1.252334 -0.182387 +v 0.145661 -1.252334 0.182387 +v -0.927957 0.750994 -0.182387 +v -0.906384 0.819374 0.182387 +v 0.146139 -1.252301 -0.182387 +v 0.146139 -1.252301 0.182387 +v -0.946680 0.678073 -0.182387 +v -0.927957 0.750994 0.182387 +v 0.146610 -1.252296 -0.182387 +v 0.146610 -1.252296 0.182387 +v -0.962543 0.600624 -0.182387 +v -0.946680 0.678073 0.182387 +v 0.147071 -1.252324 -0.182387 +v 0.147071 -1.252324 0.182387 +v -0.975540 0.518656 -0.182387 +v -0.962543 0.600624 0.182387 +v 0.149900 -1.252584 -0.182387 +v 0.149900 -1.252584 0.182387 +v -0.985663 0.432183 -0.182387 +v -0.975540 0.518656 0.182387 +v 0.152764 -1.252761 -0.182387 +v 0.152764 -1.252761 0.182387 +v -0.992904 0.341214 -0.182387 +v -0.985663 0.432183 0.182387 +v 0.155663 -1.252865 -0.182387 +v 0.155663 -1.252865 0.182387 +v -0.997254 0.245763 -0.182387 +v -0.992904 0.341214 0.182387 +v 0.158594 -1.252909 -0.182387 +v 0.158594 -1.252909 0.182387 +v -0.998706 0.145841 -0.182387 +v -0.997254 0.245763 0.182387 +v 0.161558 -1.252904 -0.182387 +v 0.161558 -1.252904 0.182387 +v -0.997645 0.052952 -0.182387 +v 0.164552 -1.252862 -0.182387 +v 0.164552 -1.252862 0.182387 +v -0.994467 -0.036208 -0.182387 +v 0.167575 -1.252794 -0.182387 +v 0.167575 -1.252794 0.182387 +v -0.989178 -0.121631 -0.182387 +v -0.994467 -0.036208 0.182387 +v 0.170627 -1.252712 -0.182387 +v 0.170627 -1.252712 0.182387 +v -0.989178 -0.121631 0.182387 +v 0.173706 -1.252628 -0.182387 +v 0.173706 -1.252628 0.182387 +v -0.981784 -0.203307 0.182387 +v 0.176810 -1.252554 -0.182387 +v 0.176810 -1.252554 0.182387 +v -0.960710 -0.355393 -0.182387 +v -0.972293 -0.281231 0.182387 +v 0.179940 -1.252501 -0.182387 +v 0.179940 -1.252501 0.182387 +v -0.947042 -0.425786 -0.182387 +v -0.960710 -0.355393 0.182387 +v 0.183092 -1.252481 -0.182387 +v 0.183092 -1.252481 0.182387 +v -0.931295 -0.492402 -0.182387 +v -0.947042 -0.425786 0.182387 +v 0.183174 -1.252481 -0.182387 +v 0.183174 -1.252481 0.182387 +v -0.913475 -0.555233 -0.182387 +v -0.931295 -0.492402 0.182387 +v 0.183265 -1.252481 -0.182387 +v 0.183265 -1.252481 0.182387 +v -0.893590 -0.614272 -0.182387 +v -0.913475 -0.555233 0.182387 +v 0.183363 -1.252481 -0.182387 +v 0.183363 -1.252481 0.182387 +v -0.871646 -0.669510 -0.182387 +v -0.893590 -0.614272 0.182387 +v 0.183463 -1.252481 -0.182387 +v 0.183463 -1.252481 0.182387 +v -0.847648 -0.720939 -0.182387 +v -0.871646 -0.669510 0.182387 +v 0.183564 -1.252481 -0.182387 +v 0.183564 -1.252481 0.182387 +v -0.822076 -0.768036 -0.182387 +v -0.847648 -0.720939 0.182387 +v 0.183662 -1.252481 -0.182387 +v 0.183662 -1.252481 0.182387 +v -0.794690 -0.811855 -0.182387 +v -0.822076 -0.768036 0.182387 +v 0.183753 -1.252481 -0.182387 +v 0.183753 -1.252481 0.182387 +v -0.765502 -0.852402 -0.182387 +v -0.794690 -0.811855 0.182387 +v 0.183835 -1.252481 -0.182387 +v 0.183835 -1.252481 0.182387 +v -0.734525 -0.889683 -0.182387 +v -0.765502 -0.852402 0.182387 +v 0.183904 -1.252481 -0.182387 +v 0.183904 -1.252481 0.182387 +v -0.701772 -0.923703 -0.182387 +v -0.734525 -0.889683 0.182387 +v 0.183957 -1.252481 -0.182387 +v 0.183957 -1.252481 0.182387 +v -0.667254 -0.954468 -0.182387 +v -0.701772 -0.923703 0.182387 +v 0.183991 -1.252481 -0.182387 +v 0.183991 -1.252481 0.182387 +v -0.630985 -0.981984 -0.182387 +v -0.667254 -0.954468 0.182387 +v 0.184003 -1.252481 -0.182387 +v 0.184003 -1.252481 0.182387 +v -0.592977 -1.006257 -0.182387 +v -0.630985 -0.981984 0.182387 +v 0.187874 -1.252534 -0.182387 +v 0.187874 -1.252534 0.182387 +v -0.553243 -1.027292 -0.182387 +v -0.592977 -1.006257 0.182387 +v 0.191482 -1.252676 -0.182387 +v 0.191482 -1.252676 0.182387 +v -0.511795 -1.045095 -0.182387 +v -0.553243 -1.027292 0.182387 +v 0.194921 -1.252880 -0.182387 +v 0.194921 -1.252880 0.182387 +v -0.468646 -1.059673 -0.182387 +v -0.511795 -1.045095 0.182387 +v 0.198291 -1.253120 -0.182387 +v 0.198291 -1.253120 0.182387 +v -0.423807 -1.071030 -0.182387 +v -0.468646 -1.059673 0.182387 +v 0.201688 -1.253370 -0.182387 +v 0.201688 -1.253370 0.182387 +v -0.413388 -1.117919 -0.182387 +v -0.423807 -1.071030 0.182387 +v 0.205209 -1.253603 -0.182387 +v 0.205209 -1.253603 0.182387 +v -0.402043 -1.162206 -0.182387 +v -0.413388 -1.117919 0.182387 +v 0.208952 -1.253793 -0.182387 +v 0.208952 -1.253793 0.182387 +v -0.389771 -1.203891 -0.182387 +v -0.402043 -1.162206 0.182387 +v 0.213012 -1.253913 -0.182387 +v 0.213012 -1.253913 0.182387 +v -0.376574 -1.242972 -0.182387 +v -0.389771 -1.203891 0.182387 +v 0.217488 -1.253938 -0.182387 +v 0.217488 -1.253938 0.182387 +v -0.362454 -1.279447 -0.182387 +v -0.376574 -1.242972 0.182387 +v 0.222476 -1.253840 -0.182387 +v 0.222476 -1.253840 0.182387 +v -0.347411 -1.313315 -0.182387 +v -0.362454 -1.279447 0.182387 +v 0.228073 -1.253593 -0.182387 +v 0.228073 -1.253593 0.182387 +v -0.331446 -1.344574 -0.182387 +v -0.347411 -1.313315 0.182387 +v 0.234377 -1.253171 -0.182387 +v 0.234377 -1.253171 0.182387 +v -0.314560 -1.373223 -0.182387 +v -0.331446 -1.344574 0.182387 +v 0.234377 -1.515692 -0.182387 +v 0.234377 -1.515692 0.182387 +v -0.296754 -1.399261 -0.182387 +v -0.314560 -1.373223 0.182387 +v 0.223663 -1.517095 -0.182387 +v 0.223663 -1.517095 0.182387 +v -0.278030 -1.422685 -0.182387 +v -0.296754 -1.399261 0.182387 +v 0.211706 -1.518660 -0.182387 +v 0.211706 -1.518660 0.182387 +v -0.258387 -1.443494 -0.182387 +v -0.278030 -1.422685 0.182387 +v 0.198920 -1.520334 -0.182387 +v 0.198920 -1.520334 0.182387 +v -0.237828 -1.461687 -0.182387 +v -0.258387 -1.443494 0.182387 +v 0.185719 -1.522063 -0.182387 +v 0.185719 -1.522063 0.182387 +v -0.221488 -1.473931 -0.182387 +v -0.237828 -1.461687 0.182387 +v 0.172517 -1.523791 -0.182387 +v 0.172517 -1.523791 0.182387 +v -0.204283 -1.485104 -0.182387 +v -0.221488 -1.473931 0.182387 +v 0.159731 -1.525465 -0.182387 +v 0.159731 -1.525465 0.182387 +v -0.186216 -1.495208 -0.182387 +v -0.204283 -1.485104 0.182387 +v 0.147774 -1.527030 -0.182387 +v 0.147774 -1.527030 0.182387 +v -0.167291 -1.504244 -0.182387 +v -0.186216 -1.495208 0.182387 +v 0.137061 -1.528433 -0.182387 +v 0.137061 -1.528433 0.182387 +v -0.147509 -1.512212 -0.182387 +v -0.167291 -1.504244 0.182387 +v 0.128007 -1.529619 -0.182387 +v 0.128007 -1.529619 0.182387 +v -0.126874 -1.519115 -0.182387 +v -0.147509 -1.512212 0.182387 +v 0.121026 -1.530532 -0.182387 +v 0.121026 -1.530532 0.182387 +v -0.105388 -1.524953 -0.182387 +v -0.126874 -1.519115 0.182387 +v 0.116533 -1.531121 -0.182387 +v 0.116533 -1.531121 0.182387 +v -0.083055 -1.529726 -0.182387 +v -0.105388 -1.524953 0.182387 +v 0.114944 -1.531329 -0.182387 +v 0.114944 -1.531329 0.182387 +v -0.059876 -1.533437 -0.182388 +v -0.083055 -1.529726 0.182387 +v 0.106191 -1.532421 -0.182388 +v 0.106191 -1.532421 0.182386 +v -0.035856 -1.536087 -0.182388 +v -0.059876 -1.533437 0.182386 +v 0.097506 -1.533419 -0.182388 +v 0.097506 -1.533419 0.182386 +v -0.010996 -1.537676 -0.182388 +v -0.035856 -1.536087 0.182386 +v 0.088889 -1.534324 -0.182388 +v 0.088889 -1.534324 0.182386 +v 0.014699 -1.538205 -0.182388 +v -0.010996 -1.537676 0.182386 +v 0.080342 -1.535135 -0.182388 +v 0.080342 -1.535135 0.182386 +v 0.022624 -1.538157 -0.182388 +v 0.014699 -1.538205 0.182386 +v 0.071868 -1.535852 -0.182388 +v 0.071868 -1.535852 0.182386 +v 0.030633 -1.538012 -0.182388 +v 0.022624 -1.538157 0.182386 +v 0.063467 -1.536474 -0.182388 +v 0.063467 -1.536474 0.182386 +v 0.038723 -1.537771 -0.182388 +v 0.030633 -1.538012 0.182386 +v 0.055141 -1.537002 -0.182388 +v 0.055141 -1.537002 0.182386 +v 0.046893 -1.537434 -0.182388 +v 0.038723 -1.537771 0.182386 +v 0.046893 -1.537434 0.182386 +v 0.069721 0.127787 -0.182387 +v -0.507111 0.055574 -0.182387 +v -0.507627 0.137615 -0.182387 +v 0.030318 -0.471963 0.182387 +v -0.465641 -0.453883 0.182387 +v -0.455769 -0.499161 0.182387 +v -0.273302 0.974642 -0.182387 +v -0.292921 0.969356 -0.182387 +v -0.292921 0.969356 0.182387 +v -0.252844 0.977813 -0.182387 +v -0.273302 0.974642 0.182387 +v -0.311702 0.961955 -0.182387 +v -0.311702 0.961955 0.182387 +v -0.231547 0.978869 -0.182387 +v -0.252844 0.977813 0.182387 +v -0.329644 0.952436 -0.182387 +v -0.329644 0.952436 0.182387 +v -0.229829 0.978862 -0.182387 +v -0.231547 0.978869 0.182387 +v -0.346747 0.940799 -0.182387 +v -0.346747 0.940799 0.182387 +v -0.228101 0.978840 -0.182387 +v -0.229829 0.978862 0.182387 +v -0.363012 0.927042 -0.182387 +v -0.363012 0.927042 0.182387 +v -0.226363 0.978804 -0.182387 +v -0.228101 0.978840 0.182387 +v -0.378438 0.911165 -0.182387 +v -0.378438 0.911165 0.182387 +v -0.224615 0.978755 -0.182387 +v -0.226363 0.978804 0.182387 +v -0.393025 0.893167 -0.182387 +v -0.393025 0.893167 0.182387 +v -0.222860 0.978691 -0.182387 +v -0.224615 0.978755 0.182387 +v -0.406773 0.873046 -0.182387 +v -0.406773 0.873046 0.182387 +v -0.221097 0.978614 -0.182387 +v -0.222860 0.978691 0.182387 +v -0.419682 0.850800 -0.182387 +v -0.419682 0.850800 0.182387 +v -0.219327 0.978523 -0.182387 +v -0.221097 0.978614 0.182387 +v -0.431753 0.826431 -0.182387 +v -0.431753 0.826431 0.182387 +v -0.217552 0.978418 -0.182387 +v -0.219327 0.978523 0.182387 +v -0.443828 0.796221 -0.182387 +v -0.443828 0.796221 0.182387 +v -0.215772 0.978299 -0.182387 +v -0.217552 0.978418 0.182387 +v -0.454864 0.761058 -0.182387 +v -0.454864 0.761058 0.182387 +v -0.213988 0.978168 -0.182387 +v -0.215772 0.978299 0.182387 +v -0.464860 0.720945 -0.182387 +v -0.464860 0.720945 0.182387 +v -0.212200 0.978023 -0.182387 +v -0.213988 0.978168 0.182387 +v -0.473812 0.675884 -0.182387 +v -0.473812 0.675884 0.182387 +v -0.210411 0.977865 -0.182387 +v -0.212200 0.978023 0.182387 +v -0.481720 0.625878 -0.182387 +v -0.481720 0.625878 0.182387 +v -0.187470 0.974624 -0.182387 +v -0.210411 0.977865 0.182387 +v -0.488580 0.570931 -0.182387 +v -0.488580 0.570931 0.182387 +v -0.165518 0.969019 -0.182387 +v -0.187470 0.974624 0.182387 +v -0.494391 0.511044 -0.182387 +v -0.494391 0.511044 0.182387 +v -0.144552 0.961056 -0.182387 +v -0.165518 0.969019 0.182387 +v -0.499150 0.446221 -0.182387 +v -0.499150 0.446221 0.182387 +v -0.124571 0.950738 -0.182387 +v -0.144552 0.961056 0.182387 +v -0.502855 0.376463 -0.182387 +v -0.502855 0.376463 0.182387 +v -0.105573 0.938070 -0.182387 +v -0.124571 0.950738 0.182387 +v -0.505505 0.301775 -0.182387 +v -0.505505 0.301775 0.182387 +v -0.087555 0.923059 -0.182387 +v -0.105573 0.938070 0.182387 +v -0.507096 0.222158 -0.182387 +v -0.507096 0.222158 0.182387 +v -0.070516 0.905708 -0.182387 +v -0.087555 0.923059 0.182387 +v -0.507627 0.137615 0.182387 +v -0.054454 0.886023 -0.182387 +v -0.070516 0.905708 0.182387 +v -0.507111 0.055574 0.182387 +v -0.039367 0.864009 -0.182387 +v -0.054454 0.886023 0.182387 +v -0.505560 -0.022395 -0.182387 +v -0.505560 -0.022395 0.182387 +v -0.025253 0.839671 -0.182387 +v -0.039367 0.864009 0.182387 +v -0.502975 -0.096287 -0.182387 +v -0.502975 -0.096287 0.182387 +v -0.012110 0.813014 -0.182387 +v -0.025253 0.839671 0.182387 +v -0.499352 -0.166100 -0.182387 +v -0.499352 -0.166100 0.182387 +v 0.000065 0.784043 -0.182387 +v -0.012110 0.813014 0.182387 +v -0.494692 -0.231832 -0.182387 +v -0.494692 -0.231832 0.182387 +v 0.011252 0.752004 -0.182387 +v 0.000065 0.784043 0.182387 +v -0.488992 -0.293479 -0.182387 +v -0.488992 -0.293479 0.182387 +v 0.021450 0.715855 -0.182387 +v 0.011252 0.752004 0.182387 +v -0.482251 -0.351039 -0.182387 +v -0.482251 -0.351039 0.182387 +v 0.030663 0.675595 -0.182387 +v 0.021450 0.715855 0.182387 +v -0.474468 -0.404507 -0.182387 +v -0.474468 -0.404507 0.182387 +v 0.038893 0.631220 -0.182387 +v 0.030663 0.675595 0.182387 +v -0.465641 -0.453883 -0.182387 +v 0.046143 0.582729 -0.182387 +v 0.038893 0.631220 0.182387 +v -0.455769 -0.499161 -0.182387 +v 0.052417 0.530117 -0.182387 +v 0.046143 0.582729 0.182387 +v -0.444850 -0.540341 -0.182387 +v -0.444850 -0.540341 0.182387 +v 0.057717 0.473383 -0.182387 +v 0.052417 0.530117 0.182387 +v -0.432883 -0.577418 -0.182387 +v -0.432883 -0.577418 0.182387 +v 0.062046 0.412525 -0.182387 +v 0.057717 0.473383 0.182387 +v -0.420633 -0.609377 -0.182387 +v -0.420633 -0.609377 0.182387 +v 0.065408 0.347538 -0.182387 +v 0.062046 0.412525 0.182387 +v -0.407408 -0.638535 -0.182387 +v -0.407408 -0.638535 0.182387 +v 0.067806 0.278422 -0.182387 +v 0.065408 0.347538 0.182387 +v -0.393214 -0.664896 -0.182387 +v -0.393214 -0.664896 0.182387 +v 0.069243 0.205172 -0.182387 +v 0.067806 0.278422 0.182387 +v -0.378055 -0.688465 -0.182387 +v -0.378055 -0.688465 0.182387 +v 0.069243 0.205172 0.182387 +v -0.361938 -0.709246 -0.182387 +v -0.361938 -0.709246 0.182387 +v 0.069238 0.041715 -0.182387 +v 0.069721 0.127787 0.182387 +v -0.344867 -0.727242 -0.182387 +v -0.344867 -0.727242 0.182387 +v 0.067786 -0.039494 -0.182387 +v 0.069238 0.041715 0.182387 +v -0.326849 -0.742459 -0.182387 +v -0.326849 -0.742459 0.182387 +v 0.065364 -0.115843 -0.182387 +v 0.067786 -0.039494 0.182387 +v -0.307887 -0.754899 -0.182387 +v -0.307887 -0.754899 0.182387 +v 0.061970 -0.187334 -0.182387 +v 0.065364 -0.115843 0.182387 +v -0.287989 -0.764568 -0.182387 +v -0.287989 -0.764568 0.182387 +v 0.057600 -0.253967 -0.182387 +v 0.061970 -0.187334 0.182387 +v -0.267158 -0.771469 -0.182387 +v -0.267158 -0.771469 0.182387 +v 0.052252 -0.315745 -0.182387 +v 0.057600 -0.253967 0.182387 +v -0.245400 -0.775607 -0.182387 +v -0.245400 -0.775607 0.182387 +v 0.045924 -0.372668 -0.182387 +v 0.052252 -0.315745 0.182387 +v -0.222722 -0.776985 -0.182387 +v -0.222722 -0.776985 0.182387 +v 0.038614 -0.424741 -0.182387 +v 0.045924 -0.372668 0.182387 +v -0.221695 -0.776981 -0.182387 +v -0.221695 -0.776981 0.182387 +v 0.030318 -0.471963 -0.182387 +v 0.038614 -0.424741 0.182387 +v -0.220669 -0.776970 -0.182387 +v -0.220669 -0.776970 0.182387 +v 0.021036 -0.514336 -0.182387 +v -0.219646 -0.776952 -0.182387 +v -0.219646 -0.776952 0.182387 +v 0.010764 -0.551863 -0.182387 +v 0.021036 -0.514336 0.182387 +v -0.218623 -0.776927 -0.182387 +v -0.218623 -0.776927 0.182387 +v -0.000501 -0.584545 -0.182387 +v 0.010764 -0.551863 0.182387 +v -0.217601 -0.776896 -0.182387 +v -0.217601 -0.776896 0.182387 +v -0.012809 -0.613863 -0.182387 +v -0.000501 -0.584545 0.182387 +v -0.216578 -0.776860 -0.182387 +v -0.216578 -0.776860 0.182387 +v -0.026056 -0.640763 -0.182387 +v -0.012809 -0.613863 0.182387 +v -0.215555 -0.776818 -0.182387 +v -0.215555 -0.776818 0.182387 +v -0.040242 -0.665243 -0.182387 +v -0.026056 -0.640763 0.182387 +v -0.214531 -0.776771 -0.182387 +v -0.214531 -0.776771 0.182387 +v -0.055369 -0.687302 -0.182387 +v -0.040242 -0.665243 0.182387 +v -0.213505 -0.776720 -0.182387 +v -0.213505 -0.776720 0.182387 +v -0.071438 -0.706941 -0.182387 +v -0.055369 -0.687302 0.182387 +v -0.212477 -0.776665 -0.182387 +v -0.212477 -0.776665 0.182387 +v -0.088450 -0.724158 -0.182387 +v -0.071438 -0.706941 0.182387 +v -0.211446 -0.776607 -0.182387 +v -0.211446 -0.776607 0.182387 +v -0.106407 -0.738952 -0.182387 +v -0.088450 -0.724158 0.182387 +v -0.210411 -0.776546 -0.182387 +v -0.210411 -0.776546 0.182387 +v -0.125311 -0.751321 -0.182387 +v -0.106407 -0.738952 0.182387 +v -0.187710 -0.773880 -0.182387 +v -0.187710 -0.773880 0.182387 +v -0.145162 -0.761267 -0.182387 +v -0.125311 -0.751321 0.182387 +v -0.165961 -0.768786 -0.182387 +v -0.165961 -0.768786 0.182387 +v -0.145162 -0.761267 0.182387 +v -0.836574 2.034443 -0.182386 +v -1.543393 -1.434298 -0.182387 +v -1.543393 -1.802300 -0.182388 +v -1.543393 -2.132013 -0.182388 +v -1.543393 1.356561 -0.182387 +v -1.543393 1.141716 -0.182387 +v -1.543393 0.863055 -0.182387 +v -1.543393 0.533343 -0.182387 +v -1.543393 0.165341 -0.182387 +v -0.683363 2.009288 -0.182386 +v -0.484644 1.976661 -0.182386 +v -0.249518 1.938057 -0.182386 +v 0.012913 1.894969 -0.182386 +v 0.293547 1.848894 -0.182386 +v 1.153652 1.707676 -0.182386 +v 1.416083 1.664589 -0.182386 +v 1.651209 1.378124 -0.182387 +v 1.651209 1.625984 -0.182386 +v 1.651209 1.101481 -0.182387 +v 0.293547 1.848894 0.182388 +v -0.683363 2.009288 0.182388 +v -0.484644 1.976661 0.182388 +v -0.249518 1.938057 0.182388 +v 0.012913 1.894969 0.182388 +v 0.873018 1.753752 0.182388 +v 1.153652 1.707676 0.182388 +v 1.416083 1.664589 0.182388 +v 1.651209 1.378124 0.182387 +v 1.651209 1.625984 0.182388 +v 1.651209 1.101481 0.182387 +v -1.543393 -1.434298 0.182387 +v -1.543393 -1.802300 0.182386 +v -1.543393 1.356561 0.182387 +v -1.543393 1.141716 0.182387 +v -1.543393 0.863055 0.182387 +v -1.543393 -0.634479 0.182387 +v -1.543393 0.533343 0.182387 +v -1.543393 -0.228187 0.182387 +v 1.651209 -0.835023 -0.182387 +v 1.651209 -0.625542 -0.182387 +v 1.651209 0.805648 -0.182387 +v 1.651209 0.194794 -0.182387 +v 1.651209 -0.101039 -0.182387 +v 1.651209 -0.377682 -0.182387 +v 1.651209 -0.101039 0.182387 +v 1.651209 -0.625542 0.182387 +v 1.651209 0.194794 0.182387 +v 1.651209 -0.377682 0.182387 +vn 0.943300 -0.332000 0.000000 +vn 0.906700 -0.421700 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.970600 -0.240500 0.000000 +vn -0.000000 -0.000000 1.000000 +vn 0.860000 -0.510200 0.000000 +vn 0.050100 -0.998700 -0.000000 +vn 0.045400 -0.999000 -0.000000 +vn 0.045700 -0.999000 -0.000000 +vn 0.039800 -0.999200 -0.000000 +vn 0.040000 -0.999200 -0.000000 +vn 0.032900 -0.999500 -0.000000 +vn 0.033000 -0.999500 0.000000 +vn 0.032600 -0.999500 -0.000000 +vn 0.025300 -0.999700 -0.000000 +vn 0.025600 -0.999700 -0.000000 +vn 0.018200 -0.999800 -0.000000 +vn 0.018000 -0.999800 -0.000000 +vn 0.010500 -0.999900 -0.000000 +vn 0.010400 -0.999900 -0.000000 +vn 0.003300 -1.000000 -0.000000 +vn 0.003200 -1.000000 -0.000000 +vn -0.027200 -0.999600 -0.000000 +vn -0.086700 -0.996200 -0.000000 +vn -0.152500 -0.988300 -0.000000 +vn -0.224600 -0.974500 -0.000000 +vn -0.301200 -0.953600 -0.000000 +vn -0.380700 -0.924700 -0.000000 +vn -0.460400 -0.887700 -0.000000 +vn -0.537400 -0.843300 -0.000000 +vn -0.609300 -0.793000 -0.000000 +vn -0.674100 -0.738700 -0.000000 +vn -0.730400 -0.683100 -0.000000 +vn -0.730400 -0.683000 -0.000000 +vn -0.778100 -0.628200 -0.000000 +vn -0.836100 -0.548600 -0.000000 +vn -0.836000 -0.548700 -0.000000 +vn -0.899000 -0.437900 -0.000000 +vn -0.938800 -0.344400 -0.000000 +vn -0.963600 -0.267500 -0.000000 +vn -0.978700 -0.205500 -0.000000 +vn -0.987800 -0.155500 -0.000000 +vn -0.993300 -0.115400 -0.000000 +vn -0.996500 -0.083100 -0.000000 +vn -0.998400 -0.056900 -0.000000 +vn -0.999400 -0.036000 -0.000000 +vn -0.999800 -0.019100 -0.000000 +vn -1.000000 -0.005700 -0.000000 +vn -1.000000 0.000000 0.000000 +vn 0.049600 0.998800 0.000000 +vn -0.076200 -0.997100 -0.000000 +vn -0.105200 -0.994400 0.000000 +vn 0.973500 -0.228800 -0.000000 +vn -0.071500 -0.997400 -0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.052500 0.998600 0.000000 +vn 0.999800 0.021400 0.000000 +vn 0.997800 0.066100 0.000000 +vn 0.993500 0.113400 0.000000 +vn 0.986600 0.163300 0.000000 +vn 0.976400 0.215800 0.000000 +vn 0.962600 0.270800 0.000000 +vn 0.944600 0.328200 0.000000 +vn 0.921800 0.387700 0.000000 +vn 0.893600 0.448900 0.000000 +vn 0.859500 0.511100 0.000000 +vn 0.819000 0.573800 0.000000 +vn 0.771800 0.635800 0.000000 +vn 0.718300 0.695700 0.000000 +vn 0.656000 0.754800 0.000000 +vn 0.589800 0.807500 0.000000 +vn 0.521500 0.853200 0.000000 +vn 0.452300 0.891800 0.000000 +vn 0.383700 0.923500 0.000000 +vn 0.316500 0.948600 0.000000 +vn 0.251800 0.967800 0.000000 +vn 0.190000 0.981800 0.000000 +vn 0.131400 0.991300 0.000000 +vn 0.076300 0.997100 0.000000 +vn 0.024600 0.999700 0.000000 +vn 0.998800 -0.049500 0.000000 +vn 0.989200 -0.146500 0.000000 +vn 0.801600 -0.597800 0.000000 +vn 0.729300 -0.684200 0.000000 +vn 0.640300 -0.768100 0.000000 +vn 0.532100 -0.846700 0.000000 +vn 0.402500 -0.915400 0.000000 +vn 0.252300 -0.967700 0.000000 +vn 0.166000 -0.986100 0.000000 +vn -0.997800 0.065600 0.000000 +vn -0.979900 0.199400 0.000000 +vn -0.943000 0.332900 0.000000 +vn -0.886600 0.462600 0.000000 +vn -0.811000 0.585000 0.000000 +vn -0.717300 0.696700 0.000000 +vn -0.607000 0.794700 0.000000 +vn -0.482300 0.876000 0.000000 +vn -0.346000 0.938200 0.000000 +vn -0.201900 0.979400 0.000000 +vn -0.054400 0.998500 0.000000 +vn 0.091800 0.995800 0.000000 +vn 0.162000 0.986800 0.000000 +vn 0.440300 -0.897900 -0.000000 +vn 0.407000 -0.913400 -0.000000 +vn 0.406900 -0.913500 -0.000000 +vn 0.374200 -0.927400 -0.000000 +vn 0.342200 -0.939600 -0.000000 +vn 0.310600 -0.950500 -0.000000 +vn 0.279100 -0.960300 -0.000000 +vn 0.247600 -0.968900 -0.000000 +vn 0.215700 -0.976500 -0.000000 +vn 0.183200 -0.983100 -0.000000 +vn 0.149500 -0.988800 -0.000000 +vn 0.114600 -0.993400 -0.000000 +vn 0.077600 -0.997000 -0.000000 +vn 0.056300 -0.998400 -0.000000 +vn 0.055900 -0.998400 -0.000000 +vn 0.056200 -0.998400 -0.000000 +vn 0.056000 -0.998400 -0.000000 +vn 0.055800 -0.998400 -0.000000 +vn 0.053300 -0.998600 -0.000000 +vn 0.053700 -0.998600 -0.000000 +vn -0.003900 1.000000 0.000000 +vn -0.052900 0.998600 0.000000 +vn -0.059200 0.998200 0.000000 +vn -0.065600 0.997800 0.000000 +vn -0.071800 0.997400 0.000000 +vn -0.077600 0.997000 0.000000 +vn -0.100200 0.995000 0.000000 +vn -0.130800 0.991400 0.000000 +vn -0.160800 0.987000 0.000000 +vn -0.190200 0.981800 0.000000 +vn -0.218500 0.975800 0.000000 +vn -0.245800 0.969300 0.000000 +vn -0.271800 0.962400 0.000000 +vn -0.296400 0.955100 0.000000 +vn -0.319600 0.947600 0.000000 +vn -0.341200 0.940000 0.000000 +vn -0.361400 0.932400 0.000000 +vn -0.380100 0.925000 0.000000 +vn -0.011500 0.999900 0.000000 +vn -0.018800 0.999800 0.000000 +vn -0.026200 0.999700 0.000000 +vn -0.032900 0.999500 0.000000 +vn -0.039800 0.999200 0.000000 +vn -0.046700 0.998900 0.000000 +vn -0.970800 0.239800 0.000000 +vn -0.979100 0.203200 0.000000 +vn -0.960200 0.279200 0.000000 +vn -0.985600 0.169100 0.000000 +vn -0.947000 0.321200 0.000000 +vn -0.990500 0.137400 0.000000 +vn -0.930600 0.365900 0.000000 +vn -0.994100 0.108100 0.000000 +vn -0.994100 0.108000 0.000000 +vn -0.910000 0.414700 0.000000 +vn -0.996700 0.080800 0.000000 +vn -0.885200 0.465200 0.000000 +vn -0.998500 0.055500 0.000000 +vn -0.855600 0.517600 0.000000 +vn -0.999500 0.032100 0.000000 +vn -0.820700 0.571300 0.000000 +vn -0.999900 0.010300 0.000000 +vn -0.780100 0.625700 0.000000 +vn -0.999900 -0.012900 -0.000000 +vn -0.733600 0.679600 0.000000 +vn -0.999200 -0.040200 -0.000000 +vn -0.681300 0.732000 0.000000 +vn -0.997600 -0.070000 -0.000000 +vn -0.623800 0.781600 0.000000 +vn -0.994800 -0.102300 -0.000000 +vn -0.561500 0.827500 0.000000 +vn -0.990500 -0.137400 -0.000000 +vn -0.495700 0.868500 0.000000 +vn -0.984500 -0.175600 -0.000000 +vn -0.427500 0.904000 0.000000 +vn -0.976200 -0.216900 -0.000000 +vn -0.358300 0.933600 0.000000 +vn -0.965200 -0.261500 -0.000000 +vn -0.978800 -0.204700 0.000000 +vn -0.950900 -0.309500 -0.000000 +vn -0.972500 -0.233000 0.000000 +vn -0.932700 -0.360700 -0.000000 +vn -0.964500 -0.264100 0.000000 +vn -0.909800 -0.415100 -0.000000 +vn -0.954500 -0.298200 0.000000 +vn -0.881600 -0.472000 -0.000000 +vn -0.941900 -0.335900 0.000000 +vn -0.848000 -0.530000 -0.000000 +vn -0.926100 -0.377300 0.000000 +vn -0.806700 -0.591000 0.000000 +vn -0.906200 -0.422900 0.000000 +vn -0.758500 -0.651700 0.000000 +vn -0.881300 -0.472600 0.000000 +vn -0.703400 -0.710800 0.000000 +vn -0.850100 -0.526600 0.000000 +vn -0.642000 -0.766700 0.000000 +vn -0.811200 -0.584800 0.000000 +vn -0.575300 -0.817900 0.000000 +vn -0.763300 -0.646100 0.000000 +vn -0.504600 -0.863400 0.000000 +vn -0.704700 -0.709500 0.000000 +vn -0.431400 -0.902100 0.000000 +vn -0.641700 -0.766900 0.000000 +vn -0.357600 -0.933900 0.000000 +vn -0.591700 -0.806100 0.000000 +vn -0.284700 -0.958600 0.000000 +vn -0.541500 -0.840700 0.000000 +vn -0.213900 -0.976900 0.000000 +vn -0.491700 -0.870800 0.000000 +vn -0.146500 -0.989200 0.000000 +vn -0.442800 -0.896600 0.000000 +vn -0.111600 -0.993800 0.000000 +vn -0.395500 -0.918400 0.000000 +vn -0.102400 -0.994700 0.000000 +vn -0.350100 -0.936700 0.000000 +vn -0.093100 -0.995700 0.000000 +vn -0.306700 -0.951800 0.000000 +vn -0.083800 -0.996500 0.000000 +vn -0.265700 -0.964100 0.000000 +vn -0.074300 -0.997200 0.000000 +vn -0.227100 -0.973900 0.000000 +vn -0.064800 -0.997900 0.000000 +vn -0.190700 -0.981700 0.000000 +vn -0.055000 -0.998500 0.000000 +vn -0.156800 -0.987600 0.000000 +vn -0.045300 -0.999000 0.000000 +vn -0.131500 -0.991300 0.000000 +vn -0.035400 -0.999400 0.000000 +vn -0.042200 -0.999100 -0.000000 +vn -0.025300 -0.999700 0.000000 +vn -0.025600 -0.999700 0.000000 +vn 0.029300 -0.999600 0.000000 +vn 0.028300 -0.999600 0.000000 +vn -0.015300 -0.999900 0.000000 +vn 0.080200 -0.996800 0.000000 +vn 0.079700 -0.996800 0.000000 +vn 0.078300 -0.996900 -0.000000 +vn -0.005100 -1.000000 0.000000 +vn 0.117200 -0.993100 0.000000 +vn 0.116100 -0.993200 -0.000000 +vn 0.033100 -0.999500 0.000000 +vn 0.132600 -0.991200 0.000000 +vn 0.131700 -0.991300 -0.000000 +vn 0.132200 -0.991200 -0.000000 +vn 0.102600 -0.994700 0.000000 +vn 0.132400 -0.991200 0.000000 +vn 0.175900 -0.984400 0.000000 +vn 0.113400 -0.993600 -0.000000 +vn 0.252000 -0.967700 0.000000 +vn 0.077300 -0.997000 0.000000 +vn 0.078200 -0.996900 -0.000000 +vn 0.329800 -0.944000 0.000000 +vn 0.024500 -0.999700 -0.000000 +vn 0.407700 -0.913100 0.000000 +vn -0.040400 -0.999200 0.000000 +vn -0.039500 -0.999200 0.000000 +vn 0.483900 -0.875100 0.000000 +vn -0.119400 -0.992800 0.000000 +vn -0.119000 -0.992900 0.000000 +vn -0.121100 -0.992600 -0.000000 +vn 0.556800 -0.830600 0.000000 +vn -0.091600 -0.995800 0.000000 +vn -0.091900 -0.995800 -0.000000 +vn -0.091400 -0.995800 0.000000 +vn 0.624900 -0.780700 0.000000 +vn -0.013600 -0.999900 0.000000 +vn -0.014200 -0.999900 0.000000 +vn 0.687100 -0.726600 0.000000 +vn 0.048300 -0.998800 0.000000 +vn 0.048600 -0.998800 0.000000 +vn 0.742600 -0.669800 0.000000 +vn 0.093400 -0.995600 0.000000 +vn 0.093200 -0.995600 0.000000 +vn 0.093000 -0.995700 -0.000000 +vn 0.791100 -0.611700 0.000000 +vn 0.123300 -0.992400 0.000000 +vn 0.123100 -0.992400 0.000000 +vn 0.835900 -0.548800 -0.000000 +vn 0.138600 -0.990300 0.000000 +vn 0.138400 -0.990400 -0.000000 +vn 0.876200 -0.481900 -0.000000 +vn 0.141400 -0.990000 0.000000 +vn 0.141700 -0.989900 -0.000000 +vn 0.908600 -0.417800 -0.000000 +vn 0.131000 -0.991400 0.000000 +vn 0.131200 -0.991400 -0.000000 +vn 0.131400 -0.991300 0.000000 +vn 0.934000 -0.357300 -0.000000 +vn 0.106100 -0.994400 0.000000 +vn 0.106300 -0.994300 0.000000 +vn 0.106000 -0.994400 -0.000000 +vn 0.953700 -0.300900 -0.000000 +vn 0.067200 -0.997700 0.000000 +vn 0.067100 -0.997700 -0.000000 +vn 0.066800 -0.997800 0.000000 +vn 0.968600 -0.248700 -0.000000 +vn 0.011700 -0.999900 0.000000 +vn 0.012000 -0.999900 0.000000 +vn 0.012100 -0.999900 -0.000000 +vn 0.979700 -0.200700 -0.000000 +vn -0.060700 -0.998200 0.000000 +vn -0.060300 -0.998200 -0.000000 +vn 0.987700 -0.156600 -0.000000 +vn -0.091500 -0.995800 0.000000 +vn 0.993200 -0.116300 -0.000000 +vn -0.061700 -0.998100 0.000000 +vn 0.996800 -0.079300 -0.000000 +vn -0.035800 -0.999400 0.000000 +vn 0.999000 -0.045500 -0.000000 +vn -0.015000 -0.999900 0.000000 +vn 0.999900 -0.014500 -0.000000 +vn 0.001600 -1.000000 0.000000 +vn 0.999900 0.011400 0.000000 +vn 0.014100 -0.999900 0.000000 +vn 0.999400 0.035600 0.000000 +vn 0.022500 -0.999700 0.000000 +vn 0.998100 0.061800 0.000000 +vn 0.026900 -0.999600 0.000000 +vn 0.027100 -0.999600 0.000000 +vn 0.995900 0.090200 0.000000 +vn 0.027000 -0.999600 -0.000000 +vn 0.027300 -0.999600 0.000000 +vn 0.992700 0.120900 0.000000 +vn 0.023800 -0.999700 0.000000 +vn 0.988000 0.154300 0.000000 +vn 0.016900 -0.999900 0.000000 +vn 0.981700 0.190600 0.000000 +vn 0.006800 -1.000000 0.000000 +vn 0.006400 -1.000000 0.000000 +vn 0.973200 0.230000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.962100 0.272900 0.000000 +vn 0.947700 0.319200 0.000000 +vn 0.929400 0.369200 0.000000 +vn 0.906200 0.422900 0.000000 +vn 0.878800 0.477200 0.000000 +vn 0.848000 0.530000 0.000000 +vn 0.811600 0.584200 0.000000 +vn 0.769100 0.639100 0.000000 +vn 0.720400 0.693600 0.000000 +vn 0.665400 0.746500 0.000000 +vn 0.604400 0.796700 0.000000 +vn 0.538200 0.842800 0.000000 +vn -0.013700 -0.999900 0.000000 +vn 0.467900 0.883800 0.000000 +vn -0.039300 -0.999200 0.000000 +vn 0.394700 0.918800 0.000000 +vn -0.059200 -0.998200 0.000000 +vn 0.320100 0.947400 0.000000 +vn -0.071000 -0.997500 0.000000 +vn 0.245500 0.969400 0.000000 +vn -0.073400 -0.997300 0.000000 +vn 0.976200 0.216900 0.000000 +vn -0.066000 -0.997800 0.000000 +vn 0.968700 0.248200 0.000000 +vn -0.050700 -0.998700 0.000000 +vn 0.959300 0.282400 0.000000 +vn -0.029600 -0.999600 0.000000 +vn 0.947400 0.319900 0.000000 +vn -0.005600 -1.000000 0.000000 +vn 0.932600 0.361000 0.000000 +vn 0.019600 -0.999800 0.000000 +vn 0.913900 0.405900 0.000000 +vn 0.044100 -0.999000 0.000000 +vn 0.890600 0.454800 0.000000 +vn 0.861500 0.507800 0.000000 +vn 0.825400 0.564500 0.000000 +vn -0.129800 0.991500 0.000000 +vn 0.781100 0.624400 0.000000 +vn 0.727200 0.686400 0.000000 +vn 0.662700 0.748900 0.000000 +vn 0.599700 0.800300 0.000000 +vn 0.544600 0.838700 0.000000 +vn 0.488100 0.872800 0.000000 +vn 0.430900 0.902400 0.000000 +vn -0.129900 0.991500 0.000000 +vn 0.373600 0.927600 0.000000 +vn 0.317200 0.948300 0.000000 +vn 0.262200 0.965000 0.000000 +vn 0.209000 0.977900 0.000000 +vn 0.158100 0.987400 0.000000 +vn -0.123800 0.992300 0.000000 +vn 0.109700 0.994000 0.000000 +vn -0.114200 0.993500 0.000000 +vn 0.063800 0.998000 0.000000 +vn -0.104500 0.994500 0.000000 +vn 0.020600 0.999800 0.000000 +vn -0.094500 0.995500 0.000000 +vn -0.006100 1.000000 0.000000 +vn -0.084300 0.996400 0.000000 +vn -0.018100 0.999800 0.000000 +vn -0.073800 0.997300 0.000000 +vn -0.029800 0.999600 0.000000 +vn -0.063300 0.998000 0.000000 +vn -0.041200 0.999200 0.000000 +vn -0.052300 0.998600 0.000000 +vn -0.260200 0.965600 0.000000 +vn -0.153200 0.988200 0.000000 +vn -0.366600 0.930400 0.000000 +vn -0.049500 0.998800 0.000000 +vn -0.468700 0.883400 0.000000 +vn 0.004100 1.000000 0.000000 +vn -0.562500 0.826800 0.000000 +vn 0.012700 0.999900 0.000000 +vn -0.645800 0.763500 0.000000 +vn 0.020700 0.999800 0.000000 +vn -0.717200 0.696800 0.000000 +vn 0.028000 0.999600 0.000000 +vn 0.028400 0.999600 0.000000 +vn -0.776900 0.629600 0.000000 +vn 0.036500 0.999300 0.000000 +vn -0.825700 0.564200 0.000000 +vn 0.044100 0.999000 0.000000 +vn -0.864900 0.501900 0.000000 +vn 0.051300 0.998700 0.000000 +vn -0.896100 0.443900 0.000000 +vn 0.059100 0.998300 0.000000 +vn -0.928600 0.371100 0.000000 +vn -0.928600 0.371200 0.000000 +vn 0.066400 0.997800 0.000000 +vn 0.066700 0.997800 0.000000 +vn -0.954100 0.299400 0.000000 +vn -0.954100 0.299500 0.000000 +vn 0.073600 0.997300 0.000000 +vn 0.073200 0.997300 0.000000 +vn -0.970300 0.241800 0.000000 +vn 0.080800 0.996700 0.000000 +vn -0.980800 0.194900 0.000000 +vn 0.088000 0.996100 0.000000 +vn -0.987700 0.156200 0.000000 +vn 0.139900 0.990200 0.000000 +vn -0.992300 0.123900 0.000000 +vn 0.247400 0.968900 0.000000 +vn -0.995300 0.096600 0.000000 +vn 0.355100 0.934800 0.000000 +vn -0.997300 0.073200 0.000000 +vn 0.458800 0.888500 0.000000 +vn -0.998600 0.053000 0.000000 +vn 0.554800 0.832000 0.000000 +vn -0.999400 0.035500 0.000000 +vn 0.640100 0.768300 0.000000 +vn -0.999800 0.020000 0.000000 +vn 0.713500 0.700700 0.000000 +vn -1.000000 0.006300 0.000000 +vn 0.774800 0.632200 0.000000 +vn -1.000000 -0.006300 -0.000000 +vn 0.824900 0.565300 0.000000 +vn -0.999800 -0.019900 -0.000000 +vn 0.865100 0.501700 0.000000 +vn -0.999400 -0.035000 -0.000000 +vn 0.896900 0.442200 0.000000 +vn -0.998700 -0.051800 -0.000000 +vn 0.921900 0.387400 0.000000 +vn -0.997500 -0.070700 -0.000000 +vn 0.944100 0.329700 0.000000 +vn -0.995800 -0.092100 -0.000000 +vn 0.962400 0.271500 0.000000 +vn -0.993200 -0.116300 -0.000000 +vn 0.974800 0.223100 0.000000 +vn -0.989600 -0.144000 -0.000000 +vn 0.983200 0.182400 0.000000 +vn -0.984400 -0.176000 -0.000000 +vn 0.989000 0.147900 0.000000 +vn -0.977000 -0.213000 -0.000000 +vn 0.993000 0.118400 0.000000 +vn -0.966600 -0.256300 -0.000000 +vn 0.995700 0.093000 0.000000 +vn -0.951700 -0.307200 -0.000000 +vn 0.997500 0.071000 0.000000 +vn -0.933800 -0.357900 -0.000000 +vn 0.998700 0.051700 0.000000 +vn -0.910700 -0.413100 -0.000000 +vn 0.999400 0.034700 0.000000 +vn -0.880500 -0.474100 -0.000000 +vn 0.999800 0.019600 0.000000 +vn -0.841100 -0.540900 -0.000000 +vn 1.000000 0.006200 0.000000 +vn -0.790200 -0.612800 -0.000000 +vn -0.790200 -0.612900 -0.000000 +vn 1.000000 -0.005600 -0.000000 +vn -0.725500 -0.688200 -0.000000 +vn 0.999800 -0.017900 -0.000000 +vn -0.645200 -0.764000 -0.000000 +vn 0.999500 -0.031700 -0.000000 +vn -0.548500 -0.836100 -0.000000 +vn 0.998900 -0.047400 -0.000000 +vn -0.437100 -0.899400 -0.000000 +vn 0.997900 -0.065400 -0.000000 +vn -0.314500 -0.949300 -0.000000 +vn 0.996300 -0.086200 -0.000000 +vn -0.186800 -0.982400 -0.000000 +vn 0.993900 -0.110500 -0.000000 +vn 0.990300 -0.139000 -0.000000 +vn 0.003900 -1.000000 -0.000000 +vn 0.984900 -0.173000 -0.000000 +vn 0.010700 -0.999900 -0.000000 +vn 0.976800 -0.214000 -0.000000 +vn 0.017900 -0.999800 -0.000000 +vn 0.017600 -0.999800 -0.000000 +vn 0.964500 -0.264000 -0.000000 +vn 0.945400 -0.325900 -0.000000 +vn 0.030300 -0.999500 -0.000000 +vn 0.922000 -0.387100 -0.000000 +vn 0.035700 -0.999400 -0.000000 +vn 0.035500 -0.999400 -0.000000 +vn 0.897100 -0.441800 -0.000000 +vn 0.040600 -0.999200 -0.000000 +vn 0.041000 -0.999200 -0.000000 +vn 0.040700 -0.999200 -0.000000 +vn 0.865200 -0.501400 -0.000000 +vn 0.045500 -0.999000 -0.000000 +vn 0.045800 -0.998900 -0.000000 +vn 0.824700 -0.565600 -0.000000 +vn 0.049700 -0.998800 -0.000000 +vn 0.773900 -0.633300 -0.000000 +vn 0.053100 -0.998600 -0.000000 +vn 0.053400 -0.998600 -0.000000 +vn 0.711300 -0.702900 -0.000000 +vn 0.056500 -0.998400 -0.000000 +vn 0.635900 -0.771800 -0.000000 +vn 0.059300 -0.998200 -0.000000 +vn 0.059100 -0.998200 -0.000000 +vn 0.547500 -0.836800 -0.000000 +vn 0.116600 -0.993200 -0.000000 +vn 0.448000 -0.894100 -0.000000 +vn 0.228000 -0.973700 -0.000000 +vn 0.340000 -0.940400 -0.000000 +vn -0.000000 0.000300 -1.000000 +vn -0.000000 0.006400 -1.000000 +vn -0.000000 -0.003500 -1.000000 +vn 0.000000 -0.001100 -1.000000 +vn 0.000000 -0.006200 -1.000000 +vn -0.000000 0.000600 -1.000000 +vn 0.000000 -0.007100 -1.000000 +vn 0.000000 0.014200 -0.999900 +vn 0.000100 0.004100 -1.000000 +vn 0.000000 -0.007600 -1.000000 +vn 0.000000 -0.000300 -1.000000 +vn -0.000100 0.000700 -1.000000 +vn 0.000000 -0.000500 -1.000000 +vn 0.000000 0.000700 -1.000000 +vn 0.000000 0.000500 -1.000000 +vn 0.000100 -0.000000 1.000000 +vn 0.045600 -0.999000 -0.000000 +vn 0.039900 -0.999200 -0.000000 +vn 0.003400 -1.000000 -0.000000 +vn 0.056100 -0.998400 -0.000000 +vn -0.078000 0.997000 0.000000 +vn -0.130700 -0.991400 0.000000 +vn -0.045100 -0.999000 -0.000000 +vn 0.028400 -0.999600 -0.000000 +vn 0.078700 -0.996900 0.000000 +vn 0.131100 -0.991400 0.000000 +vn 0.114300 -0.993400 -0.000000 +vn 0.026200 -0.999700 -0.000000 +vn -0.121600 -0.992600 0.000000 +vn -0.090900 -0.995900 0.000000 +vn -0.013400 -0.999900 0.000000 +vn 0.123400 -0.992400 0.000000 +vn 0.138500 -0.990400 -0.000000 +vn 0.141800 -0.989900 0.000000 +vn 0.131500 -0.991300 -0.000000 +vn 0.105600 -0.994400 0.000000 +vn 0.011600 -0.999900 0.000000 +vn -0.060000 -0.998200 0.000000 +vn 0.000000 -0.001700 -1.000000 +vn 0.000100 0.000000 -1.000000 +vn 0.000000 0.004600 -1.000000 +vn 0.000000 0.000600 1.000000 +vn 0.000200 0.000000 1.000000 +vn -0.000000 -0.004400 1.000000 +vn -0.000100 0.003800 1.000000 +vn 0.036100 0.999300 0.000000 +vn 0.024000 -0.999700 -0.000000 +vn 0.035800 -0.999400 -0.000000 +usemtl SVGMat.002 +s 1 +f 1//1 2//1 3//1 +f 4//2 3//2 5//2 +f 6//3 7//3 8//3 +f 9//3 10//3 11//3 +f 12//4 13//4 2//4 +f 14//5 15//5 16//5 +f 17//5 18//5 19//5 +f 20//6 5//6 15//6 +f 21//7 22//7 23//7 +f 24//8 21//9 25//9 +f 26//10 24//11 27//11 +f 28//12 26//13 29//14 +f 30//15 28//16 31//15 +f 32//17 30//18 33//17 +f 34//19 32//20 35//19 +f 36//21 34//22 37//22 +f 38//23 36//23 39//23 +f 40//24 38//24 41//24 +f 42//25 40//25 43//25 +f 44//26 42//26 45//26 +f 46//27 44//27 47//27 +f 48//28 46//28 49//28 +f 50//29 48//29 51//29 +f 52//30 50//30 53//30 +f 54//31 52//31 55//31 +f 56//32 54//32 57//32 +f 58//33 56//33 59//34 +f 60//35 58//35 61//35 +f 62//36 60//36 63//37 +f 64//38 62//38 65//38 +f 66//39 64//39 67//39 +f 68//40 66//40 69//40 +f 70//41 68//41 71//41 +f 72//42 70//42 73//42 +f 74//43 72//43 75//43 +f 76//44 74//44 77//44 +f 78//45 76//45 79//45 +f 80//46 78//46 81//46 +f 82//47 80//47 83//47 +f 84//48 82//48 85//48 +f 86//49 84//49 87//49 +f 88//49 86//49 89//49 +f 90//49 88//49 91//49 +f 92//49 90//49 93//49 +f 94//49 92//49 95//49 +f 96//49 94//49 97//49 +f 98//49 96//49 99//49 +f 100//49 98//49 101//49 +f 102//49 100//49 103//49 +f 104//49 102//49 105//49 +f 106//49 104//49 107//49 +f 108//49 106//49 109//49 +f 110//50 108//50 111//50 +f 112//49 110//49 113//49 +f 114//51 112//51 115//51 +f 116//49 114//49 117//49 +f 118//52 116//52 119//52 +f 120//53 118//53 121//53 +f 122//54 120//54 123//54 +f 124//55 122//55 125//55 +f 126//56 124//56 127//56 +f 128//55 126//55 129//55 +f 130//57 128//57 131//57 +f 132//58 130//58 133//58 +f 134//59 132//59 135//59 +f 136//60 134//60 137//60 +f 138//61 136//61 139//61 +f 140//62 138//62 141//62 +f 142//63 140//63 143//63 +f 144//64 142//64 145//64 +f 146//65 144//65 147//65 +f 11//66 146//66 148//66 +f 9//67 11//67 149//67 +f 150//68 9//68 151//68 +f 152//69 150//69 153//69 +f 154//70 152//70 155//70 +f 156//71 154//71 157//71 +f 158//72 156//72 159//72 +f 160//73 158//73 161//73 +f 162//74 160//74 163//74 +f 164//75 162//75 165//75 +f 166//76 164//76 167//76 +f 168//77 166//77 169//77 +f 170//78 168//78 171//78 +f 172//79 170//79 173//79 +f 174//80 172//80 175//80 +f 176//3 177//3 178//3 +f 179//55 180//55 181//55 +f 182//55 183//55 184//55 +f 185//81 184//81 186//81 +f 187//82 186//82 13//82 +f 188//83 15//83 189//83 +f 190//84 189//84 191//84 +f 192//85 191//85 193//85 +f 194//86 193//86 195//86 +f 196//87 195//87 197//87 +f 198//88 197//88 14//88 +f 199//89 14//89 200//89 +f 201//49 202//49 203//49 +f 204//49 205//49 206//49 +f 207//90 206//90 208//90 +f 209//91 208//91 210//91 +f 211//92 210//92 212//92 +f 213//93 212//93 214//93 +f 215//94 214//94 216//94 +f 217//95 216//95 218//95 +f 219//96 218//96 220//96 +f 221//97 220//97 222//97 +f 223//98 222//98 224//98 +f 225//99 224//99 226//99 +f 227//100 226//100 228//100 +f 229//101 228//101 230//101 +f 231//102 230//102 232//102 +f 233//102 232//102 234//102 +f 235//102 236//102 237//102 +f 238//49 239//49 240//49 +f 241//49 238//49 242//49 +f 243//103 241//103 244//103 +f 245//104 243//104 246//105 +f 247//106 245//106 248//106 +f 249//107 247//107 250//107 +f 251//108 249//108 252//108 +f 253//109 251//109 254//109 +f 255//110 253//110 256//110 +f 257//111 255//111 258//111 +f 259//112 257//112 260//112 +f 261//113 259//113 262//113 +f 263//114 261//114 264//114 +f 265//115 263//115 266//115 +f 267//116 265//117 268//118 +f 269//119 267//116 270//116 +f 271//120 269//119 272//119 +f 22//121 271//121 273//122 +f 274//5 275//5 276//5 +f 277//123 174//123 16//123 +f 278//124 279//124 280//124 +f 281//125 278//125 282//125 +f 283//126 281//126 284//126 +f 285//127 283//127 286//127 +f 287//128 285//128 288//128 +f 289//129 287//129 290//129 +f 291//130 289//130 292//130 +f 293//131 291//131 294//131 +f 295//132 293//132 296//132 +f 297//133 295//133 298//133 +f 299//134 297//134 300//134 +f 301//135 299//135 302//135 +f 303//136 301//136 304//136 +f 176//137 303//137 305//137 +f 177//138 176//138 306//138 +f 307//139 177//139 308//139 +f 309//140 307//140 310//140 +f 311//49 309//49 276//49 +f 312//49 311//49 313//49 +f 314//49 312//49 315//49 +f 316//49 314//49 317//49 +f 318//49 316//49 319//49 +f 320//49 318//49 321//49 +f 322//49 320//49 323//49 +f 324//49 322//49 325//49 +f 326//49 324//49 327//49 +f 239//49 326//49 328//49 +f 329//141 277//141 330//141 +f 331//142 329//142 332//142 +f 333//143 331//143 334//143 +f 335//144 333//144 336//144 +f 337//145 335//145 338//145 +f 279//146 337//146 339//146 +f 340//147 341//147 342//147 +f 343//148 340//148 344//148 +f 341//149 345//149 346//149 +f 347//150 343//150 348//150 +f 345//151 349//151 350//151 +f 351//152 347//152 352//152 +f 349//153 353//153 354//153 +f 355//154 351//154 356//155 +f 353//156 357//156 358//156 +f 359//157 355//157 360//157 +f 357//158 361//158 362//158 +f 363//159 359//159 364//159 +f 361//160 365//160 366//160 +f 367//161 363//161 368//161 +f 365//162 10//162 369//162 +f 370//163 367//163 371//163 +f 10//164 372//164 373//164 +f 374//165 370//165 375//165 +f 372//166 376//166 377//166 +f 378//167 374//167 379//167 +f 376//168 380//168 381//168 +f 382//169 378//169 383//169 +f 380//170 384//170 385//170 +f 386//171 382//171 387//171 +f 384//172 388//172 389//172 +f 390//173 386//173 391//173 +f 388//174 392//174 393//174 +f 394//175 390//175 395//175 +f 392//176 396//176 397//176 +f 398//177 394//177 399//177 +f 396//178 400//178 401//178 +f 402//179 398//179 403//179 +f 400//180 404//180 405//180 +f 406//181 402//181 407//181 +f 404//182 408//182 409//182 +f 410//183 406//183 411//183 +f 408//184 412//184 413//184 +f 414//185 410//185 415//185 +f 412//186 416//186 417//186 +f 418//187 414//187 419//187 +f 416//188 420//188 421//188 +f 422//189 418//189 423//189 +f 420//190 424//190 425//190 +f 426//191 422//191 427//191 +f 424//192 428//192 429//192 +f 430//193 426//193 431//193 +f 428//194 432//194 433//194 +f 434//195 430//195 435//195 +f 432//196 436//196 437//196 +f 438//197 434//197 439//197 +f 436//198 440//198 441//198 +f 442//199 438//199 443//199 +f 440//200 444//200 445//200 +f 446//201 442//201 447//201 +f 444//202 448//202 449//202 +f 450//203 446//203 451//203 +f 448//204 452//204 453//204 +f 454//205 450//205 455//205 +f 452//206 456//206 457//206 +f 458//207 454//207 459//207 +f 456//208 460//208 461//208 +f 462//209 458//209 463//209 +f 460//210 464//210 465//210 +f 466//211 462//211 467//211 +f 464//212 468//212 469//212 +f 470//213 466//213 471//213 +f 468//214 472//214 473//214 +f 474//215 470//215 475//215 +f 472//216 476//216 477//216 +f 478//217 474//217 479//217 +f 476//218 480//218 481//218 +f 482//219 478//219 483//219 +f 480//220 484//220 485//220 +f 486//221 482//221 487//221 +f 484//222 488//222 489//222 +f 490//223 486//223 491//223 +f 488//224 492//224 493//224 +f 494//225 490//225 495//225 +f 492//226 496//226 497//226 +f 498//227 494//227 499//227 +f 496//228 500//228 501//228 +f 502//229 498//229 503//229 +f 500//230 504//230 505//230 +f 506//231 502//231 507//232 +f 504//233 508//233 509//234 +f 510//235 506//235 511//235 +f 508//236 512//237 513//238 +f 514//239 510//239 515//239 +f 512//240 516//240 517//241 +f 518//242 514//242 519//242 +f 516//243 520//244 521//245 +f 522//246 518//246 523//246 +f 520//247 524//247 525//247 +f 526//248 522//248 527//248 +f 524//249 528//249 529//249 +f 530//250 526//250 531//250 +f 528//251 532//251 533//252 +f 534//253 530//253 535//253 +f 532//254 536//254 537//254 +f 538//255 534//255 539//255 +f 536//256 540//256 541//257 +f 542//258 538//258 543//258 +f 540//259 544//260 545//261 +f 546//262 542//262 547//262 +f 544//263 548//264 549//265 +f 550//266 546//266 551//266 +f 548//267 552//268 553//267 +f 554//269 550//269 555//269 +f 552//270 556//270 557//271 +f 558//272 554//272 559//272 +f 556//273 560//274 561//275 +f 562//276 558//276 563//276 +f 560//277 564//278 565//277 +f 566//279 562//279 567//279 +f 564//280 568//281 569//281 +f 570//282 566//282 571//282 +f 568//283 572//283 573//284 +f 574//285 570//285 575//285 +f 572//286 576//287 577//288 +f 578//289 574//289 579//289 +f 576//290 580//291 581//292 +f 582//293 578//293 583//293 +f 580//294 584//295 585//296 +f 586//297 582//297 587//297 +f 584//298 588//299 589//300 +f 590//301 586//301 591//301 +f 588//302 592//302 593//303 +f 594//304 590//304 595//304 +f 592//305 596//305 597//305 +f 598//306 594//306 599//306 +f 596//307 600//307 601//307 +f 602//308 598//308 603//308 +f 600//309 604//309 605//309 +f 606//310 602//310 607//310 +f 604//311 608//311 609//311 +f 610//312 606//312 611//312 +f 608//313 612//313 613//313 +f 614//314 610//314 19//314 +f 612//315 615//315 616//315 +f 617//316 614//316 18//316 +f 615//317 618//317 619//317 +f 620//318 617//318 621//318 +f 618//319 622//320 623//320 +f 6//321 620//321 624//321 +f 622//320 625//322 626//323 +f 7//324 6//324 627//324 +f 625//325 628//325 629//325 +f 630//326 7//326 631//326 +f 628//327 632//327 633//327 +f 634//328 630//328 635//328 +f 632//329 636//330 637//330 +f 638//331 634//331 639//331 +f 636//332 640//332 641//332 +f 642//333 638//333 643//333 +f 640//332 644//332 645//332 +f 646//334 642//334 647//334 +f 644//332 648//332 649//332 +f 650//335 646//335 651//335 +f 648//332 652//332 653//332 +f 654//336 650//336 655//336 +f 652//332 656//332 657//332 +f 658//337 654//337 659//337 +f 656//332 660//332 661//332 +f 662//338 658//338 663//338 +f 660//332 664//332 665//332 +f 666//339 662//339 667//339 +f 664//332 668//332 669//332 +f 670//340 666//340 671//340 +f 668//332 672//332 673//332 +f 674//341 670//341 675//341 +f 672//332 676//332 677//332 +f 678//342 674//342 679//342 +f 676//332 680//332 681//332 +f 682//343 678//343 683//343 +f 680//332 684//332 685//332 +f 686//344 682//344 687//344 +f 684//345 688//345 689//345 +f 690//346 686//346 691//346 +f 688//347 692//347 693//347 +f 694//348 690//348 695//348 +f 692//349 696//349 697//349 +f 698//350 694//350 699//350 +f 696//351 700//351 701//351 +f 702//352 698//352 703//352 +f 700//353 704//353 705//353 +f 706//354 702//354 707//354 +f 704//355 708//355 709//355 +f 710//356 706//356 711//356 +f 708//357 712//357 713//357 +f 714//358 710//358 715//358 +f 712//359 716//359 717//359 +f 718//360 714//360 719//360 +f 716//361 720//361 721//361 +f 722//362 718//362 723//362 +f 720//363 724//363 725//363 +f 726//364 722//364 727//364 +f 724//365 728//365 729//365 +f 730//366 726//366 731//366 +f 728//296 732//296 733//296 +f 734//367 730//367 735//367 +f 732//49 736//49 737//49 +f 738//368 734//368 739//368 +f 736//369 740//369 741//369 +f 742//370 738//370 743//370 +f 740//369 744//369 745//369 +f 746//371 742//371 747//371 +f 744//369 748//369 749//369 +f 750//372 746//372 751//372 +f 748//369 752//369 753//369 +f 754//373 750//373 755//373 +f 752//369 756//369 757//369 +f 758//374 754//374 759//374 +f 756//369 760//369 761//369 +f 762//375 758//375 763//375 +f 760//369 764//369 765//369 +f 766//376 762//376 767//376 +f 764//369 768//377 769//377 +f 770//378 766//378 771//378 +f 768//377 772//369 773//369 +f 774//379 770//379 775//379 +f 772//369 776//369 777//369 +f 778//380 774//380 779//380 +f 776//369 780//377 781//377 +f 782//381 778//381 783//381 +f 780//377 784//369 785//369 +f 786//382 782//382 787//382 +f 784//383 788//383 789//383 +f 790//384 786//384 791//384 +f 788//385 792//385 793//385 +f 794//386 790//386 795//386 +f 792//387 796//387 797//387 +f 798//388 794//388 799//388 +f 796//389 800//389 801//389 +f 802//390 798//390 803//390 +f 800//391 804//391 805//391 +f 806//392 802//392 807//392 +f 804//393 808//393 809//393 +f 810//394 806//394 811//394 +f 808//395 812//395 813//395 +f 814//396 810//396 815//396 +f 812//397 814//397 816//397 +f 817//3 818//3 819//3 +f 820//5 821//5 822//5 +f 823//398 824//398 825//398 +f 826//399 823//399 827//399 +f 824//400 828//400 829//400 +f 830//401 826//401 831//401 +f 828//402 832//402 833//402 +f 834//403 830//403 835//403 +f 832//404 836//404 837//404 +f 838//405 834//405 839//405 +f 836//406 840//406 841//406 +f 842//407 838//407 843//407 +f 840//408 844//408 845//408 +f 846//409 842//410 847//409 +f 844//411 848//411 849//411 +f 850//412 846//412 851//412 +f 848//413 852//413 853//413 +f 854//414 850//414 855//414 +f 852//415 856//415 857//415 +f 858//416 854//416 859//416 +f 856//417 860//417 861//417 +f 862//418 858//418 863//418 +f 860//419 864//419 865//420 +f 866//421 862//422 867//421 +f 864//423 868//423 869//424 +f 870//425 866//426 871//425 +f 868//427 872//427 873//427 +f 874//428 870//428 875//428 +f 872//429 876//429 877//429 +f 878//430 874//430 879//430 +f 876//431 880//431 881//431 +f 882//432 878//432 883//432 +f 880//433 884//433 885//433 +f 886//434 882//434 887//434 +f 884//435 888//435 889//435 +f 890//436 886//436 891//436 +f 888//437 892//437 893//437 +f 894//438 890//438 895//438 +f 892//439 896//439 897//439 +f 898//440 894//440 899//440 +f 896//441 900//441 901//441 +f 902//442 898//442 903//442 +f 900//443 904//443 905//443 +f 906//444 902//444 907//444 +f 904//445 819//445 908//445 +f 909//446 906//446 910//446 +f 819//447 818//447 911//447 +f 912//448 909//448 913//448 +f 818//449 914//449 915//449 +f 916//450 912//450 917//450 +f 914//451 918//451 919//451 +f 920//452 916//452 921//452 +f 918//453 922//453 923//453 +f 924//454 920//454 925//454 +f 922//455 926//455 927//455 +f 928//456 924//456 929//456 +f 926//457 930//457 931//457 +f 932//458 928//458 933//458 +f 930//459 934//459 935//459 +f 936//460 932//460 937//460 +f 934//461 938//461 939//461 +f 940//462 936//462 941//462 +f 938//463 942//463 821//463 +f 943//464 940//464 944//464 +f 942//465 945//465 822//465 +f 946//466 943//466 947//466 +f 945//467 948//467 949//467 +f 950//468 946//468 951//468 +f 948//469 952//469 953//469 +f 954//470 950//470 955//470 +f 952//471 956//471 957//471 +f 958//472 954//472 959//472 +f 956//473 960//473 961//473 +f 962//474 958//474 963//474 +f 960//475 964//475 965//475 +f 966//476 962//476 967//476 +f 964//477 968//477 969//477 +f 817//478 966//478 970//478 +f 968//479 971//479 972//480 +f 973//481 817//481 974//481 +f 971//482 975//482 976//482 +f 977//483 973//483 978//483 +f 975//484 979//484 980//484 +f 981//485 977//485 982//485 +f 979//486 983//486 984//486 +f 985//487 981//487 986//487 +f 983//488 987//488 988//488 +f 989//489 985//489 990//489 +f 987//490 991//490 992//490 +f 993//491 989//491 994//491 +f 991//492 995//492 996//492 +f 997//493 993//493 998//493 +f 995//302 999//302 1000//302 +f 1001//494 997//494 1002//494 +f 999//495 1003//495 1004//495 +f 1005//496 1001//496 1006//496 +f 1003//497 1007//497 1008//497 +f 1009//498 1005//498 820//498 +f 1007//499 1010//500 1011//499 +f 1012//501 1009//501 1013//501 +f 1010//254 1014//254 1015//254 +f 1016//502 1012//502 1017//502 +f 1014//503 1018//503 1019//503 +f 1020//504 1016//504 1021//504 +f 1018//505 1022//506 1023//505 +f 1024//507 1020//507 1025//507 +f 1022//508 1026//509 1027//510 +f 1028//511 1024//511 1029//511 +f 1026//512 1030//513 1031//513 +f 1032//514 1028//514 1033//514 +f 1030//515 1034//515 1035//515 +f 1036//516 1032//516 1037//516 +f 1034//517 1038//517 1039//518 +f 1040//519 1036//519 1041//519 +f 1038//520 1042//520 1043//520 +f 1044//521 1040//521 1045//521 +f 1042//522 1046//523 1047//522 +f 1048//524 1044//524 1049//524 +f 1046//525 1050//525 1051//525 +f 1052//526 1048//526 1053//526 +f 1050//527 1054//527 1055//527 +f 1054//528 1052//528 1056//528 +f 4//1 1//1 3//1 +f 20//2 4//2 5//2 +f 1057//3 454//3 458//3 +f 698//3 702//3 706//3 +f 1057//3 458//3 462//3 +f 710//3 698//3 706//3 +f 1057//3 462//3 466//3 +f 710//3 694//3 698//3 +f 1057//3 466//3 470//3 +f 710//3 714//3 694//3 +f 1057//3 470//3 474//3 +f 714//3 690//3 694//3 +f 1057//3 474//3 478//3 +f 714//3 718//3 690//3 +f 1057//3 478//3 482//3 +f 690//3 718//3 686//3 +f 1057//3 482//3 486//3 +f 718//3 722//3 686//3 +f 1057//3 486//3 490//3 +f 686//3 722//3 1058//3 +f 1057//3 490//3 494//3 +f 686//3 1058//3 682//3 +f 1057//3 494//3 498//3 +f 1058//3 678//3 682//3 +f 1057//3 498//3 502//3 +f 1058//3 674//3 678//3 +f 1057//3 502//3 506//3 +f 1058//3 722//3 726//3 +f 1057//3 506//3 510//3 +f 1059//3 726//3 730//3 +f 1057//3 510//3 514//3 +f 1059//3 730//3 734//3 +f 1057//3 514//3 518//3 +f 742//3 1059//3 738//3 +f 1057//3 518//3 522//3 +f 746//3 1059//3 742//3 +f 1057//3 522//3 526//3 +f 1060//3 798//3 199//3 +f 1057//3 526//3 530//3 +f 1060//3 794//3 798//3 +f 1057//3 530//3 534//3 +f 790//3 794//3 1060//3 +f 1057//3 534//3 538//3 +f 786//3 790//3 1060//3 +f 1057//3 538//3 542//3 +f 782//3 786//3 1060//3 +f 1057//3 542//3 546//3 +f 778//3 782//3 1060//3 +f 233//3 546//3 550//3 +f 774//3 778//3 1060//3 +f 204//3 550//3 554//3 +f 770//3 774//3 1060//3 +f 1061//3 554//3 558//3 +f 766//3 770//3 1060//3 +f 1061//3 558//3 562//3 +f 762//3 766//3 1060//3 +f 1062//3 562//3 566//3 +f 758//3 762//3 1060//3 +f 1062//3 566//3 570//3 +f 754//3 758//3 1060//3 +f 1062//3 570//3 574//3 +f 750//3 754//3 1060//3 +f 1063//3 574//3 578//3 +f 746//3 750//3 1060//3 +f 1063//3 578//3 582//3 +f 1059//3 746//3 1060//3 +f 1063//3 582//3 586//3 +f 1059//3 734//3 738//3 +f 1063//3 586//3 590//3 +f 1059//3 1058//3 726//3 +f 1064//3 590//3 594//3 +f 674//3 1058//3 670//3 +f 1064//3 594//3 598//3 +f 670//3 1058//3 202//3 +f 1061//3 204//3 554//3 +f 666//3 670//3 202//3 +f 1064//3 598//3 602//3 +f 662//3 666//3 202//3 +f 1065//3 602//3 606//3 +f 658//3 662//3 202//3 +f 546//3 233//3 1057//3 +f 654//3 658//3 202//3 +f 550//3 204//3 207//3 +f 650//3 654//3 202//3 +f 1065//3 606//3 610//3 +f 201//3 650//3 202//3 +f 1065//3 610//3 614//3 +f 201//3 646//3 650//3 +f 233//3 550//3 207//3 +f 201//3 642//3 646//3 +f 1065//3 614//3 617//3 +f 201//3 638//3 642//3 +f 209//3 233//3 207//3 +f 201//3 634//3 638//3 +f 8//3 617//3 620//3 +f 221//3 223//3 225//3 +f 225//3 219//3 221//3 +f 225//3 227//3 217//3 +f 215//3 227//3 229//3 +f 231//3 213//3 229//3 +f 574//3 1063//3 1062//3 +f 229//3 213//3 215//3 +f 562//3 1062//3 1061//3 +f 617//3 8//3 1065//3 +f 590//3 1064//3 1063//3 +f 215//3 217//3 227//3 +f 225//3 217//3 219//3 +f 209//3 231//3 233//3 +f 630//3 634//3 201//3 +f 213//3 231//3 211//3 +f 630//3 201//3 8//3 +f 602//3 1065//3 1064//3 +f 630//3 8//3 7//3 +f 620//3 6//3 8//3 +f 209//3 211//3 231//3 +f 396//3 408//3 404//3 +f 396//3 416//3 412//3 +f 392//3 424//3 420//3 +f 392//3 432//3 428//3 +f 480//3 440//3 436//3 +f 460//3 456//3 444//3 +f 448//3 456//3 452//3 +f 444//3 464//3 460//3 +f 444//3 472//3 468//3 +f 440//3 480//3 476//3 +f 588//3 488//3 484//3 +f 500//529 496//530 492//3 +f 508//3 504//531 500//532 +f 516//533 512//533 508//533 +f 548//534 544//3 540//3 +f 520//535 516//535 508//535 +f 552//3 548//534 540//3 +f 524//536 520//536 508//536 +f 556//3 552//3 540//3 +f 524//3 508//3 500//532 +f 556//537 540//537 536//537 +f 528//538 524//538 500//538 +f 560//3 556//3 536//3 +f 528//539 500//529 492//3 +f 564//3 560//3 536//3 +f 532//540 528//539 492//3 +f 568//541 564//3 536//3 +f 536//3 532//540 492//3 +f 436//3 484//3 480//3 +f 444//3 468//3 464//3 +f 444//3 456//3 448//3 +f 392//3 436//3 432//3 +f 392//3 420//3 416//3 +f 396//3 404//3 400//3 +f 1066//3 454//3 1057//3 +f 412//3 408//3 396//3 +f 1066//3 1067//3 454//3 +f 416//3 396//3 392//3 +f 454//3 1067//3 1068//3 +f 436//3 392//3 388//3 +f 1069//3 454//3 1068//3 +f 696//3 388//3 384//3 +f 1069//3 1070//3 454//3 +f 732//3 384//3 380//3 +f 1070//3 450//3 454//3 +f 732//3 380//3 376//3 +f 1070//3 446//3 450//3 +f 428//3 424//3 392//3 +f 442//3 446//3 1070//3 +f 732//3 376//3 372//3 +f 438//3 442//3 1070//3 +f 150//3 372//3 10//3 +f 438//3 1070//3 236//3 +f 484//3 436//3 388//3 +f 434//3 438//3 236//3 +f 11//3 10//3 365//3 +f 118//3 434//3 236//3 +f 146//3 365//3 361//3 +f 430//3 434//3 118//3 +f 476//3 472//3 440//3 +f 426//3 430//3 118//3 +f 142//3 361//3 357//3 +f 422//3 426//3 118//3 +f 440//3 472//3 444//3 +f 418//3 422//3 118//3 +f 138//3 357//3 353//3 +f 418//3 118//3 414//3 +f 588//3 484//3 388//3 +f 414//3 118//3 122//3 +f 136//3 353//3 349//3 +f 410//3 414//3 122//3 +f 584//542 492//3 488//3 +f 406//3 122//3 402//3 +f 576//3 536//3 492//3 +f 402//3 122//3 398//3 +f 572//543 568//541 536//3 +f 398//3 122//3 394//3 +f 576//3 572//543 536//3 +f 122//3 124//3 394//3 +f 580//3 576//3 492//3 +f 394//3 124//3 390//3 +f 584//542 580//3 492//3 +f 390//3 124//3 386//3 +f 588//3 584//542 488//3 +f 386//3 124//3 382//3 +f 592//3 588//3 388//3 +f 382//3 124//3 126//3 +f 612//3 592//3 388//3 +f 378//3 382//3 126//3 +f 600//3 596//3 592//3 +f 374//3 378//3 126//3 +f 604//3 600//3 592//3 +f 370//3 374//3 126//3 +f 608//3 604//3 592//3 +f 116//3 235//3 1071//3 +f 612//3 608//3 592//3 +f 116//3 1071//3 1072//3 +f 132//3 349//3 345//3 +f 1073//3 1072//3 1074//3 +f 615//3 612//3 388//3 +f 116//3 1072//3 1073//3 +f 618//3 615//3 388//3 +f 116//3 1073//3 1075//3 +f 622//3 618//3 388//3 +f 1075//3 239//3 238//3 +f 625//3 622//3 388//3 +f 1075//3 238//3 241//3 +f 628//3 625//3 388//3 +f 86//3 241//3 243//3 +f 632//3 628//3 388//3 +f 86//3 243//3 245//3 +f 636//3 632//3 388//3 +f 84//3 245//3 247//3 +f 640//3 636//3 388//3 +f 84//3 247//3 249//3 +f 644//3 640//3 388//3 +f 82//3 249//3 251//3 +f 648//3 644//3 388//3 +f 80//3 251//3 253//3 +f 652//3 648//3 388//3 +f 80//3 253//3 255//3 +f 656//3 652//3 388//3 +f 78//3 255//3 257//3 +f 660//3 656//3 388//3 +f 76//3 257//3 259//3 +f 664//3 660//3 388//3 +f 74//3 259//3 261//3 +f 668//3 664//3 388//3 +f 74//3 261//3 263//3 +f 672//3 668//3 388//3 +f 70//3 263//3 265//3 +f 676//3 672//3 388//3 +f 70//3 265//3 267//3 +f 680//3 676//3 388//3 +f 70//3 267//3 269//3 +f 684//3 680//3 388//3 +f 70//3 269//3 271//3 +f 688//3 684//3 388//3 +f 70//3 271//3 22//3 +f 692//3 688//3 388//3 +f 68//3 22//3 21//3 +f 696//3 692//3 388//3 +f 68//3 21//3 24//3 +f 128//3 345//3 341//3 +f 68//3 24//3 26//3 +f 732//3 728//3 384//3 +f 68//3 26//3 28//3 +f 384//3 700//3 696//3 +f 68//3 28//3 30//3 +f 384//3 704//3 700//3 +f 68//3 30//3 32//3 +f 384//3 728//3 724//3 +f 68//3 32//3 34//3 +f 704//3 384//3 708//3 +f 68//3 34//3 36//3 +f 708//3 384//3 712//3 +f 68//3 36//3 38//3 +f 712//3 384//3 716//3 +f 68//3 38//3 40//3 +f 716//3 384//3 720//3 +f 66//3 40//3 42//3 +f 128//3 341//3 340//3 +f 66//3 42//3 44//3 +f 720//3 384//3 724//3 +f 56//3 44//3 46//3 +f 128//3 130//3 345//3 +f 54//3 46//3 48//3 +f 128//3 340//3 343//3 +f 52//3 48//3 50//3 +f 199//3 740//3 736//3 +f 54//3 48//3 52//3 +f 199//3 744//3 740//3 +f 56//3 46//3 54//3 +f 199//3 748//3 744//3 +f 58//3 44//3 56//3 +f 199//3 760//3 756//3 +f 64//3 44//3 58//3 +f 199//3 764//3 760//3 +f 64//3 58//3 60//3 +f 199//3 768//3 764//3 +f 64//3 60//3 62//3 +f 199//3 756//3 752//3 +f 66//3 44//3 64//3 +f 199//3 780//3 776//3 +f 68//3 40//3 66//3 +f 199//3 776//3 772//3 +f 70//3 22//3 68//3 +f 199//3 798//3 802//3 +f 72//3 263//3 70//3 +f 199//3 802//3 806//3 +f 74//3 263//3 72//3 +f 199//3 806//3 810//3 +f 76//3 259//3 74//3 +f 199//3 810//3 814//3 +f 78//3 257//3 76//3 +f 199//3 814//3 812//3 +f 80//3 255//3 78//3 +f 199//3 812//3 808//3 +f 82//3 251//3 80//3 +f 199//3 808//3 804//3 +f 84//3 249//3 82//3 +f 199//3 804//3 800//3 +f 86//3 245//3 84//3 +f 199//3 800//3 796//3 +f 88//3 241//3 86//3 +f 199//3 796//3 792//3 +f 90//3 241//3 88//3 +f 199//3 792//3 788//3 +f 92//3 241//3 90//3 +f 199//3 788//3 784//3 +f 94//3 241//3 92//3 +f 199//3 784//3 780//3 +f 96//3 241//3 94//3 +f 199//3 772//3 768//3 +f 98//3 241//3 96//3 +f 199//3 752//3 748//3 +f 110//3 241//3 98//3 +f 168//3 199//3 736//3 +f 110//3 102//3 104//3 +f 174//3 188//3 199//3 +f 110//3 100//3 102//3 +f 199//3 196//3 198//3 +f 110//3 104//3 106//3 +f 199//3 194//3 196//3 +f 110//3 106//3 108//3 +f 199//3 192//3 194//3 +f 98//3 100//3 110//3 +f 199//3 190//3 192//3 +f 1075//3 241//3 110//3 +f 199//3 188//3 190//3 +f 1075//3 110//3 112//3 +f 174//3 20//3 188//3 +f 116//3 112//3 114//3 +f 174//3 4//3 20//3 +f 1075//3 112//3 116//3 +f 174//3 1//3 4//3 +f 118//3 235//3 116//3 +f 174//3 12//3 1//3 +f 236//3 235//3 118//3 +f 174//3 187//3 12//3 +f 122//3 118//3 120//3 +f 174//3 185//3 187//3 +f 406//3 410//3 122//3 +f 174//3 182//3 185//3 +f 370//3 126//3 367//3 +f 174//3 178//3 182//3 +f 126//3 363//3 367//3 +f 172//3 174//3 199//3 +f 126//3 128//3 363//3 +f 170//3 172//3 199//3 +f 363//3 128//3 359//3 +f 168//3 170//3 199//3 +f 128//3 355//3 359//3 +f 166//3 168//3 736//3 +f 128//3 351//3 355//3 +f 164//3 166//3 736//3 +f 128//3 347//3 351//3 +f 732//3 164//3 736//3 +f 128//3 343//3 347//3 +f 732//3 162//3 164//3 +f 130//3 132//3 345//3 +f 732//3 160//3 162//3 +f 132//3 134//3 349//3 +f 732//3 158//3 160//3 +f 134//3 136//3 349//3 +f 732//3 156//3 158//3 +f 136//3 138//3 353//3 +f 732//3 154//3 156//3 +f 138//3 140//3 357//3 +f 732//3 152//3 154//3 +f 140//3 142//3 357//3 +f 732//3 150//3 152//3 +f 142//3 144//3 361//3 +f 732//3 372//3 150//3 +f 144//3 146//3 361//3 +f 150//3 10//3 9//3 +f 146//3 11//3 365//3 +f 1//4 12//4 2//4 +f 397//5 401//5 405//5 +f 1076//5 455//5 451//5 +f 409//5 397//5 405//5 +f 1076//5 451//5 447//5 +f 409//5 413//5 397//5 +f 1076//5 447//5 443//5 +f 413//5 417//5 397//5 +f 237//5 443//5 439//5 +f 397//5 417//5 393//5 +f 1077//5 234//5 455//5 +f 393//5 417//5 421//5 +f 121//5 439//5 435//5 +f 393//5 421//5 425//5 +f 1078//5 1077//5 455//5 +f 429//5 393//5 425//5 +f 121//5 435//5 431//5 +f 433//5 393//5 429//5 +f 1079//5 1078//5 455//5 +f 437//5 393//5 433//5 +f 121//5 431//5 427//5 +f 437//5 389//5 393//5 +f 121//5 427//5 423//5 +f 441//5 477//5 481//5 +f 1080//5 1079//5 455//5 +f 469//5 445//5 465//5 +f 121//5 423//5 419//5 +f 457//5 449//5 453//5 +f 125//5 419//5 415//5 +f 445//5 449//5 457//5 +f 125//5 415//5 411//5 +f 461//5 445//5 457//5 +f 1076//5 1080//5 455//5 +f 465//5 445//5 461//5 +f 125//5 411//5 407//5 +f 469//5 473//5 445//5 +f 125//5 407//5 403//5 +f 473//5 441//5 445//5 +f 125//5 403//5 399//5 +f 473//5 477//5 441//5 +f 127//5 399//5 395//5 +f 441//5 481//5 437//5 +f 127//5 395//5 391//5 +f 481//5 485//5 437//5 +f 237//5 1076//5 443//5 +f 485//5 389//5 437//5 +f 127//5 391//5 387//5 +f 485//5 489//5 389//5 +f 129//5 387//5 383//5 +f 489//5 493//5 389//5 +f 129//5 383//5 379//5 +f 493//5 497//5 389//5 +f 129//5 379//5 375//5 +f 497//5 501//5 389//5 +f 129//5 375//5 371//5 +f 501//5 505//5 389//5 +f 129//5 371//5 368//5 +f 505//5 509//5 389//5 +f 131//5 368//5 364//5 +f 389//5 509//5 513//5 +f 121//5 1081//5 237//5 +f 389//5 513//5 517//544 +f 119//5 1082//5 1081//5 +f 389//5 517//544 521//5 +f 119//5 1083//5 1082//5 +f 389//5 521//5 525//5 +f 1084//5 1085//5 1083//5 +f 389//5 525//5 529//5 +f 119//5 1084//5 1083//5 +f 533//5 389//5 529//5 +f 242//5 240//5 1086//5 +f 537//544 389//5 533//5 +f 244//5 242//5 1086//5 +f 541//544 389//5 537//544 +f 113//5 244//5 1086//5 +f 545//5 389//5 541//544 +f 113//5 101//5 244//5 +f 549//5 389//5 545//5 +f 244//5 99//5 97//5 +f 553//5 389//5 549//5 +f 95//5 244//5 97//5 +f 557//5 389//5 553//5 +f 93//5 91//5 244//5 +f 561//5 389//5 557//5 +f 244//5 91//5 89//5 +f 565//5 389//5 561//5 +f 246//5 244//5 89//5 +f 569//5 389//5 565//5 +f 248//5 246//5 89//5 +f 573//5 389//5 569//5 +f 87//5 248//5 89//5 +f 577//5 389//5 573//5 +f 87//5 250//5 248//5 +f 581//5 389//5 577//5 +f 87//5 252//5 250//5 +f 585//5 389//5 581//5 +f 87//5 85//5 252//5 +f 589//5 389//5 585//5 +f 252//5 85//5 254//5 +f 593//5 389//5 589//5 +f 254//5 85//5 83//5 +f 613//5 389//5 593//5 +f 256//5 254//5 83//5 +f 616//5 389//5 613//5 +f 258//5 256//5 83//5 +f 623//5 389//5 619//5 +f 81//5 258//5 83//5 +f 629//5 389//5 626//5 +f 81//5 260//5 258//5 +f 633//5 389//5 629//5 +f 81//5 79//5 260//5 +f 641//5 389//5 637//5 +f 260//5 79//5 262//5 +f 645//5 389//5 641//5 +f 262//5 79//5 77//5 +f 653//5 389//5 649//5 +f 264//5 262//5 77//5 +f 657//5 389//5 653//5 +f 266//5 264//5 77//5 +f 661//5 389//5 657//5 +f 75//5 266//5 77//5 +f 601//5 593//5 597//5 +f 75//5 73//5 266//5 +f 605//5 593//5 601//5 +f 266//5 73//5 268//5 +f 609//5 593//5 605//5 +f 71//5 25//5 23//5 +f 613//5 593//5 609//5 +f 71//5 27//5 25//5 +f 616//5 619//5 389//5 +f 71//5 29//5 27//5 +f 626//5 389//5 623//5 +f 71//5 31//5 29//5 +f 389//5 633//5 637//5 +f 71//5 33//5 31//5 +f 645//5 649//5 389//5 +f 37//5 35//5 71//5 +f 661//5 665//5 389//5 +f 39//5 37//5 71//5 +f 665//5 669//5 389//5 +f 41//5 39//5 71//5 +f 669//5 673//5 389//5 +f 43//5 71//5 69//5 +f 673//5 677//5 389//5 +f 45//5 69//5 47//5 +f 677//5 681//5 389//5 +f 47//5 59//5 49//5 +f 681//5 685//5 389//5 +f 55//5 53//5 51//5 +f 685//5 689//5 389//5 +f 63//5 67//5 65//5 +f 689//5 693//5 389//5 +f 63//5 61//5 67//5 +f 693//5 697//5 389//5 +f 67//5 61//5 47//5 +f 697//5 385//5 389//5 +f 47//5 61//5 59//5 +f 701//5 385//5 697//5 +f 57//5 51//5 49//5 +f 705//5 385//5 701//5 +f 57//5 55//5 51//5 +f 709//5 385//5 705//5 +f 49//5 59//5 57//5 +f 713//5 385//5 709//5 +f 47//5 69//5 67//5 +f 717//5 385//5 713//5 +f 45//5 43//5 69//5 +f 721//5 385//5 717//5 +f 43//5 41//5 71//5 +f 369//5 373//5 153//5 +f 71//5 35//5 33//5 +f 369//5 149//5 366//5 +f 73//5 71//5 23//5 +f 149//5 148//5 366//5 +f 273//5 73//5 23//5 +f 147//5 362//5 148//5 +f 273//5 272//5 73//5 +f 151//5 369//5 153//5 +f 73//5 272//5 270//5 +f 373//5 377//5 733//5 +f 268//5 73//5 270//5 +f 733//5 381//5 385//5 +f 95//5 93//5 244//5 +f 729//5 385//5 725//5 +f 113//5 107//5 105//5 +f 385//5 721//5 725//5 +f 113//5 105//5 103//5 +f 733//5 385//5 729//5 +f 113//5 109//5 107//5 +f 377//5 381//5 733//5 +f 113//5 103//5 101//5 +f 373//5 733//5 153//5 +f 113//5 111//5 109//5 +f 145//5 358//5 362//5 +f 244//5 101//5 99//5 +f 143//5 141//5 358//5 +f 115//5 113//5 1086//5 +f 139//5 354//5 141//5 +f 119//5 115//5 1086//5 +f 167//5 733//5 737//5 +f 119//5 117//5 115//5 +f 135//5 350//5 137//5 +f 119//5 1086//5 1084//5 +f 14//5 741//5 745//5 +f 121//5 119//5 1081//5 +f 14//5 745//5 749//5 +f 439//5 121//5 237//5 +f 14//5 749//5 753//5 +f 125//5 123//5 121//5 +f 14//5 761//5 765//5 +f 125//5 121//5 419//5 +f 14//5 765//5 769//5 +f 127//5 125//5 399//5 +f 14//5 769//5 773//5 +f 131//5 364//5 360//5 +f 14//5 757//5 761//5 +f 131//5 360//5 356//5 +f 14//5 781//5 785//5 +f 129//5 127//5 387//5 +f 14//5 777//5 781//5 +f 131//5 356//5 352//5 +f 807//5 803//5 14//5 +f 131//5 352//5 348//5 +f 811//5 807//5 14//5 +f 131//5 348//5 344//5 +f 815//5 811//5 14//5 +f 131//5 129//5 368//5 +f 816//5 815//5 14//5 +f 342//5 131//5 344//5 +f 813//5 816//5 14//5 +f 342//5 346//5 131//5 +f 809//5 813//5 14//5 +f 131//5 346//5 133//5 +f 805//5 809//5 14//5 +f 133//5 346//5 135//5 +f 801//5 805//5 14//5 +f 135//5 346//5 350//5 +f 797//5 801//5 14//5 +f 137//5 350//5 139//5 +f 793//5 797//5 14//5 +f 139//5 350//5 354//5 +f 789//5 793//5 14//5 +f 141//5 354//5 358//5 +f 785//5 789//5 14//5 +f 143//5 358//5 145//5 +f 773//5 777//5 14//5 +f 145//5 362//5 147//5 +f 753//5 757//5 14//5 +f 362//5 366//5 148//5 +f 737//5 741//5 14//5 +f 14//5 197//5 195//5 +f 14//5 193//5 191//5 +f 14//5 189//5 15//5 +f 16//5 5//5 3//5 +f 16//5 2//5 13//5 +f 16//5 186//5 184//5 +f 183//5 274//5 16//5 +f 16//5 184//5 183//5 +f 16//5 3//5 2//5 +f 14//5 191//5 189//5 +f 193//5 14//5 195//5 +f 369//5 151//5 149//5 +f 14//5 16//5 175//5 +f 155//5 153//5 733//5 +f 14//5 175//5 173//5 +f 157//5 155//5 733//5 +f 14//5 173//5 171//5 +f 159//5 157//5 733//5 +f 737//5 171//5 169//5 +f 161//5 159//5 733//5 +f 13//5 186//5 16//5 +f 163//5 161//5 733//5 +f 737//5 169//5 167//5 +f 165//5 163//5 733//5 +f 733//5 167//5 165//5 +f 16//5 15//5 5//5 +f 171//5 737//5 14//5 +f 711//5 707//5 703//5 +f 459//5 455//5 234//5 +f 715//5 703//5 699//5 +f 463//5 459//5 234//5 +f 719//5 699//5 695//5 +f 467//5 463//5 234//5 +f 723//5 695//5 691//5 +f 471//5 467//5 234//5 +f 715//5 711//5 703//5 +f 475//5 471//5 234//5 +f 1087//5 691//5 687//5 +f 479//5 475//5 234//5 +f 1087//5 687//5 683//5 +f 483//5 479//5 234//5 +f 719//5 715//5 699//5 +f 487//5 483//5 234//5 +f 1087//5 683//5 679//5 +f 491//5 487//5 234//5 +f 723//5 719//5 695//5 +f 495//5 491//5 234//5 +f 727//5 723//5 691//5 +f 499//5 495//5 234//5 +f 1087//5 679//5 675//5 +f 503//5 499//5 234//5 +f 1087//5 727//5 691//5 +f 507//5 503//5 234//5 +f 1087//5 731//5 727//5 +f 511//5 507//5 234//5 +f 1087//5 1088//5 731//5 +f 515//5 511//5 234//5 +f 731//5 1088//5 735//5 +f 519//5 515//5 234//5 +f 1088//5 743//5 739//5 +f 523//5 519//5 234//5 +f 200//5 803//5 799//5 +f 527//5 523//5 234//5 +f 200//5 799//5 795//5 +f 531//5 527//5 234//5 +f 200//5 14//5 803//5 +f 535//5 531//5 234//5 +f 200//5 795//5 791//5 +f 539//5 535//5 234//5 +f 200//5 791//5 787//5 +f 543//5 539//5 234//5 +f 200//5 787//5 783//5 +f 547//5 543//5 234//5 +f 200//5 783//5 779//5 +f 551//5 547//5 234//5 +f 200//5 779//5 775//5 +f 232//5 551//5 234//5 +f 200//5 775//5 771//5 +f 232//5 555//5 551//5 +f 200//5 771//5 767//5 +f 232//5 206//5 555//5 +f 200//5 767//5 763//5 +f 555//5 205//5 559//5 +f 200//5 763//5 759//5 +f 559//5 1089//5 563//5 +f 200//5 759//5 755//5 +f 1090//5 571//5 567//5 +f 200//5 755//5 751//5 +f 1090//5 575//5 571//5 +f 1088//5 751//5 747//5 +f 1090//5 579//5 575//5 +f 1088//5 747//5 743//5 +f 1090//5 1091//5 579//5 +f 203//5 675//5 671//5 +f 579//5 1091//5 583//5 +f 203//5 671//5 667//5 +f 583//5 1091//5 587//5 +f 203//5 667//5 663//5 +f 587//5 1091//5 591//5 +f 203//5 663//5 659//5 +f 591//5 1091//5 595//5 +f 203//5 659//5 655//5 +f 1089//5 567//5 563//5 +f 1092//5 655//5 651//5 +f 595//5 1091//5 1093//5 +f 1092//5 651//5 647//5 +f 599//5 595//5 1093//5 +f 1092//5 647//5 643//5 +f 208//5 232//5 230//5 +f 1092//5 643//5 639//5 +f 212//5 230//5 228//5 +f 1092//5 639//5 635//5 +f 603//5 599//5 1093//5 +f 1094//5 635//5 631//5 +f 607//5 1093//5 17//5 +f 1094//5 631//5 627//5 +f 214//5 228//5 226//5 +f 1094//5 627//5 624//5 +f 611//5 607//5 17//5 +f 1094//5 624//5 621//5 +f 675//5 203//5 1087//5 +f 1088//5 200//5 751//5 +f 655//5 1092//5 203//5 +f 735//5 1088//5 739//5 +f 216//5 226//5 224//5 +f 224//5 222//5 220//5 +f 224//5 218//5 216//5 +f 228//5 214//5 212//5 +f 230//5 210//5 208//5 +f 555//5 206//5 205//5 +f 1093//5 607//5 603//5 +f 559//5 205//5 1089//5 +f 230//5 212//5 210//5 +f 224//5 220//5 218//5 +f 208//5 206//5 232//5 +f 621//5 17//5 1094//5 +f 1094//5 1092//5 635//5 +f 226//5 216//5 214//5 +f 567//5 1089//5 1090//5 +f 621//5 18//5 17//5 +f 19//5 611//5 17//5 +f 188//6 20//6 15//6 +f 25//7 21//7 23//7 +f 27//545 24//8 25//9 +f 29//546 26//10 27//11 +f 31//14 28//12 29//14 +f 33//16 30//15 31//15 +f 35//18 32//17 33//17 +f 37//19 34//19 35//19 +f 39//547 36//21 37//22 +f 41//23 38//23 39//23 +f 43//24 40//24 41//24 +f 45//25 42//25 43//25 +f 47//26 44//26 45//26 +f 49//27 46//27 47//27 +f 51//28 48//28 49//28 +f 53//29 50//29 51//29 +f 55//30 52//30 53//30 +f 57//31 54//31 55//31 +f 59//32 56//32 57//32 +f 61//34 58//33 59//34 +f 63//35 60//35 61//35 +f 65//37 62//36 63//37 +f 67//38 64//38 65//38 +f 69//39 66//39 67//39 +f 71//40 68//40 69//40 +f 73//41 70//41 71//41 +f 75//42 72//42 73//42 +f 77//43 74//43 75//43 +f 79//44 76//44 77//44 +f 81//45 78//45 79//45 +f 83//46 80//46 81//46 +f 85//47 82//47 83//47 +f 87//48 84//48 85//48 +f 89//49 86//49 87//49 +f 91//49 88//49 89//49 +f 93//49 90//49 91//49 +f 95//49 92//49 93//49 +f 97//49 94//49 95//49 +f 99//49 96//49 97//49 +f 101//49 98//49 99//49 +f 103//49 100//49 101//49 +f 105//49 102//49 103//49 +f 107//49 104//49 105//49 +f 109//49 106//49 107//49 +f 111//49 108//49 109//49 +f 113//50 110//50 111//50 +f 115//49 112//49 113//49 +f 117//51 114//51 115//51 +f 119//49 116//49 117//49 +f 121//52 118//52 119//52 +f 123//53 120//53 121//53 +f 125//54 122//54 123//54 +f 127//55 124//55 125//55 +f 129//56 126//56 127//56 +f 131//55 128//55 129//55 +f 133//57 130//57 131//57 +f 135//58 132//58 133//58 +f 137//59 134//59 135//59 +f 139//60 136//60 137//60 +f 141//61 138//61 139//61 +f 143//62 140//62 141//62 +f 145//63 142//63 143//63 +f 147//64 144//64 145//64 +f 148//65 146//65 147//65 +f 149//66 11//66 148//66 +f 151//67 9//67 149//67 +f 153//68 150//68 151//68 +f 155//69 152//69 153//69 +f 157//70 154//70 155//70 +f 159//71 156//71 157//71 +f 161//72 158//72 159//72 +f 163//73 160//73 161//73 +f 165//74 162//74 163//74 +f 167//75 164//75 165//75 +f 169//76 166//76 167//76 +f 171//77 168//77 169//77 +f 173//78 170//78 171//78 +f 175//79 172//79 173//79 +f 16//80 174//80 175//80 +f 178//3 174//3 277//3 +f 1095//3 311//3 312//3 +f 178//3 277//3 329//3 +f 1095//3 312//3 314//3 +f 178//3 329//3 331//3 +f 1095//3 314//3 316//3 +f 178//3 331//3 333//3 +f 1095//3 318//3 320//3 +f 178//3 333//3 335//3 +f 1095//3 316//3 318//3 +f 178//3 335//3 337//3 +f 1096//3 326//3 239//3 +f 178//3 337//3 279//3 +f 1097//3 239//3 1075//3 +f 178//3 279//3 278//3 +f 1097//3 179//3 239//3 +f 178//3 278//3 281//3 +f 239//3 179//3 1098//3 +f 178//3 281//3 283//3 +f 1099//3 239//3 1098//3 +f 178//3 283//3 285//3 +f 1100//3 239//3 1099//3 +f 178//3 285//3 287//3 +f 1096//3 239//3 1100//3 +f 178//3 287//3 289//3 +f 324//3 326//3 1096//3 +f 178//3 289//3 291//3 +f 324//3 1096//3 322//3 +f 178//3 291//3 293//3 +f 1096//3 1095//3 322//3 +f 178//3 293//3 295//3 +f 1095//3 320//3 322//3 +f 178//3 295//3 297//3 +f 309//3 311//3 1095//3 +f 178//3 297//3 299//3 +f 178//3 309//3 1095//3 +f 178//3 299//3 301//3 +f 178//3 307//3 309//3 +f 178//3 301//3 303//3 +f 178//3 177//3 307//3 +f 178//3 303//3 176//3 +f 1101//55 1100//55 1099//55 +f 275//55 1095//55 1096//55 +f 183//55 182//55 178//55 +f 178//55 274//55 183//55 +f 1096//55 1102//55 275//55 +f 1098//55 1103//55 1101//55 +f 1096//55 1104//55 1102//55 +f 275//55 274//55 178//55 +f 1101//55 1104//55 1100//55 +f 1103//55 1098//55 179//55 +f 180//55 1097//55 1075//55 +f 1084//55 1073//55 1074//55 +f 1074//55 1085//55 1084//55 +f 1075//55 1086//55 180//55 +f 179//55 181//55 1103//55 +f 1095//55 275//55 178//55 +f 1101//55 1099//55 1098//55 +f 1084//55 1075//55 1073//55 +f 1075//55 1084//55 1086//55 +f 1096//55 1100//55 1104//55 +f 179//55 1097//55 180//55 +f 185//55 182//55 184//55 +f 187//81 185//81 186//81 +f 12//82 187//82 13//82 +f 190//83 188//83 189//83 +f 192//84 190//84 191//84 +f 194//85 192//85 193//85 +f 196//86 194//86 195//86 +f 198//87 196//87 197//87 +f 199//88 198//88 14//88 +f 1060//89 199//89 200//89 +f 1089//49 1061//49 1062//49 +f 1089//49 205//49 204//49 +f 1062//49 1090//49 1089//49 +f 1064//49 1093//49 1091//49 +f 8//49 1094//49 17//49 +f 201//49 203//49 1092//49 +f 1060//49 200//49 1088//49 +f 201//49 1092//49 1094//49 +f 1059//49 1088//49 1087//49 +f 1088//49 1059//49 1060//49 +f 1087//49 202//49 1058//49 +f 1094//49 8//49 201//49 +f 1093//49 1064//49 1065//49 +f 1089//49 204//49 1061//49 +f 1091//49 1063//49 1064//49 +f 1087//49 1058//49 1059//49 +f 17//49 1065//49 8//49 +f 1091//49 1090//49 1062//49 +f 1065//49 17//49 1093//49 +f 203//49 202//49 1087//49 +f 1091//49 1062//49 1063//49 +f 207//49 204//49 206//49 +f 209//90 207//90 208//90 +f 211//91 209//91 210//91 +f 213//92 211//92 212//92 +f 215//93 213//93 214//93 +f 217//94 215//94 216//94 +f 219//95 217//95 218//95 +f 221//96 219//96 220//96 +f 223//97 221//97 222//97 +f 225//98 223//98 224//98 +f 227//99 225//99 226//99 +f 229//100 227//100 228//100 +f 231//101 229//101 230//101 +f 233//102 231//102 232//102 +f 1057//102 233//102 234//102 +f 1080//102 1069//102 1068//102 +f 1076//102 236//102 1070//102 +f 1083//102 1072//102 1071//102 +f 1076//102 1070//102 1069//102 +f 1082//102 1071//102 235//102 +f 1083//102 1085//102 1074//102 +f 1071//102 1082//102 1083//102 +f 235//102 237//102 1081//102 +f 1069//102 1080//102 1076//102 +f 1067//102 1078//102 1079//102 +f 1057//102 234//102 1077//102 +f 1077//102 1066//102 1057//102 +f 1079//102 1068//102 1067//102 +f 1083//102 1074//102 1072//102 +f 235//102 1081//102 1082//102 +f 1068//102 1079//102 1080//102 +f 1067//102 1066//102 1077//102 +f 1076//102 237//102 236//102 +f 1067//102 1077//102 1078//102 +f 242//49 238//49 240//49 +f 244//49 241//49 242//49 +f 246//103 243//103 244//103 +f 248//105 245//104 246//105 +f 250//106 247//106 248//106 +f 252//107 249//107 250//107 +f 254//108 251//108 252//108 +f 256//109 253//109 254//109 +f 258//110 255//110 256//110 +f 260//111 257//111 258//111 +f 262//112 259//112 260//112 +f 264//113 261//113 262//113 +f 266//114 263//114 264//114 +f 268//115 265//115 266//115 +f 270//116 267//116 268//118 +f 272//119 269//119 270//116 +f 273//548 271//120 272//119 +f 23//122 22//121 273//122 +f 275//5 313//5 276//5 +f 330//5 16//5 274//5 +f 275//5 315//5 313//5 +f 332//5 330//5 274//5 +f 275//5 317//5 315//5 +f 334//5 332//5 274//5 +f 275//5 321//5 319//5 +f 336//5 334//5 274//5 +f 275//5 319//5 317//5 +f 338//5 336//5 274//5 +f 1102//5 328//5 327//5 +f 339//5 338//5 274//5 +f 1102//5 240//5 328//5 +f 280//5 339//5 274//5 +f 1102//5 327//5 325//5 +f 282//5 280//5 274//5 +f 275//5 325//5 323//5 +f 284//5 282//5 274//5 +f 275//5 323//5 321//5 +f 286//5 284//5 274//5 +f 180//5 1086//5 240//5 +f 288//5 286//5 274//5 +f 181//5 180//5 240//5 +f 290//5 288//5 274//5 +f 1103//5 181//5 240//5 +f 292//5 290//5 274//5 +f 1101//5 1103//5 240//5 +f 294//5 292//5 274//5 +f 1104//5 1101//5 240//5 +f 296//5 294//5 274//5 +f 1102//5 1104//5 240//5 +f 298//5 296//5 274//5 +f 275//5 1102//5 325//5 +f 300//5 298//5 274//5 +f 274//5 276//5 310//5 +f 302//5 300//5 274//5 +f 274//5 310//5 308//5 +f 304//5 302//5 274//5 +f 274//5 308//5 306//5 +f 305//5 304//5 274//5 +f 274//5 306//5 305//5 +f 330//123 277//123 16//123 +f 282//124 278//124 280//124 +f 284//125 281//125 282//125 +f 286//126 283//126 284//126 +f 288//127 285//127 286//127 +f 290//549 287//128 288//128 +f 292//129 289//129 290//129 +f 294//130 291//130 292//130 +f 296//131 293//131 294//131 +f 298//132 295//132 296//132 +f 300//133 297//133 298//133 +f 302//134 299//134 300//134 +f 304//135 301//135 302//135 +f 305//136 303//136 304//136 +f 306//137 176//137 305//137 +f 308//138 177//138 306//138 +f 310//139 307//139 308//139 +f 276//140 309//140 310//140 +f 313//49 311//49 276//49 +f 315//49 312//49 313//49 +f 317//49 314//49 315//49 +f 319//49 316//49 317//49 +f 321//49 318//49 319//49 +f 323//49 320//49 321//49 +f 325//49 322//49 323//49 +f 327//49 324//49 325//49 +f 328//49 326//49 327//49 +f 240//49 239//49 328//49 +f 332//141 329//141 330//141 +f 334//142 331//142 332//142 +f 336//143 333//143 334//143 +f 338//144 335//144 336//144 +f 339//145 337//145 338//145 +f 280//146 279//146 339//146 +f 344//147 340//147 342//147 +f 348//148 343//148 344//148 +f 342//149 341//149 346//149 +f 352//150 347//150 348//150 +f 346//151 345//151 350//151 +f 356//152 351//152 352//152 +f 350//153 349//153 354//153 +f 360//155 355//154 356//155 +f 354//156 353//156 358//156 +f 364//157 359//157 360//157 +f 358//158 357//158 362//158 +f 368//159 363//159 364//159 +f 362//160 361//160 366//160 +f 371//161 367//161 368//161 +f 366//162 365//162 369//162 +f 375//163 370//163 371//163 +f 369//164 10//164 373//164 +f 379//165 374//165 375//165 +f 373//166 372//166 377//166 +f 383//167 378//167 379//167 +f 377//168 376//168 381//168 +f 387//169 382//169 383//169 +f 381//170 380//170 385//170 +f 391//171 386//171 387//171 +f 385//172 384//172 389//172 +f 395//173 390//173 391//173 +f 389//174 388//174 393//174 +f 399//175 394//175 395//175 +f 393//176 392//176 397//176 +f 403//177 398//177 399//177 +f 397//178 396//178 401//178 +f 407//179 402//179 403//179 +f 401//180 400//180 405//180 +f 411//181 406//181 407//181 +f 405//182 404//182 409//182 +f 415//183 410//183 411//183 +f 409//184 408//184 413//184 +f 419//185 414//185 415//185 +f 413//186 412//186 417//186 +f 423//187 418//187 419//187 +f 417//188 416//188 421//188 +f 427//189 422//189 423//189 +f 421//190 420//190 425//190 +f 431//191 426//191 427//191 +f 425//192 424//192 429//192 +f 435//193 430//193 431//193 +f 429//194 428//194 433//194 +f 439//195 434//195 435//195 +f 433//196 432//196 437//196 +f 443//197 438//197 439//197 +f 437//198 436//198 441//198 +f 447//199 442//199 443//199 +f 441//200 440//200 445//200 +f 451//201 446//201 447//201 +f 445//202 444//202 449//202 +f 455//203 450//203 451//203 +f 449//204 448//204 453//204 +f 459//205 454//205 455//205 +f 453//206 452//206 457//206 +f 463//207 458//207 459//207 +f 457//208 456//208 461//208 +f 467//209 462//209 463//209 +f 461//210 460//210 465//210 +f 471//211 466//211 467//211 +f 465//212 464//212 469//212 +f 475//213 470//213 471//213 +f 469//214 468//214 473//214 +f 479//215 474//215 475//215 +f 473//216 472//216 477//216 +f 483//217 478//217 479//217 +f 477//218 476//218 481//218 +f 487//219 482//219 483//219 +f 481//220 480//220 485//220 +f 491//221 486//221 487//221 +f 485//222 484//222 489//222 +f 495//223 490//223 491//223 +f 489//224 488//224 493//224 +f 499//225 494//225 495//225 +f 493//226 492//226 497//226 +f 503//227 498//227 499//227 +f 497//550 496//550 501//550 +f 507//229 502//229 503//229 +f 501//551 500//551 505//551 +f 511//232 506//231 507//232 +f 505//552 504//233 509//234 +f 515//235 510//235 511//235 +f 509//553 508//236 513//238 +f 519//239 514//239 515//239 +f 513//241 512//240 517//241 +f 523//242 518//242 519//242 +f 517//244 516//244 521//244 +f 527//246 522//246 523//246 +f 521//245 520//244 525//554 +f 531//248 526//248 527//248 +f 525//555 524//555 529//555 +f 535//250 530//250 531//250 +f 529//252 528//251 533//252 +f 539//253 534//253 535//253 +f 533//556 532//556 537//556 +f 543//255 538//255 539//255 +f 537//257 536//256 541//257 +f 547//258 542//258 543//258 +f 541//557 540//259 545//261 +f 551//262 546//262 547//262 +f 545//558 544//263 549//265 +f 555//266 550//266 551//266 +f 549//559 548//267 553//267 +f 559//269 554//269 555//269 +f 553//271 552//270 557//271 +f 563//272 558//272 559//272 +f 557//275 556//273 561//275 +f 567//276 562//276 563//276 +f 561//560 560//277 565//277 +f 571//279 566//279 567//279 +f 565//561 564//280 569//281 +f 575//282 570//282 571//282 +f 569//562 568//283 573//284 +f 579//285 574//285 575//285 +f 573//563 572//286 577//288 +f 583//289 578//289 579//289 +f 577//564 576//290 581//292 +f 587//293 582//293 583//293 +f 581//296 580//294 585//296 +f 591//297 586//297 587//297 +f 585//565 584//298 589//300 +f 595//301 590//301 591//301 +f 589//566 588//302 593//303 +f 599//304 594//304 595//304 +f 593//305 592//305 597//305 +f 603//306 598//306 599//306 +f 597//307 596//307 601//307 +f 607//308 602//308 603//308 +f 601//309 600//309 605//309 +f 611//310 606//310 607//310 +f 605//311 604//311 609//311 +f 19//312 610//312 611//312 +f 609//313 608//313 613//313 +f 18//314 614//314 19//314 +f 613//315 612//315 616//315 +f 621//316 617//316 18//316 +f 616//317 615//317 619//317 +f 624//318 620//318 621//318 +f 619//319 618//319 623//320 +f 627//321 6//321 624//321 +f 623//320 622//320 626//323 +f 631//324 7//324 627//324 +f 626//325 625//325 629//325 +f 635//326 630//326 631//326 +f 629//327 628//327 633//327 +f 639//328 634//328 635//328 +f 633//330 632//329 637//330 +f 643//331 638//331 639//331 +f 637//332 636//332 641//332 +f 647//333 642//333 643//333 +f 641//332 640//332 645//332 +f 651//334 646//334 647//334 +f 645//332 644//332 649//332 +f 655//335 650//335 651//335 +f 649//332 648//332 653//332 +f 659//336 654//336 655//336 +f 653//332 652//332 657//332 +f 663//337 658//337 659//337 +f 657//332 656//332 661//332 +f 667//338 662//338 663//338 +f 661//332 660//332 665//332 +f 671//339 666//339 667//339 +f 665//332 664//332 669//332 +f 675//340 670//340 671//340 +f 669//332 668//332 673//332 +f 679//341 674//341 675//341 +f 673//332 672//332 677//332 +f 683//342 678//342 679//342 +f 677//332 676//332 681//332 +f 687//343 682//343 683//343 +f 681//332 680//332 685//332 +f 691//344 686//344 687//344 +f 685//345 684//345 689//345 +f 695//346 690//346 691//346 +f 689//347 688//347 693//347 +f 699//348 694//348 695//348 +f 693//349 692//349 697//349 +f 703//350 698//350 699//350 +f 697//351 696//351 701//351 +f 707//352 702//352 703//352 +f 701//353 700//353 705//353 +f 711//354 706//354 707//354 +f 705//355 704//355 709//355 +f 715//356 710//356 711//356 +f 709//357 708//357 713//357 +f 719//358 714//358 715//358 +f 713//359 712//359 717//359 +f 723//360 718//360 719//360 +f 717//361 716//361 721//361 +f 727//362 722//362 723//362 +f 721//363 720//363 725//363 +f 731//364 726//364 727//364 +f 725//365 724//365 729//365 +f 735//366 730//366 731//366 +f 729//296 728//296 733//296 +f 739//367 734//367 735//367 +f 733//49 732//49 737//49 +f 743//368 738//368 739//368 +f 737//369 736//369 741//369 +f 747//370 742//370 743//370 +f 741//369 740//369 745//369 +f 751//371 746//371 747//371 +f 745//369 744//369 749//369 +f 755//372 750//372 751//372 +f 749//369 748//369 753//369 +f 759//373 754//373 755//373 +f 753//369 752//369 757//369 +f 763//374 758//374 759//374 +f 757//369 756//369 761//369 +f 767//375 762//375 763//375 +f 761//369 760//369 765//369 +f 771//376 766//376 767//376 +f 765//369 764//369 769//377 +f 775//378 770//378 771//378 +f 769//377 768//377 773//369 +f 779//379 774//379 775//379 +f 773//369 772//369 777//369 +f 783//380 778//380 779//380 +f 777//369 776//369 781//377 +f 787//381 782//381 783//381 +f 781//377 780//377 785//369 +f 791//382 786//382 787//382 +f 785//383 784//383 789//383 +f 795//384 790//384 791//384 +f 789//385 788//385 793//385 +f 799//386 794//386 795//386 +f 793//387 792//387 797//387 +f 803//388 798//388 799//388 +f 797//389 796//389 801//389 +f 807//390 802//390 803//390 +f 801//391 800//391 805//391 +f 811//392 806//392 807//392 +f 805//393 804//393 809//393 +f 815//394 810//394 811//394 +f 809//395 808//395 813//395 +f 816//396 814//396 815//396 +f 813//397 812//397 816//397 +f 1024//3 960//3 956//3 +f 1028//3 1032//3 964//3 +f 1054//3 975//3 971//3 +f 1018//541 1003//541 979//3 +f 983//3 991//3 987//3 +f 983//3 979//3 995//3 +f 1010//567 1007//568 1003//541 +f 1018//569 1014//569 1010//569 +f 979//3 1022//3 1018//541 +f 979//3 1030//3 1026//3 +f 979//3 1038//3 1034//3 +f 975//3 1046//3 1042//3 +f 975//3 1054//3 1050//3 +f 971//3 1048//3 1052//3 +f 971//3 1040//3 1044//3 +f 1040//3 968//3 1036//3 +f 960//3 1024//3 1028//3 +f 952//3 1016//3 1020//3 +f 948//3 1009//3 1012//3 +f 942//3 1001//3 1005//3 +f 934//3 993//3 997//3 +f 926//3 985//3 989//3 +f 918//3 977//3 981//3 +f 818//3 817//3 973//3 +f 904//3 962//3 966//3 +f 896//3 954//3 958//3 +f 888//3 946//3 950//3 +f 946//3 884//3 943//3 +f 876//3 932//3 936//3 +f 868//3 924//3 928//3 +f 864//3 916//3 920//3 +f 916//3 856//3 912//3 +f 848//3 902//3 906//3 +f 882//3 894//3 898//3 +f 894//3 886//3 890//3 +f 844//3 878//3 882//3 +f 844//3 870//3 874//3 +f 844//3 862//3 866//3 +f 844//3 840//3 858//3 +f 840//3 846//3 850//3 +f 840//3 838//3 842//3 +f 840//3 830//3 834//3 +f 836//3 823//3 826//3 +f 832//3 828//3 824//3 +f 823//3 836//3 832//3 +f 842//3 846//3 840//3 +f 906//3 852//3 848//3 +f 852//3 909//3 856//3 +f 920//3 868//3 864//3 +f 932//3 876//3 872//3 +f 936//3 940//3 880//3 +f 950//3 892//3 888//3 +f 958//3 900//3 896//3 +f 966//3 819//3 904//3 +f 973//3 914//3 818//3 +f 981//3 922//3 918//3 +f 989//3 930//3 926//3 +f 997//3 938//3 934//3 +f 1005//3 945//3 942//3 +f 1012//3 952//3 948//3 +f 1028//3 964//3 960//3 +f 1042//3 979//3 975//3 +f 983//3 995//3 991//3 +f 1018//541 1010//567 1003//541 +f 979//3 1026//3 1022//3 +f 979//3 1042//3 1038//3 +f 971//3 1052//3 1054//3 +f 971//3 968//3 1040//3 +f 956//3 1020//3 1024//3 +f 945//3 1005//3 1009//3 +f 930//3 989//3 993//3 +f 914//3 973//3 977//3 +f 900//3 958//3 962//3 +f 888//3 884//3 946//3 +f 872//3 928//3 932//3 +f 864//3 860//3 916//3 +f 848//3 844//3 902//3 +f 894//3 882//3 886//3 +f 844//3 866//3 870//3 +f 858//3 840//3 854//3 +f 840//3 834//3 838//3 +f 832//3 824//3 823//3 +f 826//3 840//3 836//3 +f 906//3 909//3 852//3 +f 928//3 872//3 868//3 +f 880//3 940//3 943//3 +f 962//3 904//3 900//3 +f 977//3 918//3 914//3 +f 993//3 934//3 930//3 +f 1009//3 948//3 945//3 +f 964//3 1032//3 968//3 +f 995//3 979//3 999//3 +f 979//3 1034//3 1030//3 +f 971//3 1044//3 1048//3 +f 952//3 1012//3 1016//3 +f 926//3 922//3 985//3 +f 896//3 892//3 954//3 +f 868//3 920//3 924//3 +f 844//3 882//3 898//3 +f 844//3 858//3 862//3 +f 840//3 826//3 830//3 +f 840//3 850//3 854//3 +f 936//3 880//3 876//3 +f 966//3 817//3 819//3 +f 997//3 1001//3 938//3 +f 979//3 1003//541 999//3 +f 975//3 1050//3 1046//3 +f 942//3 938//3 1001//3 +f 954//3 892//3 950//3 +f 902//3 844//3 898//3 +f 874//3 878//3 844//3 +f 884//3 880//3 943//3 +f 1020//3 956//3 952//3 +f 1036//3 968//3 1032//3 +f 916//3 860//3 856//3 +f 856//3 909//3 912//3 +f 922//3 981//3 985//3 +f 1002//5 935//5 939//5 +f 994//5 927//5 931//5 +f 990//5 986//5 923//5 +f 982//5 978//5 915//5 +f 970//5 905//5 908//5 +f 963//5 897//5 901//5 +f 959//5 955//5 893//5 +f 951//5 947//5 885//5 +f 937//5 873//5 877//5 +f 929//5 925//5 869//5 +f 921//5 857//5 861//5 +f 910//5 849//5 853//5 +f 863//5 841//5 845//5 +f 827//5 833//5 837//5 +f 833//5 825//5 829//5 +f 837//5 831//5 827//5 +f 841//5 839//5 835//5 +f 841//5 847//5 843//5 +f 841//5 855//5 851//5 +f 841//5 863//5 859//5 +f 845//5 871//5 867//5 +f 845//5 879//5 875//5 +f 845//5 887//5 883//5 +f 899//5 895//5 891//5 +f 887//5 903//5 899//5 +f 849//5 910//5 907//5 +f 857//5 917//5 913//5 +f 861//5 865//5 921//5 +f 869//5 933//5 929//5 +f 877//5 941//5 937//5 +f 941//5 881//5 944//5 +f 885//5 889//5 951//5 +f 897//5 963//5 959//5 +f 905//5 970//5 967//5 +f 908//5 911//5 974//5 +f 915//5 919//5 982//5 +f 927//5 994//5 990//5 +f 935//5 1002//5 998//5 +f 939//5 821//5 1006//5 +f 822//5 949//5 1013//5 +f 953//5 1025//5 1021//5 +f 961//5 1033//5 1029//5 +f 969//5 1041//5 1037//5 +f 969//5 972//5 1045//5 +f 972//5 1056//5 1053//5 +f 972//5 976//5 1055//5 +f 976//5 1043//5 1047//5 +f 980//5 1035//5 1039//5 +f 980//5 1027//5 1031//5 +f 1015//570 1019//571 1023//5 +f 1008//572 1011//572 1015//572 +f 1000//573 1004//573 1008//573 +f 980//5 996//5 1000//5 +f 984//5 988//5 992//5 +f 996//5 980//5 984//5 +f 980//5 1031//5 1035//5 +f 1037//5 965//5 969//5 +f 1029//5 957//5 961//5 +f 1021//5 1017//5 953//5 +f 1013//5 820//5 822//5 +f 998//5 931//5 935//5 +f 923//5 986//5 919//5 +f 967//5 901//5 905//5 +f 893//5 955//5 889//5 +f 933//5 869//5 873//5 +f 913//5 853//5 857//5 +f 835//5 831//5 841//5 +f 833//5 827//5 825//5 +f 841//5 843//5 839//5 +f 841//5 859//5 855//5 +f 845//5 875//5 871//5 +f 899//5 891//5 887//5 +f 845//5 907//5 903//5 +f 857//5 921//5 917//5 +f 873//5 937//5 933//5 +f 944//5 881//5 947//5 +f 901//5 967//5 963//5 +f 974//5 911//5 978//5 +f 931//5 998//5 994//5 +f 1006//5 821//5 820//5 +f 957//5 1029//5 1025//5 +f 969//5 1045//5 1041//5 +f 972//5 1055//5 1056//5 +f 976//5 980//5 1043//5 +f 980//5 1023//5 1027//5 +f 1000//5 1008//5 1015//570 +f 984//5 992//5 996//5 +f 1000//5 1023//5 980//5 +f 1033//5 961//5 965//5 +f 953//5 1017//5 949//5 +f 990//5 923//5 927//5 +f 959//5 893//5 897//5 +f 869//5 925//5 865//5 +f 841//5 831//5 837//5 +f 841//5 851//5 847//5 +f 845//5 883//5 879//5 +f 853//5 913//5 910//5 +f 877//5 881//5 941//5 +f 908//5 974//5 970//5 +f 939//5 1006//5 1002//5 +f 965//5 1037//5 1033//5 +f 1055//5 976//5 1051//5 +f 1000//5 1015//570 1023//5 +f 980//5 1039//5 1043//5 +f 1025//5 953//5 957//5 +f 919//5 986//5 982//5 +f 907//5 845//5 849//5 +f 845//5 867//5 863//5 +f 921//5 865//5 925//5 +f 978//5 911//5 915//5 +f 1045//5 972//5 1049//5 +f 1047//5 1051//5 976//5 +f 949//5 1017//5 1013//5 +f 903//5 887//5 845//5 +f 947//5 881//5 885//5 +f 1049//5 972//5 1053//5 +f 889//5 955//5 951//5 +f 827//398 823//398 825//398 +f 831//399 826//399 827//399 +f 825//400 824//400 829//400 +f 835//401 830//401 831//401 +f 829//402 828//402 833//402 +f 839//403 834//403 835//403 +f 833//404 832//404 837//404 +f 843//405 838//405 839//405 +f 837//406 836//406 841//406 +f 847//407 842//407 843//407 +f 841//408 840//408 845//408 +f 851//409 846//409 847//409 +f 845//411 844//411 849//411 +f 855//574 850//412 851//412 +f 849//413 848//413 853//413 +f 859//414 854//414 855//414 +f 853//415 852//415 857//415 +f 863//416 858//416 859//416 +f 857//417 856//417 861//417 +f 867//418 862//418 863//418 +f 861//420 860//419 865//420 +f 871//421 866//421 867//421 +f 865//424 864//423 869//424 +f 875//425 870//425 871//425 +f 869//427 868//427 873//427 +f 879//428 874//428 875//428 +f 873//429 872//429 877//429 +f 883//430 878//430 879//430 +f 877//431 876//431 881//431 +f 887//432 882//432 883//432 +f 881//433 880//433 885//433 +f 891//434 886//434 887//434 +f 885//435 884//435 889//435 +f 895//436 890//436 891//436 +f 889//437 888//437 893//437 +f 899//438 894//438 895//438 +f 893//439 892//439 897//439 +f 903//440 898//440 899//440 +f 897//441 896//441 901//441 +f 907//442 902//442 903//442 +f 901//443 900//443 905//443 +f 910//444 906//444 907//444 +f 905//445 904//445 908//445 +f 913//446 909//446 910//446 +f 908//447 819//447 911//447 +f 917//448 912//448 913//448 +f 911//449 818//449 915//449 +f 921//450 916//450 917//450 +f 915//451 914//451 919//451 +f 925//452 920//452 921//452 +f 919//453 918//453 923//453 +f 929//454 924//454 925//454 +f 923//455 922//455 927//455 +f 933//456 928//456 929//456 +f 927//457 926//457 931//457 +f 937//458 932//458 933//458 +f 931//459 930//459 935//459 +f 941//460 936//460 937//460 +f 935//461 934//461 939//461 +f 944//462 940//462 941//462 +f 939//463 938//463 821//463 +f 947//464 943//464 944//464 +f 821//465 942//465 822//465 +f 951//466 946//466 947//466 +f 822//467 945//467 949//467 +f 955//468 950//468 951//468 +f 949//469 948//469 953//469 +f 959//470 954//470 955//470 +f 953//471 952//471 957//471 +f 963//472 958//472 959//472 +f 957//473 956//473 961//473 +f 967//474 962//474 963//474 +f 961//475 960//475 965//475 +f 970//476 966//476 967//476 +f 965//477 964//477 969//477 +f 974//478 817//478 970//478 +f 969//480 968//479 972//480 +f 978//481 973//481 974//481 +f 972//482 971//482 976//482 +f 982//483 977//483 978//483 +f 976//484 975//484 980//484 +f 986//485 981//485 982//485 +f 980//486 979//486 984//486 +f 990//487 985//487 986//487 +f 984//488 983//488 988//488 +f 994//489 989//489 990//489 +f 988//490 987//490 992//490 +f 998//491 993//491 994//491 +f 992//492 991//492 996//492 +f 1002//493 997//493 998//493 +f 996//302 995//302 1000//302 +f 1006//494 1001//494 1002//494 +f 1000//495 999//495 1004//495 +f 820//496 1005//496 1006//496 +f 1004//497 1003//497 1008//497 +f 1013//498 1009//498 820//498 +f 1008//500 1007//499 1011//499 +f 1017//501 1012//501 1013//501 +f 1011//575 1010//254 1015//254 +f 1021//502 1016//502 1017//502 +f 1015//503 1014//503 1019//503 +f 1025//504 1020//504 1021//504 +f 1019//576 1018//505 1023//505 +f 1029//507 1024//507 1025//507 +f 1023//509 1022//508 1027//510 +f 1033//511 1028//511 1029//511 +f 1027//513 1026//512 1031//513 +f 1037//514 1032//514 1033//514 +f 1031//515 1030//515 1035//515 +f 1041//516 1036//516 1037//516 +f 1035//518 1034//517 1039//518 +f 1045//519 1040//519 1041//519 +f 1039//520 1038//520 1043//520 +f 1049//521 1044//521 1045//521 +f 1043//523 1042//522 1047//522 +f 1053//524 1048//524 1049//524 +f 1047//525 1046//525 1051//525 +f 1056//526 1052//526 1053//526 +f 1051//527 1050//527 1055//527 +f 1055//528 1054//528 1056//528 +o Curve_path22 +v 0.133501 -0.000000 1.118326 +v 0.133501 -0.000000 1.118326 +v 0.133052 -0.000000 1.118264 +v 0.133954 -0.000000 1.118385 +v 0.133954 -0.000000 1.118385 +v 0.134409 -0.000000 1.118442 +v 0.134409 -0.000000 1.118442 +v 0.134866 -0.000000 1.118497 +v 0.134866 -0.000000 1.118497 +v 0.135325 -0.000000 1.118550 +v 0.135325 -0.000000 1.118550 +v 0.135784 -0.000000 1.118602 +v 0.135784 -0.000000 1.118602 +v 0.136243 -0.000000 1.118652 +v 0.136243 -0.000000 1.118652 +v 0.136702 -0.000000 1.118701 +v 0.136702 -0.000000 1.118701 +v 0.137159 -0.000000 1.118750 +v 0.137159 -0.000000 1.118750 +v 0.137614 -0.000000 1.118798 +v 0.137614 -0.000000 1.118798 +v 0.138067 -0.000000 1.118845 +v 0.138067 -0.000000 1.118845 +v 0.138516 -0.000000 1.118892 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 -0.000000 +vn -0.000000 1.000000 -0.000000 +vn -0.000000 1.000000 -0.000100 +vn -0.000300 1.000000 0.000000 +vn 0.000000 0.000000 -0.000100 +usemtl SVGMat.001 +s 1 +f 1105//577 1106//577 1107//577 +f 1105//577 1108//577 1106//577 +f 1109//577 1108//577 1105//577 +f 1109//577 1110//577 1108//577 +f 1111//578 1110//579 1109//579 +f 1111//580 1112//581 1110//578 +f 1113//579 1112//581 1111//580 +f 1113//579 1114//581 1112//581 +f 1115//579 1114//581 1113//579 +f 1115//579 1116//579 1114//581 +f 1117//578 1116//579 1115//579 +f 1117//580 1118//579 1116//582 +f 1119//577 1118//577 1117//577 +f 1119//577 1120//577 1118//577 +f 1121//577 1120//577 1119//577 +f 1121//577 1122//577 1120//577 +f 1123//577 1122//577 1121//577 +f 1123//577 1124//577 1122//577 +f 1125//578 1124//579 1123//580 +f 1125//579 1126//579 1124//578 +f 1127//581 1126//579 1125//579 +f 1127//581 1128//579 1126//579 +o Curve.003_path34 +v 0.131158 -0.000000 1.117179 +v 0.139489 -0.000000 1.117165 +v 0.130979 -0.000000 1.117165 +v 0.148988 -0.000000 1.117165 +v 0.159145 -0.000000 1.117165 +v 0.169632 -0.000000 1.117165 +v 0.180118 -0.000000 1.117165 +v 0.190275 -0.000000 1.117165 +v 0.199774 -0.000000 1.117165 +v 0.208284 -0.000000 1.117165 +v 0.215477 -0.000000 1.117165 +v 0.221022 -0.000000 1.117165 +v 0.224591 -0.000000 1.117165 +v 0.225853 -0.000000 1.117165 +v 0.221277 -0.000000 1.117233 +v 0.131333 -0.000000 1.117217 +v 0.131506 -0.000000 1.117275 +v 0.216748 -0.000000 1.117421 +v 0.131677 -0.000000 1.117349 +v 0.131847 -0.000000 1.117434 +v 0.212268 -0.000000 1.117705 +v 0.132015 -0.000000 1.117526 +v 0.132185 -0.000000 1.117621 +v 0.132354 -0.000000 1.117714 +v 0.207836 -0.000000 1.118061 +v 0.132525 -0.000000 1.117801 +v 0.132698 -0.000000 1.117877 +v 0.132873 -0.000000 1.117939 +v 0.133052 -0.000000 1.117981 +v 0.133501 -0.000000 1.118049 +v 0.133954 -0.000000 1.118123 +v 0.203452 -0.000000 1.118464 +v 0.134409 -0.000000 1.118203 +v 0.134866 -0.000000 1.118287 +v 0.135325 -0.000000 1.118374 +v 0.135784 -0.000000 1.118460 +v 0.136243 -0.000000 1.118546 +v 0.199116 -0.000000 1.118892 +v 0.136702 -0.000000 1.118628 +v 0.137159 -0.000000 1.118706 +v 0.137614 -0.000000 1.118777 +v 0.138067 -0.000000 1.118839 +v 0.138516 -0.000000 1.118892 +v 0.141317 -0.000000 1.119183 +v 0.194828 -0.000000 1.119320 +v 0.144144 -0.000000 1.119445 +v 0.190587 -0.000000 1.119724 +v 0.146999 -0.000000 1.119678 +v 0.149884 -0.000000 1.119884 +v 0.186394 -0.000000 1.120079 +v 0.152797 -0.000000 1.120063 +v 0.155742 -0.000000 1.120215 +v 0.182248 -0.000000 1.120363 +v 0.158718 -0.000000 1.120341 +v 0.161726 -0.000000 1.120443 +v 0.178149 -0.000000 1.120551 +v 0.164767 -0.000000 1.120521 +v 0.167842 -0.000000 1.120576 +v 0.174098 -0.000000 1.120619 +v 0.170952 -0.000000 1.120608 +vn -0.000000 1.000000 0.000000 +usemtl SVGMat.004 +s 1 +f 1129//583 1130//583 1131//583 +f 1129//583 1132//583 1130//583 +f 1129//583 1133//583 1132//583 +f 1129//583 1134//583 1133//583 +f 1129//583 1135//583 1134//583 +f 1129//583 1136//583 1135//583 +f 1129//583 1137//583 1136//583 +f 1129//583 1138//583 1137//583 +f 1129//583 1139//583 1138//583 +f 1129//583 1140//583 1139//583 +f 1129//583 1141//583 1140//583 +f 1129//583 1142//583 1141//583 +f 1129//583 1143//583 1142//583 +f 1144//583 1143//583 1129//583 +f 1145//583 1143//583 1144//583 +f 1145//583 1146//583 1143//583 +f 1147//583 1146//583 1145//583 +f 1148//583 1146//583 1147//583 +f 1148//583 1149//583 1146//583 +f 1150//583 1149//583 1148//583 +f 1151//583 1149//583 1150//583 +f 1152//583 1149//583 1151//583 +f 1152//583 1153//583 1149//583 +f 1154//583 1153//583 1152//583 +f 1155//583 1153//583 1154//583 +f 1156//583 1153//583 1155//583 +f 1157//583 1153//583 1156//583 +f 1158//583 1153//583 1157//583 +f 1159//583 1153//583 1158//583 +f 1159//583 1160//583 1153//583 +f 1161//583 1160//583 1159//583 +f 1162//583 1160//583 1161//583 +f 1163//583 1160//583 1162//583 +f 1164//583 1160//583 1163//583 +f 1165//583 1160//583 1164//583 +f 1165//583 1166//583 1160//583 +f 1167//583 1166//583 1165//583 +f 1168//583 1166//583 1167//583 +f 1169//583 1166//583 1168//583 +f 1170//583 1166//583 1169//583 +f 1171//583 1166//583 1170//583 +f 1172//583 1166//583 1171//583 +f 1172//583 1173//583 1166//583 +f 1174//583 1173//583 1172//583 +f 1174//583 1175//583 1173//583 +f 1176//583 1175//583 1174//583 +f 1177//583 1175//583 1176//583 +f 1177//583 1178//583 1175//583 +f 1179//583 1178//583 1177//583 +f 1180//583 1178//583 1179//583 +f 1180//583 1181//583 1178//583 +f 1182//583 1181//583 1180//583 +f 1183//583 1181//583 1182//583 +f 1183//583 1184//583 1181//583 +f 1185//583 1184//583 1183//583 +f 1186//583 1184//583 1185//583 +f 1186//583 1187//583 1184//583 +f 1188//583 1187//583 1186//583 diff --git a/examples/qt3d/scene2d/main.cpp b/examples/qt3d/scene2d/main.cpp new file mode 100644 index 000000000..04c4ac58c --- /dev/null +++ b/examples/qt3d/scene2d/main.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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$ +** +****************************************************************************/ + +#include +#include + +int main(int argc, char **argv) +{ + QGuiApplication app(argc, argv); + + Qt3DExtras::Quick::Qt3DQuickWindow view; + view.setSource(QUrl("qrc:/main.qml")); + view.resize(1400, 1100); + view.show(); + + return app.exec(); +} diff --git a/examples/qt3d/scene2d/main.qml b/examples/qt3d/scene2d/main.qml new file mode 100644 index 000000000..d9d4676c2 --- /dev/null +++ b/examples/qt3d/scene2d/main.qml @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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.9 +import Qt3D.Render 2.9 +import Qt3D.Extras 2.9 +import Qt3D.Input 2.0 + +import QtQuick 2.0 +import QtQuick.Scene2D 2.9 +import QtQuick.Controls 1.4 +import QtQuick.Layouts 1.2 + +Entity { + id: sceneRoot + + Camera { + id: camera + projectionType: CameraLens.PerspectiveProjection + position: Qt.vector3d( 0.0, 0.0, 20 ) + } + + components: [ + RenderSettings { + activeFrameGraph: ForwardRenderer { + camera: camera + clearColor: "white" + } + pickingSettings.pickMethod: PickingSettings.TrianglePicking + }, + InputSettings {} + ] + + Entity { + id: logoEntity + + Transform { + id: logoTransform + scale: 1 + translation: Qt.vector3d( 0, 0, logoControls.logoCentreZ ) + rotation: fromEulerAngles( logoControls.rotationX, + logoControls.rotationY, + logoControls.rotationZ ) + } + + Mesh { + id: logoMesh + source: "Qt_logo.obj" + } + + PhongMaterial { + id: logoMaterial + ambient: Qt.rgba( logoControls.colorR/255, + logoControls.colorG/255, + logoControls.colorB/255, 1.0 ) + diffuse: Qt.rgba( 0.1, 0.1, 0.1, 0.5 ) + shininess: logoControls.shininess + } + + components: [ logoTransform, logoMesh, logoMaterial ] + } + + Entity { + id: plane + + components: [planeTransform, planeMaterial, planeMesh, planePicker] + + Transform { + id: planeTransform + translation: Qt.vector3d(2, 0, 10) + rotation: fromAxisAndAngle(Qt.vector3d(1,0,0), 90) + } + + PlaneMesh { + id: planeMesh + width: 1 + height: 4 + mirrored: true // Align OpenGL and Qt window coordinates by flipping texture coordinates + } + + ObjectPicker { + id: planePicker + hoverEnabled: true + dragEnabled: true + + // Explicitly require a middle click to have the Scene2D grab the mouse + // events from the picker + onPressed: { + if (pick.button === PickEvent.MiddleButton) { + qmlTexture.mouseEnabled = !qmlTexture.mouseEnabled + logoControls.enabled = !logoControls.enabled + } + } + } + + TextureMaterial { + id: planeMaterial + texture: offscreenTexture + } + + Scene2D { + id: qmlTexture + output: RenderTargetOutput { + attachmentPoint: RenderTargetOutput.Color0 + texture: Texture2D { + id: offscreenTexture + width: 256 + height: 1024 + format: Texture.RGBA8_UNorm + generateMipMaps: true + magnificationFilter: Texture.Linear + minificationFilter: Texture.LinearMipMapLinear + wrapMode { + x: WrapMode.ClampToEdge + y: WrapMode.ClampToEdge + } + } + } + + entities: [ plane ] + mouseEnabled: false + + LogoControls { + id: logoControls + width: offscreenTexture.width + height: offscreenTexture.height + } + } + } +} diff --git a/examples/qt3d/scene2d/scene2d.pro b/examples/qt3d/scene2d/scene2d.pro new file mode 100644 index 000000000..26ed34ce7 --- /dev/null +++ b/examples/qt3d/scene2d/scene2d.pro @@ -0,0 +1,14 @@ +!include( ../examples.pri ) { + error( "Couldn't find the examples.pri file!" ) +} + +QT += qml quick 3dquick 3dquickextras + +SOURCES += main.cpp + +RESOURCES += scene2d.qrc + +OTHER_FILES += \ + main.qml \ + Logo.qml \ + LogoControls.qml diff --git a/examples/qt3d/scene2d/scene2d.qrc b/examples/qt3d/scene2d/scene2d.qrc new file mode 100644 index 000000000..386b13456 --- /dev/null +++ b/examples/qt3d/scene2d/scene2d.qrc @@ -0,0 +1,7 @@ + + + main.qml + Qt_logo.obj + LogoControls.qml + + -- cgit v1.2.3 From 0ffdd1265b7a082a583b26a18f6cf84358edd68a Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Mon, 8 May 2017 14:41:37 +0100 Subject: Add documentation for Scene2D example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I2d47b9224e4f26b342cd8a9bbe3c9c5a5e410dc1 Reviewed-by: Antti Määttä --- examples/qt3d/scene2d/doc/images/scene2d.png | Bin 0 -> 45997 bytes examples/qt3d/scene2d/doc/src/scene2d.qdoc | 134 +++++++++++++++++++++++++++ examples/qt3d/scene2d/scene2d.pro | 3 +- src/doc/qt3d.qdocconf | 3 +- 4 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 examples/qt3d/scene2d/doc/images/scene2d.png create mode 100644 examples/qt3d/scene2d/doc/src/scene2d.qdoc diff --git a/examples/qt3d/scene2d/doc/images/scene2d.png b/examples/qt3d/scene2d/doc/images/scene2d.png new file mode 100644 index 000000000..789148537 Binary files /dev/null and b/examples/qt3d/scene2d/doc/images/scene2d.png differ diff --git a/examples/qt3d/scene2d/doc/src/scene2d.qdoc b/examples/qt3d/scene2d/doc/src/scene2d.qdoc new file mode 100644 index 000000000..66cf7dd21 --- /dev/null +++ b/examples/qt3d/scene2d/doc/src/scene2d.qdoc @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example scene2d + \title Qt 3D: Scene2D QML Example + \ingroup qt3d-examples-qml + \brief A QML application that demonstrates using Qt Quick 2 within a Qt 3D scene + + \image scene2d.png + + \e {Scene2D} demonstrates rendering a Qt Quick 2 scene into a texture and utilising + the texture within a Qt 3D application including handling mouse events. The 3D scene + contains a single active camera and renders a 3D Qt logo along with some controls + declared with Qt Quick Controls. + + \include examples-run.qdocinc + + \section1 Setting up the 3D Scene + + We set up the 3D scene in an Entity that acts as the root of the object tree. The + virtual camera is specified in \e main.qml: + + \quotefromfile scene2d/main.qml + \skipto Camera { + \printuntil } + + The RenderSettings specify the rendering algorithm used and also enable triangle + based picking which is needed to properly handle mouse events when projecting a + Qt Quick scene onto 3D geometry: + + \skipto RenderSettings { + \printuntil } + \printuntil } + + The 3D Qt logo that will be controlled by the controls in the Qt Quick scene is + declared with: + + \skipto Entity { + \printuntil } + \printuntil } + \printuntil } + \printuntil } + + It simply consists of a Mesh component to load the geometry; a PhongMaterial component + to give it a surface appearance, and a Transform component to specify its postion, + orientation, and scale. The properties of these components are bound to properties + on the logoControls element which we will discuss next. + + \section1 Rendering Qt Quick into a Texture + + We begin by declaring the Entity that will become our control panel. It consists of + a PlaneMesh onto which we will place the texture containing a rendering of the Qt Quick + scene. In this case we are using a simple flat plane for the geometry, but we could use + any valid 3D geometry as long as it has texture coordinates. The texture coordinates + are used for projecting the texture onto the 3D surface, and also for calculating the + coordinates of mouse events to be passed to the originating Qt Quick scene. + + \skipto Entity { + \printto } + \printto } + + Note that we enable the mirrored property on the PlaneMesh to ensure that the texture + coordinate vertical axis is aligned with the usual Qt window coordinate system. + + We also include an ObjectPicker component so that we can interact with the controls + using the mouse: + + \skipto ObjectPicker { + \printto } + \printto } + + For this example we have chosen to use an interaction mechanism whereby you must + explicitly middle-click the controls to enable them. + + To apply the texture to the mesh, we make use of the built in TextureMaterial: + + \skipto TextureMaterial + \printto } + + The final remaining piece is how to render the above texture from a Qt Quick scene. + This is done with the Scene2D element: + + \skipto Scene2D + \printto } + \printto } + \printto } + + where we have made use of the Texture2D and RenderTargetOutput types to create a + destination texture and attach it as the output of the Scene2D renderer. + + Next, we tell the Scene2D object which entities may feed it input events and we + initially disable the handling of mouse events: + + \printto mouseEnabled: false + + Finally, we can specify the Qt Quick scene to render by adding a custom QML component + as a child to the Scene2D element: + + \skipto LogoControls + \printto } + + When the mouseEnabled property is set to true by the ObjectPicker, then the Scene2D + object will process mouse events from any ObjectPickers attached to the listed entities. + In this way, you have the freedom to use the texture generated by the Scene2D object in + any way you wish, even on more than one Entity. + + The \e LogoControls.qml file is just a regular Qt Quick 2 scene which in this case + also makes use of the Qt Quick Controls components. +*/ diff --git a/examples/qt3d/scene2d/scene2d.pro b/examples/qt3d/scene2d/scene2d.pro index 26ed34ce7..0eb2bf550 100644 --- a/examples/qt3d/scene2d/scene2d.pro +++ b/examples/qt3d/scene2d/scene2d.pro @@ -11,4 +11,5 @@ RESOURCES += scene2d.qrc OTHER_FILES += \ main.qml \ Logo.qml \ - LogoControls.qml + LogoControls.qml \ + doc/src/* diff --git a/src/doc/qt3d.qdocconf b/src/doc/qt3d.qdocconf index aa39112d2..f5bbadd8d 100644 --- a/src/doc/qt3d.qdocconf +++ b/src/doc/qt3d.qdocconf @@ -81,7 +81,8 @@ imagedirs += images \ ../../examples/qt3d/planets-qml/doc/images \ ../../examples/qt3d/wireframe/doc/images \ ../../examples/qt3d/audio-visualizer-qml/doc/images \ - ../../examples/qt3d/simplecustommaterial/doc/images + ../../examples/qt3d/simplecustommaterial/doc/images \ + ../../examples/qt3d/scene2d/doc/images Cpp.ignoretokens += QT3DINPUTSHARED_EXPORT \ QT3DCORESHARED_EXPORT \ -- cgit v1.2.3 From 2daf7fbf486ac3e3265df2d6b6864b4d21826052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antti=20M=C3=A4=C3=A4tt=C3=A4?= Date: Mon, 13 Feb 2017 15:14:04 +0200 Subject: Add quick3d class for VertexBlendAnimation Add the missing class for VertexBlendAnimation so that it can be used from qml. Task-number: QTBUG-60618 Change-Id: If47dccf5e44d0158053ca3b9122fcef91d73ea93 Reviewed-by: Sean Harmer --- src/animation/frontend/qvertexblendanimation.cpp | 6 +- .../animation/qt3dquick3danimationplugin.cpp | 3 + src/quick3d/quick3danimation/items/items.pri | 6 +- .../items/quick3dvertexblendanimation.cpp | 104 +++++++++++++++++++++ .../items/quick3dvertexblendanimation_p.h | 93 ++++++++++++++++++ 5 files changed, 209 insertions(+), 3 deletions(-) create mode 100644 src/quick3d/quick3danimation/items/quick3dvertexblendanimation.cpp create mode 100644 src/quick3d/quick3danimation/items/quick3dvertexblendanimation_p.h diff --git a/src/animation/frontend/qvertexblendanimation.cpp b/src/animation/frontend/qvertexblendanimation.cpp index efc36e45c..3ddd83bf0 100644 --- a/src/animation/frontend/qvertexblendanimation.cpp +++ b/src/animation/frontend/qvertexblendanimation.cpp @@ -125,7 +125,7 @@ namespace Qt3DAnimation { \readonly */ /*! - \qmlproperty VertexBlendAnimation::target + \qmlproperty GeometryRenderer VertexBlendAnimation::target Holds the target GeometryRenderer the morphing animation is applied to. */ /*! @@ -135,6 +135,10 @@ namespace Qt3DAnimation { is usually same as the name of the parent entity of the target GeometryRenderer, but does not have to be. */ +/*! + \qmlproperty list VertexBlendAnimation::morphTargets + Holds the list of \l {MorphTarget}{morph targets} added to the animation. +*/ QVertexBlendAnimationPrivate::QVertexBlendAnimationPrivate() : QAbstractAnimationPrivate(QAbstractAnimation::VertexBlendAnimation) diff --git a/src/quick3d/imports/animation/qt3dquick3danimationplugin.cpp b/src/quick3d/imports/animation/qt3dquick3danimationplugin.cpp index 87c137763..7feeaf84c 100644 --- a/src/quick3d/imports/animation/qt3dquick3danimationplugin.cpp +++ b/src/quick3d/imports/animation/qt3dquick3danimationplugin.cpp @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -63,6 +64,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -92,6 +94,7 @@ void Qt3DQuick3DAnimationPlugin::registerTypes(const char *uri) qmlRegisterExtendedType(uri, 2, 9, "AnimationController"); qmlRegisterExtendedType(uri, 2, 9, "MorphingAnimation"); qmlRegisterExtendedType(uri, 2, 9, "MorphTarget"); + qmlRegisterExtendedType(uri, 2, 9, "VertexBlendAnimation"); } QT_END_NAMESPACE diff --git a/src/quick3d/quick3danimation/items/items.pri b/src/quick3d/quick3danimation/items/items.pri index 3f19965b5..27adabbe4 100644 --- a/src/quick3d/quick3danimation/items/items.pri +++ b/src/quick3d/quick3danimation/items/items.pri @@ -4,7 +4,8 @@ SOURCES += \ $$PWD/quick3danimationgroup.cpp \ $$PWD/quick3dkeyframeanimation.cpp \ $$PWD/quick3dmorphinganimation.cpp \ - $$PWD/quick3dmorphtarget.cpp + $$PWD/quick3dmorphtarget.cpp \ + $$PWD/quick3dvertexblendanimation.cpp HEADERS += \ $$PWD/quick3dchannelmapper_p.h \ @@ -12,6 +13,7 @@ HEADERS += \ $$PWD/quick3danimationgroup_p.h \ $$PWD/quick3dkeyframeanimation_p.h \ $$PWD/quick3dmorphinganimation_p.h \ - $$PWD/quick3dmorphtarget_p.h + $$PWD/quick3dmorphtarget_p.h \ + $$PWD/quick3dvertexblendanimation_p.h INCLUDEPATH += $$PWD diff --git a/src/quick3d/quick3danimation/items/quick3dvertexblendanimation.cpp b/src/quick3d/quick3danimation/items/quick3dvertexblendanimation.cpp new file mode 100644 index 000000000..2dffb7858 --- /dev/null +++ b/src/quick3d/quick3danimation/items/quick3dvertexblendanimation.cpp @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "quick3dvertexblendanimation_p.h" + +QT_BEGIN_NAMESPACE + +namespace Qt3DAnimation { +namespace Quick { + +QQuick3DVertexBlendAnimation::QQuick3DVertexBlendAnimation(QObject *parent) + : QObject(parent) +{ +} + +QQmlListProperty QQuick3DVertexBlendAnimation::morphTargets() +{ + return QQmlListProperty(this, 0, + &QQuick3DVertexBlendAnimation::appendMorphTarget, + &QQuick3DVertexBlendAnimation::morphTargetCount, + &QQuick3DVertexBlendAnimation::morphTargetAt, + &QQuick3DVertexBlendAnimation::clearMorphTargets); +} + +void QQuick3DVertexBlendAnimation::appendMorphTarget( + QQmlListProperty *list, + Qt3DAnimation::QMorphTarget *morphTarget) +{ + QQuick3DVertexBlendAnimation *animation + = qobject_cast(list->object); + if (animation) + animation->parentVertexBlendAnimation()->addMorphTarget(morphTarget); +} + +int QQuick3DVertexBlendAnimation::morphTargetCount( + QQmlListProperty *list) +{ + QQuick3DVertexBlendAnimation *animation + = qobject_cast(list->object); + if (animation) + return animation->parentVertexBlendAnimation()->morphTargetList().count(); + return 0; +} + +Qt3DAnimation::QMorphTarget *QQuick3DVertexBlendAnimation::morphTargetAt( + QQmlListProperty *list, + int index) +{ + QQuick3DVertexBlendAnimation *animation + = qobject_cast(list->object); + if (animation) { + return qobject_cast( + animation->parentVertexBlendAnimation()->morphTargetList().at(index)); + } + return nullptr; +} + +void QQuick3DVertexBlendAnimation::clearMorphTargets(QQmlListProperty *list) +{ + QQuick3DVertexBlendAnimation *animation + = qobject_cast(list->object); + if (animation) { + QVector emptyList; + animation->parentVertexBlendAnimation()->setMorphTargets(emptyList); + } +} + +} // namespace Quick +} // namespace Qt3DAnimation + +QT_END_NAMESPACE diff --git a/src/quick3d/quick3danimation/items/quick3dvertexblendanimation_p.h b/src/quick3d/quick3danimation/items/quick3dvertexblendanimation_p.h new file mode 100644 index 000000000..6be2d662f --- /dev/null +++ b/src/quick3d/quick3danimation/items/quick3dvertexblendanimation_p.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DANIMATION_QUICK_QUICK3DVERTEXBLENDANIMATION_P_H +#define QT3DANIMATION_QUICK_QUICK3DVERTEXBLENDANIMATION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +#include + +#include + +QT_BEGIN_NAMESPACE + +namespace Qt3DAnimation { +namespace Quick { + +class QT3DQUICKANIMATIONSHARED_PRIVATE_EXPORT QQuick3DVertexBlendAnimation : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQmlListProperty morphTargets READ morphTargets) + +public: + QQuick3DVertexBlendAnimation(QObject *parent = nullptr); + + inline QVertexBlendAnimation *parentVertexBlendAnimation() const + { + return qobject_cast(parent()); + } + + QQmlListProperty morphTargets(); + +private: + + static void appendMorphTarget(QQmlListProperty *list, + Qt3DAnimation::QMorphTarget *morphTarget); + static Qt3DAnimation::QMorphTarget *morphTargetAt( + QQmlListProperty *list, + int index); + static int morphTargetCount(QQmlListProperty *list); + static void clearMorphTargets(QQmlListProperty *list); +}; + +} // namespace Quick +} // namespace Qt3DAnimation + +QT_END_NAMESPACE + +#endif // QT3DANIMATION_QUICK_QUICK3DMORPHINGANIMATION_P_H -- cgit v1.2.3 From b9908909c9b364bebf16dcd0743cdeaa16555dbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A4=C3=A4tt=C3=A4=20Antti?= Date: Fri, 5 May 2017 09:09:59 +0300 Subject: Improve QScene2D documentations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add missing docs and add usage instructions for the Qml type. Change-Id: Id52025f0022bbaad56b0dbf4aa8ed33575568ceb Reviewed-by: Tomi Korpipää Reviewed-by: Sean Harmer --- src/quick3d/quick3dscene2d/items/qscene2d.cpp | 97 +++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 6 deletions(-) diff --git a/src/quick3d/quick3dscene2d/items/qscene2d.cpp b/src/quick3d/quick3dscene2d/items/qscene2d.cpp index c96509252..52e2be094 100644 --- a/src/quick3d/quick3dscene2d/items/qscene2d.cpp +++ b/src/quick3d/quick3dscene2d/items/qscene2d.cpp @@ -59,21 +59,75 @@ namespace Quick { \brief This class enables rendering qml into a texture, which then can be used as a part of 3D scene. - The component uses QQuickRenderControl to render the given QML source into an + This class uses QQuickRenderControl to render the given QQuickItem into an offscreen surface, which is attached to a texture provided by the user. This allows the component to directly render into the texture without intermediate copy and the user to freely specify how the texture is used in the 3D scene. + The entities using the QScene2D can be associated with the class to enable interaction + with the item; if an entity has a QObjectPicker component, the pick events from that picker + are sent to the QScene2D and converted to mouse events and finally sent to the item. + \since 5.9 */ /*! \qmltype Scene2D \inqmlmodule Qt3D.Scene2D - \since - \ingroup + \since 5.9 \instantiates Qt3DRender::Quick::QScene2D - \brief Scene2D + + \brief This type enables rendering qml into a texture, which then can be + used as a part of 3D scene. + + This object uses RenderControl to render the given Item into an + offscreen surface, which is attached to a texture provided by the user. This allows the + component to directly render into the texture without intermediate copy and the user to + freely specify how the texture is used in the 3D scene. + + The entities using the Scene2D can be associated with the type to enable interaction + with the item; if an entity has an ObjectPicker component, the pick events from that picker + are sent to the Scene2D and converted to mouse events and finally sent to the item. + + Usage: + \qml + Entity { + id: sceneRoot + + // specify Scene2D inside the entity hierarchy + Scene2D { + // specify output + output: RenderTargetOutput { + attachmentPoint: RenderTargetOutput.Color0 + texture: Texture2D { + id: textureId + width: 1024 + height: 1024 + format: Texture.RGBA8_UNorm + } + } + // specify entities + entities: [entityId] + + // specify rendered content + Rectangle { + color: "red" + } + } + + Entity { + id: entityId + + property Material material: TextureMaterial { + texture: textureId + } + property ObjectPicker picker: ObjectPicker { + hoverEnabled: true + dragEnabled: true + } + ... + + \endqml */ /*! @@ -93,15 +147,32 @@ namespace Quick { /*! \qmlproperty enumeration Qt3D.Render::Scene2D::renderPolicy Holds the render policy of this Scene2D. + + \list + \li Continuous The Scene2D is rendering continuously. This is the default render policy. + \li SingleShot The Scene2D renders to the texture only once after which the resources + allocated for rendering are released. + \endlist + */ +/*! + \qmlproperty Item Qt3D.Render::Scene2D::item + Holds the Item, which is rendered by Scene2D to the texture. */ /*! \qmlproperty bool Qt3D.Render::Scene2D::mouseEnabled Holds whether mouse events are enabled for the rendered item. The mouse events are - generated from object picking events of the entities added to the QScene2D. + generated from object picking events of the entities added to the Scene2D. Mouse is enabled by default. - \note Events are delayed by one frame due to object picking happening in the backend. + \note Events sent to items are delayed by one frame due to object picking + happening in the backend. + */ +/*! + \qmlproperty list Qt3D.Render::Scene2D::entities + Holds the list of entities which are associated with the Scene2D object. If the + entities have ObjectPicker, the pick events from that entity are sent to Scene2D + and converted to mouse events. */ QScene2DPrivate::QScene2DPrivate() @@ -135,6 +206,10 @@ QScene2D::QScene2D(Qt3DCore::QNode *parent) { } +/*! + \property QScene2D::item + Holds the QQuickItem, which is rendered by QScene2D to the texture. + */ QQuickItem* QScene2D::item() const { Q_D(const QScene2D); @@ -218,12 +293,19 @@ bool QScene2D::isMouseEnabled() const return d->m_renderManager->m_mouseEnabled; } +/*! + Retrieve entities associated with the QScene2D. + */ QVector QScene2D::entities() { Q_D(const QScene2D); return d->m_entities; } +/*! + 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. +*/ void QScene2D::addEntity(Qt3DCore::QEntity *entity) { Q_D(QScene2D); @@ -240,6 +322,9 @@ void QScene2D::addEntity(Qt3DCore::QEntity *entity) } } +/*! + Removes an \a entity from the the QScene2D object. +*/ void QScene2D::removeEntity(Qt3DCore::QEntity *entity) { Q_D(QScene2D); -- cgit v1.2.3 From c0f12806a2851f481788f383fef569d441b131ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A4=C3=A4tt=C3=A4=20Antti?= Date: Mon, 8 May 2017 09:26:44 +0300 Subject: Call setSurfaceFormat after QQuiApplication instance initiation The setSurfaceFormat function calls QOpenGLContext::openGLModuleType function which can only be called after QQuiApplication istance is initiated. Task-number: QTBUG-60617 Change-Id: I7cbf48f325de9c3cbbb5d8addb78bf55ae1b5d07 Reviewed-by: Laszlo Agocs --- examples/qt3d/advancedcustommaterial/main.cpp | 2 +- examples/qt3d/simplecustommaterial/main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/qt3d/advancedcustommaterial/main.cpp b/examples/qt3d/advancedcustommaterial/main.cpp index 9338ab4f4..631e26e43 100644 --- a/examples/qt3d/advancedcustommaterial/main.cpp +++ b/examples/qt3d/advancedcustommaterial/main.cpp @@ -71,8 +71,8 @@ void setSurfaceFormat() int main(int argc, char **argv) { - setSurfaceFormat(); QGuiApplication app(argc, argv); + setSurfaceFormat(); QQuickView view; diff --git a/examples/qt3d/simplecustommaterial/main.cpp b/examples/qt3d/simplecustommaterial/main.cpp index d841e7d19..6ccdcce64 100644 --- a/examples/qt3d/simplecustommaterial/main.cpp +++ b/examples/qt3d/simplecustommaterial/main.cpp @@ -71,8 +71,8 @@ void setSurfaceFormat() int main(int argc, char **argv) { - setSurfaceFormat(); QGuiApplication app(argc, argv); + setSurfaceFormat(); QQuickView view; -- cgit v1.2.3 From 2eb53d735488cd2fb609e51c036c5ee3554557c7 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Tue, 9 May 2017 14:23:24 +0200 Subject: QNode: setParent create creation change only when needed Two cases need to be handled by setParent: 1) Parent already has a backend node and receives a new child -> in which case we need to send the creation event to the backend 2) Parent was created in the frontend, but has no backend (delayed notification sending because a ctor can't call a virtual) -> in that case, when adding a child and setting its parent we shouldn't be sending the creation change. We rather let that be handled when the creation change for the parent is requested Change-Id: I434c7d4e6af785c0314ac6538dc689992d90ed0c Task-number: QTBUG-60612 Reviewed-by: Sean Harmer Reviewed-by: Oleg Evseev --- src/core/nodes/qnode.cpp | 18 ++++++- tests/auto/core/nodes/tst_nodes.cpp | 63 +++++++++++++++++++++- .../core/qchangearbiter/tst_qchangearbiter.cpp | 4 ++ tests/auto/core/qscene/tst_qscene.cpp | 3 ++ 4 files changed, 84 insertions(+), 4 deletions(-) diff --git a/src/core/nodes/qnode.cpp b/src/core/nodes/qnode.cpp index 42c8887ce..ce5e76a55 100644 --- a/src/core/nodes/qnode.cpp +++ b/src/core/nodes/qnode.cpp @@ -114,7 +114,7 @@ void QNodePrivate::notifyCreationChange() Q_Q(QNode); // Do nothing if we already have already sent a node creation change // and not a subsequent node destroyed change. - if (m_hasBackendNode) + if (m_hasBackendNode || !m_scene) return; QNodeCreatedChangeGenerator generator(q); const auto creationChanges = generator.creationChanges(); @@ -305,7 +305,21 @@ void QNodePrivate::_q_setParentHelper(QNode *parent) visitor.traverse(q, newParentNode->d_func(), &QNodePrivate::setSceneHelper); } - notifyCreationChange(); + // We want to make sure that subTreeRoot is always created before + // child. + // Given a case such as below + // QEntity *subTreeRoot = new QEntity(someGlobalExisitingRoot) + // QEntity *child = new QEntity(); + // child->setParent(subTreeRoot) + // We need to take into account that subTreeRoot needs to be + // created in the backend before the child. + // Therefore we only call notifyCreationChanges if the parent + // hasn't been created yet as we know that when the parent will be + // fully created, it will also send the changes for all of its + // children + + if (QNodePrivate::get(newParentNode)->m_hasBackendNode) + notifyCreationChange(); } // If we have a valid new parent, we let him know that we are its child diff --git a/tests/auto/core/nodes/tst_nodes.cpp b/tests/auto/core/nodes/tst_nodes.cpp index 89d396931..25c2a6dba 100644 --- a/tests/auto/core/nodes/tst_nodes.cpp +++ b/tests/auto/core/nodes/tst_nodes.cpp @@ -79,6 +79,8 @@ private slots: void appendingChildEntitiesToNode(); void removingChildEntitiesFromNode(); + void checkConstructionSetParentMix(); // QTBUG-60612 + void appendingComponentToEntity(); void appendingParentlessComponentToEntity(); void removingComponentFromEntity(); @@ -204,6 +206,11 @@ public: Qt3DCore::QNodePrivate::get(this)->setArbiter(arbiter); } + void setSimulateBackendCreated(bool created) + { + Qt3DCore::QNodePrivate::get(this)->m_hasBackendNode = created; + } + signals: void customPropertyChanged(); @@ -232,6 +239,11 @@ public: Qt3DCore::QNodePrivate::get(this)->setScene(scene); Qt3DCore::QNodePrivate::get(this)->setArbiter(arbiter); } + + void setSimulateBackendCreated(bool created) + { + Qt3DCore::QNodePrivate::get(this)->m_hasBackendNode = created; + } }; class MyQComponent : public Qt3DCore::QComponent @@ -389,6 +401,8 @@ void tst_Nodes::appendSingleChildNodeToNodeSceneExplicitParenting() QScopedPointer node(new MyQNode()); // WHEN node->setArbiterAndScene(&spy, &scene); + node->setSimulateBackendCreated(true); + // THEN QVERIFY(Qt3DCore::QNodePrivate::get(node.data())->scene() != nullptr); @@ -405,7 +419,7 @@ void tst_Nodes::appendSingleChildNodeToNodeSceneExplicitParenting() // THEN QVERIFY(child->parent() == node.data()); QVERIFY(child->parentNode() == node.data()); - QCOMPARE(spy.events.size(), 2); + QCOMPARE(spy.events.size(), 2); // Created + Child Added QCOMPARE(node->children().count(), 1); QVERIFY(Qt3DCore::QNodePrivate::get(child.data())->scene() != nullptr); @@ -482,6 +496,7 @@ void tst_Nodes::appendMultipleChildNodesToNodeScene() // WHEN node->setArbiterAndScene(&spy, &scene); + node->setSimulateBackendCreated(true); // THEN QVERIFY(Qt3DCore::QNodePrivate::get(node.data())->scene() != nullptr); @@ -664,6 +679,7 @@ void tst_Nodes::removingSingleChildNodeFromNode() // WHEN root->setArbiterAndScene(&spy, &scene); + root->setSimulateBackendCreated(true); child->setParent(root.data()); // Clear any creation event @@ -790,6 +806,47 @@ void tst_Nodes::removingChildEntitiesFromNode() QVERIFY(childEntity->parent() == nullptr); } +void tst_Nodes::checkConstructionSetParentMix() +{ + // GIVEN + ObserverSpy spy; + Qt3DCore::QScene scene; + QScopedPointer root(new MyQNode()); + + // WHEN + root->setArbiterAndScene(&spy, &scene); + root->setSimulateBackendCreated(true); + + // THEN + QVERIFY(Qt3DCore::QNodePrivate::get(root.data())->scene() != nullptr); + + // WHEN + Qt3DCore::QEntity *subTreeRoot = new Qt3DCore::QEntity(root.data()); + + for (int i = 0; i < 100; ++i) { + Qt3DCore::QEntity *child = new Qt3DCore::QEntity(); + child->setParent(subTreeRoot); + } + + // THEN + QCoreApplication::processEvents(); + QCOMPARE(root->children().count(), 1); + QCOMPARE(subTreeRoot->children().count(), 100); + QCOMPARE(spy.events.size(), 102); // 1 subTreeRoot creation change, 100 child creation, 1 child added (subTree to root) + + // Ensure first event is subTreeRoot + const Qt3DCore::QNodeCreatedChangeBasePtr firstEvent = spy.events.takeFirst().change().dynamicCast(); + QVERIFY(!firstEvent.isNull()); + QCOMPARE(firstEvent->subjectId(), subTreeRoot->id()); + QCOMPARE(firstEvent->parentId(), root->id()); + + const Qt3DCore::QPropertyNodeAddedChangePtr lastEvent = spy.events.takeLast().change().dynamicCast(); + QVERIFY(!lastEvent.isNull()); + QCOMPARE(lastEvent->subjectId(), root->id()); + QCOMPARE(lastEvent->propertyName(), "children"); + QCOMPARE(lastEvent->addedNodeId(), subTreeRoot->id()); +} + void tst_Nodes::appendingParentlessComponentToEntity() { // GIVEN @@ -798,6 +855,8 @@ void tst_Nodes::appendingParentlessComponentToEntity() { QScopedPointer entity(new MyQEntity()); entity->setArbiterAndScene(&entitySpy); + entity->setSimulateBackendCreated(true); + MyQComponent *comp = new MyQComponent(); comp->setArbiter(&componentSpy); @@ -816,7 +875,7 @@ void tst_Nodes::appendingParentlessComponentToEntity() QVERIFY(comp->parentNode() == entity.data()); QCOMPARE(entitySpy.events.size(), 1); QVERIFY(entitySpy.events.first().wasLocked()); - QCOMPARE(componentSpy.events.size(), 2); // first event is parent being set + QCOMPARE(componentSpy.events.size(), 1); // Note: since QEntity has no scene in this test case, we only have the // ComponentAdded event In theory we should also get the NodeCreated event diff --git a/tests/auto/core/qchangearbiter/tst_qchangearbiter.cpp b/tests/auto/core/qchangearbiter/tst_qchangearbiter.cpp index 061de06fa..faccb6d34 100644 --- a/tests/auto/core/qchangearbiter/tst_qchangearbiter.cpp +++ b/tests/auto/core/qchangearbiter/tst_qchangearbiter.cpp @@ -442,6 +442,7 @@ void tst_QChangeArbiter::registerSceneObserver() tst_Node *root = new tst_Node(); Qt3DCore::QNode *child = new tst_Node(); Qt3DCore::QNodePrivate::get(root)->setScene(scene.data()); + Qt3DCore::QNodePrivate::get(root)->m_hasBackendNode = true; scene->addObservable(root); QList observers; @@ -573,6 +574,7 @@ void tst_QChangeArbiter::unregisterSceneObservers() tst_Node *root = new tst_Node(); Qt3DCore::QNode *child = new tst_Node(); Qt3DCore::QNodePrivate::get(root)->setScene(scene.data()); + Qt3DCore::QNodePrivate::get(root)->m_hasBackendNode = true; scene->addObservable(root); QList observers; @@ -796,6 +798,7 @@ void tst_QChangeArbiter::distributePropertyChanges() // WHEN PropertyTestNode *root = new PropertyTestNode(); Qt3DCore::QNodePrivate::get(root)->setScene(scene.data()); + Qt3DCore::QNodePrivate::get(root)->m_hasBackendNode = true; scene->addObservable(root); tst_SimpleObserver *rootObserver = new tst_SimpleObserver(); @@ -890,6 +893,7 @@ void tst_QChangeArbiter::distributeBackendChanges() // WHEN tst_Node *root = new tst_Node(); Qt3DCore::QNodePrivate::get(root)->setScene(scene.data()); + Qt3DCore::QNodePrivate::get(root)->m_hasBackendNode = true; scene->addObservable(root); tst_BackendObserverObservable *backenObserverObservable = new tst_BackendObserverObservable(); diff --git a/tests/auto/core/qscene/tst_qscene.cpp b/tests/auto/core/qscene/tst_qscene.cpp index f4b04362d..78f17e8fa 100644 --- a/tests/auto/core/qscene/tst_qscene.cpp +++ b/tests/auto/core/qscene/tst_qscene.cpp @@ -297,6 +297,8 @@ void tst_QScene::deleteChildNode() Qt3DCore::QNode *root2 = new tst_Node(); Qt3DCore::QNodePrivate::get(root1)->setScene(scene); Qt3DCore::QNodePrivate::get(root2)->setScene(scene); + Qt3DCore::QNodePrivate::get(root1)->m_hasBackendNode = true; + Qt3DCore::QNodePrivate::get(root2)->m_hasBackendNode = true; // WHEN scene->addObservable(root1); @@ -358,6 +360,7 @@ void tst_QScene::removeChildNode() Qt3DCore::QNode *root = new tst_Node; Qt3DCore::QNodePrivate::get(root)->setScene(scene); + Qt3DCore::QNodePrivate::get(root)->m_hasBackendNode = true; scene->addObservable(root); // WHEN -- cgit v1.2.3 From b35237bfee04ae38cc35bdb333ab1ef8a74ffaae Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Tue, 9 May 2017 15:14:00 +0200 Subject: Scene2D example: highlight that QtQuick is a Texture on a Mesh Change-Id: Ibc78cc120ceed26c8521fa116e1794500b47c2dd Task-number: QTBUG-60695 Reviewed-by: Sean Harmer --- examples/qt3d/scene2d/doc/images/scene2d.png | Bin 45997 -> 60762 bytes examples/qt3d/scene2d/doc/src/scene2d.qdoc | 23 +++++++-------- examples/qt3d/scene2d/main.qml | 40 +++++++++++++++++++-------- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/examples/qt3d/scene2d/doc/images/scene2d.png b/examples/qt3d/scene2d/doc/images/scene2d.png index 789148537..db55a2fe5 100644 Binary files a/examples/qt3d/scene2d/doc/images/scene2d.png and b/examples/qt3d/scene2d/doc/images/scene2d.png differ diff --git a/examples/qt3d/scene2d/doc/src/scene2d.qdoc b/examples/qt3d/scene2d/doc/src/scene2d.qdoc index 66cf7dd21..90b767e43 100644 --- a/examples/qt3d/scene2d/doc/src/scene2d.qdoc +++ b/examples/qt3d/scene2d/doc/src/scene2d.qdoc @@ -74,25 +74,25 @@ \section1 Rendering Qt Quick into a Texture We begin by declaring the Entity that will become our control panel. It consists of - a PlaneMesh onto which we will place the texture containing a rendering of the Qt Quick - scene. In this case we are using a simple flat plane for the geometry, but we could use + a CuboidMesh onto which we will place the texture containing a rendering of the Qt Quick + scene. In this case we are using a simple cube for the geometry, but we could use any valid 3D geometry as long as it has texture coordinates. The texture coordinates are used for projecting the texture onto the 3D surface, and also for calculating the coordinates of mouse events to be passed to the originating Qt Quick scene. \skipto Entity { - \printto } - \printto } - - Note that we enable the mirrored property on the PlaneMesh to ensure that the texture - coordinate vertical axis is aligned with the usual Qt window coordinate system. + \printto Behavior + \skipto Transform { + \printuntil } + \printuntil } We also include an ObjectPicker component so that we can interact with the controls using the mouse: \skipto ObjectPicker { - \printto } - \printto } + \printuntil } + \printuntil } + \printuntil } For this example we have chosen to use an interaction mechanism whereby you must explicitly middle-click the controls to enable them. @@ -100,7 +100,7 @@ To apply the texture to the mesh, we make use of the built in TextureMaterial: \skipto TextureMaterial - \printto } + \printuntil } The final remaining piece is how to render the above texture from a Qt Quick scene. This is done with the Scene2D element: @@ -122,7 +122,8 @@ as a child to the Scene2D element: \skipto LogoControls - \printto } + \printuntil } + \printuntil } When the mouseEnabled property is set to true by the ObjectPicker, then the Scene2D object will process mouse events from any ObjectPickers attached to the listed entities. diff --git a/examples/qt3d/scene2d/main.qml b/examples/qt3d/scene2d/main.qml index d9d4676c2..35b8f3eb6 100644 --- a/examples/qt3d/scene2d/main.qml +++ b/examples/qt3d/scene2d/main.qml @@ -108,25 +108,41 @@ Entity { } Entity { - id: plane + id: cube - components: [planeTransform, planeMaterial, planeMesh, planePicker] + components: [cubeTransform, cubeMaterial, cubeMesh, cubePicker] + + property real rotationAngle: 0 + + Behavior on rotationAngle { + enabled: logoControls.enabled + RotationAnimation { + direction: RotationAnimation.Shortest + duration: 450 + } + } + + RotationAnimation on rotationAngle { + running: !logoControls.enabled + loops: Animation.Infinite + from: 0; to: 360 + duration: 4000 + onStopped: cube.rotationAngle = 0 + } Transform { - id: planeTransform + id: cubeTransform translation: Qt.vector3d(2, 0, 10) - rotation: fromAxisAndAngle(Qt.vector3d(1,0,0), 90) + scale3D: Qt.vector3d(1, 4, 1) + rotation: fromAxisAndAngle(Qt.vector3d(0,1,0), cube.rotationAngle) } - PlaneMesh { - id: planeMesh - width: 1 - height: 4 - mirrored: true // Align OpenGL and Qt window coordinates by flipping texture coordinates + CuboidMesh { + id: cubeMesh } ObjectPicker { - id: planePicker + id: cubePicker hoverEnabled: true dragEnabled: true @@ -141,7 +157,7 @@ Entity { } TextureMaterial { - id: planeMaterial + id: cubeMaterial texture: offscreenTexture } @@ -164,7 +180,7 @@ Entity { } } - entities: [ plane ] + entities: [ cube ] mouseEnabled: false LogoControls { -- cgit v1.2.3 From 773402d482c5b478e9b4b73719fa7b76792344f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A4=C3=A4tt=C3=A4=20Antti?= Date: Fri, 21 Apr 2017 14:17:20 +0300 Subject: Write docs for advanced custom material example Also add it to highlighted items. Task-number: QTBUG-60287 Change-Id: I87a6074bed171970b287c6cd934e6550d86e27e0 Reviewed-by: Sean Harmer --- .../doc/images/advanced-custom-material.jpg | Bin 0 -> 41394 bytes .../doc/src/advancedcustommaterial.qdoc | 84 +++++++++++++++++++++ src/doc/qt3d.qdocconf | 9 ++- 3 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 examples/qt3d/advancedcustommaterial/doc/images/advanced-custom-material.jpg create mode 100644 examples/qt3d/advancedcustommaterial/doc/src/advancedcustommaterial.qdoc diff --git a/examples/qt3d/advancedcustommaterial/doc/images/advanced-custom-material.jpg b/examples/qt3d/advancedcustommaterial/doc/images/advanced-custom-material.jpg new file mode 100644 index 000000000..98c4d8f68 Binary files /dev/null and b/examples/qt3d/advancedcustommaterial/doc/images/advanced-custom-material.jpg differ diff --git a/examples/qt3d/advancedcustommaterial/doc/src/advancedcustommaterial.qdoc b/examples/qt3d/advancedcustommaterial/doc/src/advancedcustommaterial.qdoc new file mode 100644 index 000000000..eeb59f07b --- /dev/null +++ b/examples/qt3d/advancedcustommaterial/doc/src/advancedcustommaterial.qdoc @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example advancedcustommaterial + \title Qt 3D: Advanced custom material QML Example + \ingroup qt3d-examples-qml + \brief Demonstrates creating advanced materials in Qt3D + + \image advanced-custom-material.jpg + + \e This example demonstrates creating advanced custom materials. + + \include examples-run.qdocinc + + \section1 Description + + Advanced custom material example shows more complex shaders, and demonstrates controlling your + shader properties with QtQuick user interface and Animation. Water is a 3D mesh, that is + modeled and uv mapped inside Blender, and then brought into Scene 3D as an \c {.obj} file. + Shader properties that user can control, are defined in \l {advancedcustommaterial/WaterMaterial.qml}{WaterMaterial}. + + \section1 Controls + \section2 Texture scale slider + + Multiplies texture coordinates inside the vertex shader. Controls the size of the textures + on water surface. + + \section2 Texture speed slider + + Offsets values for texture coordinates which are animated in + \l {advancedcustommaterial/Water.qml}{Water.qml} and then passed to vertex shader. + Creates the effect of textures scrolling over the surface. + + \section2 Specularity + + Multiplies specular texture values inside fragment shader. Makes the water reflective. + + \section2 Distortion + + Multiplies the offset in red and blue channels of wave texture in fragment shader. + Makes the surface textures animate more randomly. + + \section2 Normal amount + + Multiplies the normal map values inside fragment shader. Controls the visibility of + smaller waves on the water surface. + + \section2 Wave speed + + Modifies the frequency of the sine wave inside vertex shader. Controls the speed of the waves. + + \section2 Wave height + + Multiplies the vertex \c {Y} position inside vertex shader. Controls the height of the waves. + + \section2 Mesh rotation + + Rotates the water mesh in \l {advancedcustommaterial/Water.qml}{Water.qml}. +*/ diff --git a/src/doc/qt3d.qdocconf b/src/doc/qt3d.qdocconf index f5bbadd8d..7da047ced 100644 --- a/src/doc/qt3d.qdocconf +++ b/src/doc/qt3d.qdocconf @@ -82,7 +82,8 @@ imagedirs += images \ ../../examples/qt3d/wireframe/doc/images \ ../../examples/qt3d/audio-visualizer-qml/doc/images \ ../../examples/qt3d/simplecustommaterial/doc/images \ - ../../examples/qt3d/scene2d/doc/images + ../../examples/qt3d/scene2d/doc/images \ + ../../examples/qt3d/advancedcustommaterial/doc/images Cpp.ignoretokens += QT3DINPUTSHARED_EXPORT \ QT3DCORESHARED_EXPORT \ @@ -97,8 +98,10 @@ Cpp.ignoretokens += QT3DINPUTSHARED_EXPORT \ Cpp.ignoredirectives += Q_DECLARE_LOGGING_CATEGORY -manifestmeta.highlighted.names = "Qt3D/Qt 3D: Audio Visualizer Example" \ - "Qt3D/Qt 3D: Planets QML Example" +manifestmeta.highlighted.names = \ + "Qt3D/Qt 3D: Advanced custom material QML Example" \ + "Qt3D/Qt 3D: Audio Visualizer Example" \ + "Qt3D/Qt 3D: Planets QML Example" manifestmeta.thumbnail.names += "Qt3D/Qt 3D: Deferred Renderer C++ Example" -- cgit v1.2.3 From 094e697edbc1195105f05f8aef860d5256622a9a Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 10 May 2017 19:05:22 +0200 Subject: Bump version Change-Id: I161683e507ddce74818a832e8b7791f78d209b84 --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index b1c22d3b7..0dcf6d9b0 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,3 +1,3 @@ load(qt_build_config) -MODULE_VERSION = 5.9.0 +MODULE_VERSION = 5.9.1 -- cgit v1.2.3 From c85c89443d45368441d7bc8747dd73364df37306 Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Thu, 11 May 2017 16:19:15 +0100 Subject: Fix SC break Change-Id: If9bd9142dcfceedb8baefe0c8229e7eb7e1e6e50 Reviewed-by: Laszlo Agocs --- src/render/frontend/qabstractfunctor.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/render/frontend/qabstractfunctor.h b/src/render/frontend/qabstractfunctor.h index c05c04743..95f6aee51 100644 --- a/src/render/frontend/qabstractfunctor.h +++ b/src/render/frontend/qabstractfunctor.h @@ -80,6 +80,14 @@ public: virtual ~QAbstractFunctor(); virtual qintptr id() const = 0; + // TODO: Remove when moving a copy of this to Qt3DCore + template + const T *functor_cast(const QAbstractFunctor *other) const + { + if (other->id() == functorTypeId()) + return static_cast(other); + return nullptr; + } private: Q_DISABLE_COPY(QAbstractFunctor) }; -- cgit v1.2.3 From ac0f074a96fcb980b409a6deb961e6594ee1a9b8 Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Thu, 11 May 2017 16:08:48 +0100 Subject: Remove duplicate subdirs target that slipped in MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia2c5a7ae98d5a3cbf7c0981caeccaa4245a57707 Reviewed-by: Antti Määttä --- tests/auto/animation/animation.pro | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/auto/animation/animation.pro b/tests/auto/animation/animation.pro index d3ef37a61..b48fd347b 100644 --- a/tests/auto/animation/animation.pro +++ b/tests/auto/animation/animation.pro @@ -13,8 +13,7 @@ SUBDIRS += \ qkeyframeanimation \ qmorphinganimation \ qmorphtarget \ - qvertexblendanimation \ - qanimationcontroller + qvertexblendanimation qtConfig(private_tests) { SUBDIRS += \ -- cgit v1.2.3 From 8dfcdb186dd15f2948c02054bdef94f7aafeb412 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 12 May 2017 12:10:14 +0200 Subject: Document version of assimp library Change-Id: I43414f0cb882086bb2bbb85a875fc1045877cd64 Reviewed-by: Sean Harmer --- src/3rdparty/assimp/qt_attribution.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/3rdparty/assimp/qt_attribution.json b/src/3rdparty/assimp/qt_attribution.json index 79f23979e..564058dc4 100644 --- a/src/3rdparty/assimp/qt_attribution.json +++ b/src/3rdparty/assimp/qt_attribution.json @@ -6,6 +6,7 @@ "QtUsage": "Used in Qt 3D.", "Homepage": "http://www.assimp.org/", + "Version": "3.3.1", "License": "BSD 3-clause \"New\" or \"Revised\" Licensee", "LicenseId": "BSD-3-Clause", "LicenseFile": "LICENSE", -- cgit v1.2.3 From 469c3b91b68fe741258b7d7636c84422c147fe8b Mon Sep 17 00:00:00 2001 From: Jani Heikkinen Date: Fri, 5 May 2017 09:17:54 +0300 Subject: Add changes file for 5.9.0 Listing important changes and bug-fixes. Change-Id: I638bf3914bff7df015e6e842ef0f564b7b4180bf Reviewed-by: Sean Harmer --- dist/changes-5.9.0 | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 dist/changes-5.9.0 diff --git a/dist/changes-5.9.0 b/dist/changes-5.9.0 new file mode 100644 index 000000000..098c191a6 --- /dev/null +++ b/dist/changes-5.9.0 @@ -0,0 +1,81 @@ +Qt 5.9 introduces many new features and improvements as well as bugfixes +over the 5.8.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +Third-Party Code +---------------- + +- Updated assimp 3rdparty library to version 3.3.1 + +Important Changes +----------------- + + - Added zooming with the mouse scroll wheel to + QFirstPersonCameraController and QOrbitCameraController. + - Updated assimp scene importer to load simple keyframe and morphing animations. + - New Animation module supporting key framed animations. + - New Scene2D module supporting rendering Qt Quick within Qt 3D scenes and + interacting with them. + - Level of details support. + - 2D distance field and 3D geometric text support. + - Physics Based Rendering support. + +Render +------ + + - Added new QBufferCapture frame graph node to support QBuffer readback. + - Added new QMemoryBarrier frame graph node. + - Added EnvironmentLight type for environment mapping. Works well with PBR materials + in Qt3DExtras to give realistic lighting and specular reflections. + - Added support for level of detail with the QLevelOfDetail component and helpers. + Allows switching based upon distance from camera or projected screen size. + - Lots of performance and stability fixes. + +Scene2D +------- + + - Added new Scene2D module, which allows rendering Qt Quick content to Qt 3D + texture and using it as part of a 3D scene. + +Animation +--------- + + - Added technology preview of new Animation module. + - Added new animation classes to support loading animations using assimp scene loader. + - Added support for defining key framed animations or loading them from file. + - Added an animation export script for Blender + - Added classes to play back simple key frame animations and apply the animation to + arbitrary QObjects or QNodes. + - Added classes to support play back and blending of key frame animations. This allows + dynamically combining libraries of animation clips at runtime. + +Extras +------ + + - Added support for Physically Based Rendering with QMetalRough and QTexturedMetalRough + materials. + - Added new QText2Entity for distance field based 2D planar text in 3D scenes. + - Added QExtrudedTextMesh and QExtrudedTextGeometry classes to support 3D text rendering. + - Added new QMorphPhongMaterial to support mesh morphing and phong lighting model. + - Added new QTextureMaterial to support simple unlit textured geometry. + - Improved API consistency between QML and C++ + +Examples +-------- + + - Added new simple custom material and advanced custom material examples. + - Modified multiviewport example rendered content. + - Added new Scene2D example to showcase the new feature. -- cgit v1.2.3 From c9dbd1025cf31ca512ff29a169970275b76752dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A4=C3=A4tt=C3=A4=20Antti?= Date: Fri, 12 May 2017 14:45:27 +0300 Subject: Fix qmlClearTypeRegistrations for Qt 3D Unregister valueTypeProvider in qtquick_global.cpp to prevent multiple registrations. The Quick3DColorProvider doesn't seem to cause problems so leave as it is. Task-number: QTBUG-56546 Change-Id: I79139d8e8ab80458e72633dd97e15dbf108388e4 Reviewed-by: Sean Harmer --- src/quick3d/imports/core/qt3dquick3dcoreplugin.cpp | 5 +++++ src/quick3d/imports/core/qt3dquick3dcoreplugin.h | 1 + src/quick3d/quick3d/qt3dquick_global.cpp | 7 ++++++- src/quick3d/quick3d/qt3dquick_global_p.h | 1 + 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/quick3d/imports/core/qt3dquick3dcoreplugin.cpp b/src/quick3d/imports/core/qt3dquick3dcoreplugin.cpp index 6d2a78166..3ff63d9d9 100644 --- a/src/quick3d/imports/core/qt3dquick3dcoreplugin.cpp +++ b/src/quick3d/imports/core/qt3dquick3dcoreplugin.cpp @@ -71,4 +71,9 @@ void Qt3DQuick3DCorePlugin::registerTypes(const char *uri) qmlRegisterExtendedUncreatableType(uri, 2, 9, "Node", QStringLiteral("Node is a base class")); } +Qt3DQuick3DCorePlugin::~Qt3DQuick3DCorePlugin() +{ + Qt3DCore::Quick::Quick3D_uninitialize(); +} + QT_END_NAMESPACE diff --git a/src/quick3d/imports/core/qt3dquick3dcoreplugin.h b/src/quick3d/imports/core/qt3dquick3dcoreplugin.h index a9b215c4a..b0ef5947c 100644 --- a/src/quick3d/imports/core/qt3dquick3dcoreplugin.h +++ b/src/quick3d/imports/core/qt3dquick3dcoreplugin.h @@ -57,6 +57,7 @@ class Qt3DQuick3DCorePlugin : public QQmlExtensionPlugin Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: Qt3DQuick3DCorePlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { initResources(); } + ~Qt3DQuick3DCorePlugin(); void registerTypes(const char *uri) Q_DECL_OVERRIDE; }; diff --git a/src/quick3d/quick3d/qt3dquick_global.cpp b/src/quick3d/quick3d/qt3dquick_global.cpp index ebf27e7ae..a98211991 100644 --- a/src/quick3d/quick3d/qt3dquick_global.cpp +++ b/src/quick3d/quick3d/qt3dquick_global.cpp @@ -659,9 +659,9 @@ public: #undef ASSERT_VALID_SIZE }; +static Quick3DValueTypeProvider valueTypeProvider; static Quick3DValueTypeProvider *getValueTypeProvider() { - static Quick3DValueTypeProvider valueTypeProvider; return &valueTypeProvider; } @@ -706,6 +706,11 @@ void Quick3D_initialize() QQmlPrivate::qmlregister(QQmlPrivate::AutoParentRegistration, &autoparent); } +void Quick3D_uninitialize() +{ + QQml_removeValueTypeProvider(&valueTypeProvider); +} + void Quick3D_registerType(const char *className, const char *quickName, int major, int minor) { QuickNodeFactory::instance()->registerType(className, quickName, major, minor); diff --git a/src/quick3d/quick3d/qt3dquick_global_p.h b/src/quick3d/quick3d/qt3dquick_global_p.h index d67209404..ffc603f91 100644 --- a/src/quick3d/quick3d/qt3dquick_global_p.h +++ b/src/quick3d/quick3d/qt3dquick_global_p.h @@ -62,6 +62,7 @@ namespace Qt3DCore { namespace Quick { QT3DQUICKSHARED_PRIVATE_EXPORT void Quick3D_initialize(); +QT3DQUICKSHARED_PRIVATE_EXPORT void Quick3D_uninitialize(); QT3DQUICKSHARED_PRIVATE_EXPORT void Quick3D_registerType(const char *className, const char *quickName, int major, int minor); template void registerExtendedType(const char *className, const char *quickName, -- cgit v1.2.3 From 1d03c298fa27e2747fd41a9b5378135d57656fd9 Mon Sep 17 00:00:00 2001 From: Jere Tuliniemi Date: Tue, 9 May 2017 12:34:37 +0300 Subject: Implement PIMPL for Qt3DQuickWindow Moved private members of Qt3DQuickWindow to Qt3DQuickWindowPrivate to hide implementation. m_engine is now a normal pointer so that it can be deleted in the Qt3DQuickWindow destructor. Task-number: QTBUG-60426 Change-Id: I99dd1b89aa2036272add7ba276e9b8f0c867e4a1 Reviewed-by: Sean Harmer --- src/quick3d/quick3dextras/qt3dquickwindow.cpp | 80 +++++++++++++++---------- src/quick3d/quick3dextras/qt3dquickwindow.h | 14 +---- src/quick3d/quick3dextras/qt3dquickwindow_p.h | 86 +++++++++++++++++++++++++++ src/quick3d/quick3dextras/quick3dextras.pro | 1 + 4 files changed, 138 insertions(+), 43 deletions(-) create mode 100644 src/quick3d/quick3dextras/qt3dquickwindow_p.h diff --git a/src/quick3d/quick3dextras/qt3dquickwindow.cpp b/src/quick3d/quick3dextras/qt3dquickwindow.cpp index 7f32f03f0..91773bb66 100644 --- a/src/quick3d/quick3dextras/qt3dquickwindow.cpp +++ b/src/quick3d/quick3dextras/qt3dquickwindow.cpp @@ -49,6 +49,7 @@ ****************************************************************************/ #include +#include "qt3dquickwindow_p.h" #include #include #include @@ -96,16 +97,21 @@ private: } // anonymous -Qt3DQuickWindow::Qt3DQuickWindow(QWindow *parent) - : QWindow(parent) - , m_engine(nullptr) +Qt3DQuickWindowPrivate::Qt3DQuickWindowPrivate() + : m_engine(nullptr) , m_renderAspect(nullptr) , m_inputAspect(nullptr) , m_logicAspect(nullptr) , m_initialized(false) - , m_cameraAspectRatioMode(AutomaticAspectRatio) + , m_cameraAspectRatioMode(Qt3DQuickWindow::AutomaticAspectRatio) , m_incubationController(nullptr) { +} + +Qt3DQuickWindow::Qt3DQuickWindow(QWindow *parent) + : QWindow(*new Qt3DQuickWindowPrivate(), parent) +{ + Q_D(Qt3DQuickWindow); setSurfaceType(QSurface::OpenGLSurface); resize(1024, 768); @@ -125,78 +131,87 @@ Qt3DQuickWindow::Qt3DQuickWindow(QWindow *parent) setFormat(format); QSurfaceFormat::setDefaultFormat(format); - m_engine.reset(new Qt3DCore::Quick::QQmlAspectEngine); - m_renderAspect = new Qt3DRender::QRenderAspect; - m_inputAspect = new Qt3DInput::QInputAspect; - m_logicAspect = new Qt3DLogic::QLogicAspect; + d->m_engine = new Qt3DCore::Quick::QQmlAspectEngine; + d->m_renderAspect = new Qt3DRender::QRenderAspect; + d->m_inputAspect = new Qt3DInput::QInputAspect; + d->m_logicAspect = new Qt3DLogic::QLogicAspect; - m_engine->aspectEngine()->registerAspect(m_renderAspect); - m_engine->aspectEngine()->registerAspect(m_inputAspect); - m_engine->aspectEngine()->registerAspect(m_logicAspect); + d->m_engine->aspectEngine()->registerAspect(d->m_renderAspect); + d->m_engine->aspectEngine()->registerAspect(d->m_inputAspect); + d->m_engine->aspectEngine()->registerAspect(d->m_logicAspect); } Qt3DQuickWindow::~Qt3DQuickWindow() { + Q_D(Qt3DQuickWindow); + delete d->m_engine; } void Qt3DQuickWindow::registerAspect(Qt3DCore::QAbstractAspect *aspect) { Q_ASSERT(!isVisible()); - m_engine->aspectEngine()->registerAspect(aspect); + Q_D(Qt3DQuickWindow); + d->m_engine->aspectEngine()->registerAspect(aspect); } void Qt3DQuickWindow::registerAspect(const QString &name) { Q_ASSERT(!isVisible()); - m_engine->aspectEngine()->registerAspect(name); + Q_D(Qt3DQuickWindow); + d->m_engine->aspectEngine()->registerAspect(name); } void Qt3DQuickWindow::setSource(const QUrl &source) { - m_source = source; + Q_D(Qt3DQuickWindow); + d->m_source = source; } Qt3DCore::Quick::QQmlAspectEngine *Qt3DQuickWindow::engine() const { - return m_engine.data(); + Q_D(const Qt3DQuickWindow); + return d->m_engine; } void Qt3DQuickWindow::setCameraAspectRatioMode(CameraAspectRatioMode mode) { - if (m_cameraAspectRatioMode == mode) + Q_D(Qt3DQuickWindow); + if (d->m_cameraAspectRatioMode == mode) return; - m_cameraAspectRatioMode = mode; + d->m_cameraAspectRatioMode = mode; setCameraAspectModeHelper(); emit cameraAspectRatioModeChanged(mode); } Qt3DQuickWindow::CameraAspectRatioMode Qt3DQuickWindow::cameraAspectRatioMode() const { - return m_cameraAspectRatioMode; + Q_D(const Qt3DQuickWindow); + return d->m_cameraAspectRatioMode; } void Qt3DQuickWindow::showEvent(QShowEvent *e) { - if (!m_initialized) { + Q_D(Qt3DQuickWindow); + if (!d->m_initialized) { // Connect to the QQmlAspectEngine's statusChanged signal so that when the QML is loaded // and th eobjects hav ebeen instantiated, but before we set them on the QAspectEngine we // can swoop in and set the window surface and camera on the framegraph and ensure the camera // respects the window's aspect ratio - connect(m_engine.data(), &Qt3DCore::Quick::QQmlAspectEngine::sceneCreated, + connect(d->m_engine, &Qt3DCore::Quick::QQmlAspectEngine::sceneCreated, this, &Qt3DQuickWindow::onSceneCreated); - m_engine->setSource(m_source); + d->m_engine->setSource(d->m_source); // Set the QQmlIncubationController on the window // to benefit from asynchronous incubation - if (!m_incubationController) - m_incubationController = new Qt3DQuickWindowIncubationController(this); + if (!d->m_incubationController) + d->m_incubationController = new Qt3DQuickWindowIncubationController(this); - m_engine->qmlEngine()->setIncubationController(m_incubationController); + d->m_engine->qmlEngine()->setIncubationController(d->m_incubationController); - m_initialized = true; + d->m_initialized = true; } QWindow::showEvent(e); } @@ -204,17 +219,18 @@ void Qt3DQuickWindow::showEvent(QShowEvent *e) void Qt3DQuickWindow::onSceneCreated(QObject *rootObject) { Q_ASSERT(rootObject); + Q_D(Qt3DQuickWindow); setWindowSurface(rootObject); - if (m_cameraAspectRatioMode == AutomaticAspectRatio) { + if (d->m_cameraAspectRatioMode == AutomaticAspectRatio) { // Set aspect ratio of first camera to match the window QList cameras = rootObject->findChildren(); if (cameras.isEmpty()) { qCDebug(QuickWindow) << "No camera found"; } else { - m_camera = cameras.first(); + d->m_camera = cameras.first(); setCameraAspectModeHelper(); } } @@ -237,7 +253,8 @@ void Qt3DQuickWindow::setWindowSurface(QObject *rootObject) void Qt3DQuickWindow::setCameraAspectModeHelper() { - switch (m_cameraAspectRatioMode) { + Q_D(Qt3DQuickWindow); + switch (d->m_cameraAspectRatioMode) { case AutomaticAspectRatio: connect(this, &QWindow::widthChanged, this, &Qt3DQuickWindow::updateCameraAspectRatio); connect(this, &QWindow::heightChanged, this, &Qt3DQuickWindow::updateCameraAspectRatio); @@ -253,9 +270,10 @@ void Qt3DQuickWindow::setCameraAspectModeHelper() void Qt3DQuickWindow::updateCameraAspectRatio() { - if (m_camera) { - m_camera->setAspectRatio(static_cast(width()) / - static_cast(height())); + Q_D(Qt3DQuickWindow); + if (d->m_camera) { + d->m_camera->setAspectRatio(static_cast(width()) / + static_cast(height())); } } diff --git a/src/quick3d/quick3dextras/qt3dquickwindow.h b/src/quick3d/quick3dextras/qt3dquickwindow.h index 1b4d3fabf..0880fc160 100644 --- a/src/quick3d/quick3dextras/qt3dquickwindow.h +++ b/src/quick3d/quick3dextras/qt3dquickwindow.h @@ -84,6 +84,7 @@ namespace Qt3DExtras { namespace Quick { +class Qt3DQuickWindowPrivate; class QT3DQUICKEXTRASSHARED_EXPORT Qt3DQuickWindow : public QWindow { @@ -121,18 +122,7 @@ private: void setCameraAspectModeHelper(); void updateCameraAspectRatio(); - QScopedPointer m_engine; - - // Aspects - Qt3DRender::QRenderAspect *m_renderAspect; - Qt3DInput::QInputAspect *m_inputAspect; - Qt3DLogic::QLogicAspect *m_logicAspect; - - QUrl m_source; - bool m_initialized; - QPointer m_camera; - CameraAspectRatioMode m_cameraAspectRatioMode; - QQmlIncubationController *m_incubationController; + Q_DECLARE_PRIVATE(Qt3DQuickWindow) }; } // Quick diff --git a/src/quick3d/quick3dextras/qt3dquickwindow_p.h b/src/quick3d/quick3dextras/qt3dquickwindow_p.h new file mode 100644 index 000000000..f2f8d0492 --- /dev/null +++ b/src/quick3d/quick3dextras/qt3dquickwindow_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DQUICKWINDOW_P_H +#define QT3DQUICKWINDOW_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +namespace Quick { + +class Qt3DQuickWindowPrivate : public QWindowPrivate +{ +public: + Qt3DQuickWindowPrivate(); + + Qt3DCore::Quick::QQmlAspectEngine *m_engine; + + // Aspects + Qt3DRender::QRenderAspect *m_renderAspect; + Qt3DInput::QInputAspect *m_inputAspect; + Qt3DLogic::QLogicAspect *m_logicAspect; + + QUrl m_source; + bool m_initialized; + QPointer m_camera; + Qt3DQuickWindow::CameraAspectRatioMode m_cameraAspectRatioMode; + QQmlIncubationController *m_incubationController; + + Q_DECLARE_PUBLIC(Qt3DQuickWindow) +}; + +} // Quick + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DQUICKWINDOW_P_H diff --git a/src/quick3d/quick3dextras/quick3dextras.pro b/src/quick3d/quick3dextras/quick3dextras.pro index 9044c1668..976430eba 100644 --- a/src/quick3d/quick3dextras/quick3dextras.pro +++ b/src/quick3d/quick3dextras/quick3dextras.pro @@ -21,6 +21,7 @@ HEADERS += \ qt3dquickextras_global.h \ qt3dquickextras_global_p.h \ qt3dquickwindow.h \ + qt3dquickwindow_p.h \ qt3dquickwindowlogging_p.h # otherwise mingw headers do not declare common functions like ::strcasecmp -- cgit v1.2.3 From 757e26894b5b912bd03ce93b7e538e26f88c9b62 Mon Sep 17 00:00:00 2001 From: Jere Tuliniemi Date: Tue, 9 May 2017 11:30:47 +0300 Subject: Implement PIMPL for Qt3DWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added private members of Qt3DWindow to Qt3DWindowPrivate to hide implementation. m_aspectEngine is a normal pointer now so that it can be deleted from Qt3DWindow destructor. Screen connection happens after QWindow constructor now because it lacks a constructor that takes a d_ptr and a screen pointer. Task-number: QTBUG-60426 Change-Id: I08e431ec0ea570e5f2c5fb103bcf0fe16e1b23bc Reviewed-by: Antti Määttä --- src/extras/defaults/defaults.pri | 1 + src/extras/defaults/qt3dwindow.cpp | 80 +++++++++++++++++++++------------ src/extras/defaults/qt3dwindow.h | 25 ++--------- src/extras/defaults/qt3dwindow_p.h | 92 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 147 insertions(+), 51 deletions(-) create mode 100644 src/extras/defaults/qt3dwindow_p.h diff --git a/src/extras/defaults/defaults.pri b/src/extras/defaults/defaults.pri index ec8c9a7b5..8a18fb6e9 100644 --- a/src/extras/defaults/defaults.pri +++ b/src/extras/defaults/defaults.pri @@ -24,6 +24,7 @@ HEADERS += \ $$PWD/qphongalphamaterial.h \ $$PWD/qphongalphamaterial_p.h \ $$PWD/qt3dwindow.h \ + $$PWD/qt3dwindow_p.h \ $$PWD/qfirstpersoncameracontroller.h \ $$PWD/qfirstpersoncameracontroller_p.h \ $$PWD/qorbitcameracontroller.h \ diff --git a/src/extras/defaults/qt3dwindow.cpp b/src/extras/defaults/qt3dwindow.cpp index a0ce40e16..635d81956 100644 --- a/src/extras/defaults/qt3dwindow.cpp +++ b/src/extras/defaults/qt3dwindow.cpp @@ -49,6 +49,7 @@ ****************************************************************************/ #include "qt3dwindow.h" +#include "qt3dwindow_p.h" #include #include @@ -65,9 +66,8 @@ QT_BEGIN_NAMESPACE namespace Qt3DExtras { -Qt3DWindow::Qt3DWindow(QScreen *screen) - : QWindow(screen) - , m_aspectEngine(new Qt3DCore::QAspectEngine) +Qt3DWindowPrivate::Qt3DWindowPrivate() + : m_aspectEngine(new Qt3DCore::QAspectEngine) , m_renderAspect(new Qt3DRender::QRenderAspect) , m_inputAspect(new Qt3DInput::QInputAspect) , m_logicAspect(new Qt3DLogic::QLogicAspect) @@ -79,6 +79,16 @@ Qt3DWindow::Qt3DWindow(QScreen *screen) , m_userRoot(nullptr) , m_initialized(false) { +} + +Qt3DWindow::Qt3DWindow(QScreen *screen) + : QWindow(*new Qt3DWindowPrivate(), nullptr) +{ + Q_D(Qt3DWindow); + + if (!d->parentWindow) + d->connectToScreen(screen ? screen : d->topLevelScreen.data()); + setSurfaceType(QSurface::OpenGLSurface); resize(1024, 768); @@ -98,77 +108,88 @@ Qt3DWindow::Qt3DWindow(QScreen *screen) setFormat(format); QSurfaceFormat::setDefaultFormat(format); - m_aspectEngine->registerAspect(m_renderAspect); - m_aspectEngine->registerAspect(m_inputAspect); - m_aspectEngine->registerAspect(m_logicAspect); + d->m_aspectEngine->registerAspect(d->m_renderAspect); + d->m_aspectEngine->registerAspect(d->m_inputAspect); + d->m_aspectEngine->registerAspect(d->m_logicAspect); - m_defaultCamera->setParent(m_root); - m_forwardRenderer->setCamera(m_defaultCamera); - m_forwardRenderer->setSurface(this); - m_renderSettings->setActiveFrameGraph(m_forwardRenderer); - m_inputSettings->setEventSource(this); + d->m_defaultCamera->setParent(d->m_root); + d->m_forwardRenderer->setCamera(d->m_defaultCamera); + d->m_forwardRenderer->setSurface(this); + d->m_renderSettings->setActiveFrameGraph(d->m_forwardRenderer); + d->m_inputSettings->setEventSource(this); } Qt3DWindow::~Qt3DWindow() { + Q_D(Qt3DWindow); + delete d->m_aspectEngine; } void Qt3DWindow::registerAspect(Qt3DCore::QAbstractAspect *aspect) { Q_ASSERT(!isVisible()); - m_aspectEngine->registerAspect(aspect); + Q_D(Qt3DWindow); + d->m_aspectEngine->registerAspect(aspect); } void Qt3DWindow::registerAspect(const QString &name) { Q_ASSERT(!isVisible()); - m_aspectEngine->registerAspect(name); + Q_D(Qt3DWindow); + d->m_aspectEngine->registerAspect(name); } void Qt3DWindow::setRootEntity(Qt3DCore::QEntity *root) { - if (m_userRoot != root) { - if (m_userRoot != nullptr) - m_userRoot->setParent(static_cast(nullptr)); + Q_D(Qt3DWindow); + if (d->m_userRoot != root) { + if (d->m_userRoot != nullptr) + d->m_userRoot->setParent(static_cast(nullptr)); if (root != nullptr) - root->setParent(m_root); - m_userRoot = root; + root->setParent(d->m_root); + d->m_userRoot = root; } } void Qt3DWindow::setActiveFrameGraph(Qt3DRender::QFrameGraphNode *activeFrameGraph) { - m_renderSettings->setActiveFrameGraph(activeFrameGraph); + Q_D(Qt3DWindow); + d->m_renderSettings->setActiveFrameGraph(activeFrameGraph); } Qt3DRender::QFrameGraphNode *Qt3DWindow::activeFrameGraph() const { - return m_renderSettings->activeFrameGraph(); + Q_D(const Qt3DWindow); + return d->m_renderSettings->activeFrameGraph(); } Qt3DExtras::QForwardRenderer *Qt3DWindow::defaultFrameGraph() const { - return m_forwardRenderer; + Q_D(const Qt3DWindow); + return d->m_forwardRenderer; } Qt3DRender::QCamera *Qt3DWindow::camera() const { - return m_defaultCamera; + Q_D(const Qt3DWindow); + return d->m_defaultCamera; } Qt3DRender::QRenderSettings *Qt3DWindow::renderSettings() const { - return m_renderSettings; + Q_D(const Qt3DWindow); + return d->m_renderSettings; } void Qt3DWindow::showEvent(QShowEvent *e) { - if (!m_initialized) { - m_root->addComponent(m_renderSettings); - m_root->addComponent(m_inputSettings); - m_aspectEngine->setRootEntity(Qt3DCore::QEntityPtr(m_root)); + Q_D(Qt3DWindow); + if (!d->m_initialized) { + d->m_root->addComponent(d->m_renderSettings); + d->m_root->addComponent(d->m_inputSettings); + d->m_aspectEngine->setRootEntity(Qt3DCore::QEntityPtr(d->m_root)); - m_initialized = true; + d->m_initialized = true; } QWindow::showEvent(e); @@ -176,7 +197,8 @@ void Qt3DWindow::showEvent(QShowEvent *e) void Qt3DWindow::resizeEvent(QResizeEvent *) { - m_defaultCamera->setAspectRatio(float(width()) / float(height())); + Q_D(Qt3DWindow); + d->m_defaultCamera->setAspectRatio(float(width()) / float(height())); } } // Qt3DExtras diff --git a/src/extras/defaults/qt3dwindow.h b/src/extras/defaults/qt3dwindow.h index 811bb134d..6ec1bbf8b 100644 --- a/src/extras/defaults/qt3dwindow.h +++ b/src/extras/defaults/qt3dwindow.h @@ -84,6 +84,8 @@ class QLogicAspect; namespace Qt3DExtras { +class Qt3DWindowPrivate; + class QT3DEXTRASSHARED_EXPORT Qt3DWindow : public QWindow { Q_OBJECT @@ -112,28 +114,7 @@ protected: void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE; private: - QScopedPointer m_aspectEngine; - - // Aspects - Qt3DRender::QRenderAspect *m_renderAspect; - Qt3DInput::QInputAspect *m_inputAspect; - Qt3DLogic::QLogicAspect *m_logicAspect; - - // Renderer configuration - Qt3DRender::QRenderSettings *m_renderSettings; - Qt3DExtras::QForwardRenderer *m_forwardRenderer; - Qt3DRender::QCamera *m_defaultCamera; - - // Input configuration - Qt3DInput::QInputSettings *m_inputSettings; - - // Logic configuration - - // Scene - Qt3DCore::QEntity *m_root; - Qt3DCore::QEntity *m_userRoot; - - bool m_initialized; + Q_DECLARE_PRIVATE(Qt3DWindow) }; } // Qt3DExtras diff --git a/src/extras/defaults/qt3dwindow_p.h b/src/extras/defaults/qt3dwindow_p.h new file mode 100644 index 000000000..731d5298e --- /dev/null +++ b/src/extras/defaults/qt3dwindow_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DWINDOW_P_H +#define QT3DWINDOW_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class Qt3DWindowPrivate : public QWindowPrivate +{ +public: + Qt3DWindowPrivate(); + + Qt3DCore::QAspectEngine *m_aspectEngine; + + // Aspects + Qt3DRender::QRenderAspect *m_renderAspect; + Qt3DInput::QInputAspect *m_inputAspect; + Qt3DLogic::QLogicAspect *m_logicAspect; + + // Renderer configuration + Qt3DRender::QRenderSettings *m_renderSettings; + Qt3DExtras::QForwardRenderer *m_forwardRenderer; + Qt3DRender::QCamera *m_defaultCamera; + + // Input configuration + Qt3DInput::QInputSettings *m_inputSettings; + + // Logic configuration + + // Scene + Qt3DCore::QEntity *m_root; + Qt3DCore::QEntity *m_userRoot; + + bool m_initialized; + + Q_DECLARE_PUBLIC(Qt3DWindow) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DWINDOW_P_H -- cgit v1.2.3 From 7261606116768d563c0e49a23ca60ab367a4cab5 Mon Sep 17 00:00:00 2001 From: Oleg Evseev Date: Fri, 12 May 2017 12:35:08 +0300 Subject: Fix speed regressions in ES2 shaders The GLSL ES specification (up to at least 3.0) does not mandate support of dynamic indexing of uniform block arrays. For that reason loops in ES2 shaders were unrolled by calling separate functions, but it had leaded to rendering speed regressions. This patch reverts loops unrolling using separate functions and replaces dynamic indexing in place instead. Task-number: QTBUG-60183 Task-number: QTBUG-54994 Change-Id: Ieb036f442922de312b2941a0b8c511c0b4b3ec5a Reviewed-by: Sean Harmer Reviewed-by: Oleg Evseev --- src/extras/shaders/es2/light.inc.frag | 310 +++++++++++++++------------------- 1 file changed, 137 insertions(+), 173 deletions(-) diff --git a/src/extras/shaders/es2/light.inc.frag b/src/extras/shaders/es2/light.inc.frag index 726340d7e..074af5799 100644 --- a/src/extras/shaders/es2/light.inc.frag +++ b/src/extras/shaders/es2/light.inc.frag @@ -14,215 +14,179 @@ struct Light { uniform Light lights[MAX_LIGHTS]; uniform int lightCount; -void addLightAdsModelNormalMapped(const in FP vec3 vpos, - const in FP vec3 n, - const in FP vec3 eye, - const in FP float shininess, - const in FP mat3 tangentMatrix, - const in Light light, - inout FP vec3 diffuseColor, - inout FP vec3 specularColor) -{ - FP vec3 snormal = normalize( vec3( tangentMatrix[0][2], tangentMatrix[1][2], tangentMatrix[2][2] ) ); - - FP vec3 s, ts; - FP float att = 1.0; - if ( light.type != TYPE_DIRECTIONAL ) { - s = light.position - vpos; - if ( dot(snormal, s) < 0.0 ) - att = 0.0; - else { - ts = normalize( tangentMatrix * s ); - if (length( light.attenuation ) != 0.0) { - FP float dist = length(s); - att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist); - } - s = normalize( s ); - if ( light.type == TYPE_SPOT ) { - if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle) - att = 0.0; - } - } - } else { - if ( dot(snormal, -light.direction) > 0.0 ) - s = normalize( tangentMatrix * -light.direction ); - else - att = 0.0; - } - - FP float diffuse = max( dot( ts, n ), 0.0 ); - - FP float specular = 0.0; - if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) { - FP vec3 r = reflect( -ts, n ); - FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) ); - FP float normFactor = ( shininess + 2.0 ) / 2.0; - specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess ); - } - - diffuseColor += att * light.intensity * diffuse * light.color; - specularColor += att * light.intensity * specular * light.color; -} - void adsModelNormalMapped(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess, const in FP mat3 tangentMatrix, out FP vec3 diffuseColor, out FP vec3 specularColor) { diffuseColor = vec3(0.0); specularColor = vec3(0.0); - if (lightCount < 1) return; - FP vec3 n = normalize( vnormal ); - addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[0], diffuseColor, specularColor); - if (lightCount < 2) return; - - addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[1], diffuseColor, specularColor); - if (lightCount < 3) return; - - addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[2], diffuseColor, specularColor); - if (lightCount < 4) return; - - addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[3], diffuseColor, specularColor); - if (lightCount < 5) return; - - addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[4], diffuseColor, specularColor); - if (lightCount < 6) return; - - addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[5], diffuseColor, specularColor); - if (lightCount < 7) return; - - addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[6], diffuseColor, specularColor); - if (lightCount < 8) return; - - addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[7], diffuseColor, specularColor); -} + FP vec3 snormal = normalize( vec3( tangentMatrix[0][2], tangentMatrix[1][2], tangentMatrix[2][2] ) ); -void addLightAdsModel(const in FP vec3 vpos, - const in FP vec3 n, - const in FP vec3 eye, - const in FP float shininess, - const in Light light, - inout FP vec3 diffuseColor, - inout FP vec3 specularColor) -{ - FP vec3 s; + FP vec3 n = normalize( vnormal ); - FP float att = 1.0; - if ( light.type != TYPE_DIRECTIONAL ) { - s = light.position - vpos; - if (length( light.attenuation ) != 0.0) { - FP float dist = length(s); - att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist); - } - s = normalize( s ); - if ( light.type == TYPE_SPOT ) { - if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle) + FP vec3 s, ts; + Light light; + for (int i = 0; i < lightCount; ++i) { + if (i == 0) + light = lights[0]; + else if (i == 1) + light = lights[1]; + else if (i == 2) + light = lights[2]; + else if (i == 3) + light = lights[3]; + else if (i == 4) + light = lights[4]; + else if (i == 5) + light = lights[5]; + else if (i == 6) + light = lights[6]; + else if (i == 7) + light = lights[7]; + + FP float att = 1.0; + if ( light.type != TYPE_DIRECTIONAL ) { + s = light.position - vpos; + if ( dot(snormal, s) < 0.0 ) + att = 0.0; + else { + ts = normalize( tangentMatrix * s ); + if (length( light.attenuation ) != 0.0) { + FP float dist = length(s); + att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist); + } + s = normalize( s ); + if ( light.type == TYPE_SPOT ) { + if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle) + att = 0.0; + } + } + } else { + if ( dot(snormal, -light.direction) > 0.0 ) + s = normalize( tangentMatrix * -light.direction ); + else att = 0.0; } - } else { - s = normalize( -light.direction ); - } - FP float diffuse = max( dot( s, n ), 0.0 ); - FP float specular = 0.0; + FP float diffuse = max( dot( ts, n ), 0.0 ); - if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) { - FP vec3 r = reflect( -s, n ); - FP vec3 v = normalize( eye - vpos ); - FP float normFactor = ( shininess + 2.0 ) / 2.0; - specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess ); - } + FP float specular = 0.0; + if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) { + FP vec3 r = reflect( -ts, n ); + FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) ); + FP float normFactor = ( shininess + 2.0 ) / 2.0; + specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess ); + } - diffuseColor += att * light.intensity * diffuse * light.color; - specularColor += att * light.intensity * specular * light.color; + diffuseColor += att * light.intensity * diffuse * light.color; + specularColor += att * light.intensity * specular * light.color; + } } - void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess, out FP vec3 diffuseColor, out FP vec3 specularColor) { diffuseColor = vec3(0.0); specularColor = vec3(0.0); - if (lightCount < 1) return; FP vec3 n = normalize( vnormal ); - addLightAdsModel(vpos, n, eye, shininess, lights[0], diffuseColor, specularColor); - if (lightCount < 2) return; - - addLightAdsModel(vpos, n, eye, shininess, lights[1], diffuseColor, specularColor); - if (lightCount < 3) return; - - addLightAdsModel(vpos, n, eye, shininess, lights[2], diffuseColor, specularColor); - if (lightCount < 4) return; - - addLightAdsModel(vpos, n, eye, shininess, lights[3], diffuseColor, specularColor); - if (lightCount < 5) return; - - addLightAdsModel(vpos, n, eye, shininess, lights[4], diffuseColor, specularColor); - if (lightCount < 6) return; - - addLightAdsModel(vpos, n, eye, shininess, lights[5], diffuseColor, specularColor); - if (lightCount < 7) return; - addLightAdsModel(vpos, n, eye, shininess, lights[6], diffuseColor, specularColor); - if (lightCount < 8) return; - - addLightAdsModel(vpos, n, eye, shininess, lights[7], diffuseColor, specularColor); -} - -void addLightAdModel(const in FP vec3 vpos, - const in FP vec3 n, - const in Light light, - inout FP vec3 diffuseColor) -{ FP vec3 s; - FP float att = 1.0; - if ( light.type != TYPE_DIRECTIONAL ) { - s = light.position - vpos; - if (length( light.attenuation ) != 0.0) { - FP float dist = length(s); - att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist); - } - s = normalize( s ); - if ( light.type == TYPE_SPOT ) { - if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle) - att = 0.0; + Light light; + for (int i = 0; i < lightCount; ++i) { + if (i == 0) + light = lights[0]; + else if (i == 1) + light = lights[1]; + else if (i == 2) + light = lights[2]; + else if (i == 3) + light = lights[3]; + else if (i == 4) + light = lights[4]; + else if (i == 5) + light = lights[5]; + else if (i == 6) + light = lights[6]; + else if (i == 7) + light = lights[7]; + + FP float att = 1.0; + if ( light.type != TYPE_DIRECTIONAL ) { + s = light.position - vpos; + if (length( light.attenuation ) != 0.0) { + FP float dist = length(s); + att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist); + } + s = normalize( s ); + if ( light.type == TYPE_SPOT ) { + if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle) + att = 0.0; + } + } else { + s = normalize( -light.direction ); } - } else { - s = normalize( -light.direction ); - } - FP float diffuse = max( dot( s, n ), 0.0 ); + FP float diffuse = max( dot( s, n ), 0.0 ); + + FP float specular = 0.0; + if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) { + FP vec3 r = reflect( -s, n ); + FP vec3 v = normalize( eye - vpos ); + FP float normFactor = ( shininess + 2.0 ) / 2.0; + specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess ); + } - diffuseColor += att * light.intensity * diffuse * light.color; + diffuseColor += att * light.intensity * diffuse * light.color; + specularColor += att * light.intensity * specular * light.color; + } } void adModel(const in FP vec3 vpos, const in FP vec3 vnormal, out FP vec3 diffuseColor) { diffuseColor = vec3(0.0); - if (lightCount < 1) return; FP vec3 n = normalize( vnormal ); - addLightAdModel(vpos, n, lights[0], diffuseColor); - if (lightCount < 2) return; - - addLightAdModel(vpos, n, lights[1], diffuseColor); - if (lightCount < 3) return; - addLightAdModel(vpos, n, lights[2], diffuseColor); - if (lightCount < 4) return; - - addLightAdModel(vpos, n, lights[3], diffuseColor); - if (lightCount < 5) return; - - addLightAdModel(vpos, n, lights[4], diffuseColor); - if (lightCount < 6) return; - - addLightAdModel(vpos, n, lights[5], diffuseColor); - if (lightCount < 7) return; + FP vec3 s; + Light light; + for (int i = 0; i < lightCount; ++i) { + if (i == 0) + light = lights[0]; + else if (i == 1) + light = lights[1]; + else if (i == 2) + light = lights[2]; + else if (i == 3) + light = lights[3]; + else if (i == 4) + light = lights[4]; + else if (i == 5) + light = lights[5]; + else if (i == 6) + light = lights[6]; + else if (i == 7) + light = lights[7]; + + FP float att = 1.0; + if ( light.type != TYPE_DIRECTIONAL ) { + s = light.position - vpos; + if (length( light.attenuation ) != 0.0) { + FP float dist = length(s); + att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist); + } + s = normalize( s ); + if ( light.type == TYPE_SPOT ) { + if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle) + att = 0.0; + } + } else { + s = normalize( -light.direction ); + } - addLightAdModel(vpos, n, lights[6], diffuseColor); - if (lightCount < 8) return; + FP float diffuse = max( dot( s, n ), 0.0 ); - addLightAdModel(vpos, n, lights[7], diffuseColor); + diffuseColor += att * light.intensity * diffuse * light.color; + } } -- cgit v1.2.3 From 4b3f368aba47d559040c3f038620883462b925ea Mon Sep 17 00:00:00 2001 From: Robert Brock Date: Mon, 9 Jan 2017 08:10:57 +0000 Subject: Replace undistributable files The texture files used were from a third party that didn't explicitly allow their distribution. All of them have been replaced by textures from NASA and another third party that do allow their distribution and editing. Task-number: QTBUG-57543 Change-Id: I69f1309424bba029cdce08689ea8670ed32d44ae Reviewed-by: Lars Knoll --- examples/qt3d/planets-qml/SolarSystem.qml | 42 +++++++++--------- .../planets-qml/images/earthcloudmapcolortrans.png | Bin 1041258 -> 0 bytes .../qt3d/planets-qml/images/earthcloudmapspec.jpg | Bin 102821 -> 0 bytes examples/qt3d/planets-qml/images/earthmap1k.jpg | Bin 341782 -> 0 bytes examples/qt3d/planets-qml/images/earthnormal1k.jpg | Bin 176666 -> 0 bytes examples/qt3d/planets-qml/images/earthspec1k.jpg | Bin 100936 -> 0 bytes .../qt3d/planets-qml/images/galaxy_starfield.png | Bin 670297 -> 0 bytes examples/qt3d/planets-qml/images/jupitermap.jpg | Bin 157780 -> 0 bytes examples/qt3d/planets-qml/images/marsmap1k.jpg | Bin 501328 -> 0 bytes examples/qt3d/planets-qml/images/marsnormal1k.jpg | Bin 226859 -> 0 bytes examples/qt3d/planets-qml/images/mercurymap.jpg | Bin 285975 -> 0 bytes examples/qt3d/planets-qml/images/mercurynormal.jpg | Bin 961068 -> 0 bytes examples/qt3d/planets-qml/images/moonmap1k.jpg | Bin 389305 -> 0 bytes examples/qt3d/planets-qml/images/moonnormal1k.jpg | Bin 847618 -> 0 bytes examples/qt3d/planets-qml/images/nasa/license.txt | 3 ++ .../planets-qml/images/nasa/qt_attribution.json | 13 ++++++ .../images/nasa/uranusringcolortrans.png | Bin 0 -> 341169 bytes examples/qt3d/planets-qml/images/neptunemap.jpg | Bin 48069 -> 0 bytes examples/qt3d/planets-qml/images/saturnmap.jpg | Bin 40837 -> 0 bytes .../planets-qml/images/saturnringcolortrans.png | Bin 311632 -> 0 bytes .../solarsystemscope/earthcloudmapcolortrans.png | Bin 0 -> 1830686 bytes .../images/solarsystemscope/earthcloudmapspec.jpg | Bin 0 -> 603331 bytes .../images/solarsystemscope/earthmap2k.jpg | Bin 0 -> 307630 bytes .../images/solarsystemscope/earthnormal2k.jpg | Bin 0 -> 584692 bytes .../images/solarsystemscope/earthspec2k.jpg | Bin 0 -> 185837 bytes .../images/solarsystemscope/galaxy_starfield.jpg | Bin 0 -> 521243 bytes .../images/solarsystemscope/jupitermap.jpg | Bin 0 -> 345203 bytes .../images/solarsystemscope/license.txt | 6 +++ .../images/solarsystemscope/marsmap2k.jpg | Bin 0 -> 489786 bytes .../images/solarsystemscope/marsnormal2k.jpg | Bin 0 -> 1073295 bytes .../images/solarsystemscope/mercurymap.jpg | Bin 0 -> 534775 bytes .../images/solarsystemscope/mercurynormal.jpg | Bin 0 -> 1397792 bytes .../images/solarsystemscope/moonmap2k.jpg | Bin 0 -> 641394 bytes .../images/solarsystemscope/moonnormal2k.jpg | Bin 0 -> 1473741 bytes .../images/solarsystemscope/neptunemap.jpg | Bin 0 -> 87217 bytes .../images/solarsystemscope/qt_attribution.json | 14 ++++++ .../images/solarsystemscope/saturnmap.jpg | Bin 0 -> 143493 bytes .../solarsystemscope/saturnringcolortrans.png | Bin 0 -> 355950 bytes .../planets-qml/images/solarsystemscope/sunmap.jpg | Bin 0 -> 563238 bytes .../images/solarsystemscope/uranusmap.jpg | Bin 0 -> 40631 bytes .../images/solarsystemscope/venusmap.jpg | Bin 0 -> 555402 bytes .../images/solarsystemscope/venusnormal.jpg | Bin 0 -> 1263138 bytes examples/qt3d/planets-qml/images/sunmap.jpg | Bin 281479 -> 0 bytes examples/qt3d/planets-qml/images/uranusmap.jpg | Bin 8942 -> 0 bytes .../planets-qml/images/uranusringcolortrans.png | Bin 300655 -> 0 bytes examples/qt3d/planets-qml/images/venusmap.jpg | Bin 255067 -> 0 bytes examples/qt3d/planets-qml/images/venusnormal.jpg | Bin 742335 -> 0 bytes examples/qt3d/planets-qml/planets-qml-images.qrc | 47 +++++++++++---------- examples/qt3d/planets-qml/planets-qml.pro | 3 +- .../qt3d/planets-qml/shaders/gl3/planetDSB.frag | 14 +++--- 50 files changed, 90 insertions(+), 52 deletions(-) delete mode 100644 examples/qt3d/planets-qml/images/earthcloudmapcolortrans.png delete mode 100644 examples/qt3d/planets-qml/images/earthcloudmapspec.jpg delete mode 100644 examples/qt3d/planets-qml/images/earthmap1k.jpg delete mode 100644 examples/qt3d/planets-qml/images/earthnormal1k.jpg delete mode 100644 examples/qt3d/planets-qml/images/earthspec1k.jpg delete mode 100644 examples/qt3d/planets-qml/images/galaxy_starfield.png delete mode 100644 examples/qt3d/planets-qml/images/jupitermap.jpg delete mode 100644 examples/qt3d/planets-qml/images/marsmap1k.jpg delete mode 100644 examples/qt3d/planets-qml/images/marsnormal1k.jpg delete mode 100644 examples/qt3d/planets-qml/images/mercurymap.jpg delete mode 100644 examples/qt3d/planets-qml/images/mercurynormal.jpg delete mode 100644 examples/qt3d/planets-qml/images/moonmap1k.jpg delete mode 100644 examples/qt3d/planets-qml/images/moonnormal1k.jpg create mode 100644 examples/qt3d/planets-qml/images/nasa/license.txt create mode 100644 examples/qt3d/planets-qml/images/nasa/qt_attribution.json create mode 100755 examples/qt3d/planets-qml/images/nasa/uranusringcolortrans.png delete mode 100644 examples/qt3d/planets-qml/images/neptunemap.jpg delete mode 100644 examples/qt3d/planets-qml/images/saturnmap.jpg delete mode 100644 examples/qt3d/planets-qml/images/saturnringcolortrans.png create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/earthcloudmapcolortrans.png create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/earthcloudmapspec.jpg create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/earthmap2k.jpg create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/earthnormal2k.jpg create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/earthspec2k.jpg create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/galaxy_starfield.jpg create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/jupitermap.jpg create mode 100644 examples/qt3d/planets-qml/images/solarsystemscope/license.txt create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/marsmap2k.jpg create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/marsnormal2k.jpg create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/mercurymap.jpg create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/mercurynormal.jpg create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/moonmap2k.jpg create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/moonnormal2k.jpg create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/neptunemap.jpg create mode 100644 examples/qt3d/planets-qml/images/solarsystemscope/qt_attribution.json create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/saturnmap.jpg create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/saturnringcolortrans.png create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/sunmap.jpg create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/uranusmap.jpg create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/venusmap.jpg create mode 100755 examples/qt3d/planets-qml/images/solarsystemscope/venusnormal.jpg delete mode 100644 examples/qt3d/planets-qml/images/sunmap.jpg delete mode 100644 examples/qt3d/planets-qml/images/uranusmap.jpg delete mode 100644 examples/qt3d/planets-qml/images/uranusringcolortrans.png delete mode 100644 examples/qt3d/planets-qml/images/venusmap.jpg delete mode 100644 examples/qt3d/planets-qml/images/venusnormal.jpg diff --git a/examples/qt3d/planets-qml/SolarSystem.qml b/examples/qt3d/planets-qml/SolarSystem.qml index 0cd2a4db5..f9353d6dc 100644 --- a/examples/qt3d/planets-qml/SolarSystem.qml +++ b/examples/qt3d/planets-qml/SolarSystem.qml @@ -503,7 +503,7 @@ Entity { effect: effectD ambientLight: ambientStrengthStarfield specularColor: Qt.rgba(0.0, 0.0, 0.0, 1.0) - diffuseMap: "qrc:/images/galaxy_starfield.png" + diffuseMap: "qrc:/images/solarsystemscope/galaxy_starfield.jpg" shininess: 1000000.0 } @@ -531,7 +531,7 @@ Entity { id: materialSun effect: sunEffect ambientLight: ambientStrengthSun - diffuseMap: "qrc:/images/sunmap.jpg" + diffuseMap: "qrc:/images/solarsystemscope/sunmap.jpg" } property Transform transformSun: Transform { @@ -567,8 +567,8 @@ Entity { effect: effectDB ambientLight: ambientStrengthPlanet specularColor: Qt.rgba(0.2, 0.2, 0.2, 1.0) - diffuseMap: "qrc:/images/mercurymap.jpg" - normalMap: "qrc:/images/mercurynormal.jpg" + diffuseMap: "qrc:/images/solarsystemscope/mercurymap.jpg" + normalMap: "qrc:/images/solarsystemscope/mercurynormal.jpg" shininess: shininessSpecularMap } @@ -601,8 +601,8 @@ Entity { effect: effectDB ambientLight: ambientStrengthPlanet specularColor: Qt.rgba(0.2, 0.2, 0.2, 1.0) - diffuseMap: "qrc:/images/venusmap.jpg" - normalMap: "qrc:/images/venusnormal.jpg" + diffuseMap: "qrc:/images/solarsystemscope/venusmap.jpg" + normalMap: "qrc:/images/solarsystemscope/venusnormal.jpg" shininess: shininessSpecularMap } @@ -635,9 +635,9 @@ Entity { id: materialEarth effect: effectDSB ambientLight: ambientStrengthPlanet - diffuseMap: "qrc:/images/earthmap1k.jpg" - specularMap: "qrc:/images/earthspec1k.jpg" - normalMap: "qrc:/images/earthnormal1k.jpg" + diffuseMap: "qrc:/images/solarsystemscope/earthmap2k.jpg" + specularMap: "qrc:/images/solarsystemscope/earthspec2k.jpg" + normalMap: "qrc:/images/solarsystemscope/earthnormal2k.jpg" shininess: shininessSpecularMap } @@ -670,8 +670,8 @@ Entity { id: materialEarthClouds effect: cloudEffect ambientLight: ambientStrengthClouds - diffuseMap: "qrc:/images/earthcloudmapcolortrans.png" - specularMap: "qrc:/images/earthcloudmapspec.jpg" + diffuseMap: "qrc:/images/solarsystemscope/earthcloudmapcolortrans.png" + specularMap: "qrc:/images/solarsystemscope/earthcloudmapspec.jpg" shininess: shininessClouds opacity: 0.2 } @@ -705,8 +705,8 @@ Entity { effect: effectDB ambientLight: ambientStrengthPlanet specularColor: Qt.rgba(0.2, 0.2, 0.2, 1.0) - diffuseMap: "qrc:/images/moonmap1k.jpg" - normalMap: "qrc:/images/moonnormal1k.jpg" + diffuseMap: "qrc:/images/solarsystemscope/moonmap2k.jpg" + normalMap: "qrc:/images/solarsystemscope/moonnormal2k.jpg" shininess: shininessSpecularMap } @@ -739,8 +739,8 @@ Entity { effect: effectDB ambientLight: ambientStrengthPlanet specularColor: Qt.rgba(0.2, 0.2, 0.2, 1.0) - diffuseMap: "qrc:/images/marsmap1k.jpg" - normalMap: "qrc:/images/marsnormal1k.jpg" + diffuseMap: "qrc:/images/solarsystemscope/marsmap2k.jpg" + normalMap: "qrc:/images/solarsystemscope/marsnormal2k.jpg" shininess: shininessSpecularMap } @@ -773,7 +773,7 @@ Entity { effect: effectD ambientLight: ambientStrengthPlanet specularColor: Qt.rgba(0.2, 0.2, 0.2, 1.0) - diffuseMap: "qrc:/images/jupitermap.jpg" + diffuseMap: "qrc:/images/solarsystemscope/jupitermap.jpg" shininess: shininessBasic } @@ -806,7 +806,7 @@ Entity { effect: shadowMapEffect ambientLight: ambientStrengthPlanet specularColor: Qt.rgba(0.2, 0.2, 0.2, 1.0) - diffuseMap: "qrc:/images/saturnmap.jpg" + diffuseMap: "qrc:/images/solarsystemscope/saturnmap.jpg" shininess: shininessBasic } @@ -840,7 +840,7 @@ Entity { effect: shadowMapEffect ambientLight: ambientStrengthRing specularColor: Qt.rgba(0.01, 0.01, 0.01, 1.0) - diffuseMap: "qrc:/images/saturnringcolortrans.png" + diffuseMap: "qrc:/images/solarsystemscope/saturnringcolortrans.png" shininess: shininessBasic opacity: 0.4 } @@ -874,7 +874,7 @@ Entity { effect: shadowMapEffect ambientLight: ambientStrengthPlanet specularColor: Qt.rgba(0.2, 0.2, 0.2, 1.0) - diffuseMap: "qrc:/images/uranusmap.jpg" + diffuseMap: "qrc:/images/solarsystemscope/uranusmap.jpg" shininess: shininessBasic } @@ -908,7 +908,7 @@ Entity { effect: shadowMapEffect ambientLight: ambientStrengthRing specularColor: Qt.rgba(0.01, 0.01, 0.01, 1.0) - diffuseMap: "qrc:/images/uranusringcolortrans.png" + diffuseMap: "qrc:/images/nasa/uranusringcolortrans.png" shininess: shininessBasic opacity: 0.4 } @@ -942,7 +942,7 @@ Entity { effect: effectD ambientLight: ambientStrengthPlanet specularColor: Qt.rgba(0.2, 0.2, 0.2, 1.0) - diffuseMap: "qrc:/images/neptunemap.jpg" + diffuseMap: "qrc:/images/solarsystemscope/neptunemap.jpg" shininess: shininessBasic } diff --git a/examples/qt3d/planets-qml/images/earthcloudmapcolortrans.png b/examples/qt3d/planets-qml/images/earthcloudmapcolortrans.png deleted file mode 100644 index ee2a89732..000000000 Binary files a/examples/qt3d/planets-qml/images/earthcloudmapcolortrans.png and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/earthcloudmapspec.jpg b/examples/qt3d/planets-qml/images/earthcloudmapspec.jpg deleted file mode 100644 index 9970a3839..000000000 Binary files a/examples/qt3d/planets-qml/images/earthcloudmapspec.jpg and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/earthmap1k.jpg b/examples/qt3d/planets-qml/images/earthmap1k.jpg deleted file mode 100644 index e1de9d3a9..000000000 Binary files a/examples/qt3d/planets-qml/images/earthmap1k.jpg and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/earthnormal1k.jpg b/examples/qt3d/planets-qml/images/earthnormal1k.jpg deleted file mode 100644 index 491d430a1..000000000 Binary files a/examples/qt3d/planets-qml/images/earthnormal1k.jpg and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/earthspec1k.jpg b/examples/qt3d/planets-qml/images/earthspec1k.jpg deleted file mode 100644 index 3de6fe7af..000000000 Binary files a/examples/qt3d/planets-qml/images/earthspec1k.jpg and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/galaxy_starfield.png b/examples/qt3d/planets-qml/images/galaxy_starfield.png deleted file mode 100644 index 36a762e3c..000000000 Binary files a/examples/qt3d/planets-qml/images/galaxy_starfield.png and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/jupitermap.jpg b/examples/qt3d/planets-qml/images/jupitermap.jpg deleted file mode 100644 index 69107dfe6..000000000 Binary files a/examples/qt3d/planets-qml/images/jupitermap.jpg and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/marsmap1k.jpg b/examples/qt3d/planets-qml/images/marsmap1k.jpg deleted file mode 100644 index 64ebc538c..000000000 Binary files a/examples/qt3d/planets-qml/images/marsmap1k.jpg and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/marsnormal1k.jpg b/examples/qt3d/planets-qml/images/marsnormal1k.jpg deleted file mode 100644 index af910cab4..000000000 Binary files a/examples/qt3d/planets-qml/images/marsnormal1k.jpg and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/mercurymap.jpg b/examples/qt3d/planets-qml/images/mercurymap.jpg deleted file mode 100644 index 9bb2c0be0..000000000 Binary files a/examples/qt3d/planets-qml/images/mercurymap.jpg and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/mercurynormal.jpg b/examples/qt3d/planets-qml/images/mercurynormal.jpg deleted file mode 100644 index d64512489..000000000 Binary files a/examples/qt3d/planets-qml/images/mercurynormal.jpg and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/moonmap1k.jpg b/examples/qt3d/planets-qml/images/moonmap1k.jpg deleted file mode 100644 index 509d3f5a4..000000000 Binary files a/examples/qt3d/planets-qml/images/moonmap1k.jpg and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/moonnormal1k.jpg b/examples/qt3d/planets-qml/images/moonnormal1k.jpg deleted file mode 100644 index b478ed484..000000000 Binary files a/examples/qt3d/planets-qml/images/moonnormal1k.jpg and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/nasa/license.txt b/examples/qt3d/planets-qml/images/nasa/license.txt new file mode 100644 index 000000000..62a6d9ffd --- /dev/null +++ b/examples/qt3d/planets-qml/images/nasa/license.txt @@ -0,0 +1,3 @@ +Uranus Ring: +http://photojournal.jpl.nasa.gov/catalog/PIA00033 - Courtesy NASA/JPL-Caltech. +Used under the terms of the license at http://www.jpl.nasa.gov/imagepolicy/ diff --git a/examples/qt3d/planets-qml/images/nasa/qt_attribution.json b/examples/qt3d/planets-qml/images/nasa/qt_attribution.json new file mode 100644 index 000000000..174e092ef --- /dev/null +++ b/examples/qt3d/planets-qml/images/nasa/qt_attribution.json @@ -0,0 +1,13 @@ +{ + "Id": "nasa-jpl", + "Name": "Jet Propulsion Laboratory Photojournal", + "QDocModule": "qt3d", + "Description": "The NASA/JPL Photojournal provides high quality images related to space research and exploration", + "QtUsage": "Used in Qt 3D planets-qml example.", + + "DownloadLocation": "https://photojournal.jpl.nasa.gov/catalog/PIA00033", + "Homepage": "https://photojournal.jpl.nasa.gov/", + "License": "JPL Image Use Policy", + "LicenseFile": "license.txt", + "Copyright": "Copyright (c) 1996, Jet Propulsion Laboratory" +} diff --git a/examples/qt3d/planets-qml/images/nasa/uranusringcolortrans.png b/examples/qt3d/planets-qml/images/nasa/uranusringcolortrans.png new file mode 100755 index 000000000..b0953dec5 Binary files /dev/null and b/examples/qt3d/planets-qml/images/nasa/uranusringcolortrans.png differ diff --git a/examples/qt3d/planets-qml/images/neptunemap.jpg b/examples/qt3d/planets-qml/images/neptunemap.jpg deleted file mode 100644 index 0d0d3f06a..000000000 Binary files a/examples/qt3d/planets-qml/images/neptunemap.jpg and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/saturnmap.jpg b/examples/qt3d/planets-qml/images/saturnmap.jpg deleted file mode 100644 index 767be39e4..000000000 Binary files a/examples/qt3d/planets-qml/images/saturnmap.jpg and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/saturnringcolortrans.png b/examples/qt3d/planets-qml/images/saturnringcolortrans.png deleted file mode 100644 index 48a9a5911..000000000 Binary files a/examples/qt3d/planets-qml/images/saturnringcolortrans.png and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/earthcloudmapcolortrans.png b/examples/qt3d/planets-qml/images/solarsystemscope/earthcloudmapcolortrans.png new file mode 100755 index 000000000..1aabde94e Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/earthcloudmapcolortrans.png differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/earthcloudmapspec.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/earthcloudmapspec.jpg new file mode 100755 index 000000000..254b6fb6c Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/earthcloudmapspec.jpg differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/earthmap2k.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/earthmap2k.jpg new file mode 100755 index 000000000..e90540c83 Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/earthmap2k.jpg differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/earthnormal2k.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/earthnormal2k.jpg new file mode 100755 index 000000000..8215226fb Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/earthnormal2k.jpg differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/earthspec2k.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/earthspec2k.jpg new file mode 100755 index 000000000..8e2b3f6c1 Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/earthspec2k.jpg differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/galaxy_starfield.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/galaxy_starfield.jpg new file mode 100755 index 000000000..2be906a73 Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/galaxy_starfield.jpg differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/jupitermap.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/jupitermap.jpg new file mode 100755 index 000000000..f5af80197 Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/jupitermap.jpg differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/license.txt b/examples/qt3d/planets-qml/images/solarsystemscope/license.txt new file mode 100644 index 000000000..40ff1c577 --- /dev/null +++ b/examples/qt3d/planets-qml/images/solarsystemscope/license.txt @@ -0,0 +1,6 @@ +www.solarsystemscope.com/textures distributed under the terms of +https://creativecommons.org/licenses/by/4.0/ + +Changes: +- Rings created from the reference rectangle file. +- earthcloudmapcolortrans.png was made from the earthcloudmapspec.jpg file diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/marsmap2k.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/marsmap2k.jpg new file mode 100755 index 000000000..ea77177fb Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/marsmap2k.jpg differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/marsnormal2k.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/marsnormal2k.jpg new file mode 100755 index 000000000..44a2e2f9b Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/marsnormal2k.jpg differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/mercurymap.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/mercurymap.jpg new file mode 100755 index 000000000..f69e947c0 Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/mercurymap.jpg differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/mercurynormal.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/mercurynormal.jpg new file mode 100755 index 000000000..5e77923bf Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/mercurynormal.jpg differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/moonmap2k.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/moonmap2k.jpg new file mode 100755 index 000000000..0e0c20d0a Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/moonmap2k.jpg differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/moonnormal2k.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/moonnormal2k.jpg new file mode 100755 index 000000000..10797cf0a Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/moonnormal2k.jpg differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/neptunemap.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/neptunemap.jpg new file mode 100755 index 000000000..250fce966 Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/neptunemap.jpg differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/qt_attribution.json b/examples/qt3d/planets-qml/images/solarsystemscope/qt_attribution.json new file mode 100644 index 000000000..35e9afe39 --- /dev/null +++ b/examples/qt3d/planets-qml/images/solarsystemscope/qt_attribution.json @@ -0,0 +1,14 @@ +{ + "Id": "solar_system_scope", + "Name": "Solar System Scope Texture Library", + "QDocModule": "qt3d", + "QtParts": ["examples"], + "Description": "Solar System Scope provides high quality, free to use textures for objects in the solar system.", + "QtUsage": "Used in Qt 3D planets-qml example.", + + "Homepage": "www.solarsystemscope.com/textures", + "License": "Creative Commons Attribution 4.0", + "LicenseId": "CC-BY-4.0", + "LicenseFile": "license.txt", + "Copyright": "Copyright (c) 2010-2017, Solar System Scope" +} diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/saturnmap.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/saturnmap.jpg new file mode 100755 index 000000000..981bb36c9 Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/saturnmap.jpg differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/saturnringcolortrans.png b/examples/qt3d/planets-qml/images/solarsystemscope/saturnringcolortrans.png new file mode 100755 index 000000000..aefd9f6c4 Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/saturnringcolortrans.png differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/sunmap.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/sunmap.jpg new file mode 100755 index 000000000..46f2ce8c1 Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/sunmap.jpg differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/uranusmap.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/uranusmap.jpg new file mode 100755 index 000000000..96cea14be Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/uranusmap.jpg differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/venusmap.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/venusmap.jpg new file mode 100755 index 000000000..93bed3e47 Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/venusmap.jpg differ diff --git a/examples/qt3d/planets-qml/images/solarsystemscope/venusnormal.jpg b/examples/qt3d/planets-qml/images/solarsystemscope/venusnormal.jpg new file mode 100755 index 000000000..0fc5ff703 Binary files /dev/null and b/examples/qt3d/planets-qml/images/solarsystemscope/venusnormal.jpg differ diff --git a/examples/qt3d/planets-qml/images/sunmap.jpg b/examples/qt3d/planets-qml/images/sunmap.jpg deleted file mode 100644 index 3e0b520e4..000000000 Binary files a/examples/qt3d/planets-qml/images/sunmap.jpg and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/uranusmap.jpg b/examples/qt3d/planets-qml/images/uranusmap.jpg deleted file mode 100644 index aad43fb47..000000000 Binary files a/examples/qt3d/planets-qml/images/uranusmap.jpg and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/uranusringcolortrans.png b/examples/qt3d/planets-qml/images/uranusringcolortrans.png deleted file mode 100644 index 13a5f1558..000000000 Binary files a/examples/qt3d/planets-qml/images/uranusringcolortrans.png and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/venusmap.jpg b/examples/qt3d/planets-qml/images/venusmap.jpg deleted file mode 100644 index 699f2804e..000000000 Binary files a/examples/qt3d/planets-qml/images/venusmap.jpg and /dev/null differ diff --git a/examples/qt3d/planets-qml/images/venusnormal.jpg b/examples/qt3d/planets-qml/images/venusnormal.jpg deleted file mode 100644 index fea52cb47..000000000 Binary files a/examples/qt3d/planets-qml/images/venusnormal.jpg and /dev/null differ diff --git a/examples/qt3d/planets-qml/planets-qml-images.qrc b/examples/qt3d/planets-qml/planets-qml-images.qrc index 937e32de8..6b6b30ec4 100644 --- a/examples/qt3d/planets-qml/planets-qml-images.qrc +++ b/examples/qt3d/planets-qml/planets-qml-images.qrc @@ -1,34 +1,35 @@ - images/sunmap.jpg - images/mercurymap.jpg - images/mercurynormal.jpg - images/venusmap.jpg - images/venusnormal.jpg - images/earthmap1k.jpg - images/earthnormal1k.jpg - images/earthspec1k.jpg - images/moonmap1k.jpg - images/moonnormal1k.jpg - images/marsmap1k.jpg - images/marsnormal1k.jpg - images/jupitermap.jpg - images/saturnmap.jpg - images/uranusmap.jpg - images/neptunemap.jpg + images/nasa/uranusringcolortrans.png + images/solarsystemscope/earthcloudmapcolortrans.png + images/solarsystemscope/earthcloudmapspec.jpg + images/solarsystemscope/earthmap2k.jpg + images/solarsystemscope/earthnormal2k.jpg + images/solarsystemscope/earthspec2k.jpg + images/solarsystemscope/galaxy_starfield.jpg + images/solarsystemscope/jupitermap.jpg + images/solarsystemscope/license.txt + images/solarsystemscope/marsmap2k.jpg + images/solarsystemscope/marsnormal2k.jpg + images/solarsystemscope/mercurymap.jpg + images/solarsystemscope/mercurynormal.jpg + images/solarsystemscope/moonmap2k.jpg + images/solarsystemscope/moonnormal2k.jpg + images/solarsystemscope/neptunemap.jpg + images/solarsystemscope/saturnmap.jpg + images/solarsystemscope/saturnringcolortrans.png + images/solarsystemscope/sunmap.jpg + images/solarsystemscope/uranusmap.jpg + images/solarsystemscope/venusmap.jpg + images/solarsystemscope/venusnormal.jpg images/earth.png - images/mercury.png images/jupiter.png images/mars.png - images/neptune.png + images/mercury.png images/saturn.png images/sun.png images/uranus.png images/venus.png - images/earthcloudmapcolortrans.png - images/earthcloudmapspec.jpg - images/saturnringcolortrans.png - images/uranusringcolortrans.png - images/galaxy_starfield.png + images/neptune.png diff --git a/examples/qt3d/planets-qml/planets-qml.pro b/examples/qt3d/planets-qml/planets-qml.pro index 18175823f..de14ecc8a 100644 --- a/examples/qt3d/planets-qml/planets-qml.pro +++ b/examples/qt3d/planets-qml/planets-qml.pro @@ -31,6 +31,7 @@ RESOURCES += \ DISTFILES += \ PlanetsMain.qml \ - android/AndroidManifest.xml + android/AndroidManifest.xml \ + images/license.txt ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android diff --git a/examples/qt3d/planets-qml/shaders/gl3/planetDSB.frag b/examples/qt3d/planets-qml/shaders/gl3/planetDSB.frag index 507d1d208..bf6461191 100644 --- a/examples/qt3d/planets-qml/shaders/gl3/planetDSB.frag +++ b/examples/qt3d/planets-qml/shaders/gl3/planetDSB.frag @@ -70,13 +70,13 @@ in vec2 texCoord; out vec4 fragColor; -void dsbModel(const in vec3 norm, const in vec2 flipYTexCoord, out vec3 ambientAndDiff, out vec3 spec) +void dsbModel(const in vec3 norm, const in vec2 flipXTexCoord, out vec3 ambientAndDiff, out vec3 spec) { // Reflection of light direction about normal vec3 r = reflect(-lightDir, norm); - vec3 diffuseColor = texture(diffuseTexture, flipYTexCoord).rgb; - vec3 specularColor = texture(specularTexture, flipYTexCoord).rgb; + vec3 diffuseColor = texture(diffuseTexture, flipXTexCoord).rgb; + vec3 specularColor = texture(specularTexture, flipXTexCoord).rgb; // Calculate the ambient contribution vec3 ambient = lightIntensity * ka * diffuseColor; @@ -98,15 +98,15 @@ void dsbModel(const in vec3 norm, const in vec2 flipYTexCoord, out vec3 ambientA void main() { - vec2 flipYTexCoord = texCoord; - flipYTexCoord.y = 1.0 - texCoord.y; + vec2 flipXTexCoord = texCoord; + flipXTexCoord.x = 1.0 - texCoord.x; // Sample the textures at the interpolated texCoords - vec4 normal = 2.0 * texture(normalTexture, flipYTexCoord) - vec4(1.0); + vec4 normal = 2.0 * texture(normalTexture, flipXTexCoord) - vec4(1.0); // Calculate the lighting model, keeping the specular component separate vec3 ambientAndDiff, spec; - dsbModel(normalize(normal.xyz), flipYTexCoord, ambientAndDiff, spec); + dsbModel(normalize(normal.xyz), flipXTexCoord, ambientAndDiff, spec); vec3 result = ambientAndDiff + spec; // Combine spec with ambient+diffuse for final fragment color -- cgit v1.2.3 From bfb5627c3426ac60223c0fe422e707013598d129 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Fri, 28 Apr 2017 10:36:11 +0200 Subject: Renderer: prevent crash in case texture failed to be built This can occur if a TextureLoader fails to load (wrong path, access denied ...) Change-Id: I55b62312db79db3980146bb17cbadbe5c66d7a48 Reviewed-by: Sean Harmer --- src/render/texture/gltexture.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/render/texture/gltexture.cpp b/src/render/texture/gltexture.cpp index a2e0dc5d0..606681bd5 100644 --- a/src/render/texture/gltexture.cpp +++ b/src/render/texture/gltexture.cpp @@ -188,6 +188,8 @@ QOpenGLTexture* GLTexture::getOrCreateGLTexture() if (!m_gl) { m_gl = buildGLTexture(); + if (!m_gl) + return nullptr; m_gl->allocateStorage(); if (!m_gl->isStorageAllocated()) { qWarning() << Q_FUNC_INFO << "texture storage allocation failed"; -- cgit v1.2.3 From 6b231725b2b5e0f2d797f8939bd02637d0196942 Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Thu, 11 May 2017 12:09:24 +0100 Subject: Improve the roughness to mip level mapping We follow the approach used by Lys as detailed at: https://docs.knaldtech.com/doku.php?id=specular_lys Along with the perceptual linear roughness remapping as used by: UE4: http://graphicrants.blogspot.co.uk/2013/08/specular-brdf-reference.html Frostbite: http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf We should also check the punctual light implementation of Blinn Phong specular power based on the above references. Task-number: QTBUG-60181 Change-Id: I8ca6116d8d7847a8f200f366dcd11f693810608e Reviewed-by: Kevin Ottens --- src/extras/shaders/gl3/metalrough.frag | 71 +++++++++++++++++++++++---- src/extras/shaders/gl3/metalroughuniform.frag | 71 +++++++++++++++++++++++---- 2 files changed, 122 insertions(+), 20 deletions(-) diff --git a/src/extras/shaders/gl3/metalrough.frag b/src/extras/shaders/gl3/metalrough.frag index e1eb6bab2..0bbef9167 100644 --- a/src/extras/shaders/gl3/metalrough.frag +++ b/src/extras/shaders/gl3/metalrough.frag @@ -71,11 +71,6 @@ uniform sampler2D ambientOcclusionMap; // User control parameters uniform float metalFactor = 1.0; -// Roughness -> mip level mapping -uniform float maxT = 0.939824; -uniform float mipLevels = 11.0; -uniform float mipOffset = 5.0; - // Exposure correction uniform float exposure = 0.0; // Gamma correction @@ -83,6 +78,13 @@ uniform float gamma = 2.2; #pragma include light.inc.frag +int mipLevelCount(const in samplerCube cube) +{ + int baseSize = textureSize(cube, 0).x; + int nMips = int(log2(float(baseSize>0 ? baseSize : 1))) + 1; + return nMips; +} + mat3 calcWorldSpaceToTangentSpaceMatrix(const in vec3 wNormal, const in vec4 wTangent) { // Make the tangent truly orthogonal to the normal by using Gram-Schmidt. @@ -105,10 +107,35 @@ mat3 calcWorldSpaceToTangentSpaceMatrix(const in vec3 wNormal, const in vec4 wTa float roughnessToMipLevel(float roughness) { - // HACK: Improve the roughness -> mip level mapping for roughness map from substace painter - // TODO: Use mathematica or similar to improve this mapping more generally - roughness = 0.75 + (1.7 * (roughness - 0.5)); - return (mipLevels - 1.0 - mipOffset) * (1.0 - (1.0 - roughness) / maxT); + const float maxSpecPower = 999999.0; + const float minRoughness = sqrt(2.0 / (maxSpecPower + 2)); + float r = max(roughness, minRoughness); + float specPower = 2.0 / (r * r) - 2.0; + + // We use the mip level calculation from Lys' default power drop, which in + // turn is a slight modification of that used in Marmoset Toolbag. See + // https://docs.knaldtech.com/doku.php?id=specular_lys for details. + // For now we assume a max specular power of 999999 which gives + // maxGlossiness = 1. + const float k0 = 0.00098; + const float k1 = 0.9921; + float glossiness = (pow(2.0, -10.0 / sqrt(specPower)) - k0) / k1; + + // TODO: Optimize by doing this on CPU and set as + // uniform int envLight.specularMipLevels say (if present in shader). + // Lookup the number of mips in the specular envmap + int mipLevels = mipLevelCount(envLight.specular); + + // Offset of smallest miplevel we should use (corresponds to specular + // power of 1). I.e. in the 32x32 sized mip. + const float mipOffset = 5.0; + + // The final factor is really 1 - g / g_max but as mentioned above g_max + // is 1 by definition here so we can avoid the division. If we make the + // max specular power for the spec map configurable, this will need to + // be handled properly. + float mipLevel = (mipLevels - 1.0 - mipOffset) * (1.0 - glossiness); + return mipLevel; } // Helper function to map from linear roughness value to non-linear alpha (shininess) @@ -277,7 +304,31 @@ vec3 pbrIblModel(const in vec3 wNormal, vec3 F0 = mix(dielectricColor, baseColor, metalness); vec3 specularFactor = specularModel(F0, lDotH, lDotN, vDotN, n, h); - float lod = roughnessToMipLevel(roughness); + // As per page 14 of + // http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf + // we remap the roughness to give a more perceptually linear response + // of "bluriness" as a function of the roughness specified by the user. + // r = roughness^2 + float lod = roughnessToMipLevel(roughness * roughness); +//#define DEBUG_SPECULAR_LODS +#ifdef DEBUG_SPECULAR_LODS + if (lod > 7.0) + return vec3(1.0, 0.0, 0.0); + else if (lod > 6.0) + return vec3(1.0, 0.333, 0.0); + else if (lod > 5.0) + return vec3(1.0, 1.0, 0.0); + else if (lod > 4.0) + return vec3(0.666, 1.0, 0.0); + else if (lod > 3.0) + return vec3(0.0, 1.0, 0.666); + else if (lod > 2.0) + return vec3(0.0, 0.666, 1.0); + else if (lod > 1.0) + return vec3(0.0, 0.0, 1.0); + else if (lod > 0.0) + return vec3(1.0, 0.0, 1.0); +#endif vec3 specularSkyColor = textureLod(envLight.specular, l, lod).rgb; vec3 specular = specularSkyColor * specularFactor; diff --git a/src/extras/shaders/gl3/metalroughuniform.frag b/src/extras/shaders/gl3/metalroughuniform.frag index cccd31b52..17773515d 100644 --- a/src/extras/shaders/gl3/metalroughuniform.frag +++ b/src/extras/shaders/gl3/metalroughuniform.frag @@ -66,11 +66,6 @@ uniform vec4 baseColor; uniform float metalness; uniform float roughness; -// Roughness -> mip level mapping -uniform float maxT = 0.939824; -uniform float mipLevels = 11.0; -uniform float mipOffset = 5.0; - // Exposure correction uniform float exposure = 0.0; // Gamma correction @@ -78,6 +73,13 @@ uniform float gamma = 2.2; #pragma include light.inc.frag +int mipLevelCount(const in samplerCube cube) +{ + int baseSize = textureSize(cube, 0).x; + int nMips = int(log2(float(baseSize>0 ? baseSize : 1))) + 1; + return nMips; +} + mat3 calcWorldSpaceToTangentSpaceMatrix(const in vec3 wNormal, const in vec4 wTangent) { // Make the tangent truly orthogonal to the normal by using Gram-Schmidt. @@ -100,10 +102,35 @@ mat3 calcWorldSpaceToTangentSpaceMatrix(const in vec3 wNormal, const in vec4 wTa float roughnessToMipLevel(float roughness) { - // HACK: Improve the roughness -> mip level mapping for roughness map from substace painter - // TODO: Use mathematica or similar to improve this mapping more generally - roughness = 0.75 + (1.7 * (roughness - 0.5)); - return (mipLevels - 1.0 - mipOffset) * (1.0 - (1.0 - roughness) / maxT); + const float maxSpecPower = 999999.0; + const float minRoughness = sqrt(2.0 / (maxSpecPower + 2)); + float r = max(roughness, minRoughness); + float specPower = 2.0 / (r * r) - 2.0; + + // We use the mip level calculation from Lys' default power drop, which in + // turn is a slight modification of that used in Marmoset Toolbag. See + // https://docs.knaldtech.com/doku.php?id=specular_lys for details. + // For now we assume a max specular power of 999999 which gives + // maxGlossiness = 1. + const float k0 = 0.00098; + const float k1 = 0.9921; + float glossiness = (pow(2.0, -10.0 / sqrt(specPower)) - k0) / k1; + + // TODO: Optimize by doing this on CPU and set as + // uniform int envLight.specularMipLevels say (if present in shader). + // Lookup the number of mips in the specular envmap + int mipLevels = mipLevelCount(envLight.specular); + + // Offset of smallest miplevel we should use (corresponds to specular + // power of 1). I.e. in the 32x32 sized mip. + const float mipOffset = 5.0; + + // The final factor is really 1 - g / g_max but as mentioned above g_max + // is 1 by definition here so we can avoid the division. If we make the + // max specular power for the spec map configurable, this will need to + // be handled properly. + float mipLevel = (mipLevels - 1.0 - mipOffset) * (1.0 - glossiness); + return mipLevel; } // Helper function to map from linear roughness value to non-linear alpha (shininess) @@ -265,7 +292,31 @@ vec3 pbrIblModel(const in vec3 wNormal, vec3 F0 = mix(dielectricColor, baseColor, metalness); vec3 specularFactor = specularModel(F0, lDotH, lDotN, vDotN, n, h); - float lod = roughnessToMipLevel(roughness); + // As per page 14 of + // http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf + // we remap the roughness to give a more perceptually linear response + // of "bluriness" as a function of the roughness specified by the user. + // r = roughness^2 + float lod = roughnessToMipLevel(roughness * roughness); +//#define DEBUG_SPECULAR_LODS +#ifdef DEBUG_SPECULAR_LODS + if (lod > 7.0) + return vec3(1.0, 0.0, 0.0); + else if (lod > 6.0) + return vec3(1.0, 0.333, 0.0); + else if (lod > 5.0) + return vec3(1.0, 1.0, 0.0); + else if (lod > 4.0) + return vec3(0.666, 1.0, 0.0); + else if (lod > 3.0) + return vec3(0.0, 1.0, 0.666); + else if (lod > 2.0) + return vec3(0.0, 0.666, 1.0); + else if (lod > 1.0) + return vec3(0.0, 0.0, 1.0); + else if (lod > 0.0) + return vec3(1.0, 0.0, 1.0); +#endif vec3 specularSkyColor = textureLod(envLight.specular, l, lod).rgb; vec3 specular = specularSkyColor * specularFactor; -- cgit v1.2.3 From afbf3d45f6e440b1d71d62a85289bd8fcc98a134 Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Thu, 11 May 2017 15:03:20 +0100 Subject: Match the Blinn-Phong specular power to be consistent with IBL Use the same specular power as a function of roughness as used by Blinn-Phong in other engines and in Lys which is used to generate the image based lighting specular maps. During testing, noticed the specular highlight from punctual lights seems more like it's per-vertex based. Task-number: QTBUG-60181 Change-Id: Id379d59a5e1295c2cdf9bdabf246b7e0c0a9c499 Reviewed-by: Kevin Ottens --- src/extras/shaders/gl3/metalrough.frag | 61 ++++++++++++--------------- src/extras/shaders/gl3/metalroughuniform.frag | 56 ++++++++++++------------ 2 files changed, 56 insertions(+), 61 deletions(-) diff --git a/src/extras/shaders/gl3/metalrough.frag b/src/extras/shaders/gl3/metalrough.frag index 0bbef9167..7f2f3d20e 100644 --- a/src/extras/shaders/gl3/metalrough.frag +++ b/src/extras/shaders/gl3/metalrough.frag @@ -85,6 +85,18 @@ int mipLevelCount(const in samplerCube cube) return nMips; } +float remapRoughness(const in float roughness) +{ + // As per page 14 of + // http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf + // we remap the roughness to give a more perceptually linear response + // of "bluriness" as a function of the roughness specified by the user. + // r = roughness^2 + const float maxSpecPower = 999999.0; + const float minRoughness = sqrt(2.0 / (maxSpecPower + 2)); + return max(roughness * roughness, minRoughness); +} + mat3 calcWorldSpaceToTangentSpaceMatrix(const in vec3 wNormal, const in vec4 wTangent) { // Make the tangent truly orthogonal to the normal by using Gram-Schmidt. @@ -105,12 +117,9 @@ mat3 calcWorldSpaceToTangentSpaceMatrix(const in vec3 wNormal, const in vec4 wTa return worldToTangentMatrix; } -float roughnessToMipLevel(float roughness) +float alphaToMipLevel(float alpha) { - const float maxSpecPower = 999999.0; - const float minRoughness = sqrt(2.0 / (maxSpecPower + 2)); - float r = max(roughness, minRoughness); - float specPower = 2.0 / (r * r) - 2.0; + float specPower = 2.0 / (alpha * alpha) - 2.0; // We use the mip level calculation from Lys' default power drop, which in // turn is a slight modification of that used in Marmoset Toolbag. See @@ -138,24 +147,12 @@ float roughnessToMipLevel(float roughness) return mipLevel; } -// Helper function to map from linear roughness value to non-linear alpha (shininess) -float roughnessToAlpha(const in float roughness) +float normalDistribution(const in vec3 n, const in vec3 h, const in float alpha) { - // Constants to control how to convert from roughness [0,1] to - // shininess (alpha) [minAlpha, maxAlpha] using a power law with - // a power of 1 / rho. - const float minAlpha = 1.0; - const float maxAlpha = 1024.0; - const float rho = 3.0; - - return minAlpha + (maxAlpha - minAlpha) * (1.0 - pow(roughness, 1.0 / rho)); -} - -float normalDistribution(const in vec3 n, const in vec3 h, const in float roughness) -{ - // Blinn-Phong approximation - float alpha = roughnessToAlpha(roughness); - return (alpha + 2.0) / (2.0 * 3.14159) * pow(max(dot(n, h), 0.0), alpha); + // Blinn-Phong approximation - see + // http://graphicrants.blogspot.co.uk/2013/08/specular-brdf-reference.html + float specPower = 2.0 / (alpha * alpha) - 2.0; + return (specPower + 2.0) / (2.0 * 3.14159) * pow(max(dot(n, h), 0.0), specPower); } vec3 fresnelFactor(const in vec3 color, const in float cosineFactor) @@ -203,7 +200,7 @@ vec3 pbrModel(const in int lightIndex, const in vec3 wView, const in vec3 baseColor, const in float metalness, - const in float roughness, + const in float alpha, const in float ambientOcclusion) { // Calculate some useful quantities @@ -261,7 +258,7 @@ vec3 pbrModel(const in int lightIndex, vec3 specularFactor = vec3(0.0); if (sDotN > 0.0) { specularFactor = specularModel(F0, sDotH, sDotN, vDotN, n, h); - specularFactor *= normalDistribution(n, h, roughness); + specularFactor *= normalDistribution(n, h, alpha); } vec3 specularColor = lights[lightIndex].color; vec3 specular = specularColor * specularFactor; @@ -279,7 +276,7 @@ vec3 pbrIblModel(const in vec3 wNormal, const in vec3 wView, const in vec3 baseColor, const in float metalness, - const in float roughness, + const in float alpha, const in float ambientOcclusion) { // Calculate reflection direction of view vector about surface normal @@ -304,12 +301,7 @@ vec3 pbrIblModel(const in vec3 wNormal, vec3 F0 = mix(dielectricColor, baseColor, metalness); vec3 specularFactor = specularModel(F0, lDotH, lDotN, vDotN, n, h); - // As per page 14 of - // http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf - // we remap the roughness to give a more perceptually linear response - // of "bluriness" as a function of the roughness specified by the user. - // r = roughness^2 - float lod = roughnessToMipLevel(roughness * roughness); + float lod = alphaToMipLevel(alpha); //#define DEBUG_SPECULAR_LODS #ifdef DEBUG_SPECULAR_LODS if (lod > 7.0) @@ -368,12 +360,15 @@ void main() vec3 tNormal = 2.0 * texture(normalMap, texCoord).rgb - vec3(1.0); vec3 wNormal = normalize(transpose(worldToTangentMatrix) * tNormal); + // Remap roughness for a perceptually more linear correspondence + float alpha = remapRoughness(roughness); + for (int i = 0; i < envLightCount; ++i) { cLinear += pbrIblModel(wNormal, wView, baseColor, metalness, - roughness, + alpha, ambientOcclusion); } @@ -384,7 +379,7 @@ void main() wView, baseColor.rgb, metalness, - roughness, + alpha, ambientOcclusion); } diff --git a/src/extras/shaders/gl3/metalroughuniform.frag b/src/extras/shaders/gl3/metalroughuniform.frag index 17773515d..c9191adbf 100644 --- a/src/extras/shaders/gl3/metalroughuniform.frag +++ b/src/extras/shaders/gl3/metalroughuniform.frag @@ -80,6 +80,18 @@ int mipLevelCount(const in samplerCube cube) return nMips; } +float remapRoughness(const in float roughness) +{ + // As per page 14 of + // http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf + // we remap the roughness to give a more perceptually linear response + // of "bluriness" as a function of the roughness specified by the user. + // r = roughness^2 + const float maxSpecPower = 999999.0; + const float minRoughness = sqrt(2.0 / (maxSpecPower + 2)); + return max(roughness * roughness, minRoughness); +} + mat3 calcWorldSpaceToTangentSpaceMatrix(const in vec3 wNormal, const in vec4 wTangent) { // Make the tangent truly orthogonal to the normal by using Gram-Schmidt. @@ -100,12 +112,9 @@ mat3 calcWorldSpaceToTangentSpaceMatrix(const in vec3 wNormal, const in vec4 wTa return worldToTangentMatrix; } -float roughnessToMipLevel(float roughness) +float alphaToMipLevel(float alpha) { - const float maxSpecPower = 999999.0; - const float minRoughness = sqrt(2.0 / (maxSpecPower + 2)); - float r = max(roughness, minRoughness); - float specPower = 2.0 / (r * r) - 2.0; + float specPower = 2.0 / (alpha * alpha) - 2.0; // We use the mip level calculation from Lys' default power drop, which in // turn is a slight modification of that used in Marmoset Toolbag. See @@ -133,24 +142,12 @@ float roughnessToMipLevel(float roughness) return mipLevel; } -// Helper function to map from linear roughness value to non-linear alpha (shininess) -float roughnessToAlpha(const in float roughness) +float normalDistribution(const in vec3 n, const in vec3 h, const in float alpha) { - // Constants to control how to convert from roughness [0,1] to - // shininess (alpha) [minAlpha, maxAlpha] using a power law with - // a power of 1 / rho. - const float minAlpha = 1.0; - const float maxAlpha = 1024.0; - const float rho = 3.0; - - return minAlpha + (maxAlpha - minAlpha) * (1.0 - pow(roughness, 1.0 / rho)); -} - -float normalDistribution(const in vec3 n, const in vec3 h, const in float roughness) -{ - // Blinn-Phong approximation - float alpha = roughnessToAlpha(roughness); - return (alpha + 2.0) / (2.0 * 3.14159) * pow(max(dot(n, h), 0.0), alpha); + // Blinn-Phong approximation - see + // http://graphicrants.blogspot.co.uk/2013/08/specular-brdf-reference.html + float specPower = 2.0 / (alpha * alpha) - 2.0; + return (specPower + 2.0) / (2.0 * 3.14159) * pow(max(dot(n, h), 0.0), specPower); } vec3 fresnelFactor(const in vec3 color, const in float cosineFactor) @@ -198,7 +195,7 @@ vec3 pbrModel(const in int lightIndex, const in vec3 wView, const in vec3 baseColor, const in float metalness, - const in float roughness) + const in float alpha) { // Calculate some useful quantities vec3 n = wNormal; @@ -255,7 +252,7 @@ vec3 pbrModel(const in int lightIndex, vec3 specularFactor = vec3(0.0); if (sDotN > 0.0) { specularFactor = specularModel(F0, sDotH, sDotN, vDotN, n, h); - specularFactor *= normalDistribution(n, h, roughness); + specularFactor *= normalDistribution(n, h, alpha); } vec3 specularColor = lights[lightIndex].color; vec3 specular = specularColor * specularFactor; @@ -268,7 +265,7 @@ vec3 pbrIblModel(const in vec3 wNormal, const in vec3 wView, const in vec3 baseColor, const in float metalness, - const in float roughness) + const in float alpha) { // Calculate reflection direction of view vector about surface normal // vector in world space. This is used in the fragment shader to sample @@ -297,7 +294,7 @@ vec3 pbrIblModel(const in vec3 wNormal, // we remap the roughness to give a more perceptually linear response // of "bluriness" as a function of the roughness specified by the user. // r = roughness^2 - float lod = roughnessToMipLevel(roughness * roughness); + float lod = alphaToMipLevel(alpha); //#define DEBUG_SPECULAR_LODS #ifdef DEBUG_SPECULAR_LODS if (lod > 7.0) @@ -338,13 +335,16 @@ void main() { vec3 cLinear = vec3(0.0); + // Remap roughness for a perceptually more linear correspondence + float alpha = remapRoughness(roughness); + vec3 worldView = normalize(eyePosition - worldPosition); for (int i = 0; i < envLightCount; ++i) { cLinear += pbrIblModel(worldNormal, worldView, baseColor.rgb, metalness, - roughness); + alpha); } for (int i = 0; i < lightCount; ++i) { @@ -354,7 +354,7 @@ void main() worldView, baseColor.rgb, metalness, - roughness); + alpha); } // Apply exposure correction -- cgit v1.2.3 From cd18ac348388cbc55aef11cca3a9a291fd79fe76 Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Thu, 11 May 2017 15:21:13 +0100 Subject: Ensure normal vector is normalized following interpolation Fixes "per-vertex" appearance of specular highlight in QMetalRoughMaterial. Task-number: QTBUG-60181 Change-Id: I03fd54ff997242fd987174d453642bd00076e26f Reviewed-by: Kevin Ottens --- src/extras/shaders/gl3/metalroughuniform.frag | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/extras/shaders/gl3/metalroughuniform.frag b/src/extras/shaders/gl3/metalroughuniform.frag index c9191adbf..f4bad0a00 100644 --- a/src/extras/shaders/gl3/metalroughuniform.frag +++ b/src/extras/shaders/gl3/metalroughuniform.frag @@ -338,9 +338,11 @@ void main() // Remap roughness for a perceptually more linear correspondence float alpha = remapRoughness(roughness); + + vec3 wNormal = normalize(worldNormal); vec3 worldView = normalize(eyePosition - worldPosition); for (int i = 0; i < envLightCount; ++i) { - cLinear += pbrIblModel(worldNormal, + cLinear += pbrIblModel(wNormal, worldView, baseColor.rgb, metalness, @@ -350,7 +352,7 @@ void main() for (int i = 0; i < lightCount; ++i) { cLinear += pbrModel(i, worldPosition, - worldNormal, + wNormal, worldView, baseColor.rgb, metalness, -- cgit v1.2.3 From 9bf4daddeb62ec6a40e2d90587a7327acbb3780f Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Mon, 15 May 2017 19:54:01 +0100 Subject: Don't use seamless cubemap on GL <3.2 Otherwise it just floods with qWarning messages. This is only available on GL 3.2 or newer so only try it there. Task-number: QTBUG-60180 Change-Id: I8681c900ad5febc28a671305fa8c5d2e81662cab Reviewed-by: Oleg Evseev Reviewed-by: Paul Lemire --- src/extras/defaults/qskyboxentity.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/extras/defaults/qskyboxentity.cpp b/src/extras/defaults/qskyboxentity.cpp index ae3fa1087..3c7b0dd4e 100644 --- a/src/extras/defaults/qskyboxentity.cpp +++ b/src/extras/defaults/qskyboxentity.cpp @@ -138,10 +138,8 @@ void QSkyboxEntityPrivate::init() m_gl3RenderPass->addRenderState(seamlessCubemap); m_gl2RenderPass->addRenderState(cullFront); m_gl2RenderPass->addRenderState(depthTest); - m_gl2RenderPass->addRenderState(seamlessCubemap); m_es2RenderPass->addRenderState(cullFront); m_es2RenderPass->addRenderState(depthTest); - m_es2RenderPass->addRenderState(seamlessCubemap); m_gl3Technique->addRenderPass(m_gl3RenderPass); m_gl2Technique->addRenderPass(m_gl2RenderPass); -- cgit v1.2.3 From 1d024678ba16dd979a8c7023b35cdc76db357d37 Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Fri, 19 May 2017 19:44:52 +0100 Subject: Fix build with QT_STRICT_ITERATORS Which also fixes potential bugs when comparing iterators from different containers in case a detach happens. Change-Id: I5e91f82177d46a0f06272035af837e8a8b196f81 Reviewed-by: Mike Krus --- src/extras/text/qdistancefieldglyphcache.cpp | 2 +- src/plugins/geometryloaders/default/objgeometryloader.cpp | 2 +- src/render/materialsystem/shader.cpp | 12 ++++++------ src/render/texture/apitexturemanager_p.h | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/extras/text/qdistancefieldglyphcache.cpp b/src/extras/text/qdistancefieldglyphcache.cpp index 9c997013e..99085f378 100644 --- a/src/extras/text/qdistancefieldglyphcache.cpp +++ b/src/extras/text/qdistancefieldglyphcache.cpp @@ -272,7 +272,7 @@ DistanceFieldFont* QDistanceFieldGlyphCache::getOrCreateDistanceFieldFont(const // return, if font already exists (make sure to only create one DistanceFieldFont for // each unique QRawFont, by building a hash on the QRawFont that ignores the font size) const QString key = fontKey(font); - const auto it = m_fonts.find(key); + const auto it = m_fonts.constFind(key); if (it != m_fonts.cend()) return it.value(); diff --git a/src/plugins/geometryloaders/default/objgeometryloader.cpp b/src/plugins/geometryloaders/default/objgeometryloader.cpp index 0f22acc66..9f31c7de6 100644 --- a/src/plugins/geometryloaders/default/objgeometryloader.cpp +++ b/src/plugins/geometryloaders/default/objgeometryloader.cpp @@ -219,7 +219,7 @@ bool ObjGeometryLoader::doLoad(QIODevice *ioDev, const QString &subMesh) if (hasNormals) m_normals.resize(vertexCount); - for (QHash::const_iterator it = faceIndexMap.begin(), endIt = faceIndexMap.end(); it != endIt; ++it) { + for (auto it = faceIndexMap.cbegin(), endIt = faceIndexMap.cend(); it != endIt; ++it) { m_points[it.value()] = positions[it.key().positionIndex]; if (hasTexCoords) m_texCoords[it.value()] = std::numeric_limits::max() != it.key().texCoordIndex ? texCoords[it.key().texCoordIndex] : QVector2D(); diff --git a/src/render/materialsystem/shader.cpp b/src/render/materialsystem/shader.cpp index 3ee00739d..915ca1d54 100644 --- a/src/render/materialsystem/shader.cpp +++ b/src/render/materialsystem/shader.cpp @@ -311,8 +311,8 @@ void Shader::updateDNA() QMutexLocker locker(&m_mutex); uint attachmentHash = 0; - QHash::const_iterator it = m_fragOutputs.begin(); - QHash::const_iterator end = m_fragOutputs.end(); + QHash::const_iterator it = m_fragOutputs.cbegin(); + QHash::const_iterator end = m_fragOutputs.cend(); while (it != end) { attachmentHash += ::qHash(it.value()) + ::qHash(it.key()); ++it; @@ -373,11 +373,11 @@ void Shader::initializeUniformBlocks(const QVector &uniformB qCDebug(Shaders) << "Initializing Uniform Block {" << m_uniformBlockNames[i] << "}"; // Find all active uniforms for the shader block - QVector::const_iterator uniformsIt = m_uniforms.begin(); - const QVector::const_iterator uniformsEnd = m_uniforms.end(); + QVector::const_iterator uniformsIt = m_uniforms.cbegin(); + const QVector::const_iterator uniformsEnd = m_uniforms.cend(); - QVector::const_iterator uniformNamesIt = m_uniformsNames.begin(); - const QVector::const_iterator uniformNamesEnd = m_attributesNames.end(); + QVector::const_iterator uniformNamesIt = m_uniformsNames.cbegin(); + const QVector::const_iterator uniformNamesEnd = m_attributesNames.cend(); QHash activeUniformsInBlock; diff --git a/src/render/texture/apitexturemanager_p.h b/src/render/texture/apitexturemanager_p.h index c062f0971..91747b3bc 100644 --- a/src/render/texture/apitexturemanager_p.h +++ b/src/render/texture/apitexturemanager_p.h @@ -273,7 +273,7 @@ public: if (impl->isUnique()) return false; - auto it = m_sharedTextures.find(impl); + auto it = m_sharedTextures.constFind(impl); if (it == m_sharedTextures.cend()) return false; -- cgit v1.2.3