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