summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2014-07-15 16:27:54 +0200
committerSean Harmer <sean.harmer@kdab.com>2014-07-19 23:19:34 +0200
commit90e3ebfec5c521acfa2f5aa756d9216a2051d477 (patch)
tree3100c7b718cc97fec7e7e198af5ada22442d1b9e
parent65061f869f59d579113e153a3753249477dd723e (diff)
QAbstractMeshFunctor
Each QAbstractMesh class now has to implement a QAbstractMeshFunctor class. When a mesh is set to dirty, the functor is sent through a QChangeArbiter notification to the backend. The backend, using the functor can then rebuild the mesh. There should be no issue if the frontend mesh is deleted while the backend is creating the mesh as the functor has no direct reference to the frontend element and contains all the data needed for a complete creation of the mesh. Change-Id: I4984f03a612e74c688bfb6cc2f19d9241b517457 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/core/core-components/qabstractmesh.cpp27
-rw-r--r--src/core/core-components/qabstractmesh.h16
-rw-r--r--src/core/core-components/qabstractmesh_p.h2
-rw-r--r--src/render/backend/jobs/loadmeshdatajob.cpp37
-rw-r--r--src/render/backend/jobs/loadmeshdatajob.h11
-rw-r--r--src/render/backend/meshdatamanager.cpp19
-rw-r--r--src/render/backend/meshdatamanager.h10
-rw-r--r--src/render/backend/rendercommand.h1
-rw-r--r--src/render/backend/renderentity.cpp4
-rw-r--r--src/render/backend/rendereraspect.cpp9
-rw-r--r--src/render/backend/rendermesh.cpp28
-rw-r--r--src/render/backend/rendermesh.h6
-rw-r--r--src/render/backend/renderview.cpp7
-rw-r--r--src/render/frontend/qabstractshapemesh.cpp6
-rw-r--r--src/render/frontend/qabstractshapemesh.h4
-rw-r--r--src/render/frontend/qmesh.cpp46
-rw-r--r--src/render/frontend/qmesh.h2
-rw-r--r--src/render/frontend/qspheremesh.cpp46
-rw-r--r--src/render/frontend/qspheremesh.h5
-rw-r--r--src/render/frontend/qtorusmesh.cpp45
-rw-r--r--src/render/frontend/qtorusmesh.h4
-rw-r--r--src/render/io/assimpparser.cpp22
-rw-r--r--src/render/io/assimpparser.h15
-rw-r--r--src/render/io/gltfparser.cpp20
-rw-r--r--src/render/io/gltfparser.h16
25 files changed, 247 insertions, 161 deletions
diff --git a/src/core/core-components/qabstractmesh.cpp b/src/core/core-components/qabstractmesh.cpp
index 96694947a..1da8548b0 100644
--- a/src/core/core-components/qabstractmesh.cpp
+++ b/src/core/core-components/qabstractmesh.cpp
@@ -41,6 +41,7 @@
#include "qabstractmesh.h"
#include "qabstractmesh_p.h"
+#include <Qt3DCore/qscenepropertychange.h>
/*!
* \class QAbstractMesh
@@ -61,7 +62,7 @@ namespace Qt3D {
QAbstractMeshPrivate::QAbstractMeshPrivate(QAbstractMesh *qq)
: QComponentPrivate(qq)
- , m_dirty(true)
+ , m_dirty(false)
{
}
@@ -76,12 +77,6 @@ QAbstractMesh::QAbstractMesh(QAbstractMeshPrivate &dd, QNode *parent)
{
}
-void QAbstractMesh::setData(QAbstractMeshDataPtr data)
-{
- Q_D(QAbstractMesh);
- d->m_data = data;
-}
-
bool QAbstractMesh::isDirty() const
{
Q_D(const QAbstractMesh);
@@ -91,13 +86,17 @@ bool QAbstractMesh::isDirty() const
void QAbstractMesh::setDirty(bool dirty)
{
Q_D(QAbstractMesh);
- d->m_dirty = dirty;
-}
-
-QAbstractMeshDataPtr QAbstractMesh::data() const
-{
- Q_D(const QAbstractMesh);
- return d->m_data;
+ if (dirty != d->m_dirty) {
+ d->m_dirty = dirty;
+ QScenePropertyChangePtr change(new QScenePropertyChange(ComponentUpdated, this));
+ change->setPropertyName(QByteArrayLiteral("meshFunctor"));
+ change->setValue(QVariant::fromValue(meshFunctor()));
+ 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
+ d->m_dirty = false;
+ }
}
} // Qt3D
diff --git a/src/core/core-components/qabstractmesh.h b/src/core/core-components/qabstractmesh.h
index 27ddb9004..29d4e9607 100644
--- a/src/core/core-components/qabstractmesh.h
+++ b/src/core/core-components/qabstractmesh.h
@@ -54,6 +54,15 @@ class QAbstractMeshData;
typedef QSharedPointer<QAbstractMeshData> QAbstractMeshDataPtr;
+class QT3DCORESHARED_EXPORT QAbstractMeshFunctor
+{
+public:
+ virtual QAbstractMeshDataPtr operator()() = 0;
+ virtual ~QAbstractMeshFunctor() {}
+};
+
+typedef QSharedPointer<QAbstractMeshFunctor> QAbstractMeshFunctorPtr;
+
class QT3DCORESHARED_EXPORT QAbstractMesh : public QComponent
{
Q_OBJECT
@@ -64,8 +73,7 @@ public:
bool isDirty() const;
void setDirty(bool dirty);
- virtual bool load() = 0;
- virtual QAbstractMeshDataPtr data() const;
+ virtual QAbstractMeshFunctorPtr meshFunctor() const = 0;
Q_SIGNALS:
void sourceChanged();
@@ -73,12 +81,12 @@ Q_SIGNALS:
protected:
Q_DECLARE_PRIVATE(QAbstractMesh)
QAbstractMesh(QAbstractMeshPrivate &dd, QNode *parent = 0);
-
- void setData(QAbstractMeshDataPtr data);
};
} // Qt3D
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(Qt3D::QAbstractMeshFunctorPtr)
+
#endif // QABSTRACTMESH_H
diff --git a/src/core/core-components/qabstractmesh_p.h b/src/core/core-components/qabstractmesh_p.h
index 8a05608ad..caf3249f2 100644
--- a/src/core/core-components/qabstractmesh_p.h
+++ b/src/core/core-components/qabstractmesh_p.h
@@ -54,7 +54,6 @@ QT_BEGIN_NAMESPACE
namespace Qt3D {
class QAbstractMesh;
-class QAbstractMeshData;
class QT3DCORESHARED_EXPORT QAbstractMeshPrivate : public QComponentPrivate
{
@@ -65,7 +64,6 @@ public:
const QUuid m_uuid;
bool m_dirty;
- QSharedPointer<QAbstractMeshData> m_data;
};
}
diff --git a/src/render/backend/jobs/loadmeshdatajob.cpp b/src/render/backend/jobs/loadmeshdatajob.cpp
index 96c5ab07e..596e58675 100644
--- a/src/render/backend/jobs/loadmeshdatajob.cpp
+++ b/src/render/backend/jobs/loadmeshdatajob.cpp
@@ -57,9 +57,10 @@ QT_BEGIN_NAMESPACE
namespace Qt3D {
namespace Render {
-LoadMeshDataJob::LoadMeshDataJob(const QUuid &meshEntityId)
+LoadMeshDataJob::LoadMeshDataJob(QAbstractMeshFunctorPtr functor, const QUuid &meshUuid)
: QJob()
- , m_meshSourceId(meshEntityId)
+ , m_meshUuid(meshUuid)
+ , m_functor(functor)
{
}
@@ -67,39 +68,19 @@ void LoadMeshDataJob::run()
{
qCDebug(Jobs) << "Entering" << Q_FUNC_INFO << QThread::currentThread();
- // Load the mesh from disk (or wherever)
-
- RenderMesh *rMesh = m_renderer->meshManager()->lookupResource(m_meshSourceId);
- if (rMesh == Q_NULLPTR)
- return ;
- // TO DO : Find a way to make that secure
- // Either loading has to be done somewhere, either we have to be sure a QAbstractMesh
- // Will stay valid up until that point
- QAbstractMesh *meshSource = rMesh->peer();
- if (meshSource == Q_NULLPTR)
- {
- qCDebug(Jobs) << Q_FUNC_INFO << " Mesh is null, why ?";
+ if (m_functor.isNull())
return ;
- }
-
- if (!meshSource->load()) {
- qCDebug(Jobs) << Q_FUNC_INFO << "Mesh failed to load";
- return ;
- }
-
- MeshDataPtr meshDataPtr = meshSource->data().staticCast<MeshData>();
+ // Load the mesh from disk (or wherever)
+ MeshDataPtr meshDataPtr = m_functor->operator ()().staticCast<MeshData>();
if (meshDataPtr.isNull()) {
qCDebug(Jobs) << Q_FUNC_INFO << "Mesh has no raw data";
return ;
}
// TO DO try to use QAbstractMeshData if possible
- // This is not properly thread synched
- MeshData *meshData = m_renderer->meshDataManager()->getOrCreateResource(rMesh->meshUuid());
- MeshDataManager::WriteLocker(m_renderer->meshDataManager());
- *meshData = *meshDataPtr.data();
- MeshManager::WriteLocker(m_renderer->meshManager());
- rMesh->setMeshData(m_renderer->meshDataManager()->lookupHandle(rMesh->meshUuid()));
+ QMutexLocker lock(m_renderer->mutex());
+ MeshData *meshData = m_renderer->meshDataManager()->getOrCreateResource(m_meshUuid);
+ *meshData = *(meshDataPtr.data());
AttributePtr attr = meshData->attributeByName(QAbstractMeshData::defaultPositionAttributeName()).staticCast<Attribute>();
if (!attr)
diff --git a/src/render/backend/jobs/loadmeshdatajob.h b/src/render/backend/jobs/loadmeshdatajob.h
index 8f519aa5f..bbd9a75e9 100644
--- a/src/render/backend/jobs/loadmeshdatajob.h
+++ b/src/render/backend/jobs/loadmeshdatajob.h
@@ -46,31 +46,32 @@
#include <Qt3DCore/qjob.h>
#include <Qt3DCore/qhandle.h>
#include <Qt3DRenderer/meshdata.h>
-
+#include <Qt3DCore/qabstractmesh.h>
#include <QSharedPointer>
QT_BEGIN_NAMESPACE
namespace Qt3D {
-class QAbstractMesh;
typedef QHandle<MeshData, 16> HMeshData;
namespace Render {
class Renderer;
+class RenderMesh;
+typedef QHandle<RenderMesh, 16> HMesh;
class LoadMeshDataJob : public Qt3D::QJob
{
public:
- LoadMeshDataJob(const QUuid &meshEntityId);
-
+ LoadMeshDataJob(QAbstractMeshFunctorPtr functor, const QUuid &meshUuid);
void setRenderer(Renderer *renderer) { m_renderer = renderer; }
protected:
void run() Q_DECL_OVERRIDE;
private:
- QUuid m_meshSourceId;
+ QUuid m_meshUuid;
+ QAbstractMeshFunctorPtr m_functor;
Renderer *m_renderer;
};
diff --git a/src/render/backend/meshdatamanager.cpp b/src/render/backend/meshdatamanager.cpp
index 1dfbc9baf..4c3e8c2a5 100644
--- a/src/render/backend/meshdatamanager.cpp
+++ b/src/render/backend/meshdatamanager.cpp
@@ -55,24 +55,19 @@ MeshDataManager::MeshDataManager()
{
}
-// Called concurrently by multiple Jobs when building RenderCommands
-void MeshDataManager::addMeshData(QUuid meshEntityId)
+// Called by aspect thread when RenderMesh receive a new functor in syncChanges
+void MeshDataManager::addMeshData(QAbstractMeshFunctorPtr functor, const QUuid &meshUuid)
{
- MeshDataManager::WriteLocker(this);
- if (!m_meshesPending.contains(meshEntityId))
- m_meshesPending.append(meshEntityId);
+ m_meshesPending[meshUuid] = functor;
}
// Called by single thread in RendererAspect
-QList<QUuid> MeshDataManager::meshesPending() const
-{
- return m_meshesPending;
-}
-
-// Called by single thread in RendererAspect
-void MeshDataManager::clearMeshesPending()
+// Needs to be protected as we ways call it while addMeshData is called
+QHash<QUuid, QAbstractMeshFunctorPtr> MeshDataManager::meshesPending()
{
+ QHash<QUuid, QAbstractMeshFunctorPtr> meshFunctors = m_meshesPending;
m_meshesPending.clear();
+ return meshFunctors;
}
} // namespace Render
diff --git a/src/render/backend/meshdatamanager.h b/src/render/backend/meshdatamanager.h
index da06cd64b..a52984e55 100644
--- a/src/render/backend/meshdatamanager.h
+++ b/src/render/backend/meshdatamanager.h
@@ -45,6 +45,7 @@
#include <Qt3DCore/qabstractmesh.h>
#include <Qt3DCore/qresourcesmanager.h>
#include <Qt3DRenderer/meshdata.h>
+#include <Qt3DRenderer/rendermesh.h>
#include <QHash>
#include <QPair>
@@ -57,6 +58,7 @@ namespace Qt3D {
namespace Render {
typedef QHandle<MeshData, 16> HMeshData;
+typedef QHandle<RenderMesh, 16> HMesh;
class MeshDataManager : public QResourcesManager<MeshData,
QUuid,
@@ -70,15 +72,15 @@ public:
inline bool hasMeshData(const QUuid &id) { return contains(id); }
inline MeshData* getOrCreateMeshData(const QUuid &id) { return getOrCreateResource(id); }
inline MeshData* meshData(const QUuid &id) { return lookupResource(id); }
- void addMeshData(QUuid meshEntityId);
+ void addMeshData(QAbstractMeshFunctorPtr functor, const QUuid &meshUuid);
- QList<QUuid> meshesPending() const;
- void clearMeshesPending();
+ QHash<QUuid, QAbstractMeshFunctorPtr> meshesPending();
private:
// List of meshes that we need to schedule jobs to load
// and calculate bounds for.
- QList<QUuid> m_meshesPending;
+
+ QHash<QUuid, QAbstractMeshFunctorPtr> m_meshesPending;
};
} // namespace Render
diff --git a/src/render/backend/rendercommand.h b/src/render/backend/rendercommand.h
index a2d3a2515..e97f6e3a7 100644
--- a/src/render/backend/rendercommand.h
+++ b/src/render/backend/rendercommand.h
@@ -86,7 +86,6 @@ public:
//private:
HVao m_vao; // VAO used during the submission step to store all states and VBOs
QMatrix4x4 m_worldMatrix; // modelMatrix for the mesh -> could maybe be stored directly with other uniform
- HMesh m_mesh;
HMeshData m_meshData;
HShader m_shader; // Shader for given pass and mesh
QUniformPack m_uniforms; // Might need to be reworked so as to be able to destroy the
diff --git a/src/render/backend/renderentity.cpp b/src/render/backend/renderentity.cpp
index f19436bcc..cef6c2c9a 100644
--- a/src/render/backend/renderentity.cpp
+++ b/src/render/backend/renderentity.cpp
@@ -89,13 +89,15 @@ RenderEntity::~RenderEntity()
{
if (m_renderer != Q_NULLPTR) {
RenderEntity *parentEntity = parent();
- m_renderer->rendererAspect()->aspectManager()->changeArbiter()->unregisterObserver(this, m_frontEndPeer);
if (parentEntity != Q_NULLPTR)
parentEntity->removeChildHandle(m_handle);
for (int i = 0; i < m_childrenHandles.size(); i++)
m_renderer->renderNodesManager()->release(m_childrenHandles[i]);
+ setTransform(Q_NULLPTR);
m_renderer->localMatrixManager()->release(m_localTransform);
m_renderer->worldMatrixManager()->release(m_worldTransform);
+ m_renderer->meshManager()->releaseRenderMesh(m_frontendUuid);
+ m_renderer->rendererAspect()->aspectManager()->changeArbiter()->unregisterObserver(this, m_frontEndPeer);
}
delete m_localBoundingVolume;
delete m_worldBoundingVolume;
diff --git a/src/render/backend/rendereraspect.cpp b/src/render/backend/rendereraspect.cpp
index be6d5fd9e..8439a4f39 100644
--- a/src/render/backend/rendereraspect.cpp
+++ b/src/render/backend/rendereraspect.cpp
@@ -41,6 +41,8 @@
#include "rendereraspect.h"
+#include "rendermesh.h"
+#include "meshmanager.h"
#include "meshdatamanager.h"
#include "renderer.h"
#include "renderthread.h"
@@ -82,14 +84,13 @@ QVector<QJobPtr> RendererAspect::jobsToExecute()
// Create jobs to load in any meshes that are pending
if (m_renderThread->renderer() != Q_NULLPTR) {
- QList<QUuid> meshSources = m_renderThread->renderer()->meshDataManager()->meshesPending();
+ QHash<QUuid, QAbstractMeshFunctorPtr> meshSources = m_renderThread->renderer()->meshDataManager()->meshesPending();
QVector<QJobPtr> meshesJobs;
- Q_FOREACH (const QUuid &meshEntityId, meshSources) {
- Render::LoadMeshDataJobPtr loadMeshJob(new Render::LoadMeshDataJob(meshEntityId));
+ Q_FOREACH (const QUuid &meshId, meshSources.keys()) {
+ Render::LoadMeshDataJobPtr loadMeshJob(new Render::LoadMeshDataJob(meshSources[meshId], meshId));
loadMeshJob->setRenderer(m_renderThread->renderer());
meshesJobs.append(loadMeshJob);
}
- m_renderThread->renderer()->meshDataManager()->clearMeshesPending();
// Create jobs to update transforms and bounding volumes
Render::UpdateWorldTransformJobPtr worldTransformJob(new Render::UpdateWorldTransformJob(m_renderThread->renderer()->renderSceneRoot()));
diff --git a/src/render/backend/rendermesh.cpp b/src/render/backend/rendermesh.cpp
index 301a0b18f..e8df82659 100644
--- a/src/render/backend/rendermesh.cpp
+++ b/src/render/backend/rendermesh.cpp
@@ -116,13 +116,13 @@ void RenderMesh::sceneChangeEvent(const QSceneChangePtr &e)
switch (e->type()) {
case ComponentUpdated: {
QScenePropertyChangePtr propertyChange = qSharedPointerCast<QScenePropertyChange>(e);
- if (propertyChange->propertyName() == QByteArrayLiteral("source") && qobject_cast<QMesh*>(m_peer)) // Mesh with source
+ if (propertyChange->propertyName() == QByteArrayLiteral("meshFunctor")) // Mesh with source
{
- QVariant propertyValue = propertyChange->value();
- m_source = propertyValue.toString();
- m_meshDirty = true;
- // TO DO Try to use and monitor for changes the peer dirty property to check if a mesh has to be reloaded
- m_peer->setDirty(true);
+ QAbstractMeshFunctorPtr functor = propertyChange->value().value<QAbstractMeshFunctorPtr>();
+ if (m_functor != functor) {
+ m_functor = functor;
+ m_renderer->meshDataManager()->addMeshData(m_functor, m_meshUuid);
+ }
}
break;
}
@@ -132,23 +132,9 @@ void RenderMesh::sceneChangeEvent(const QSceneChangePtr &e)
}
}
-bool RenderMesh::meshDirty() const
-{
- QReadLocker lock(m_lock);
- return m_meshDirty;
-}
-
HMeshData RenderMesh::meshData() const
{
- QReadLocker lock(m_lock);
- return m_meshDataHandle;
-}
-
-void RenderMesh::setMeshData(HMeshData handle)
-{
- QWriteLocker lock(m_lock);
- m_meshDataHandle = handle;
- m_meshDirty = false;
+ return m_renderer->meshDataManager()->lookupHandle(m_meshUuid);
}
//DrawStateSet *RenderMesh::stateSet()
diff --git a/src/render/backend/rendermesh.h b/src/render/backend/rendermesh.h
index 2ade2cddb..86521f7e6 100644
--- a/src/render/backend/rendermesh.h
+++ b/src/render/backend/rendermesh.h
@@ -55,9 +55,11 @@ class QReadWriteLock;
namespace Qt3D {
class QAbstractMesh;
+class QAbstractMeshFunctor;
class QRenderPass;
class MeshData;
+typedef QSharedPointer<QAbstractMeshFunctor> QAbstractMeshFunctorPtr;
typedef QHandle<MeshData, 16> HMeshData;
namespace Render {
@@ -78,11 +80,11 @@ public:
QAbstractMesh *peer() const { return m_peer; }
void sceneChangeEvent(const QSceneChangePtr &e);
- bool meshDirty() const;
HMeshData meshData() const;
void setMeshData(HMeshData handle);
QUuid meshUuid() const { return m_meshUuid; }
+ QAbstractMeshFunctorPtr meshFunctor() const { return m_functor; }
/**
* @brief mapAttributeNames - resolve mapping of mesh-data attribute
@@ -94,7 +96,7 @@ public:
private:
Renderer *m_renderer;
QAbstractMesh* m_peer;
- QString m_source;
+ QAbstractMeshFunctorPtr m_functor;
bool m_meshDirty;
HMeshData m_meshDataHandle;
diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp
index 2b22a54ca..9b469fa07 100644
--- a/src/render/backend/renderview.cpp
+++ b/src/render/backend/renderview.cpp
@@ -311,10 +311,8 @@ void RenderView::buildRenderCommands(RenderEntity *node)
if (m_renderer->meshManager()->contains(node->entityUuid()) &&
(meshHandle = m_renderer->meshManager()->lookupHandle(node->entityUuid())) != HMesh() &&
(mesh = m_renderer->meshManager()->data(meshHandle)) != Q_NULLPTR) {
- if (mesh->meshDirty()) {
- m_renderer->meshDataManager()->addMeshData(node->entityUuid());
- }
- else {
+ if (!mesh->meshData().isNull())
+ {
RenderMaterial *material = findMaterialForMeshNode(node->entityUuid());
RenderEffect *effect = findEffectForMaterial(material);
RenderTechnique *technique = findTechniqueForEffect(effect);
@@ -330,7 +328,6 @@ void RenderView::buildRenderCommands(RenderEntity *node)
Q_FOREACH (RenderRenderPass *pass, passes) {
RenderCommand *command = m_allocator->allocate<RenderCommand>();
- command->m_mesh = meshHandle;
command->m_meshData = mesh->meshData();
command->m_instancesCount = 0;
command->m_worldMatrix = *(node->worldTransform());
diff --git a/src/render/frontend/qabstractshapemesh.cpp b/src/render/frontend/qabstractshapemesh.cpp
index f418e1fc7..a716b9e6b 100644
--- a/src/render/frontend/qabstractshapemesh.cpp
+++ b/src/render/frontend/qabstractshapemesh.cpp
@@ -64,12 +64,6 @@ QAbstractShapeMesh::QAbstractShapeMesh(QAbstractShapeMeshPrivate &dd, QNode *par
{
}
-bool QAbstractShapeMesh::load()
-{
- QAbstractMesh::setData(buildMeshdata().staticCast<QAbstractMeshData>());
- return true;
-}
-
} // namespace Qt3D
QT_END_NAMESPACE
diff --git a/src/render/frontend/qabstractshapemesh.h b/src/render/frontend/qabstractshapemesh.h
index 0613e7128..ec6e2c5e1 100644
--- a/src/render/frontend/qabstractshapemesh.h
+++ b/src/render/frontend/qabstractshapemesh.h
@@ -61,10 +61,6 @@ class QT3DRENDERERSHARED_EXPORT QAbstractShapeMesh : public QAbstractMesh
public:
explicit QAbstractShapeMesh(QNode *parent = 0);
- bool load() Q_DECL_OVERRIDE;
-
- virtual QAbstractMeshDataPtr buildMeshdata() const = 0;
-
protected:
Q_DECLARE_PRIVATE(QAbstractShapeMesh)
QAbstractShapeMesh(QAbstractShapeMeshPrivate &dd, QNode* parent = 0);
diff --git a/src/render/frontend/qmesh.cpp b/src/render/frontend/qmesh.cpp
index 81f75e6a3..20392d444 100644
--- a/src/render/frontend/qmesh.cpp
+++ b/src/render/frontend/qmesh.cpp
@@ -55,6 +55,17 @@ QT_BEGIN_NAMESPACE
namespace Qt3D {
+class MeshFunctor : public QAbstractMeshFunctor
+{
+public :
+ MeshFunctor(const QString &sourcePath);
+ QAbstractMeshDataPtr operator()() Q_DECL_OVERRIDE;
+
+private:
+ QString m_sourcePath;
+};
+
+
QMeshPrivate::QMeshPrivate(QMesh *qq)
: QAbstractMeshPrivate(qq)
{}
@@ -77,10 +88,7 @@ void QMesh::setSource( const QString& source )
d->m_source = source;
emit sourceChanged();
// Let aspects know about the change
- QScenePropertyChangePtr e(new QScenePropertyChange(ComponentUpdated, this));
- e->setPropertyName(QByteArrayLiteral("source"));
- e->setValue(d->m_source);
- notifyObservers(e);
+ QAbstractMesh::setDirty(true);
}
QString QMesh::source() const
@@ -89,27 +97,35 @@ QString QMesh::source() const
return d->m_source;
}
-bool QMesh::load()
+QAbstractMeshFunctorPtr QMesh::meshFunctor() const
{
- Q_D(QMesh);
+ Q_D(const QMesh);
+ return QAbstractMeshFunctorPtr(new MeshFunctor(d->m_source));
+}
+
+MeshFunctor::MeshFunctor(const QString &sourcePath)
+ : QAbstractMeshFunctor()
+ , m_sourcePath(sourcePath)
+{
+}
- if (d->m_source.isEmpty()) {
+QAbstractMeshDataPtr MeshFunctor::operator()()
+{
+ if (m_sourcePath.isEmpty()) {
qCWarning(Render::Jobs) << Q_FUNC_INFO << "Mesh is empty, nothing to load";
- return false;
+ return MeshDataPtr();
}
// TO DO : Maybe use Assimp instead of ObjLoader to handle more sources
ObjLoader loader;
loader.setLoadTextureCoordinatesEnabled(true);
- qCDebug(Render::Jobs) << Q_FUNC_INFO << "Loading mesh from" << d->m_source;
+ qCDebug(Render::Jobs) << Q_FUNC_INFO << "Loading mesh from" << m_sourcePath;
- if (loader.load(d->m_source)) {
- QAbstractMesh::setData(QAbstractMeshDataPtr(loader.mesh()));
- return true;
- }
+ if (loader.load(m_sourcePath))
+ return MeshDataPtr(loader.mesh());
- qCWarning(Render::Jobs) << Q_FUNC_INFO << "OBJ load failure for:" << d->m_source;
- return false;
+ qCWarning(Render::Jobs) << Q_FUNC_INFO << "OBJ load failure for:" << m_sourcePath;
+ return MeshDataPtr();
}
} // namespace Qt3D
diff --git a/src/render/frontend/qmesh.h b/src/render/frontend/qmesh.h
index f582e748a..9bab103cd 100644
--- a/src/render/frontend/qmesh.h
+++ b/src/render/frontend/qmesh.h
@@ -69,7 +69,7 @@ public:
void setSource(const QString &source);
QString source() const;
- bool load() Q_DECL_OVERRIDE;
+ QAbstractMeshFunctorPtr meshFunctor() const Q_DECL_OVERRIDE;
Q_SIGNALS:
void sourceChanged();
diff --git a/src/render/frontend/qspheremesh.cpp b/src/render/frontend/qspheremesh.cpp
index 59b732a2b..0bda79428 100644
--- a/src/render/frontend/qspheremesh.cpp
+++ b/src/render/frontend/qspheremesh.cpp
@@ -52,6 +52,20 @@ QT_BEGIN_NAMESPACE
namespace Qt3D {
+class SphereMeshFunctor : public QAbstractMeshFunctor
+{
+public:
+ SphereMeshFunctor(int rings, int slices, float radius, bool generateTangents);
+ QAbstractMeshDataPtr operator ()() Q_DECL_OVERRIDE;
+
+private:
+ int m_rings;
+ int m_slices;
+ float m_radius;
+ bool m_generateTangents;
+
+};
+
class QSphereMeshPrivate : public QAbstractShapeMeshPrivate
{
QSphereMeshPrivate(QSphereMesh *qq)
@@ -80,6 +94,7 @@ void QSphereMesh::setRings(int rings)
if (rings != d->m_rings) {
d->m_rings = rings;
emit ringsChanged();
+ QAbstractMesh::setDirty(true);
}
}
@@ -89,6 +104,7 @@ void QSphereMesh::setSlices(int slices)
if (slices != d->m_slices) {
d->m_slices = slices;
emit slicesChanged();
+ QAbstractMesh::setDirty(true);
}
}
@@ -98,6 +114,7 @@ void QSphereMesh::setRadius(float radius)
if (radius != d->m_radius) {
d->m_radius = radius;
emit radiusChanged();
+ QAbstractMesh::setDirty(true);
}
}
@@ -107,6 +124,7 @@ void QSphereMesh::setGenerateTangents(bool gen)
if (d->m_generateTangents != gen) {
d->m_generateTangents = gen;
emit generateTangentsChanged();
+ QAbstractMesh::setDirty(true);
}
}
@@ -116,6 +134,12 @@ bool QSphereMesh::generateTangents() const
return d->m_generateTangents;
}
+QAbstractMeshFunctorPtr QSphereMesh::meshFunctor() const
+{
+ Q_D(const QSphereMesh);
+ return QAbstractMeshFunctorPtr(new SphereMeshFunctor(d->m_rings, d->m_slices, d->m_radius, d->m_generateTangents));
+}
+
int QSphereMesh::rings() const
{
Q_D(const QSphereMesh);
@@ -134,13 +158,7 @@ float QSphereMesh::radius() const
return d->m_radius;
}
-QAbstractMeshDataPtr QSphereMesh::buildMeshdata() const
-{
- Q_D(const QSphereMesh);
- return createSphereMesh(d->m_radius, d->m_rings, d->m_slices, d->m_generateTangents);
-}
-
-MeshDataPtr QSphereMesh::createSphereMesh(double radius, int rings, int slices, bool hasTangents)
+MeshDataPtr createSphereMesh(double radius, int rings, int slices, bool hasTangents)
{
MeshDataPtr mesh(new MeshData(GL_TRIANGLES));
@@ -272,6 +290,20 @@ MeshDataPtr QSphereMesh::createSphereMesh(double radius, int rings, int slices,
return mesh;
}
+SphereMeshFunctor::SphereMeshFunctor(int rings, int slices, float radius, bool generateTangents)
+ : QAbstractMeshFunctor()
+ , m_rings(rings)
+ , m_slices(slices)
+ , m_radius(radius)
+ , m_generateTangents(generateTangents)
+{
+}
+
+QAbstractMeshDataPtr SphereMeshFunctor::operator ()()
+{
+ return createSphereMesh(m_radius, m_rings, m_slices, m_generateTangents);
+}
+
} //Qt3D
QT_END_NAMESPACE
diff --git a/src/render/frontend/qspheremesh.h b/src/render/frontend/qspheremesh.h
index e3dc7f0cd..38653c6d6 100644
--- a/src/render/frontend/qspheremesh.h
+++ b/src/render/frontend/qspheremesh.h
@@ -73,7 +73,7 @@ public:
float radius() const;
bool generateTangents() const;
- QAbstractMeshDataPtr buildMeshdata() const Q_DECL_OVERRIDE;
+ QAbstractMeshFunctorPtr meshFunctor() const Q_DECL_OVERRIDE;
Q_SIGNALS:
@@ -83,11 +83,8 @@ Q_SIGNALS:
void generateTangentsChanged();
private:
-
Q_DECLARE_PRIVATE(QSphereMesh)
- static MeshDataPtr createSphereMesh(double radius, int rings, int slices, bool hasTangents);
-
};
} // Qt3D
diff --git a/src/render/frontend/qtorusmesh.cpp b/src/render/frontend/qtorusmesh.cpp
index 823af9759..430542d66 100644
--- a/src/render/frontend/qtorusmesh.cpp
+++ b/src/render/frontend/qtorusmesh.cpp
@@ -51,6 +51,19 @@ QT_BEGIN_NAMESPACE
namespace Qt3D {
+class TorusMeshFunctor : public QAbstractMeshFunctor
+{
+public:
+ TorusMeshFunctor(int rings, int slices, float radius, float minorRadius);
+ QAbstractMeshDataPtr operator ()() Q_DECL_OVERRIDE;
+
+private:
+ int m_rings;
+ int m_slices;
+ float m_radius;
+ float m_minorRadius;
+};
+
class QTorusMeshPrivate : public QAbstractShapeMeshPrivate
{
QTorusMeshPrivate(QTorusMesh *qq)
@@ -79,6 +92,7 @@ void QTorusMesh::setRings(int rings)
if (rings != d->m_rings) {
d->m_rings = rings;
emit ringsChanged();
+ QAbstractMesh::setDirty(true);
}
}
@@ -88,6 +102,7 @@ void QTorusMesh::setSlices(int slices)
if (slices != d->m_slices) {
d->m_slices = slices;
emit slicesChanged();
+ QAbstractMesh::setDirty(true);
}
}
@@ -97,6 +112,7 @@ void QTorusMesh::setRadius(float radius)
if (radius != d->m_radius) {
d->m_radius = radius;
emit radiusChanged();
+ QAbstractMesh::setDirty(true);
}
}
@@ -106,6 +122,7 @@ void QTorusMesh::setMinorRadius(float minorRadius)
if (minorRadius != d->m_minorRadius) {
d->m_minorRadius = minorRadius;
emit minorRadiusChanged();
+ QAbstractMesh::setDirty(true);
}
}
@@ -133,13 +150,7 @@ float QTorusMesh::minorRadius() const
return d->m_minorRadius;
}
-QAbstractMeshDataPtr QTorusMesh::buildMeshdata() const
-{
- Q_D(const QTorusMesh);
- return createTorusMesh(d->m_radius, d->m_minorRadius, d->m_rings, d->m_slices);
-}
-
-QAbstractMeshDataPtr QTorusMesh::createTorusMesh(double radius, double minorRadius,
+QAbstractMeshDataPtr createTorusMesh(double radius, double minorRadius,
int rings, int sides)
{
QAbstractMeshDataPtr mesh(new MeshData(GL_TRIANGLES));
@@ -231,6 +242,26 @@ QAbstractMeshDataPtr QTorusMesh::createTorusMesh(double radius, double minorRadi
return mesh;
}
+QAbstractMeshFunctorPtr QTorusMesh::meshFunctor() const
+{
+ Q_D(const QTorusMesh);
+ return QAbstractMeshFunctorPtr(new TorusMeshFunctor(d->m_rings, d->m_slices, d->m_radius, d->m_minorRadius));
+}
+
+TorusMeshFunctor::TorusMeshFunctor(int rings, int slices, float radius, float minorRadius)
+ : QAbstractMeshFunctor()
+ , m_rings(rings)
+ , m_slices(slices)
+ , m_radius(radius)
+ , m_minorRadius(minorRadius)
+{
+}
+
+QAbstractMeshDataPtr TorusMeshFunctor::operator ()()
+{
+ return createTorusMesh(m_radius, m_minorRadius, m_rings, m_slices);
+}
+
} // Qt3D
QT_END_NAMESPACE
diff --git a/src/render/frontend/qtorusmesh.h b/src/render/frontend/qtorusmesh.h
index aec539176..4d8717456 100644
--- a/src/render/frontend/qtorusmesh.h
+++ b/src/render/frontend/qtorusmesh.h
@@ -72,7 +72,7 @@ public:
float radius() const;
float minorRadius() const;
- QAbstractMeshDataPtr buildMeshdata() const Q_DECL_OVERRIDE;
+ QAbstractMeshFunctorPtr meshFunctor() const;
Q_SIGNALS:
@@ -83,8 +83,6 @@ Q_SIGNALS:
private:
Q_DECLARE_PRIVATE(QTorusMesh)
-
- static QAbstractMeshDataPtr createTorusMesh(double radius, double minorRadius, int rings, int sides);
};
} // Qt3D
diff --git a/src/render/io/assimpparser.cpp b/src/render/io/assimpparser.cpp
index 48acfebcc..5b5bbf9be 100644
--- a/src/render/io/assimpparser.cpp
+++ b/src/render/io/assimpparser.cpp
@@ -793,16 +793,30 @@ AssimpParser::AssimpMesh::AssimpMesh(QNode *parent)
{
}
-bool AssimpParser::AssimpMesh::load()
+void AssimpParser::AssimpMesh::setData(MeshDataPtr data)
{
- return true;
+ m_meshData = data;
+ QAbstractMesh::setDirty(this);
}
-void AssimpParser::AssimpMesh::setData(MeshDataPtr data)
+QAbstractMeshFunctorPtr AssimpParser::AssimpMesh::meshFunctor() const
+{
+ return QAbstractMeshFunctorPtr(new AssimpMeshFunctor(m_meshData));
+}
+
+AssimpParser::AssimpMeshFunctor::AssimpMeshFunctor(MeshDataPtr meshData)
+ : QAbstractMeshFunctor()
+ , m_meshData(meshData)
{
- QAbstractMesh::setData(data.staticCast<QAbstractMeshData>());
+}
+
+QAbstractMeshDataPtr AssimpParser::AssimpMeshFunctor::operator()()
+{
+ return m_meshData;
}
} // Qt3D
QT_END_NAMESPACE
+
+
diff --git a/src/render/io/assimpparser.h b/src/render/io/assimpparser.h
index c706fd8ab..db3c55d34 100644
--- a/src/render/io/assimpparser.h
+++ b/src/render/io/assimpparser.h
@@ -90,13 +90,24 @@ public:
private :
+ class AssimpMeshFunctor : public QAbstractMeshFunctor
+ {
+ public:
+ explicit AssimpMeshFunctor(MeshDataPtr meshData);
+ QAbstractMeshDataPtr operator()() Q_DECL_OVERRIDE;
+ private:
+ MeshDataPtr m_meshData;
+ };
+
class AssimpMesh : public QAbstractMesh
{
public :
- AssimpMesh(QNode *parent = 0);
+ explicit AssimpMesh(QNode *parent = 0);
- bool load() Q_DECL_OVERRIDE;
+ QAbstractMeshFunctorPtr meshFunctor() const Q_DECL_OVERRIDE;
void setData(MeshDataPtr data);
+ private:
+ MeshDataPtr m_meshData;
};
static QStringList assimpSupportedFormats();
diff --git a/src/render/io/gltfparser.cpp b/src/render/io/gltfparser.cpp
index fa23b3ca2..431adb06c 100644
--- a/src/render/io/gltfparser.cpp
+++ b/src/render/io/gltfparser.cpp
@@ -965,14 +965,26 @@ GLTFParser::GLTFParserMesh::GLTFParserMesh(QNode *parent)
{
}
-bool GLTFParser::GLTFParserMesh::load()
+void GLTFParser::GLTFParserMesh::setData(MeshDataPtr data)
{
- return true;
+ m_meshData = data;
+ QAbstractMesh::setDirty(this);
}
-void GLTFParser::GLTFParserMesh::setData(MeshDataPtr data)
+QAbstractMeshFunctorPtr GLTFParser::GLTFParserMesh::meshFunctor() const
+{
+ return QAbstractMeshFunctorPtr(new GLTFParserMesh::GLTFParserMeshFunctor(m_meshData));
+}
+
+GLTFParser::GLTFParserMesh::GLTFParserMeshFunctor::GLTFParserMeshFunctor(MeshDataPtr meshData)
+ : QAbstractMeshFunctor()
+ , m_meshData(meshData)
+{
+}
+
+QAbstractMeshDataPtr GLTFParser::GLTFParserMesh::GLTFParserMeshFunctor::operator ()()
{
- QAbstractMesh::setData(data.staticCast<QAbstractMeshData>());
+ return m_meshData;
}
} // of namespace Qt3D
diff --git a/src/render/io/gltfparser.h b/src/render/io/gltfparser.h
index d06dc6d0b..422b746f4 100644
--- a/src/render/io/gltfparser.h
+++ b/src/render/io/gltfparser.h
@@ -100,11 +100,25 @@ private:
class GLTFParserMesh : public QAbstractMesh
{
+ private:
+ class GLTFParserMeshFunctor : public QAbstractMeshFunctor
+ {
+ public:
+ explicit GLTFParserMeshFunctor(MeshDataPtr meshData);
+ QAbstractMeshDataPtr operator ()();
+
+ private:
+ MeshDataPtr m_meshData;
+ };
+
public:
GLTFParserMesh(QNode *parent = 0);
- bool load() Q_DECL_OVERRIDE;
void setData(MeshDataPtr data);
+ QAbstractMeshFunctorPtr meshFunctor() const Q_DECL_OVERRIDE;
+
+ private:
+ MeshDataPtr m_meshData;
};
void parse();