diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2015-07-20 09:10:08 +0200 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2015-07-28 09:49:19 +0000 |
commit | 90623e3ccbeba4f498b3ce5c1b6c88f1122df434 (patch) | |
tree | 2e7a5b59b3d6830d0f0d70f1c1cec5cb6f355a9e | |
parent | 3fe37f854dcaa2d92e8936ccddd07800fb4d04d3 (diff) |
Functors: remove dynamic_cast
Introduce a QAbstractFunctor class which QAbstractMeshFunctor and
QTextureDataFunctor subclass
Make all QAbstractFunctor subclasses implement an id() function (using
QT3D_FUNCTOR(Class)).
Use this id to compare to other QAbstractMeshFunctor and eventually
static_cast into right type if possible using the functor_cast member
function.
Change-Id: Iface956e6cd818cbef204d8fa7bf2bc23c6ffa3f
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r-- | examples/qt3d/tessellation-modes/tessellatedquadmesh.cpp | 4 | ||||
-rw-r--r-- | src/core/core.pri | 6 | ||||
-rw-r--r-- | src/core/qabstractfunctor.cpp | 50 | ||||
-rw-r--r-- | src/core/qabstractfunctor.h | 92 | ||||
-rw-r--r-- | src/plugins/sceneparsers/assimp/assimpparser.cpp | 32 | ||||
-rw-r--r-- | src/render/frontend/qabstractmesh.cpp | 45 | ||||
-rw-r--r-- | src/render/frontend/qabstractmesh.h | 3 | ||||
-rw-r--r-- | src/render/frontend/qabstracttextureimage.h | 3 | ||||
-rw-r--r-- | src/render/frontend/qcuboidmesh.cpp | 4 | ||||
-rw-r--r-- | src/render/frontend/qcylindermesh.cpp | 4 | ||||
-rw-r--r-- | src/render/frontend/qmesh.cpp | 3 | ||||
-rw-r--r-- | src/render/frontend/qplanemesh.cpp | 3 | ||||
-rw-r--r-- | src/render/frontend/qspheremesh.cpp | 3 | ||||
-rw-r--r-- | src/render/frontend/qtextureimage.cpp | 4 | ||||
-rw-r--r-- | src/render/frontend/qtorusmesh.cpp | 4 | ||||
-rw-r--r-- | src/render/io/gltfparser.cpp | 37 | ||||
-rw-r--r-- | tests/auto/render/meshfunctors/meshfunctors.pro | 9 | ||||
-rw-r--r-- | tests/auto/render/meshfunctors/tst_meshfunctors.cpp | 131 | ||||
-rw-r--r-- | tests/auto/render/render.pro | 3 |
19 files changed, 383 insertions, 57 deletions
diff --git a/examples/qt3d/tessellation-modes/tessellatedquadmesh.cpp b/examples/qt3d/tessellation-modes/tessellatedquadmesh.cpp index 08a3f54b3..630fa1061 100644 --- a/examples/qt3d/tessellation-modes/tessellatedquadmesh.cpp +++ b/examples/qt3d/tessellation-modes/tessellatedquadmesh.cpp @@ -83,11 +83,13 @@ public: bool operator ==(const Qt3D::QAbstractMeshFunctor &other) const { - const TessellatedQuadMeshFunctor *otherFunctor = dynamic_cast<const TessellatedQuadMeshFunctor *>(&other); + const TessellatedQuadMeshFunctor *otherFunctor = functor_cast<TessellatedQuadMeshFunctor>(&other); if (otherFunctor != Q_NULLPTR) return true; return false; } + + QT3D_FUNCTOR(TessellatedQuadMeshFunctor) }; Qt3D::QAbstractMeshFunctorPtr TessellatedQuadMesh::meshFunctor() const diff --git a/src/core/core.pri b/src/core/core.pri index 4eb8f09ff..dd9bb52ab 100644 --- a/src/core/core.pri +++ b/src/core/core.pri @@ -39,7 +39,8 @@ HEADERS += \ $$PWD/qbackendnodefactory.h \ $$PWD/qray3d.h \ $$PWD/qt3dcore_global_p.h \ - $$PWD/qscene_p.h + $$PWD/qscene_p.h \ + $$PWD/qabstractfunctor.h SOURCES += \ $$PWD/qtickclock.cpp \ @@ -56,4 +57,5 @@ SOURCES += \ $$PWD/qscene.cpp \ $$PWD/qbackendscenepropertychange.cpp \ $$PWD/qbackendnodefactory.cpp \ - $$PWD/qray3d.cpp + $$PWD/qray3d.cpp \ + $$PWD/qabstractfunctor.cpp diff --git a/src/core/qabstractfunctor.cpp b/src/core/qabstractfunctor.cpp new file mode 100644 index 000000000..30bb573ee --- /dev/null +++ b/src/core/qabstractfunctor.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** 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 "qabstractfunctor.h" + +QT_BEGIN_NAMESPACE + +namespace Qt3D { + +QAbstractFunctor::~QAbstractFunctor() +{ +} + +} // Qt3D + +QT_END_NAMESPACE + diff --git a/src/core/qabstractfunctor.h b/src/core/qabstractfunctor.h new file mode 100644 index 000000000..47edc62f1 --- /dev/null +++ b/src/core/qabstractfunctor.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** 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 QT3D_QABSTRACTFUNCTOR_H +#define QT3D_QABSTRACTFUNCTOR_H + +#include <Qt3DCore/qt3dcore_global.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3D { + +// This will generate a unique id() function per type +// <=> 1 unique function address per type +template<class T> +struct FunctorType +{ + static qintptr id() + { + // The MSVC linker can under some cases optimize all the template + // functions into a single function. The code below is there to ensure + // that the linker won't collapse all these distincts functions into one + static T *t = 0; + return reinterpret_cast<qintptr>(t); + } +}; + +template<class T> +qintptr functorTypeId() +{ + return reinterpret_cast<qintptr>(&FunctorType<T>::id); +} + +#define QT3D_FUNCTOR(Class) \ + qintptr id() const Q_DECL_OVERRIDE { \ + return Qt3D::functorTypeId<Class>(); \ + } + + +class QT3DCORESHARED_EXPORT QAbstractFunctor +{ +public: + virtual ~QAbstractFunctor(); + virtual qintptr id() const = 0; + + template<class T> + const T *functor_cast(const QAbstractFunctor *other) const + { + if (other->id() == functorTypeId<T>()) + return static_cast<const T *>(other); + return Q_NULLPTR; + } +}; + +} // Qt3D + +QT_END_NAMESPACE + +#endif // QT3D_QABSTRACTFUNCTOR_H diff --git a/src/plugins/sceneparsers/assimp/assimpparser.cpp b/src/plugins/sceneparsers/assimp/assimpparser.cpp index 272cc533a..351faa281 100644 --- a/src/plugins/sceneparsers/assimp/assimpparser.cpp +++ b/src/plugins/sceneparsers/assimp/assimpparser.cpp @@ -267,15 +267,18 @@ private: QMeshDataPtr m_meshData; QT3D_CLONEABLE(AssimpMesh) - class AssimpMeshFunctor : public QAbstractMeshFunctor - { - public: - explicit AssimpMeshFunctor(QMeshDataPtr meshData); - QMeshDataPtr operator()() Q_DECL_OVERRIDE; - bool operator ==(const QAbstractMeshFunctor &other) const Q_DECL_OVERRIDE; - private: - QMeshDataPtr m_meshData; - }; +}; + +class AssimpMeshFunctor : public QAbstractMeshFunctor +{ +public: + explicit AssimpMeshFunctor(QMeshDataPtr meshData = QMeshDataPtr()); + QMeshDataPtr operator()() Q_DECL_OVERRIDE; + bool operator ==(const QAbstractMeshFunctor &other) const Q_DECL_OVERRIDE; + QT3D_FUNCTOR(AssimpMeshFunctor) + +private: + QMeshDataPtr m_meshData; }; class AssimpRawTextureImage : public QAbstractTextureImage @@ -300,6 +303,7 @@ private: TexImageDataPtr operator()() Q_DECL_FINAL; bool operator ==(const QTextureDataFunctor &other) const Q_DECL_FINAL; + QT3D_FUNCTOR(AssimpRawTextureImageFunctor) private: QByteArray m_data; }; @@ -917,18 +921,18 @@ QAbstractMeshFunctorPtr AssimpMesh::meshFunctor() const return QAbstractMeshFunctorPtr(new AssimpMeshFunctor(m_meshData)); } -AssimpMesh::AssimpMeshFunctor::AssimpMeshFunctor(QMeshDataPtr meshData) +AssimpMeshFunctor::AssimpMeshFunctor(QMeshDataPtr meshData) : QAbstractMeshFunctor() , m_meshData(meshData) { } -QMeshDataPtr AssimpMesh::AssimpMeshFunctor::operator()() +QMeshDataPtr AssimpMeshFunctor::operator()() { return m_meshData; } -bool AssimpMesh::AssimpMeshFunctor::operator ==(const QAbstractMeshFunctor &) const +bool AssimpMeshFunctor::operator ==(const QAbstractMeshFunctor &) const { return false; } @@ -966,7 +970,7 @@ TexImageDataPtr AssimpRawTextureImage::AssimpRawTextureImageFunctor::operator()( bool AssimpRawTextureImage::AssimpRawTextureImageFunctor::operator ==(const QTextureDataFunctor &other) const { - const AssimpRawTextureImageFunctor *otherFunctor = dynamic_cast<const AssimpRawTextureImageFunctor *>(&other); + const AssimpRawTextureImageFunctor *otherFunctor = functor_cast<AssimpRawTextureImageFunctor>(&other); return (otherFunctor != Q_NULLPTR && otherFunctor->m_data == m_data); } @@ -986,4 +990,6 @@ AssimpParser::SceneImporter::~SceneImporter() QT_END_NAMESPACE +Q_DECLARE_METATYPE(Qt3D::AssimpMeshFunctor) + #include "assimpparser.moc" diff --git a/src/render/frontend/qabstractmesh.cpp b/src/render/frontend/qabstractmesh.cpp index c81f5aa8f..a8912b63e 100644 --- a/src/render/frontend/qabstractmesh.cpp +++ b/src/render/frontend/qabstractmesh.cpp @@ -39,13 +39,36 @@ #include <Qt3DCore/qscenepropertychange.h> /*! + \class Qt3D::QAbstractMeshFunctor + + \brief Encapsulates all the required data to build a mesh at any given time. + + Each Qt3D::QAbstractMesh implementation needs to provide a Qt3D::QAbstractMeshFunctor. + The functor allows the creation of meshes at runtime by the renderer. + + At runtime, mesh functors are compared so that several optimizations can take + place. When implementing the comparison operator you should use + Qt3D::QAbstractFunctor::functor_cast to check that other + Qt3D::QAbstractFunctor instances are of the same type as an alternative + to dynamic_cast. + + \note Be sure to add the QT3D_FUNCTOR macro in the public declarations + of your Qt3D::QAbstractMeshFunctor subclass so that + Qt3D::QAbstractMeshFunctor::isType can function properly. + + \sa Qt3D::QAbstractMesh + + */ + +/*! * \class Qt3D::QAbstractMesh * * \brief Provides an abstract class that should be the base of all Mesh * primitives in a scene * - * QAbstractMesh subclasses should encapsulate vertices needed to render a Mesh. - * These should match and be packed according to what the aspect they live in expects. + * QAbstractMesh subclasses should encapsulate vertices needed to render a + * Mesh. These should match and be packed according to what the aspect they + * live in expects. * * \sa QAbstractTechnique, Component */ @@ -90,15 +113,15 @@ QAbstractMesh::QAbstractMesh(QAbstractMeshPrivate &dd, QNode *parent) void QAbstractMesh::update() { Q_D(QAbstractMesh); - if (d->m_changeArbiter != Q_NULLPTR) { - QScenePropertyChangePtr change(new QScenePropertyChange(NodeUpdated, QSceneChange::Node, id())); - change->setPropertyName("meshFunctor"); - change->setValue(QVariant::fromValue(meshFunctor())); - d->notifyObservers(change); - // TO DO see if we can clear the d->m_dirty on request. - // This would allow to send a single notification for classes that have several property changes occur - // over a single given frame or maybe that's the job of the QChangeArbiter - } + if (d->m_changeArbiter != Q_NULLPTR) { + QScenePropertyChangePtr change(new QScenePropertyChange(NodeUpdated, QSceneChange::Node, id())); + change->setPropertyName("meshFunctor"); + change->setValue(QVariant::fromValue(meshFunctor())); + d->notifyObservers(change); + // TO DO see if we can clear the d->m_dirty on request. + // This would allow to send a single notification for classes that have several property changes occur + // over a single given frame or maybe that's the job of the QChangeArbiter + } } } // Qt3D diff --git a/src/render/frontend/qabstractmesh.h b/src/render/frontend/qabstractmesh.h index f90e05dff..bc6207040 100644 --- a/src/render/frontend/qabstractmesh.h +++ b/src/render/frontend/qabstractmesh.h @@ -39,6 +39,7 @@ #include <Qt3DRenderer/qt3drenderer_global.h> #include <Qt3DCore/qcomponent.h> +#include <Qt3DCore/qabstractfunctor.h> #include <QSharedPointer> QT_BEGIN_NAMESPACE @@ -50,7 +51,7 @@ class QMeshData; typedef QSharedPointer<QMeshData> QMeshDataPtr; -class QT3DRENDERERSHARED_EXPORT QAbstractMeshFunctor +class QT3DRENDERERSHARED_EXPORT QAbstractMeshFunctor : public QAbstractFunctor { public: virtual QMeshDataPtr operator()() = 0; diff --git a/src/render/frontend/qabstracttextureimage.h b/src/render/frontend/qabstracttextureimage.h index 81f0599ae..e73e823d1 100644 --- a/src/render/frontend/qabstracttextureimage.h +++ b/src/render/frontend/qabstracttextureimage.h @@ -37,6 +37,7 @@ #ifndef QT3D_QABSTRACTTEXTUREIMAGE_H #define QT3D_QABSTRACTTEXTUREIMAGE_H +#include <Qt3DCore/qabstractfunctor.h> #include <Qt3DRenderer/qabstracttextureprovider.h> QT_BEGIN_NAMESPACE @@ -47,7 +48,7 @@ namespace Qt3D { // We might also get rid of the layer, face, mipmap level from // TexImageDataPtr and store that in the functor directly // or use the QTextureImage instead -class QT3DRENDERERSHARED_EXPORT QTextureDataFunctor +class QT3DRENDERERSHARED_EXPORT QTextureDataFunctor : public QAbstractFunctor { public: virtual ~QTextureDataFunctor() {} diff --git a/src/render/frontend/qcuboidmesh.cpp b/src/render/frontend/qcuboidmesh.cpp index 665eafd7a..d8fb1175e 100644 --- a/src/render/frontend/qcuboidmesh.cpp +++ b/src/render/frontend/qcuboidmesh.cpp @@ -220,7 +220,7 @@ public: bool operator ==(const QAbstractMeshFunctor &other) const Q_DECL_OVERRIDE { - const CuboidMeshFunctor *otherFunctor = dynamic_cast<const CuboidMeshFunctor *>(&other); + const CuboidMeshFunctor *otherFunctor = functor_cast<CuboidMeshFunctor>(&other); if (otherFunctor != Q_NULLPTR) return (otherFunctor->m_xExtent == m_xExtent && otherFunctor->m_yExtent == m_yExtent && @@ -231,6 +231,8 @@ public: return false; } + QT3D_FUNCTOR(CuboidMeshFunctor) + private: // Dimensions float m_xExtent; diff --git a/src/render/frontend/qcylindermesh.cpp b/src/render/frontend/qcylindermesh.cpp index c45e68a74..5f173fbc4 100644 --- a/src/render/frontend/qcylindermesh.cpp +++ b/src/render/frontend/qcylindermesh.cpp @@ -57,13 +57,13 @@ public: CylinderMeshFunctor(int rings, int slices, float radius, float length); QMeshDataPtr operator ()() Q_DECL_OVERRIDE; bool operator ==(const QAbstractMeshFunctor &other) const Q_DECL_OVERRIDE; + QT3D_FUNCTOR(CylinderMeshFunctor) private: int m_rings; int m_slices; float m_radius; float m_length; - }; class QCylinderMeshPrivate : public QAbstractMeshPrivate @@ -348,7 +348,7 @@ QMeshDataPtr CylinderMeshFunctor::operator ()() bool CylinderMeshFunctor::operator ==(const QAbstractMeshFunctor &other) const { - const CylinderMeshFunctor *otherFunctor = dynamic_cast<const CylinderMeshFunctor *>(&other); + const CylinderMeshFunctor *otherFunctor = functor_cast<CylinderMeshFunctor>(&other); if (otherFunctor != Q_NULLPTR) return (otherFunctor->m_radius == m_radius && otherFunctor->m_length == m_length && diff --git a/src/render/frontend/qmesh.cpp b/src/render/frontend/qmesh.cpp index 882fdb2a1..59ef25bff 100644 --- a/src/render/frontend/qmesh.cpp +++ b/src/render/frontend/qmesh.cpp @@ -55,6 +55,7 @@ public : MeshFunctor(const QUrl &sourcePath); QMeshDataPtr operator()() Q_DECL_OVERRIDE; bool operator ==(const QAbstractMeshFunctor &other) const Q_DECL_OVERRIDE; + QT3D_FUNCTOR(MeshFunctor) private: QUrl m_sourcePath; @@ -147,7 +148,7 @@ QMeshDataPtr MeshFunctor::operator()() bool MeshFunctor::operator ==(const QAbstractMeshFunctor &other) const { - const MeshFunctor *otherFunctor = dynamic_cast<const MeshFunctor *>(&other); + const MeshFunctor *otherFunctor = functor_cast<MeshFunctor>(&other); if (otherFunctor != Q_NULLPTR) return (otherFunctor->m_sourcePath == m_sourcePath); return false; diff --git a/src/render/frontend/qplanemesh.cpp b/src/render/frontend/qplanemesh.cpp index 1bb06d79d..e255a6f59 100644 --- a/src/render/frontend/qplanemesh.cpp +++ b/src/render/frontend/qplanemesh.cpp @@ -155,7 +155,7 @@ public: bool operator ==(const QAbstractMeshFunctor &other) const Q_DECL_OVERRIDE { - const PlaneMeshFunctor *otherFunctor = dynamic_cast<const PlaneMeshFunctor *>(&other); + const PlaneMeshFunctor *otherFunctor = functor_cast<PlaneMeshFunctor>(&other); if (otherFunctor != Q_NULLPTR) return (otherFunctor->m_width == m_width && otherFunctor->m_height == m_height && @@ -163,6 +163,7 @@ public: return false; } + QT3D_FUNCTOR(PlaneMeshFunctor) private: float m_width; float m_height; diff --git a/src/render/frontend/qspheremesh.cpp b/src/render/frontend/qspheremesh.cpp index 0c6fdbaa3..169317891 100644 --- a/src/render/frontend/qspheremesh.cpp +++ b/src/render/frontend/qspheremesh.cpp @@ -58,6 +58,7 @@ public: SphereMeshFunctor(int rings, int slices, float radius, bool generateTangents); QMeshDataPtr operator ()() Q_DECL_OVERRIDE; bool operator ==(const QAbstractMeshFunctor &other) const Q_DECL_OVERRIDE; + QT3D_FUNCTOR(SphereMeshFunctor) private: int m_rings; @@ -322,7 +323,7 @@ QMeshDataPtr SphereMeshFunctor::operator ()() bool SphereMeshFunctor::operator ==(const QAbstractMeshFunctor &other) const { - const SphereMeshFunctor *otherFunctor = dynamic_cast<const SphereMeshFunctor *>(&other); + const SphereMeshFunctor *otherFunctor = functor_cast<SphereMeshFunctor>(&other); if (otherFunctor != Q_NULLPTR) return (otherFunctor->m_rings == m_rings && otherFunctor->m_slices == m_slices && diff --git a/src/render/frontend/qtextureimage.cpp b/src/render/frontend/qtextureimage.cpp index d052f8b3c..d221828bf 100644 --- a/src/render/frontend/qtextureimage.cpp +++ b/src/render/frontend/qtextureimage.cpp @@ -83,10 +83,12 @@ public: bool operator ==(const QTextureDataFunctor &other) const Q_DECL_FINAL { - const QImageTextureDataFunctor *otherFunctor = dynamic_cast<const QImageTextureDataFunctor*>(&other); + const QImageTextureDataFunctor *otherFunctor = functor_cast<QImageTextureDataFunctor>(&other); return (otherFunctor != Q_NULLPTR && otherFunctor->m_url == m_url); } + QT3D_FUNCTOR(QImageTextureDataFunctor) + private: QUrl m_url; }; diff --git a/src/render/frontend/qtorusmesh.cpp b/src/render/frontend/qtorusmesh.cpp index d4f3e3ba0..af115baab 100644 --- a/src/render/frontend/qtorusmesh.cpp +++ b/src/render/frontend/qtorusmesh.cpp @@ -57,7 +57,7 @@ public: TorusMeshFunctor(int rings, int slices, float radius, float minorRadius); QMeshDataPtr operator ()() Q_DECL_OVERRIDE; bool operator ==(const QAbstractMeshFunctor &other) const Q_DECL_OVERRIDE; - + QT3D_FUNCTOR(TorusMeshFunctor) private: int m_rings; int m_slices; @@ -282,7 +282,7 @@ QMeshDataPtr TorusMeshFunctor::operator ()() bool TorusMeshFunctor::operator ==(const QAbstractMeshFunctor &other) const { - const TorusMeshFunctor *otherFunctor = dynamic_cast<const TorusMeshFunctor *>(&other); + const TorusMeshFunctor *otherFunctor = functor_cast<TorusMeshFunctor>(&other); if (otherFunctor != Q_NULLPTR) return (otherFunctor->m_radius == m_radius && otherFunctor->m_slices == m_slices && diff --git a/src/render/io/gltfparser.cpp b/src/render/io/gltfparser.cpp index 745180e56..0cff55016 100644 --- a/src/render/io/gltfparser.cpp +++ b/src/render/io/gltfparser.cpp @@ -41,7 +41,7 @@ #include <Qt3DRenderer/private/renderlogging_p.h> #include <Qt3DCore/qentity.h> -#include <qmesh.h> +#include <qabstractmesh.h> #include <qmaterial.h> #include <qtechnique.h> #include <qshaderprogram.h> @@ -203,29 +203,28 @@ const QString KEY_INTERNAL_FORMAT = QStringLiteral("internalFormat"); class GLTFParserMeshPrivate; -class GLTFParserMesh : public QAbstractMesh +class GLTFParserMeshFunctor : public QAbstractMeshFunctor { - Q_OBJECT +public: + explicit GLTFParserMeshFunctor(QMeshDataPtr meshData = QMeshDataPtr()); + QMeshDataPtr operator ()() Q_DECL_OVERRIDE; + bool operator ==(const QAbstractMeshFunctor &other) const Q_DECL_OVERRIDE; + QT3D_FUNCTOR(GLTFParserMeshFunctor) private: - class GLTFParserMeshFunctor : public QAbstractMeshFunctor - { - public: - explicit GLTFParserMeshFunctor(QMeshDataPtr meshData); - QMeshDataPtr operator ()() Q_DECL_OVERRIDE; - bool operator ==(const QAbstractMeshFunctor &other) const Q_DECL_OVERRIDE; - - private: - QMeshDataPtr m_meshData; - }; + QMeshDataPtr m_meshData; +}; +class GLTFParserMesh : public QAbstractMesh +{ + Q_OBJECT public: explicit GLTFParserMesh(QNode *parent = 0); void setData(QMeshDataPtr data); - QAbstractMeshFunctorPtr meshFunctor() const Q_DECL_OVERRIDE; + QAbstractMeshFunctorPtr meshFunctor() const Q_DECL_FINAL; protected: - void copy(const QNode *ref) Q_DECL_OVERRIDE; + void copy(const QNode *ref) Q_DECL_FINAL; private: QT3D_CLONEABLE(GLTFParserMesh) @@ -1030,18 +1029,18 @@ QAbstractMeshFunctorPtr GLTFParserMesh::meshFunctor() const return QAbstractMeshFunctorPtr(new GLTFParserMeshFunctor(d->m_meshData)); } -GLTFParserMesh::GLTFParserMeshFunctor::GLTFParserMeshFunctor(QMeshDataPtr meshData) +GLTFParserMeshFunctor::GLTFParserMeshFunctor(QMeshDataPtr meshData) : QAbstractMeshFunctor() , m_meshData(meshData) { } -QMeshDataPtr GLTFParserMesh::GLTFParserMeshFunctor::operator ()() +QMeshDataPtr GLTFParserMeshFunctor::operator ()() { return m_meshData; } -bool GLTFParserMesh::GLTFParserMeshFunctor::operator ==(const QAbstractMeshFunctor &) const +bool GLTFParserMeshFunctor::operator ==(const QAbstractMeshFunctor &) const { return false; } @@ -1050,4 +1049,6 @@ bool GLTFParserMesh::GLTFParserMeshFunctor::operator ==(const QAbstractMeshFunct QT_END_NAMESPACE +Q_DECLARE_METATYPE(Qt3D::GLTFParserMeshFunctor) + #include "gltfparser.moc" diff --git a/tests/auto/render/meshfunctors/meshfunctors.pro b/tests/auto/render/meshfunctors/meshfunctors.pro new file mode 100644 index 000000000..008969cd0 --- /dev/null +++ b/tests/auto/render/meshfunctors/meshfunctors.pro @@ -0,0 +1,9 @@ +TEMPLATE = app + +TARGET = tst_renderviews + +QT += 3dcore 3dcore-private 3drenderer 3drenderer-private testlib + +CONFIG += testcase + +SOURCES += tst_meshfunctors.cpp diff --git a/tests/auto/render/meshfunctors/tst_meshfunctors.cpp b/tests/auto/render/meshfunctors/tst_meshfunctors.cpp new file mode 100644 index 000000000..702449a9f --- /dev/null +++ b/tests/auto/render/meshfunctors/tst_meshfunctors.cpp @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** 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 <QtTest/QtTest> +#include <Qt3DRenderer/QAbstractMesh> + +class MeshFunctorA : public Qt3D::QAbstractMeshFunctor +{ +public: + MeshFunctorA() + {} + + ~MeshFunctorA() + {} + + Qt3D::QMeshDataPtr operator ()() Q_DECL_OVERRIDE + { + return Qt3D::QMeshDataPtr(); + } + + bool operator ==(const Qt3D::QAbstractMeshFunctor &other) const Q_DECL_OVERRIDE + { + return functor_cast<MeshFunctorA>(&other); + } + + QT3D_FUNCTOR(MeshFunctorA) +}; + +class MeshFunctorB : public Qt3D::QAbstractMeshFunctor +{ +public: + MeshFunctorB() + {} + + ~MeshFunctorB() + {} + + Qt3D::QMeshDataPtr operator ()() Q_DECL_OVERRIDE + { + return Qt3D::QMeshDataPtr(); + } + + bool operator ==(const Qt3D::QAbstractMeshFunctor &other) const Q_DECL_OVERRIDE + { + return functor_cast<MeshFunctorB>(&other); + } + + QT3D_FUNCTOR(MeshFunctorB) +}; + +class MeshFunctorASub : public MeshFunctorA +{ +public: + MeshFunctorASub() + {} + + ~MeshFunctorASub() + {} + + bool operator ==(const Qt3D::QAbstractMeshFunctor &other) const Q_DECL_OVERRIDE + { + return functor_cast<MeshFunctorASub>(&other); + } + + QT3D_FUNCTOR(MeshFunctorASub) +}; + + +class tst_MeshFunctors : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void functorComparison() + { + // GIVEN + QScopedPointer<MeshFunctorA> functorA(new MeshFunctorA); + QScopedPointer<MeshFunctorB> functorB(new MeshFunctorB); + QScopedPointer<MeshFunctorASub> functorASub(new MeshFunctorASub); + + // THEN + QVERIFY(!(*functorA == *functorB)); + QVERIFY(!(*functorA == *functorASub)); + + QVERIFY(!(*functorB == *functorA)); + QVERIFY(!(*functorB == *functorASub)); + + QVERIFY(!(*functorASub == *functorA)); + QVERIFY(!(*functorASub == *functorB)); + + QVERIFY(*functorA == *functorA); + QVERIFY(*functorB == *functorB); + QVERIFY(*functorASub == *functorASub); + } +}; + +QTEST_APPLESS_MAIN(tst_MeshFunctors) + +#include "tst_meshfunctors.moc" diff --git a/tests/auto/render/render.pro b/tests/auto/render/render.pro index 2da3d77f5..65317484c 100644 --- a/tests/auto/render/render.pro +++ b/tests/auto/render/render.pro @@ -11,5 +11,6 @@ contains(QT_CONFIG, private_tests) { renderviews \ rendermaterial \ rendermesh \ - vsyncframeadvanceservice + vsyncframeadvanceservice \ + meshfunctors } |