summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2017-05-21 08:26:29 +0100
committerSean Harmer <sean.harmer@kdab.com>2017-05-21 08:26:29 +0100
commit9f8fc3717508a6b8045f65e6c820692fb67dc450 (patch)
treead426afcaa91f61ecd669fbc416838f108554771 /src
parenta830a9365832fd52c1849768543a64c55e4cee0a (diff)
parentcd9059a22604307f483764db134d51b15c540758 (diff)
Merge branch '5.9' into dev
Conflicts: .qmake.conf src/core/qscene.cpp src/plugins/sceneparsers/gltf/gltfimporter.cpp src/plugins/sceneparsers/gltfexport/gltfexporter.cpp src/render/texture/gltexture.cpp Change-Id: I7bde0fc0177eae252fef01cc43725fcf69c13a80
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/assimp/qt_attribution.json1
-rw-r--r--src/animation/backend/animationclip_p.h2
-rw-r--r--src/animation/backend/animationutils.cpp2
-rw-r--r--src/animation/backend/buildblendtreesjob.cpp2
-rw-r--r--src/animation/backend/fcurve_p.h2
-rw-r--r--src/animation/frontend/qabstractclipanimator.cpp112
-rw-r--r--src/animation/frontend/qabstractclipanimator.h3
-rw-r--r--src/animation/frontend/qabstractclipblendnode.cpp71
-rw-r--r--src/animation/frontend/qadditiveclipblend.cpp123
-rw-r--r--src/animation/frontend/qanimationcontroller.cpp4
-rw-r--r--src/animation/frontend/qanimationgroup.cpp2
-rw-r--r--src/animation/frontend/qblendedclipanimator.cpp208
-rw-r--r--src/animation/frontend/qclipanimator.cpp62
-rw-r--r--src/animation/frontend/qkeyframeanimation.cpp4
-rw-r--r--src/animation/frontend/qmorphinganimation.cpp2
-rw-r--r--src/animation/frontend/qmorphtarget.cpp4
-rw-r--r--src/animation/frontend/qvertexblendanimation.cpp6
-rw-r--r--src/core/aspects/qaspectengine.cpp2
-rw-r--r--src/core/configure.json2
-rw-r--r--src/core/nodes/qbackendnode.cpp2
-rw-r--r--src/core/nodes/qnode.cpp18
-rw-r--r--src/core/services/qabstractframeadvanceservice_p.h1
-rw-r--r--src/core/services/qeventfilterservice_p.h1
-rw-r--r--src/core/services/qopenglinformationservice_p.h1
-rw-r--r--src/core/services/qsysteminformationservice_p.h1
-rw-r--r--src/core/services/qtickclockservice_p.h1
-rw-r--r--src/doc/qt3d.qdocconf11
-rw-r--r--src/doc/src/levelofdetailloader.qdoc2
-rw-r--r--src/extras/defaults/defaults.pri1
-rw-r--r--src/extras/defaults/qskyboxentity.cpp2
-rw-r--r--src/extras/defaults/qt3dwindow.cpp80
-rw-r--r--src/extras/defaults/qt3dwindow.h25
-rw-r--r--src/extras/defaults/qt3dwindow_p.h92
-rw-r--r--src/extras/geometries/qplanegeometry.cpp47
-rw-r--r--src/extras/geometries/qplanegeometry.h4
-rw-r--r--src/extras/geometries/qplanegeometry_p.h1
-rw-r--r--src/extras/geometries/qplanemesh.cpp24
-rw-r--r--src/extras/geometries/qplanemesh.h4
-rw-r--r--src/extras/shaders/es2/light.inc.frag310
-rw-r--r--src/extras/shaders/gl3/metalrough.frag112
-rw-r--r--src/extras/shaders/gl3/metalroughuniform.frag123
-rw-r--r--src/extras/text/qdistancefieldglyphcache.cpp4
-rw-r--r--src/input/backend/inputhandler.cpp20
-rw-r--r--src/input/backend/inputhandler_p.h4
-rw-r--r--src/input/backend/mousedevice.cpp2
-rw-r--r--src/input/backend/mousedevice_p.h2
-rw-r--r--src/input/backend/mouseeventdispatcherjob.cpp11
-rw-r--r--src/input/backend/mouseeventdispatcherjob_p.h9
-rw-r--r--src/input/backend/mouseeventfilter.cpp2
-rw-r--r--src/input/backend/mousehandler.cpp2
-rw-r--r--src/input/backend/mousehandler_p.h2
-rw-r--r--src/input/frontend/qinputdeviceintegrationfactory.cpp5
-rw-r--r--src/input/frontend/qkeyevent.h2
-rw-r--r--src/input/frontend/qmouseevent.cpp2
-rw-r--r--src/input/frontend/qmouseevent.h13
-rw-r--r--src/input/frontend/qmousehandler.cpp4
-rw-r--r--src/input/frontend/qmousehandler.h2
-rw-r--r--src/logic/executor.cpp2
-rw-r--r--src/plugins/geometryloaders/default/objgeometryloader.cpp4
-rw-r--r--src/plugins/geometryloaders/geometryloaders.pro2
-rw-r--r--src/plugins/sceneparsers/assimp/assimpimporter.cpp58
-rw-r--r--src/plugins/sceneparsers/assimp/assimpimporter.h1
-rw-r--r--src/plugins/sceneparsers/gltf/gltfimporter.cpp2
-rw-r--r--src/plugins/sceneparsers/gltfexport/gltfexporter.cpp43
-rw-r--r--src/plugins/sceneparsers/sceneparsers.pro10
-rw-r--r--src/quick3d/imports/animation/plugins.qmltypes670
-rw-r--r--src/quick3d/imports/animation/qt3dquick3danimationplugin.cpp3
-rw-r--r--src/quick3d/imports/core/plugins.qmltypes82
-rw-r--r--src/quick3d/imports/core/qt3dquick3dcoreplugin.cpp5
-rw-r--r--src/quick3d/imports/core/qt3dquick3dcoreplugin.h1
-rw-r--r--src/quick3d/imports/extras/plugins.qmltypes394
-rw-r--r--src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp2
-rw-r--r--src/quick3d/imports/input/plugins.qmltypes86
-rw-r--r--src/quick3d/imports/input/qt3dquick3dinputplugin.cpp2
-rw-r--r--src/quick3d/imports/logic/plugins.qmltypes27
-rw-r--r--src/quick3d/imports/render/plugins.qmltypes438
-rw-r--r--src/quick3d/imports/scene3d/scene3ditem.cpp2
-rw-r--r--src/quick3d/imports/scene3d/scene3ditem_p.h2
-rw-r--r--src/quick3d/imports/scene3d/scene3drenderer.cpp18
-rw-r--r--src/quick3d/quick3d/qt3dquick_global.cpp7
-rw-r--r--src/quick3d/quick3d/qt3dquick_global_p.h1
-rw-r--r--src/quick3d/quick3danimation/items/items.pri6
-rw-r--r--src/quick3d/quick3danimation/items/quick3dvertexblendanimation.cpp104
-rw-r--r--src/quick3d/quick3danimation/items/quick3dvertexblendanimation_p.h93
-rw-r--r--src/quick3d/quick3dextras/qt3dquickwindow.cpp80
-rw-r--r--src/quick3d/quick3dextras/qt3dquickwindow.h14
-rw-r--r--src/quick3d/quick3dextras/qt3dquickwindow_p.h86
-rw-r--r--src/quick3d/quick3dextras/quick3dextras.pro1
-rw-r--r--src/quick3d/quick3dscene2d/items/qscene2d.cpp203
-rw-r--r--src/quick3d/quick3dscene2d/items/qscene2d.h22
-rw-r--r--src/quick3d/quick3dscene2d/items/qscene2d_p.h7
-rw-r--r--src/quick3d/quick3dscene2d/items/scene2d.cpp108
-rw-r--r--src/quick3d/quick3dscene2d/items/scene2d_p.h2
-rw-r--r--src/quick3d/quick3dscene2d/items/scene2dmanager.cpp141
-rw-r--r--src/quick3d/quick3dscene2d/items/scene2dmanager_p.h15
-rw-r--r--src/render/backend/platformsurfacefilter.cpp4
-rw-r--r--src/render/backend/renderer.cpp150
-rw-r--r--src/render/backend/renderer_p.h4
-rw-r--r--src/render/backend/renderqueue.cpp6
-rw-r--r--src/render/backend/renderqueue_p.h4
-rw-r--r--src/render/backend/renderviewbuilder.cpp28
-rw-r--r--src/render/framegraph/framegraphvisitor.cpp26
-rw-r--r--src/render/framegraph/framegraphvisitor_p.h14
-rw-r--r--src/render/framegraph/qsortcriterion.cpp82
-rw-r--r--src/render/framegraph/qsortcriterion.h85
-rw-r--r--src/render/framegraph/rendercapture.cpp2
-rw-r--r--src/render/framegraph/viewportnode.cpp2
-rw-r--r--src/render/frontend/qabstractfunctor.h8
-rw-r--r--src/render/frontend/qlevelofdetail.cpp33
-rw-r--r--src/render/frontend/qlevelofdetailswitch.cpp8
-rw-r--r--src/render/frontend/qrenderaspect.cpp4
-rw-r--r--src/render/geometry/attribute.cpp2
-rw-r--r--src/render/geometry/buffer.cpp25
-rw-r--r--src/render/geometry/buffer_p.h1
-rw-r--r--src/render/geometry/geometryrenderer.cpp2
-rw-r--r--src/render/graphicshelpers/graphicscontext.cpp50
-rw-r--r--src/render/jobs/pickboundingvolumejob.cpp6
-rw-r--r--src/render/materialsystem/qeffect.cpp60
-rw-r--r--src/render/materialsystem/qmaterial.cpp102
-rw-r--r--src/render/materialsystem/qparameter.cpp127
-rw-r--r--src/render/materialsystem/qrenderpass.cpp89
-rw-r--r--src/render/materialsystem/qtechnique.cpp128
-rw-r--r--src/render/materialsystem/shader.cpp12
-rw-r--r--src/render/raycasting/qabstractcollisionqueryservice_p.h1
-rw-r--r--src/render/texture/apitexturemanager_p.h2
-rw-r--r--src/render/texture/gltexture.cpp12
-rw-r--r--src/render/texture/texture.cpp10
-rw-r--r--src/render/texture/texture_p.h1
-rw-r--r--src/src.pro160
129 files changed, 4057 insertions, 1500 deletions
diff --git a/src/3rdparty/assimp/qt_attribution.json b/src/3rdparty/assimp/qt_attribution.json
index 79f23979e..564058dc4 100644
--- a/src/3rdparty/assimp/qt_attribution.json
+++ b/src/3rdparty/assimp/qt_attribution.json
@@ -6,6 +6,7 @@
"QtUsage": "Used in Qt 3D.",
"Homepage": "http://www.assimp.org/",
+ "Version": "3.3.1",
"License": "BSD 3-clause \"New\" or \"Revised\" Licensee",
"LicenseId": "BSD-3-Clause",
"LicenseFile": "LICENSE",
diff --git a/src/animation/backend/animationclip_p.h b/src/animation/backend/animationclip_p.h
index 286ec38c0..7ff79c01a 100644
--- a/src/animation/backend/animationclip_p.h
+++ b/src/animation/backend/animationclip_p.h
@@ -127,7 +127,7 @@ inline QDebug operator<<(QDebug dbg, const AnimationClip &animationClip)
<< "Channels:" << endl;
const QVector<Channel> channels = animationClip.channels();
- for (const auto channel : channels) {
+ for (const auto &channel : channels) {
dbg << channel;
}
diff --git a/src/animation/backend/animationutils.cpp b/src/animation/backend/animationutils.cpp
index c9c7c29d4..1f675f271 100644
--- a/src/animation/backend/animationutils.cpp
+++ b/src/animation/backend/animationutils.cpp
@@ -197,7 +197,7 @@ ClipResults evaluateClipAtLocalTime(AnimationClip *clip, float localTime)
const QVector<Channel> &channels = clip->channels();
int i = 0;
for (const Channel &channel : channels) {
- for (const auto channelComponent : qAsConst(channel.channelComponents))
+ for (const auto &channelComponent : qAsConst(channel.channelComponents))
channelResults[i++] = channelComponent.fcurve.evaluateAtTime(localTime);
}
return channelResults;
diff --git a/src/animation/backend/buildblendtreesjob.cpp b/src/animation/backend/buildblendtreesjob.cpp
index ac95808bc..fe56099a2 100644
--- a/src/animation/backend/buildblendtreesjob.cpp
+++ b/src/animation/backend/buildblendtreesjob.cpp
@@ -63,7 +63,7 @@ void BuildBlendTreesJob::setBlendedClipAnimators(const QVector<HBlendedClipAnima
// We assume that the structure of blend node tree does not change once a BlendClipAnimator has been set to running
void BuildBlendTreesJob::run()
{
- for (const HBlendedClipAnimator blendedClipAnimatorHandle : m_blendedClipAnimatorHandles) {
+ for (const HBlendedClipAnimator blendedClipAnimatorHandle : qAsConst(m_blendedClipAnimatorHandles)) {
// Retrieve BlendTree node
BlendedClipAnimator *blendClipAnimator = m_handler->blendedClipAnimatorManager()->data(blendedClipAnimatorHandle);
Q_ASSERT(blendClipAnimator);
diff --git a/src/animation/backend/fcurve_p.h b/src/animation/backend/fcurve_p.h
index 7bc6ccccb..7ab1593d1 100644
--- a/src/animation/backend/fcurve_p.h
+++ b/src/animation/backend/fcurve_p.h
@@ -146,7 +146,7 @@ inline QDebug operator<<(QDebug dbg, const Channel &channel)
dbg << "Channel Name: " << channel.name << endl
<< "Channels:" << channel.channelComponents.size() << endl;
- for (const auto channelComponent : qAsConst(channel.channelComponents)) {
+ for (const auto &channelComponent : qAsConst(channel.channelComponents)) {
dbg << channelComponent;
}
return dbg;
diff --git a/src/animation/frontend/qabstractclipanimator.cpp b/src/animation/frontend/qabstractclipanimator.cpp
index 307f2d2f3..0d215b470 100644
--- a/src/animation/frontend/qabstractclipanimator.cpp
+++ b/src/animation/frontend/qabstractclipanimator.cpp
@@ -53,6 +53,57 @@ QAbstractClipAnimatorPrivate::QAbstractClipAnimatorPrivate()
{
}
+/*!
+ \qmltype AbsractClipAnimator
+ \instantiates Qt3DAnimation::QAbstractClipAnimator
+ \inqmlmodule Qt3D.Animation
+ \since 5.9
+
+ \brief AbstractClipAnimator is the base class for types providing animation playback
+ capabilities.
+
+ Subclasses of AbstractClipAnimator can be aggregated by an Entity to
+ provide animation capabilities. The animator components provide an
+ interface for controlling the animation (e.g. start, stop). Each animator
+ type requires some form of animation data such as an AbstractAnimationClip
+ as well as a ChannelMapper which describes how the channels in the
+ animation clip should be mapped onto the properties of the objects you wish
+ to animate.
+
+ The following subclasses are available:
+
+ \list
+ \li Qt3D.Animation.ClipAnimator
+ \li Qt3D.Animation.BlendedClipAnimator
+ \endlist
+*/
+
+/*!
+ \class Qt3DAnimation::QAbstractClipAnimator
+ \inherits Qt3DCore::QComponent
+
+ \inmodule Qt3DAnimation
+ \since 5.9
+
+ \brief QAbstractClipAnimator is the base class for types providing animation playback
+ capabilities.
+
+ Subclasses of QAbstractClipAnimator can be aggregated by a QEntity to
+ provide animation capabilities. The animator components provide an
+ interface for controlling the animation (e.g. start, stop). Each animator
+ type requires some form of animation data such as a QAbstractAnimationClip
+ as well as a QChannelMapper which describes how the channels in the
+ animation clip should be mapped onto the properties of the objects you wish
+ to animate.
+
+ The following subclasses are available:
+
+ \list
+ \li Qt3DAnimation::QClipAnimator
+ \li Qt3DAnimation::QBlendedClipAnimator
+ \endlist
+*/
+
QAbstractClipAnimator::QAbstractClipAnimator(Qt3DCore::QNode *parent)
: Qt3DCore::QComponent(*new QAbstractClipAnimatorPrivate, parent)
{
@@ -67,18 +118,63 @@ QAbstractClipAnimator::~QAbstractClipAnimator()
{
}
+/*!
+ \qmlproperty bool running
+
+ This property holds whether the animation is currently running.
+*/
+
+/*!
+ \property running
+
+ This property holds whether the animation is currently running.
+*/
bool QAbstractClipAnimator::isRunning() const
{
Q_D(const QAbstractClipAnimator);
return d->m_running;
}
+/*!
+ \property ChannelMapper channelMapper
+
+ This property holds the ChannelMapper that controls how the channels in
+ the animation clip map onto the properties of the target objects.
+*/
+
+/*!
+ \property channelMapper
+
+ This property holds the QChannelMapper that controls how the channels in
+ the animation clip map onto the properties of the target objects.
+*/
QChannelMapper *QAbstractClipAnimator::channelMapper() const
{
Q_D(const QAbstractClipAnimator);
return d->m_mapper;
}
+/*!
+ \qmlproperty int loops
+
+ This property holds the number of times the animation should play.
+
+ By default, loops is 1: the animation will play through once and then stop.
+
+ If set to QAbstractClipAnimator::Infinite, the animation will continuously
+ repeat until it is explicitly stopped.
+*/
+
+/*!
+ \property loops
+
+ This property holds the number of times the animation should play.
+
+ By default, loops is 1: the animation will play through once and then stop.
+
+ If set to QAbstractClipAnimator::Infinite, the animation will continuously
+ repeat until it is explicitly stopped.
+*/
int QAbstractClipAnimator::loopCount() const
{
Q_D(const QAbstractClipAnimator);
@@ -124,6 +220,22 @@ void QAbstractClipAnimator::setLoopCount(int loops)
emit loopCountChanged(loops);
}
+/*!
+ Starts the animation.
+*/
+void QAbstractClipAnimator::start()
+{
+ setRunning(true);
+}
+
+/*!
+ Stops the animation.
+*/
+void QAbstractClipAnimator::stop()
+{
+ setRunning(false);
+}
+
} // namespace Qt3DAnimation
QT_END_NAMESPACE
diff --git a/src/animation/frontend/qabstractclipanimator.h b/src/animation/frontend/qabstractclipanimator.h
index 805fcb2b3..bd38fd68b 100644
--- a/src/animation/frontend/qabstractclipanimator.h
+++ b/src/animation/frontend/qabstractclipanimator.h
@@ -73,6 +73,9 @@ public Q_SLOTS:
void setChannelMapper(Qt3DAnimation::QChannelMapper *channelMapper);
void setLoopCount(int loops);
+ void start();
+ void stop();
+
Q_SIGNALS:
void runningChanged(bool running);
void channelMapperChanged(Qt3DAnimation::QChannelMapper *channelMapper);
diff --git a/src/animation/frontend/qabstractclipblendnode.cpp b/src/animation/frontend/qabstractclipblendnode.cpp
index 9cc6f3de6..9860e969f 100644
--- a/src/animation/frontend/qabstractclipblendnode.cpp
+++ b/src/animation/frontend/qabstractclipblendnode.cpp
@@ -46,11 +46,82 @@ QAbstractClipBlendNodePrivate::QAbstractClipBlendNodePrivate()
{
}
+/*!
+ \qmltype AbstractClipBlendNode
+ \instantiates Qt3DAnimation::QAbstractClipBlendNode
+ \inqmlmodule Qt3D.Animation
+ \since 5.9
+
+ \brief AbstractClipBlendNode is the base class for types used to construct animation blend
+ trees.
+
+ Animation blend trees are used with a BlendedClipAnimator to dynamically blend a set of
+ animation clips together. The way in which the blending of animation clips is performed is
+ controlled by the structure of the blend tree and the properties on the nodes it contains.
+
+ The leaf nodes in a blend tree are containers for the input animation clips. These clips can be
+ baked clips read from file via AnimationClipLoader, or they can be clips that you build within
+ your application with AnimatitonClip and AnimationClipData. To include a clip in your blend
+ tree, wrap it in a ClipBlendValue node.
+
+ The interior nodes of a blend tree represent blending operations that will be applied to their
+ arguments which hold the input clips or even entire sub-trees of other blend tree nodes.
+
+ At present, the Qt 3D Animation module provides the following blend tree node types:
+
+ \list
+ \li Qt3D.Animation.ClipBlendValue
+ \li Qt3D.Animation.LerpClipBlend
+ \li Qt3D.Animation.QAdditiveClipBlend
+ \endlist
+
+ Additional node types representing other blending operations will be added in the future.
+
+ \sa BlendedClipAnimator
+*/
+
+/*!
+ \class Qt3DAnimation::QAbstractClipBlendNode
+ \inherits Qt3DCore::QNode
+
+ \inmodule Qt3DAnimation
+ \since 5.9
+
+ \brief QAbstractClipBlendNode is the base class for types used to construct animation blend
+ trees.
+
+ Animation blend trees are used with a QBlendedClipAnimator to dynamically blend a set of
+ animation clips together. The way in which the blending of animation clips is performed is
+ controlled by the structure of the blend tree and the properties on the nodes it contains.
+
+ The leaf nodes in a blend tree are containers for the input animation clips. These clips can be
+ baked clips read from file via QAnimationClipLoader, or they can be clips that you build within
+ your application with QAnimatitonClip and QAnimationClipData. To include a clip in your blend
+ tree, wrap it in a QClipBlendValue node.
+
+ The interior nodes of a blend tree represent blending operations that will be applied to their
+ arguments which hold the input clips or even entire sub-trees of other blend tree nodes.
+
+ At present, the Qt 3D Animation module provides the following blend tree node types:
+
+ \list
+ \li Qt3DAnimation::QClipBlendValue
+ \li Qt3DAnimation::QLerpClipBlend
+ \li Qt3DAnimation::QAdditiveClipBlend
+ \endlist
+
+ Additional node types representing other blending operations will be added in the future.
+
+ \sa QBlendedClipAnimator
+*/
+
+/*! \internal */
QAbstractClipBlendNode::QAbstractClipBlendNode(Qt3DCore::QNode *parent)
: Qt3DCore::QNode(*new QAbstractClipBlendNodePrivate(), parent)
{
}
+/*! \internal */
QAbstractClipBlendNode::QAbstractClipBlendNode(QAbstractClipBlendNodePrivate &dd, Qt3DCore::QNode *parent)
: Qt3DCore::QNode(dd, parent)
{
diff --git a/src/animation/frontend/qadditiveclipblend.cpp b/src/animation/frontend/qadditiveclipblend.cpp
index ee207eb42..58ef5e577 100644
--- a/src/animation/frontend/qadditiveclipblend.cpp
+++ b/src/animation/frontend/qadditiveclipblend.cpp
@@ -48,39 +48,67 @@ namespace Qt3DAnimation {
\instantiates Qt3DAnimation::QAdditiveClipBlend
\inqmlmodule Qt3D.Animation
- \brief Performs an addition of two animation clips based on a
- normalized factor
-
\since 5.9
- AdditiveClipBlend can be useful to create advanced animation effects based on
- individual animation clips. For instance, given a player character, additive
- blending could be used to combine a walking animation clip with an injured
- animation clip based on a blend factor that increases the more the player
- gets injured. This would then allow with blend factor == 0 to have a non
- injured walking player, with blend factor == 1 a fully injured player, with
- blend factor == 0.5 a partially walking and injured player.
+ \brief Performs an additive blend of two animation clips based on an additive factor.
+
+ QAdditiveClipBlend can be useful to create advanced animation effects based on
+ individual animation clips. For example, if you:
+
+ \list
+ \li set the baseClip property to a normal walk cycle animation clip and
+ \li set the additiveClip property to a shaking head difference clip,
+ \endlist
+
+ then adjusting the additiveFactor property will control how much of the additiveClip gets added
+ on to the baseClip. This has he effect that with an additiveFactor of zero, this blend node will
+ yield the original walk cycle clip. With an additiveFactor of 1, it will yield the walk cycle
+ including a shaking head animation.
+
+ The blending operation implemented by this class is:
+
+ \badcode
+ resultClip = baseClip + additiveFactor * additiveClip
+ \endcode
+
+ There is nothing stopping you from using values for the additiveFacor property outside the 0 to
+ 1 range, but please be aware that the input animation clips may not be authored in such a way
+ for this to make sense.
\sa BlendedClipAnimator
*/
/*!
\class Qt3DAnimation::QAdditiveClipBlend
- \inmodule Qt3DAnimation
\inherits Qt3DAnimation::QAbstractClipBlendNode
- \brief Performs an addition of two animation clips based on a
- normalized factor
-
+ \inmodule Qt3DAnimation
\since 5.9
+ \brief Performs an additive blend of two animation clips based on an additive factor.
+
QAdditiveClipBlend can be useful to create advanced animation effects based on
- individual animation clips. For instance, given a player character, additive
- blending could be used to combine a walking animation clip with an injured
- animation clip based on a blend factor that increases the more the player
- gets injured. This would then allow with blend factor == 0 to have a non
- injured walking player, with blend factor == 1 a fully injured player, with
- blend factor == 0.5 a partially walking and injured player.
+ individual animation clips. For example, if you:
+
+ \list
+ \li set the baseClip property to a normal walk cycle animation clip and
+ \li set the additiveClip property to a shaking head difference clip,
+ \endlist
+
+ then adjusting the additiveFactor property will control how much of the additiveClip gets added
+ on to the baseClip. This has he effect that with an additiveFactor of zero, this blend node will
+ yield the original walk cycle clip. With an additiveFactor of 1, it will yield the walk cycle
+ including a shaking head animation.
+
+ The blending operation implemented by this class is:
+
+ \badcode
+ resultClip = baseClip + additiveFactor * additiveClip
+ \endcode
+
+ There is nothing stopping you from using values for the additiveFacor property outside the 0 to
+ 1 range, but please be aware that the input animation clips may not be authored in such a way
+ for this to make sense.
\sa QBlendedClipAnimator
*/
@@ -121,13 +149,13 @@ Qt3DCore::QNodeCreatedChangeBasePtr QAdditiveClipBlend::createNodeCreationChange
/*!
\qmlproperty real AdditiveClipBlend::additiveFactor
- Specifies the blending factor between 0 and 1 to control the blending of
+ Specifies the blending factor, typically between 0 and 1, to control the blending of
two animation clips.
*/
/*!
\property QAdditiveClipBlend::additiveFactor
- Specifies the blending factor between 0 and 1 to control the blending of
+ Specifies the blending factor, typically between 0 and 1, to control the blending of
two animation clips.
*/
float QAdditiveClipBlend::additiveFactor() const
@@ -136,12 +164,36 @@ float QAdditiveClipBlend::additiveFactor() const
return d->m_additiveFactor;
}
+/*!
+ \qmlproperty AbstractClipBlendNode baseClip
+
+ This property holds the base animation clip. When the additiveFacgtor is zero the baseClip will
+ also be the resulting clip of this blend node.
+*/
+/*!
+ \property baseClip
+
+ This property holds the base animation clip. When the additiveFacgtor is zero the baseClip will
+ also be the resulting clip of this blend node.
+*/
QAbstractClipBlendNode *QAdditiveClipBlend::baseClip() const
{
Q_D(const QAdditiveClipBlend);
return d->m_baseClip;
}
+/*!
+ \qmlproperty AbstractClipBlendNode additiveClip
+
+ This property holds the additive clip to be blended with the baseClip. The amount of blending
+ is controlled by the additiveFactor property.
+*/
+/*!
+ \property additiveClip
+
+ This property holds the additive clip to be blended with the baseClip. The amount of blending
+ is controlled by the additiveFactor property.
+*/
QAbstractClipBlendNode *QAdditiveClipBlend::additiveClip() const
{
Q_D(const QAdditiveClipBlend);
@@ -197,33 +249,6 @@ void QAdditiveClipBlend::setAdditiveClip(QAbstractClipBlendNode *additiveClip)
emit additiveClipChanged(additiveClip);
}
-/*!
- \qmlproperty list<AnimationClip> AdditiveClipBlend::clips
-
- Holds the list of AnimationClip nodes against which the blending is performed.
-
- \note Only the two first AnimationClip are used, subsequent ones are ignored
-*/
-
-
-/*!
- \fn void QAdditiveClipBlend::addClip(QAnimationClip *clip);
- Adds a \a clip to the blending node's clips list.
-
- \note Only the two first AnimationClip are used, subsequent ones are ignored
- */
-
-/*!
- \fn void QAdditiveClipBlend::removeClip(QAnimationClip *clip);
- Removes a \a clip from the blending node's clips list.
- */
-
-/*!
- \fn QVector<QAnimationClip *> QAdditiveClipBlend::clips() const;
- Returns the list of QAnimationClip against which the blending is performed.
- */
-
-
} // Qt3DAnimation
QT_END_NAMESPACE
diff --git a/src/animation/frontend/qanimationcontroller.cpp b/src/animation/frontend/qanimationcontroller.cpp
index 5df2c713a..d4c3c4005 100644
--- a/src/animation/frontend/qanimationcontroller.cpp
+++ b/src/animation/frontend/qanimationcontroller.cpp
@@ -182,7 +182,7 @@ float QAnimationControllerPrivate::scaledPosition(float position) const
QAnimationGroup *QAnimationControllerPrivate::findGroup(const QString &name)
{
- for (QAnimationGroup *g : m_animationGroups) {
+ for (QAnimationGroup *g : qAsConst(m_animationGroups)) {
if (g->name() == name)
return g;
}
@@ -211,7 +211,7 @@ void QAnimationControllerPrivate::extractAnimations()
}
void QAnimationControllerPrivate::clearAnimations()
{
- for (Qt3DAnimation::QAnimationGroup *a : m_animationGroups)
+ for (Qt3DAnimation::QAnimationGroup *a : qAsConst(m_animationGroups))
a->deleteLater();
m_animationGroups.clear();
m_activeAnimationGroup = 0;
diff --git a/src/animation/frontend/qanimationgroup.cpp b/src/animation/frontend/qanimationgroup.cpp
index 07d0fadc5..365745662 100644
--- a/src/animation/frontend/qanimationgroup.cpp
+++ b/src/animation/frontend/qanimationgroup.cpp
@@ -109,7 +109,7 @@ QAnimationGroupPrivate::QAnimationGroupPrivate()
void QAnimationGroupPrivate::updatePosition(float position)
{
m_position = position;
- for (QAbstractAnimation *aa : m_animations)
+ for (QAbstractAnimation *aa : qAsConst(m_animations))
aa->setPosition(position);
}
diff --git a/src/animation/frontend/qblendedclipanimator.cpp b/src/animation/frontend/qblendedclipanimator.cpp
index 971f4e1e7..e6b127bf1 100644
--- a/src/animation/frontend/qblendedclipanimator.cpp
+++ b/src/animation/frontend/qblendedclipanimator.cpp
@@ -55,32 +55,208 @@ QBlendedClipAnimatorPrivate::QBlendedClipAnimatorPrivate()
\qmltype BlendedClipAnimator
\instantiates Qt3DAnimation::QBlendedClipAnimator
\inqmlmodule Qt3D.Animation
+ \since 5.9
- \brief Performs an animation based on a tree of blend nodes
+ \brief BlendedClipAnimator is a component providing animation playback capabilities of a tree
+ of blend nodes.
- \note The blend node tree should only be edited when the clip is not
- running
+ An instance of BlendedClipAnimator can be aggregated by an Entity to add the ability to play
+ back animation clips and to apply the calculated animation values to properties of QObjects.
- \since 5.9
+ Whereas a ClipAnimator gets its animation data from a single animation clip,
+ BlendedClipAnimator can blend together multiple clips. The animation data is obtained by
+ evaluating a so called \e {blend tree}. A blend tree is a hierarchical tree structure where the
+ leaf nodes are value nodes that encapsulate an animation clip (AbstractAnimationClip); and the
+ internal nodes represent blending operations that operate on the nodes pointed to by their
+ operand properties.
+
+ To associate a blend tree with a BlendedClipAnimator, set the animator's blendTree property to
+ point at the root node of your blend tree:
+
+ \badcode
+ BlendedClipAnimator {
+ blendTree: AdditiveClipBlend {
+ ....
+ }
+ }
+ \endcode
+
+ A blend tree can be constructed from the following node types:
+
+ \note The blend node tree should only be edited when the animator is not running.
+
+ \list
+ \li Qt3D.Animation.ClipBlendValue
+ \li Qt3D.Animation.LerpClipBlend
+ \li Qt3D.Animation.AdditiveClipBlend
+ \endlist
+
+ Additional node types will be added over time.
+
+ As an example consider the following blend tree:
+
+ \badcode
+ Clip0----
+ |
+ Lerp Node----
+ | |
+ Clip1---- Additive Node
+ |
+ Clip2----
+ \endcode
+
+ This can be created and used as follows:
+
+ \badcode
+ BlendedClipAnimator {
+ blendTree: AdditiveClipBlend {
+ baseClip: LerpClipBlend {
+ startClip: ClipBlendValue {
+ clip: AnimationClipLoader { source: "walk.json" }
+ }
+
+ endClip: ClipBlendValue {
+ clip: AnimationClipLoader { source: "run.json" }
+ }
+ }
+
+ additiveClip: ClipBlendValue {
+ clip: AnimationClipLoader { source: "wave-arm.json" }
+ }
+ }
+
+ channelMapper: ChannelMapper {...}
+ running: true
+ }
+ \endcode
+
+ By authoring a set of animation clips and blending between them dynamically at runtime with a
+ blend tree, we open up a huge set of possible resulting animations. As some simple examples of
+ the above blend tree, where alpha is the additive factor and beta is the lerp blend factor we
+ can get a 2D continuum of possible animations:
+
+ \badcode
+ (alpha = 0, beta = 1) Running, No arm waving --- (alpha = 1, beta = 1) Running, Arm waving
+ | |
+ | |
+ | |
+ (alpha = 0, beta = 0) Walking, No arm waving --- (alpha = 0, beta = 1) Running, No arm waving
+ \endcode
+
+ More complex blend trees offer even more flexibility for combining your animation clips. Note
+ that the values used to control the blend tree (alpha and beta above) are simple properties on
+ the blend nodes. This means, that these properties themselves can also be controlled by
+ the animation framework.
*/
/*!
\class Qt3DAnimation::QBlendedClipAnimator
+ \inherits Qt3DAnimation::QAbstractClipAnimator
+
\inmodule Qt3DAnimation
- \inherits Qt3DCore::QComponent
+ \since 5.9
- \brief Performs an animation based on a tree of blend nodes
+ \brief QBlendedClipAnimator is a component providing animation playback capabilities of a tree
+ of blend nodes.
- \note The blend node tree should only be edited when the clip is not
- running
+ An instance of QBlendedClipAnimator can be aggregated by a QEntity to add the ability to play
+ back animation clips and to apply the calculated animation values to properties of QObjects.
+
+ Whereas a QClipAnimator gets its animation data from a single animation clip,
+ QBlendedClipAnimator can blend together multiple clips. The animation data is obtained by
+ evaluating a so called \e {blend tree}. A blend tree is a hierarchical tree structure where the
+ leaf nodes are value nodes that encapsulate an animation clip (QAbstractAnimationClip); and the
+ internal nodes represent blending operations that operate on the nodes pointed to by their
+ operand properties.
+
+ To associate a blend tree with a QBlendedClipAnimator, set the animator's blendTree property to
+ point at the root node of your blend tree:
+
+ \badcode
+ auto blendTreeRoot = new QAdditiveClipBlend();
+ ...
+ auto animator = new QBlendedClipAnimator();
+ animator->setBlendTree(blendTreeRoot);
+ \endcode
+
+ A blend tree can be constructed from the following node types:
+
+ \note The blend node tree should only be edited when the animator is not running.
+
+ \list
+ \li Qt3DAnimation::QClipBlendValue
+ \li Qt3DAnimation::QLerpClipBlend
+ \li Qt3DAnimation::QAdditiveClipBlend
+ \endlist
+
+ Additional node types will be added over time.
+
+ As an example consider the following blend tree:
+
+ \badcode
+ Clip0----
+ |
+ Lerp Node----
+ | |
+ Clip1---- Additive Node
+ |
+ Clip2----
+ \endcode
+
+ This can be created and used as follows:
+
+ \code
+ // Create leaf nodes of blend tree
+ auto clip0 = new QClipBlendValue(
+ new QAnimationClipLoader(QUrl::fromLocalFile("walk.json")));
+ auto clip1 = new QClipBlendValue(
+ new QAnimationClipLoader(QUrl::fromLocalFile("run.json")));
+ auto clip2 = new QClipBlendValue(
+ new QAnimationClipLoader(QUrl::fromLocalFile("wave-arm.json")));
+
+ // Create blend tree inner nodes
+ auto lerpNode = new QLerpClipBlend();
+ lerpNode->setStartClip(clip0);
+ lerpNode->setEndClip(clip1);
+ lerpNode->setBlendFactor(0.5f); // Half-walk, half-run
+
+ auto additiveNode = new QAdditiveClipBlend();
+ additiveNode->setBaseClip(lerpNode); // Comes from lerp sub-tree
+ additiveNode->setAdditiveClip(clip2);
+ additiveNode->setAdditiveFactor(1.0f); // Wave arm fully
+
+ // Run the animator
+ auto animator = new QBlendedClipAnimator();
+ animator->setBlendTree(additiveNode);
+ animator->setChannelMapper(...);
+ animator->setRunning(true);
+ \endcode
+
+ By authoring a set of animation clips and blending between them dynamically at runtime with a
+ blend tree, we open up a huge set of possible resulting animations. As some simple examples of
+ the above blend tree, where alpha is the additive factor and beta is the lerp blend factor we
+ can get a 2D continuum of possible animations:
+
+ \badcode
+ (alpha = 0, beta = 1) Running, No arm waving --- (alpha = 1, beta = 1) Running, Arm waving
+ | |
+ | |
+ | |
+ (alpha = 0, beta = 0) Walking, No arm waving --- (alpha = 0, beta = 1) Running, No arm waving
+ \endcode
+
+ More complex blend trees offer even more flexibility for combining your animation clips. Note
+ that the values used to control the blend tree (alpha and beta above) are simple properties on
+ the blend nodes. This means, that these properties themselves can also be controlled by
+ the animation framework.
- \since 5.9
*/
QBlendedClipAnimator::QBlendedClipAnimator(Qt3DCore::QNode *parent)
: Qt3DAnimation::QAbstractClipAnimator(*new QBlendedClipAnimatorPrivate, parent)
{
}
+/*! \internal */
QBlendedClipAnimator::QBlendedClipAnimator(QBlendedClipAnimatorPrivate &dd, Qt3DCore::QNode *parent)
: Qt3DAnimation::QAbstractClipAnimator(dd, parent)
{
@@ -90,6 +266,19 @@ QBlendedClipAnimator::~QBlendedClipAnimator()
{
}
+/*!
+ \qmlproperty AbstractClipBlendNode blendTree
+
+ This property holds the root of the animation blend tree that will be evaluated before being
+ interpolated by the animator.
+*/
+
+/*!
+ \property blendTree
+
+ This property holds the root of the animation blend tree that will be evaluated before being
+ interpolated by the animator.
+*/
QAbstractClipBlendNode *QBlendedClipAnimator::blendTree() const
{
Q_D(const QBlendedClipAnimator);
@@ -116,6 +305,7 @@ void QBlendedClipAnimator::setBlendTree(QAbstractClipBlendNode *blendTree)
emit blendTreeChanged(blendTree);
}
+/*! \internal */
Qt3DCore::QNodeCreatedChangeBasePtr QBlendedClipAnimator::createNodeCreationChange() const
{
auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QBlendedClipAnimatorData>::create(this);
diff --git a/src/animation/frontend/qclipanimator.cpp b/src/animation/frontend/qclipanimator.cpp
index 4dcc4b578..eb6c80aee 100644
--- a/src/animation/frontend/qclipanimator.cpp
+++ b/src/animation/frontend/qclipanimator.cpp
@@ -52,11 +52,59 @@ QClipAnimatorPrivate::QClipAnimatorPrivate()
{
}
+/*!
+ \qmltype ClipAnimator
+ \instantiates Qt3DAnimation::QClipAnimator
+ \inqmlmodule Qt3D.Animation
+ \since 5.9
+
+ \brief ClipAnimator is a component providing simple animation playback capabilities.
+
+ An instance of ClipAnimator can be aggregated by an Entity to add the ability to play back
+ animation clips and to apply the calculated animation values to properties of QObjects.
+
+ The animation key frame data is provided via the clip property. This can be created
+ programmatically with AnimationClip or loaded from file with AnimationClipLoader.
+
+ In order to apply the values played back from the channels of data in the animation clip, the
+ clip animator needs to have a ChannelMapper object assigned to the channelMapper property.
+
+ The properties for controlling the animator are provided by the AbstractClipAnimator base
+ class.
+
+ \sa AbstractClipAnimator, AbstractAnimationClip, ChannelMapper, BlendedClipAnimator
+*/
+
+/*!
+ \class Qt3DAnimation::QClipAnimator
+ \inherits Qt3DAnimation::QAbstractClipAnimator
+
+ \inmodule Qt3DAnimation
+ \since 5.9
+
+ \brief QClipAnimator is a component providing simple animation playback capabilities.
+
+ An instance of QClipAnimator can be aggregated by a QEntity to add the ability to play back
+ animation clips and to apply the calculated animation values to properties of QObjects.
+
+ The animation key frame data is provided via the clip property. This can be created
+ programmatically with QAnimationClip or loaded from file with QAnimationClipLoader.
+
+ In order to apply the values played back from the channels of data in the animation clip, the
+ clip animator needs to have a QChannelMapper object assigned to the channelMapper property.
+
+ The properties for controlling the animator are provided by the QAbstractClipAnimator base
+ class.
+
+ \sa QAbstractClipAnimator, QAbstractAnimationClip, QChannelMapper, QBlendedClipAnimator
+*/
+
QClipAnimator::QClipAnimator(Qt3DCore::QNode *parent)
: Qt3DAnimation::QAbstractClipAnimator(*new QClipAnimatorPrivate, parent)
{
}
+/*! \internal */
QClipAnimator::QClipAnimator(QClipAnimatorPrivate &dd, Qt3DCore::QNode *parent)
: Qt3DAnimation::QAbstractClipAnimator(dd, parent)
{
@@ -66,6 +114,19 @@ QClipAnimator::~QClipAnimator()
{
}
+/*!
+ \qmlproperty AbstractAnimationClip clip
+
+ This property holds the animation clip which contains the key frame data to be played back.
+ The key frame data can be specified in either an AnimationClip or AnimationClipLoader.
+*/
+
+/*!
+ \property clip
+
+ This property holds the animation clip which contains the key frame data to be played back.
+ The key frame data can be specified in either a QAnimationClip or QAnimationClipLoader.
+*/
QAbstractAnimationClip *QClipAnimator::clip() const
{
Q_D(const QClipAnimator);
@@ -91,6 +152,7 @@ void QClipAnimator::setClip(QAbstractAnimationClip *clip)
emit clipChanged(clip);
}
+/*! \internal */
Qt3DCore::QNodeCreatedChangeBasePtr QClipAnimator::createNodeCreationChange() const
{
auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QClipAnimatorData>::create(this);
diff --git a/src/animation/frontend/qkeyframeanimation.cpp b/src/animation/frontend/qkeyframeanimation.cpp
index 0b17265a6..597b34cee 100644
--- a/src/animation/frontend/qkeyframeanimation.cpp
+++ b/src/animation/frontend/qkeyframeanimation.cpp
@@ -68,7 +68,7 @@ namespace Qt3DAnimation {
A KeyframeAnimation type implements simple keyframe animation
that can be used to animate \l Transform. The keyframes consists of multiple
- timed \l {Qt3D.Render::Transform}{Transforms}, which are interpolated and applied
+ timed \l {Qt3D.Core::Transform}s, which are interpolated and applied
to the target Transform. EasingCurve is used between keyframes to control
the interpolator. RepeatMode can be set for when the position set to the
KeyframeAnimation is less or or greater than the values defined in the keyframe positions.
@@ -190,7 +190,7 @@ void QKeyframeAnimation::setFramePositions(const QVector<float> &positions)
d->m_minposition = d->m_framePositions.first();
d->m_maxposition = d->m_framePositions.last();
float lastPos = d->m_minposition;
- for (float p : d->m_framePositions) {
+ for (float p : qAsConst(d->m_framePositions)) {
if (p < lastPos || p > d->m_maxposition)
qWarning() << "positions not ordered correctly";
lastPos = p;
diff --git a/src/animation/frontend/qmorphinganimation.cpp b/src/animation/frontend/qmorphinganimation.cpp
index e8f440c45..3824b8d64 100644
--- a/src/animation/frontend/qmorphinganimation.cpp
+++ b/src/animation/frontend/qmorphinganimation.cpp
@@ -179,7 +179,7 @@ QMorphingAnimationPrivate::QMorphingAnimationPrivate()
QMorphingAnimationPrivate::~QMorphingAnimationPrivate()
{
- for (QVector<float> *weights : m_weights)
+ for (QVector<float> *weights : qAsConst(m_weights))
delete weights;
}
diff --git a/src/animation/frontend/qmorphtarget.cpp b/src/animation/frontend/qmorphtarget.cpp
index e16dd8698..9dc30b8ba 100644
--- a/src/animation/frontend/qmorphtarget.cpp
+++ b/src/animation/frontend/qmorphtarget.cpp
@@ -99,7 +99,7 @@ QMorphTargetPrivate::QMorphTargetPrivate()
void QMorphTargetPrivate::updateAttributeNames()
{
m_attributeNames.clear();
- for (const Qt3DRender::QAttribute *attr : m_targetAttributes)
+ for (const Qt3DRender::QAttribute *attr : qAsConst(m_targetAttributes))
m_attributeNames.push_back(attr->name());
}
@@ -148,7 +148,7 @@ void QMorphTarget::setAttributes(const QVector<Qt3DRender::QAttribute *> &attrib
void QMorphTarget::addAttribute(Qt3DRender::QAttribute *attribute)
{
Q_D(QMorphTarget);
- for (const Qt3DRender::QAttribute *attr : d->m_targetAttributes) {
+ for (const Qt3DRender::QAttribute *attr : qAsConst(d->m_targetAttributes)) {
if (attr->name() == attribute->name())
return;
}
diff --git a/src/animation/frontend/qvertexblendanimation.cpp b/src/animation/frontend/qvertexblendanimation.cpp
index efc36e45c..3ddd83bf0 100644
--- a/src/animation/frontend/qvertexblendanimation.cpp
+++ b/src/animation/frontend/qvertexblendanimation.cpp
@@ -125,7 +125,7 @@ namespace Qt3DAnimation {
\readonly
*/
/*!
- \qmlproperty VertexBlendAnimation::target
+ \qmlproperty GeometryRenderer VertexBlendAnimation::target
Holds the target GeometryRenderer the morphing animation is applied to.
*/
/*!
@@ -135,6 +135,10 @@ namespace Qt3DAnimation {
is usually same as the name of the parent entity of the target GeometryRenderer, but
does not have to be.
*/
+/*!
+ \qmlproperty list<MorphTarget> VertexBlendAnimation::morphTargets
+ Holds the list of \l {MorphTarget}{morph targets} added to the animation.
+*/
QVertexBlendAnimationPrivate::QVertexBlendAnimationPrivate()
: QAbstractAnimationPrivate(QAbstractAnimation::VertexBlendAnimation)
diff --git a/src/core/aspects/qaspectengine.cpp b/src/core/aspects/qaspectengine.cpp
index a3fda90b0..b9c9d2283 100644
--- a/src/core/aspects/qaspectengine.cpp
+++ b/src/core/aspects/qaspectengine.cpp
@@ -103,8 +103,8 @@ QAspectEnginePrivate::~QAspectEnginePrivate()
*/
void QAspectEnginePrivate::initNode(QNode *node)
{
- QNodePrivate::get(node)->setScene(m_scene);
m_scene->addObservable(node);
+ QNodePrivate::get(node)->setScene(m_scene);
}
void QAspectEnginePrivate::initEntity(QEntity *entity)
diff --git a/src/core/configure.json b/src/core/configure.json
index 86b31223f..47a726d82 100644
--- a/src/core/configure.json
+++ b/src/core/configure.json
@@ -4,7 +4,7 @@
"commandline": {
"options": {
- "assimp": { "type": "enum", "values": [ "qt", "system" ] },
+ "assimp": { "type": "enum", "values": [ "qt", "system", "no" ] },
"qt3d-profile-jobs": "boolean",
"qt3d-profile-gl": "boolean"
}
diff --git a/src/core/nodes/qbackendnode.cpp b/src/core/nodes/qbackendnode.cpp
index e3963b202..dc751cb93 100644
--- a/src/core/nodes/qbackendnode.cpp
+++ b/src/core/nodes/qbackendnode.cpp
@@ -233,7 +233,7 @@ void QBackendNode::sceneChangeEvent(const QSceneChangePtr &e)
switch (e->type()) {
case PropertyUpdated: {
if (propertyChange->propertyName() == QByteArrayLiteral("enabled"))
- d->m_enabled = propertyChange->value().value<bool>();
+ d->m_enabled = propertyChange->value().toBool();
break;
}
default:
diff --git a/src/core/nodes/qnode.cpp b/src/core/nodes/qnode.cpp
index 42c8887ce..ce5e76a55 100644
--- a/src/core/nodes/qnode.cpp
+++ b/src/core/nodes/qnode.cpp
@@ -114,7 +114,7 @@ void QNodePrivate::notifyCreationChange()
Q_Q(QNode);
// Do nothing if we already have already sent a node creation change
// and not a subsequent node destroyed change.
- if (m_hasBackendNode)
+ if (m_hasBackendNode || !m_scene)
return;
QNodeCreatedChangeGenerator generator(q);
const auto creationChanges = generator.creationChanges();
@@ -305,7 +305,21 @@ void QNodePrivate::_q_setParentHelper(QNode *parent)
visitor.traverse(q, newParentNode->d_func(), &QNodePrivate::setSceneHelper);
}
- notifyCreationChange();
+ // We want to make sure that subTreeRoot is always created before
+ // child.
+ // Given a case such as below
+ // QEntity *subTreeRoot = new QEntity(someGlobalExisitingRoot)
+ // QEntity *child = new QEntity();
+ // child->setParent(subTreeRoot)
+ // We need to take into account that subTreeRoot needs to be
+ // created in the backend before the child.
+ // Therefore we only call notifyCreationChanges if the parent
+ // hasn't been created yet as we know that when the parent will be
+ // fully created, it will also send the changes for all of its
+ // children
+
+ if (QNodePrivate::get(newParentNode)->m_hasBackendNode)
+ notifyCreationChange();
}
// If we have a valid new parent, we let him know that we are its child
diff --git a/src/core/services/qabstractframeadvanceservice_p.h b/src/core/services/qabstractframeadvanceservice_p.h
index a5f635710..dac72a98d 100644
--- a/src/core/services/qabstractframeadvanceservice_p.h
+++ b/src/core/services/qabstractframeadvanceservice_p.h
@@ -64,6 +64,7 @@ class QAbstractFrameAdvanceServicePrivate;
class QT3DCORESHARED_EXPORT QAbstractFrameAdvanceService : public QAbstractServiceProvider
{
+ Q_OBJECT
public:
virtual qint64 waitForNextFrame() = 0;
virtual void start() = 0;
diff --git a/src/core/services/qeventfilterservice_p.h b/src/core/services/qeventfilterservice_p.h
index 5f779c9cd..58b87d9cc 100644
--- a/src/core/services/qeventfilterservice_p.h
+++ b/src/core/services/qeventfilterservice_p.h
@@ -63,6 +63,7 @@ class QEventFilterServicePrivate;
class QT3DCORESHARED_EXPORT QEventFilterService : public QAbstractServiceProvider
{
+ Q_OBJECT
public:
QEventFilterService();
~QEventFilterService();
diff --git a/src/core/services/qopenglinformationservice_p.h b/src/core/services/qopenglinformationservice_p.h
index c84c5ed10..2adf73307 100644
--- a/src/core/services/qopenglinformationservice_p.h
+++ b/src/core/services/qopenglinformationservice_p.h
@@ -65,6 +65,7 @@ class QOpenGLInformationServicePrivate;
class QT3DCORESHARED_EXPORT QOpenGLInformationService : public QAbstractServiceProvider
{
+ Q_OBJECT
public:
virtual QSurfaceFormat format() const = 0;
diff --git a/src/core/services/qsysteminformationservice_p.h b/src/core/services/qsysteminformationservice_p.h
index 0ab737817..01e976b77 100644
--- a/src/core/services/qsysteminformationservice_p.h
+++ b/src/core/services/qsysteminformationservice_p.h
@@ -64,6 +64,7 @@ class QSystemInformationServicePrivate;
class QT3DCORESHARED_EXPORT QSystemInformationService : public QAbstractServiceProvider
{
+ Q_OBJECT
public:
virtual QStringList aspectNames() const = 0;
virtual int threadPoolThreadCount() const = 0;
diff --git a/src/core/services/qtickclockservice_p.h b/src/core/services/qtickclockservice_p.h
index 53f3cf310..6f02643f4 100644
--- a/src/core/services/qtickclockservice_p.h
+++ b/src/core/services/qtickclockservice_p.h
@@ -61,6 +61,7 @@ class QTickClockServicePrivate;
class QTickClockService : public QAbstractFrameAdvanceService
{
+ Q_OBJECT
public:
QTickClockService();
~QTickClockService();
diff --git a/src/doc/qt3d.qdocconf b/src/doc/qt3d.qdocconf
index 8c1508fa4..7da047ced 100644
--- a/src/doc/qt3d.qdocconf
+++ b/src/doc/qt3d.qdocconf
@@ -80,7 +80,10 @@ imagedirs += images \
../../examples/qt3d/basicshapes-cpp/doc/images \
../../examples/qt3d/planets-qml/doc/images \
../../examples/qt3d/wireframe/doc/images \
- ../../examples/qt3d/audio-visualizer-qml/doc/images
+ ../../examples/qt3d/audio-visualizer-qml/doc/images \
+ ../../examples/qt3d/simplecustommaterial/doc/images \
+ ../../examples/qt3d/scene2d/doc/images \
+ ../../examples/qt3d/advancedcustommaterial/doc/images
Cpp.ignoretokens += QT3DINPUTSHARED_EXPORT \
QT3DCORESHARED_EXPORT \
@@ -95,8 +98,10 @@ Cpp.ignoretokens += QT3DINPUTSHARED_EXPORT \
Cpp.ignoredirectives += Q_DECLARE_LOGGING_CATEGORY
-manifestmeta.highlighted.names = "Qt3D/Qt 3D: Audio Visualizer Example" \
- "Qt3D/Qt 3D: Planets QML Example"
+manifestmeta.highlighted.names = \
+ "Qt3D/Qt 3D: Advanced custom material QML Example" \
+ "Qt3D/Qt 3D: Audio Visualizer Example" \
+ "Qt3D/Qt 3D: Planets QML Example"
manifestmeta.thumbnail.names += "Qt3D/Qt 3D: Deferred Renderer C++ Example"
diff --git a/src/doc/src/levelofdetailloader.qdoc b/src/doc/src/levelofdetailloader.qdoc
index 65fda072a..6294e4735 100644
--- a/src/doc/src/levelofdetailloader.qdoc
+++ b/src/doc/src/levelofdetailloader.qdoc
@@ -40,12 +40,12 @@
/*!
\qmltype LevelOfDetailLoader
\inqmlmodule Qt3D.Render
+ \inherits Entity
\since 5.9
\brief An entity loader that changes depending on distance to camera or screen size
A LevelOfDetailLoader will load the entity matching the \l LevelOfDetail::currentIndex.
The source is selected from the \l sources property.
- The range is specified using the \l {minimum} and the \l{maximum} values.
\sa LevelOfDetail
*/
diff --git a/src/extras/defaults/defaults.pri b/src/extras/defaults/defaults.pri
index ec8c9a7b5..8a18fb6e9 100644
--- a/src/extras/defaults/defaults.pri
+++ b/src/extras/defaults/defaults.pri
@@ -24,6 +24,7 @@ HEADERS += \
$$PWD/qphongalphamaterial.h \
$$PWD/qphongalphamaterial_p.h \
$$PWD/qt3dwindow.h \
+ $$PWD/qt3dwindow_p.h \
$$PWD/qfirstpersoncameracontroller.h \
$$PWD/qfirstpersoncameracontroller_p.h \
$$PWD/qorbitcameracontroller.h \
diff --git a/src/extras/defaults/qskyboxentity.cpp b/src/extras/defaults/qskyboxentity.cpp
index ae3fa1087..3c7b0dd4e 100644
--- a/src/extras/defaults/qskyboxentity.cpp
+++ b/src/extras/defaults/qskyboxentity.cpp
@@ -138,10 +138,8 @@ void QSkyboxEntityPrivate::init()
m_gl3RenderPass->addRenderState(seamlessCubemap);
m_gl2RenderPass->addRenderState(cullFront);
m_gl2RenderPass->addRenderState(depthTest);
- m_gl2RenderPass->addRenderState(seamlessCubemap);
m_es2RenderPass->addRenderState(cullFront);
m_es2RenderPass->addRenderState(depthTest);
- m_es2RenderPass->addRenderState(seamlessCubemap);
m_gl3Technique->addRenderPass(m_gl3RenderPass);
m_gl2Technique->addRenderPass(m_gl2RenderPass);
diff --git a/src/extras/defaults/qt3dwindow.cpp b/src/extras/defaults/qt3dwindow.cpp
index a0ce40e16..635d81956 100644
--- a/src/extras/defaults/qt3dwindow.cpp
+++ b/src/extras/defaults/qt3dwindow.cpp
@@ -49,6 +49,7 @@
****************************************************************************/
#include "qt3dwindow.h"
+#include "qt3dwindow_p.h"
#include <Qt3DCore/qaspectengine.h>
#include <Qt3DCore/qentity.h>
@@ -65,9 +66,8 @@ QT_BEGIN_NAMESPACE
namespace Qt3DExtras {
-Qt3DWindow::Qt3DWindow(QScreen *screen)
- : QWindow(screen)
- , m_aspectEngine(new Qt3DCore::QAspectEngine)
+Qt3DWindowPrivate::Qt3DWindowPrivate()
+ : m_aspectEngine(new Qt3DCore::QAspectEngine)
, m_renderAspect(new Qt3DRender::QRenderAspect)
, m_inputAspect(new Qt3DInput::QInputAspect)
, m_logicAspect(new Qt3DLogic::QLogicAspect)
@@ -79,6 +79,16 @@ Qt3DWindow::Qt3DWindow(QScreen *screen)
, m_userRoot(nullptr)
, m_initialized(false)
{
+}
+
+Qt3DWindow::Qt3DWindow(QScreen *screen)
+ : QWindow(*new Qt3DWindowPrivate(), nullptr)
+{
+ Q_D(Qt3DWindow);
+
+ if (!d->parentWindow)
+ d->connectToScreen(screen ? screen : d->topLevelScreen.data());
+
setSurfaceType(QSurface::OpenGLSurface);
resize(1024, 768);
@@ -98,77 +108,88 @@ Qt3DWindow::Qt3DWindow(QScreen *screen)
setFormat(format);
QSurfaceFormat::setDefaultFormat(format);
- m_aspectEngine->registerAspect(m_renderAspect);
- m_aspectEngine->registerAspect(m_inputAspect);
- m_aspectEngine->registerAspect(m_logicAspect);
+ d->m_aspectEngine->registerAspect(d->m_renderAspect);
+ d->m_aspectEngine->registerAspect(d->m_inputAspect);
+ d->m_aspectEngine->registerAspect(d->m_logicAspect);
- m_defaultCamera->setParent(m_root);
- m_forwardRenderer->setCamera(m_defaultCamera);
- m_forwardRenderer->setSurface(this);
- m_renderSettings->setActiveFrameGraph(m_forwardRenderer);
- m_inputSettings->setEventSource(this);
+ d->m_defaultCamera->setParent(d->m_root);
+ d->m_forwardRenderer->setCamera(d->m_defaultCamera);
+ d->m_forwardRenderer->setSurface(this);
+ d->m_renderSettings->setActiveFrameGraph(d->m_forwardRenderer);
+ d->m_inputSettings->setEventSource(this);
}
Qt3DWindow::~Qt3DWindow()
{
+ Q_D(Qt3DWindow);
+ delete d->m_aspectEngine;
}
void Qt3DWindow::registerAspect(Qt3DCore::QAbstractAspect *aspect)
{
Q_ASSERT(!isVisible());
- m_aspectEngine->registerAspect(aspect);
+ Q_D(Qt3DWindow);
+ d->m_aspectEngine->registerAspect(aspect);
}
void Qt3DWindow::registerAspect(const QString &name)
{
Q_ASSERT(!isVisible());
- m_aspectEngine->registerAspect(name);
+ Q_D(Qt3DWindow);
+ d->m_aspectEngine->registerAspect(name);
}
void Qt3DWindow::setRootEntity(Qt3DCore::QEntity *root)
{
- if (m_userRoot != root) {
- if (m_userRoot != nullptr)
- m_userRoot->setParent(static_cast<Qt3DCore::QNode*>(nullptr));
+ Q_D(Qt3DWindow);
+ if (d->m_userRoot != root) {
+ if (d->m_userRoot != nullptr)
+ d->m_userRoot->setParent(static_cast<Qt3DCore::QNode*>(nullptr));
if (root != nullptr)
- root->setParent(m_root);
- m_userRoot = root;
+ root->setParent(d->m_root);
+ d->m_userRoot = root;
}
}
void Qt3DWindow::setActiveFrameGraph(Qt3DRender::QFrameGraphNode *activeFrameGraph)
{
- m_renderSettings->setActiveFrameGraph(activeFrameGraph);
+ Q_D(Qt3DWindow);
+ d->m_renderSettings->setActiveFrameGraph(activeFrameGraph);
}
Qt3DRender::QFrameGraphNode *Qt3DWindow::activeFrameGraph() const
{
- return m_renderSettings->activeFrameGraph();
+ Q_D(const Qt3DWindow);
+ return d->m_renderSettings->activeFrameGraph();
}
Qt3DExtras::QForwardRenderer *Qt3DWindow::defaultFrameGraph() const
{
- return m_forwardRenderer;
+ Q_D(const Qt3DWindow);
+ return d->m_forwardRenderer;
}
Qt3DRender::QCamera *Qt3DWindow::camera() const
{
- return m_defaultCamera;
+ Q_D(const Qt3DWindow);
+ return d->m_defaultCamera;
}
Qt3DRender::QRenderSettings *Qt3DWindow::renderSettings() const
{
- return m_renderSettings;
+ Q_D(const Qt3DWindow);
+ return d->m_renderSettings;
}
void Qt3DWindow::showEvent(QShowEvent *e)
{
- if (!m_initialized) {
- m_root->addComponent(m_renderSettings);
- m_root->addComponent(m_inputSettings);
- m_aspectEngine->setRootEntity(Qt3DCore::QEntityPtr(m_root));
+ Q_D(Qt3DWindow);
+ if (!d->m_initialized) {
+ d->m_root->addComponent(d->m_renderSettings);
+ d->m_root->addComponent(d->m_inputSettings);
+ d->m_aspectEngine->setRootEntity(Qt3DCore::QEntityPtr(d->m_root));
- m_initialized = true;
+ d->m_initialized = true;
}
QWindow::showEvent(e);
@@ -176,7 +197,8 @@ void Qt3DWindow::showEvent(QShowEvent *e)
void Qt3DWindow::resizeEvent(QResizeEvent *)
{
- m_defaultCamera->setAspectRatio(float(width()) / float(height()));
+ Q_D(Qt3DWindow);
+ d->m_defaultCamera->setAspectRatio(float(width()) / float(height()));
}
} // Qt3DExtras
diff --git a/src/extras/defaults/qt3dwindow.h b/src/extras/defaults/qt3dwindow.h
index 811bb134d..6ec1bbf8b 100644
--- a/src/extras/defaults/qt3dwindow.h
+++ b/src/extras/defaults/qt3dwindow.h
@@ -84,6 +84,8 @@ class QLogicAspect;
namespace Qt3DExtras {
+class Qt3DWindowPrivate;
+
class QT3DEXTRASSHARED_EXPORT Qt3DWindow : public QWindow
{
Q_OBJECT
@@ -112,28 +114,7 @@ protected:
void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE;
private:
- QScopedPointer<Qt3DCore::QAspectEngine> m_aspectEngine;
-
- // Aspects
- Qt3DRender::QRenderAspect *m_renderAspect;
- Qt3DInput::QInputAspect *m_inputAspect;
- Qt3DLogic::QLogicAspect *m_logicAspect;
-
- // Renderer configuration
- Qt3DRender::QRenderSettings *m_renderSettings;
- Qt3DExtras::QForwardRenderer *m_forwardRenderer;
- Qt3DRender::QCamera *m_defaultCamera;
-
- // Input configuration
- Qt3DInput::QInputSettings *m_inputSettings;
-
- // Logic configuration
-
- // Scene
- Qt3DCore::QEntity *m_root;
- Qt3DCore::QEntity *m_userRoot;
-
- bool m_initialized;
+ Q_DECLARE_PRIVATE(Qt3DWindow)
};
} // Qt3DExtras
diff --git a/src/extras/defaults/qt3dwindow_p.h b/src/extras/defaults/qt3dwindow_p.h
new file mode 100644
index 000000000..731d5298e
--- /dev/null
+++ b/src/extras/defaults/qt3dwindow_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DWINDOW_P_H
+#define QT3DWINDOW_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 <QtGui/private/qwindow_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class Qt3DWindowPrivate : public QWindowPrivate
+{
+public:
+ Qt3DWindowPrivate();
+
+ Qt3DCore::QAspectEngine *m_aspectEngine;
+
+ // Aspects
+ Qt3DRender::QRenderAspect *m_renderAspect;
+ Qt3DInput::QInputAspect *m_inputAspect;
+ Qt3DLogic::QLogicAspect *m_logicAspect;
+
+ // Renderer configuration
+ Qt3DRender::QRenderSettings *m_renderSettings;
+ Qt3DExtras::QForwardRenderer *m_forwardRenderer;
+ Qt3DRender::QCamera *m_defaultCamera;
+
+ // Input configuration
+ Qt3DInput::QInputSettings *m_inputSettings;
+
+ // Logic configuration
+
+ // Scene
+ Qt3DCore::QEntity *m_root;
+ Qt3DCore::QEntity *m_userRoot;
+
+ bool m_initialized;
+
+ Q_DECLARE_PUBLIC(Qt3DWindow)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DWINDOW_P_H
diff --git a/src/extras/geometries/qplanegeometry.cpp b/src/extras/geometries/qplanegeometry.cpp
index f6eba9e61..14ddb25e6 100644
--- a/src/extras/geometries/qplanegeometry.cpp
+++ b/src/extras/geometries/qplanegeometry.cpp
@@ -54,7 +54,7 @@ namespace Qt3DExtras {
namespace {
-QByteArray createPlaneVertexData(float w, float h, const QSize &resolution)
+QByteArray createPlaneVertexData(float w, float h, const QSize &resolution, bool mirrored)
{
Q_ASSERT(w > 0.0f);
Q_ASSERT(h > 0.0f);
@@ -95,7 +95,7 @@ QByteArray createPlaneVertexData(float w, float h, const QSize &resolution)
// texture coordinates
*fptr++ = u;
- *fptr++ = v;
+ *fptr++ = mirrored ? 1.0f - v : v;
// normal
*fptr++ = 0.0f;
@@ -149,17 +149,18 @@ QByteArray createPlaneIndexData(const QSize &resolution)
class PlaneVertexBufferFunctor : public QBufferDataGenerator
{
public:
- explicit PlaneVertexBufferFunctor(float w, float h, const QSize &resolution)
+ explicit PlaneVertexBufferFunctor(float w, float h, const QSize &resolution, bool mirrored)
: m_width(w)
, m_height(h)
, m_resolution(resolution)
+ , m_mirrored(mirrored)
{}
~PlaneVertexBufferFunctor() {}
QByteArray operator()() Q_DECL_FINAL
{
- return createPlaneVertexData(m_width, m_height, m_resolution);
+ return createPlaneVertexData(m_width, m_height, m_resolution, m_mirrored);
}
bool operator ==(const QBufferDataGenerator &other) const Q_DECL_FINAL
@@ -168,7 +169,8 @@ public:
if (otherFunctor != nullptr)
return (otherFunctor->m_width == m_width &&
otherFunctor->m_height == m_height &&
- otherFunctor->m_resolution == m_resolution);
+ otherFunctor->m_resolution == m_resolution &&
+ otherFunctor->m_mirrored == m_mirrored);
return false;
}
@@ -178,6 +180,7 @@ public:
float m_width;
float m_height;
QSize m_resolution;
+ bool m_mirrored;
};
class PlaneIndexBufferFunctor : public QBufferDataGenerator
@@ -237,6 +240,13 @@ public:
*/
/*!
+ * \qmlproperty bool PlaneGeometry::mirrored
+ * \since 5.9
+ *
+ * Controls if the UV coordinates of the plane should be flipped vertically.
+ */
+
+/*!
* \qmlproperty Attribute PlaneGeometry::positionAttribute
*
* Holds the geometry position attribute.
@@ -318,7 +328,7 @@ void QPlaneGeometry::updateVertices()
d->m_normalAttribute->setCount(nVerts);
d->m_texCoordAttribute->setCount(nVerts);
d->m_tangentAttribute->setCount(nVerts);
- d->m_vertexBuffer->setDataGenerator(QSharedPointer<PlaneVertexBufferFunctor>::create(d->m_width, d->m_height, d->m_meshResolution));
+ d->m_vertexBuffer->setDataGenerator(QSharedPointer<PlaneVertexBufferFunctor>::create(d->m_width, d->m_height, d->m_meshResolution, d->m_mirrored));
}
/*!
@@ -365,6 +375,16 @@ void QPlaneGeometry::setHeight(float height)
emit heightChanged(height);
}
+void QPlaneGeometry::setMirrored(bool mirrored)
+{
+ Q_D(QPlaneGeometry);
+ if (mirrored == d->m_mirrored)
+ return;
+ d->m_mirrored = mirrored;
+ updateVertices();
+ emit mirroredChanged(mirrored);
+}
+
/*!
* \property QPlaneGeometry::resolution
*
@@ -399,6 +419,18 @@ float QPlaneGeometry::height() const
}
/*!
+ * \property QPlaneGeometry::mirrored
+ * \since 5.9
+ *
+ * Controls if the UV coordinates of the plane should be flipped vertically.
+ */
+bool QPlaneGeometry::mirrored() const
+{
+ Q_D(const QPlaneGeometry);
+ return d->m_mirrored;
+}
+
+/*!
* \property QPlaneGeometry::positionAttribute
*
* Holds the geometry position attribute.
@@ -458,6 +490,7 @@ QPlaneGeometryPrivate::QPlaneGeometryPrivate()
, m_width(1.0f)
, m_height(1.0f)
, m_meshResolution(QSize(2, 2))
+ , m_mirrored(false)
, m_positionAttribute(nullptr)
, m_normalAttribute(nullptr)
, m_texCoordAttribute(nullptr)
@@ -525,7 +558,7 @@ void QPlaneGeometryPrivate::init()
// Each primitive has 3 vertives
m_indexAttribute->setCount(faces * 3);
- m_vertexBuffer->setDataGenerator(QSharedPointer<PlaneVertexBufferFunctor>::create(m_width, m_height, m_meshResolution));
+ m_vertexBuffer->setDataGenerator(QSharedPointer<PlaneVertexBufferFunctor>::create(m_width, m_height, m_meshResolution, m_mirrored));
m_indexBuffer->setDataGenerator(QSharedPointer<PlaneIndexBufferFunctor>::create(m_meshResolution));
q->addAttribute(m_positionAttribute);
diff --git a/src/extras/geometries/qplanegeometry.h b/src/extras/geometries/qplanegeometry.h
index 694e04e82..4a4efe6eb 100644
--- a/src/extras/geometries/qplanegeometry.h
+++ b/src/extras/geometries/qplanegeometry.h
@@ -62,6 +62,7 @@ class QT3DEXTRASSHARED_EXPORT QPlaneGeometry : public Qt3DRender::QGeometry
Q_PROPERTY(float width READ width WRITE setWidth NOTIFY widthChanged)
Q_PROPERTY(float height READ height WRITE setHeight NOTIFY heightChanged)
Q_PROPERTY(QSize resolution READ resolution WRITE setResolution NOTIFY resolutionChanged)
+ Q_PROPERTY(bool mirrored READ mirrored WRITE setMirrored NOTIFY mirroredChanged REVISION 9)
Q_PROPERTY(Qt3DRender::QAttribute *positionAttribute READ positionAttribute CONSTANT)
Q_PROPERTY(Qt3DRender::QAttribute *normalAttribute READ normalAttribute CONSTANT)
Q_PROPERTY(Qt3DRender::QAttribute *texCoordAttribute READ texCoordAttribute CONSTANT)
@@ -78,6 +79,7 @@ public:
QSize resolution() const;
float width() const;
float height() const;
+ bool mirrored() const;
Qt3DRender::QAttribute *positionAttribute() const;
Qt3DRender::QAttribute *normalAttribute() const;
@@ -89,11 +91,13 @@ public Q_SLOTS:
void setResolution(const QSize &resolution);
void setWidth(float width);
void setHeight(float height);
+ void setMirrored(bool mirrored);
Q_SIGNALS:
void resolutionChanged(const QSize &resolution);
void widthChanged(float width);
void heightChanged(float height);
+ void mirroredChanged(bool mirrored);
protected:
QPlaneGeometry(QPlaneGeometryPrivate &dd, QNode *parent = nullptr);
diff --git a/src/extras/geometries/qplanegeometry_p.h b/src/extras/geometries/qplanegeometry_p.h
index cfde6da1c..68d979895 100644
--- a/src/extras/geometries/qplanegeometry_p.h
+++ b/src/extras/geometries/qplanegeometry_p.h
@@ -75,6 +75,7 @@ public:
float m_width;
float m_height;
QSize m_meshResolution;
+ bool m_mirrored;
Qt3DRender::QAttribute *m_positionAttribute;
Qt3DRender::QAttribute *m_normalAttribute;
Qt3DRender::QAttribute *m_texCoordAttribute;
diff --git a/src/extras/geometries/qplanemesh.cpp b/src/extras/geometries/qplanemesh.cpp
index 5991c5397..4804df024 100644
--- a/src/extras/geometries/qplanemesh.cpp
+++ b/src/extras/geometries/qplanemesh.cpp
@@ -73,6 +73,13 @@ namespace Qt3DExtras {
*/
/*!
+ * \qmlproperty bool PlaneMesh::mirrored
+ * \since 5.9
+ *
+ * Controls if the UV coordinates of the plane should be flipped vertically.
+ */
+
+/*!
* \class Qt3DExtras::QPlaneMesh
* \inheaderfile Qt3DExtras/QPlaneMesh
* \inmodule Qt3DExtras
@@ -92,6 +99,7 @@ QPlaneMesh::QPlaneMesh(QNode *parent)
QObject::connect(geometry, &QPlaneGeometry::widthChanged, this, &QPlaneMesh::widthChanged);
QObject::connect(geometry, &QPlaneGeometry::heightChanged, this, &QPlaneMesh::heightChanged);
QObject::connect(geometry, &QPlaneGeometry::resolutionChanged, this, &QPlaneMesh::meshResolutionChanged);
+ QObject::connect(geometry, &QPlaneGeometry::mirroredChanged, this, &QPlaneMesh::mirroredChanged);
QGeometryRenderer::setGeometry(geometry);
}
@@ -147,6 +155,22 @@ QSize QPlaneMesh::meshResolution() const
return static_cast<QPlaneGeometry *>(geometry())->resolution();
}
+void QPlaneMesh::setMirrored(bool mirrored)
+{
+ static_cast<QPlaneGeometry *>(geometry())->setMirrored(mirrored);
+}
+
+/*!
+ * \property QPlaneMesh::mirrored
+ * \since 5.9
+ *
+ * Controls if the UV coordinates of the plane should be flipped vertically.
+ */
+bool QPlaneMesh::mirrored() const
+{
+ return static_cast<QPlaneGeometry *>(geometry())->mirrored();
+}
+
} // namespace Qt3DExtras
QT_END_NAMESPACE
diff --git a/src/extras/geometries/qplanemesh.h b/src/extras/geometries/qplanemesh.h
index d68774ca0..1cf2ae79e 100644
--- a/src/extras/geometries/qplanemesh.h
+++ b/src/extras/geometries/qplanemesh.h
@@ -54,6 +54,7 @@ class QT3DEXTRASSHARED_EXPORT QPlaneMesh : public Qt3DRender::QGeometryRenderer
Q_PROPERTY(float width READ width WRITE setWidth NOTIFY widthChanged)
Q_PROPERTY(float height READ height WRITE setHeight NOTIFY heightChanged)
Q_PROPERTY(QSize meshResolution READ meshResolution WRITE setMeshResolution NOTIFY meshResolutionChanged)
+ Q_PROPERTY(bool mirrored READ mirrored WRITE setMirrored NOTIFY mirroredChanged REVISION 9)
public:
explicit QPlaneMesh(Qt3DCore::QNode *parent = nullptr);
@@ -62,16 +63,19 @@ public:
float width() const;
float height() const;
QSize meshResolution() const;
+ bool mirrored() const;
public Q_SLOTS:
void setWidth(float width);
void setHeight(float height);
void setMeshResolution(const QSize &resolution);
+ void setMirrored(bool mirrored);
Q_SIGNALS:
void meshResolutionChanged(const QSize &meshResolution);
void widthChanged(float width);
void heightChanged(float height);
+ void mirroredChanged(bool mirrored);
private:
// As this is a default provided geometry renderer, no one should be able
diff --git a/src/extras/shaders/es2/light.inc.frag b/src/extras/shaders/es2/light.inc.frag
index 726340d7e..074af5799 100644
--- a/src/extras/shaders/es2/light.inc.frag
+++ b/src/extras/shaders/es2/light.inc.frag
@@ -14,215 +14,179 @@ struct Light {
uniform Light lights[MAX_LIGHTS];
uniform int lightCount;
-void addLightAdsModelNormalMapped(const in FP vec3 vpos,
- const in FP vec3 n,
- const in FP vec3 eye,
- const in FP float shininess,
- const in FP mat3 tangentMatrix,
- const in Light light,
- inout FP vec3 diffuseColor,
- inout FP vec3 specularColor)
-{
- FP vec3 snormal = normalize( vec3( tangentMatrix[0][2], tangentMatrix[1][2], tangentMatrix[2][2] ) );
-
- FP vec3 s, ts;
- FP float att = 1.0;
- if ( light.type != TYPE_DIRECTIONAL ) {
- s = light.position - vpos;
- if ( dot(snormal, s) < 0.0 )
- att = 0.0;
- else {
- ts = normalize( tangentMatrix * s );
- if (length( light.attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( light.type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle)
- att = 0.0;
- }
- }
- } else {
- if ( dot(snormal, -light.direction) > 0.0 )
- s = normalize( tangentMatrix * -light.direction );
- else
- att = 0.0;
- }
-
- FP float diffuse = max( dot( ts, n ), 0.0 );
-
- FP float specular = 0.0;
- if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
- FP vec3 r = reflect( -ts, n );
- FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
-
- diffuseColor += att * light.intensity * diffuse * light.color;
- specularColor += att * light.intensity * specular * light.color;
-}
-
void adsModelNormalMapped(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
const in FP mat3 tangentMatrix,
out FP vec3 diffuseColor, out FP vec3 specularColor)
{
diffuseColor = vec3(0.0);
specularColor = vec3(0.0);
- if (lightCount < 1) return;
- FP vec3 n = normalize( vnormal );
- addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[0], diffuseColor, specularColor);
- if (lightCount < 2) return;
-
- addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[1], diffuseColor, specularColor);
- if (lightCount < 3) return;
-
- addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[2], diffuseColor, specularColor);
- if (lightCount < 4) return;
-
- addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[3], diffuseColor, specularColor);
- if (lightCount < 5) return;
-
- addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[4], diffuseColor, specularColor);
- if (lightCount < 6) return;
-
- addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[5], diffuseColor, specularColor);
- if (lightCount < 7) return;
-
- addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[6], diffuseColor, specularColor);
- if (lightCount < 8) return;
-
- addLightAdsModelNormalMapped(vpos, n, eye, shininess, tangentMatrix, lights[7], diffuseColor, specularColor);
-}
+ FP vec3 snormal = normalize( vec3( tangentMatrix[0][2], tangentMatrix[1][2], tangentMatrix[2][2] ) );
-void addLightAdsModel(const in FP vec3 vpos,
- const in FP vec3 n,
- const in FP vec3 eye,
- const in FP float shininess,
- const in Light light,
- inout FP vec3 diffuseColor,
- inout FP vec3 specularColor)
-{
- FP vec3 s;
+ FP vec3 n = normalize( vnormal );
- FP float att = 1.0;
- if ( light.type != TYPE_DIRECTIONAL ) {
- s = light.position - vpos;
- if (length( light.attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( light.type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle)
+ FP vec3 s, ts;
+ Light light;
+ for (int i = 0; i < lightCount; ++i) {
+ if (i == 0)
+ light = lights[0];
+ else if (i == 1)
+ light = lights[1];
+ else if (i == 2)
+ light = lights[2];
+ else if (i == 3)
+ light = lights[3];
+ else if (i == 4)
+ light = lights[4];
+ else if (i == 5)
+ light = lights[5];
+ else if (i == 6)
+ light = lights[6];
+ else if (i == 7)
+ light = lights[7];
+
+ FP float att = 1.0;
+ if ( light.type != TYPE_DIRECTIONAL ) {
+ s = light.position - vpos;
+ if ( dot(snormal, s) < 0.0 )
+ att = 0.0;
+ else {
+ ts = normalize( tangentMatrix * s );
+ if (length( light.attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( light.type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle)
+ att = 0.0;
+ }
+ }
+ } else {
+ if ( dot(snormal, -light.direction) > 0.0 )
+ s = normalize( tangentMatrix * -light.direction );
+ else
att = 0.0;
}
- } else {
- s = normalize( -light.direction );
- }
- FP float diffuse = max( dot( s, n ), 0.0 );
- FP float specular = 0.0;
+ FP float diffuse = max( dot( ts, n ), 0.0 );
- if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
- FP vec3 r = reflect( -s, n );
- FP vec3 v = normalize( eye - vpos );
- FP float normFactor = ( shininess + 2.0 ) / 2.0;
- specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
- }
+ FP float specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
+ FP vec3 r = reflect( -ts, n );
+ FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
- diffuseColor += att * light.intensity * diffuse * light.color;
- specularColor += att * light.intensity * specular * light.color;
+ diffuseColor += att * light.intensity * diffuse * light.color;
+ specularColor += att * light.intensity * specular * light.color;
+ }
}
-
void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
out FP vec3 diffuseColor, out FP vec3 specularColor)
{
diffuseColor = vec3(0.0);
specularColor = vec3(0.0);
- if (lightCount < 1) return;
FP vec3 n = normalize( vnormal );
- addLightAdsModel(vpos, n, eye, shininess, lights[0], diffuseColor, specularColor);
- if (lightCount < 2) return;
-
- addLightAdsModel(vpos, n, eye, shininess, lights[1], diffuseColor, specularColor);
- if (lightCount < 3) return;
-
- addLightAdsModel(vpos, n, eye, shininess, lights[2], diffuseColor, specularColor);
- if (lightCount < 4) return;
-
- addLightAdsModel(vpos, n, eye, shininess, lights[3], diffuseColor, specularColor);
- if (lightCount < 5) return;
-
- addLightAdsModel(vpos, n, eye, shininess, lights[4], diffuseColor, specularColor);
- if (lightCount < 6) return;
-
- addLightAdsModel(vpos, n, eye, shininess, lights[5], diffuseColor, specularColor);
- if (lightCount < 7) return;
- addLightAdsModel(vpos, n, eye, shininess, lights[6], diffuseColor, specularColor);
- if (lightCount < 8) return;
-
- addLightAdsModel(vpos, n, eye, shininess, lights[7], diffuseColor, specularColor);
-}
-
-void addLightAdModel(const in FP vec3 vpos,
- const in FP vec3 n,
- const in Light light,
- inout FP vec3 diffuseColor)
-{
FP vec3 s;
- FP float att = 1.0;
- if ( light.type != TYPE_DIRECTIONAL ) {
- s = light.position - vpos;
- if (length( light.attenuation ) != 0.0) {
- FP float dist = length(s);
- att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist);
- }
- s = normalize( s );
- if ( light.type == TYPE_SPOT ) {
- if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle)
- att = 0.0;
+ Light light;
+ for (int i = 0; i < lightCount; ++i) {
+ if (i == 0)
+ light = lights[0];
+ else if (i == 1)
+ light = lights[1];
+ else if (i == 2)
+ light = lights[2];
+ else if (i == 3)
+ light = lights[3];
+ else if (i == 4)
+ light = lights[4];
+ else if (i == 5)
+ light = lights[5];
+ else if (i == 6)
+ light = lights[6];
+ else if (i == 7)
+ light = lights[7];
+
+ FP float att = 1.0;
+ if ( light.type != TYPE_DIRECTIONAL ) {
+ s = light.position - vpos;
+ if (length( light.attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( light.type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( -light.direction );
}
- } else {
- s = normalize( -light.direction );
- }
- FP float diffuse = max( dot( s, n ), 0.0 );
+ FP float diffuse = max( dot( s, n ), 0.0 );
+
+ FP float specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP vec3 v = normalize( eye - vpos );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
- diffuseColor += att * light.intensity * diffuse * light.color;
+ diffuseColor += att * light.intensity * diffuse * light.color;
+ specularColor += att * light.intensity * specular * light.color;
+ }
}
void adModel(const in FP vec3 vpos, const in FP vec3 vnormal, out FP vec3 diffuseColor)
{
diffuseColor = vec3(0.0);
- if (lightCount < 1) return;
FP vec3 n = normalize( vnormal );
- addLightAdModel(vpos, n, lights[0], diffuseColor);
- if (lightCount < 2) return;
-
- addLightAdModel(vpos, n, lights[1], diffuseColor);
- if (lightCount < 3) return;
- addLightAdModel(vpos, n, lights[2], diffuseColor);
- if (lightCount < 4) return;
-
- addLightAdModel(vpos, n, lights[3], diffuseColor);
- if (lightCount < 5) return;
-
- addLightAdModel(vpos, n, lights[4], diffuseColor);
- if (lightCount < 6) return;
-
- addLightAdModel(vpos, n, lights[5], diffuseColor);
- if (lightCount < 7) return;
+ FP vec3 s;
+ Light light;
+ for (int i = 0; i < lightCount; ++i) {
+ if (i == 0)
+ light = lights[0];
+ else if (i == 1)
+ light = lights[1];
+ else if (i == 2)
+ light = lights[2];
+ else if (i == 3)
+ light = lights[3];
+ else if (i == 4)
+ light = lights[4];
+ else if (i == 5)
+ light = lights[5];
+ else if (i == 6)
+ light = lights[6];
+ else if (i == 7)
+ light = lights[7];
+
+ FP float att = 1.0;
+ if ( light.type != TYPE_DIRECTIONAL ) {
+ s = light.position - vpos;
+ if (length( light.attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( light.type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(light.direction))) ) > light.cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( -light.direction );
+ }
- addLightAdModel(vpos, n, lights[6], diffuseColor);
- if (lightCount < 8) return;
+ FP float diffuse = max( dot( s, n ), 0.0 );
- addLightAdModel(vpos, n, lights[7], diffuseColor);
+ diffuseColor += att * light.intensity * diffuse * light.color;
+ }
}
diff --git a/src/extras/shaders/gl3/metalrough.frag b/src/extras/shaders/gl3/metalrough.frag
index e1eb6bab2..7f2f3d20e 100644
--- a/src/extras/shaders/gl3/metalrough.frag
+++ b/src/extras/shaders/gl3/metalrough.frag
@@ -71,11 +71,6 @@ uniform sampler2D ambientOcclusionMap;
// User control parameters
uniform float metalFactor = 1.0;
-// Roughness -> mip level mapping
-uniform float maxT = 0.939824;
-uniform float mipLevels = 11.0;
-uniform float mipOffset = 5.0;
-
// Exposure correction
uniform float exposure = 0.0;
// Gamma correction
@@ -83,6 +78,25 @@ uniform float gamma = 2.2;
#pragma include light.inc.frag
+int mipLevelCount(const in samplerCube cube)
+{
+ int baseSize = textureSize(cube, 0).x;
+ int nMips = int(log2(float(baseSize>0 ? baseSize : 1))) + 1;
+ return nMips;
+}
+
+float remapRoughness(const in float roughness)
+{
+ // As per page 14 of
+ // http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
+ // we remap the roughness to give a more perceptually linear response
+ // of "bluriness" as a function of the roughness specified by the user.
+ // r = roughness^2
+ const float maxSpecPower = 999999.0;
+ const float minRoughness = sqrt(2.0 / (maxSpecPower + 2));
+ return max(roughness * roughness, minRoughness);
+}
+
mat3 calcWorldSpaceToTangentSpaceMatrix(const in vec3 wNormal, const in vec4 wTangent)
{
// Make the tangent truly orthogonal to the normal by using Gram-Schmidt.
@@ -103,32 +117,42 @@ mat3 calcWorldSpaceToTangentSpaceMatrix(const in vec3 wNormal, const in vec4 wTa
return worldToTangentMatrix;
}
-float roughnessToMipLevel(float roughness)
+float alphaToMipLevel(float alpha)
{
- // HACK: Improve the roughness -> mip level mapping for roughness map from substace painter
- // TODO: Use mathematica or similar to improve this mapping more generally
- roughness = 0.75 + (1.7 * (roughness - 0.5));
- return (mipLevels - 1.0 - mipOffset) * (1.0 - (1.0 - roughness) / maxT);
+ float specPower = 2.0 / (alpha * alpha) - 2.0;
+
+ // We use the mip level calculation from Lys' default power drop, which in
+ // turn is a slight modification of that used in Marmoset Toolbag. See
+ // https://docs.knaldtech.com/doku.php?id=specular_lys for details.
+ // For now we assume a max specular power of 999999 which gives
+ // maxGlossiness = 1.
+ const float k0 = 0.00098;
+ const float k1 = 0.9921;
+ float glossiness = (pow(2.0, -10.0 / sqrt(specPower)) - k0) / k1;
+
+ // TODO: Optimize by doing this on CPU and set as
+ // uniform int envLight.specularMipLevels say (if present in shader).
+ // Lookup the number of mips in the specular envmap
+ int mipLevels = mipLevelCount(envLight.specular);
+
+ // Offset of smallest miplevel we should use (corresponds to specular
+ // power of 1). I.e. in the 32x32 sized mip.
+ const float mipOffset = 5.0;
+
+ // The final factor is really 1 - g / g_max but as mentioned above g_max
+ // is 1 by definition here so we can avoid the division. If we make the
+ // max specular power for the spec map configurable, this will need to
+ // be handled properly.
+ float mipLevel = (mipLevels - 1.0 - mipOffset) * (1.0 - glossiness);
+ return mipLevel;
}
-// Helper function to map from linear roughness value to non-linear alpha (shininess)
-float roughnessToAlpha(const in float roughness)
+float normalDistribution(const in vec3 n, const in vec3 h, const in float alpha)
{
- // Constants to control how to convert from roughness [0,1] to
- // shininess (alpha) [minAlpha, maxAlpha] using a power law with
- // a power of 1 / rho.
- const float minAlpha = 1.0;
- const float maxAlpha = 1024.0;
- const float rho = 3.0;
-
- return minAlpha + (maxAlpha - minAlpha) * (1.0 - pow(roughness, 1.0 / rho));
-}
-
-float normalDistribution(const in vec3 n, const in vec3 h, const in float roughness)
-{
- // Blinn-Phong approximation
- float alpha = roughnessToAlpha(roughness);
- return (alpha + 2.0) / (2.0 * 3.14159) * pow(max(dot(n, h), 0.0), alpha);
+ // Blinn-Phong approximation - see
+ // http://graphicrants.blogspot.co.uk/2013/08/specular-brdf-reference.html
+ float specPower = 2.0 / (alpha * alpha) - 2.0;
+ return (specPower + 2.0) / (2.0 * 3.14159) * pow(max(dot(n, h), 0.0), specPower);
}
vec3 fresnelFactor(const in vec3 color, const in float cosineFactor)
@@ -176,7 +200,7 @@ vec3 pbrModel(const in int lightIndex,
const in vec3 wView,
const in vec3 baseColor,
const in float metalness,
- const in float roughness,
+ const in float alpha,
const in float ambientOcclusion)
{
// Calculate some useful quantities
@@ -234,7 +258,7 @@ vec3 pbrModel(const in int lightIndex,
vec3 specularFactor = vec3(0.0);
if (sDotN > 0.0) {
specularFactor = specularModel(F0, sDotH, sDotN, vDotN, n, h);
- specularFactor *= normalDistribution(n, h, roughness);
+ specularFactor *= normalDistribution(n, h, alpha);
}
vec3 specularColor = lights[lightIndex].color;
vec3 specular = specularColor * specularFactor;
@@ -252,7 +276,7 @@ vec3 pbrIblModel(const in vec3 wNormal,
const in vec3 wView,
const in vec3 baseColor,
const in float metalness,
- const in float roughness,
+ const in float alpha,
const in float ambientOcclusion)
{
// Calculate reflection direction of view vector about surface normal
@@ -277,7 +301,26 @@ vec3 pbrIblModel(const in vec3 wNormal,
vec3 F0 = mix(dielectricColor, baseColor, metalness);
vec3 specularFactor = specularModel(F0, lDotH, lDotN, vDotN, n, h);
- float lod = roughnessToMipLevel(roughness);
+ float lod = alphaToMipLevel(alpha);
+//#define DEBUG_SPECULAR_LODS
+#ifdef DEBUG_SPECULAR_LODS
+ if (lod > 7.0)
+ return vec3(1.0, 0.0, 0.0);
+ else if (lod > 6.0)
+ return vec3(1.0, 0.333, 0.0);
+ else if (lod > 5.0)
+ return vec3(1.0, 1.0, 0.0);
+ else if (lod > 4.0)
+ return vec3(0.666, 1.0, 0.0);
+ else if (lod > 3.0)
+ return vec3(0.0, 1.0, 0.666);
+ else if (lod > 2.0)
+ return vec3(0.0, 0.666, 1.0);
+ else if (lod > 1.0)
+ return vec3(0.0, 0.0, 1.0);
+ else if (lod > 0.0)
+ return vec3(1.0, 0.0, 1.0);
+#endif
vec3 specularSkyColor = textureLod(envLight.specular, l, lod).rgb;
vec3 specular = specularSkyColor * specularFactor;
@@ -317,12 +360,15 @@ void main()
vec3 tNormal = 2.0 * texture(normalMap, texCoord).rgb - vec3(1.0);
vec3 wNormal = normalize(transpose(worldToTangentMatrix) * tNormal);
+ // Remap roughness for a perceptually more linear correspondence
+ float alpha = remapRoughness(roughness);
+
for (int i = 0; i < envLightCount; ++i) {
cLinear += pbrIblModel(wNormal,
wView,
baseColor,
metalness,
- roughness,
+ alpha,
ambientOcclusion);
}
@@ -333,7 +379,7 @@ void main()
wView,
baseColor.rgb,
metalness,
- roughness,
+ alpha,
ambientOcclusion);
}
diff --git a/src/extras/shaders/gl3/metalroughuniform.frag b/src/extras/shaders/gl3/metalroughuniform.frag
index cccd31b52..f4bad0a00 100644
--- a/src/extras/shaders/gl3/metalroughuniform.frag
+++ b/src/extras/shaders/gl3/metalroughuniform.frag
@@ -66,11 +66,6 @@ uniform vec4 baseColor;
uniform float metalness;
uniform float roughness;
-// Roughness -> mip level mapping
-uniform float maxT = 0.939824;
-uniform float mipLevels = 11.0;
-uniform float mipOffset = 5.0;
-
// Exposure correction
uniform float exposure = 0.0;
// Gamma correction
@@ -78,6 +73,25 @@ uniform float gamma = 2.2;
#pragma include light.inc.frag
+int mipLevelCount(const in samplerCube cube)
+{
+ int baseSize = textureSize(cube, 0).x;
+ int nMips = int(log2(float(baseSize>0 ? baseSize : 1))) + 1;
+ return nMips;
+}
+
+float remapRoughness(const in float roughness)
+{
+ // As per page 14 of
+ // http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
+ // we remap the roughness to give a more perceptually linear response
+ // of "bluriness" as a function of the roughness specified by the user.
+ // r = roughness^2
+ const float maxSpecPower = 999999.0;
+ const float minRoughness = sqrt(2.0 / (maxSpecPower + 2));
+ return max(roughness * roughness, minRoughness);
+}
+
mat3 calcWorldSpaceToTangentSpaceMatrix(const in vec3 wNormal, const in vec4 wTangent)
{
// Make the tangent truly orthogonal to the normal by using Gram-Schmidt.
@@ -98,32 +112,42 @@ mat3 calcWorldSpaceToTangentSpaceMatrix(const in vec3 wNormal, const in vec4 wTa
return worldToTangentMatrix;
}
-float roughnessToMipLevel(float roughness)
-{
- // HACK: Improve the roughness -> mip level mapping for roughness map from substace painter
- // TODO: Use mathematica or similar to improve this mapping more generally
- roughness = 0.75 + (1.7 * (roughness - 0.5));
- return (mipLevels - 1.0 - mipOffset) * (1.0 - (1.0 - roughness) / maxT);
-}
-
-// Helper function to map from linear roughness value to non-linear alpha (shininess)
-float roughnessToAlpha(const in float roughness)
+float alphaToMipLevel(float alpha)
{
- // Constants to control how to convert from roughness [0,1] to
- // shininess (alpha) [minAlpha, maxAlpha] using a power law with
- // a power of 1 / rho.
- const float minAlpha = 1.0;
- const float maxAlpha = 1024.0;
- const float rho = 3.0;
-
- return minAlpha + (maxAlpha - minAlpha) * (1.0 - pow(roughness, 1.0 / rho));
+ float specPower = 2.0 / (alpha * alpha) - 2.0;
+
+ // We use the mip level calculation from Lys' default power drop, which in
+ // turn is a slight modification of that used in Marmoset Toolbag. See
+ // https://docs.knaldtech.com/doku.php?id=specular_lys for details.
+ // For now we assume a max specular power of 999999 which gives
+ // maxGlossiness = 1.
+ const float k0 = 0.00098;
+ const float k1 = 0.9921;
+ float glossiness = (pow(2.0, -10.0 / sqrt(specPower)) - k0) / k1;
+
+ // TODO: Optimize by doing this on CPU and set as
+ // uniform int envLight.specularMipLevels say (if present in shader).
+ // Lookup the number of mips in the specular envmap
+ int mipLevels = mipLevelCount(envLight.specular);
+
+ // Offset of smallest miplevel we should use (corresponds to specular
+ // power of 1). I.e. in the 32x32 sized mip.
+ const float mipOffset = 5.0;
+
+ // The final factor is really 1 - g / g_max but as mentioned above g_max
+ // is 1 by definition here so we can avoid the division. If we make the
+ // max specular power for the spec map configurable, this will need to
+ // be handled properly.
+ float mipLevel = (mipLevels - 1.0 - mipOffset) * (1.0 - glossiness);
+ return mipLevel;
}
-float normalDistribution(const in vec3 n, const in vec3 h, const in float roughness)
+float normalDistribution(const in vec3 n, const in vec3 h, const in float alpha)
{
- // Blinn-Phong approximation
- float alpha = roughnessToAlpha(roughness);
- return (alpha + 2.0) / (2.0 * 3.14159) * pow(max(dot(n, h), 0.0), alpha);
+ // Blinn-Phong approximation - see
+ // http://graphicrants.blogspot.co.uk/2013/08/specular-brdf-reference.html
+ float specPower = 2.0 / (alpha * alpha) - 2.0;
+ return (specPower + 2.0) / (2.0 * 3.14159) * pow(max(dot(n, h), 0.0), specPower);
}
vec3 fresnelFactor(const in vec3 color, const in float cosineFactor)
@@ -171,7 +195,7 @@ vec3 pbrModel(const in int lightIndex,
const in vec3 wView,
const in vec3 baseColor,
const in float metalness,
- const in float roughness)
+ const in float alpha)
{
// Calculate some useful quantities
vec3 n = wNormal;
@@ -228,7 +252,7 @@ vec3 pbrModel(const in int lightIndex,
vec3 specularFactor = vec3(0.0);
if (sDotN > 0.0) {
specularFactor = specularModel(F0, sDotH, sDotN, vDotN, n, h);
- specularFactor *= normalDistribution(n, h, roughness);
+ specularFactor *= normalDistribution(n, h, alpha);
}
vec3 specularColor = lights[lightIndex].color;
vec3 specular = specularColor * specularFactor;
@@ -241,7 +265,7 @@ vec3 pbrIblModel(const in vec3 wNormal,
const in vec3 wView,
const in vec3 baseColor,
const in float metalness,
- const in float roughness)
+ const in float alpha)
{
// Calculate reflection direction of view vector about surface normal
// vector in world space. This is used in the fragment shader to sample
@@ -265,7 +289,31 @@ vec3 pbrIblModel(const in vec3 wNormal,
vec3 F0 = mix(dielectricColor, baseColor, metalness);
vec3 specularFactor = specularModel(F0, lDotH, lDotN, vDotN, n, h);
- float lod = roughnessToMipLevel(roughness);
+ // As per page 14 of
+ // http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
+ // we remap the roughness to give a more perceptually linear response
+ // of "bluriness" as a function of the roughness specified by the user.
+ // r = roughness^2
+ float lod = alphaToMipLevel(alpha);
+//#define DEBUG_SPECULAR_LODS
+#ifdef DEBUG_SPECULAR_LODS
+ if (lod > 7.0)
+ return vec3(1.0, 0.0, 0.0);
+ else if (lod > 6.0)
+ return vec3(1.0, 0.333, 0.0);
+ else if (lod > 5.0)
+ return vec3(1.0, 1.0, 0.0);
+ else if (lod > 4.0)
+ return vec3(0.666, 1.0, 0.0);
+ else if (lod > 3.0)
+ return vec3(0.0, 1.0, 0.666);
+ else if (lod > 2.0)
+ return vec3(0.0, 0.666, 1.0);
+ else if (lod > 1.0)
+ return vec3(0.0, 0.0, 1.0);
+ else if (lod > 0.0)
+ return vec3(1.0, 0.0, 1.0);
+#endif
vec3 specularSkyColor = textureLod(envLight.specular, l, lod).rgb;
vec3 specular = specularSkyColor * specularFactor;
@@ -287,23 +335,28 @@ void main()
{
vec3 cLinear = vec3(0.0);
+ // Remap roughness for a perceptually more linear correspondence
+ float alpha = remapRoughness(roughness);
+
+
+ vec3 wNormal = normalize(worldNormal);
vec3 worldView = normalize(eyePosition - worldPosition);
for (int i = 0; i < envLightCount; ++i) {
- cLinear += pbrIblModel(worldNormal,
+ cLinear += pbrIblModel(wNormal,
worldView,
baseColor.rgb,
metalness,
- roughness);
+ alpha);
}
for (int i = 0; i < lightCount; ++i) {
cLinear += pbrModel(i,
worldPosition,
- worldNormal,
+ wNormal,
worldView,
baseColor.rgb,
metalness,
- roughness);
+ alpha);
}
// Apply exposure correction
diff --git a/src/extras/text/qdistancefieldglyphcache.cpp b/src/extras/text/qdistancefieldglyphcache.cpp
index aacccc7dc..99085f378 100644
--- a/src/extras/text/qdistancefieldglyphcache.cpp
+++ b/src/extras/text/qdistancefieldglyphcache.cpp
@@ -61,7 +61,7 @@ namespace Qt3DExtras {
class StoredGlyph {
public:
StoredGlyph() = default;
- StoredGlyph(const StoredGlyph &other) = default;
+ StoredGlyph(const StoredGlyph &) = default;
StoredGlyph(const QRawFont &font, quint32 glyph, bool doubleResolution);
int refCount() const { return m_ref; }
@@ -272,7 +272,7 @@ DistanceFieldFont* QDistanceFieldGlyphCache::getOrCreateDistanceFieldFont(const
// return, if font already exists (make sure to only create one DistanceFieldFont for
// each unique QRawFont, by building a hash on the QRawFont that ignores the font size)
const QString key = fontKey(font);
- const auto it = m_fonts.find(key);
+ const auto it = m_fonts.constFind(key);
if (it != m_fonts.cend())
return it.value();
diff --git a/src/input/backend/inputhandler.cpp b/src/input/backend/inputhandler.cpp
index 985d67470..525a45b6c 100644
--- a/src/input/backend/inputhandler.cpp
+++ b/src/input/backend/inputhandler.cpp
@@ -163,6 +163,7 @@ void InputHandler::clearPendingMouseEvents()
m_pendingMouseEvents.clear();
}
+#if QT_CONFIG(wheelevent)
void InputHandler::appendWheelEvent(const QT_PREPEND_NAMESPACE(QWheelEvent) &event)
{
QMutexLocker lock(&m_mutex);
@@ -180,7 +181,7 @@ void InputHandler::clearPendingWheelEvents()
QMutexLocker lock(&m_mutex);
m_pendingWheelEvents.clear();
}
-
+#endif
void InputHandler::appendKeyboardDevice(HKeyboardDevice device)
{
@@ -249,15 +250,23 @@ QVector<Qt3DCore::QAspectJobPtr> InputHandler::mouseJobs()
{
QVector<QAspectJobPtr> jobs;
const QList<QT_PREPEND_NAMESPACE(QMouseEvent)> mouseEvents = pendingMouseEvents();
+#if QT_CONFIG(wheelevent)
const QList<QT_PREPEND_NAMESPACE(QWheelEvent)> wheelEvents = pendingWheelEvents();
+#endif
for (const HMouseDevice cHandle : qAsConst(m_activeMouseDevices)) {
MouseDevice *controller = m_mouseDeviceManager->data(cHandle);
controller->updateMouseEvents(mouseEvents);
+#if QT_CONFIG(wheelevent)
controller->updateWheelEvents(wheelEvents);
+#endif
// Event dispacthing job
- if (!mouseEvents.isEmpty() || !wheelEvents.empty()) {
+ if (!mouseEvents.isEmpty()
+#if QT_CONFIG(wheelevent)
+ || !wheelEvents.empty()
+#endif
+ ) {
// Send the events to the mouse handlers that have for sourceDevice controller
const QVector<HMouseHandler> activeMouseHandlers = m_mouseInputManager->activeHandles();
for (HMouseHandler mouseHandlerHandle : activeMouseHandlers) {
@@ -267,8 +276,11 @@ QVector<Qt3DCore::QAspectJobPtr> InputHandler::mouseJobs()
if (mouseHandler->mouseDevice() == controller->peerId()) {
MouseEventDispatcherJob *job = new MouseEventDispatcherJob(mouseHandler->peerId(),
- mouseEvents,
- wheelEvents);
+ mouseEvents
+#if QT_CONFIG(wheelevent)
+ , wheelEvents
+#endif
+ );
job->setInputHandler(this);
jobs.append(QAspectJobPtr(job));
}
diff --git a/src/input/backend/inputhandler_p.h b/src/input/backend/inputhandler_p.h
index e80441f1a..a2a38262d 100644
--- a/src/input/backend/inputhandler_p.h
+++ b/src/input/backend/inputhandler_p.h
@@ -127,9 +127,11 @@ public:
QList<QT_PREPEND_NAMESPACE(QMouseEvent)> pendingMouseEvents();
void clearPendingMouseEvents();
+#if QT_CONFIG(wheelevent)
void appendWheelEvent(const QT_PREPEND_NAMESPACE(QWheelEvent) &event);
QList<QT_PREPEND_NAMESPACE(QWheelEvent)> pendingWheelEvents();
void clearPendingWheelEvents();
+#endif
void appendKeyboardDevice(HKeyboardDevice device);
void removeKeyboardDevice(HKeyboardDevice device);
@@ -170,7 +172,9 @@ private:
QList<QT_PREPEND_NAMESPACE(QKeyEvent)> m_pendingKeyEvents;
QList<QT_PREPEND_NAMESPACE(QMouseEvent)> m_pendingMouseEvents;
+#if QT_CONFIG(wheelevent)
QList<QT_PREPEND_NAMESPACE(QWheelEvent)> m_pendingWheelEvents;
+#endif
mutable QMutex m_mutex;
AxisManager *m_axisManager;
diff --git a/src/input/backend/mousedevice.cpp b/src/input/backend/mousedevice.cpp
index 1d329252d..128988637 100644
--- a/src/input/backend/mousedevice.cpp
+++ b/src/input/backend/mousedevice.cpp
@@ -135,6 +135,7 @@ float MouseDevice::sensitivity() const
return m_sensitivity;
}
+#if QT_CONFIG(wheelevent)
void MouseDevice::updateWheelEvents(const QList<QT_PREPEND_NAMESPACE (QWheelEvent)> &events)
{
// Reset axis values before we accumulate new values for this frame
@@ -147,6 +148,7 @@ void MouseDevice::updateWheelEvents(const QList<QT_PREPEND_NAMESPACE (QWheelEven
}
}
}
+#endif
void MouseDevice::updateMouseEvents(const QList<QT_PREPEND_NAMESPACE(QMouseEvent)> &events)
{
diff --git a/src/input/backend/mousedevice_p.h b/src/input/backend/mousedevice_p.h
index 0b95c6183..a085194ff 100644
--- a/src/input/backend/mousedevice_p.h
+++ b/src/input/backend/mousedevice_p.h
@@ -99,7 +99,9 @@ public:
bool isButtonPressed(int buttonIdentifier) const Q_DECL_OVERRIDE;
void updateMouseEvents(const QList<QT_PREPEND_NAMESPACE(QMouseEvent)> &events);
+#if QT_CONFIG(wheelevent)
void updateWheelEvents(const QList<QT_PREPEND_NAMESPACE(QWheelEvent)> &events);
+#endif
MouseState mouseState() const;
QPointF previousPos() const;
diff --git a/src/input/backend/mouseeventdispatcherjob.cpp b/src/input/backend/mouseeventdispatcherjob.cpp
index 77eb69712..11653d8a8 100644
--- a/src/input/backend/mouseeventdispatcherjob.cpp
+++ b/src/input/backend/mouseeventdispatcherjob.cpp
@@ -50,13 +50,18 @@ namespace Qt3DInput {
namespace Input {
MouseEventDispatcherJob::MouseEventDispatcherJob(Qt3DCore::QNodeId input,
- const QList<QT_PREPEND_NAMESPACE (QMouseEvent)> &mouseEvents,
- const QList<QT_PREPEND_NAMESPACE (QWheelEvent)> &wheelEvents)
+ const QList<QT_PREPEND_NAMESPACE (QMouseEvent)> &mouseEvents
+#if QT_CONFIG(wheelevent)
+ , const QList<QT_PREPEND_NAMESPACE (QWheelEvent)> &wheelEvents
+#endif
+ )
: QAspectJob()
, m_inputHandler(nullptr)
, m_mouseInput(input)
, m_mouseEvents(mouseEvents)
+#if QT_CONFIG(wheelevent)
, m_wheelEvents(wheelEvents)
+#endif
{
SET_JOB_RUN_STAT_TYPE(this, JobTypes::MouseEventDispatcher, 0);
}
@@ -73,8 +78,10 @@ void MouseEventDispatcherJob::run()
// Send mouse and wheel events to frontend
for (const QT_PREPEND_NAMESPACE(QMouseEvent) &e : m_mouseEvents)
input->mouseEvent(QMouseEventPtr(new QMouseEvent(e)));
+#if QT_CONFIG(wheelevent)
for (const QT_PREPEND_NAMESPACE(QWheelEvent) &e : m_wheelEvents)
input->wheelEvent(QWheelEventPtr(new QWheelEvent(e)));
+#endif
}
}
diff --git a/src/input/backend/mouseeventdispatcherjob_p.h b/src/input/backend/mouseeventdispatcherjob_p.h
index ebf1538e4..366774005 100644
--- a/src/input/backend/mouseeventdispatcherjob_p.h
+++ b/src/input/backend/mouseeventdispatcherjob_p.h
@@ -66,8 +66,11 @@ class MouseEventDispatcherJob : public Qt3DCore::QAspectJob
{
public:
explicit MouseEventDispatcherJob(Qt3DCore::QNodeId input,
- const QList<QT_PREPEND_NAMESPACE(QMouseEvent)> &mouseEvents,
- const QList<QT_PREPEND_NAMESPACE(QWheelEvent)> &wheelEvents);
+ const QList<QT_PREPEND_NAMESPACE(QMouseEvent)> &mouseEvents
+#if QT_CONFIG(wheelevent)
+ , const QList<QT_PREPEND_NAMESPACE(QWheelEvent)> &wheelEvents
+#endif
+ );
void setInputHandler(InputHandler *handler);
void run() Q_DECL_FINAL;
@@ -75,7 +78,9 @@ private:
InputHandler *m_inputHandler;
const Qt3DCore::QNodeId m_mouseInput;
const QList<QT_PREPEND_NAMESPACE(QMouseEvent)> m_mouseEvents;
+#if QT_CONFIG(wheelevent)
const QList<QT_PREPEND_NAMESPACE(QWheelEvent)> m_wheelEvents;
+#endif
};
} // namespace Input
diff --git a/src/input/backend/mouseeventfilter.cpp b/src/input/backend/mouseeventfilter.cpp
index bc2473a33..618a64b15 100644
--- a/src/input/backend/mouseeventfilter.cpp
+++ b/src/input/backend/mouseeventfilter.cpp
@@ -80,10 +80,12 @@ bool MouseEventFilter::eventFilter(QObject *obj, QEvent *e)
// Creates copy and store event to be processed later on in an InputAspect job
m_inputHandler->appendMouseEvent(QMouseEvent(*static_cast<QMouseEvent *>(e)));
break;
+#if QT_CONFIG(wheelevent)
case QEvent::Wheel:
// Creates copy and store event to be processed later on in an InputAspect job
m_inputHandler->appendWheelEvent(QWheelEvent(*static_cast<QWheelEvent *>(e)));
break;
+#endif
default:
break;
}
diff --git a/src/input/backend/mousehandler.cpp b/src/input/backend/mousehandler.cpp
index a0619aaf2..c492dcf28 100644
--- a/src/input/backend/mousehandler.cpp
+++ b/src/input/backend/mousehandler.cpp
@@ -91,6 +91,7 @@ void MouseHandler::mouseEvent(const QMouseEventPtr &event)
notifyObservers(e);
}
+#if QT_CONFIG(wheelevent)
void MouseHandler::wheelEvent(const QWheelEventPtr &event)
{
auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
@@ -99,6 +100,7 @@ void MouseHandler::wheelEvent(const QWheelEventPtr &event)
e->setValue(QVariant::fromValue(event));
notifyObservers(e);
}
+#endif
void MouseHandler::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
{
diff --git a/src/input/backend/mousehandler_p.h b/src/input/backend/mousehandler_p.h
index 867764017..ae484d8d6 100644
--- a/src/input/backend/mousehandler_p.h
+++ b/src/input/backend/mousehandler_p.h
@@ -70,7 +70,9 @@ public:
Qt3DCore::QNodeId mouseDevice() const;
void setInputHandler(InputHandler *handler);
void mouseEvent(const QMouseEventPtr &event);
+#if QT_CONFIG(wheelevent)
void wheelEvent(const QWheelEventPtr &event);
+#endif
protected:
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE;
diff --git a/src/input/frontend/qinputdeviceintegrationfactory.cpp b/src/input/frontend/qinputdeviceintegrationfactory.cpp
index 052f2d2b2..957b33542 100644
--- a/src/input/frontend/qinputdeviceintegrationfactory.cpp
+++ b/src/input/frontend/qinputdeviceintegrationfactory.cpp
@@ -74,6 +74,7 @@ QStringList QInputDeviceIntegrationFactory::keys(const QString &pluginPath)
list.append(loader()->keyMap().values());
return list;
#else
+ Q_UNUSED(pluginPath);
return QStringList();
#endif
}
@@ -88,6 +89,10 @@ QInputDeviceIntegration *QInputDeviceIntegrationFactory::create(const QString &n
}
if (QInputDeviceIntegration *ret = qLoadPlugin<QInputDeviceIntegration, QInputDevicePlugin>(loader(), name, args))
return ret;
+#else
+ Q_UNUSED(name);
+ Q_UNUSED(args);
+ Q_UNUSED(pluginPath);
#endif
return nullptr;
}
diff --git a/src/input/frontend/qkeyevent.h b/src/input/frontend/qkeyevent.h
index 23fed5545..e028438ce 100644
--- a/src/input/frontend/qkeyevent.h
+++ b/src/input/frontend/qkeyevent.h
@@ -78,7 +78,9 @@ public:
inline bool isAccepted() const { return m_event.isAccepted(); }
inline void setAccepted(bool accepted) { m_event.setAccepted(accepted); }
inline QEvent::Type type() const { return m_event.type(); }
+#if QT_CONFIG(shortcut)
Q_INVOKABLE bool matches(QKeySequence::StandardKey key_) const { return m_event.matches(key_); }
+#endif
private:
QT_PREPEND_NAMESPACE(QKeyEvent) m_event;
diff --git a/src/input/frontend/qmouseevent.cpp b/src/input/frontend/qmouseevent.cpp
index b1574f623..62f7a097e 100644
--- a/src/input/frontend/qmouseevent.cpp
+++ b/src/input/frontend/qmouseevent.cpp
@@ -455,6 +455,7 @@ QMouseEvent::Modifiers QMouseEvent::modifiers() const
* Returns the QEvent::Type of the event.
*/
+#if QT_CONFIG(wheelevent)
/*!
* Constructs a new QWheelEvent instance from the QWheelEvent \a e.
*/
@@ -497,6 +498,7 @@ QWheelEvent::Modifiers QWheelEvent::modifiers() const
return QWheelEvent::NoModifier;
}
}
+#endif // QT_CONFIG(wheelevent)
} // namespace Qt3DInput
diff --git a/src/input/frontend/qmouseevent.h b/src/input/frontend/qmouseevent.h
index 043f1023d..63786ac28 100644
--- a/src/input/frontend/qmouseevent.h
+++ b/src/input/frontend/qmouseevent.h
@@ -85,7 +85,13 @@ public:
inline int x() const { return m_event.x(); }
inline int y() const { return m_event.y(); }
- inline bool wasHeld() const { return static_cast<Qt::GestureType>(m_event.type()) == Qt::TapAndHoldGesture; }
+ inline bool wasHeld() const {
+#if QT_CONFIG(gestures)
+ return static_cast<Qt::GestureType>(m_event.type()) == Qt::TapAndHoldGesture;
+#else
+ return false;
+#endif
+ }
Buttons button() const;
int buttons() const;
Modifiers modifiers() const;
@@ -100,6 +106,7 @@ private:
typedef QSharedPointer<QMouseEvent> QMouseEventPtr;
+#if QT_CONFIG(wheelevent)
class QT3DINPUTSHARED_EXPORT QWheelEvent : public QObject
{
Q_OBJECT
@@ -148,12 +155,16 @@ private:
};
typedef QSharedPointer<QWheelEvent> QWheelEventPtr;
+#endif
} // namespace Qt3DInput
QT_END_NAMESPACE
Q_DECLARE_METATYPE(Qt3DInput::QMouseEvent*) // LCOV_EXCL_LINE
+
+#if QT_CONFIG(wheelevent)
Q_DECLARE_METATYPE(Qt3DInput::QWheelEvent*) // LCOV_EXCL_LINE
+#endif
#endif // QT3DINPUT_QMOUSEEVENT_H
diff --git a/src/input/frontend/qmousehandler.cpp b/src/input/frontend/qmousehandler.cpp
index 750251be9..419052d8a 100644
--- a/src/input/frontend/qmousehandler.cpp
+++ b/src/input/frontend/qmousehandler.cpp
@@ -83,9 +83,11 @@ void QMouseHandlerPrivate::mouseEvent(const QMouseEventPtr &event)
m_pressAndHoldTimer->stop();
emit q->released(event.data());
break;
+#if QT_CONFIG(gestures)
case Qt::TapGesture:
emit q->clicked(event.data());
break;
+#endif
case QEvent::MouseButtonDblClick:
emit q->doubleClicked(event.data());
break;
@@ -311,9 +313,11 @@ void QMouseHandler::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
if (e->propertyName() == QByteArrayLiteral("mouse")) {
QMouseEventPtr ev = e->value().value<QMouseEventPtr>();
d->mouseEvent(ev);
+#if QT_CONFIG(wheelevent)
} else if (e->propertyName() == QByteArrayLiteral("wheel")) {
QWheelEventPtr ev = e->value().value<QWheelEventPtr>();
emit wheel(ev.data());
+#endif
}
}
}
diff --git a/src/input/frontend/qmousehandler.h b/src/input/frontend/qmousehandler.h
index 750ed394d..ef4267c5c 100644
--- a/src/input/frontend/qmousehandler.h
+++ b/src/input/frontend/qmousehandler.h
@@ -82,7 +82,9 @@ Q_SIGNALS:
void pressAndHold(Qt3DInput::QMouseEvent *mouse);
void positionChanged(Qt3DInput::QMouseEvent *mouse);
+#if QT_CONFIG(wheelevent)
void wheel(Qt3DInput::QWheelEvent *wheel);
+#endif
protected:
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) Q_DECL_OVERRIDE;
diff --git a/src/logic/executor.cpp b/src/logic/executor.cpp
index ab4ac154d..6134e801e 100644
--- a/src/logic/executor.cpp
+++ b/src/logic/executor.cpp
@@ -96,7 +96,7 @@ void Executor::processLogicFrameUpdates(float dt)
const QVector<QNode *> nodes = m_scene->lookupNodes(m_nodeIds);
for (QNode *node : nodes) {
QFrameAction *frameAction = qobject_cast<QFrameAction *>(node);
- if (frameAction)
+ if (frameAction && frameAction->isEnabled())
frameAction->onTriggered(dt);
}
diff --git a/src/plugins/geometryloaders/default/objgeometryloader.cpp b/src/plugins/geometryloaders/default/objgeometryloader.cpp
index 0f22acc66..b1fb1f931 100644
--- a/src/plugins/geometryloaders/default/objgeometryloader.cpp
+++ b/src/plugins/geometryloaders/default/objgeometryloader.cpp
@@ -219,7 +219,7 @@ bool ObjGeometryLoader::doLoad(QIODevice *ioDev, const QString &subMesh)
if (hasNormals)
m_normals.resize(vertexCount);
- for (QHash<FaceIndices, unsigned int>::const_iterator it = faceIndexMap.begin(), endIt = faceIndexMap.end(); it != endIt; ++it) {
+ for (auto it = faceIndexMap.cbegin(), endIt = faceIndexMap.cend(); it != endIt; ++it) {
m_points[it.value()] = positions[it.key().positionIndex];
if (hasTexCoords)
m_texCoords[it.value()] = std::numeric_limits<unsigned int>::max() != it.key().texCoordIndex ? texCoords[it.key().texCoordIndex] : QVector2D();
@@ -231,7 +231,7 @@ bool ObjGeometryLoader::doLoad(QIODevice *ioDev, const QString &subMesh)
const int indexCount = faceIndexVector.size();
m_indices.clear();
m_indices.reserve(indexCount);
- for (const FaceIndices faceIndices : faceIndexVector) {
+ for (const FaceIndices faceIndices : qAsConst(faceIndexVector)) {
const unsigned int i = faceIndexMap.value(faceIndices);
m_indices.append(i);
}
diff --git a/src/plugins/geometryloaders/geometryloaders.pro b/src/plugins/geometryloaders/geometryloaders.pro
index 8dd99deb5..764c615da 100644
--- a/src/plugins/geometryloaders/geometryloaders.pro
+++ b/src/plugins/geometryloaders/geometryloaders.pro
@@ -1,4 +1,4 @@
TEMPLATE = subdirs
-SUBDIRS += default
+qtConfig(regularexpression) : SUBDIRS += default
SUBDIRS += gltf
qtConfig(qt3d-fbxsdk) : SUBDIRS += fbx
diff --git a/src/plugins/sceneparsers/assimp/assimpimporter.cpp b/src/plugins/sceneparsers/assimp/assimpimporter.cpp
index 7e8681981..d5fc113e3 100644
--- a/src/plugins/sceneparsers/assimp/assimpimporter.cpp
+++ b/src/plugins/sceneparsers/assimp/assimpimporter.cpp
@@ -142,7 +142,7 @@ QMatrix4x4 aiMatrix4x4ToQMatrix4x4(const aiMatrix4x4 &matrix) Q_DECL_NOTHROW
/*!
* Returns a QString from \a str;
*/
-static inline QString aiStringToQString(const aiString &str)
+inline QString aiStringToQString(const aiString &str)
{
return QString::fromUtf8(str.data, int(str.length));
}
@@ -246,6 +246,21 @@ QAttribute *createAttribute(QBuffer *buffer,
return attribute;
}
+QTextureWrapMode::WrapMode wrapModeFromaiTextureMapMode(int mode)
+{
+ switch (mode) {
+ case aiTextureMapMode_Wrap:
+ return QTextureWrapMode::Repeat;
+ case aiTextureMapMode_Mirror:
+ return QTextureWrapMode::MirroredRepeat;
+ case aiTextureMapMode_Decal:
+ return QTextureWrapMode::ClampToBorder;
+ case aiTextureMapMode_Clamp:
+ default:
+ return QTextureWrapMode::ClampToEdge;
+ }
+}
+
} // anonymous
QStringList AssimpImporter::assimpSupportedFormatsList = AssimpImporter::assimpSupportedFormats();
@@ -428,7 +443,7 @@ Qt3DCore::QEntity *AssimpImporter::scene(const QString &id)
if (m_scene->m_animations.size() > 0) {
qWarning() << "No target found for " << m_scene->m_animations.size() << " animations!";
- for (Qt3DAnimation::QKeyframeAnimation *anim : m_scene->m_animations)
+ for (Qt3DAnimation::QKeyframeAnimation *anim : qAsConst(m_scene->m_animations))
delete anim;
m_scene->m_animations.clear();
}
@@ -490,7 +505,7 @@ Qt3DCore::QEntity *AssimpImporter::node(aiNode *node)
animations,
aiStringToQString(node->mName));
const auto morphTargetList = morphingAnimations.at(0)->morphTargetList();
- for (Qt3DAnimation::QMorphingAnimation *anim : animations) {
+ for (Qt3DAnimation::QMorphingAnimation *anim : qAsConst(animations)) {
anim->setParent(entityNode);
anim->setTarget(mesh);
anim->setMorphTargets(morphTargetList);
@@ -543,7 +558,7 @@ Qt3DCore::QEntity *AssimpImporter::node(aiNode *node)
animations,
aiStringToQString(node->mName));
- for (Qt3DAnimation::QKeyframeAnimation *anim : animations) {
+ for (Qt3DAnimation::QKeyframeAnimation *anim : qAsConst(animations)) {
anim->setTarget(transform);
anim->setParent(entityNode);
}
@@ -1237,18 +1252,28 @@ void AssimpImporter::copyMaterialTextures(QMaterial *material, aiMaterial *assim
for (unsigned int i = 0; i < sizeof(textureType)/sizeof(textureType[0]); i++) {
aiString path;
if (assimpMaterial->GetTexture(textureType[i], 0, &path) == AI_SUCCESS) {
- QString fullPath = m_sceneDir.absoluteFilePath(texturePath(path));
+ const QString fullPath = m_sceneDir.absoluteFilePath(texturePath(path));
// Load texture if not already loaded
- if (!m_scene->m_materialTextures.contains(fullPath)) {
- QAbstractTexture *tex = QAbstractNodeFactory::createNode<QTexture2D>("QTexture2D");
- QTextureImage *texImage = QAbstractNodeFactory::createNode<QTextureImage>("QTextureImage");
- texImage->setSource(QUrl::fromLocalFile(fullPath));
- tex->addTextureImage(texImage);
- m_scene->m_materialTextures.insert(fullPath, tex);
- qCDebug(AssimpImporterLog) << Q_FUNC_INFO << " Loaded Texture " << fullPath;
- }
+ QAbstractTexture *tex = QAbstractNodeFactory::createNode<QTexture2D>("QTexture2D");
+ QTextureImage *texImage = QAbstractNodeFactory::createNode<QTextureImage>("QTextureImage");
+ texImage->setSource(QUrl::fromLocalFile(fullPath));
+ tex->addTextureImage(texImage);
+
+ // Set proper wrapping mode
+ QTextureWrapMode wrapMode(QTextureWrapMode::Repeat);
+ int xMode = 0;
+ int yMode = 0;
+
+ if (assimpMaterial->Get(AI_MATKEY_MAPPINGMODE_U(textureType[i], 0), xMode) == aiReturn_SUCCESS)
+ wrapMode.setX(wrapModeFromaiTextureMapMode(xMode));
+ if (assimpMaterial->Get(AI_MATKEY_MAPPINGMODE_V(textureType[i], 0), yMode) == aiReturn_SUCCESS)
+ wrapMode.setY(wrapModeFromaiTextureMapMode(yMode));
+
+ tex->setWrapMode(wrapMode);
+
+ qCDebug(AssimpImporterLog) << Q_FUNC_INFO << " Loaded Texture " << fullPath;
setParameterValue(m_scene->m_textureToParameterName[textureType[i]],
- material, QVariant::fromValue(m_scene->m_materialTextures[fullPath]));
+ material, QVariant::fromValue(tex));
}
}
}
@@ -1297,8 +1322,9 @@ AssimpRawTextureImage::AssimpRawTextureImageFunctor::AssimpRawTextureImageFuncto
QTextureImageDataPtr AssimpRawTextureImage::AssimpRawTextureImageFunctor::operator()()
{
- QTextureImageDataPtr dataPtr;
- dataPtr->setData(m_data, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8);
+ QTextureImageDataPtr dataPtr = QTextureImageDataPtr::create();
+ // Note: we assume 4 components per pixel and not compressed for now
+ dataPtr->setData(m_data, 4, false);
return dataPtr;
}
diff --git a/src/plugins/sceneparsers/assimp/assimpimporter.h b/src/plugins/sceneparsers/assimp/assimpimporter.h
index 7335830f5..e37950981 100644
--- a/src/plugins/sceneparsers/assimp/assimpimporter.h
+++ b/src/plugins/sceneparsers/assimp/assimpimporter.h
@@ -143,7 +143,6 @@ private:
QMap<uint, QMaterial*> m_materials;
QMap<uint, QEffect *> m_effects;
QMap<uint, QAbstractTexture *> m_embeddedTextures;
- QMap<QString, QAbstractTexture *> m_materialTextures;
QMap<aiNode*, Qt3DCore::QEntity*> m_cameras;
QHash<aiTextureType, QString> m_textureToParameterName;
QVector<Qt3DAnimation::QKeyframeAnimation *> m_animations;
diff --git a/src/plugins/sceneparsers/gltf/gltfimporter.cpp b/src/plugins/sceneparsers/gltf/gltfimporter.cpp
index 6a10381df..78e230969 100644
--- a/src/plugins/sceneparsers/gltf/gltfimporter.cpp
+++ b/src/plugins/sceneparsers/gltf/gltfimporter.cpp
@@ -1546,7 +1546,7 @@ void GLTFImporter::processJSONExtensions(const QString &id, const QJsonObject &j
// level GLTF item.
if (id == KEY_COMMON_MAT) {
const auto lights = jsonObject.value(KEY_LIGHTS).toObject();
- for (auto lightKey : lights.keys()) {
+ for (const auto &lightKey : lights.keys()) {
const auto light = lights.value(lightKey).toObject();
auto lightType = light.value(KEY_TYPE).toString();
const auto lightValues = light.value(lightType).toObject();
diff --git a/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp b/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp
index 5fb1241d0..7921fce64 100644
--- a/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp
+++ b/src/plugins/sceneparsers/gltfexport/gltfexporter.cpp
@@ -370,7 +370,7 @@ bool GLTFExporter::exportScene(QEntity *sceneRoot, const QString &outDir,
QFile::Permissions targetPermissions = gltfFile.permissions();
// Copy exported scene to actual export directory
- for (auto sourceFileStr : m_exportedFiles) {
+ for (const auto &sourceFileStr : m_exportedFiles) {
QFileInfo fiSource(m_exportDir + sourceFileStr);
QFileInfo fiDestination(finalExportDir + sourceFileStr);
if (fiDestination.exists()) {
@@ -524,7 +524,7 @@ void GLTFExporter::copyTextures()
void GLTFExporter::createShaders()
{
qCDebug(GLTFExporterLog, "Creating shaders...");
- for (auto si : m_shaderInfo) {
+ for (const auto &si : m_shaderInfo) {
const QString fileName = m_exportDir + si.uri;
QFile f(fileName);
if (f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
@@ -940,11 +940,11 @@ void GLTFExporter::parseMeshes()
qCDebug(GLTFExporterLog, " Vertex buffer size (bytes): %i", vertexBuf.size());
qCDebug(GLTFExporterLog, " Index buffer size (bytes): %i", indexBuf.size());
QStringList sl;
- for (auto bv : meshInfo.views)
+ for (const auto &bv : meshInfo.views)
sl << bv.name;
qCDebug(GLTFExporterLog) << " buffer views:" << sl;
sl.clear();
- for (auto acc : meshInfo.accessors)
+ for (const auto &acc : meshInfo.accessors)
sl << acc.name;
qCDebug(GLTFExporterLog) << " accessors:" << sl;
qCDebug(GLTFExporterLog, " material: '%ls'",
@@ -1129,7 +1129,7 @@ QString GLTFExporter::addShaderInfo(QShaderProgram::ShaderType type, QByteArray
if (code.isEmpty())
return QString();
- for (auto si : m_shaderInfo) {
+ for (const auto &si : m_shaderInfo) {
if (si.type == QShaderProgram::Vertex && code == si.code)
return si.name;
}
@@ -1153,10 +1153,11 @@ bool GLTFExporter::saveScene()
QVector<MeshInfo::BufferView> bvList;
QVector<MeshInfo::Accessor> accList;
- for (auto mi : m_meshInfo.values()) {
- for (auto v : mi.views)
+ for (auto it = m_meshInfo.begin(); it != m_meshInfo.end(); ++it) {
+ auto &mi = it.value();
+ for (auto &v : mi.views)
bvList << v;
- for (auto acc : mi.accessors)
+ for (auto &acc : mi.accessors)
accList << acc;
}
@@ -1193,7 +1194,7 @@ bool GLTFExporter::saveScene()
m_obj["buffers"] = buffers;
QJsonObject bufferViews;
- for (auto bv : bvList) {
+ for (const auto &bv : bvList) {
QJsonObject bufferView;
bufferView["buffer"] = QStringLiteral("buf");
bufferView["byteLength"] = int(bv.length);
@@ -1206,7 +1207,7 @@ bool GLTFExporter::saveScene()
m_obj["bufferViews"] = bufferViews;
QJsonObject accessors;
- for (auto acc : accList) {
+ for (const auto &acc : accList) {
QJsonObject accessor;
accessor["bufferView"] = acc.bufferView;
accessor["byteOffset"] = int(acc.offset);
@@ -1220,7 +1221,8 @@ bool GLTFExporter::saveScene()
m_obj["accessors"] = accessors;
QJsonObject meshes;
- for (auto meshInfo : m_meshInfo.values()) {
+ for (auto it = m_meshInfo.begin(); it != m_meshInfo.end(); ++it) {
+ auto &meshInfo = it.value();
QJsonObject mesh;
mesh["name"] = meshInfo.originalName;
if (meshInfo.meshType != TypeNone) {
@@ -1234,7 +1236,7 @@ bool GLTFExporter::saveScene()
QJsonObject prim;
prim["mode"] = 4; // triangles
QJsonObject attrs;
- for (auto acc : meshInfo.accessors) {
+ for (const auto &acc : meshInfo.accessors) {
if (acc.usage != QStringLiteral("INDEX"))
attrs[acc.usage] = acc.name;
else
@@ -1283,7 +1285,7 @@ bool GLTFExporter::saveScene()
if (m_rootNodeEmpty) {
// Don't export the root node if it is there just to group the scene, so we don't get
// an extra empty node when we import the scene back.
- for (auto c : m_rootNode->children)
+ for (auto c : qAsConst(m_rootNode->children))
sceneNodes << exportNodes(c, nodes);
} else {
sceneNodes << exportNodes(m_rootNode, nodes);
@@ -1305,7 +1307,8 @@ bool GLTFExporter::saveScene()
// Lights must be declared as extensions to the top-level glTF object
QJsonObject lights;
- for (auto lightInfo : m_lightInfo.values()) {
+ for (auto it = m_lightInfo.begin(); it != m_lightInfo.end(); ++it) {
+ const auto &lightInfo = it.value();
QJsonObject light;
QJsonObject lightDetails;
QString type;
@@ -1406,7 +1409,7 @@ bool GLTFExporter::saveScene()
if (!gFilter->vendor().isEmpty())
graphicsApiFilterObj["vendor"] = gFilter->vendor();
QJsonArray extensions;
- for (auto extName : gFilter->extensions())
+ for (const auto &extName : gFilter->extensions())
extensions << extName;
if (!extensions.isEmpty())
graphicsApiFilterObj["extensions"] = extensions;
@@ -1485,7 +1488,7 @@ bool GLTFExporter::saveScene()
// Save shaders for custom materials
QJsonObject shaders;
- for (auto si : m_shaderInfo) {
+ for (const auto &si : m_shaderInfo) {
QJsonObject shaderObj;
shaderObj["uri"] = si.uri;
shaders[si.name] = shaderObj;
@@ -1572,7 +1575,7 @@ bool GLTFExporter::saveScene()
QByteArray pre = "<RCC><qresource prefix=\"/gltf_res\">\n";
QByteArray post = "</qresource></RCC>\n";
f.write(pre);
- for (auto file : m_exportedFiles) {
+ for (const auto &file : qAsConst(m_exportedFiles)) {
QString line = QString(QStringLiteral(" <file>%1</file>\n")).arg(file);
f.write(line.toUtf8());
}
@@ -1594,7 +1597,7 @@ void GLTFExporter::delNode(GLTFExporter::Node *n)
{
if (!n)
return;
- for (auto *c : n->children)
+ for (auto *c : qAsConst(n->children))
delNode(c);
delete n;
}
@@ -1604,7 +1607,7 @@ QString GLTFExporter::exportNodes(GLTFExporter::Node *n, QJsonObject &nodes)
QJsonObject node;
node["name"] = n->name;
QJsonArray children;
- for (auto c : n->children)
+ for (auto c : qAsConst(n->children))
children << exportNodes(c, nodes);
node["children"] = children;
if (auto transform = m_transformMap.value(n))
@@ -2060,7 +2063,7 @@ void GLTFExporter::setVarToJSonObject(QJsonObject &jsObj, const QString &key, co
jsObj[key] = var.value<float>();
break;
case QMetaType::QSize:
- jsObj[key] = size2jsvec(var.value<QSize>());
+ jsObj[key] = size2jsvec(var.toSize());
break;
case QMetaType::QVector2D:
jsObj[key] = vec2jsvec(var.value<QVector2D>());
diff --git a/src/plugins/sceneparsers/sceneparsers.pro b/src/plugins/sceneparsers/sceneparsers.pro
index befe08e41..cb274b472 100644
--- a/src/plugins/sceneparsers/sceneparsers.pro
+++ b/src/plugins/sceneparsers/sceneparsers.pro
@@ -1,5 +1,11 @@
TEMPLATE = subdirs
# QNX is not supported, and Linux GCC 4.9 on ARM chokes on the assimp
# sources (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66964).
-config_assimp|!cross_compile: SUBDIRS += assimp
-SUBDIRS += gltf gltfexport
+QT_FOR_CONFIG += 3dcore-private
+qtConfig(assimp):if(qtConfig(system-assimp)|!cross_compile): \
+ SUBDIRS += assimp
+SUBDIRS += gltf
+
+qtConfig(temporaryfile):qtConfig(regularexpression) {
+ SUBDIRS += gltfexport
+}
diff --git a/src/quick3d/imports/animation/plugins.qmltypes b/src/quick3d/imports/animation/plugins.qmltypes
new file mode 100644
index 000000000..08879ee52
--- /dev/null
+++ b/src/quick3d/imports/animation/plugins.qmltypes
@@ -0,0 +1,670 @@
+import QtQuick.tooling 1.2
+
+// This file describes the plugin-supplied types contained in the library.
+// It is used for QML tooling purposes only.
+//
+// This file was auto-generated by:
+// 'qmlplugindump -nonrelocatable Qt3D.Animation 2.9'
+
+Module {
+ dependencies: ["QtQuick 2.8"]
+ Component {
+ name: "Qt3DAnimation::Animation::Quick::Quick3DChannelMapper"
+ defaultProperty: "mappings"
+ prototype: "Qt3DAnimation::QChannelMapper"
+ exports: ["Qt3D.Animation/ChannelMapper 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property {
+ name: "mappings"
+ type: "Qt3DAnimation::QChannelMapping"
+ isList: true
+ isReadonly: true
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::QAbstractAnimation"
+ prototype: "QObject"
+ exports: ["Qt3D.Animation/AbstractAnimation 2.9"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "AnimationType"
+ values: {
+ "KeyframeAnimation": 1,
+ "MorphingAnimation": 2,
+ "VertexBlendAnimation": 3
+ }
+ }
+ Property { name: "animationName"; type: "string" }
+ Property { name: "animationType"; type: "QAbstractAnimation::AnimationType"; isReadonly: true }
+ Property { name: "position"; type: "float" }
+ Property { name: "duration"; type: "float"; isReadonly: true }
+ Signal {
+ name: "animationNameChanged"
+ Parameter { name: "name"; type: "string" }
+ }
+ Signal {
+ name: "positionChanged"
+ Parameter { name: "position"; type: "float" }
+ }
+ Signal {
+ name: "durationChanged"
+ Parameter { name: "duration"; type: "float" }
+ }
+ Method {
+ name: "setAnimationName"
+ Parameter { name: "name"; type: "string" }
+ }
+ Method {
+ name: "setPosition"
+ Parameter { name: "position"; type: "float" }
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::QAbstractAnimationClip"
+ prototype: "Qt3DCore::QNode"
+ exports: ["Qt3D.Animation/AbstractAnimationClip 2.9"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Property { name: "duration"; type: "float"; isReadonly: true }
+ Signal {
+ name: "durationChanged"
+ Parameter { name: "duration"; type: "float" }
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::QAbstractClipAnimator"
+ prototype: "Qt3DCore::QComponent"
+ exports: ["Qt3D.Animation/AbstractClipAnimator 2.9"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "Loops"
+ values: {
+ "Infinite": -1
+ }
+ }
+ Property { name: "running"; type: "bool" }
+ Property { name: "loops"; type: "int" }
+ Property { name: "channelMapper"; type: "Qt3DAnimation::QChannelMapper"; isPointer: true }
+ Signal {
+ name: "runningChanged"
+ Parameter { name: "running"; type: "bool" }
+ }
+ Signal {
+ name: "channelMapperChanged"
+ Parameter { name: "channelMapper"; type: "Qt3DAnimation::QChannelMapper"; isPointer: true }
+ }
+ Signal {
+ name: "loopCountChanged"
+ Parameter { name: "loops"; type: "int" }
+ }
+ Method {
+ name: "setRunning"
+ Parameter { name: "running"; type: "bool" }
+ }
+ Method {
+ name: "setChannelMapper"
+ Parameter { name: "channelMapper"; type: "Qt3DAnimation::QChannelMapper"; isPointer: true }
+ }
+ Method {
+ name: "setLoopCount"
+ Parameter { name: "loops"; type: "int" }
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::QAbstractClipBlendNode"
+ prototype: "Qt3DCore::QNode"
+ exports: ["Qt3D.Animation/AbstractClipBlendNode 2.9"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ }
+ Component {
+ name: "Qt3DAnimation::QAdditiveClipBlend"
+ prototype: "Qt3DAnimation::QAbstractClipBlendNode"
+ exports: ["Qt3D.Animation/AdditiveClipBlend 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "baseClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true }
+ Property {
+ name: "additiveClip"
+ type: "Qt3DAnimation::QAbstractClipBlendNode"
+ isPointer: true
+ }
+ Property { name: "additiveFactor"; type: "float" }
+ Signal {
+ name: "additiveFactorChanged"
+ Parameter { name: "additiveFactor"; type: "float" }
+ }
+ Signal {
+ name: "baseClipChanged"
+ Parameter { name: "baseClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true }
+ }
+ Signal {
+ name: "additiveClipChanged"
+ Parameter {
+ name: "additiveClip"
+ type: "Qt3DAnimation::QAbstractClipBlendNode"
+ isPointer: true
+ }
+ }
+ Method {
+ name: "setAdditiveFactor"
+ Parameter { name: "additiveFactor"; type: "float" }
+ }
+ Method {
+ name: "setBaseClip"
+ Parameter { name: "baseClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true }
+ }
+ Method {
+ name: "setAdditiveClip"
+ Parameter {
+ name: "additiveClip"
+ type: "Qt3DAnimation::QAbstractClipBlendNode"
+ isPointer: true
+ }
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::QAnimationClip"
+ prototype: "Qt3DAnimation::QAbstractAnimationClip"
+ exports: ["Qt3D.Animation/AnimationClip 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "clipData"; type: "Qt3DAnimation::QAnimationClipData" }
+ Signal {
+ name: "clipDataChanged"
+ Parameter { name: "clipData"; type: "Qt3DAnimation::QAnimationClipData" }
+ }
+ Method {
+ name: "setClipData"
+ Parameter { name: "clipData"; type: "Qt3DAnimation::QAnimationClipData" }
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::QAnimationClipLoader"
+ prototype: "Qt3DAnimation::QAbstractAnimationClip"
+ exports: ["Qt3D.Animation/AnimationClipLoader 2.9"]
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "Status"
+ values: {
+ "NotReady": 0,
+ "Ready": 1,
+ "Error": 2
+ }
+ }
+ Property { name: "source"; type: "QUrl" }
+ Property { name: "status"; type: "Status"; isReadonly: true }
+ Signal {
+ name: "sourceChanged"
+ Parameter { name: "source"; type: "QUrl" }
+ }
+ Signal {
+ name: "statusChanged"
+ Parameter { name: "status"; type: "Status" }
+ }
+ Method {
+ name: "setSource"
+ Parameter { name: "source"; type: "QUrl" }
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::QAnimationController"
+ prototype: "QObject"
+ Property { name: "activeAnimationGroup"; type: "int" }
+ Property { name: "position"; type: "float" }
+ Property { name: "positionScale"; type: "float" }
+ Property { name: "positionOffset"; type: "float" }
+ Property { name: "entity"; type: "Qt3DCore::QEntity"; isPointer: true }
+ Property { name: "recursive"; type: "bool" }
+ Signal {
+ name: "activeAnimationGroupChanged"
+ Parameter { name: "index"; type: "int" }
+ }
+ Signal {
+ name: "positionChanged"
+ Parameter { name: "position"; type: "float" }
+ }
+ Signal {
+ name: "positionScaleChanged"
+ Parameter { name: "scale"; type: "float" }
+ }
+ Signal {
+ name: "positionOffsetChanged"
+ Parameter { name: "offset"; type: "float" }
+ }
+ Signal {
+ name: "entityChanged"
+ Parameter { name: "entity"; type: "Qt3DCore::QEntity"; isPointer: true }
+ }
+ Signal {
+ name: "recursiveChanged"
+ Parameter { name: "recursive"; type: "bool" }
+ }
+ Method {
+ name: "setActiveAnimationGroup"
+ Parameter { name: "index"; type: "int" }
+ }
+ Method {
+ name: "setPosition"
+ Parameter { name: "position"; type: "float" }
+ }
+ Method {
+ name: "setPositionScale"
+ Parameter { name: "scale"; type: "float" }
+ }
+ Method {
+ name: "setPositionOffset"
+ Parameter { name: "offset"; type: "float" }
+ }
+ Method {
+ name: "setEntity"
+ Parameter { name: "entity"; type: "Qt3DCore::QEntity"; isPointer: true }
+ }
+ Method {
+ name: "setRecursive"
+ Parameter { name: "recursive"; type: "bool" }
+ }
+ Method {
+ name: "getAnimationIndex"
+ type: "int"
+ Parameter { name: "name"; type: "string" }
+ }
+ Method {
+ name: "getGroup"
+ type: "Qt3DAnimation::QAnimationGroup*"
+ Parameter { name: "index"; type: "int" }
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::QAnimationGroup"
+ prototype: "QObject"
+ Property { name: "name"; type: "string" }
+ Property { name: "position"; type: "float" }
+ Property { name: "duration"; type: "float"; isReadonly: true }
+ Signal {
+ name: "nameChanged"
+ Parameter { name: "name"; type: "string" }
+ }
+ Signal {
+ name: "positionChanged"
+ Parameter { name: "position"; type: "float" }
+ }
+ Signal {
+ name: "durationChanged"
+ Parameter { name: "duration"; type: "float" }
+ }
+ Method {
+ name: "setName"
+ Parameter { name: "name"; type: "string" }
+ }
+ Method {
+ name: "setPosition"
+ Parameter { name: "position"; type: "float" }
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::QBlendedClipAnimator"
+ prototype: "Qt3DAnimation::QAbstractClipAnimator"
+ exports: ["Qt3D.Animation/BlendedClipAnimator 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "blendTree"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true }
+ Signal {
+ name: "blendTreeChanged"
+ Parameter { name: "blendTree"; type: "QAbstractClipBlendNode"; isPointer: true }
+ }
+ Method {
+ name: "setBlendTree"
+ Parameter { name: "blendTree"; type: "QAbstractClipBlendNode"; isPointer: true }
+ }
+ }
+ Component { name: "Qt3DAnimation::QChannelMapper"; prototype: "Qt3DCore::QNode" }
+ Component {
+ name: "Qt3DAnimation::QChannelMapping"
+ prototype: "Qt3DCore::QNode"
+ exports: ["Qt3D.Animation/ChannelMapping 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "channelName"; type: "string" }
+ Property { name: "target"; type: "Qt3DCore::QNode"; isPointer: true }
+ Property { name: "property"; type: "string" }
+ Signal {
+ name: "channelNameChanged"
+ Parameter { name: "channelName"; type: "string" }
+ }
+ Signal {
+ name: "targetChanged"
+ Parameter { name: "target"; type: "Qt3DCore::QNode"; isPointer: true }
+ }
+ Signal {
+ name: "propertyChanged"
+ Parameter { name: "property"; type: "string" }
+ }
+ Method {
+ name: "setChannelName"
+ Parameter { name: "channelName"; type: "string" }
+ }
+ Method {
+ name: "setTarget"
+ Parameter { name: "target"; type: "Qt3DCore::QNode"; isPointer: true }
+ }
+ Method {
+ name: "setProperty"
+ Parameter { name: "property"; type: "string" }
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::QClipAnimator"
+ prototype: "Qt3DAnimation::QAbstractClipAnimator"
+ exports: ["Qt3D.Animation/ClipAnimator 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "clip"; type: "Qt3DAnimation::QAbstractAnimationClip"; isPointer: true }
+ Signal {
+ name: "clipChanged"
+ Parameter { name: "clip"; type: "Qt3DAnimation::QAbstractAnimationClip"; isPointer: true }
+ }
+ Method {
+ name: "setClip"
+ Parameter { name: "clip"; type: "Qt3DAnimation::QAbstractAnimationClip"; isPointer: true }
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::QClipBlendValue"
+ prototype: "Qt3DAnimation::QAbstractClipBlendNode"
+ exports: ["Qt3D.Animation/ClipBlendValue 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "clip"; type: "Qt3DAnimation::QAbstractAnimationClip"; isPointer: true }
+ Signal {
+ name: "clipChanged"
+ Parameter { name: "clip"; type: "Qt3DAnimation::QAbstractAnimationClip"; isPointer: true }
+ }
+ Method {
+ name: "setClip"
+ Parameter { name: "clip"; type: "Qt3DAnimation::QAbstractAnimationClip"; isPointer: true }
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::QKeyframeAnimation"
+ prototype: "Qt3DAnimation::QAbstractAnimation"
+ Enum {
+ name: "RepeatMode"
+ values: {
+ "None": 0,
+ "Constant": 1,
+ "Repeat": 2
+ }
+ }
+ Property { name: "framePositions"; type: "QVector<float>" }
+ Property { name: "target"; type: "Qt3DCore::QTransform"; isPointer: true }
+ Property { name: "easing"; type: "QEasingCurve" }
+ Property { name: "targetName"; type: "string" }
+ Property { name: "startMode"; type: "QKeyframeAnimation::RepeatMode" }
+ Property { name: "endMode"; type: "QKeyframeAnimation::RepeatMode" }
+ Signal {
+ name: "framePositionsChanged"
+ Parameter { name: "positions"; type: "QVector<float>" }
+ }
+ Signal {
+ name: "targetChanged"
+ Parameter { name: "target"; type: "Qt3DCore::QTransform"; isPointer: true }
+ }
+ Signal {
+ name: "easingChanged"
+ Parameter { name: "easing"; type: "QEasingCurve" }
+ }
+ Signal {
+ name: "targetNameChanged"
+ Parameter { name: "name"; type: "string" }
+ }
+ Signal {
+ name: "startModeChanged"
+ Parameter { name: "startMode"; type: "QKeyframeAnimation::RepeatMode" }
+ }
+ Signal {
+ name: "endModeChanged"
+ Parameter { name: "endMode"; type: "QKeyframeAnimation::RepeatMode" }
+ }
+ Method {
+ name: "setFramePositions"
+ Parameter { name: "positions"; type: "QVector<float>" }
+ }
+ Method {
+ name: "setTarget"
+ Parameter { name: "target"; type: "Qt3DCore::QTransform"; isPointer: true }
+ }
+ Method {
+ name: "setEasing"
+ Parameter { name: "easing"; type: "QEasingCurve" }
+ }
+ Method {
+ name: "setTargetName"
+ Parameter { name: "name"; type: "string" }
+ }
+ Method {
+ name: "setStartMode"
+ Parameter { name: "mode"; type: "RepeatMode" }
+ }
+ Method {
+ name: "setEndMode"
+ Parameter { name: "mode"; type: "RepeatMode" }
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::QLerpClipBlend"
+ prototype: "Qt3DAnimation::QAbstractClipBlendNode"
+ exports: ["Qt3D.Animation/LerpClipBlend 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "startClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true }
+ Property { name: "endClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true }
+ Property { name: "blendFactor"; type: "float" }
+ Signal {
+ name: "blendFactorChanged"
+ Parameter { name: "blendFactor"; type: "float" }
+ }
+ Signal {
+ name: "startClipChanged"
+ Parameter { name: "startClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true }
+ }
+ Signal {
+ name: "endClipChanged"
+ Parameter { name: "endClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true }
+ }
+ Method {
+ name: "setBlendFactor"
+ Parameter { name: "blendFactor"; type: "float" }
+ }
+ Method {
+ name: "setStartClip"
+ Parameter { name: "startClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true }
+ }
+ Method {
+ name: "setEndClip"
+ Parameter { name: "endClip"; type: "Qt3DAnimation::QAbstractClipBlendNode"; isPointer: true }
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::QMorphTarget"
+ prototype: "QObject"
+ Property { name: "attributeNames"; type: "QStringList"; isReadonly: true }
+ Signal {
+ name: "attributeNamesChanged"
+ Parameter { name: "attributeNames"; type: "QStringList" }
+ }
+ Method {
+ name: "fromGeometry"
+ type: "QMorphTarget*"
+ Parameter { name: "geometry"; type: "Qt3DRender::QGeometry"; isPointer: true }
+ Parameter { name: "attributes"; type: "QStringList" }
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::QMorphingAnimation"
+ prototype: "Qt3DAnimation::QAbstractAnimation"
+ Enum {
+ name: "Method"
+ values: {
+ "Normalized": 0,
+ "Relative": 1
+ }
+ }
+ Property { name: "targetPositions"; type: "QVector<float>" }
+ Property { name: "interpolator"; type: "float"; isReadonly: true }
+ Property { name: "target"; type: "Qt3DRender::QGeometryRenderer"; isPointer: true }
+ Property { name: "targetName"; type: "string" }
+ Property { name: "method"; type: "QMorphingAnimation::Method" }
+ Property { name: "easing"; type: "QEasingCurve" }
+ Signal {
+ name: "targetPositionsChanged"
+ Parameter { name: "targetPositions"; type: "QVector<float>" }
+ }
+ Signal {
+ name: "interpolatorChanged"
+ Parameter { name: "interpolator"; type: "float" }
+ }
+ Signal {
+ name: "targetChanged"
+ Parameter { name: "target"; type: "Qt3DRender::QGeometryRenderer"; isPointer: true }
+ }
+ Signal {
+ name: "targetNameChanged"
+ Parameter { name: "name"; type: "string" }
+ }
+ Signal {
+ name: "methodChanged"
+ Parameter { name: "method"; type: "QMorphingAnimation::Method" }
+ }
+ Signal {
+ name: "easingChanged"
+ Parameter { name: "easing"; type: "QEasingCurve" }
+ }
+ Method {
+ name: "setTargetPositions"
+ Parameter { name: "targetPositions"; type: "QVector<float>" }
+ }
+ Method {
+ name: "setTarget"
+ Parameter { name: "target"; type: "Qt3DRender::QGeometryRenderer"; isPointer: true }
+ }
+ Method {
+ name: "setTargetName"
+ Parameter { name: "name"; type: "string" }
+ }
+ Method {
+ name: "setMethod"
+ Parameter { name: "method"; type: "QMorphingAnimation::Method" }
+ }
+ Method {
+ name: "setEasing"
+ Parameter { name: "easing"; type: "QEasingCurve" }
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::Quick::QQuick3DAnimationController"
+ prototype: "Qt3DAnimation::QAnimationController"
+ exports: ["Qt3D.Animation/AnimationController 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property {
+ name: "animationGroups"
+ type: "Qt3DAnimation::QAnimationGroup"
+ isList: true
+ isReadonly: true
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::Quick::QQuick3DAnimationGroup"
+ prototype: "Qt3DAnimation::QAnimationGroup"
+ exports: ["Qt3D.Animation/AnimationGroup 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property {
+ name: "animations"
+ type: "Qt3DAnimation::QAbstractAnimation"
+ isList: true
+ isReadonly: true
+ }
+ }
+ Component {
+ name: "Qt3DAnimation::Quick::QQuick3DKeyframeAnimation"
+ prototype: "Qt3DAnimation::QKeyframeAnimation"
+ exports: ["Qt3D.Animation/KeyframeAnimation 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "keyframes"; type: "Qt3DCore::QTransform"; isList: true; isReadonly: true }
+ }
+ Component {
+ name: "Qt3DAnimation::Quick::QQuick3DMorphTarget"
+ prototype: "Qt3DAnimation::QMorphTarget"
+ exports: ["Qt3D.Animation/MorphTarget 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "attributes"; type: "Qt3DRender::QAttribute"; isList: true; isReadonly: true }
+ }
+ Component {
+ name: "Qt3DAnimation::Quick::QQuick3DMorphingAnimation"
+ prototype: "Qt3DAnimation::QMorphingAnimation"
+ exports: ["Qt3D.Animation/MorphingAnimation 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property {
+ name: "morphTargets"
+ type: "Qt3DAnimation::QMorphTarget"
+ isList: true
+ isReadonly: true
+ }
+ }
+ Component {
+ name: "Qt3DCore::QComponent"
+ prototype: "Qt3DCore::QNode"
+ Property { name: "isShareable"; type: "bool" }
+ Signal {
+ name: "shareableChanged"
+ Parameter { name: "isShareable"; type: "bool" }
+ }
+ Signal {
+ name: "addedToEntity"
+ Parameter { name: "entity"; type: "QEntity"; isPointer: true }
+ }
+ Signal {
+ name: "removedFromEntity"
+ Parameter { name: "entity"; type: "QEntity"; isPointer: true }
+ }
+ Method {
+ name: "setShareable"
+ Parameter { name: "isShareable"; type: "bool" }
+ }
+ }
+ Component {
+ name: "Qt3DCore::QNode"
+ prototype: "QObject"
+ Enum {
+ name: "PropertyTrackingMode"
+ values: {
+ "TrackFinalValues": 0,
+ "DontTrackValues": 1,
+ "TrackAllValues": 2
+ }
+ }
+ Property { name: "parent"; type: "Qt3DCore::QNode"; isPointer: true }
+ Property { name: "enabled"; type: "bool" }
+ Property { name: "defaultPropertyTrackingMode"; revision: 9; type: "PropertyTrackingMode" }
+ Signal {
+ name: "parentChanged"
+ Parameter { name: "parent"; type: "QObject"; isPointer: true }
+ }
+ Signal {
+ name: "enabledChanged"
+ Parameter { name: "enabled"; type: "bool" }
+ }
+ Signal {
+ name: "defaultPropertyTrackingModeChanged"
+ Parameter { name: "mode"; type: "PropertyTrackingMode" }
+ }
+ Signal { name: "nodeDestroyed" }
+ Method {
+ name: "setParent"
+ Parameter { name: "parent"; type: "QNode"; isPointer: true }
+ }
+ Method {
+ name: "setEnabled"
+ Parameter { name: "isEnabled"; type: "bool" }
+ }
+ Method {
+ name: "setDefaultPropertyTrackingMode"
+ Parameter { name: "mode"; type: "PropertyTrackingMode" }
+ }
+ }
+}
diff --git a/src/quick3d/imports/animation/qt3dquick3danimationplugin.cpp b/src/quick3d/imports/animation/qt3dquick3danimationplugin.cpp
index 87c137763..7feeaf84c 100644
--- a/src/quick3d/imports/animation/qt3dquick3danimationplugin.cpp
+++ b/src/quick3d/imports/animation/qt3dquick3danimationplugin.cpp
@@ -55,6 +55,7 @@
#include <Qt3DAnimation/qmorphinganimation.h>
#include <Qt3DAnimation/qanimationgroup.h>
#include <Qt3DAnimation/qmorphtarget.h>
+#include <Qt3DAnimation/qvertexblendanimation.h>
#include <Qt3DQuickAnimation/private/qt3dquickanimation_global_p.h>
#include <Qt3DQuickAnimation/private/quick3dchannelmapper_p.h>
@@ -63,6 +64,7 @@
#include <Qt3DQuickAnimation/private/quick3danimationcontroller_p.h>
#include <Qt3DQuickAnimation/private/quick3dmorphtarget_p.h>
#include <Qt3DQuickAnimation/private/quick3dmorphinganimation_p.h>
+#include <Qt3DQuickAnimation/private/quick3dvertexblendanimation_p.h>
QT_BEGIN_NAMESPACE
@@ -92,6 +94,7 @@ void Qt3DQuick3DAnimationPlugin::registerTypes(const char *uri)
qmlRegisterExtendedType<Qt3DAnimation::QAnimationController, Qt3DAnimation::Quick::QQuick3DAnimationController>(uri, 2, 9, "AnimationController");
qmlRegisterExtendedType<Qt3DAnimation::QMorphingAnimation, Qt3DAnimation::Quick::QQuick3DMorphingAnimation>(uri, 2, 9, "MorphingAnimation");
qmlRegisterExtendedType<Qt3DAnimation::QMorphTarget, Qt3DAnimation::Quick::QQuick3DMorphTarget>(uri, 2, 9, "MorphTarget");
+ qmlRegisterExtendedType<Qt3DAnimation::QVertexBlendAnimation, Qt3DAnimation::Quick::QQuick3DVertexBlendAnimation>(uri, 2, 9, "VertexBlendAnimation");
}
QT_END_NAMESPACE
diff --git a/src/quick3d/imports/core/plugins.qmltypes b/src/quick3d/imports/core/plugins.qmltypes
index ed06f8e0c..87cdac04c 100644
--- a/src/quick3d/imports/core/plugins.qmltypes
+++ b/src/quick3d/imports/core/plugins.qmltypes
@@ -4,29 +4,41 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable Qt3D.Core 2.0'
+// 'qmlplugindump -nonrelocatable Qt3D.Core 2.9'
Module {
- dependencies: ["QtQuick 2.7"]
+ dependencies: ["QtQuick 2.8"]
Component {
name: "Qt3DCore::QComponent"
- prototype: "Qt3DCore::QNode"
- Property { name: "isShareable"; type: "bool" }
+ defaultProperty: "data"
+ prototype: "Qt3DCore::QComponent"
+ Property { name: "propertyTrackingOverrides"; type: "QJSValue" }
+ Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
+ Property { name: "childNodes"; type: "Qt3DCore::QNode"; isList: true; isReadonly: true }
Signal {
- name: "shareableChanged"
- Parameter { name: "isShareable"; type: "bool" }
+ name: "propertyTrackingOverridesChanged"
+ Parameter { name: "value"; type: "QJSValue" }
}
- Method {
- name: "setShareable"
- Parameter { name: "isShareable"; type: "bool" }
+ Signal {
+ name: "propertyTrackingOverridesChanged"
+ Parameter { name: "value"; type: "QJSValue" }
}
}
Component { name: "Qt3DCore::QEntity"; prototype: "Qt3DCore::QNode" }
Component {
name: "Qt3DCore::QNode"
prototype: "QObject"
+ Enum {
+ name: "PropertyTrackingMode"
+ values: {
+ "TrackFinalValues": 0,
+ "DontTrackValues": 1,
+ "TrackAllValues": 2
+ }
+ }
Property { name: "parent"; type: "Qt3DCore::QNode"; isPointer: true }
Property { name: "enabled"; type: "bool" }
+ Property { name: "defaultPropertyTrackingMode"; revision: 9; type: "PropertyTrackingMode" }
Signal {
name: "parentChanged"
Parameter { name: "parent"; type: "QObject"; isPointer: true }
@@ -35,6 +47,10 @@ Module {
name: "enabledChanged"
Parameter { name: "enabled"; type: "bool" }
}
+ Signal {
+ name: "defaultPropertyTrackingModeChanged"
+ Parameter { name: "mode"; type: "PropertyTrackingMode" }
+ }
Signal { name: "nodeDestroyed" }
Method {
name: "setParent"
@@ -44,11 +60,14 @@ Module {
name: "setEnabled"
Parameter { name: "isEnabled"; type: "bool" }
}
+ Method {
+ name: "setDefaultPropertyTrackingMode"
+ Parameter { name: "mode"; type: "PropertyTrackingMode" }
+ }
}
Component {
name: "Qt3DCore::QTransform"
prototype: "Qt3DCore::QComponent"
- exports: ["Qt3D.Core/Transform 2.0"]
Property { name: "matrix"; type: "QMatrix4x4" }
Property { name: "scale"; type: "float" }
Property { name: "scale3D"; type: "QVector3D" }
@@ -230,10 +249,8 @@ Module {
Component {
name: "Qt3DCore::Quick::Quick3DEntityLoader"
defaultProperty: "data"
- prototype: "Qt3DCore::QEntity"
- exports: ["Qt3D.Core/EntityLoader 2.0"]
- Property { name: "entity"; type: "Qt3DCore::QEntity"; isPointer: true; isReadonly: true }
- Property { name: "source"; type: "QUrl" }
+ prototype: "Qt3DCore::Quick::Quick3DEntityLoader"
+ Property { name: "components"; type: "Qt3DCore::QComponent"; isList: true; isReadonly: true }
}
Component {
name: "Qt3DCore::Quick::Quick3DNode"
@@ -248,13 +265,36 @@ Module {
Component {
name: "Qt3DCore::Quick::Quick3DNodeInstantiator"
defaultProperty: "delegate"
+ prototype: "Qt3DCore::Quick::Quick3DNodeInstantiator"
+ Property { name: "propertyTrackingOverrides"; type: "QJSValue" }
+ Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
+ Property { name: "childNodes"; type: "Qt3DCore::QNode"; isList: true; isReadonly: true }
+ Signal {
+ name: "propertyTrackingOverridesChanged"
+ Parameter { name: "value"; type: "QJSValue" }
+ }
+ Signal {
+ name: "propertyTrackingOverridesChanged"
+ Parameter { name: "value"; type: "QJSValue" }
+ }
+ }
+ Component {
+ name: "Qt3DCore::Quick::Quick3DNodeV9"
+ defaultProperty: "data"
prototype: "Qt3DCore::QNode"
- exports: ["Qt3D.Core/NodeInstantiator 2.0"]
- Property { name: "active"; type: "bool" }
- Property { name: "asynchronous"; type: "bool" }
- Property { name: "model"; type: "QVariant" }
- Property { name: "count"; type: "int"; isReadonly: true }
- Property { name: "delegate"; type: "QQmlComponent" }
- Property { name: "object"; type: "QObject"; isReadonly: true }
+ exports: ["Qt3D.Core/Node 2.9"]
+ isCreatable: false
+ exportMetaObjectRevisions: [9]
+ Property { name: "propertyTrackingOverrides"; type: "QJSValue" }
+ Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
+ Property { name: "childNodes"; type: "Qt3DCore::QNode"; isList: true; isReadonly: true }
+ Signal {
+ name: "propertyTrackingOverridesChanged"
+ Parameter { name: "value"; type: "QJSValue" }
+ }
+ Signal {
+ name: "propertyTrackingOverridesChanged"
+ Parameter { name: "value"; type: "QJSValue" }
+ }
}
}
diff --git a/src/quick3d/imports/core/qt3dquick3dcoreplugin.cpp b/src/quick3d/imports/core/qt3dquick3dcoreplugin.cpp
index 6d2a78166..3ff63d9d9 100644
--- a/src/quick3d/imports/core/qt3dquick3dcoreplugin.cpp
+++ b/src/quick3d/imports/core/qt3dquick3dcoreplugin.cpp
@@ -71,4 +71,9 @@ void Qt3DQuick3DCorePlugin::registerTypes(const char *uri)
qmlRegisterExtendedUncreatableType<Qt3DCore::QNode, Qt3DCore::Quick::Quick3DNodeV9, 9>(uri, 2, 9, "Node", QStringLiteral("Node is a base class"));
}
+Qt3DQuick3DCorePlugin::~Qt3DQuick3DCorePlugin()
+{
+ Qt3DCore::Quick::Quick3D_uninitialize();
+}
+
QT_END_NAMESPACE
diff --git a/src/quick3d/imports/core/qt3dquick3dcoreplugin.h b/src/quick3d/imports/core/qt3dquick3dcoreplugin.h
index a9b215c4a..b0ef5947c 100644
--- a/src/quick3d/imports/core/qt3dquick3dcoreplugin.h
+++ b/src/quick3d/imports/core/qt3dquick3dcoreplugin.h
@@ -57,6 +57,7 @@ class Qt3DQuick3DCorePlugin : public QQmlExtensionPlugin
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
Qt3DQuick3DCorePlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { initResources(); }
+ ~Qt3DQuick3DCorePlugin();
void registerTypes(const char *uri) Q_DECL_OVERRIDE;
};
diff --git a/src/quick3d/imports/extras/plugins.qmltypes b/src/quick3d/imports/extras/plugins.qmltypes
index cbe12c9ad..a623f385c 100644
--- a/src/quick3d/imports/extras/plugins.qmltypes
+++ b/src/quick3d/imports/extras/plugins.qmltypes
@@ -4,68 +4,30 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable Qt3D.Extras 2.0'
+// 'qmlplugindump -nonrelocatable Qt3D.Extras 2.9'
Module {
- dependencies: []
- Component {
- name: "Qt3DCore::QComponent"
- prototype: "Qt3DCore::QNode"
- Property { name: "isShareable"; type: "bool" }
- Signal {
- name: "shareableChanged"
- Parameter { name: "isShareable"; type: "bool" }
- }
- Signal {
- name: "addedToEntity"
- Parameter { name: "entity"; type: "QEntity"; isPointer: true }
- }
- Signal {
- name: "removedFromEntity"
- Parameter { name: "entity"; type: "QEntity"; isPointer: true }
- }
- Method {
- name: "setShareable"
- Parameter { name: "isShareable"; type: "bool" }
- }
- }
+ dependencies: ["Qt3D.Logic 2.0"]
Component { name: "Qt3DCore::QEntity"; prototype: "Qt3DCore::QNode" }
Component {
- name: "Qt3DCore::QNode"
- prototype: "QObject"
- Property { name: "parent"; type: "Qt3DCore::QNode"; isPointer: true }
- Property { name: "enabled"; type: "bool" }
- Signal {
- name: "parentChanged"
- Parameter { name: "parent"; type: "QObject"; isPointer: true }
- }
- Signal {
- name: "enabledChanged"
- Parameter { name: "enabled"; type: "bool" }
- }
- Signal { name: "nodeDestroyed" }
- Method {
- name: "setParent"
- Parameter { name: "parent"; type: "QNode"; isPointer: true }
- }
- Method {
- name: "setEnabled"
- Parameter { name: "isEnabled"; type: "bool" }
- }
- }
- Component {
name: "Qt3DExtras::Extras::Quick::Quick3DLevelOfDetailLoader"
prototype: "Qt3DCore::QEntity"
- exports: ["Qt3D.Extras/LevelOfDetailLoader 2.2"]
+ exports: ["Qt3D.Extras/LevelOfDetailLoader 2.9"]
exportMetaObjectRevisions: [0]
Property { name: "sources"; type: "QVariantList" }
Property { name: "camera"; type: "Qt3DRender::QCamera"; isPointer: true }
Property { name: "currentIndex"; type: "int" }
Property { name: "thresholdType"; type: "Qt3DRender::QLevelOfDetail::ThresholdType" }
Property { name: "thresholds"; type: "QVector<qreal>" }
- Property { name: "volumeOverride"; type: "Qt3DRender::QBoundingSphere"; isPointer: true }
+ Property { name: "volumeOverride"; type: "Qt3DRender::QLevelOfDetailBoundingSphere" }
Property { name: "entity"; type: "QObject"; isReadonly: true; isPointer: true }
Property { name: "source"; type: "QUrl"; isReadonly: true }
+ Method {
+ name: "createBoundingSphere"
+ type: "Qt3DRender::QLevelOfDetailBoundingSphere"
+ Parameter { name: "center"; type: "QVector3D" }
+ Parameter { name: "radius"; type: "float" }
+ }
}
Component {
name: "Qt3DExtras::QConeGeometry"
@@ -590,6 +552,90 @@ Module {
}
}
Component {
+ name: "Qt3DExtras::QExtrudedTextGeometry"
+ prototype: "Qt3DRender::QGeometry"
+ exports: ["Qt3D.Extras/ExtrudedTextGeometry 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "text"; type: "string" }
+ Property { name: "font"; type: "QFont" }
+ Property { name: "extrusionLength"; type: "float" }
+ Property {
+ name: "positionAttribute"
+ type: "Qt3DRender::QAttribute"
+ isReadonly: true
+ isPointer: true
+ }
+ Property {
+ name: "normalAttribute"
+ type: "Qt3DRender::QAttribute"
+ isReadonly: true
+ isPointer: true
+ }
+ Property {
+ name: "indexAttribute"
+ type: "Qt3DRender::QAttribute"
+ isReadonly: true
+ isPointer: true
+ }
+ Signal {
+ name: "textChanged"
+ Parameter { name: "text"; type: "string" }
+ }
+ Signal {
+ name: "fontChanged"
+ Parameter { name: "font"; type: "QFont" }
+ }
+ Signal {
+ name: "depthChanged"
+ Parameter { name: "extrusionLength"; type: "float" }
+ }
+ Method {
+ name: "setText"
+ Parameter { name: "text"; type: "string" }
+ }
+ Method {
+ name: "setFont"
+ Parameter { name: "font"; type: "QFont" }
+ }
+ Method {
+ name: "setDepth"
+ Parameter { name: "extrusionLength"; type: "float" }
+ }
+ }
+ Component {
+ name: "Qt3DExtras::QExtrudedTextMesh"
+ prototype: "Qt3DRender::QGeometryRenderer"
+ exports: ["Qt3D.Extras/ExtrudedTextMesh 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "text"; type: "string" }
+ Property { name: "font"; type: "QFont" }
+ Property { name: "depth"; type: "float" }
+ Signal {
+ name: "textChanged"
+ Parameter { name: "text"; type: "string" }
+ }
+ Signal {
+ name: "fontChanged"
+ Parameter { name: "font"; type: "QFont" }
+ }
+ Signal {
+ name: "depthChanged"
+ Parameter { name: "depth"; type: "float" }
+ }
+ Method {
+ name: "setText"
+ Parameter { name: "text"; type: "string" }
+ }
+ Method {
+ name: "setFont"
+ Parameter { name: "font"; type: "QFont" }
+ }
+ Method {
+ name: "setDepth"
+ Parameter { name: "depth"; type: "float" }
+ }
+ }
+ Component {
name: "Qt3DExtras::QFirstPersonCameraController"
prototype: "Qt3DCore::QEntity"
exports: ["Qt3D.Extras/FirstPersonCameraController 2.0"]
@@ -599,6 +645,14 @@ Module {
Property { name: "lookSpeed"; type: "float" }
Property { name: "acceleration"; type: "float" }
Property { name: "deceleration"; type: "float" }
+ Signal {
+ name: "accelerationChanged"
+ Parameter { name: "acceleration"; type: "float" }
+ }
+ Signal {
+ name: "decelerationChanged"
+ Parameter { name: "deceleration"; type: "float" }
+ }
}
Component {
name: "Qt3DExtras::QForwardRenderer"
@@ -612,6 +666,7 @@ Module {
Property { name: "camera"; type: "Qt3DCore::QEntity"; isPointer: true }
Property { name: "externalRenderTargetSize"; type: "QSize" }
Property { name: "frustumCulling"; type: "bool" }
+ Property { name: "gamma"; revision: 9; type: "float" }
Signal {
name: "viewportRectChanged"
Parameter { name: "viewportRect"; type: "QRectF" }
@@ -636,6 +691,10 @@ Module {
name: "frustumCullingEnabledChanged"
Parameter { name: "enabled"; type: "bool" }
}
+ Signal {
+ name: "gammaChanged"
+ Parameter { name: "gamma"; type: "float" }
+ }
Method {
name: "setViewportRect"
Parameter { name: "viewportRect"; type: "QRectF" }
@@ -660,6 +719,10 @@ Module {
name: "setFrustumCullingEnabled"
Parameter { name: "enabled"; type: "bool" }
}
+ Method {
+ name: "setGamma"
+ Parameter { name: "gamma"; type: "float" }
+ }
}
Component {
name: "Qt3DExtras::QGoochMaterial"
@@ -733,18 +796,11 @@ Module {
Component {
name: "Qt3DExtras::QMetalRoughMaterial"
prototype: "Qt3DRender::QMaterial"
- exports: ["Qt3D.Extras/MetalRoughMaterial 2.2"]
+ exports: ["Qt3D.Extras/MetalRoughMaterial 2.9"]
exportMetaObjectRevisions: [0]
Property { name: "baseColor"; type: "QColor" }
Property { name: "metalness"; type: "float" }
Property { name: "roughness"; type: "float" }
- Property {
- name: "environmentIrradiance"
- type: "Qt3DRender::QAbstractTexture"
- isPointer: true
- }
- Property { name: "environmentSpecular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
- Property { name: "exposure"; type: "float" }
Signal {
name: "baseColorChanged"
Parameter { name: "baseColor"; type: "QColor" }
@@ -757,22 +813,6 @@ Module {
name: "roughnessChanged"
Parameter { name: "roughness"; type: "float" }
}
- Signal {
- name: "environmentIrradianceChanged"
- Parameter {
- name: "environmentIrradiance"
- type: "Qt3DRender::QAbstractTexture"
- isPointer: true
- }
- }
- Signal {
- name: "environmentSpecularChanged"
- Parameter { name: "environmentSpecular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
- }
- Signal {
- name: "exposureChanged"
- Parameter { name: "exposure"; type: "float" }
- }
Method {
name: "setBaseColor"
Parameter { name: "baseColor"; type: "QColor" }
@@ -785,21 +825,56 @@ Module {
name: "setRoughness"
Parameter { name: "roughness"; type: "float" }
}
+ }
+ Component {
+ name: "Qt3DExtras::QMorphPhongMaterial"
+ prototype: "Qt3DRender::QMaterial"
+ exports: ["Qt3D.Extras/MorphPhongMaterial 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "ambient"; type: "QColor" }
+ Property { name: "diffuse"; type: "QColor" }
+ Property { name: "specular"; type: "QColor" }
+ Property { name: "shininess"; type: "float" }
+ Property { name: "interpolator"; type: "float" }
+ Signal {
+ name: "ambientChanged"
+ Parameter { name: "ambient"; type: "QColor" }
+ }
+ Signal {
+ name: "diffuseChanged"
+ Parameter { name: "diffuse"; type: "QColor" }
+ }
+ Signal {
+ name: "specularChanged"
+ Parameter { name: "specular"; type: "QColor" }
+ }
+ Signal {
+ name: "shininessChanged"
+ Parameter { name: "shininess"; type: "float" }
+ }
+ Signal {
+ name: "interpolatorChanged"
+ Parameter { name: "interpolator"; type: "float" }
+ }
Method {
- name: "setEnvironmentIrradiance"
- Parameter {
- name: "environmentIrradiance"
- type: "Qt3DRender::QAbstractTexture"
- isPointer: true
- }
+ name: "setAmbient"
+ Parameter { name: "ambient"; type: "QColor" }
+ }
+ Method {
+ name: "setDiffuse"
+ Parameter { name: "diffuse"; type: "QColor" }
}
Method {
- name: "setEnvironmentSpecular"
- Parameter { name: "environmentSpecular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
+ name: "setSpecular"
+ Parameter { name: "specular"; type: "QColor" }
}
Method {
- name: "setExposure"
- Parameter { name: "exposure"; type: "float" }
+ name: "setShininess"
+ Parameter { name: "shininess"; type: "float" }
+ }
+ Method {
+ name: "setInterpolator"
+ Parameter { name: "interpolator"; type: "float" }
}
}
Component {
@@ -1194,6 +1269,7 @@ Module {
exportMetaObjectRevisions: [0]
Property { name: "baseName"; type: "string" }
Property { name: "extension"; type: "string" }
+ Property { name: "gammaCorrect"; revision: 9; type: "bool" }
Signal {
name: "baseNameChanged"
Parameter { name: "path"; type: "string" }
@@ -1202,6 +1278,22 @@ Module {
name: "extensionChanged"
Parameter { name: "extension"; type: "string" }
}
+ Signal {
+ name: "gammaCorrectEnabledChanged"
+ Parameter { name: "enabled"; type: "bool" }
+ }
+ Method {
+ name: "setBaseName"
+ Parameter { name: "path"; type: "string" }
+ }
+ Method {
+ name: "setExtension"
+ Parameter { name: "extension"; type: "string" }
+ }
+ Method {
+ name: "setGammaCorrectEnabled"
+ Parameter { name: "enabled"; type: "bool" }
+ }
}
Component {
name: "Qt3DExtras::QSphereGeometry"
@@ -1318,105 +1410,34 @@ Module {
}
}
Component {
- name: "Qt3DExtras::QText3DGeometry"
- prototype: "Qt3DRender::QGeometry"
- exports: ["Qt3D.Extras/Text3DGeometry 2.2"]
+ name: "Qt3DExtras::QText2DEntity"
+ prototype: "Qt3DCore::QEntity"
+ exports: ["Qt3D.Extras/Text2DEntity 2.9"]
exportMetaObjectRevisions: [0]
- Property { name: "text"; type: "string" }
Property { name: "font"; type: "QFont" }
- Property { name: "depth"; type: "float" }
- Property { name: "edgeSplitAngle"; type: "float" }
- Property {
- name: "positionAttribute"
- type: "Qt3DRender::QAttribute"
- isReadonly: true
- isPointer: true
- }
- Property {
- name: "normalAttribute"
- type: "Qt3DRender::QAttribute"
- isReadonly: true
- isPointer: true
- }
- Property {
- name: "indexAttribute"
- type: "Qt3DRender::QAttribute"
- isReadonly: true
- isPointer: true
- }
- Signal {
- name: "textChanged"
- Parameter { name: "text"; type: "string" }
- }
+ Property { name: "text"; type: "string" }
+ Property { name: "color"; type: "QColor" }
+ Property { name: "width"; type: "float" }
+ Property { name: "height"; type: "float" }
Signal {
name: "fontChanged"
Parameter { name: "font"; type: "QFont" }
}
Signal {
- name: "depthChanged"
- Parameter { name: "depth"; type: "float" }
- }
- Signal {
- name: "edgeSplitAngleChanged"
- Parameter { name: "edgeSplitAngle"; type: "float" }
- }
- Method {
- name: "setText"
- Parameter { name: "text"; type: "string" }
- }
- Method {
- name: "setFont"
- Parameter { name: "font"; type: "QFont" }
- }
- Method {
- name: "setDepth"
- Parameter { name: "depth"; type: "float" }
- }
- Method {
- name: "setEdgeSplitAngle"
- Parameter { name: "edgeSplitAngle"; type: "float" }
+ name: "colorChanged"
+ Parameter { name: "color"; type: "QColor" }
}
- }
- Component {
- name: "Qt3DExtras::QText3DMesh"
- prototype: "Qt3DRender::QGeometryRenderer"
- exports: ["Qt3D.Extras/Text3DMesh 2.2"]
- exportMetaObjectRevisions: [0]
- Property { name: "text"; type: "string" }
- Property { name: "font"; type: "QFont" }
- Property { name: "depth"; type: "float" }
- Property { name: "edgeSplitAngle"; type: "float" }
Signal {
name: "textChanged"
Parameter { name: "text"; type: "string" }
}
Signal {
- name: "fontChanged"
- Parameter { name: "font"; type: "QFont" }
- }
- Signal {
- name: "depthChanged"
- Parameter { name: "depth"; type: "float" }
+ name: "widthChanged"
+ Parameter { name: "width"; type: "float" }
}
Signal {
- name: "edgeSplitAngleChanged"
- Parameter { name: "edgeSplitAngle"; type: "float" }
- }
- Method {
- name: "setText"
- Parameter { name: "text"; type: "string" }
- }
- Method {
- name: "setFont"
- Parameter { name: "font"; type: "QFont" }
- }
- Method {
- name: "setDepth"
- Parameter { name: "depth"; type: "float" }
- }
- Method {
- name: "setEdgeSplitAngle"
- Parameter { name: "edgeSplitAngle"; type: "float" }
+ name: "heightChanged"
+ Parameter { name: "height"; type: "float" }
}
}
Component {
@@ -1446,20 +1467,13 @@ Module {
Component {
name: "Qt3DExtras::QTexturedMetalRoughMaterial"
prototype: "Qt3DRender::QMaterial"
- exports: ["Qt3D.Extras/TexturedMetalRoughMaterial 2.2"]
+ exports: ["Qt3D.Extras/TexturedMetalRoughMaterial 2.9"]
exportMetaObjectRevisions: [0]
Property { name: "baseColor"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
Property { name: "metalness"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
Property { name: "roughness"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
Property { name: "ambientOcclusion"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
Property { name: "normal"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
- Property {
- name: "environmentIrradiance"
- type: "Qt3DRender::QAbstractTexture"
- isPointer: true
- }
- Property { name: "environmentSpecular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
- Property { name: "exposure"; type: "float" }
Signal {
name: "baseColorChanged"
Parameter { name: "baseColor"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
@@ -1480,22 +1494,6 @@ Module {
name: "normalChanged"
Parameter { name: "normal"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
}
- Signal {
- name: "environmentIrradianceChanged"
- Parameter {
- name: "environmentIrradiance"
- type: "Qt3DRender::QAbstractTexture"
- isPointer: true
- }
- }
- Signal {
- name: "environmentSpecularChanged"
- Parameter { name: "environmentSpecular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
- }
- Signal {
- name: "exposureChanged"
- Parameter { name: "exposure"; type: "float" }
- }
Method {
name: "setBaseColor"
Parameter { name: "baseColor"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
@@ -1516,22 +1514,6 @@ Module {
name: "setNormal"
Parameter { name: "normal"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
}
- Method {
- name: "setEnvironmentIrradiance"
- Parameter {
- name: "environmentIrradiance"
- type: "Qt3DRender::QAbstractTexture"
- isPointer: true
- }
- }
- Method {
- name: "setEnvironmentSpecular"
- Parameter { name: "environmentSpecular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
- }
- Method {
- name: "setExposure"
- Parameter { name: "exposure"; type: "float" }
- }
}
Component {
name: "Qt3DExtras::QTorusGeometry"
diff --git a/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp b/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp
index 647eb003b..879b79294 100644
--- a/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp
+++ b/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp
@@ -116,7 +116,9 @@ void Qt3DQuick3DExtrasPlugin::registerTypes(const char *uri)
qmlRegisterType<Qt3DExtras::QCylinderMesh>(uri, 2, 0, "CylinderMesh");
qmlRegisterType<Qt3DExtras::QCylinderGeometry>(uri, 2, 0, "CylinderGeometry");
qmlRegisterType<Qt3DExtras::QPlaneMesh>(uri, 2, 0, "PlaneMesh");
+ qmlRegisterRevision<Qt3DExtras::QPlaneMesh, 9>(uri, 2, 9);
qmlRegisterType<Qt3DExtras::QPlaneGeometry>(uri, 2, 0, "PlaneGeometry");
+ qmlRegisterRevision<Qt3DExtras::QPlaneGeometry, 9>(uri, 2, 9);
qmlRegisterType<Qt3DExtras::QTorusMesh>(uri, 2, 0, "TorusMesh");
qmlRegisterType<Qt3DExtras::QTorusGeometry>(uri, 2, 0, "TorusGeometry");
qmlRegisterType<Qt3DExtras::QSphereMesh>(uri, 2, 0, "SphereMesh");
diff --git a/src/quick3d/imports/input/plugins.qmltypes b/src/quick3d/imports/input/plugins.qmltypes
index 860ab4d68..24655977e 100644
--- a/src/quick3d/imports/input/plugins.qmltypes
+++ b/src/quick3d/imports/input/plugins.qmltypes
@@ -4,10 +4,10 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable Qt3D.Input 2.0'
+// 'qmlplugindump -nonrelocatable Qt3D.Input 2.1'
Module {
- dependencies: ["QtQuick 2.7"]
+ dependencies: ["QtQuick 2.8"]
Component {
name: "Qt3DCore::QComponent"
prototype: "Qt3DCore::QNode"
@@ -16,6 +16,14 @@ Module {
name: "shareableChanged"
Parameter { name: "isShareable"; type: "bool" }
}
+ Signal {
+ name: "addedToEntity"
+ Parameter { name: "entity"; type: "QEntity"; isPointer: true }
+ }
+ Signal {
+ name: "removedFromEntity"
+ Parameter { name: "entity"; type: "QEntity"; isPointer: true }
+ }
Method {
name: "setShareable"
Parameter { name: "isShareable"; type: "bool" }
@@ -24,8 +32,17 @@ Module {
Component {
name: "Qt3DCore::QNode"
prototype: "QObject"
+ Enum {
+ name: "PropertyTrackingMode"
+ values: {
+ "TrackFinalValues": 0,
+ "DontTrackValues": 1,
+ "TrackAllValues": 2
+ }
+ }
Property { name: "parent"; type: "Qt3DCore::QNode"; isPointer: true }
Property { name: "enabled"; type: "bool" }
+ Property { name: "defaultPropertyTrackingMode"; revision: 9; type: "PropertyTrackingMode" }
Signal {
name: "parentChanged"
Parameter { name: "parent"; type: "QObject"; isPointer: true }
@@ -34,6 +51,10 @@ Module {
name: "enabledChanged"
Parameter { name: "enabled"; type: "bool" }
}
+ Signal {
+ name: "defaultPropertyTrackingModeChanged"
+ Parameter { name: "mode"; type: "PropertyTrackingMode" }
+ }
Signal { name: "nodeDestroyed" }
Method {
name: "setParent"
@@ -43,6 +64,10 @@ Module {
name: "setEnabled"
Parameter { name: "isEnabled"; type: "bool" }
}
+ Method {
+ name: "setDefaultPropertyTrackingMode"
+ Parameter { name: "mode"; type: "PropertyTrackingMode" }
+ }
}
Component {
name: "Qt3DInput::Input::Quick::Quick3DAction"
@@ -101,6 +126,7 @@ Module {
name: "Qt3DInput::Input::Quick::Quick3DPhysicalDevice"
prototype: "Qt3DInput::QAbstractPhysicalDevice"
exports: ["Qt3D.Input/QAbstractPhysicalDevice 2.0"]
+ isCreatable: false
exportMetaObjectRevisions: [0]
Property { name: "axisSettings"; type: "Qt3DInput::QAxisSetting"; isList: true; isReadonly: true }
}
@@ -186,6 +212,56 @@ Module {
}
}
Component {
+ name: "Qt3DInput::QAxisAccumulator"
+ prototype: "Qt3DCore::QComponent"
+ exports: ["Qt3D.Input/AxisAccumulator 2.1"]
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "SourceAxisType"
+ values: {
+ "Velocity": 0,
+ "Acceleration": 1
+ }
+ }
+ Property { name: "sourceAxis"; type: "Qt3DInput::QAxis"; isPointer: true }
+ Property { name: "sourceAxisType"; type: "SourceAxisType" }
+ Property { name: "scale"; type: "float" }
+ Property { name: "value"; type: "float"; isReadonly: true }
+ Property { name: "velocity"; type: "float"; isReadonly: true }
+ Signal {
+ name: "sourceAxisChanged"
+ Parameter { name: "sourceAxis"; type: "Qt3DInput::QAxis"; isPointer: true }
+ }
+ Signal {
+ name: "sourceAxisTypeChanged"
+ Parameter { name: "sourceAxisType"; type: "QAxisAccumulator::SourceAxisType" }
+ }
+ Signal {
+ name: "valueChanged"
+ Parameter { name: "value"; type: "float" }
+ }
+ Signal {
+ name: "velocityChanged"
+ Parameter { name: "value"; type: "float" }
+ }
+ Signal {
+ name: "scaleChanged"
+ Parameter { name: "scale"; type: "float" }
+ }
+ Method {
+ name: "setSourceAxis"
+ Parameter { name: "sourceAxis"; type: "Qt3DInput::QAxis"; isPointer: true }
+ }
+ Method {
+ name: "setSourceAxisType"
+ Parameter { name: "sourceAxisType"; type: "QAxisAccumulator::SourceAxisType" }
+ }
+ Method {
+ name: "setScale"
+ Parameter { name: "scale"; type: "float" }
+ }
+ }
+ Component {
name: "Qt3DInput::QAxisSetting"
prototype: "Qt3DCore::QNode"
exports: ["Qt3D.Input/AxisSetting 2.0"]
@@ -337,7 +413,6 @@ Module {
Component {
name: "Qt3DInput::QKeyboardDevice"
prototype: "Qt3DInput::QAbstractPhysicalDevice"
- exports: ["Qt3D.Input/KeyboardDevice 2.0"]
Property {
name: "activeInput"
type: "Qt3DInput::QKeyboardHandler"
@@ -537,12 +612,13 @@ Module {
Component {
name: "Qt3DInput::QMouseDevice"
prototype: "Qt3DInput::QAbstractPhysicalDevice"
- exports: ["Qt3D.Input/MouseDevice 2.0"]
Enum {
name: "Axis"
values: {
"X": 0,
- "Y": 1
+ "Y": 1,
+ "WheelX": 2,
+ "WheelY": 3
}
}
Property { name: "sensitivity"; type: "float" }
diff --git a/src/quick3d/imports/input/qt3dquick3dinputplugin.cpp b/src/quick3d/imports/input/qt3dquick3dinputplugin.cpp
index 9d83f964f..5719a2b98 100644
--- a/src/quick3d/imports/input/qt3dquick3dinputplugin.cpp
+++ b/src/quick3d/imports/input/qt3dquick3dinputplugin.cpp
@@ -81,7 +81,9 @@ void Qt3DQuick3DInputPlugin::registerTypes(const char *uri)
qmlRegisterType<Qt3DInput::QInputSettings>(uri, 2, 0, "InputSettings");
qmlRegisterUncreatableType<Qt3DInput::QMouseEvent>(uri, 2, 0, "MouseEvent", QStringLiteral("Events cannot be created"));
+#if QT_CONFIG(wheelevent)
qmlRegisterUncreatableType<Qt3DInput::QWheelEvent>(uri, 2, 0, "WheelEvent", QStringLiteral("Events cannot be created"));
+#endif
qmlRegisterType<Qt3DInput::QMouseHandler>(uri, 2, 0, "MouseHandler");
qmlRegisterType<Qt3DInput::QMouseDevice>(uri, 2, 0, "MouseDevice");
diff --git a/src/quick3d/imports/logic/plugins.qmltypes b/src/quick3d/imports/logic/plugins.qmltypes
index 0c0ccc847..61b67ca73 100644
--- a/src/quick3d/imports/logic/plugins.qmltypes
+++ b/src/quick3d/imports/logic/plugins.qmltypes
@@ -7,7 +7,7 @@ import QtQuick.tooling 1.2
// 'qmlplugindump -nonrelocatable Qt3D.Logic 2.0'
Module {
- dependencies: ["QtQuick 2.7"]
+ dependencies: ["QtQuick 2.8"]
Component {
name: "Qt3DCore::QComponent"
prototype: "Qt3DCore::QNode"
@@ -16,6 +16,14 @@ Module {
name: "shareableChanged"
Parameter { name: "isShareable"; type: "bool" }
}
+ Signal {
+ name: "addedToEntity"
+ Parameter { name: "entity"; type: "QEntity"; isPointer: true }
+ }
+ Signal {
+ name: "removedFromEntity"
+ Parameter { name: "entity"; type: "QEntity"; isPointer: true }
+ }
Method {
name: "setShareable"
Parameter { name: "isShareable"; type: "bool" }
@@ -24,8 +32,17 @@ Module {
Component {
name: "Qt3DCore::QNode"
prototype: "QObject"
+ Enum {
+ name: "PropertyTrackingMode"
+ values: {
+ "TrackFinalValues": 0,
+ "DontTrackValues": 1,
+ "TrackAllValues": 2
+ }
+ }
Property { name: "parent"; type: "Qt3DCore::QNode"; isPointer: true }
Property { name: "enabled"; type: "bool" }
+ Property { name: "defaultPropertyTrackingMode"; revision: 9; type: "PropertyTrackingMode" }
Signal {
name: "parentChanged"
Parameter { name: "parent"; type: "QObject"; isPointer: true }
@@ -34,6 +51,10 @@ Module {
name: "enabledChanged"
Parameter { name: "enabled"; type: "bool" }
}
+ Signal {
+ name: "defaultPropertyTrackingModeChanged"
+ Parameter { name: "mode"; type: "PropertyTrackingMode" }
+ }
Signal { name: "nodeDestroyed" }
Method {
name: "setParent"
@@ -43,6 +64,10 @@ Module {
name: "setEnabled"
Parameter { name: "isEnabled"; type: "bool" }
}
+ Method {
+ name: "setDefaultPropertyTrackingMode"
+ Parameter { name: "mode"; type: "PropertyTrackingMode" }
+ }
}
Component {
name: "Qt3DLogic::QFrameAction"
diff --git a/src/quick3d/imports/render/plugins.qmltypes b/src/quick3d/imports/render/plugins.qmltypes
index 9e6e5fe38..aa0272430 100644
--- a/src/quick3d/imports/render/plugins.qmltypes
+++ b/src/quick3d/imports/render/plugins.qmltypes
@@ -4,10 +4,10 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable Qt3D.Render 2.0'
+// 'qmlplugindump -nonrelocatable Qt3D.Render 2.9'
Module {
- dependencies: ["QtQuick 2.7"]
+ dependencies: ["QtQuick 2.8"]
Component {
name: "QWindow"
prototype: "QObject"
@@ -25,6 +25,13 @@ Module {
"FullScreen": 5
}
}
+ Enum {
+ name: "AncestorMode"
+ values: {
+ "ExcludeTransients": 0,
+ "IncludeTransients": 1
+ }
+ }
Property { name: "title"; type: "string" }
Property { name: "modality"; type: "Qt::WindowModality" }
Property { name: "flags"; type: "Qt::WindowFlags" }
@@ -178,6 +185,14 @@ Module {
name: "shareableChanged"
Parameter { name: "isShareable"; type: "bool" }
}
+ Signal {
+ name: "addedToEntity"
+ Parameter { name: "entity"; type: "QEntity"; isPointer: true }
+ }
+ Signal {
+ name: "removedFromEntity"
+ Parameter { name: "entity"; type: "QEntity"; isPointer: true }
+ }
Method {
name: "setShareable"
Parameter { name: "isShareable"; type: "bool" }
@@ -187,8 +202,17 @@ Module {
Component {
name: "Qt3DCore::QNode"
prototype: "QObject"
+ Enum {
+ name: "PropertyTrackingMode"
+ values: {
+ "TrackFinalValues": 0,
+ "DontTrackValues": 1,
+ "TrackAllValues": 2
+ }
+ }
Property { name: "parent"; type: "Qt3DCore::QNode"; isPointer: true }
Property { name: "enabled"; type: "bool" }
+ Property { name: "defaultPropertyTrackingMode"; revision: 9; type: "PropertyTrackingMode" }
Signal {
name: "parentChanged"
Parameter { name: "parent"; type: "QObject"; isPointer: true }
@@ -197,6 +221,10 @@ Module {
name: "enabledChanged"
Parameter { name: "enabled"; type: "bool" }
}
+ Signal {
+ name: "defaultPropertyTrackingModeChanged"
+ Parameter { name: "mode"; type: "PropertyTrackingMode" }
+ }
Signal { name: "nodeDestroyed" }
Method {
name: "setParent"
@@ -206,6 +234,10 @@ Module {
name: "setEnabled"
Parameter { name: "isEnabled"; type: "bool" }
}
+ Method {
+ name: "setDefaultPropertyTrackingMode"
+ Parameter { name: "mode"; type: "PropertyTrackingMode" }
+ }
}
Component {
name: "Qt3DCore::Quick::Quick3DNode"
@@ -404,7 +436,8 @@ Module {
"CubeMapPositiveY": 34071,
"CubeMapNegativeY": 34072,
"CubeMapPositiveZ": 34073,
- "CubeMapNegativeZ": 34074
+ "CubeMapNegativeZ": 34074,
+ "AllFaces": 34075
}
}
Enum {
@@ -446,6 +479,7 @@ Module {
Property { name: "comparisonFunction"; type: "ComparisonFunction" }
Property { name: "comparisonMode"; type: "ComparisonMode" }
Property { name: "layers"; type: "int" }
+ Property { name: "samples"; type: "int" }
Signal {
name: "formatChanged"
Parameter { name: "format"; type: "TextureFormat" }
@@ -494,6 +528,10 @@ Module {
name: "layersChanged"
Parameter { name: "layers"; type: "int" }
}
+ Signal {
+ name: "samplesChanged"
+ Parameter { name: "samples"; type: "int" }
+ }
Method {
name: "setFormat"
Parameter { name: "format"; type: "TextureFormat" }
@@ -538,6 +576,10 @@ Module {
name: "setLayers"
Parameter { name: "layers"; type: "int" }
}
+ Method {
+ name: "setSamples"
+ Parameter { name: "samples"; type: "int" }
+ }
}
Component {
name: "Qt3DRender::QAbstractTextureImage"
@@ -625,7 +667,8 @@ Module {
name: "AttributeType"
values: {
"VertexAttribute": 0,
- "IndexAttribute": 1
+ "IndexAttribute": 1,
+ "DrawIndirectAttribute": 2
}
}
Enum {
@@ -651,6 +694,11 @@ Module {
Property { name: "byteOffset"; type: "uint" }
Property { name: "divisor"; type: "uint" }
Property { name: "attributeType"; type: "AttributeType" }
+ Property { name: "defaultPositionAttributeName"; type: "string"; isReadonly: true }
+ Property { name: "defaultNormalAttributeName"; type: "string"; isReadonly: true }
+ Property { name: "defaultColorAttributeName"; type: "string"; isReadonly: true }
+ Property { name: "defaultTextureCoordinateAttributeName"; type: "string"; isReadonly: true }
+ Property { name: "defaultTangentAttributeName"; type: "string"; isReadonly: true }
Signal {
name: "bufferChanged"
Parameter { name: "buffer"; type: "QBuffer"; isPointer: true }
@@ -660,6 +708,14 @@ Module {
Parameter { name: "name"; type: "string" }
}
Signal {
+ name: "vertexBaseTypeChanged"
+ Parameter { name: "vertexBaseType"; type: "VertexBaseType" }
+ }
+ Signal {
+ name: "vertexSizeChanged"
+ Parameter { name: "vertexSize"; type: "uint" }
+ }
+ Signal {
name: "dataTypeChanged"
Parameter { name: "vertexBaseType"; type: "VertexBaseType" }
}
@@ -696,6 +752,14 @@ Module {
Parameter { name: "name"; type: "string" }
}
Method {
+ name: "setVertexBaseType"
+ Parameter { name: "type"; type: "VertexBaseType" }
+ }
+ Method {
+ name: "setVertexSize"
+ Parameter { name: "size"; type: "uint" }
+ }
+ Method {
name: "setDataType"
Parameter { name: "type"; type: "VertexBaseType" }
}
@@ -780,7 +844,8 @@ Module {
"OneMinusConstantColor": 32770,
"OneMinusConstantAlpha": 32772,
"OneMinusSource1Alpha": 32773,
- "OneMinusSource1Color": 32774
+ "OneMinusSource1Color": 32774,
+ "OneMinusSource1Color0": 32774
}
}
Property { name: "sourceRgb"; type: "Blending" }
@@ -848,6 +913,9 @@ Module {
Component {
name: "Qt3DRender::QBuffer"
prototype: "Qt3DCore::QNode"
+ exports: ["Qt3D.Render/BufferBase 2.0", "Qt3D.Render/BufferBase 2.9"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0, 9]
Enum {
name: "BufferType"
values: {
@@ -856,7 +924,8 @@ Module {
"PixelPackBuffer": 35051,
"PixelUnpackBuffer": 35052,
"UniformBuffer": 35345,
- "ShaderStorageBuffer": 37074
+ "ShaderStorageBuffer": 37074,
+ "DrawIndirectBuffer": 36671
}
}
Enum {
@@ -873,9 +942,18 @@ Module {
"DynamicCopy": 35050
}
}
+ Enum {
+ name: "AccessType"
+ values: {
+ "Write": 1,
+ "Read": 2,
+ "ReadWrite": 3
+ }
+ }
Property { name: "type"; type: "BufferType" }
Property { name: "usage"; type: "UsageType" }
Property { name: "syncData"; type: "bool" }
+ Property { name: "accessType"; revision: 9; type: "AccessType" }
Signal {
name: "dataChanged"
Parameter { name: "bytes"; type: "QByteArray" }
@@ -892,6 +970,11 @@ Module {
name: "syncDataChanged"
Parameter { name: "syncData"; type: "bool" }
}
+ Signal {
+ name: "accessTypeChanged"
+ Parameter { name: "access"; type: "AccessType" }
+ }
+ Signal { name: "dataAvailable" }
Method {
name: "setType"
Parameter { name: "type"; type: "BufferType" }
@@ -904,6 +987,21 @@ Module {
name: "setSyncData"
Parameter { name: "syncData"; type: "bool" }
}
+ Method {
+ name: "setAccessType"
+ Parameter { name: "access"; type: "AccessType" }
+ }
+ Method {
+ name: "updateData"
+ Parameter { name: "offset"; type: "int" }
+ Parameter { name: "bytes"; type: "QByteArray" }
+ }
+ }
+ Component {
+ name: "Qt3DRender::QBufferCapture"
+ prototype: "Qt3DRender::QFrameGraphNode"
+ exports: ["Qt3D.Render/BufferCapture 2.9"]
+ exportMetaObjectRevisions: [0]
}
Component {
name: "Qt3DRender::QCamera"
@@ -927,6 +1025,7 @@ Module {
Property { name: "bottom"; type: "float" }
Property { name: "top"; type: "float" }
Property { name: "projectionMatrix"; type: "QMatrix4x4" }
+ Property { name: "exposure"; revision: 9; type: "float" }
Property { name: "position"; type: "QVector3D" }
Property { name: "upVector"; type: "QVector3D" }
Property { name: "viewCenter"; type: "QVector3D" }
@@ -973,6 +1072,10 @@ Module {
Parameter { name: "projectionMatrix"; type: "QMatrix4x4" }
}
Signal {
+ name: "exposureChanged"
+ Parameter { name: "exposure"; type: "float" }
+ }
+ Signal {
name: "positionChanged"
Parameter { name: "position"; type: "QVector3D" }
}
@@ -1029,6 +1132,10 @@ Module {
Parameter { name: "projectionMatrix"; type: "QMatrix4x4" }
}
Method {
+ name: "setExposure"
+ Parameter { name: "exposure"; type: "float" }
+ }
+ Method {
name: "setPosition"
Parameter { name: "position"; type: "QVector3D" }
}
@@ -1146,6 +1253,7 @@ Module {
Property { name: "bottom"; type: "float" }
Property { name: "top"; type: "float" }
Property { name: "projectionMatrix"; type: "QMatrix4x4" }
+ Property { name: "exposure"; revision: 9; type: "float" }
Signal {
name: "projectionTypeChanged"
Parameter { name: "projectionType"; type: "QCameraLens::ProjectionType" }
@@ -1186,6 +1294,10 @@ Module {
name: "projectionMatrixChanged"
Parameter { name: "projectionMatrix"; type: "QMatrix4x4" }
}
+ Signal {
+ name: "exposureChanged"
+ Parameter { name: "exposure"; type: "float" }
+ }
Method {
name: "setProjectionType"
Parameter { name: "projectionType"; type: "ProjectionType" }
@@ -1226,6 +1338,10 @@ Module {
name: "setProjectionMatrix"
Parameter { name: "projectionMatrix"; type: "QMatrix4x4" }
}
+ Method {
+ name: "setExposure"
+ Parameter { name: "exposure"; type: "float" }
+ }
}
Component {
name: "Qt3DRender::QCameraSelector"
@@ -1496,6 +1612,34 @@ Module {
}
Component { name: "Qt3DRender::QEffect"; prototype: "Qt3DCore::QNode" }
Component {
+ name: "Qt3DRender::QEnvironmentLight"
+ prototype: "Qt3DCore::QComponent"
+ exports: ["Qt3D.Render/EnvironmentLight 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "irradiance"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
+ Property { name: "specular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
+ Signal {
+ name: "irradianceChanged"
+ Parameter {
+ name: "environmentIrradiance"
+ type: "Qt3DRender::QAbstractTexture"
+ isPointer: true
+ }
+ }
+ Signal {
+ name: "specularChanged"
+ Parameter { name: "environmentSpecular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
+ }
+ Method {
+ name: "setIrradiance"
+ Parameter { name: "irradiance"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
+ }
+ Method {
+ name: "setSpecular"
+ Parameter { name: "specular"; type: "Qt3DRender::QAbstractTexture"; isPointer: true }
+ }
+ }
+ Component {
name: "Qt3DRender::QFilterKey"
prototype: "Qt3DCore::QNode"
exports: ["Qt3D.Render/FilterKey 2.0"]
@@ -1523,7 +1667,6 @@ Module {
name: "Qt3DRender::QFrameGraphNode"
prototype: "Qt3DCore::QNode"
exports: ["Qt3D.Render/FrameGraphNode 2.0"]
- isCreatable: false
exportMetaObjectRevisions: [0]
}
Component {
@@ -1776,6 +1919,76 @@ Module {
}
Component { name: "Qt3DRender::QLayerFilter"; prototype: "Qt3DRender::QFrameGraphNode" }
Component {
+ name: "Qt3DRender::QLevelOfDetail"
+ prototype: "Qt3DCore::QComponent"
+ exports: ["Qt3D.Render/LevelOfDetail 2.9"]
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "ThresholdType"
+ values: {
+ "DistanceToCameraThreshold": 0,
+ "ProjectedScreenPixelSizeThreshold": 1
+ }
+ }
+ Property { name: "camera"; type: "Qt3DRender::QCamera"; isPointer: true }
+ Property { name: "currentIndex"; type: "int" }
+ Property { name: "thresholdType"; type: "ThresholdType" }
+ Property { name: "thresholds"; type: "QVector<qreal>" }
+ Property { name: "volumeOverride"; type: "Qt3DRender::QLevelOfDetailBoundingSphere" }
+ Signal {
+ name: "cameraChanged"
+ Parameter { name: "camera"; type: "QCamera"; isPointer: true }
+ }
+ Signal {
+ name: "currentIndexChanged"
+ Parameter { name: "currentIndex"; type: "int" }
+ }
+ Signal {
+ name: "thresholdTypeChanged"
+ Parameter { name: "thresholdType"; type: "ThresholdType" }
+ }
+ Signal {
+ name: "thresholdsChanged"
+ Parameter { name: "thresholds"; type: "QVector<qreal>" }
+ }
+ Signal {
+ name: "volumeOverrideChanged"
+ Parameter { name: "volumeOverride"; type: "QLevelOfDetailBoundingSphere" }
+ }
+ Method {
+ name: "setCamera"
+ Parameter { name: "camera"; type: "QCamera"; isPointer: true }
+ }
+ Method {
+ name: "setCurrentIndex"
+ Parameter { name: "currentIndex"; type: "int" }
+ }
+ Method {
+ name: "setThresholdType"
+ Parameter { name: "thresholdType"; type: "ThresholdType" }
+ }
+ Method {
+ name: "setThresholds"
+ Parameter { name: "thresholds"; type: "QVector<qreal>" }
+ }
+ Method {
+ name: "setVolumeOverride"
+ Parameter { name: "volumeOverride"; type: "QLevelOfDetailBoundingSphere" }
+ }
+ Method {
+ name: "createBoundingSphere"
+ type: "QLevelOfDetailBoundingSphere"
+ Parameter { name: "center"; type: "QVector3D" }
+ Parameter { name: "radius"; type: "float" }
+ }
+ }
+ Component {
+ name: "Qt3DRender::QLevelOfDetailSwitch"
+ prototype: "Qt3DRender::QLevelOfDetail"
+ exports: ["Qt3D.Render/LevelOfDetailSwitch 2.9"]
+ exportMetaObjectRevisions: [0]
+ }
+ Component {
name: "Qt3DRender::QMaterial"
prototype: "Qt3DCore::QComponent"
Property { name: "effect"; type: "Qt3DRender::QEffect"; isPointer: true }
@@ -1789,6 +2002,39 @@ Module {
}
}
Component {
+ name: "Qt3DRender::QMemoryBarrier"
+ prototype: "Qt3DRender::QFrameGraphNode"
+ Enum {
+ name: "Operation"
+ values: {
+ "None": 0,
+ "VertexAttributeArray": 1,
+ "ElementArray": 2,
+ "Uniform": 4,
+ "TextureFetch": 8,
+ "ShaderImageAccess": 16,
+ "Command": 32,
+ "PixelBuffer": 64,
+ "TextureUpdate": 128,
+ "BufferUpdate": 256,
+ "FrameBuffer": 512,
+ "TransformFeedback": 1024,
+ "AtomicCounter": 2048,
+ "ShaderStorage": 4096,
+ "QueryBuffer": 8192,
+ "All": -1
+ }
+ }
+ Signal {
+ name: "waitOperationsChanged"
+ Parameter { name: "barrierTypes"; type: "QMemoryBarrier::Operations" }
+ }
+ Method {
+ name: "setWaitOperations"
+ Parameter { name: "operations"; type: "QMemoryBarrier::Operations" }
+ }
+ }
+ Component {
name: "Qt3DRender::QMesh"
prototype: "Qt3DRender::QGeometryRenderer"
exports: ["Qt3D.Render/Mesh 2.0"]
@@ -1913,11 +2159,35 @@ Module {
exports: ["Qt3D.Render/PickEvent 2.0"]
isCreatable: false
exportMetaObjectRevisions: [0]
+ Enum {
+ name: "Buttons"
+ values: {
+ "LeftButton": 1,
+ "RightButton": 2,
+ "MiddleButton": 4,
+ "BackButton": 8,
+ "NoButton": 0
+ }
+ }
+ Enum {
+ name: "Modifiers"
+ values: {
+ "NoModifier": 0,
+ "ShiftModifier": 33554432,
+ "ControlModifier": 67108864,
+ "AltModifier": 134217728,
+ "MetaModifier": 268435456,
+ "KeypadModifier": 536870912
+ }
+ }
Property { name: "accepted"; type: "bool" }
Property { name: "position"; type: "QPointF"; isReadonly: true }
Property { name: "distance"; type: "float"; isReadonly: true }
Property { name: "localIntersection"; type: "QVector3D"; isReadonly: true }
Property { name: "worldIntersection"; type: "QVector3D"; isReadonly: true }
+ Property { name: "button"; type: "Qt3DRender::QPickEvent::Buttons"; isReadonly: true }
+ Property { name: "buttons"; type: "int"; isReadonly: true }
+ Property { name: "modifiers"; type: "int"; isReadonly: true }
Signal {
name: "acceptedChanged"
Parameter { name: "accepted"; type: "bool" }
@@ -1946,8 +2216,17 @@ Module {
"AllPicks": 1
}
}
+ Enum {
+ name: "FaceOrientationPickingMode"
+ values: {
+ "FrontFace": 1,
+ "BackFace": 2,
+ "FrontAndBackFace": 3
+ }
+ }
Property { name: "pickMethod"; type: "PickMethod" }
Property { name: "pickResultMode"; type: "PickResultMode" }
+ Property { name: "faceOrientationPickingMode"; type: "FaceOrientationPickingMode" }
Signal {
name: "pickMethodChanged"
Parameter { name: "pickMethod"; type: "QPickingSettings::PickMethod" }
@@ -1956,6 +2235,13 @@ Module {
name: "pickResultModeChanged"
Parameter { name: "pickResult"; type: "QPickingSettings::PickResultMode" }
}
+ Signal {
+ name: "faceOrientationPickingModeChanged"
+ Parameter {
+ name: "faceOrientationPickingMode"
+ type: "QPickingSettings::FaceOrientationPickingMode"
+ }
+ }
Method {
name: "setPickMethod"
Parameter { name: "pickMethod"; type: "PickMethod" }
@@ -1964,6 +2250,10 @@ Module {
name: "setPickResultMode"
Parameter { name: "pickResultMode"; type: "PickResultMode" }
}
+ Method {
+ name: "setFaceOrientationPickingMode"
+ Parameter { name: "faceOrientationPickingMode"; type: "FaceOrientationPickingMode" }
+ }
}
Component {
name: "Qt3DRender::QPointLight"
@@ -2054,6 +2344,42 @@ Module {
}
}
Component {
+ name: "Qt3DRender::QRenderCapture"
+ prototype: "Qt3DRender::QFrameGraphNode"
+ exports: ["Qt3D.Render/RenderCapture 2.1"]
+ exportMetaObjectRevisions: [0]
+ Method {
+ name: "requestCapture"
+ type: "Qt3DRender::QRenderCaptureReply*"
+ Parameter { name: "captureId"; type: "int" }
+ }
+ Method { name: "requestCapture"; revision: 9; type: "Qt3DRender::QRenderCaptureReply*" }
+ }
+ Component {
+ name: "Qt3DRender::QRenderCaptureReply"
+ prototype: "QObject"
+ exports: ["Qt3D.Render/RenderCaptureReply 2.1"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Property { name: "image"; type: "QImage"; isReadonly: true }
+ Property { name: "captureId"; type: "int"; isReadonly: true }
+ Property { name: "complete"; type: "bool"; isReadonly: true }
+ Signal {
+ name: "completeChanged"
+ Parameter { name: "isComplete"; type: "bool" }
+ }
+ Signal { name: "completed" }
+ Method {
+ name: "saveImage"
+ type: "bool"
+ Parameter { name: "fileName"; type: "string" }
+ }
+ Method {
+ name: "saveToFile"
+ Parameter { name: "fileName"; type: "string" }
+ }
+ }
+ Component {
name: "Qt3DRender::QRenderPass"
prototype: "Qt3DCore::QNode"
Property { name: "shaderProgram"; type: "Qt3DRender::QShaderProgram"; isPointer: true }
@@ -2119,7 +2445,7 @@ Module {
exports: ["Qt3D.Render/RenderSurfaceSelector 2.0"]
exportMetaObjectRevisions: [0]
Property { name: "surface"; type: "QObject"; isPointer: true }
- Property { name: "externalRenderTargetSize"; type: "QSize"; isReadonly: true }
+ Property { name: "externalRenderTargetSize"; type: "QSize" }
Property { name: "surfacePixelRatio"; type: "float" }
Signal {
name: "surfaceChanged"
@@ -2141,6 +2467,10 @@ Module {
name: "setSurfacePixelRatio"
Parameter { name: "ratio"; type: "float" }
}
+ Method {
+ name: "setExternalRenderTargetSize"
+ Parameter { name: "size"; type: "QSize" }
+ }
}
Component { name: "Qt3DRender::QRenderTarget"; prototype: "Qt3DCore::QComponent" }
Component {
@@ -2176,7 +2506,7 @@ Module {
Property { name: "texture"; type: "QAbstractTexture"; isPointer: true }
Property { name: "mipLevel"; type: "int" }
Property { name: "layer"; type: "int" }
- Property { name: "face"; type: "QAbstractTexture::CubeMapFace" }
+ Property { name: "face"; type: "Qt3DRender::QAbstractTexture::CubeMapFace" }
Signal {
name: "attachmentPointChanged"
Parameter { name: "attachmentPoint"; type: "AttachmentPoint" }
@@ -2243,6 +2573,17 @@ Module {
"Error": 3
}
}
+ Enum {
+ name: "ComponentType"
+ values: {
+ "UnknownComponent": 0,
+ "GeometryRendererComponent": 1,
+ "TransformComponent": 2,
+ "MaterialComponent": 3,
+ "LightComponent": 4,
+ "CameraLensComponent": 5
+ }
+ }
Property { name: "source"; type: "QUrl" }
Property { name: "status"; type: "Status"; isReadonly: true }
Signal {
@@ -2261,6 +2602,20 @@ Module {
name: "setStatus"
Parameter { name: "status"; type: "Status" }
}
+ Method {
+ name: "entity"
+ revision: 9
+ type: "Qt3DCore::QEntity*"
+ Parameter { name: "entityName"; type: "string" }
+ }
+ Method { name: "entityNames"; revision: 9; type: "QStringList" }
+ Method {
+ name: "component"
+ revision: 9
+ type: "Qt3DCore::QComponent*"
+ Parameter { name: "entityName"; type: "string" }
+ Parameter { name: "componentType"; type: "ComponentType" }
+ }
}
Component {
name: "Qt3DRender::QScissorTest"
@@ -2333,12 +2688,22 @@ Module {
"Compute": 5
}
}
+ Enum {
+ name: "Status"
+ values: {
+ "NotReady": 0,
+ "Ready": 1,
+ "Error": 2
+ }
+ }
Property { name: "vertexShaderCode"; type: "QByteArray" }
Property { name: "tessellationControlShaderCode"; type: "QByteArray" }
Property { name: "tessellationEvaluationShaderCode"; type: "QByteArray" }
Property { name: "geometryShaderCode"; type: "QByteArray" }
Property { name: "fragmentShaderCode"; type: "QByteArray" }
Property { name: "computeShaderCode"; type: "QByteArray" }
+ Property { name: "log"; revision: 9; type: "string"; isReadonly: true }
+ Property { name: "status"; revision: 9; type: "Status"; isReadonly: true }
Signal {
name: "vertexShaderCodeChanged"
Parameter { name: "vertexShaderCode"; type: "QByteArray" }
@@ -2363,6 +2728,14 @@ Module {
name: "computeShaderCodeChanged"
Parameter { name: "computeShaderCode"; type: "QByteArray" }
}
+ Signal {
+ name: "logChanged"
+ Parameter { name: "log"; type: "string" }
+ }
+ Signal {
+ name: "statusChanged"
+ Parameter { name: "status"; type: "Status" }
+ }
Method {
name: "setVertexShaderCode"
Parameter { name: "vertexShaderCode"; type: "QByteArray" }
@@ -2701,6 +3074,7 @@ Module {
}
Property { name: "source"; type: "QUrl" }
Property { name: "status"; type: "Status"; isReadonly: true }
+ Property { name: "mirrored"; type: "bool" }
Signal {
name: "sourceChanged"
Parameter { name: "source"; type: "QUrl" }
@@ -2709,23 +3083,40 @@ Module {
name: "statusChanged"
Parameter { name: "status"; type: "Status" }
}
+ Signal {
+ name: "mirroredChanged"
+ Parameter { name: "mirrored"; type: "bool" }
+ }
Method {
name: "setSource"
Parameter { name: "source"; type: "QUrl" }
}
+ Method {
+ name: "setMirrored"
+ Parameter { name: "mirrored"; type: "bool" }
+ }
}
Component {
name: "Qt3DRender::QTextureLoader"
prototype: "Qt3DRender::QAbstractTexture"
Property { name: "source"; type: "QUrl" }
+ Property { name: "mirrored"; type: "bool" }
Signal {
name: "sourceChanged"
Parameter { name: "source"; type: "QUrl" }
}
+ Signal {
+ name: "mirroredChanged"
+ Parameter { name: "mirrored"; type: "bool" }
+ }
Method {
name: "setSource"
Parameter { name: "source"; type: "QUrl" }
}
+ Method {
+ name: "setMirrored"
+ Parameter { name: "mirrored"; type: "bool" }
+ }
}
Component { name: "Qt3DRender::QTextureRectangle"; prototype: "Qt3DRender::QAbstractTexture" }
Component {
@@ -2774,14 +3165,23 @@ Module {
name: "Qt3DRender::QViewport"
prototype: "Qt3DRender::QFrameGraphNode"
Property { name: "normalizedRect"; type: "QRectF" }
+ Property { name: "gamma"; revision: 9; type: "float" }
Signal {
name: "normalizedRectChanged"
Parameter { name: "normalizedRect"; type: "QRectF" }
}
+ Signal {
+ name: "gammaChanged"
+ Parameter { name: "gamma"; type: "float" }
+ }
Method {
name: "setNormalizedRect"
Parameter { name: "normalizedRect"; type: "QRectF" }
}
+ Method {
+ name: "setGamma"
+ Parameter { name: "gamma"; type: "float" }
+ }
}
Component {
name: "Qt3DRender::Render::Quick::Quick3DBuffer"
@@ -2790,7 +3190,16 @@ Module {
exportMetaObjectRevisions: [0]
Property { name: "data"; type: "QVariant" }
Signal { name: "bufferDataChanged" }
- Signal { name: "bufferDataChanged" }
+ Method {
+ name: "updateData"
+ Parameter { name: "offset"; type: "int" }
+ Parameter { name: "bytes"; type: "QVariant" }
+ }
+ Method {
+ name: "readBinaryFile"
+ type: "QVariant"
+ Parameter { name: "fileUrl"; type: "QUrl" }
+ }
}
Component {
name: "Qt3DRender::Render::Quick::Quick3DEffect"
@@ -2823,6 +3232,13 @@ Module {
Property { name: "parameters"; type: "Qt3DRender::QParameter"; isList: true; isReadonly: true }
}
Component {
+ name: "Qt3DRender::Render::Quick::Quick3DMemoryBarrier"
+ prototype: "Qt3DRender::QMemoryBarrier"
+ exports: ["Qt3D.Render/MemoryBarrier 2.9"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "waitFor"; type: "int" }
+ }
+ Component {
name: "Qt3DRender::Render::Quick::Quick3DParameter"
prototype: "Qt3DRender::QParameter"
exports: ["Qt3D.Render/Parameter 2.0"]
@@ -2921,7 +3337,7 @@ Module {
Component {
name: "Qt3DRender::Render::Quick::Quick3DTextureExtension"
defaultProperty: "textureImages"
- prototype: "Qt3DRender::QTextureLoader"
+ prototype: "Qt3DRender::QTextureRectangle"
exports: [
"Qt3D.Render/Texture1D 2.0",
"Qt3D.Render/Texture1DArray 2.0",
diff --git a/src/quick3d/imports/scene3d/scene3ditem.cpp b/src/quick3d/imports/scene3d/scene3ditem.cpp
index 6c285e133..c31f4aa97 100644
--- a/src/quick3d/imports/scene3d/scene3ditem.cpp
+++ b/src/quick3d/imports/scene3d/scene3ditem.cpp
@@ -223,7 +223,7 @@ void Scene3DItem::setWindowSurface(QObject *rootObject)
}
}
-void Scene3DItem::setItemArea(const QSize &area)
+void Scene3DItem::setItemArea(QSize area)
{
Qt3DRender::QRenderSurfaceSelector *surfaceSelector = Qt3DRender::QRenderSurfaceSelectorPrivate::find(m_entity);
if (surfaceSelector)
diff --git a/src/quick3d/imports/scene3d/scene3ditem_p.h b/src/quick3d/imports/scene3d/scene3ditem_p.h
index eb14645c3..e0ce3addc 100644
--- a/src/quick3d/imports/scene3d/scene3ditem_p.h
+++ b/src/quick3d/imports/scene3d/scene3ditem_p.h
@@ -88,7 +88,7 @@ public:
bool multisample() const;
void setMultisample(bool enable);
- void setItemArea(const QSize &area);
+ Q_INVOKABLE void setItemArea(QSize area);
bool isHoverEnabled() const;
enum CameraAspectRatioMode {
diff --git a/src/quick3d/imports/scene3d/scene3drenderer.cpp b/src/quick3d/imports/scene3d/scene3drenderer.cpp
index 88f3be3c1..b32191391 100644
--- a/src/quick3d/imports/scene3d/scene3drenderer.cpp
+++ b/src/quick3d/imports/scene3d/scene3drenderer.cpp
@@ -57,6 +57,17 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender {
+namespace {
+
+inline QMetaMethod setItemAreaMethod()
+{
+ const int idx = Scene3DItem::staticMetaObject.indexOfMethod("setItemArea(QSize)");
+ Q_ASSERT(idx != -1);
+ return Scene3DItem::staticMetaObject.method(idx);
+}
+
+} // anonymous
+
class ContextSaver
{
public:
@@ -250,8 +261,11 @@ void Scene3DRenderer::render()
const bool multisampleHasChanged = m_multisample != m_lastMultisample;
const bool forceRecreate = sizeHasChanged || multisampleHasChanged;
- if (sizeHasChanged)
- m_item->setItemArea(boundingRectSize);
+ if (sizeHasChanged) {
+ // We are in the QSGRenderThread (doing a direct call would result in a race)
+ static const QMetaMethod setItemArea = setItemAreaMethod();
+ setItemArea.invoke(m_item, Qt::QueuedConnection, Q_ARG(QSize, boundingRectSize));
+ }
// Rebuild FBO and textures if never created or a resize has occurred
if ((m_multisampledFBO.isNull() || forceRecreate) && m_multisample) {
diff --git a/src/quick3d/quick3d/qt3dquick_global.cpp b/src/quick3d/quick3d/qt3dquick_global.cpp
index ebf27e7ae..a98211991 100644
--- a/src/quick3d/quick3d/qt3dquick_global.cpp
+++ b/src/quick3d/quick3d/qt3dquick_global.cpp
@@ -659,9 +659,9 @@ public:
#undef ASSERT_VALID_SIZE
};
+static Quick3DValueTypeProvider valueTypeProvider;
static Quick3DValueTypeProvider *getValueTypeProvider()
{
- static Quick3DValueTypeProvider valueTypeProvider;
return &valueTypeProvider;
}
@@ -706,6 +706,11 @@ void Quick3D_initialize()
QQmlPrivate::qmlregister(QQmlPrivate::AutoParentRegistration, &autoparent);
}
+void Quick3D_uninitialize()
+{
+ QQml_removeValueTypeProvider(&valueTypeProvider);
+}
+
void Quick3D_registerType(const char *className, const char *quickName, int major, int minor)
{
QuickNodeFactory::instance()->registerType(className, quickName, major, minor);
diff --git a/src/quick3d/quick3d/qt3dquick_global_p.h b/src/quick3d/quick3d/qt3dquick_global_p.h
index d67209404..ffc603f91 100644
--- a/src/quick3d/quick3d/qt3dquick_global_p.h
+++ b/src/quick3d/quick3d/qt3dquick_global_p.h
@@ -62,6 +62,7 @@ namespace Qt3DCore {
namespace Quick {
QT3DQUICKSHARED_PRIVATE_EXPORT void Quick3D_initialize();
+QT3DQUICKSHARED_PRIVATE_EXPORT void Quick3D_uninitialize();
QT3DQUICKSHARED_PRIVATE_EXPORT void Quick3D_registerType(const char *className, const char *quickName, int major, int minor);
template<class T, class E> void registerExtendedType(const char *className, const char *quickName,
diff --git a/src/quick3d/quick3danimation/items/items.pri b/src/quick3d/quick3danimation/items/items.pri
index 3f19965b5..27adabbe4 100644
--- a/src/quick3d/quick3danimation/items/items.pri
+++ b/src/quick3d/quick3danimation/items/items.pri
@@ -4,7 +4,8 @@ SOURCES += \
$$PWD/quick3danimationgroup.cpp \
$$PWD/quick3dkeyframeanimation.cpp \
$$PWD/quick3dmorphinganimation.cpp \
- $$PWD/quick3dmorphtarget.cpp
+ $$PWD/quick3dmorphtarget.cpp \
+ $$PWD/quick3dvertexblendanimation.cpp
HEADERS += \
$$PWD/quick3dchannelmapper_p.h \
@@ -12,6 +13,7 @@ HEADERS += \
$$PWD/quick3danimationgroup_p.h \
$$PWD/quick3dkeyframeanimation_p.h \
$$PWD/quick3dmorphinganimation_p.h \
- $$PWD/quick3dmorphtarget_p.h
+ $$PWD/quick3dmorphtarget_p.h \
+ $$PWD/quick3dvertexblendanimation_p.h
INCLUDEPATH += $$PWD
diff --git a/src/quick3d/quick3danimation/items/quick3dvertexblendanimation.cpp b/src/quick3d/quick3danimation/items/quick3dvertexblendanimation.cpp
new file mode 100644
index 000000000..2dffb7858
--- /dev/null
+++ b/src/quick3d/quick3danimation/items/quick3dvertexblendanimation.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "quick3dvertexblendanimation_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+namespace Quick {
+
+QQuick3DVertexBlendAnimation::QQuick3DVertexBlendAnimation(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QQmlListProperty<Qt3DAnimation::QMorphTarget> QQuick3DVertexBlendAnimation::morphTargets()
+{
+ return QQmlListProperty<Qt3DAnimation::QMorphTarget>(this, 0,
+ &QQuick3DVertexBlendAnimation::appendMorphTarget,
+ &QQuick3DVertexBlendAnimation::morphTargetCount,
+ &QQuick3DVertexBlendAnimation::morphTargetAt,
+ &QQuick3DVertexBlendAnimation::clearMorphTargets);
+}
+
+void QQuick3DVertexBlendAnimation::appendMorphTarget(
+ QQmlListProperty<Qt3DAnimation::QMorphTarget> *list,
+ Qt3DAnimation::QMorphTarget *morphTarget)
+{
+ QQuick3DVertexBlendAnimation *animation
+ = qobject_cast<QQuick3DVertexBlendAnimation *>(list->object);
+ if (animation)
+ animation->parentVertexBlendAnimation()->addMorphTarget(morphTarget);
+}
+
+int QQuick3DVertexBlendAnimation::morphTargetCount(
+ QQmlListProperty<Qt3DAnimation::QMorphTarget> *list)
+{
+ QQuick3DVertexBlendAnimation *animation
+ = qobject_cast<QQuick3DVertexBlendAnimation *>(list->object);
+ if (animation)
+ return animation->parentVertexBlendAnimation()->morphTargetList().count();
+ return 0;
+}
+
+Qt3DAnimation::QMorphTarget *QQuick3DVertexBlendAnimation::morphTargetAt(
+ QQmlListProperty<Qt3DAnimation::QMorphTarget> *list,
+ int index)
+{
+ QQuick3DVertexBlendAnimation *animation
+ = qobject_cast<QQuick3DVertexBlendAnimation *>(list->object);
+ if (animation) {
+ return qobject_cast<Qt3DAnimation::QMorphTarget *>(
+ animation->parentVertexBlendAnimation()->morphTargetList().at(index));
+ }
+ return nullptr;
+}
+
+void QQuick3DVertexBlendAnimation::clearMorphTargets(QQmlListProperty<Qt3DAnimation::QMorphTarget> *list)
+{
+ QQuick3DVertexBlendAnimation *animation
+ = qobject_cast<QQuick3DVertexBlendAnimation *>(list->object);
+ if (animation) {
+ QVector<Qt3DAnimation::QMorphTarget *> emptyList;
+ animation->parentVertexBlendAnimation()->setMorphTargets(emptyList);
+ }
+}
+
+} // namespace Quick
+} // namespace Qt3DAnimation
+
+QT_END_NAMESPACE
diff --git a/src/quick3d/quick3danimation/items/quick3dvertexblendanimation_p.h b/src/quick3d/quick3danimation/items/quick3dvertexblendanimation_p.h
new file mode 100644
index 000000000..6be2d662f
--- /dev/null
+++ b/src/quick3d/quick3danimation/items/quick3dvertexblendanimation_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DANIMATION_QUICK_QUICK3DVERTEXBLENDANIMATION_P_H
+#define QT3DANIMATION_QUICK_QUICK3DVERTEXBLENDANIMATION_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 <QtQml/qqmllist.h>
+
+#include <Qt3DAnimation/qvertexblendanimation.h>
+
+#include <private/qt3dquickanimation_global_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+namespace Quick {
+
+class QT3DQUICKANIMATIONSHARED_PRIVATE_EXPORT QQuick3DVertexBlendAnimation : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QQmlListProperty<Qt3DAnimation::QMorphTarget> morphTargets READ morphTargets)
+
+public:
+ QQuick3DVertexBlendAnimation(QObject *parent = nullptr);
+
+ inline QVertexBlendAnimation *parentVertexBlendAnimation() const
+ {
+ return qobject_cast<QVertexBlendAnimation *>(parent());
+ }
+
+ QQmlListProperty<Qt3DAnimation::QMorphTarget> morphTargets();
+
+private:
+
+ static void appendMorphTarget(QQmlListProperty<Qt3DAnimation::QMorphTarget> *list,
+ Qt3DAnimation::QMorphTarget *morphTarget);
+ static Qt3DAnimation::QMorphTarget *morphTargetAt(
+ QQmlListProperty<Qt3DAnimation::QMorphTarget> *list,
+ int index);
+ static int morphTargetCount(QQmlListProperty<Qt3DAnimation::QMorphTarget> *list);
+ static void clearMorphTargets(QQmlListProperty<Qt3DAnimation::QMorphTarget> *list);
+};
+
+} // namespace Quick
+} // namespace Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QUICK_QUICK3DMORPHINGANIMATION_P_H
diff --git a/src/quick3d/quick3dextras/qt3dquickwindow.cpp b/src/quick3d/quick3dextras/qt3dquickwindow.cpp
index 7f32f03f0..91773bb66 100644
--- a/src/quick3d/quick3dextras/qt3dquickwindow.cpp
+++ b/src/quick3d/quick3dextras/qt3dquickwindow.cpp
@@ -49,6 +49,7 @@
****************************************************************************/
#include <Qt3DQuickExtras/qt3dquickwindow.h>
+#include "qt3dquickwindow_p.h"
#include <Qt3DQuick/QQmlAspectEngine>
#include <Qt3DQuickExtras/qt3dquickwindow.h>
#include <Qt3DInput/qinputaspect.h>
@@ -96,16 +97,21 @@ private:
} // anonymous
-Qt3DQuickWindow::Qt3DQuickWindow(QWindow *parent)
- : QWindow(parent)
- , m_engine(nullptr)
+Qt3DQuickWindowPrivate::Qt3DQuickWindowPrivate()
+ : m_engine(nullptr)
, m_renderAspect(nullptr)
, m_inputAspect(nullptr)
, m_logicAspect(nullptr)
, m_initialized(false)
- , m_cameraAspectRatioMode(AutomaticAspectRatio)
+ , m_cameraAspectRatioMode(Qt3DQuickWindow::AutomaticAspectRatio)
, m_incubationController(nullptr)
{
+}
+
+Qt3DQuickWindow::Qt3DQuickWindow(QWindow *parent)
+ : QWindow(*new Qt3DQuickWindowPrivate(), parent)
+{
+ Q_D(Qt3DQuickWindow);
setSurfaceType(QSurface::OpenGLSurface);
resize(1024, 768);
@@ -125,78 +131,87 @@ Qt3DQuickWindow::Qt3DQuickWindow(QWindow *parent)
setFormat(format);
QSurfaceFormat::setDefaultFormat(format);
- m_engine.reset(new Qt3DCore::Quick::QQmlAspectEngine);
- m_renderAspect = new Qt3DRender::QRenderAspect;
- m_inputAspect = new Qt3DInput::QInputAspect;
- m_logicAspect = new Qt3DLogic::QLogicAspect;
+ d->m_engine = new Qt3DCore::Quick::QQmlAspectEngine;
+ d->m_renderAspect = new Qt3DRender::QRenderAspect;
+ d->m_inputAspect = new Qt3DInput::QInputAspect;
+ d->m_logicAspect = new Qt3DLogic::QLogicAspect;
- m_engine->aspectEngine()->registerAspect(m_renderAspect);
- m_engine->aspectEngine()->registerAspect(m_inputAspect);
- m_engine->aspectEngine()->registerAspect(m_logicAspect);
+ d->m_engine->aspectEngine()->registerAspect(d->m_renderAspect);
+ d->m_engine->aspectEngine()->registerAspect(d->m_inputAspect);
+ d->m_engine->aspectEngine()->registerAspect(d->m_logicAspect);
}
Qt3DQuickWindow::~Qt3DQuickWindow()
{
+ Q_D(Qt3DQuickWindow);
+ delete d->m_engine;
}
void Qt3DQuickWindow::registerAspect(Qt3DCore::QAbstractAspect *aspect)
{
Q_ASSERT(!isVisible());
- m_engine->aspectEngine()->registerAspect(aspect);
+ Q_D(Qt3DQuickWindow);
+ d->m_engine->aspectEngine()->registerAspect(aspect);
}
void Qt3DQuickWindow::registerAspect(const QString &name)
{
Q_ASSERT(!isVisible());
- m_engine->aspectEngine()->registerAspect(name);
+ Q_D(Qt3DQuickWindow);
+ d->m_engine->aspectEngine()->registerAspect(name);
}
void Qt3DQuickWindow::setSource(const QUrl &source)
{
- m_source = source;
+ Q_D(Qt3DQuickWindow);
+ d->m_source = source;
}
Qt3DCore::Quick::QQmlAspectEngine *Qt3DQuickWindow::engine() const
{
- return m_engine.data();
+ Q_D(const Qt3DQuickWindow);
+ return d->m_engine;
}
void Qt3DQuickWindow::setCameraAspectRatioMode(CameraAspectRatioMode mode)
{
- if (m_cameraAspectRatioMode == mode)
+ Q_D(Qt3DQuickWindow);
+ if (d->m_cameraAspectRatioMode == mode)
return;
- m_cameraAspectRatioMode = mode;
+ d->m_cameraAspectRatioMode = mode;
setCameraAspectModeHelper();
emit cameraAspectRatioModeChanged(mode);
}
Qt3DQuickWindow::CameraAspectRatioMode Qt3DQuickWindow::cameraAspectRatioMode() const
{
- return m_cameraAspectRatioMode;
+ Q_D(const Qt3DQuickWindow);
+ return d->m_cameraAspectRatioMode;
}
void Qt3DQuickWindow::showEvent(QShowEvent *e)
{
- if (!m_initialized) {
+ Q_D(Qt3DQuickWindow);
+ if (!d->m_initialized) {
// Connect to the QQmlAspectEngine's statusChanged signal so that when the QML is loaded
// and th eobjects hav ebeen instantiated, but before we set them on the QAspectEngine we
// can swoop in and set the window surface and camera on the framegraph and ensure the camera
// respects the window's aspect ratio
- connect(m_engine.data(), &Qt3DCore::Quick::QQmlAspectEngine::sceneCreated,
+ connect(d->m_engine, &Qt3DCore::Quick::QQmlAspectEngine::sceneCreated,
this, &Qt3DQuickWindow::onSceneCreated);
- m_engine->setSource(m_source);
+ d->m_engine->setSource(d->m_source);
// Set the QQmlIncubationController on the window
// to benefit from asynchronous incubation
- if (!m_incubationController)
- m_incubationController = new Qt3DQuickWindowIncubationController(this);
+ if (!d->m_incubationController)
+ d->m_incubationController = new Qt3DQuickWindowIncubationController(this);
- m_engine->qmlEngine()->setIncubationController(m_incubationController);
+ d->m_engine->qmlEngine()->setIncubationController(d->m_incubationController);
- m_initialized = true;
+ d->m_initialized = true;
}
QWindow::showEvent(e);
}
@@ -204,17 +219,18 @@ void Qt3DQuickWindow::showEvent(QShowEvent *e)
void Qt3DQuickWindow::onSceneCreated(QObject *rootObject)
{
Q_ASSERT(rootObject);
+ Q_D(Qt3DQuickWindow);
setWindowSurface(rootObject);
- if (m_cameraAspectRatioMode == AutomaticAspectRatio) {
+ if (d->m_cameraAspectRatioMode == AutomaticAspectRatio) {
// Set aspect ratio of first camera to match the window
QList<Qt3DRender::QCamera *> cameras
= rootObject->findChildren<Qt3DRender::QCamera *>();
if (cameras.isEmpty()) {
qCDebug(QuickWindow) << "No camera found";
} else {
- m_camera = cameras.first();
+ d->m_camera = cameras.first();
setCameraAspectModeHelper();
}
}
@@ -237,7 +253,8 @@ void Qt3DQuickWindow::setWindowSurface(QObject *rootObject)
void Qt3DQuickWindow::setCameraAspectModeHelper()
{
- switch (m_cameraAspectRatioMode) {
+ Q_D(Qt3DQuickWindow);
+ switch (d->m_cameraAspectRatioMode) {
case AutomaticAspectRatio:
connect(this, &QWindow::widthChanged, this, &Qt3DQuickWindow::updateCameraAspectRatio);
connect(this, &QWindow::heightChanged, this, &Qt3DQuickWindow::updateCameraAspectRatio);
@@ -253,9 +270,10 @@ void Qt3DQuickWindow::setCameraAspectModeHelper()
void Qt3DQuickWindow::updateCameraAspectRatio()
{
- if (m_camera) {
- m_camera->setAspectRatio(static_cast<float>(width()) /
- static_cast<float>(height()));
+ Q_D(Qt3DQuickWindow);
+ if (d->m_camera) {
+ d->m_camera->setAspectRatio(static_cast<float>(width()) /
+ static_cast<float>(height()));
}
}
diff --git a/src/quick3d/quick3dextras/qt3dquickwindow.h b/src/quick3d/quick3dextras/qt3dquickwindow.h
index 1b4d3fabf..0880fc160 100644
--- a/src/quick3d/quick3dextras/qt3dquickwindow.h
+++ b/src/quick3d/quick3dextras/qt3dquickwindow.h
@@ -84,6 +84,7 @@ namespace Qt3DExtras {
namespace Quick {
+class Qt3DQuickWindowPrivate;
class QT3DQUICKEXTRASSHARED_EXPORT Qt3DQuickWindow : public QWindow
{
@@ -121,18 +122,7 @@ private:
void setCameraAspectModeHelper();
void updateCameraAspectRatio();
- QScopedPointer<Qt3DCore::Quick::QQmlAspectEngine> m_engine;
-
- // Aspects
- Qt3DRender::QRenderAspect *m_renderAspect;
- Qt3DInput::QInputAspect *m_inputAspect;
- Qt3DLogic::QLogicAspect *m_logicAspect;
-
- QUrl m_source;
- bool m_initialized;
- QPointer<Qt3DRender::QCamera> m_camera;
- CameraAspectRatioMode m_cameraAspectRatioMode;
- QQmlIncubationController *m_incubationController;
+ Q_DECLARE_PRIVATE(Qt3DQuickWindow)
};
} // Quick
diff --git a/src/quick3d/quick3dextras/qt3dquickwindow_p.h b/src/quick3d/quick3dextras/qt3dquickwindow_p.h
new file mode 100644
index 000000000..f2f8d0492
--- /dev/null
+++ b/src/quick3d/quick3dextras/qt3dquickwindow_p.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DQUICKWINDOW_P_H
+#define QT3DQUICKWINDOW_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 <QtGui/private/qwindow_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+namespace Quick {
+
+class Qt3DQuickWindowPrivate : public QWindowPrivate
+{
+public:
+ Qt3DQuickWindowPrivate();
+
+ Qt3DCore::Quick::QQmlAspectEngine *m_engine;
+
+ // Aspects
+ Qt3DRender::QRenderAspect *m_renderAspect;
+ Qt3DInput::QInputAspect *m_inputAspect;
+ Qt3DLogic::QLogicAspect *m_logicAspect;
+
+ QUrl m_source;
+ bool m_initialized;
+ QPointer<Qt3DRender::QCamera> m_camera;
+ Qt3DQuickWindow::CameraAspectRatioMode m_cameraAspectRatioMode;
+ QQmlIncubationController *m_incubationController;
+
+ Q_DECLARE_PUBLIC(Qt3DQuickWindow)
+};
+
+} // Quick
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DQUICKWINDOW_P_H
diff --git a/src/quick3d/quick3dextras/quick3dextras.pro b/src/quick3d/quick3dextras/quick3dextras.pro
index 9044c1668..976430eba 100644
--- a/src/quick3d/quick3dextras/quick3dextras.pro
+++ b/src/quick3d/quick3dextras/quick3dextras.pro
@@ -21,6 +21,7 @@ HEADERS += \
qt3dquickextras_global.h \
qt3dquickextras_global_p.h \
qt3dquickwindow.h \
+ qt3dquickwindow_p.h \
qt3dquickwindowlogging_p.h
# otherwise mingw headers do not declare common functions like ::strcasecmp
diff --git a/src/quick3d/quick3dscene2d/items/qscene2d.cpp b/src/quick3d/quick3dscene2d/items/qscene2d.cpp
index 3470ac9d8..52e2be094 100644
--- a/src/quick3d/quick3dscene2d/items/qscene2d.cpp
+++ b/src/quick3d/quick3dscene2d/items/qscene2d.cpp
@@ -59,21 +59,75 @@ namespace Quick {
\brief This class enables rendering qml into a texture, which then can be
used as a part of 3D scene.
- The component uses QQuickRenderControl to render the given QML source into an
+ This class uses QQuickRenderControl to render the given QQuickItem into an
offscreen surface, which is attached to a texture provided by the user. This allows the
component to directly render into the texture without intermediate copy and the user to
freely specify how the texture is used in the 3D scene.
+ The entities using the QScene2D can be associated with the class to enable interaction
+ with the item; if an entity has a QObjectPicker component, the pick events from that picker
+ are sent to the QScene2D and converted to mouse events and finally sent to the item.
+
\since 5.9
*/
/*!
\qmltype Scene2D
\inqmlmodule Qt3D.Scene2D
- \since
- \ingroup
+ \since 5.9
\instantiates Qt3DRender::Quick::QScene2D
- \brief Scene2D
+
+ \brief This type enables rendering qml into a texture, which then can be
+ used as a part of 3D scene.
+
+ This object uses RenderControl to render the given Item into an
+ offscreen surface, which is attached to a texture provided by the user. This allows the
+ component to directly render into the texture without intermediate copy and the user to
+ freely specify how the texture is used in the 3D scene.
+
+ The entities using the Scene2D can be associated with the type to enable interaction
+ with the item; if an entity has an ObjectPicker component, the pick events from that picker
+ are sent to the Scene2D and converted to mouse events and finally sent to the item.
+
+ Usage:
+ \qml
+ Entity {
+ id: sceneRoot
+
+ // specify Scene2D inside the entity hierarchy
+ Scene2D {
+ // specify output
+ output: RenderTargetOutput {
+ attachmentPoint: RenderTargetOutput.Color0
+ texture: Texture2D {
+ id: textureId
+ width: 1024
+ height: 1024
+ format: Texture.RGBA8_UNorm
+ }
+ }
+ // specify entities
+ entities: [entityId]
+
+ // specify rendered content
+ Rectangle {
+ color: "red"
+ }
+ }
+
+ Entity {
+ id: entityId
+
+ property Material material: TextureMaterial {
+ texture: textureId
+ }
+ property ObjectPicker picker: ObjectPicker {
+ hoverEnabled: true
+ dragEnabled: true
+ }
+ ...
+
+ \endqml
*/
/*!
@@ -91,18 +145,34 @@ namespace Quick {
*/
/*!
- \qmlproperty QUrl Qt3D.Render::Scene2D::source
- Holds the qml source url.
- */
-
-/*!
\qmlproperty enumeration Qt3D.Render::Scene2D::renderPolicy
Holds the render policy of this Scene2D.
+
+ \list
+ \li Continuous The Scene2D is rendering continuously. This is the default render policy.
+ \li SingleShot The Scene2D renders to the texture only once after which the resources
+ allocated for rendering are released.
+ \endlist
+ */
+/*!
+ \qmlproperty Item Qt3D.Render::Scene2D::item
+ Holds the Item, which is rendered by Scene2D to the texture.
*/
/*!
- \qmlproperty bool Qt3D.Render::Scene2D::loaded
- Holds whether the source has been loaded.
+ \qmlproperty bool Qt3D.Render::Scene2D::mouseEnabled
+ Holds whether mouse events are enabled for the rendered item. The mouse events are
+ generated from object picking events of the entities added to the Scene2D.
+ Mouse is enabled by default.
+
+ \note Events sent to items are delayed by one frame due to object picking
+ happening in the backend.
+ */
+/*!
+ \qmlproperty list<Entity> Qt3D.Render::Scene2D::entities
+ Holds the list of entities which are associated with the Scene2D object. If the
+ entities have ObjectPicker, the pick events from that entity are sent to Scene2D
+ and converted to mouse events.
*/
QScene2DPrivate::QScene2DPrivate()
@@ -118,6 +188,15 @@ QScene2DPrivate::~QScene2DPrivate()
delete m_renderManager;
}
+void QScene2DPrivate::setScene(Qt3DCore::QScene *scene)
+{
+ Q_Q(QScene2D);
+ QNodePrivate::setScene(scene);
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(q->id());
+ change->setPropertyName("sceneInitialized");
+ notifyObservers(change);
+}
+
/*!
The constructor creates a new QScene2D instance with the specified \a parent.
@@ -125,58 +204,12 @@ QScene2DPrivate::~QScene2DPrivate()
QScene2D::QScene2D(Qt3DCore::QNode *parent)
: Qt3DCore::QNode(*new QScene2DPrivate, parent)
{
- Q_D(QScene2D);
- connect(d->m_renderManager, &Scene2DManager::onLoadedChanged,
- this, &QScene2D::sourceLoaded);
-}
-
-QScene2D::QScene2D(QQmlEngine *engine, Qt3DCore::QNode *parent)
- : Qt3DCore::QNode(*new QScene2DPrivate, parent)
-{
- Q_D(QScene2D);
- connect(d->m_renderManager, &Scene2DManager::onLoadedChanged,
- this, &QScene2D::sourceLoaded);
- d->m_renderManager->setEngine(engine);
-}
-
-QScene2D::~QScene2D()
-{
-}
-
-bool QScene2D::loaded() const
-{
- Q_D(const QScene2D);
- return d->m_renderManager->m_initialized;
}
/*!
- \property QScene2D::source
- \brief Specifies the url for the qml.
-
- This property specifies the url to the qml being rendered to the texture.
- The source must specify QQuickItem as a root. The item must specify width
- and height. The rendered qml is scaled to the texture size.
- The property can not be changed after the rendering has been initialized.
+ \property QScene2D::item
+ Holds the QQuickItem, which is rendered by QScene2D to the texture.
*/
-QUrl QScene2D::source() const
-{
- Q_D(const QScene2D);
- return d->m_renderManager->m_source;
-}
-
-void QScene2D::setSource(const QUrl &url)
-{
- Q_D(QScene2D);
- if (d->m_renderManager->m_initialized) {
- qWarning() << "Unable to set source after initialization.";
- return;
- }
- if (d->m_renderManager->m_source != url) {
- d->m_renderManager->setSource(url);
- emit sourceChanged(url);
- }
-}
-
QQuickItem* QScene2D::item() const
{
Q_D(const QScene2D);
@@ -250,46 +283,29 @@ Qt3DCore::QNodeCreatedChangeBasePtr QScene2D::createNodeCreationChange() const
data.output = d->m_output ? d->m_output->id() : Qt3DCore::QNodeId();
for (Qt3DCore::QEntity *e : d->m_entities)
data.entityIds.append(e->id());
+ data.mouseEnabled = d->m_renderManager->m_mouseEnabled;
return creationChange;
}
-bool QScene2D::event(QEvent *event)
-{
- Q_D(QScene2D);
- d->m_renderManager->forwardEvent(event);
- return true;
-}
-
-/*!
- Returns the qml engine used by the QScene2D.
- */
-QQmlEngine *QScene2D::engine() const
+bool QScene2D::isMouseEnabled() const
{
Q_D(const QScene2D);
- return d->m_renderManager->m_qmlEngine;
-}
-
-bool QScene2D::isGrabMouseEnabled() const
-{
- Q_D(const QScene2D);
- return d->m_renderManager->m_grabMouse;
+ return d->m_renderManager->m_mouseEnabled;
}
/*!
- \internal
+ Retrieve entities associated with the QScene2D.
*/
-void QScene2D::sourceLoaded()
-{
- emit loadedChanged(true);
-}
-
-
QVector<Qt3DCore::QEntity*> QScene2D::entities()
{
Q_D(const QScene2D);
return d->m_entities;
}
+/*!
+ Adds an \a entity to the the QScene2D object. If the entities have QObjectPicker,
+ the pick events from that entity are sent to QScene2D and converted to mouse events.
+*/
void QScene2D::addEntity(Qt3DCore::QEntity *entity)
{
Q_D(QScene2D);
@@ -306,6 +322,9 @@ void QScene2D::addEntity(Qt3DCore::QEntity *entity)
}
}
+/*!
+ Removes an \a entity from the the QScene2D object.
+*/
void QScene2D::removeEntity(Qt3DCore::QEntity *entity)
{
Q_D(QScene2D);
@@ -322,12 +341,20 @@ void QScene2D::removeEntity(Qt3DCore::QEntity *entity)
}
}
-void QScene2D::setGrabMouseEnabled(bool grab)
+/*!
+ \property QScene2D::mouseEnabled
+ Holds whether mouse events are enabled for the rendered item. The mouse events are
+ generated from object picking events of the entities added to the QScene2D.
+ Mouse is enabled by default.
+
+ \note Events are delayed by one frame due to object picking happening in the backend.
+ */
+void QScene2D::setMouseEnabled(bool enabled)
{
Q_D(QScene2D);
- if (d->m_renderManager->m_grabMouse != grab) {
- d->m_renderManager->m_grabMouse = grab;
- emit grabMouseChanged(grab);
+ if (d->m_renderManager->m_mouseEnabled != enabled) {
+ d->m_renderManager->m_mouseEnabled = enabled;
+ emit mouseEnabledChanged(enabled);
}
}
diff --git a/src/quick3d/quick3dscene2d/items/qscene2d.h b/src/quick3d/quick3dscene2d/items/qscene2d.h
index 2c982668a..73322a9e9 100644
--- a/src/quick3d/quick3dscene2d/items/qscene2d.h
+++ b/src/quick3d/quick3dscene2d/items/qscene2d.h
@@ -60,11 +60,9 @@ class QT3DQUICKSCENE2DSHARED_EXPORT QScene2D : public Qt3DCore::QNode
Q_OBJECT
Q_PROPERTY(Qt3DRender::QRenderTargetOutput *output READ output WRITE setOutput NOTIFY outputChanged)
- Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
Q_PROPERTY(QScene2D::RenderPolicy renderPolicy READ renderPolicy WRITE setRenderPolicy NOTIFY renderPolicyChanged)
- Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged)
Q_PROPERTY(QQuickItem *item READ item WRITE setItem NOTIFY itemChanged)
- Q_PROPERTY(bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled NOTIFY grabMouseChanged)
+ Q_PROPERTY(bool mouseEnabled READ isMouseEnabled WRITE setMouseEnabled NOTIFY mouseEnabledChanged)
Q_CLASSINFO("DefaultProperty", "item")
@@ -77,18 +75,11 @@ public:
Q_ENUM(RenderPolicy)
explicit QScene2D(Qt3DCore::QNode *parent = nullptr);
- QScene2D(QQmlEngine *engine, Qt3DCore::QNode *parent = nullptr);
- ~QScene2D();
Qt3DRender::QRenderTargetOutput *output() const;
- QUrl source() const;
- bool loaded() const;
QScene2D::RenderPolicy renderPolicy() const;
QQuickItem *item() const;
- QQmlEngine *engine() const;
- bool isGrabMouseEnabled() const;
-
- bool event(QEvent *event) Q_DECL_OVERRIDE;
+ bool isMouseEnabled() const;
QVector<Qt3DCore::QEntity *> entities();
void addEntity(Qt3DCore::QEntity *entity);
@@ -96,26 +87,21 @@ public:
public Q_SLOTS:
void setOutput(Qt3DRender::QRenderTargetOutput *output);
- void setSource(const QUrl &url);
void setRenderPolicy(QScene2D::RenderPolicy policy);
void setItem(QQuickItem *item);
- void setGrabMouseEnabled(bool grab);
+ void setMouseEnabled(bool enabled);
Q_SIGNALS:
void outputChanged(Qt3DRender::QRenderTargetOutput *output);
- void sourceChanged(const QUrl &url);
- void loadedChanged(bool loaded);
void renderPolicyChanged(QScene2D::RenderPolicy policy);
void itemChanged(QQuickItem *item);
- void grabMouseChanged(bool grab);
+ void mouseEnabledChanged(bool enabled);
protected:
Q_DECLARE_PRIVATE(QScene2D)
private:
Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const Q_DECL_OVERRIDE;
-
- void sourceLoaded();
};
} // namespace Quick
diff --git a/src/quick3d/quick3dscene2d/items/qscene2d_p.h b/src/quick3d/quick3dscene2d/items/qscene2d_p.h
index e40d3d6a9..217058f5c 100644
--- a/src/quick3d/quick3dscene2d/items/qscene2d_p.h
+++ b/src/quick3d/quick3dscene2d/items/qscene2d_p.h
@@ -55,6 +55,10 @@
QT_BEGIN_NAMESPACE
+namespace Qt3DCore {
+class QScene;
+}
+
namespace Qt3DRender {
namespace Quick {
@@ -70,6 +74,8 @@ public:
QScene2DPrivate();
~QScene2DPrivate();
+ void setScene(Qt3DCore::QScene *scene) Q_DECL_OVERRIDE;
+
Scene2DManager *m_renderManager;
QMetaObject::Connection m_textureDestroyedConnection;
Qt3DRender::QRenderTargetOutput *m_output;
@@ -82,6 +88,7 @@ struct QScene2DData
Scene2DSharedObjectPtr sharedObject;
Qt3DCore::QNodeId output;
QVector<Qt3DCore::QNodeId> entityIds;
+ bool mouseEnabled;
};
} // namespace Quick
diff --git a/src/quick3d/quick3dscene2d/items/scene2d.cpp b/src/quick3d/quick3dscene2d/items/scene2d.cpp
index ded595b36..b0c58c6c5 100644
--- a/src/quick3d/quick3dscene2d/items/scene2d.cpp
+++ b/src/quick3d/quick3dscene2d/items/scene2d.cpp
@@ -118,6 +118,7 @@ Scene2D::Scene2D()
, m_rbo(0)
, m_initialized(false)
, m_renderInitialized(false)
+ , m_mouseEnabled(true)
, m_renderPolicy(Qt3DRender::Quick::QScene2D::Continuous)
{
renderThreadClientCount->fetchAndAddAcquire(1);
@@ -125,12 +126,7 @@ Scene2D::Scene2D()
Scene2D::~Scene2D()
{
- // this gets called from aspect thread. Wait for the render thread then delete it.
- // TODO: render thread deletion
-// if (m_renderThread) {
-// m_renderThread->wait(1000);
-// delete m_renderThread;
-// }
+ stopGrabbing();
}
void Scene2D::setOutput(Qt3DCore::QNodeId outputId)
@@ -177,6 +173,7 @@ void Scene2D::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &chan
setSharedObject(data.sharedObject);
setOutput(data.output);
m_entities = data.entityIds;
+ m_mouseEnabled = data.mouseEnabled;
}
void Scene2D::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
@@ -192,49 +189,42 @@ void Scene2D::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
} else if (propertyChange->propertyName() == QByteArrayLiteral("output")) {
Qt3DCore::QNodeId outputId = propertyChange->value().value<Qt3DCore::QNodeId>();
setOutput(outputId);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("sharedObject")) {
- const Scene2DSharedObjectPtr sharedObject
- = propertyChange->value().value<Scene2DSharedObjectPtr>();
- setSharedObject(sharedObject);
} else if (propertyChange->propertyName() == QByteArrayLiteral("pressed")) {
QPickEventPtr ev = propertyChange->value().value<QPickEventPtr>();
handlePickEvent(QEvent::MouseButtonPress, ev);
} else if (propertyChange->propertyName() == QByteArrayLiteral("released")) {
QPickEventPtr ev = propertyChange->value().value<QPickEventPtr>();
handlePickEvent(QEvent::MouseButtonRelease, ev);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("clicked")) {
- QPickEventPtr ev = propertyChange->value().value<QPickEventPtr>();
- handlePickEvent(QEvent::MouseButtonDblClick, ev);
} else if (propertyChange->propertyName() == QByteArrayLiteral("moved")) {
QPickEventPtr ev = propertyChange->value().value<QPickEventPtr>();
handlePickEvent(QEvent::MouseMove, ev);
- } else if (propertyChange->propertyName() == QByteArrayLiteral("grabMouse")) {
- if (propertyChange->value().toBool()) {
- startGrabbing();
- } else {
- stopGrabbing();
+ } else if (propertyChange->propertyName() == QByteArrayLiteral("mouseEnabled")) {
+ m_mouseEnabled = propertyChange->value().toBool();
+ if (m_mouseEnabled && !m_cachedPickEvent.isNull()) {
+ handlePickEvent(QEvent::MouseButtonPress, m_cachedPickEvent);
+ m_cachedPickEvent.clear();
}
+ } else if (propertyChange->propertyName() == QByteArrayLiteral("sceneInitialized")) {
+ startGrabbing();
}
- /* TODO: handle these?
- else if (propertyChange->propertyName() == QByteArrayLiteral("entered")) {
-
- } else if (propertyChange->propertyName() == QByteArrayLiteral("exited")) {
-
- }*/
break;
}
case Qt3DCore::PropertyValueAdded: {
const auto change = qSharedPointerCast<Qt3DCore::QPropertyNodeAddedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("entities"))
+ if (change->propertyName() == QByteArrayLiteral("entities")) {
m_entities.push_back(change->addedNodeId());
+ registerObjectPickerEvents(change->addedNodeId());
+ }
break;
}
case Qt3DCore::PropertyValueRemoved: {
const auto change = qSharedPointerCast<Qt3DCore::QPropertyNodeRemovedChange>(e);
- if (change->propertyName() == QByteArrayLiteral("entities"))
+ if (change->propertyName() == QByteArrayLiteral("entities")) {
m_entities.removeOne(change->removedNodeId());
+ unregisterObjectPickerEvents(change->removedNodeId());
+ }
break;
}
@@ -468,46 +458,54 @@ void Scene2D::unregisterObjectPickerEvents(Qt3DCore::QNodeId entityId)
void Scene2D::handlePickEvent(int type, const Qt3DRender::QPickEventPtr &ev)
{
- QPickTriangleEvent *pickTriangle = static_cast<QPickTriangleEvent *>(ev.data());
- Entity *entity = nullptr;
- if (!resourceAccessor()->accessResource(RenderBackendResourceAccessor::EntityHandle,
- QPickEventPrivate::get(pickTriangle)->m_entity,
- (void**)&entity, nullptr)) {
+ if (!isEnabled())
return;
- }
- CoordinateReader reader(renderer()->nodeManagers());
- if (reader.setGeometry(entity->renderComponent<GeometryRenderer>(),
- QAttribute::defaultTextureCoordinateAttributeName())) {
- QVector4D c0 = reader.getCoordinate(pickTriangle->vertex1Index());
- QVector4D c1 = reader.getCoordinate(pickTriangle->vertex2Index());
- QVector4D c2 = reader.getCoordinate(pickTriangle->vertex3Index());
- QVector4D ci = c0 * pickTriangle->uvw().x()
- + c1 * pickTriangle->uvw().y() + c2 * pickTriangle->uvw().z();
- ci.setW(1.0f);
-
- const QSize size = m_sharedObject->m_quickWindow->size();
- QPointF pos = QPointF(ci.x() * size.width(), ci.y() * size.height());
- QMouseEvent *mouseEvent
- = new QMouseEvent(static_cast<QEvent::Type>(type),
- pos, pos, pos,
- static_cast<Qt::MouseButton>(pickTriangle->button()),
- static_cast<Qt::MouseButtons>(pickTriangle->buttons()),
- static_cast<Qt::KeyboardModifiers>(pickTriangle->modifiers()),
- Qt::MouseEventSynthesizedByApplication);
-
- QCoreApplication::postEvent(m_sharedObject->m_quickWindow, mouseEvent);
+ if (m_mouseEnabled) {
+ QPickTriangleEvent *pickTriangle = static_cast<QPickTriangleEvent *>(ev.data());
+ Entity *entity = nullptr;
+ if (!resourceAccessor()->accessResource(RenderBackendResourceAccessor::EntityHandle,
+ QPickEventPrivate::get(pickTriangle)->m_entity,
+ (void**)&entity, nullptr)) {
+ return;
+ }
+ CoordinateReader reader(renderer()->nodeManagers());
+ if (reader.setGeometry(entity->renderComponent<GeometryRenderer>(),
+ QAttribute::defaultTextureCoordinateAttributeName())) {
+ QVector4D c0 = reader.getCoordinate(pickTriangle->vertex1Index());
+ QVector4D c1 = reader.getCoordinate(pickTriangle->vertex2Index());
+ QVector4D c2 = reader.getCoordinate(pickTriangle->vertex3Index());
+ QVector4D ci = c0 * pickTriangle->uvw().x()
+ + c1 * pickTriangle->uvw().y() + c2 * pickTriangle->uvw().z();
+ ci.setW(1.0f);
+
+ const QSize size = m_sharedObject->m_quickWindow->size();
+ QPointF pos = QPointF(ci.x() * size.width(), (1.0f - ci.y()) * size.height());
+ QMouseEvent *mouseEvent
+ = new QMouseEvent(static_cast<QEvent::Type>(type),
+ pos, pos, pos,
+ static_cast<Qt::MouseButton>(pickTriangle->button()),
+ static_cast<Qt::MouseButtons>(pickTriangle->buttons()),
+ static_cast<Qt::KeyboardModifiers>(pickTriangle->modifiers()),
+ Qt::MouseEventSynthesizedByApplication);
+
+ QCoreApplication::postEvent(m_sharedObject->m_quickWindow, mouseEvent);
+ }
+ } else if (type == QEvent::MouseButtonPress) {
+ m_cachedPickEvent = ev;
+ } else {
+ m_cachedPickEvent.clear();
}
}
void Scene2D::startGrabbing()
{
- for (Qt3DCore::QNodeId e : m_entities)
+ for (Qt3DCore::QNodeId e : qAsConst(m_entities))
registerObjectPickerEvents(e);
}
void Scene2D::stopGrabbing()
{
- for (Qt3DCore::QNodeId e : m_entities)
+ for (Qt3DCore::QNodeId e : qAsConst(m_entities))
unregisterObjectPickerEvents(e);
}
diff --git a/src/quick3d/quick3dscene2d/items/scene2d_p.h b/src/quick3d/quick3dscene2d/items/scene2d_p.h
index d2845d847..b42089306 100644
--- a/src/quick3d/quick3dscene2d/items/scene2d_p.h
+++ b/src/quick3d/quick3dscene2d/items/scene2d_p.h
@@ -119,8 +119,10 @@ public:
bool m_initialized;
bool m_renderInitialized;
+ bool m_mouseEnabled;
Qt3DRender::Quick::QScene2D::RenderPolicy m_renderPolicy;
QVector<Qt3DCore::QNodeId> m_entities;
+ Qt3DRender::QPickEventPtr m_cachedPickEvent;
};
} // Quick
diff --git a/src/quick3d/quick3dscene2d/items/scene2dmanager.cpp b/src/quick3d/quick3dscene2d/items/scene2dmanager.cpp
index f0d6a6e34..20c080dec 100644
--- a/src/quick3d/quick3dscene2d/items/scene2dmanager.cpp
+++ b/src/quick3d/quick3dscene2d/items/scene2dmanager.cpp
@@ -72,9 +72,7 @@ QWindow *RenderControl::renderWindow(QPoint *offset)
Constructs qml render manager.
*/
Scene2DManager::Scene2DManager(QScene2DPrivate *priv)
- : m_qmlEngine(nullptr)
- , m_qmlComponent(nullptr)
- , m_rootItem(nullptr)
+ : m_rootItem(nullptr)
, m_item(nullptr)
, m_priv(priv)
, m_sharedObject(new Scene2DSharedObject(this))
@@ -83,9 +81,7 @@ Scene2DManager::Scene2DManager(QScene2DPrivate *priv)
, m_initialized(false)
, m_renderSyncRequested(false)
, m_backendInitialized(false)
- , m_noSourceMode(false)
- , m_ownEngine(false)
- , m_grabMouse(false)
+ , m_mouseEnabled(true)
{
m_sharedObject->m_surface = new QOffscreenSurface;
m_sharedObject->m_surface->setFormat(QSurfaceFormat::defaultFormat());
@@ -135,38 +131,17 @@ void Scene2DManager::requestRenderSync()
void Scene2DManager::startIfInitialized()
{
- if (!m_initialized && m_backendInitialized) {
- if (m_source.isValid() && !m_noSourceMode) {
- // Create a QML engine.
- if (!m_qmlEngine) {
- m_qmlEngine = new QQmlEngine;
- if (!m_qmlEngine->incubationController()) {
- m_qmlEngine->setIncubationController(m_sharedObject->m_quickWindow
- ->incubationController());
- }
- }
-
- // create component
- m_ownEngine = true;
- m_qmlComponent = new QQmlComponent(m_qmlEngine, m_source);
- if (m_qmlComponent->isLoading()) {
- connect(m_qmlComponent, &QQmlComponent::statusChanged,
- this, &Scene2DManager::run);
- } else {
- run();
- }
- } else if (m_item != nullptr) {
- m_rootItem = m_item;
+ if (!m_initialized && m_backendInitialized && m_item != nullptr) {
+ m_rootItem = m_item;
- // Associate root item with the window.
- m_rootItem->setParentItem(m_sharedObject->m_quickWindow->contentItem());
+ // Associate root item with the window.
+ m_rootItem->setParentItem(m_sharedObject->m_quickWindow->contentItem());
- // Update window size.
- updateSizes();
+ // Update window size.
+ updateSizes();
- m_initialized = true;
- m_sharedObject->setInitialized();
- }
+ m_initialized = true;
+ m_sharedObject->setInitialized();
}
}
@@ -177,54 +152,9 @@ void Scene2DManager::stopAndClean()
m_sharedObject->requestQuit();
m_sharedObject->wait();
m_sharedObject->cleanup();
- if (m_ownEngine) {
- QObject::disconnect(m_connection);
- delete m_qmlEngine;
- }
- delete m_qmlComponent;
- m_qmlEngine = nullptr;
- m_qmlComponent = nullptr;
}
}
-void Scene2DManager::run()
-{
- disconnect(m_qmlComponent, &QQmlComponent::statusChanged, this, &Scene2DManager::run);
-
- if (m_qmlComponent->isError()) {
- QList<QQmlError> errorList = m_qmlComponent->errors();
- for (const QQmlError &error: errorList)
- qWarning() << error.url() << error.line() << error;
- return;
- }
-
- QObject *rootObject = m_qmlComponent->create();
- if (m_qmlComponent->isError()) {
- QList<QQmlError> errorList = m_qmlComponent->errors();
- for (const QQmlError &error: errorList)
- qWarning() << error.url() << error.line() << error;
- return;
- }
-
- m_rootItem = qobject_cast<QQuickItem *>(rootObject);
- if (!m_rootItem) {
- qWarning("QScene2D: Root item is not a QQuickItem.");
- delete rootObject;
- return;
- }
-
- // The root item is ready. Associate it with the window.
- m_rootItem->setParentItem(m_sharedObject->m_quickWindow->contentItem());
-
- // Update window size.
- updateSizes();
-
- m_initialized = true;
- m_sharedObject->setInitialized();
-
- emit onLoadedChanged();
-}
-
void Scene2DManager::updateSizes()
{
const int width = m_rootItem->width();
@@ -236,15 +166,8 @@ void Scene2DManager::updateSizes()
m_sharedObject->m_quickWindow->setGeometry(0, 0, width, height);
}
-void Scene2DManager::setSource(const QUrl &url)
-{
- m_source = url;
- startIfInitialized();
-}
-
void Scene2DManager::setItem(QQuickItem *item)
{
- m_noSourceMode = true;
m_item = item;
startIfInitialized();
}
@@ -302,33 +225,6 @@ bool Scene2DManager::event(QEvent *e)
return QObject::event(e);
}
-bool Scene2DManager::forwardEvent(QEvent *event)
-{
- switch (event->type()) {
-
- case QEvent::MouseMove:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease: {
- QMouseEvent* me = static_cast<QMouseEvent *>(event);
- QPointF pos = me->localPos();
- pos = QPointF(pos.x() * m_rootItem->width(), pos.y() * m_rootItem->height());
- QMouseEvent nme = QMouseEvent(me->type(), pos, pos, pos, me->button(), me->buttons(),
- me->modifiers(), Qt::MouseEventSynthesizedByApplication);
- QCoreApplication::sendEvent(m_sharedObject->m_quickWindow, &nme);
- } break;
-
- case QEvent::KeyPress:
- case QEvent::KeyRelease: {
- QCoreApplication::sendEvent(m_sharedObject->m_quickWindow, event);
- } break;
-
- default:
- break;
- }
- return false;
-}
-
void Scene2DManager::doRenderSync()
{
QMutexLocker lock(&m_sharedObject->m_mutex);
@@ -346,23 +242,6 @@ void Scene2DManager::cleanup()
stopAndClean();
}
-void Scene2DManager::setEngine(QQmlEngine *engine)
-{
- m_qmlEngine = engine;
- m_ownEngine = false;
- if (engine) {
- m_connection = QObject::connect(engine, &QObject::destroyed,
- this, &Scene2DManager::engineDestroyed);
- }
-}
-
-void Scene2DManager::engineDestroyed()
-{
- QObject::disconnect(m_connection);
- m_qmlEngine = nullptr;
- m_ownEngine = false;
-}
-
} // namespace Quick
} // namespace Qt3DRender
diff --git a/src/quick3d/quick3dscene2d/items/scene2dmanager_p.h b/src/quick3d/quick3dscene2d/items/scene2dmanager_p.h
index d3c3a60a2..821616f47 100644
--- a/src/quick3d/quick3dscene2d/items/scene2dmanager_p.h
+++ b/src/quick3d/quick3dscene2d/items/scene2dmanager_p.h
@@ -75,46 +75,33 @@ public:
Scene2DManager(QScene2DPrivate *priv);
~Scene2DManager();
- QQmlEngine *m_qmlEngine;
- QQmlComponent *m_qmlComponent;
QQuickItem *m_rootItem;
QQuickItem *m_item;
QScene2DPrivate *m_priv;
QSharedPointer<Scene2DSharedObject> m_sharedObject;
- QUrl m_source;
Qt3DCore::QNodeId m_id;
- QMetaObject::Connection m_connection;
QScene2D::RenderPolicy m_renderPolicy;
bool m_requested;
bool m_initialized;
bool m_renderSyncRequested;
bool m_backendInitialized;
- bool m_noSourceMode;
- bool m_ownEngine;
- bool m_grabMouse;
+ bool m_mouseEnabled;
void requestRender();
void requestRenderSync();
void doRenderSync();
void startIfInitialized();
void stopAndClean();
- void run();
void updateSizes();
- void setSource(const QUrl &url);
void setItem(QQuickItem *item);
bool event(QEvent *e) Q_DECL_OVERRIDE;
- bool forwardEvent(QEvent *event);
-
- Q_SIGNAL void onLoadedChanged();
void cleanup();
- void setEngine(QQmlEngine *engine);
- void engineDestroyed();
};
} // namespace Quick
diff --git a/src/render/backend/platformsurfacefilter.cpp b/src/render/backend/platformsurfacefilter.cpp
index 891e30c44..7458f607d 100644
--- a/src/render/backend/platformsurfacefilter.cpp
+++ b/src/render/backend/platformsurfacefilter.cpp
@@ -107,6 +107,10 @@ bool PlatformSurfaceFilter::eventFilter(QObject *obj, QEvent *e)
// If we remove it, the call to isSurfaceValid will
// implicitely return false
PlatformSurfaceFilter::m_surfacesValidity.remove(m_surface);
+ if (m_obj) {
+ m_obj->removeEventFilter(this);
+ m_obj = nullptr;
+ }
break;
}
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
index 0fda6e5b4..bd8687d5e 100644
--- a/src/render/backend/renderer.cpp
+++ b/src/render/backend/renderer.cpp
@@ -86,6 +86,7 @@
#include <Qt3DRender/private/updatelevelofdetailjob_p.h>
#include <Qt3DRender/private/buffercapture_p.h>
#include <Qt3DRender/private/offscreensurfacehelper_p.h>
+#include <Qt3DRender/private/renderviewbuilder_p.h>
#include <Qt3DRender/qcameralens.h>
#include <Qt3DCore/qt3dcore-config.h>
@@ -535,17 +536,26 @@ void Renderer::render()
void Renderer::doRender()
{
- bool submissionSucceeded = false;
- bool hasCleanedQueueAndProceeded = false;
Renderer::ViewSubmissionResultData submissionData;
+ bool hasCleanedQueueAndProceeded = false;
bool preprocessingComplete = false;
-
- if (isReadyToSubmit()) {
-
- // Lock the mutex to protect access to m_surface and check if we are still set
- // to the running state and that we have a valid surface on which to draw
- // TO DO: Is that still needed given the surface changes
- QMutexLocker locker(&m_mutex);
+ bool beganDrawing = false;
+ const bool canSubmit = isReadyToSubmit();
+
+ // Lock the mutex to protect access to the renderQueue while we look for its state
+ QMutexLocker locker(&m_renderQueueMutex);
+ const bool queueIsComplete = m_renderQueue->isFrameQueueComplete();
+ const bool queueIsEmpty = m_renderQueue->targetRenderViewCount() == 0;
+
+ // When using synchronous rendering (QtQuick)
+ // We are not sure that the frame queue is actually complete
+ // Since a call to render may not be synched with the completions
+ // of the RenderViewJobs
+ // In such a case we return early, waiting for a next call with
+ // the frame queue complete at this point
+
+ // RenderQueue is complete (but that means it may be of size 0)
+ if (canSubmit && (queueIsComplete && !queueIsEmpty)) {
const QVector<Render::RenderView *> renderViews = m_renderQueue->nextFrameQueue();
#ifdef QT3D_JOBS_RUN_STATS
@@ -560,8 +570,7 @@ void Renderer::doRender()
submissionStatsPart2.jobId.typeAndInstance[1] = 0;
submissionStatsPart2.threadId = reinterpret_cast<quint64>(QThread::currentThreadId());
#endif
-
- if (canRender() && (submissionSucceeded = renderViews.size() > 0) == true) {
+ if (canRender()) {
// Clear all dirty flags but Compute so that
// we still render every frame when a compute shader is used in a scene
BackendNodeDirtySet changesToUnset = m_changeSet;
@@ -583,7 +592,8 @@ void Renderer::doRender()
// Reset state for each draw if we don't have complete control of the context
if (!m_ownedContext)
m_graphicsContext->setCurrentStateSet(nullptr);
- if (m_graphicsContext->beginDrawing(surface)) {
+ beganDrawing = m_graphicsContext->beginDrawing(surface);
+ if (beganDrawing) {
// 1) Execute commands for buffer uploads, texture updates, shader loading first
updateGLResources();
// 2) Update VAO and copy data into commands to allow concurrent submission
@@ -594,6 +604,7 @@ void Renderer::doRender()
}
// 2) Proceed to next frame and start preparing frame n + 1
m_renderQueue->reset();
+ locker.unlock(); // Done protecting RenderQueue
m_vsyncFrameAdvanceService->proceedToNextFrame();
hasCleanedQueueAndProceeded = true;
@@ -637,61 +648,57 @@ void Renderer::doRender()
#endif
}
- // Note: submissionSucceeded is false when
- // * we cannot render because a shutdown has been scheduled
- // * the renderqueue is incomplete (only when rendering with a Scene3D)
- // Otherwise returns true even for cases like
- // * No render view
- // * No surface set
- // * OpenGLContext failed to be set current
- // This behavior is important as we need to
- // call proceedToNextFrame despite rendering errors that aren't fatal
-
// Only reset renderQueue and proceed to next frame if the submission
- // succeeded or it we are using a render thread and that is wasn't performed
+ // succeeded or if we are using a render thread and that is wasn't performed
// already
- // If submissionSucceeded isn't true this implies that something went wrong
+ // If hasCleanedQueueAndProceeded isn't true this implies that something went wrong
// with the rendering and/or the renderqueue is incomplete from some reason
// (in the case of scene3d the render jobs may be taking too long ....)
- if (m_renderThread || submissionSucceeded) {
-
- if (!hasCleanedQueueAndProceeded) {
- // Reset the m_renderQueue so that we won't try to render
- // with a queue used by a previous frame with corrupted content
- // if the current queue was correctly submitted
- m_renderQueue->reset();
-
- // We allow the RenderTickClock service to proceed to the next frame
- // In turn this will allow the aspect manager to request a new set of jobs
- // to be performed for each aspect
- m_vsyncFrameAdvanceService->proceedToNextFrame();
- }
+ // or alternatively it could be complete but empty (RenderQueue of size 0)
+ if (!hasCleanedQueueAndProceeded &&
+ (m_renderThread || queueIsComplete || queueIsEmpty)) {
+ // RenderQueue was full but something bad happened when
+ // trying to render it and therefore proceedToNextFrame was not called
+ // Note: in this case the renderQueue mutex is still locked
+
+ // Reset the m_renderQueue so that we won't try to render
+ // with a queue used by a previous frame with corrupted content
+ // if the current queue was correctly submitted
+ m_renderQueue->reset();
+
+ // We allow the RenderTickClock service to proceed to the next frame
+ // In turn this will allow the aspect manager to request a new set of jobs
+ // to be performed for each aspect
+ m_vsyncFrameAdvanceService->proceedToNextFrame();
+ }
- // Perform the last swapBuffers calls after the proceedToNextFrame
- // as this allows us to gain a bit of time for the preparation of the
- // next frame
+ // Perform the last swapBuffers calls after the proceedToNextFrame
+ // as this allows us to gain a bit of time for the preparation of the
+ // next frame
+ // Finish up with last surface used in the list of RenderViews
+ if (beganDrawing) {
+ SurfaceLocker surfaceLock(submissionData.surface);
// Finish up with last surface used in the list of RenderViews
- if (submissionSucceeded) {
- SurfaceLocker surfaceLock(submissionData.surface);
- // Finish up with last surface used in the list of RenderViews
- m_graphicsContext->endDrawing(submissionData.lastBoundFBOId == m_graphicsContext->defaultFBO() && surfaceLock.isSurfaceValid());
- }
+ m_graphicsContext->endDrawing(submissionData.lastBoundFBOId == m_graphicsContext->defaultFBO() && surfaceLock.isSurfaceValid());
}
}
// Called by RenderViewJobs
+// When the frameQueue is complete and we are using a renderThread
+// we allow the render thread to proceed
void Renderer::enqueueRenderView(Render::RenderView *renderView, int submitOrder)
{
- QMutexLocker locker(&m_mutex); // Prevent out of order execution
+ QMutexLocker locker(&m_renderQueueMutex); // Prevent out of order execution
// We cannot use a lock free primitive here because:
// - QVector is not thread safe
// - Even if the insert is made correctly, the isFrameComplete call
// could be invalid since depending on the order of execution
// the counter could be complete but the renderview not yet added to the
// buffer depending on whichever order the cpu decides to process this
-
- if (m_renderQueue->queueRenderView(renderView, submitOrder)) {
+ const bool isQueueComplete = m_renderQueue->queueRenderView(renderView, submitOrder);
+ locker.unlock(); // We're done protecting the queue at this point
+ if (isQueueComplete) {
if (m_renderThread && m_running.load())
Q_ASSERT(m_submitRenderViewsSemaphore.available() == 0);
m_submitRenderViewsSemaphore.release(1);
@@ -730,16 +737,6 @@ bool Renderer::isReadyToSubmit()
// something to render
// The case of shutdown should have been handled just before
Q_ASSERT(m_renderQueue->isFrameQueueComplete());
- } else {
- // When using synchronous rendering (QtQuick)
- // We are not sure that the frame queue is actually complete
- // Since a call to render may not be synched with the completions
- // of the RenderViewJobs
- // In such a case we return early, waiting for a next call with
- // the frame queue complete at this point
- QMutexLocker locker(&m_mutex);
- if (!m_renderQueue->isFrameQueueComplete())
- return false;
}
return true;
}
@@ -1016,12 +1013,11 @@ void Renderer::updateGLResources()
const QVector<HBuffer> dirtyBufferHandles = std::move(m_dirtyBuffers);
for (HBuffer handle: dirtyBufferHandles) {
Buffer *buffer = m_nodesManager->bufferManager()->data(handle);
- // Perform data upload
// Forces creation if it doesn't exit
if (!m_graphicsContext->hasGLBufferForBuffer(buffer))
m_graphicsContext->glBufferForRenderBuffer(buffer);
- else if (buffer->isDirty()) // Otherwise update the glBuffer
- m_graphicsContext->updateBuffer(buffer);
+ // Update the glBuffer data
+ m_graphicsContext->updateBuffer(buffer);
buffer->unsetDirty();
}
}
@@ -1061,6 +1057,11 @@ void Renderer::updateGLResources()
// Render Thread
void Renderer::updateTexture(Texture *texture)
{
+ // Check that the current texture images are still in place, if not, do not update
+ const bool isValid = texture->isValid();
+ if (!isValid)
+ return;
+
// For implementing unique, non-shared, non-cached textures.
// for now, every texture is shared by default
@@ -1425,16 +1426,25 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
renderBinJobs.push_back(m_textureGathererJob);
renderBinJobs.push_back(m_shaderGathererJob);
- // Traverse the current framegraph. For each leaf node create a
- // RenderView and set its configuration then create a job to
- // populate the RenderView with a set of RenderCommands that get
- // their details from the RenderNodes that are visible to the
- // Camera selected by the framegraph configuration
- FrameGraphVisitor visitor(this, m_nodesManager->frameGraphManager());
- visitor.traverse(frameGraphRoot(), &renderBinJobs);
+ QMutexLocker lock(&m_renderQueueMutex);
+ if (m_renderQueue->wasReset()) { // Have we rendered yet? (Scene3D case)
+ // Traverse the current framegraph. For each leaf node create a
+ // RenderView and set its configuration then create a job to
+ // populate the RenderView with a set of RenderCommands that get
+ // their details from the RenderNodes that are visible to the
+ // Camera selected by the framegraph configuration
+ FrameGraphVisitor visitor(m_nodesManager->frameGraphManager());
+ const QVector<FrameGraphNode *> fgLeaves = visitor.traverse(frameGraphRoot());
+
+ const int fgBranchCount = fgLeaves.size();
+ for (int i = 0; i < fgBranchCount; ++i) {
+ RenderViewBuilder builder(fgLeaves.at(i), i, this);
+ renderBinJobs.append(builder.buildJobHierachy());
+ }
- // Set target number of RenderViews
- m_renderQueue->setTargetRenderViewCount(visitor.leafNodeCount());
+ // Set target number of RenderViews
+ m_renderQueue->setTargetRenderViewCount(fgBranchCount);
+ }
return renderBinJobs;
}
diff --git a/src/render/backend/renderer_p.h b/src/render/backend/renderer_p.h
index 9df24ef2c..af10108e9 100644
--- a/src/render/backend/renderer_p.h
+++ b/src/render/backend/renderer_p.h
@@ -259,7 +259,7 @@ public:
ViewSubmissionResultData submitRenderViews(const QVector<Render::RenderView *> &renderViews);
- QMutex* mutex() { return &m_mutex; }
+ QMutex* mutex() { return &m_renderQueueMutex; }
#ifdef QT3D_RENDER_UNIT_TESTS
@@ -290,7 +290,7 @@ private:
QScopedPointer<RenderThread> m_renderThread;
QScopedPointer<VSyncFrameAdvanceService> m_vsyncFrameAdvanceService;
- QMutex m_mutex;
+ QMutex m_renderQueueMutex;
QSemaphore m_submitRenderViewsSemaphore;
QSemaphore m_waitForInitializationToBeCompleted;
diff --git a/src/render/backend/renderqueue.cpp b/src/render/backend/renderqueue.cpp
index 6ec7da464..2fa1cb7d2 100644
--- a/src/render/backend/renderqueue.cpp
+++ b/src/render/backend/renderqueue.cpp
@@ -49,6 +49,7 @@ namespace Render {
RenderQueue::RenderQueue()
: m_noRender(false)
+ , m_wasReset(true)
, m_targetRenderViewCount(0)
, m_currentRenderViewCount(0)
, m_currentWorkQueue(1)
@@ -70,6 +71,7 @@ void RenderQueue::reset()
m_targetRenderViewCount = 0;
m_currentWorkQueue.clear();
m_noRender = false;
+ m_wasReset = true;
}
void RenderQueue::setNoRender()
@@ -88,6 +90,7 @@ bool RenderQueue::queueRenderView(RenderView *renderView, uint submissionOrderIn
Q_ASSERT(!m_noRender);
m_currentWorkQueue[submissionOrderIndex] = renderView;
++m_currentRenderViewCount;
+ Q_ASSERT(m_currentRenderViewCount <= m_targetRenderViewCount);
return isFrameQueueComplete();
}
@@ -109,6 +112,7 @@ void RenderQueue::setTargetRenderViewCount(int targetRenderViewCount)
Q_ASSERT(!m_noRender);
m_targetRenderViewCount = targetRenderViewCount;
m_currentWorkQueue.resize(targetRenderViewCount);
+ m_wasReset = false;
}
/*!
@@ -119,7 +123,7 @@ void RenderQueue::setTargetRenderViewCount(int targetRenderViewCount)
bool RenderQueue::isFrameQueueComplete() const
{
return (m_noRender
- || (m_targetRenderViewCount && m_targetRenderViewCount == currentRenderViewCount()));
+ || (m_targetRenderViewCount > 0 && m_targetRenderViewCount == m_currentRenderViewCount));
}
} // namespace Render
diff --git a/src/render/backend/renderqueue_p.h b/src/render/backend/renderqueue_p.h
index 49316049b..611f5849a 100644
--- a/src/render/backend/renderqueue_p.h
+++ b/src/render/backend/renderqueue_p.h
@@ -77,9 +77,13 @@ public:
void reset();
void setNoRender();
+ inline bool isNoRender() const { return m_noRender; }
+
+ inline bool wasReset() const { return m_wasReset; }
private:
bool m_noRender;
+ bool m_wasReset;
int m_targetRenderViewCount;
int m_currentRenderViewCount;
QVector<RenderView *> m_currentWorkQueue;
diff --git a/src/render/backend/renderviewbuilder.cpp b/src/render/backend/renderviewbuilder.cpp
index f1355d27e..f47c6f419 100644
--- a/src/render/backend/renderviewbuilder.cpp
+++ b/src/render/backend/renderviewbuilder.cpp
@@ -66,14 +66,14 @@ public:
RenderView *rv = m_renderViewJob->renderView();
int totalCommandCount = 0;
- for (const auto renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs))
+ for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs))
totalCommandCount += renderViewCommandBuilder->commands().size();
QVector<RenderCommand *> commands;
commands.reserve(totalCommandCount);
// Reduction
- for (const auto renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs))
+ for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs))
commands += std::move(renderViewCommandBuilder->commands());
rv->setCommands(commands);
@@ -139,13 +139,13 @@ public:
m_filterEntityByLayerJob->setLayers(rv->layerFilter());
// Material Parameter building
- for (const auto materialGatherer : qAsConst(m_materialGathererJobs)) {
+ for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) {
materialGatherer->setRenderPassFilter(const_cast<RenderPassFilter *>(rv->renderPassFilter()));
materialGatherer->setTechniqueFilter(const_cast<TechniqueFilter *>(rv->techniqueFilter()));
}
// Command builders
- for (const auto renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs))
+ for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs))
renderViewCommandBuilder->setRenderView(rv);
// Set whether frustum culling is enabled or not
@@ -188,8 +188,6 @@ public:
RenderView *rv = m_renderViewJob->renderView();
if (!rv->noDraw()) {
- // Set the light sources
- rv->setLightSources(std::move(m_lightGathererJob->lights()));
rv->setEnvironmentLight(m_lightGathererJob->takeEnvironmentLight());
// We sort the vector so that the removal can then be performed linearly
@@ -208,6 +206,14 @@ public:
QVector<Entity *> filteredEntities = m_filterEntityByLayerJob->filteredEntities();
RenderViewBuilder::removeEntitiesNotInSubset(renderableEntities, filteredEntities);
+ // Set the light sources, with layer filters applied.
+ QVector<LightSource> lightSources = m_lightGathererJob->lights();
+ for (int i = 0; i < lightSources.count(); ++i) {
+ if (!filteredEntities.contains(lightSources[i].entity))
+ lightSources.removeAt(i--);
+ }
+ rv->setLightSources(lightSources);
+
// Filter out frustum culled entity for drawable entities
if (isDraw && rv->frustumCulling())
RenderViewBuilder::removeEntitiesNotInSubset(renderableEntities, m_frustumCullingJob->visibleEntities());
@@ -225,7 +231,7 @@ public:
// Reduction
QHash<Qt3DCore::QNodeId, QVector<RenderPassParameterData>> params;
- for (const auto materialGatherer : qAsConst(m_materialGathererJobs))
+ for (const auto &materialGatherer : qAsConst(m_materialGathererJobs))
params.unite(materialGatherer->materialToPassAndParameter());
// Set all required data on the RenderView for final processing
rv->setMaterialParameterTable(std::move(params));
@@ -425,7 +431,7 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
m_filterEntityByLayerJob->addDependency(m_renderer->updateTreeEnabledJob());
m_syncRenderCommandBuildingJob->addDependency(m_syncRenderViewInitializationJob);
- for (const auto materialGatherer : qAsConst(m_materialGathererJobs)) {
+ for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) {
materialGatherer->addDependency(m_syncRenderViewInitializationJob);
materialGatherer->addDependency(m_renderer->filterCompatibleTechniqueJob());
m_syncRenderCommandBuildingJob->addDependency(materialGatherer);
@@ -436,7 +442,7 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
m_syncRenderCommandBuildingJob->addDependency(m_lightGathererJob);
m_syncRenderCommandBuildingJob->addDependency(m_frustumCullingJob);
- for (const auto renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) {
+ for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) {
renderViewCommandBuilder->addDependency(m_syncRenderCommandBuildingJob);
m_syncRenderViewCommandBuildersJob->addDependency(renderViewCommandBuilder);
}
@@ -458,13 +464,13 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
jobs.push_back(m_filterEntityByLayerJob); // Step 3
jobs.push_back(m_setClearDrawBufferIndexJob); // Step 3
- for (const auto materialGatherer : qAsConst(m_materialGathererJobs)) // Step3
+ for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) // Step3
jobs.push_back(materialGatherer);
jobs.push_back(m_frustumCullingJob); // Step 4
jobs.push_back(m_syncRenderCommandBuildingJob); // Step 4
- for (const auto renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) // Step 5
+ for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) // Step 5
jobs.push_back(renderViewCommandBuilder);
jobs.push_back(m_syncRenderViewCommandBuildersJob); // Step 6
diff --git a/src/render/framegraph/framegraphvisitor.cpp b/src/render/framegraph/framegraphvisitor.cpp
index d31e9cddd..cd8b08219 100644
--- a/src/render/framegraph/framegraphvisitor.cpp
+++ b/src/render/framegraph/framegraphvisitor.cpp
@@ -43,7 +43,6 @@
#include "framegraphnode_p.h"
#include <Qt3DRender/private/renderer_p.h>
#include <Qt3DRender/private/managers_p.h>
-#include <Qt3DRender/private/renderviewbuilder_p.h>
#include <QThreadPool>
QT_BEGIN_NAMESPACE
@@ -53,24 +52,16 @@ using namespace Qt3DCore;
namespace Qt3DRender {
namespace Render {
-FrameGraphVisitor::FrameGraphVisitor(Renderer *renderer,
- const FrameGraphManager *manager)
- : m_renderer(renderer)
- , m_manager(manager)
- , m_jobs(nullptr)
- , m_renderviewIndex(0)
-
+FrameGraphVisitor::FrameGraphVisitor(const FrameGraphManager *manager)
+ : m_manager(manager)
{
+ m_leaves.reserve(8);
}
-void FrameGraphVisitor::traverse(FrameGraphNode *root,
- QVector<Qt3DCore::QAspectJobPtr> *jobs)
+QVector<FrameGraphNode *> FrameGraphVisitor::traverse(FrameGraphNode *root)
{
- m_jobs = jobs;
- m_renderviewIndex = 0;
+ m_leaves.clear();
- Q_ASSERT(m_renderer);
- Q_ASSERT(m_jobs);
Q_ASSERT_X(root, Q_FUNC_INFO, "The FrameGraphRoot is null");
// Kick off the traversal
@@ -78,6 +69,7 @@ void FrameGraphVisitor::traverse(FrameGraphNode *root,
if (node == nullptr)
qCritical() << Q_FUNC_INFO << "FrameGraph is null";
visit(node);
+ return m_leaves;
}
void FrameGraphVisitor::visit(Render::FrameGraphNode *node)
@@ -97,10 +89,8 @@ void FrameGraphVisitor::visit(Render::FrameGraphNode *node)
// Leaf node - create a RenderView ready to be populated
// TODO: Pass in only framegraph config that has changed from previous
// index RenderViewJob.
- if (fgChildIds.empty()) {
- RenderViewBuilder builder(node, m_renderviewIndex++, m_renderer);
- m_jobs->append(builder.buildJobHierachy());
- }
+ if (fgChildIds.empty())
+ m_leaves.push_back(node);
}
} // namespace Render
diff --git a/src/render/framegraph/framegraphvisitor_p.h b/src/render/framegraph/framegraphvisitor_p.h
index af8f4caab..f4c0d7796 100644
--- a/src/render/framegraph/framegraphvisitor_p.h
+++ b/src/render/framegraph/framegraphvisitor_p.h
@@ -66,24 +66,18 @@ class FrameGraphNode;
class Renderer;
class FrameGraphManager;
-class FrameGraphVisitor
+class Q_AUTOTEST_EXPORT FrameGraphVisitor
{
public:
- explicit FrameGraphVisitor(Renderer *renderer,
- const FrameGraphManager *nodeManager);
+ explicit FrameGraphVisitor(const FrameGraphManager *nodeManager);
- void traverse(FrameGraphNode *root,
- QVector<Qt3DCore::QAspectJobPtr> *jobs);
-
- inline int leafNodeCount() Q_DECL_NOTHROW { return m_renderviewIndex; }
+ QVector<FrameGraphNode *> traverse(FrameGraphNode *root);
private:
void visit(Render::FrameGraphNode *node);
- Renderer *m_renderer;
const FrameGraphManager *m_manager;
- QVector<Qt3DCore::QAspectJobPtr> *m_jobs;
- int m_renderviewIndex;
+ QVector<FrameGraphNode *> m_leaves;
};
} // namespace Render
diff --git a/src/render/framegraph/qsortcriterion.cpp b/src/render/framegraph/qsortcriterion.cpp
deleted file mode 100644
index f5252b1f7..000000000
--- a/src/render/framegraph/qsortcriterion.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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 "qsortcriterion.h"
-#include "qsortcriterion_p.h"
-#include <Qt3DCore/qnodepropertychange.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-
-QSortCriterionPrivate::QSortCriterionPrivate()
- : QNodePrivate()
- , m_sort(QSortCriterion::StateChangeCost)
-{
-}
-
-QSortCriterion::QSortCriterion(QNode *parent)
- : QNode(*new QSortCriterionPrivate, parent)
-{
-}
-
-QSortCriterion::SortType QSortCriterion::sort() const
-{
- Q_D(const QSortCriterion);
- return d->m_sort;
-}
-
-void QSortCriterion::setSort(QSortCriterion::SortType sort)
-{
- Q_D(QSortCriterion);
- if (d->m_sort != sort) {
- d->m_sort = sort;
- emit sortChanged(sort);
- }
-}
-
-/*! \internal */
-QSortCriterion::QSortCriterion(QSortCriterionPrivate &dd, QNode *parent)
- : QNode(dd, parent)
-{
-}
-
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
diff --git a/src/render/framegraph/qsortcriterion.h b/src/render/framegraph/qsortcriterion.h
deleted file mode 100644
index 230f111f9..000000000
--- a/src/render/framegraph/qsortcriterion.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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 QT3DRENDER_QSORTCRITERION_H
-#define QT3DRENDER_QSORTCRITERION_H
-
-#include <Qt3DCore/qnode.h>
-#include <Qt3DRender/qt3drender_global.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-
-class QSortCriterionPrivate;
-
-class QT3DRENDERSHARED_EXPORT QSortCriterion : public Qt3DCore::QNode
-{
- Q_OBJECT
- Q_PROPERTY(Qt3DRender::QSortCriterion::SortType sort READ sort WRITE setSort NOTIFY sortChanged)
-public:
- explicit QSortCriterion(Qt3DCore::QNode *parent = Q_NULLPTR);
-
- enum SortType {
- StateChangeCost = (1 << 0),
- BackToFront = (1 << 1),
- Material = (1 << 2)
- };
- Q_ENUM(SortType) // LCOV_EXCL_LINE
-
- SortType sort() const;
-
-public Q_SLOTS:
- void setSort(SortType sort);
-
-Q_SIGNALS:
- void sortChanged(SortType sort);
-
-protected:
- QSortCriterion(QSortCriterionPrivate &dd, Qt3DCore::QNode *parent = Q_NULLPTR);
-
-private:
- Q_DECLARE_PRIVATE(QSortCriterion)
-};
-
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
-
-#endif // QSORTCRITERION_H
diff --git a/src/render/framegraph/rendercapture.cpp b/src/render/framegraph/rendercapture.cpp
index 1d3117c0d..dea1cf565 100644
--- a/src/render/framegraph/rendercapture.cpp
+++ b/src/render/framegraph/rendercapture.cpp
@@ -92,7 +92,7 @@ void RenderCapture::sendRenderCaptures()
{
QMutexLocker lock(&m_mutex);
- for (const RenderCaptureDataPtr data : qAsConst(m_renderCaptureData)) {
+ for (const RenderCaptureDataPtr &data : qAsConst(m_renderCaptureData)) {
auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
e->setPropertyName("renderCaptureData");
diff --git a/src/render/framegraph/viewportnode.cpp b/src/render/framegraph/viewportnode.cpp
index c16a660b0..b68f7b55b 100644
--- a/src/render/framegraph/viewportnode.cpp
+++ b/src/render/framegraph/viewportnode.cpp
@@ -123,7 +123,7 @@ void ViewportNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
if (e->type() == PropertyUpdated) {
QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
if (propertyChange->propertyName() == QByteArrayLiteral("normalizedRect")) {
- QRectF normalizedRect = propertyChange->value().value<QRectF>();
+ QRectF normalizedRect = propertyChange->value().toRectF();
setXMin(normalizedRect.x());
setYMin(normalizedRect.y());
setXMax(normalizedRect.width());
diff --git a/src/render/frontend/qabstractfunctor.h b/src/render/frontend/qabstractfunctor.h
index c05c04743..95f6aee51 100644
--- a/src/render/frontend/qabstractfunctor.h
+++ b/src/render/frontend/qabstractfunctor.h
@@ -80,6 +80,14 @@ public:
virtual ~QAbstractFunctor();
virtual qintptr id() const = 0;
+ // TODO: Remove when moving a copy of this to Qt3DCore
+ template<class T>
+ const T *functor_cast(const QAbstractFunctor *other) const
+ {
+ if (other->id() == functorTypeId<T>())
+ return static_cast<const T *>(other);
+ return nullptr;
+ }
private:
Q_DISABLE_COPY(QAbstractFunctor)
};
diff --git a/src/render/frontend/qlevelofdetail.cpp b/src/render/frontend/qlevelofdetail.cpp
index df169876e..03df4e6a8 100644
--- a/src/render/frontend/qlevelofdetail.cpp
+++ b/src/render/frontend/qlevelofdetail.cpp
@@ -77,7 +77,7 @@ QLevelOfDetailPrivate::QLevelOfDetailPrivate()
The currentIndex property can then be used, for example, to enable or
disable entities, change material, etc.
- The LevelOfDetail component is not shareable between multiple Entity's.
+ The LevelOfDetail component is not shareable between multiple \l [QML]{Entity}{entities}.
\code
#include <Qt3DCore/QEntity>
@@ -185,35 +185,6 @@ QLevelOfDetailPrivate::QLevelOfDetailPrivate()
* \sa Qt3DRender::QLevelOfDetail::ThresholdType
*/
-
-/*!
- * \enum Qt3DRender::QLevelOfDetail::SizeProxyMode
- *
- * Specifies what is used as a proxy for the entity when computing distance
- * or size.
- *
- * \value LevelOfDetailBoundingSphere use the bounding sphere specified by the center
- * and radius properties.
- * \value Children LevelOfDetailBoundingSphere use the bounding sphere of the entity the
- * component is attached to.
- */
-
-/*!
- * \qmlproperty enumeration LevelOfDetail::SizeProxyMode
- *
- * Specifies what is used as a proxy for the entity when computing distance
- * or size.
- *
- * \list
- * \li LevelOfDetailBoundingSphere use the bounding sphere specified by the center
- * and radius properties.
- * \li Children LevelOfDetailBoundingSphere use the bounding sphere of the entity the
- * component is attached to.
- * \endlist
- * \sa Qt3DRender::QLevelOfDetail::SizeProxyMode
- */
-
-
/*!
* \qmlproperty Camera LevelOfDetail::camera
*
@@ -442,7 +413,7 @@ void QLevelOfDetail::setThresholds(const QVector<qreal> &thresholds)
Q_D(QLevelOfDetail);
if (d->m_thresholds != thresholds) {
d->m_thresholds = thresholds;
- thresholdsChanged(d->m_thresholds);
+ emit thresholdsChanged(d->m_thresholds);
}
}
diff --git a/src/render/frontend/qlevelofdetailswitch.cpp b/src/render/frontend/qlevelofdetailswitch.cpp
index a6d2b1530..845fdd5a6 100644
--- a/src/render/frontend/qlevelofdetailswitch.cpp
+++ b/src/render/frontend/qlevelofdetailswitch.cpp
@@ -69,11 +69,17 @@ namespace Qt3DRender {
This component is assigned to an entity. When the entity changes distance relative
to the camera, the LevelOfDetailSwitch will disable all the child entities except
- the one matching index \l LevelOfDetailSwitch::currentIndex.
+ the one matching index \l currentIndex.
\sa LevelOfDetail
*/
+/*!
+ \qmlproperty int LevelOfDetailSwitch::currentIndex
+
+ The index of the presently selected child entity.
+*/
+
/*! \fn Qt3DRender::QLevelOfDetailSwitch::QLevelOfDetailSwitch(Qt3DCore::QNode *parent)
Constructs a new QLevelOfDetailSwitch with the specified \a parent.
*/
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp
index e962f3700..11c03e7db 100644
--- a/src/render/frontend/qrenderaspect.cpp
+++ b/src/render/frontend/qrenderaspect.cpp
@@ -267,7 +267,7 @@ void QRenderAspectPrivate::registerBackendTypes()
q->registerBackendType<QObjectPicker>(QSharedPointer<Render::NodeFunctor<Render::ObjectPicker, Render::ObjectPickerManager> >::create(m_renderer));
// Plugins
- for (QString plugin : m_pluginConfig)
+ for (const QString &plugin : m_pluginConfig)
loadRenderPlugin(plugin);
}
@@ -608,7 +608,7 @@ void QRenderAspectPrivate::configurePlugin(const QString &plugin)
if (!m_pluginConfig.contains(plugin)) {
m_pluginConfig.append(plugin);
- for (QRenderAspectPrivate *instance : m_instances)
+ for (QRenderAspectPrivate *instance : qAsConst(m_instances))
instance->loadRenderPlugin(plugin);
}
}
diff --git a/src/render/geometry/attribute.cpp b/src/render/geometry/attribute.cpp
index 7e1ea79dd..6c8c0113a 100644
--- a/src/render/geometry/attribute.cpp
+++ b/src/render/geometry/attribute.cpp
@@ -108,7 +108,7 @@ void Attribute::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
QByteArray propertyName = propertyChange->propertyName();
if (propertyName == QByteArrayLiteral("name")) {
- m_name = propertyChange->value().value<QString>();
+ m_name = propertyChange->value().toString();
m_nameId = StringToInt::lookupId(m_name);
m_attributeDirty = true;
} else if (propertyName == QByteArrayLiteral("vertexBaseType")) {
diff --git a/src/render/geometry/buffer.cpp b/src/render/geometry/buffer.cpp
index 1133b8e5e..55c86910f 100644
--- a/src/render/geometry/buffer.cpp
+++ b/src/render/geometry/buffer.cpp
@@ -88,6 +88,9 @@ void Buffer::executeFunctor()
{
Q_ASSERT(m_functor);
m_data = (*m_functor)();
+ // Request data to be loaded
+ forceDataUpload();
+
if (m_syncData) {
// Send data back to the frontend
auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
@@ -101,6 +104,8 @@ void Buffer::executeFunctor()
//Called from th sendBufferJob
void Buffer::updateDataFromGPUToCPU(QByteArray data)
{
+ // Note: when this is called, data is what's currently in GPU memory
+ // so m_data shouldn't be reuploaded
m_data = data;
// Send data back to the frontend
auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
@@ -121,21 +126,37 @@ void Buffer::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &chang
m_access = data.access;
m_bufferDirty = true;
+ if (!m_data.isEmpty())
+ forceDataUpload();
+
m_functor = data.functor;
Q_ASSERT(m_manager);
if (m_functor)
m_manager->addDirtyBuffer(peerId());
}
+void Buffer::forceDataUpload()
+{
+ // We push back an update with offset = -1
+ // As this is the way to force data to be loaded
+ QBufferUpdate updateNewData;
+ updateNewData.offset = -1;
+ m_bufferUpdates.clear(); //previous updates are pointless
+ m_bufferUpdates.push_back(updateNewData);
+}
+
void Buffer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
{
if (e->type() == PropertyUpdated) {
QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e);
QByteArray propertyName = propertyChange->propertyName();
if (propertyName == QByteArrayLiteral("data")) {
- QByteArray newData = propertyChange->value().value<QByteArray>();
- m_bufferDirty |= m_data != newData;
+ QByteArray newData = propertyChange->value().toByteArray();
+ bool dirty = m_data != newData;
+ m_bufferDirty |= dirty;
m_data = newData;
+ if (dirty)
+ forceDataUpload();
} else if (propertyName == QByteArrayLiteral("updateData")) {
Qt3DRender::QBufferUpdate updateData = propertyChange->value().value<Qt3DRender::QBufferUpdate>();
m_bufferUpdates.push_back(updateData);
diff --git a/src/render/geometry/buffer_p.h b/src/render/geometry/buffer_p.h
index 9d9606eb0..691d6cc60 100644
--- a/src/render/geometry/buffer_p.h
+++ b/src/render/geometry/buffer_p.h
@@ -90,6 +90,7 @@ public:
private:
void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL;
+ void forceDataUpload();
QBuffer::BufferType m_type;
QBuffer::UsageType m_usage;
diff --git a/src/render/geometry/geometryrenderer.cpp b/src/render/geometry/geometryrenderer.cpp
index 54fe61831..4f5432e1d 100644
--- a/src/render/geometry/geometryrenderer.cpp
+++ b/src/render/geometry/geometryrenderer.cpp
@@ -153,7 +153,7 @@ void GeometryRenderer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
m_verticesPerPatch = propertyChange->value().value<int>();
m_dirty = true;
} else if (propertyName == QByteArrayLiteral("primitiveRestartEnabled")) {
- m_primitiveRestartEnabled = propertyChange->value().value<bool>();
+ m_primitiveRestartEnabled = propertyChange->value().toBool();
m_dirty = true;
} else if (propertyName == QByteArrayLiteral("primitiveType")) {
m_primitiveType = static_cast<QGeometryRenderer::PrimitiveType>(propertyChange->value().value<int>());
diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp
index 6fa081552..80e8267da 100644
--- a/src/render/graphicshelpers/graphicscontext.cpp
+++ b/src/render/graphicshelpers/graphicscontext.cpp
@@ -1320,16 +1320,16 @@ void GraphicsContext::applyUniform(const ShaderUniform &description, const Unifo
break;
case UniformType::UInt:
- applyUniformHelper<UniformType::Int>(description.m_location, description.m_size, v);
+ applyUniformHelper<UniformType::UInt>(description.m_location, description.m_size, v);
break;
case UniformType::UIVec2:
- applyUniformHelper<UniformType::IVec2>(description.m_location, description.m_size, v);
+ applyUniformHelper<UniformType::UIVec2>(description.m_location, description.m_size, v);
break;
case UniformType::UIVec3:
- applyUniformHelper<UniformType::IVec3>(description.m_location, description.m_size, v);
+ applyUniformHelper<UniformType::UIVec3>(description.m_location, description.m_size, v);
break;
case UniformType::UIVec4:
- applyUniformHelper<UniformType::IVec4>(description.m_location, description.m_size, v);
+ applyUniformHelper<UniformType::UIVec4>(description.m_location, description.m_size, v);
break;
case UniformType::Bool:
@@ -1501,8 +1501,6 @@ HGLBuffer GraphicsContext::createGLBufferFor(Buffer *buffer)
if (!bindGLBuffer(b, bufferTypeToGLBufferType(buffer->type())))
qCWarning(Render::Io) << Q_FUNC_INFO << "buffer binding failed";
- // TO DO: Handle usage pattern
- b->allocate(this, buffer->data().constData(), buffer->data().size(), false);
return m_renderer->nodeManagers()->glBufferManager()->lookupHandle(buffer->peerId());
}
@@ -1528,21 +1526,39 @@ void GraphicsContext::uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool rel
// * setData was called changing the whole data or functor (or the usage pattern)
// * partial buffer updates where received
- // Note: we assume the case where both setData/functor and updates are called to be a misuse
- // with unexpected behavior
- const QVector<Qt3DRender::QBufferUpdate> updates = std::move(buffer->pendingBufferUpdates());
- if (!updates.empty()) {
- for (const Qt3DRender::QBufferUpdate &update : updates) {
+ // TO DO: Handle usage pattern
+ QVector<Qt3DRender::QBufferUpdate> updates = std::move(buffer->pendingBufferUpdates());
+ for (auto it = updates.begin(); it != updates.end(); ++it) {
+ auto update = it;
+ // We have a partial update
+ if (update->offset >= 0) {
+ //accumulate sequential updates as single one
+ int bufferSize = update->data.size();
+ auto it2 = it + 1;
+ while ((it2 != updates.end())
+ && (it2->offset - update->offset == bufferSize)) {
+ bufferSize += it2->data.size();
+ ++it2;
+ }
+ update->data.resize(bufferSize);
+ while (it + 1 != it2) {
+ ++it;
+ update->data.replace(it->offset - update->offset, it->data.size(), it->data);
+ it->data.clear();
+ }
// TO DO: based on the number of updates .., it might make sense to
// sometime use glMapBuffer rather than glBufferSubData
- b->update(this, update.data.constData(), update.data.size(), update.offset);
+ b->update(this, update->data.constData(), update->data.size(), update->offset);
+ } else {
+ // We have an update that was done by calling QBuffer::setData
+ // which is used to resize or entirely clear the buffer
+ // Note: we use the buffer data directly in that case
+ const int bufferSize = buffer->data().size();
+ b->allocate(this, bufferSize, false); // orphan the buffer
+ b->allocate(this, buffer->data().constData(), bufferSize, false);
}
- } else {
- const int bufferSize = buffer->data().size();
- // TO DO: Handle usage pattern
- b->allocate(this, bufferSize, false); // orphan the buffer
- b->allocate(this, buffer->data().constData(), bufferSize, false);
}
+
if (releaseBuffer) {
b->release(this);
if (bufferTypeToGLBufferType(buffer->type()) == GLBuffer::ArrayBuffer)
diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp
index 7bd45587c..f9c7a390c 100644
--- a/src/render/jobs/pickboundingvolumejob.cpp
+++ b/src/render/jobs/pickboundingvolumejob.cpp
@@ -371,14 +371,14 @@ void PickBoundingVolumeJob::dispatchPickEvents(const QMouseEvent &event,
}
break;
}
-
+#if QT_CONFIG(gestures)
case Qt::TapGesture: {
objectPicker->onClicked(pickEvent);
break;
}
-
+#endif
case QEvent::MouseMove: {
- if (objectPicker->isPressed() && objectPicker->isDragEnabled()) {
+ if ((objectPicker->isPressed() || objectPicker->isHoverEnabled()) && objectPicker->isDragEnabled()) {
objectPicker->onMoved(pickEvent);
}
// fallthrough
diff --git a/src/render/materialsystem/qeffect.cpp b/src/render/materialsystem/qeffect.cpp
index 7778b5621..b611657c4 100644
--- a/src/render/materialsystem/qeffect.cpp
+++ b/src/render/materialsystem/qeffect.cpp
@@ -67,6 +67,35 @@ QEffectPrivate::QEffectPrivate()
The QEffect class combines a set of techniques and parameters used by those techniques to
produce a rendering effect for a material.
+ An QEffect instance should be shared among several QMaterial instances when possible.
+
+ \code
+ QEffect *effect = new QEffect();
+
+ // Create technique, render pass and shader
+ QTechnique *gl3Technique = new QTechnique();
+ QRenderPass *gl3Pass = new QRenderPass();
+ QShaderProgram *glShader = new QShaderProgram();
+
+ // Set the shader on the render pass
+ gl3Pass->setShaderProgram(glShader);
+
+ // Add the pass to the technique
+ gl3Technique->addRenderPass(gl3Pass);
+
+ // Set the targeted GL version for the technique
+ gl3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ gl3Technique->graphicsApiFilter()->setMajorVersion(3);
+ gl3Technique->graphicsApiFilter()->setMinorVersion(1);
+ gl3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
+
+ // Add the technique to the effect
+ effect->addTechnique(gl3Technique);
+ \endcode
+
+ A QParameter defined on an Effect is overridden by a QParameter (of the same
+ name) defined in a QMaterial, QTechniqueFilter, QRenderPassFilter.
+
\sa QMaterial, QTechnique, QParameter
*/
@@ -81,6 +110,37 @@ QEffectPrivate::QEffectPrivate()
The Effect type combines a set of techniques and parameters used by those techniques to
produce a rendering effect for a material.
+ An Effect instance should be shared among several Material instances when possible.
+
+ A Parameter defined on an Effect is overridden by a QParameter (of the same
+ name) defined in a Material, TechniqueFilter, RenderPassFilter.
+
+ \code
+ Effect {
+ id: effect
+
+ technique: [
+ Technique {
+ id: gl3Technique
+ graphicsApiFilter {
+ api: GraphicsApiFilter.OpenGL
+ profile: GraphicsApiFilter.CoreProfile
+ majorVersion: 3
+ minorVersion: 1
+ }
+ renderPasses: [
+ RenderPass {
+ id: gl3Pass
+ shaderProgram: ShaderProgram {
+ ...
+ }
+ }
+ ]
+ }
+ ]
+ }
+ \endcode
+
\sa Material, Technique, Parameter
*/
diff --git a/src/render/materialsystem/qmaterial.cpp b/src/render/materialsystem/qmaterial.cpp
index ca0f86463..c6913441e 100644
--- a/src/render/materialsystem/qmaterial.cpp
+++ b/src/render/materialsystem/qmaterial.cpp
@@ -60,7 +60,58 @@
sound should reflect off an element, the temperature of a surface,
and so on.
- \sa Effect
+ In itself, a Material doesn't do anything. It's only when it references an
+ Effect node that a Material becomes useful.
+
+ In practice, it often happens that a single Effect is being referenced by
+ several Material components. This allows to only create the effect,
+ techniques, passes and shaders once while allowing to specify the material
+ by adding Parameter instances.
+
+ A Parameter defined on a Material is overridden by a Parameter (of the same
+ name) defined in a TechniqueFilter or a RenderPassFilter.
+
+ \code
+ Effect {
+ id: effect
+
+ technique: [
+ Technique {
+ id: gl3Technique
+ graphicsApiFilter {
+ api: GraphicsApiFilter.OpenGL
+ profile: GraphicsApiFilter.CoreProfile
+ majorVersion: 3
+ minorVersion: 1
+ }
+ renderPasses: [
+ RenderPass {
+ id: gl3Pass
+ shaderProgram: ShaderProgram {
+ ...
+ }
+ }
+ ]
+ }
+ ]
+ }
+
+ Material {
+ id: material1
+ parameters: [
+ Parameter { name: "color"; value: "green" }
+ ]
+ }
+
+ Material {
+ id: material2
+ parameters: [
+ Parameter { name: "color"; value: "white" }
+ ]
+ }
+ \endcode
+
+ \sa Effect, Technique, Parameter
*/
/*!
@@ -77,7 +128,54 @@
sound should reflect off an element, the temperature of a surface,
and so on.
- \sa QEffect
+ In itself, a QMaterial doesn't do anything. It's only when it references a
+ QEffect node that a QMaterial becomes useful.
+
+ In practice, it often happens that a single QEffect is being referenced by
+ several QMaterial components. This allows to only create the effect,
+ techniques, passes and shaders once while allowing to specify the material
+ by adding QParameter instances.
+
+ A QParameter defined on a QMaterial is overridden by a QParameter (of the same
+ name) defined in a QTechniqueFilter or a QRenderPassFilter.
+
+ \code
+ QMaterial *material1 = new QMaterial();
+ QMaterial *material2 = new QMaterial();
+
+ // Create effect, technique, render pass and shader
+ QEffect *effect = new QEffect();
+ QTechnique *gl3Technique = new QTechnique();
+ QRenderPass *gl3Pass = new QRenderPass();
+ QShaderProgram *glShader = new QShaderProgram();
+
+ // Set the shader on the render pass
+ gl3Pass->setShaderProgram(glShader);
+
+ // Add the pass to the technique
+ gl3Technique->addRenderPass(gl3Pass);
+
+ // Set the targeted GL version for the technique
+ gl3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ gl3Technique->graphicsApiFilter()->setMajorVersion(3);
+ gl3Technique->graphicsApiFilter()->setMinorVersion(1);
+ gl3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
+
+ // Add the technique to the effect
+ effect->addTechnique(gl3Technique);
+
+ // Set the effect on the materials
+ material1->setEffect(effect);
+ material2->setEffect(effect);
+
+ // Set different parameters on the materials
+ const QString parameterName = QStringLiteral("color");
+ material1->addParameter(new QParameter(parameterName, QColor::fromRgbF(0.0f, 1.0f, 0.0f, 1.0f);
+ material2->addParameter(new QParameter(parameterName, QColor::fromRgbF(1.0f, 1.0f, 1.0f, 1.0f);
+
+ \endcode
+
+ \sa QEffect, QTechnique, QParameter
*/
QT_BEGIN_NAMESPACE
diff --git a/src/render/materialsystem/qparameter.cpp b/src/render/materialsystem/qparameter.cpp
index 8f83fd02e..2ca7d176b 100644
--- a/src/render/materialsystem/qparameter.cpp
+++ b/src/render/materialsystem/qparameter.cpp
@@ -45,18 +45,127 @@
/*!
- * \qmltype Parameter
- * \instantiates Qt3DRender::QParameter
- * \inqmlmodule Qt3D.Render
- * \brief Provides storage for a name and value pair.
+ \qmltype Parameter
+ \instantiates Qt3DRender::QParameter
+ \inqmlmodule Qt3D.Render
+ \brief Provides storage for a name and value pair. This maps to a shader uniform.
+
+ A Parameter can be referenced by a RenderPass, Technique, Effect, Material,
+ TechniqueFilter, RenderPassFilter. At runtime, depending on which shader is
+ selected for a given step of the rendering, the value contained in a
+ Parameter will be converted and uploaded if the shader contains a uniform
+ with a name matching that of the Parameter.
+
+ \code
+ Parameter {
+ name: "diffuseColor"
+ value: "blue"
+ }
+
+ // Works with the following GLSL uniform shader declarations
+ // uniform vec4 diffuseColor;
+ // uniform vec3 diffuseColor;
+ // uniform vec2 diffuseColor;
+ // uniform float diffuseColor;
+ \endcode
+
+ \note some care must be taken to ensure the value wrapped by a Parameter
+ can actually be converted to what the real uniform expect. Giving a value
+ stored as an int where the actual shader uniform is of type float could
+ result in undefined behaviors.
+
+ \note when the targeted uniform is an array, the name should be the name
+ of the uniform with [0] appended to it.
+
+ \code
+ Parameter {
+ name: "diffuseValues[0]"
+ value: [0.0, 1.0. 2.0, 3.0, 4.0, 883.0, 1340.0, 1584.0]
+ }
+
+ // Matching GLSL shader uniform declaration
+ // uniform float diffuseValues[8];
+ \endcode
+
+ When it comes to texture support, the Parameter value should be set to the
+ appropriate Texture subclass that matches the sampler type of the shader
+ uniform.
+
+ \code
+ Parameter {
+ name: "diffuseTexture"
+ value: Texture2D { ... }
+ }
+
+ // Works with the following GLSL uniform shader declaration
+ // uniform sampler2D diffuseTexture
+ \endcode
+
+ \sa Texture
*/
/*!
- * \class Qt3DRender::QParameter
- * \inheaderfile Qt3DRender/QParameter
- * \inmodule Qt3DRender
- *
- * \brief Provides storage for a name and value pair.
+ \class Qt3DRender::QParameter
+ \inheaderfile Qt3DRender/QParameter
+ \inmodule Qt3DRender
+ \brief Provides storage for a name and value pair. This maps to a shader uniform.
+
+ A QParameter can be referenced by a QRenderPass, QTechnique, QEffect, QMaterial,
+ QTechniqueFilter, QRenderPassFilter. At runtime, depending on which shader is
+ selected for a given step of the rendering, the value contained in a
+ QParameter will be converted and uploaded if the shader contains a uniform
+ with a name matching that of the QParameter.
+
+ \code
+ QParameter *param = new QParameter();
+ param->setName(QStringLiteral("diffuseColor"));
+ param->setValue(QColor::fromRgbF(0.0f, 0.0f, 1.0f, 1.0f));
+
+ // Alternatively you can create and set a QParameter this way
+ QParameter *param2 = new QParameter(QStringLiteral("diffuseColor"), QColor::fromRgbF(0.0f, 0.0f, 1.0f, 1.0f));
+
+ // Such QParameters will work with the following GLSL uniform shader declarations
+ // uniform vec4 diffuseColor;
+ // uniform vec3 diffuseColor;
+ // uniform vec2 diffuseColor;
+ // uniform float diffuseColor;
+ \endcode
+
+ \note some care must be taken to ensure the value wrapped by a QParameter
+ can actually be converted to what the real uniform expect. Giving a value
+ stored as an int where the actual shader uniform is of type float could
+ result in undefined behaviors.
+
+ \note when the targeted uniform is an array, the name should be the name
+ of the uniform with [0] appended to it.
+
+ \code
+ QParameter *param = new QParameter();
+ QVariantList values = QVariantList() << 0.0f << 1.0f << 2.0f << 3.0f << 4.0f << 883.0f << 1340.0f << 1584.0f;
+
+ param->setName(QStringLiteral("diffuseValues[0]"));
+ param->setValue(values);
+
+ // Matching GLSL shader uniform declaration
+ // uniform float diffuseValues[8];
+ \endcode
+
+ When it comes to texture support, the QParameter value should be set to the
+ appropriate QAbstractTexture subclass that matches the sampler type of the shader
+ uniform.
+
+ \code
+ QTexture2D *texture = new QTexture2D();
+ ...
+ QParameter *param = new QParameter();
+ param->setName(QStringLiteral("diffuseTexture"));
+ param->setValue(QVariant::fromValue(texture));
+
+ // Works with the following GLSL uniform shader declaration
+ // uniform sampler2D diffuseTexture
+ \endcode
+
+ \sa QAbstractTexture
*/
QT_BEGIN_NAMESPACE
diff --git a/src/render/materialsystem/qrenderpass.cpp b/src/render/materialsystem/qrenderpass.cpp
index 6f5949781..61f844be3 100644
--- a/src/render/materialsystem/qrenderpass.cpp
+++ b/src/render/materialsystem/qrenderpass.cpp
@@ -72,9 +72,40 @@ QRenderPassPrivate::QRenderPassPrivate()
a list of FilterKey objects, a list of RenderState objects and a list
of \l Parameter objects.
- RenderPass executes the ShaderProgram using the given render states and parameters
- when its filter keys match the filter keys in RenderPassFilter or when no filter
- keys are specified and no RenderPassFilter is present in the FrameGraph.
+ RenderPass executes the ShaderProgram using the given RenderState and
+ Parameter nodes when at least one of FilterKey nodes being referenced
+ matches any of the FilterKey nodes in RenderPassFilter or when no FilterKey
+ nodes are specified and no RenderPassFilter is present in the FrameGraph.
+
+ If the RenderPass defines a Parameter, it will be overridden by a Parameter
+ with the same name if it exists in any of the Technique, Effect, Material,
+ TechniqueFilter, RenderPassFilter associated with the pass at runtime. This
+ still can be useful to define sane default values.
+
+ At render time, for each leaf node of the FrameGraph a base render state is
+ recorded by accumulating states defined by all RenderStateSet nodes in the
+ FrameGraph branch. Each RenderPass can overload this base render state by
+ specifying its own RenderState nodes.
+
+ \code
+ RenderPass {
+ id: pass
+ shaderProgram: ShaderProgram {
+ ...
+ }
+ parameters: [
+ Parameters { name: "color"; value: "red" }
+ ]
+ filterKeys: [
+ FilterKey { name: "name"; value: "zFillPass" }
+ ]
+ renderStates: [
+ DepthTest { }
+ ]
+ }
+ \endcode
+
+ \sa RenderPassFilter, FilterKey, Parameter, RenderState, Effect, Technique
*/
/*!
@@ -88,10 +119,54 @@ QRenderPassPrivate::QRenderPassPrivate()
of a Qt3DRender::QShaderProgram and a list of Qt3DRender::QFilterKey objects,
a list of Qt3DRender::QRenderState objects and a list of Qt3DRender::QParameter objects.
- QRenderPass executes the QShaderProgram using the given render states and parameters
- when its filter keys match the filter keys in Qt3DRender::QRenderPassFilter or
- when no filter keys are specified and no QRenderPassFilter is present
- in the FrameGraph.
+ QRenderPass executes the QShaderProgram using the given QRenderState and
+ QParameter nodes when at least one of QFilterKey nodes being referenced
+ matches any of the QFilterKey nodes in QRenderPassFilter or when no
+ QFilterKey nodes are specified and no QRenderPassFilter is present in the
+ FrameGraph.
+
+ If the QRenderPass defines a QParameter, it will be overridden by a
+ QParameter with the same name if it exists in any of the QTechnique,
+ QEffect, QMaterial, QTechniqueFilter, QRenderPassFilter associated with the
+ pass at runtime. This still can be useful to define sane default values.
+
+ At render time, for each leaf node of the FrameGraph a base render state is
+ recorded by accumulating states defined by all QRenderStateSet nodes in the
+ FrameGraph branch. Each QRenderPass can overload this base render state by
+ specifying its own QRenderState nodes.
+
+ \code
+ // Create the render passes
+ QRenderPass *pass = new QRenderPass();
+
+ // Create shader program
+ QShaderProgram *glShader = new QShaderProgram();
+
+ // Set the shader on the render pass
+ pass->setShaderProgram(glShader);
+
+ // Create a FilterKey
+ QFilterKey *filterKey = new QFilterKey();
+ filterKey->setName(QStringLiteral("name"));
+ fitlerKey->setValue(QStringLiteral("zFillPass"));
+
+ // Add the FilterKey to the pass
+ pass->addFilterKey(filterKey);
+
+ // Create a QParameter
+ QParameter *colorParameter = new QParameter(QStringLiteral("color"), QColor::fromRgbF(0.0f, 0.0f, 1.0f, 1.0f));
+
+ // Add parameter to pass
+ pass->addParameter(colorParameter);
+
+ // Create a QRenderState
+ QDepthTest *depthTest = new QDepthTest();
+
+ // Add the render state to the pass
+ pass->addRenderState(depthTest);
+ \endcode
+
+ \sa QRenderPassFilter, QFilterKey, QParameter, QRenderState, QEffect, QTechnique
*/
/*!
\typedef ParameterList
diff --git a/src/render/materialsystem/qtechnique.cpp b/src/render/materialsystem/qtechnique.cpp
index 74505bfbd..df142cdee 100644
--- a/src/render/materialsystem/qtechnique.cpp
+++ b/src/render/materialsystem/qtechnique.cpp
@@ -68,14 +68,61 @@ QTechniquePrivate::~QTechniquePrivate()
\since 5.7
\brief Encapsulates a Technique.
- A Technique specifies a set of RenderPass objects, FilterKey objects, Parameter objects
- and a GraphicsApiFilter, which together define a rendering technique the given
- graphics API can render. The filter keys are used by TechniqueFilter
- to select specific techinques at specific parts of the FrameGraph.
- If the same parameter is specified both in Technique and RenderPass, the one
- in Technique overrides the one used in the RenderPass.
-
- \sa Qt3D.Render::Effect
+ A Technique specifies a set of RenderPass objects, FilterKey objects,
+ Parameter objects and a GraphicsApiFilter, which together define a
+ rendering technique the given graphics API can render. The filter keys are
+ used by TechniqueFilter to select specific techniques at specific parts of
+ the FrameGraph. If two Parameter instances with the same name are specified
+ in a Technique and a RenderPass, the one in Technique overrides the one
+ used in the RenderPass.
+
+ When creating an Effect that targets several versions of a graphics API, it
+ is useful to create several Technique nodes each with a graphicsApiFilter
+ set to match one of the targeted versions. At runtime, the Qt3D renderer
+ will select the most appropriate Technique based on which graphics API
+ versions are supported and (if specified) the FilterKey nodes that satisfy
+ a given TechniqueFilter in the FrameGraph.
+
+ \note When using OpenGL as the graphics API for rendering, Qt3D relies on
+ the QSurfaceFormat returned by QSurfaceFormat::defaultFormat() at runtime
+ to decide what is the most appropriate GL version available. If you need to
+ customize the QSurfaceFormat, do not forget to apply it with
+ QSurfaceFormat::setDefaultFormat(). Setting the QSurfaceFormat on the view
+ will likely have no effect on Qt3D related rendering.
+
+ \code
+ Technique {
+ id: gl3Technique
+ parameters: [
+ Parameter { name: "color"; value: "orange" }
+ ]
+ filterKeys: [
+ FilterKey { name: "name"; value: "zFillTechnique" }
+ ]
+ graphicsApiFilter {
+ api: GraphicsApiFilter.OpenGL
+ profile: GraphicsApiFilter.CoreProfile
+ majorVersion: 3
+ minorVersion: 1
+ }
+ renderPasses: [
+ RenderPass {
+ id: firstPass
+ shaderProgram: ShaderProgram {
+ ...
+ }
+ },
+ RenderPass {
+ id: secondPass
+ shaderProgram: ShaderProgram {
+ ...
+ }
+ }
+ ]
+ }
+ \endcode
+
+ \sa Effect, RenderPass, TechniqueFilter
*/
/*!
@@ -85,15 +132,62 @@ QTechniquePrivate::~QTechniquePrivate()
\since 5.7
\brief Encapsulates a Technique.
- A Qt3DRender::QTechnique specifies a set of Qt3DRender::QRenderPass objects,
- Qt3DRender::QFilterKey objects, Qt3DRender::QParameter objects and
- a Qt3DRender::QGraphicsApiFilter, which together define a rendering technique the given
- graphics API can render. The filter keys are used by Qt3DRender::QTechniqueFilter
- to select specific techinques at specific parts of the FrameGraph.
- If the same parameter is specified both in QTechnique and QRenderPass, the one
- in QTechnique overrides the one used in the QRenderPass.
-
- \sa Qt3DRender::QEffect
+ A Qt3DRender::QTechnique specifies a set of Qt3DRender::QRenderPass
+ objects, Qt3DRender::QFilterKey objects, Qt3DRender::QParameter objects and
+ a Qt3DRender::QGraphicsApiFilter, which together define a rendering
+ technique the given graphics API can render. The filter keys are used by
+ Qt3DRender::QTechniqueFilter to select specific techniques at specific
+ parts of the FrameGraph. If two QParameter instances with the same name are
+ specified in a QTechnique and a QRenderPass, the one in Technique overrides
+ the one used in the QRenderPass.
+
+ When creating an QEffect that targets several versions of a graphics API,
+ it is useful to create several QTechnique nodes each with a
+ graphicsApiFilter set to match one of the targeted GL versions. At runtime,
+ the Qt3D renderer will select the most appropriate QTechnique based on
+ which graphics API versions are supported and (if specified) the QFilterKey
+ nodes that satisfy a given QTechniqueFilter in the FrameGraph.
+
+ \note When using OpenGL as the graphics API for rendering, Qt3D relies on
+ the QSurfaceFormat returned by QSurfaceFormat::defaultFormat() at runtime
+ to decide what is the most appropriate GL version available. If you need to
+ customize the QSurfaceFormat, do not forget to apply it with
+ QSurfaceFormat::setDefaultFormat(). Setting the QSurfaceFormat on the view
+ will likely have no effect on Qt3D related rendering.
+
+ \code
+ QTechnique *gl3Technique = new QTechnique();
+
+ // Create the render passes
+ QRenderPass *firstPass = new QRenderPass();
+ QRenderPass *secondPass = new QRenderPass();
+
+ // Add the passes to the technique
+ gl3Technique->addRenderPass(firstPass);
+ gl3Technique->addRenderPass(secondPass);
+
+ // Set the targeted GL version for the technique
+ gl3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ gl3Technique->graphicsApiFilter()->setMajorVersion(3);
+ gl3Technique->graphicsApiFilter()->setMinorVersion(1);
+ gl3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
+
+ // Create a FilterKey
+ QFilterKey *filterKey = new QFilterKey();
+ filterKey->setName(QStringLiteral("name"));
+ fitlerKey->setValue(QStringLiteral("zFillPass"));
+
+ // Add the FilterKey to the Technique
+ gl3Technique->addFilterKey(filterKey);
+
+ // Create a QParameter
+ QParameter *colorParameter = new QParameter(QStringLiteral("color"), QColor::fromRgbF(0.0f, 0.0f, 1.0f, 1.0f));
+
+ // Add parameter to technique
+ gl3Technique->addParameter(colorParameter);
+ \endcode
+
+ \sa QEffect, QRenderPass, QTechniqueFilter
*/
/*!
diff --git a/src/render/materialsystem/shader.cpp b/src/render/materialsystem/shader.cpp
index 3ee00739d..915ca1d54 100644
--- a/src/render/materialsystem/shader.cpp
+++ b/src/render/materialsystem/shader.cpp
@@ -311,8 +311,8 @@ void Shader::updateDNA()
QMutexLocker locker(&m_mutex);
uint attachmentHash = 0;
- QHash<QString, int>::const_iterator it = m_fragOutputs.begin();
- QHash<QString, int>::const_iterator end = m_fragOutputs.end();
+ QHash<QString, int>::const_iterator it = m_fragOutputs.cbegin();
+ QHash<QString, int>::const_iterator end = m_fragOutputs.cend();
while (it != end) {
attachmentHash += ::qHash(it.value()) + ::qHash(it.key());
++it;
@@ -373,11 +373,11 @@ void Shader::initializeUniformBlocks(const QVector<ShaderUniformBlock> &uniformB
qCDebug(Shaders) << "Initializing Uniform Block {" << m_uniformBlockNames[i] << "}";
// Find all active uniforms for the shader block
- QVector<ShaderUniform>::const_iterator uniformsIt = m_uniforms.begin();
- const QVector<ShaderUniform>::const_iterator uniformsEnd = m_uniforms.end();
+ QVector<ShaderUniform>::const_iterator uniformsIt = m_uniforms.cbegin();
+ const QVector<ShaderUniform>::const_iterator uniformsEnd = m_uniforms.cend();
- QVector<QString>::const_iterator uniformNamesIt = m_uniformsNames.begin();
- const QVector<QString>::const_iterator uniformNamesEnd = m_attributesNames.end();
+ QVector<QString>::const_iterator uniformNamesIt = m_uniformsNames.cbegin();
+ const QVector<QString>::const_iterator uniformNamesEnd = m_attributesNames.cend();
QHash<QString, ShaderUniform> activeUniformsInBlock;
diff --git a/src/render/raycasting/qabstractcollisionqueryservice_p.h b/src/render/raycasting/qabstractcollisionqueryservice_p.h
index 806c33d5b..1c1261937 100644
--- a/src/render/raycasting/qabstractcollisionqueryservice_p.h
+++ b/src/render/raycasting/qabstractcollisionqueryservice_p.h
@@ -79,6 +79,7 @@ public:
class QT3DRENDERSHARED_EXPORT QAbstractCollisionQueryService : public Qt3DCore::QAbstractServiceProvider
{
+ Q_OBJECT
public:
enum QueryMode {
FirstHit,
diff --git a/src/render/texture/apitexturemanager_p.h b/src/render/texture/apitexturemanager_p.h
index c062f0971..91747b3bc 100644
--- a/src/render/texture/apitexturemanager_p.h
+++ b/src/render/texture/apitexturemanager_p.h
@@ -273,7 +273,7 @@ public:
if (impl->isUnique())
return false;
- auto it = m_sharedTextures.find(impl);
+ auto it = m_sharedTextures.constFind(impl);
if (it == m_sharedTextures.cend())
return false;
diff --git a/src/render/texture/gltexture.cpp b/src/render/texture/gltexture.cpp
index bc2a1d464..854789e94 100644
--- a/src/render/texture/gltexture.cpp
+++ b/src/render/texture/gltexture.cpp
@@ -188,13 +188,11 @@ QOpenGLTexture* GLTexture::getOrCreateGLTexture()
if (!m_gl) {
m_gl = buildGLTexture();
- if (m_gl) {
- m_gl->allocateStorage();
- if (!m_gl->isStorageAllocated()) {
- qWarning() << Q_FUNC_INFO << "texture storage allocation failed";
- return nullptr;
- }
- } else {
+ if (!m_gl)
+ return nullptr;
+ m_gl->allocateStorage();
+ if (!m_gl->isStorageAllocated()) {
+ qWarning() << Q_FUNC_INFO << "texture storage allocation failed";
return nullptr;
}
}
diff --git a/src/render/texture/texture.cpp b/src/render/texture/texture.cpp
index a1f0d0f98..21f29d0b6 100644
--- a/src/render/texture/texture.cpp
+++ b/src/render/texture/texture.cpp
@@ -254,6 +254,16 @@ void Texture::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
BackendNode::sceneChangeEvent(e);
}
+bool Texture::isValid() const
+{
+ for (const auto handle : m_textureImages) {
+ TextureImage *img = m_textureImageManager->data(handle);
+ if (img == nullptr)
+ return false;
+ }
+ return true;
+}
+
void Texture::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
{
const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QAbstractTextureData>>(change);
diff --git a/src/render/texture/texture_p.h b/src/render/texture/texture_p.h
index 18f650686..1f3ba729c 100644
--- a/src/render/texture/texture_p.h
+++ b/src/render/texture/texture_p.h
@@ -157,6 +157,7 @@ public:
inline const QVector<HTextureImage>& textureImages() const { return m_textureImages; }
inline const QTextureGeneratorPtr& dataGenerator() const { return m_dataFunctor; }
+ bool isValid() const;
private:
void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL;
diff --git a/src/src.pro b/src/src.pro
index 86a885e51..46c205849 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -23,63 +23,65 @@ src_extras.subdir = $$PWD/extras
src_extras.target = src_extras
src_extras.depends = src_render src_input src_logic
-# Quick3D libs
-src_quick3d_core.subdir = $$PWD/quick3d/quick3d
-src_quick3d_core.target = sub-quick3d-core
-src_quick3d_core.depends = src_core src_input
-
-src_quick3d_render.subdir = $$PWD/quick3d/quick3drender
-src_quick3d_render.target = sub-quick3d-render
-src_quick3d_render.depends = src_render src_quick3d_core
-
-src_quick3d_input.subdir = $$PWD/quick3d/quick3dinput
-src_quick3d_input.target = sub-quick3d-input
-src_quick3d_input.depends = src_input src_quick3d_core
-
-src_quick3d_animation.subdir = $$PWD/quick3d/quick3danimation
-src_quick3d_animation.target = sub-quick3d-animation
-src_quick3d_animation.depends = src_animation src_quick3d_core src_quick3d_render
-
-src_quick3d_extras.subdir = $$PWD/quick3d/quick3dextras
-src_quick3d_extras.target = sub-quick3d-extras
-src_quick3d_extras.depends = src_render src_logic src_input src_extras src_quick3d_core
-
-src_quick3d_scene2d.subdir = $$PWD/quick3d/quick3dscene2d
-src_quick3d_scene2d.target = sub-quick3d-scene2d
-src_quick3d_scene2d.depends = src_render src_logic src_input src_quick3d_core
-
-# Quick3D imports
-src_quick3d_core_imports.file = $$PWD/quick3d/imports/core/importscore.pro
-src_quick3d_core_imports.target = sub-quick3d-imports-core
-src_quick3d_core_imports.depends = src_quick3d_core
-
-src_quick3d_imports_render.file = $$PWD/quick3d/imports/render/importsrender.pro
-src_quick3d_imports_render.target = sub-quick3d-imports-render
-src_quick3d_imports_render.depends = src_quick3d_render
-
-src_quick3d_imports_scene3d.file = $$PWD/quick3d/imports/scene3d/importsscene3d.pro
-src_quick3d_imports_scene3d.target = sub-quick3d-imports-scene3d
-src_quick3d_imports_scene3d.depends = src_quick3d_render src_input
-
-src_quick3d_imports_input.file = $$PWD/quick3d/imports/input/importsinput.pro
-src_quick3d_imports_input.target = sub-quick3d-imports-input
-src_quick3d_imports_input.depends = src_input src_quick3d_input
-
-src_quick3d_imports_logic.file = $$PWD/quick3d/imports/logic/importslogic.pro
-src_quick3d_imports_logic.target = sub-quick3d-imports-logic
-src_quick3d_imports_logic.depends = src_logic
-
-src_quick3d_imports_animation.file = $$PWD/quick3d/imports/animation/importsanimation.pro
-src_quick3d_imports_animation.target = sub-quick3d-imports-animation
-src_quick3d_imports_animation.depends = src_animation src_quick3d_animation
-
-src_quick3d_imports_extras.file = $$PWD/quick3d/imports/extras/importsextras.pro
-src_quick3d_imports_extras.target = sub-quick3d-imports-extras
-src_quick3d_imports_extras.depends = src_extras src_quick3d_extras
-
-src_quick3d_imports_scene2d.file = $$PWD/quick3d/imports/scene2d/importsscene2d.pro
-src_quick3d_imports_scene2d.target = sub-quick3d-imports-scene2d
-src_quick3d_imports_scene2d.depends = src_quick3d_scene2d
+qtHaveModule(quick) {
+ # Quick3D libs
+ src_quick3d_core.subdir = $$PWD/quick3d/quick3d
+ src_quick3d_core.target = sub-quick3d-core
+ src_quick3d_core.depends = src_core src_input
+
+ src_quick3d_render.subdir = $$PWD/quick3d/quick3drender
+ src_quick3d_render.target = sub-quick3d-render
+ src_quick3d_render.depends = src_render src_quick3d_core
+
+ src_quick3d_input.subdir = $$PWD/quick3d/quick3dinput
+ src_quick3d_input.target = sub-quick3d-input
+ src_quick3d_input.depends = src_input src_quick3d_core
+
+ src_quick3d_animation.subdir = $$PWD/quick3d/quick3danimation
+ src_quick3d_animation.target = sub-quick3d-animation
+ src_quick3d_animation.depends = src_animation src_quick3d_core src_quick3d_render
+
+ src_quick3d_extras.subdir = $$PWD/quick3d/quick3dextras
+ src_quick3d_extras.target = sub-quick3d-extras
+ src_quick3d_extras.depends = src_render src_logic src_input src_extras src_quick3d_core
+
+ src_quick3d_scene2d.subdir = $$PWD/quick3d/quick3dscene2d
+ src_quick3d_scene2d.target = sub-quick3d-scene2d
+ src_quick3d_scene2d.depends = src_render src_logic src_input src_quick3d_core
+
+ # Quick3D imports
+ src_quick3d_core_imports.file = $$PWD/quick3d/imports/core/importscore.pro
+ src_quick3d_core_imports.target = sub-quick3d-imports-core
+ src_quick3d_core_imports.depends = src_quick3d_core
+
+ src_quick3d_imports_render.file = $$PWD/quick3d/imports/render/importsrender.pro
+ src_quick3d_imports_render.target = sub-quick3d-imports-render
+ src_quick3d_imports_render.depends = src_quick3d_render
+
+ src_quick3d_imports_scene3d.file = $$PWD/quick3d/imports/scene3d/importsscene3d.pro
+ src_quick3d_imports_scene3d.target = sub-quick3d-imports-scene3d
+ src_quick3d_imports_scene3d.depends = src_quick3d_render src_input
+
+ src_quick3d_imports_input.file = $$PWD/quick3d/imports/input/importsinput.pro
+ src_quick3d_imports_input.target = sub-quick3d-imports-input
+ src_quick3d_imports_input.depends = src_input src_quick3d_input
+
+ src_quick3d_imports_logic.file = $$PWD/quick3d/imports/logic/importslogic.pro
+ src_quick3d_imports_logic.target = sub-quick3d-imports-logic
+ src_quick3d_imports_logic.depends = src_logic
+
+ src_quick3d_imports_animation.file = $$PWD/quick3d/imports/animation/importsanimation.pro
+ src_quick3d_imports_animation.target = sub-quick3d-imports-animation
+ src_quick3d_imports_animation.depends = src_animation src_quick3d_animation
+
+ src_quick3d_imports_extras.file = $$PWD/quick3d/imports/extras/importsextras.pro
+ src_quick3d_imports_extras.target = sub-quick3d-imports-extras
+ src_quick3d_imports_extras.depends = src_extras src_quick3d_extras
+
+ src_quick3d_imports_scene2d.file = $$PWD/quick3d/imports/scene2d/importsscene2d.pro
+ src_quick3d_imports_scene2d.target = sub-quick3d-imports-scene2d
+ src_quick3d_imports_scene2d.depends = src_quick3d_scene2d
+}
# Qt3D Scene Parser plugins
src_plugins_sceneparsers.file = $$PWD/plugins/sceneparsers/sceneparsers.pro
@@ -91,10 +93,12 @@ src_plugins_geometryloaders.file = $$PWD/plugins/geometryloaders/geometryloaders
src_plugins_geometryloaders.target = sub-plugins-geometryloaders
src_plugins_geometryloaders.depends = src_render src_extras
-# Qt3D Render plugins
-src_plugins_render.file = $$PWD/plugins/renderplugins/renderplugins.pro
-src_plugins_render.target = sub-plugins-render
-src_plugins_render.depends = src_render src_extras src_quick3d_render src_quick3d_scene2d
+qtHaveModule(quick) {
+ # Qt3D Render plugins
+ src_plugins_render.file = $$PWD/plugins/renderplugins/renderplugins.pro
+ src_plugins_render.target = sub-plugins-render
+ src_plugins_render.depends = src_render src_extras src_quick3d_render src_quick3d_scene2d
+}
SUBDIRS += \
src_core \
@@ -103,21 +107,25 @@ SUBDIRS += \
src_input \
src_animation \
src_extras \
- src_quick3d_core \
- src_quick3d_core_imports \
- src_quick3d_render \
- src_quick3d_input \
- src_quick3d_animation \
- src_quick3d_extras \
- src_quick3d_imports_render \
- src_quick3d_imports_scene3d \
- src_quick3d_imports_input \
- src_quick3d_imports_logic \
- src_quick3d_imports_animation \
- src_quick3d_imports_extras \
src_plugins_sceneparsers \
src_plugins_geometryloaders \
- src_plugins_render \
- src_quick3d_scene2d \
- src_quick3d_imports_scene2d \
doc
+
+qtHaveModule(quick) {
+ SUBDIRS += \
+ src_quick3d_core \
+ src_quick3d_core_imports \
+ src_quick3d_render \
+ src_quick3d_input \
+ src_quick3d_animation \
+ src_quick3d_extras \
+ src_quick3d_imports_render \
+ src_quick3d_imports_scene3d \
+ src_quick3d_imports_input \
+ src_quick3d_imports_logic \
+ src_quick3d_imports_animation \
+ src_quick3d_imports_extras \
+ src_plugins_render \
+ src_quick3d_scene2d \
+ src_quick3d_imports_scene2d
+}