summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2015-07-20 09:10:08 +0200
committerSean Harmer <sean.harmer@kdab.com>2015-07-28 09:49:19 +0000
commit90623e3ccbeba4f498b3ce5c1b6c88f1122df434 (patch)
tree2e7a5b59b3d6830d0f0d70f1c1cec5cb6f355a9e
parent3fe37f854dcaa2d92e8936ccddd07800fb4d04d3 (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.cpp4
-rw-r--r--src/core/core.pri6
-rw-r--r--src/core/qabstractfunctor.cpp50
-rw-r--r--src/core/qabstractfunctor.h92
-rw-r--r--src/plugins/sceneparsers/assimp/assimpparser.cpp32
-rw-r--r--src/render/frontend/qabstractmesh.cpp45
-rw-r--r--src/render/frontend/qabstractmesh.h3
-rw-r--r--src/render/frontend/qabstracttextureimage.h3
-rw-r--r--src/render/frontend/qcuboidmesh.cpp4
-rw-r--r--src/render/frontend/qcylindermesh.cpp4
-rw-r--r--src/render/frontend/qmesh.cpp3
-rw-r--r--src/render/frontend/qplanemesh.cpp3
-rw-r--r--src/render/frontend/qspheremesh.cpp3
-rw-r--r--src/render/frontend/qtextureimage.cpp4
-rw-r--r--src/render/frontend/qtorusmesh.cpp4
-rw-r--r--src/render/io/gltfparser.cpp37
-rw-r--r--tests/auto/render/meshfunctors/meshfunctors.pro9
-rw-r--r--tests/auto/render/meshfunctors/tst_meshfunctors.cpp131
-rw-r--r--tests/auto/render/render.pro3
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
}