diff options
-rw-r--r-- | src/core/aspect/qcoreaspect.cpp | 41 | ||||
-rw-r--r-- | src/core/aspect/qcoreaspect.h | 5 | ||||
-rw-r--r-- | src/core/aspect/qcoreaspect_p.h | 6 | ||||
-rw-r--r-- | src/core/core.pro | 7 | ||||
-rw-r--r-- | src/core/geometry/bufferutils_p.h | 113 | ||||
-rw-r--r-- | src/core/geometry/buffervisitor_p.h | 285 | ||||
-rw-r--r-- | src/core/geometry/geometry.pri | 4 | ||||
-rw-r--r-- | src/core/geometry/qgeometry_p.h | 1 | ||||
-rw-r--r-- | src/core/geometry/qgeometryview.cpp | 244 | ||||
-rw-r--r-- | src/core/geometry/qgeometryview_p.h | 28 | ||||
-rw-r--r-- | src/core/jobs/calcboundingvolumejob.cpp | 317 | ||||
-rw-r--r-- | src/core/jobs/calcboundingvolumejob_p.h | 113 | ||||
-rw-r--r-- | src/core/jobs/job_common_p.h | 73 | ||||
-rw-r--r-- | src/core/jobs/jobs.pri | 7 |
14 files changed, 1233 insertions, 11 deletions
diff --git a/src/core/aspect/qcoreaspect.cpp b/src/core/aspect/qcoreaspect.cpp index 48f9aaf3a..dc3566edc 100644 --- a/src/core/aspect/qcoreaspect.cpp +++ b/src/core/aspect/qcoreaspect.cpp @@ -39,12 +39,16 @@ #include "qcoreaspect.h" #include "qcoreaspect_p.h" +#include <Qt3DCore/private/qaspectmanager_p.h> +#include <Qt3DCore/private/qscene_p.h> +#include <Qt3DCore/private/calcboundingvolumejob_p.h> QT_BEGIN_NAMESPACE using namespace Qt3DCore; QCoreAspectPrivate::QCoreAspectPrivate() + : Qt3DCore::QAbstractAspectPrivate() { } @@ -65,7 +69,7 @@ void QCoreAspectPrivate::frameDone() } QCoreAspect::QCoreAspect(QObject *parent) - : Qt3DCore::QAbstractAspect(parent) + : Qt3DCore::QAbstractAspect(*new QCoreAspectPrivate, parent) { } @@ -75,10 +79,28 @@ QCoreAspect::~QCoreAspect() } +QAspectJobPtr QCoreAspect::calculateBoundingVolumeJob() const +{ + Q_D(const QCoreAspect); + return d->m_calculateBoundingVolumeJob; +} + QVector<QAspectJobPtr> QCoreAspect::jobsToExecute(qint64 time) { + Q_D(QCoreAspect); Q_UNUSED(time) - return {}; + + QVector<QAspectJobPtr> jobs; + + auto scene = d->m_aspectManager->scene(); + auto dirtyBits = scene->dirtyBits(); + + if (dirtyBits & QScene::GeometryDirty || + dirtyBits & QScene::BuffersDirty) { + jobs.push_back(d->m_calculateBoundingVolumeJob); + } + + return jobs; } QVariant QCoreAspect::executeCommand(const QStringList &args) @@ -89,12 +111,25 @@ QVariant QCoreAspect::executeCommand(const QStringList &args) void QCoreAspect::onRegistered() { + Q_D(QCoreAspect); + if (d->m_calculateBoundingVolumeJob.isNull()) + d->m_calculateBoundingVolumeJob = CalculateBoundingVolumeJobPtr::create(); } -void QCoreAspect::onUnregistered() +void QCoreAspect::onEngineStartup() { + Q_D(QCoreAspect); + Q_ASSERT(d->m_calculateBoundingVolumeJob); + d->m_calculateBoundingVolumeJob->setRoot(d->m_root); +} + +void QCoreAspect::frameDone() +{ + Q_D(QCoreAspect); + auto scene = d->m_aspectManager->scene(); + scene->clearDirtyBits(); } QT_END_NAMESPACE diff --git a/src/core/aspect/qcoreaspect.h b/src/core/aspect/qcoreaspect.h index 27c72f405..071b7387a 100644 --- a/src/core/aspect/qcoreaspect.h +++ b/src/core/aspect/qcoreaspect.h @@ -55,6 +55,8 @@ public: explicit QCoreAspect(QObject *parent = nullptr); ~QCoreAspect(); + QAspectJobPtr calculateBoundingVolumeJob() const; + protected: Q_DECLARE_PRIVATE(QCoreAspect) @@ -62,7 +64,8 @@ private: QVector<Qt3DCore::QAspectJobPtr> jobsToExecute(qint64 time) override; QVariant executeCommand(const QStringList &args) override; void onRegistered() override; - void onUnregistered() override; + void onEngineStartup() override; + void frameDone() override; }; } diff --git a/src/core/aspect/qcoreaspect_p.h b/src/core/aspect/qcoreaspect_p.h index ca665faf8..cda0a140a 100644 --- a/src/core/aspect/qcoreaspect_p.h +++ b/src/core/aspect/qcoreaspect_p.h @@ -55,10 +55,15 @@ #include <Qt3DCore/private/qabstractaspect_p.h> #include <Qt3DCore/private/qt3dcore_global_p.h> +#include <QSharedPointer> + QT_BEGIN_NAMESPACE namespace Qt3DCore { +class CalculateBoundingVolumeJob; +using CalculateBoundingVolumeJobPtr = QSharedPointer<CalculateBoundingVolumeJob>; + class Q_3DCORE_PRIVATE_EXPORT QCoreAspectPrivate : public Qt3DCore::QAbstractAspectPrivate { public: @@ -71,6 +76,7 @@ public: void frameDone() override; bool m_initialized; + CalculateBoundingVolumeJobPtr m_calculateBoundingVolumeJob; }; } diff --git a/src/core/core.pro b/src/core/core.pro index b149497fb..846e9d836 100644 --- a/src/core/core.pro +++ b/src/core/core.pro @@ -1,7 +1,8 @@ -TARGET = Qt3DCore -MODULE = 3dcore +TARGET = Qt3DCore +MODULE = 3dcore -QT = core-private gui-private network +QT = core-private gui-private network +QT_FOR_PRIVATE = concurrent gcov { QMAKE_CXXFLAGS += -fprofile-arcs -ftest-coverage diff --git a/src/core/geometry/bufferutils_p.h b/src/core/geometry/bufferutils_p.h new file mode 100644 index 000000000..1b83d9949 --- /dev/null +++ b/src/core/geometry/bufferutils_p.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Paul Lemire paul.lemire350@gmail.com +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DCORE_BUFFERUTILS_P_H +#define QT3DCORE_BUFFERUTILS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DCore/QAttribute> +#include <QByteArray> + +QT_BEGIN_NAMESPACE + + +namespace Qt3DCore { + +class QGeometryView; +class QBuffer; + +struct BufferInfo +{ + BufferInfo() + : type(Qt3DCore::QAttribute::VertexBaseType::Float) + , dataSize(0) + , count(0) + , byteStride(0) + , byteOffset(0) + , restartEnabled(false) + , restartIndexValue(-1) + {} + + QByteArray data; + Qt3DCore::QAttribute::VertexBaseType type; + uint dataSize; + uint count; + uint byteStride; + uint byteOffset; + bool restartEnabled; + int restartIndexValue; +}; + + +namespace BufferTypeInfo { + + template <Qt3DCore::QAttribute::VertexBaseType> struct EnumToType; + template <> struct EnumToType<Qt3DCore::QAttribute::Byte> { typedef const char type; }; + template <> struct EnumToType<Qt3DCore::QAttribute::UnsignedByte> { typedef const uchar type; }; + template <> struct EnumToType<Qt3DCore::QAttribute::Short> { typedef const short type; }; + template <> struct EnumToType<Qt3DCore::QAttribute::UnsignedShort> { typedef const ushort type; }; + template <> struct EnumToType<Qt3DCore::QAttribute::Int> { typedef const int type; }; + template <> struct EnumToType<Qt3DCore::QAttribute::UnsignedInt> { typedef const uint type; }; + template <> struct EnumToType<Qt3DCore::QAttribute::Float> { typedef const float type; }; + template <> struct EnumToType<Qt3DCore::QAttribute::Double> { typedef const double type; }; + + template<Qt3DCore::QAttribute::VertexBaseType v> + typename EnumToType<v>::type *castToType(const QByteArray &u, uint byteOffset) + { + return reinterpret_cast< typename EnumToType<v>::type *>(u.constData() + byteOffset); + } + +} // namespace BufferTypeInfo + +} // namespace Qt3DCore + +QT_END_NAMESPACE + + +#endif // QT3DCORE_BUFFERUTILS_P_H diff --git a/src/core/geometry/buffervisitor_p.h b/src/core/geometry/buffervisitor_p.h new file mode 100644 index 000000000..69cfb9b50 --- /dev/null +++ b/src/core/geometry/buffervisitor_p.h @@ -0,0 +1,285 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DCORE_BUFFERVISITOR_P_H +#define QT3DCORE_BUFFERVISITOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DCore/qnodeid.h> +#include <Qt3DCore/qattribute.h> +#include <Qt3DCore/qbuffer.h> +#include <Qt3DCore/private/bufferutils_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DCore { +class QEntity; + +template <typename ValueType, Qt3DCore::QAttribute::VertexBaseType VertexBaseType, uint dataSize> +class Q_AUTOTEST_EXPORT BufferVisitor +{ +public: + explicit BufferVisitor() = default; + virtual ~BufferVisitor() = default; + + virtual void visit(uint ndx, ValueType x) { + Q_UNUSED(ndx) Q_UNUSED(x) + } + virtual void visit(uint ndx, ValueType x, ValueType y) { + Q_UNUSED(ndx) Q_UNUSED(x) Q_UNUSED(y) + } + virtual void visit(uint ndx, ValueType x, ValueType y, ValueType z) { + Q_UNUSED(ndx) Q_UNUSED(x) Q_UNUSED(y) Q_UNUSED(z) + } + virtual void visit(uint ndx, ValueType x, ValueType y, ValueType z, ValueType w) { + Q_UNUSED(ndx) Q_UNUSED(x) Q_UNUSED(y) Q_UNUSED(z) Q_UNUSED(w) + } + + bool apply(QAttribute *attribute, + QAttribute *indexAttribute, + int drawVertexCount, + bool primitiveRestartEnabled, + int primitiveRestartIndex) + { + if (attribute->vertexBaseType() != VertexBaseType) + return false; + if (attribute->vertexSize() < dataSize) + return false; + + auto data = attribute->buffer()->data(); + auto vertexBuffer = BufferTypeInfo::castToType<VertexBaseType>(data, attribute->byteOffset()); + + if (indexAttribute) { + auto indexData = indexAttribute->buffer()->data(); + switch (indexAttribute->vertexBaseType()) { + case Qt3DCore::QAttribute::UnsignedShort: { + auto indexBuffer = BufferTypeInfo::castToType<Qt3DCore::QAttribute::UnsignedShort>(indexData, indexAttribute->byteOffset()); + traverseCoordinateIndexed(vertexBuffer, indexBuffer, attribute->byteStride(), drawVertexCount, + primitiveRestartEnabled, primitiveRestartIndex); + break; + } + case Qt3DCore::QAttribute::UnsignedInt: { + auto indexBuffer = BufferTypeInfo::castToType<Qt3DCore::QAttribute::UnsignedInt>(indexData, indexAttribute->byteOffset()); + traverseCoordinateIndexed(vertexBuffer, indexBuffer, attribute->byteStride(), drawVertexCount, + primitiveRestartEnabled, primitiveRestartIndex); + break; + } + case Qt3DCore::QAttribute::UnsignedByte: { + auto indexBuffer = BufferTypeInfo::castToType<Qt3DCore::QAttribute::UnsignedByte>(indexData, indexAttribute->byteOffset()); + traverseCoordinateIndexed(vertexBuffer, indexBuffer, attribute->byteStride(), drawVertexCount, + primitiveRestartEnabled, primitiveRestartIndex); + break; + } + default: Q_UNREACHABLE(); + } + } else { + switch (dataSize) { + case 1: traverseCoordinates1(vertexBuffer, attribute->byteStride(), drawVertexCount); break; + case 2: traverseCoordinates2(vertexBuffer, attribute->byteStride(), drawVertexCount); break; + case 3: traverseCoordinates3(vertexBuffer, attribute->byteStride(), drawVertexCount); break; + case 4: traverseCoordinates4(vertexBuffer, attribute->byteStride(), drawVertexCount); break; + default: Q_UNREACHABLE(); + } + } + + return true; + } + +protected: + template<typename VertexBufferType, typename IndexBufferType> + void traverseCoordinateIndexed(VertexBufferType *vertexBuffer, + IndexBufferType *indexBuffer, + int vertexByteStride, + int drawVertexCount, + bool primitiveRestartEnabled, + int primitiveRestartIndex) + { + switch (dataSize) { + case 1: traverseCoordinates1Indexed(vertexBuffer, vertexByteStride, indexBuffer, drawVertexCount, + primitiveRestartEnabled, primitiveRestartIndex); + break; + case 2: traverseCoordinates2Indexed(vertexBuffer, vertexByteStride, indexBuffer, drawVertexCount, + primitiveRestartEnabled, primitiveRestartIndex); + break; + case 3: traverseCoordinates3Indexed(vertexBuffer, vertexByteStride, indexBuffer, drawVertexCount, + primitiveRestartEnabled, primitiveRestartIndex); + break; + case 4: traverseCoordinates4Indexed(vertexBuffer, vertexByteStride, indexBuffer, drawVertexCount, + primitiveRestartEnabled, primitiveRestartIndex); + break; + default: Q_UNREACHABLE(); + } + } + + template <typename Coordinate> + void traverseCoordinates1(Coordinate *coordinates, + const uint byteStride, + const uint count) + { + const uint stride = byteStride / sizeof(Coordinate); + for (uint ndx = 0; ndx < count; ++ndx) { + visit(ndx, coordinates[0]); + coordinates += stride; + } + } + + template <typename Coordinate, typename IndexElem> + void traverseCoordinates1Indexed(Coordinate *coordinates, + const uint byteStride, + IndexElem *indices, + const uint count, + bool primitiveRestartEnabled, + int primitiveRestartIndex) + { + const uint stride = byteStride / sizeof(Coordinate); + for (uint i = 0; i < count; ++i) { + if (!primitiveRestartEnabled || static_cast<int>(indices[i]) != primitiveRestartIndex) { + const uint n = stride * indices[i]; + visit(i, coordinates[n]); + } + } + } + + template <typename Coordinate> + void traverseCoordinates2(Coordinate *coordinates, + const uint byteStride, + const uint count) + { + const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 2; + for (uint ndx = 0; ndx < count; ++ndx) { + visit(ndx, coordinates[0], coordinates[1]); + coordinates += stride; + } + } + + + template <typename Coordinate, typename IndexElem> + void traverseCoordinates2Indexed(Coordinate *coordinates, + const uint byteStride, + IndexElem *indices, + const uint count, + bool primitiveRestartEnabled, + int primitiveRestartIndex) + { + const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 2; + for (uint i = 0; i < count; ++i) { + if (!primitiveRestartEnabled || static_cast<int>(indices[i]) != primitiveRestartIndex) { + const uint n = stride * indices[i]; + visit(i, coordinates[n], coordinates[n + 1]); + } + } + } + + template <typename Coordinate> + void traverseCoordinates3(Coordinate *coordinates, + const uint byteStride, + const uint count) + { + const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 3; + for (uint ndx = 0; ndx < count; ++ndx) { + visit(ndx, coordinates[0], coordinates[1], coordinates[2]); + coordinates += stride; + } + } + + template <typename Coordinate, typename IndexElem> + void traverseCoordinates3Indexed(Coordinate *coordinates, + const uint byteStride, + IndexElem *indices, + const uint count, + bool primitiveRestartEnabled, + int primitiveRestartIndex) + { + const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 3; + for (uint i = 0; i < count; ++i) { + if (!primitiveRestartEnabled || static_cast<int>(indices[i]) != primitiveRestartIndex) { + const uint n = stride * indices[i]; + visit(i, coordinates[n], coordinates[n + 1], coordinates[n + 2]); + } + } + } + + template <typename Coordinate> + void traverseCoordinates4(Coordinate *coordinates, + const uint byteStride, + const uint count) + { + const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 4; + for (uint ndx = 0; ndx < count; ++ndx) { + visit(ndx, coordinates[0], coordinates[1], coordinates[2], coordinates[3]); + coordinates += stride; + } + } + + template <typename Coordinate, typename IndexElem> + void traverseCoordinates4Indexed(Coordinate *coordinates, + const uint byteStride, + IndexElem *indices, + const uint count, + bool primitiveRestartEnabled, + int primitiveRestartIndex) + { + const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 4; + for (uint i = 0; i < count; ++i) { + if (!primitiveRestartEnabled || static_cast<int>(indices[i]) != primitiveRestartIndex) { + const uint n = stride * indices[i]; + visit(i, coordinates[n], coordinates[n + 1], coordinates[n + 2], coordinates[n + 3]); + } + } + } +}; + +typedef BufferVisitor<float, Qt3DCore::QAttribute::Float, 3> Buffer3fVisitor; + +} // namespace Qt3DCore + +QT_END_NAMESPACE + + +#endif // QT3DCORE_BUFFERVISITOR_P_H diff --git a/src/core/geometry/geometry.pri b/src/core/geometry/geometry.pri index eadf7ca0b..70bda07ed 100644 --- a/src/core/geometry/geometry.pri +++ b/src/core/geometry/geometry.pri @@ -12,7 +12,9 @@ HEADERS += \ $$PWD/qgeometry.h \ $$PWD/qgeometryfactory_p.h \ $$PWD/qgeometryview_p.h \ - $$PWD/qgeometryview.h + $$PWD/qgeometryview.h \ + $$PWD/bufferutils_p.h \ + $$PWD/buffervisitor_p.h SOURCES += \ $$PWD/qabstractfunctor.cpp \ diff --git a/src/core/geometry/qgeometry_p.h b/src/core/geometry/qgeometry_p.h index 2a05b5b6f..ed13b3feb 100644 --- a/src/core/geometry/qgeometry_p.h +++ b/src/core/geometry/qgeometry_p.h @@ -72,7 +72,6 @@ public: void setScene(QScene *scene) override; void update() override; void setExtent(const QVector3D &minExtent, const QVector3D &maxExtent); - static QGeometryPrivate *get(QGeometry *q); QVector<QAttribute *> m_attributes; diff --git a/src/core/geometry/qgeometryview.cpp b/src/core/geometry/qgeometryview.cpp index 65e30d982..258448ba4 100644 --- a/src/core/geometry/qgeometryview.cpp +++ b/src/core/geometry/qgeometryview.cpp @@ -39,11 +39,250 @@ #include "qgeometryview.h" #include "qgeometryview_p.h" +#include "qgeometry_p.h" +#include "buffervisitor_p.h" + +#include <Qt3DCore/QAttribute> +#include <Qt3DCore/QBuffer> +#include <Qt3DCore/private/vector3d_p.h> QT_BEGIN_NAMESPACE using namespace Qt3DCore; +namespace { + +class FindExtremePoints : public Buffer3fVisitor +{ +public: + FindExtremePoints() + : Buffer3fVisitor() + , xMin(0.0f), xMax(0.0f), yMin(0.0f), yMax(0.0f), zMin(0.0f), zMax(0.0f) + { } + + float xMin, xMax, yMin, yMax, zMin, zMax; + Vector3D xMinPt, xMaxPt, yMinPt, yMaxPt, zMinPt, zMaxPt; + + void visit(uint ndx, float x, float y, float z) override + { + if (ndx) { + if (x < xMin) { + xMin = x; + xMinPt = Vector3D(x, y, z); + } + if (x > xMax) { + xMax = x; + xMaxPt = Vector3D(x, y, z); + } + if (y < yMin) { + yMin = y; + yMinPt = Vector3D(x, y, z); + } + if (y > yMax) { + yMax = y; + yMaxPt = Vector3D(x, y, z); + } + if (z < zMin) { + zMin = z; + zMinPt = Vector3D(x, y, z); + } + if (z > zMax) { + zMax = z; + zMaxPt = Vector3D(x, y, z); + } + } else { + xMin = xMax = x; + yMin = yMax = y; + zMin = zMax = z; + xMinPt = xMaxPt = yMinPt = yMaxPt = zMinPt = zMaxPt = Vector3D(x, y, z); + } + } +}; + +class FindMaxDistantPoint : public Buffer3fVisitor +{ +public: + FindMaxDistantPoint() + : Buffer3fVisitor() + { } + + float maxLengthSquared = 0.0f; + bool setReferencePoint = false; + bool hasNoPoints = true; + Vector3D maxDistPt; + Vector3D referencePt; + + void visit(uint ndx, float x, float y, float z) override + { + Q_UNUSED(ndx) + const Vector3D p = Vector3D(x, y, z); + + if (hasNoPoints && setReferencePoint) { + maxLengthSquared = 0.0f; + referencePt = p; + } + const float lengthSquared = (p - referencePt).lengthSquared(); + if ( lengthSquared >= maxLengthSquared ) { + maxDistPt = p; + maxLengthSquared = lengthSquared; + } + hasNoPoints = false; + } +}; + +std::pair<QVector3D, QVector3D> calculateLocalBoundingVolume(QGeometryView *node) +{ + // The Bounding volume will only be computed if the position Buffer + // isDirty + + if (!node->isEnabled()) + return {}; + + if (node->primitiveType() == QGeometryView::Patches) + return {}; + + QGeometry *geom = node->geometry(); + QGeometryPrivate *dgeom = QGeometryPrivate::get(geom); + + if (!geom) + return {}; + + int drawVertexCount = node->vertexCount(); // may be 0, gets changed below if so + + QAttribute *positionAttribute = dgeom->m_boundingVolumePositionAttribute; + const QVector<Qt3DCore::QAttribute *> attributes = geom->attributes(); + + // Use the default position attribute if attribute is null + if (!positionAttribute) { + for (QAttribute *attr : attributes) { + if (attr->name() == QAttribute::defaultPositionAttributeName()) { + positionAttribute = attr; + break; + } + } + } + + if (!positionAttribute + || positionAttribute->attributeType() != QAttribute::VertexAttribute + || positionAttribute->vertexBaseType() != QAttribute::Float + || positionAttribute->vertexSize() < 3) { + qWarning("calculateLocalBoundingVolume: Position attribute not suited for bounding volume computation"); + return {}; + } + + Qt3DCore::QBuffer *buf = positionAttribute->buffer(); + // No point in continuing if the positionAttribute doesn't have a suitable buffer + if (!buf) { + qWarning("calculateLocalBoundingVolume: Position attribute not referencing a valid buffer"); + return {}; + } + + // Check if there is an index attribute. + QAttribute *indexAttribute = nullptr; + Qt3DCore::QBuffer *indexBuf = nullptr; + + for (const auto attr : attributes) { + if (attr->attributeType() == QAttribute::IndexAttribute) { + indexBuf = attr->buffer(); + if (indexBuf) { + indexAttribute = attr; + + if (!drawVertexCount) + drawVertexCount = static_cast<int>(indexAttribute->count()); + + static const QAttribute::VertexBaseType validIndexTypes[] = { + QAttribute::UnsignedShort, + QAttribute::UnsignedInt, + QAttribute::UnsignedByte + }; + + if (std::find(std::begin(validIndexTypes), + std::end(validIndexTypes), + indexAttribute->vertexBaseType()) == std::end(validIndexTypes)) { + qWarning() << "calculateLocalBoundingVolume: Unsupported index attribute type" << indexAttribute->name() << indexAttribute->vertexBaseType(); + return {}; + } + + break; + } + } + } + + if (!indexAttribute && !drawVertexCount) + drawVertexCount = static_cast<int>(positionAttribute->count()); + + // Buf will be set to not dirty once it's loaded + // in a job executed after this one + // We need to recompute the bounding volume + // If anything in the GeometryRenderer has changed + BoundingVolumeCalculator reader; + if (reader.apply(positionAttribute, indexAttribute, drawVertexCount, + node->primitiveRestartEnabled(), node->restartIndexValue())) + return {reader.min(), reader.max()}; + + return {}; +} + +} + + +bool BoundingVolumeCalculator::apply(QAttribute *positionAttribute, + QAttribute *indexAttribute, + int drawVertexCount, + bool primitiveRestartEnabled, + int primitiveRestartIndex) +{ + m_radius = -1.f; + + FindExtremePoints findExtremePoints; + if (!findExtremePoints.apply(positionAttribute, indexAttribute, drawVertexCount, + primitiveRestartEnabled, primitiveRestartIndex)) { + return false; + } + + m_min = QVector3D(findExtremePoints.xMin, findExtremePoints.yMin, findExtremePoints.zMin); + m_max = QVector3D(findExtremePoints.xMax, findExtremePoints.yMax, findExtremePoints.zMax); + + FindMaxDistantPoint maxDistantPointY; + maxDistantPointY.setReferencePoint = true; + if (!maxDistantPointY.apply(positionAttribute, indexAttribute, drawVertexCount, + primitiveRestartEnabled, primitiveRestartIndex)) { + return false; + } + if (maxDistantPointY.hasNoPoints) + return false; + + //const Vector3D x = maxDistantPointY.referencePt; + const Vector3D y = maxDistantPointY.maxDistPt; + + FindMaxDistantPoint maxDistantPointZ; + maxDistantPointZ.setReferencePoint = false; + maxDistantPointZ.referencePt = y; + if (!maxDistantPointZ.apply(positionAttribute, indexAttribute, drawVertexCount, + primitiveRestartEnabled, primitiveRestartIndex)) + return false; + const Vector3D z = maxDistantPointZ.maxDistPt; + const Vector3D center = (y + z) * .5f; + + FindMaxDistantPoint maxDistantPointCenter; + maxDistantPointCenter.setReferencePoint = false; + maxDistantPointCenter.referencePt = center; + if (!maxDistantPointCenter.apply(positionAttribute, indexAttribute, drawVertexCount, + primitiveRestartEnabled, primitiveRestartIndex)) + return false; + + const float radius = (center - maxDistantPointCenter.maxDistPt).length(); + + if (center == Vector3D{} || radius < 0.f) + return false; + + m_radius = radius; + m_center = QVector3D{ center.x(), center.y(), center.z() }; + + return true; +} + + QGeometryViewPrivate::QGeometryViewPrivate() : QNodePrivate() , m_instanceCount(1) @@ -65,6 +304,11 @@ QGeometryViewPrivate::~QGeometryViewPrivate() { } +QGeometryViewPrivate *QGeometryViewPrivate::get(QGeometryView *q) +{ + return q->d_func(); +} + void QGeometryViewPrivate::update() { if (!m_blockNotifications) diff --git a/src/core/geometry/qgeometryview_p.h b/src/core/geometry/qgeometryview_p.h index f806c4d69..05dea1d0e 100644 --- a/src/core/geometry/qgeometryview_p.h +++ b/src/core/geometry/qgeometryview_p.h @@ -55,6 +55,8 @@ #include <Qt3DCore/qgeometryview.h> #include <Qt3DCore/private/qgeometryfactory_p.h> #include <Qt3DCore/private/qt3dcore_global_p.h> + +#include <QtGui/qvector3d.h> #include <memory> QT_BEGIN_NAMESPACE @@ -67,6 +69,8 @@ public: QGeometryViewPrivate(); ~QGeometryViewPrivate(); + static QGeometryViewPrivate *get(QGeometryView *q); + void update() override; Q_DECLARE_PUBLIC(QGeometryView) @@ -85,6 +89,30 @@ public: bool m_dirty; }; +class BoundingVolumeCalculator +{ +public: + BoundingVolumeCalculator() = default; + + const QVector3D min() const { return m_min; } + const QVector3D max() const { return m_max; } + const QVector3D center() const { return m_center; } + float radius() const { return m_radius; } + bool isValid() const { return m_radius >= 0.f; } + + bool apply(QAttribute *positionAttribute, + QAttribute *indexAttribute, + int drawVertexCount, + bool primitiveRestartEnabled, + int primitiveRestartIndex); + +private: + QVector3D m_min; + QVector3D m_max; + QVector3D m_center; + float m_radius = -1.f; +}; + } // namespace Qt3DCore QT_END_NAMESPACE diff --git a/src/core/jobs/calcboundingvolumejob.cpp b/src/core/jobs/calcboundingvolumejob.cpp new file mode 100644 index 000000000..37ee92e84 --- /dev/null +++ b/src/core/jobs/calcboundingvolumejob.cpp @@ -0,0 +1,317 @@ +/**************************************************************************** +** +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "calcboundingvolumejob_p.h" + +#include <Qt3DCore/qattribute.h> +#include <Qt3DCore/qboundingvolume.h> +#include <Qt3DCore/qbuffer.h> +#include <Qt3DCore/qgeometryview.h> +#include <Qt3DCore/private/job_common_p.h> +#include <Qt3DCore/private/qaspectjob_p.h> +#include <Qt3DCore/private/qaspectmanager_p.h> +#include <Qt3DCore/private/qattribute_p.h> +#include <Qt3DCore/private/qboundingvolume_p.h> +#include <Qt3DCore/private/qbuffer_p.h> +#include <Qt3DCore/private/qentity_p.h> +#include <Qt3DCore/private/qgeometry_p.h> +#include <Qt3DCore/private/qgeometryview_p.h> +#include <Qt3DCore/private/qnodevisitor_p.h> + +#include <QtCore/qmath.h> +#if QT_CONFIG(concurrent) +#include <QtConcurrent/QtConcurrent> +#endif + +QT_BEGIN_NAMESPACE + +namespace Qt3DCore { + +namespace { + +BoundingVolumeComputeData findBoundingVolumeComputeData(QGeometryView *node) +{ + if (!node->isEnabled()) + return {}; + + if (node->primitiveType() == QGeometryView::Patches) + return {}; + + QGeometry *geom = node->geometry(); + QGeometryPrivate *dgeom = QGeometryPrivate::get(geom); + if (!geom) + return {}; + + int drawVertexCount = node->vertexCount(); // may be 0, gets changed below if so + + QAttribute *positionAttribute = dgeom->m_boundingVolumePositionAttribute; + const QVector<Qt3DCore::QAttribute *> attributes = geom->attributes(); + + // Use the default position attribute if attribute is null + if (!positionAttribute) { + for (QAttribute *attr : attributes) { + if (attr->name() == QAttribute::defaultPositionAttributeName()) { + positionAttribute = attr; + break; + } + } + } + + if (!positionAttribute + || positionAttribute->attributeType() != QAttribute::VertexAttribute + || positionAttribute->vertexBaseType() != QAttribute::Float + || positionAttribute->vertexSize() < 3) { + qWarning("findBoundingVolumeComputeData: Position attribute not suited for bounding volume computation"); + return {}; + } + + Qt3DCore::QBuffer *positionBuffer = positionAttribute->buffer(); + // No point in continuing if the positionAttribute doesn't have a suitable buffer + if (!positionBuffer) { + qWarning("findBoundingVolumeComputeData: Position attribute not referencing a valid buffer"); + return {}; + } + + // Check if there is an index attribute. + QAttribute *indexAttribute = nullptr; + Qt3DCore::QBuffer *indexBuffer = nullptr; + + for (const auto attr : attributes) { + if (attr->attributeType() == QAttribute::IndexAttribute) { + indexBuffer = attr->buffer(); + if (indexBuffer) { + indexAttribute = attr; + + if (!drawVertexCount) + drawVertexCount = static_cast<int>(indexAttribute->count()); + + static const QAttribute::VertexBaseType validIndexTypes[] = { + QAttribute::UnsignedShort, + QAttribute::UnsignedInt, + QAttribute::UnsignedByte + }; + + if (std::find(std::begin(validIndexTypes), + std::end(validIndexTypes), + indexAttribute->vertexBaseType()) == std::end(validIndexTypes)) { + qWarning() << "findBoundingVolumeComputeData: Unsupported index attribute type" << indexAttribute->name() << indexAttribute->vertexBaseType(); + return {}; + } + + break; + } + } + } + + if (!indexAttribute && !drawVertexCount) + drawVertexCount = static_cast<int>(positionAttribute->count()); + + return { nullptr, nullptr, positionAttribute, indexAttribute, drawVertexCount }; +} + +BoundingVolumeComputeResult calculateLocalBoundingVolume(const BoundingVolumeComputeData &data) { + BoundingVolumeCalculator calculator; + if (calculator.apply(data.positionAttribute, data.indexAttribute, data.vertexCount, + data.provider->view()->primitiveRestartEnabled(), + data.provider->view()->restartIndexValue())) + return { + data.entity, data.provider, data.positionAttribute, data.indexAttribute, + calculator.min(), calculator.max(), + calculator.center(), calculator.radius() + }; + return {}; +} + +bool isTreeEnabled(QEntity *entity) { + if (!entity->isEnabled()) + return false; + + QEntity *parent = entity->parentEntity(); + while (parent) { + if (!parent->isEnabled()) + return false; + parent = parent->parentEntity(); + } + + return true; +} + +struct UpdateBoundFunctor +{ + // This define is required to work with QtConcurrent + typedef QVector<BoundingVolumeComputeResult> result_type; + result_type operator ()(const BoundingVolumeComputeData &data) + { + return { calculateLocalBoundingVolume(data) }; + } +}; + +struct ReduceUpdateBoundFunctor +{ + void operator ()(QVector<BoundingVolumeComputeResult> &result, const QVector<BoundingVolumeComputeResult> &values) + { + result += values; + } +}; + +} // anonymous + +//class CalculateBoundingVolumeJobPrivate : public Qt3DCore::QAspectJobPrivate +//{ +//public: +// CalculateBoundingVolumeJobPrivate() { } +// ~CalculateBoundingVolumeJobPrivate() override { } + +// void postFrame(Qt3DCore::QAspectManager *manager) override +// { +// Q_UNUSED(manager) +//// for (Geometry *backend : qAsConst(m_updatedGeometries)) { +//// Qt3DCore::QGeometry *node = qobject_cast<Qt3DCore::QGeometry *>(manager->lookupNode(backend->peerId())); +//// if (!node) +//// continue; +//// Qt3DCore::QGeometryPrivate *dNode = static_cast<Qt3DCore::QGeometryPrivate *>(Qt3DCore::QNodePrivate::get(node)); +//// dNode->setExtent(backend->min(), backend->max()); +//// } +// } + +//}; + +CalculateBoundingVolumeJob::CalculateBoundingVolumeJob() + : Qt3DCore::QAspectJob() + , m_root(nullptr) +{ + SET_JOB_RUN_STAT_TYPE(this, JobTypes::CalcBoundingVolume, 0) +} + +void CalculateBoundingVolumeJob::run() +{ + m_results.clear(); + + QHash<QEntity *, BoundingVolumeComputeData> dirtyEntities; + QNodeVisitor visitor; + visitor.traverse(m_root, [](QNode *) {}, [&dirtyEntities](QEntity *entity) { + if (!isTreeEnabled(entity)) + return; + + const auto bvProviders = entity->componentsOfType<QBoundingVolume>(); + if (bvProviders.isEmpty()) + return; + + // we go through the list until be find a dirty provider, + // or THE primary provider + bool foundBV = false; + for (auto bv: bvProviders) { + if (!bv->view()) + continue; + auto dbv = QBoundingVolumePrivate::get(bv); + if (foundBV && !dbv->m_primaryProvider) + continue; + + auto bvdata = findBoundingVolumeComputeData(bv->view()); + if (!bvdata.valid()) + continue; + bvdata.entity = entity; + bvdata.provider = bv; + + bool dirty = QEntityPrivate::get(entity)->m_dirty; + dirty |= QGeometryViewPrivate::get(bv->view())->m_dirty; + dirty |= QGeometryPrivate::get(bv->view()->geometry())->m_dirty; + dirty |= QAttributePrivate::get(bvdata.positionAttribute)->m_dirty; + dirty |= QBufferPrivate::get(bvdata.positionAttribute->buffer())->m_dirty; + if (bvdata.indexAttribute) { + dirty |= QAttributePrivate::get(bvdata.indexAttribute)->m_dirty; + dirty |= QBufferPrivate::get(bvdata.indexAttribute->buffer())->m_dirty; + } + + if (dbv->m_primaryProvider) { + if (dirty) + dirtyEntities[entity] = bvdata; + break; + } else if (dirty) { + dirtyEntities[entity] = bvdata; + foundBV = true; + } + } + }); + +#if QT_CONFIG(concurrent) + if (dirtyEntities.size() > 1) { + UpdateBoundFunctor functor; + ReduceUpdateBoundFunctor reduceFunctor; + m_results = QtConcurrent::blockingMappedReduced<decltype(m_results)>(dirtyEntities, functor, reduceFunctor); + } else +#endif + { + for (auto it = dirtyEntities.begin(); it != dirtyEntities.end(); ++it) { + auto res = calculateLocalBoundingVolume(it.value()); + if (res.valid()) + m_results.push_back(res); // How do we push it to the backends???? + } + } + + for (auto result: qAsConst(m_results)) { + // set the results + QBoundingVolumePrivate::get(result.provider)->setImplicitBounds(result.m_min, result.m_max, result.m_center, result.m_radius); + } +} + +void CalculateBoundingVolumeJob::postFrame(QAspectEngine *aspectEngine) +{ + Q_UNUSED(aspectEngine) + + for (auto result: qAsConst(m_results)) { + // reset dirty flags + QEntityPrivate::get(result.entity)->m_dirty = false; + QGeometryViewPrivate::get(result.provider->view())->m_dirty = false; + QGeometryPrivate::get(result.provider->view()->geometry())->m_dirty = false; + QAttributePrivate::get(result.positionAttribute)->m_dirty = false; + QBufferPrivate::get(result.positionAttribute->buffer())->m_dirty = false; + if (result.indexAttribute) { + QAttributePrivate::get(result.indexAttribute)->m_dirty = false; + QBufferPrivate::get(result.indexAttribute->buffer())->m_dirty = false; + } + } + + m_results.clear(); +} + +} // namespace Qt3DCore + +QT_END_NAMESPACE + diff --git a/src/core/jobs/calcboundingvolumejob_p.h b/src/core/jobs/calcboundingvolumejob_p.h new file mode 100644 index 000000000..498fe766f --- /dev/null +++ b/src/core/jobs/calcboundingvolumejob_p.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DCORE_CALCBOUNDINGVOLUMEJOB_H +#define QT3DCORE_CALCBOUNDINGVOLUMEJOB_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DCore/qaspectjob.h> +#include <Qt3DCore/private/qt3dcore_global_p.h> + +#include <QtCore/QSharedPointer> +#include <QtGui/qvector3d.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DCore { + +class CalculateBoundingVolumeJobPrivate; +class QEntity; +class QAttribute; +class QBoundingVolume; + +struct BoundingVolumeComputeData { + QEntity *entity = nullptr; + QBoundingVolume *provider = nullptr; + QAttribute *positionAttribute = nullptr; + QAttribute *indexAttribute = nullptr; + int vertexCount = 0; + + bool valid() const { return positionAttribute != nullptr; } +}; + +struct BoundingVolumeComputeResult { + QEntity *entity = nullptr; + QBoundingVolume *provider = nullptr; + QAttribute *positionAttribute = nullptr; + QAttribute *indexAttribute = nullptr; + QVector3D m_min; + QVector3D m_max; + QVector3D m_center; + float m_radius = -1.f; + + bool valid() const { return m_radius >= 0.f; } +}; + +class Q_3DCORE_PRIVATE_EXPORT CalculateBoundingVolumeJob : public Qt3DCore::QAspectJob +{ +public: + explicit CalculateBoundingVolumeJob(); + + void setRoot(QEntity *root) { m_root = root; } + void run() override; + void postFrame(QAspectEngine *aspectEngine) override; + +private: + Q_DECLARE_PRIVATE(CalculateBoundingVolumeJob) + QEntity *m_root; + QVector<BoundingVolumeComputeResult> m_results; +}; + +typedef QSharedPointer<CalculateBoundingVolumeJob> CalculateBoundingVolumeJobPtr; + +} // namespace Qt3DCore + +QT_END_NAMESPACE + +#endif // QT3DCORE_CALCBOUNDINGVOLUMEJOB_H diff --git a/src/core/jobs/job_common_p.h b/src/core/jobs/job_common_p.h new file mode 100644 index 000000000..6cbf17800 --- /dev/null +++ b/src/core/jobs/job_common_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DCORE_JOB_COMMON_P_H +#define QT3DCORE_JOB_COMMON_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DCore/private/qaspectjob_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DCore { + +namespace JobTypes { + + enum JobType { + LoadBuffer = 4096, + CalcBoundingVolume, + }; + +} // JobTypes + +} // Qt3DCore + +QT_END_NAMESPACE + +#endif // QT3DCORE_JOB_COMMON_P_H diff --git a/src/core/jobs/jobs.pri b/src/core/jobs/jobs.pri index 5d262f5c7..a0453395c 100644 --- a/src/core/jobs/jobs.pri +++ b/src/core/jobs/jobs.pri @@ -4,7 +4,8 @@ SOURCES += \ $$PWD/qaspectjobmanager.cpp \ $$PWD/qabstractaspectjobmanager.cpp \ $$PWD/qthreadpooler.cpp \ - $$PWD/task.cpp + $$PWD/task.cpp \ + $$PWD/calcboundingvolumejob.cpp HEADERS += \ $$PWD/qaspectjob.h \ @@ -13,7 +14,9 @@ HEADERS += \ $$PWD/qaspectjobmanager_p.h \ $$PWD/qabstractaspectjobmanager_p.h \ $$PWD/task_p.h \ - $$PWD/qthreadpooler_p.h + $$PWD/qthreadpooler_p.h \ + $$PWD/calcboundingvolumejob_p.h \ + $$PWD/job_common_p.h INCLUDEPATH += $$PWD |