12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481 |
- If an entity uses a QBoundingVolume and a QGeometryView, compute
- the bounding volume data in the core aspect. All other cases will
- still happen in the render aspect.
- Result not currently used (ie it's done again in render aspect).
- Change-Id: I4b5ed21bac42b79777c3112aa76d876ac5b6f52d
- Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
- 14 files changed:
- src/core/aspect/qcoreaspect.cpp patch | blob | history
- src/core/aspect/qcoreaspect.h patch | blob | history
- src/core/aspect/qcoreaspect_p.h patch | blob | history
- src/core/core.pro patch | blob | history
- src/core/geometry/bufferutils_p.h [new file with mode: 0644] patch | blob
- src/core/geometry/buffervisitor_p.h [new file with mode: 0644] patch | blob
- src/core/geometry/geometry.pri patch | blob | history
- src/core/geometry/qgeometry_p.h patch | blob | history
- src/core/geometry/qgeometryview.cpp patch | blob | history
- src/core/geometry/qgeometryview_p.h patch | blob | history
- src/core/jobs/calcboundingvolumejob.cpp [new file with mode: 0644] patch | blob
- src/core/jobs/calcboundingvolumejob_p.h [new file with mode: 0644] patch | blob
- src/core/jobs/job_common_p.h [new file with mode: 0644] patch | blob
- src/core/jobs/jobs.pri patch | blob | history
- diff --git a/src/core/aspect/qcoreaspect.cpp b/src/core/aspect/qcoreaspect.cpp
- index 48f9aaf..dc3566e 100644 (file)
- --- 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 27c72f4..071b738 100644 (file)
- --- 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 ca665fa..cda0a14 100644 (file)
- --- 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 b149497..846e9d8 100644 (file)
- --- 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 (file)
- index 0000000..1b83d99
- --- /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 (file)
- index 0000000..69cfb9b
- --- /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 eadf7ca..70bda07 100644 (file)
- --- 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 2a05b5b..ed13b3f 100644 (file)
- --- 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 65e30d9..258448b 100644 (file)
- --- 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 f806c4d..05dea1d 100644 (file)
- --- 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 (file)
- index 0000000..37ee92e
- --- /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 (file)
- index 0000000..498fe76
- --- /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 (file)
- index 0000000..6cbf178
- --- /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 5d262f5..a045339 100644 (file)
- --- 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
|