diff options
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(); |