summaryrefslogtreecommitdiffstats
path: root/src/animation/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'src/animation/frontend')
-rw-r--r--src/animation/frontend/frontend.pri63
-rw-r--r--src/animation/frontend/qabstractanimation.cpp189
-rw-r--r--src/animation/frontend/qabstractanimation.h94
-rw-r--r--src/animation/frontend/qabstractanimation_p.h75
-rw-r--r--src/animation/frontend/qabstractanimationclip.cpp171
-rw-r--r--src/animation/frontend/qabstractanimationclip.h (renamed from src/animation/frontend/qlerpblend.h)35
-rw-r--r--src/animation/frontend/qabstractanimationclip_p.h76
-rw-r--r--src/animation/frontend/qabstractclipanimator.cpp241
-rw-r--r--src/animation/frontend/qabstractclipanimator.h96
-rw-r--r--src/animation/frontend/qabstractclipanimator_p.h (renamed from src/animation/frontend/qconductedclipanimator_p.h)24
-rw-r--r--src/animation/frontend/qabstractclipblendnode.cpp130
-rw-r--r--src/animation/frontend/qabstractclipblendnode.h8
-rw-r--r--src/animation/frontend/qabstractclipblendnode_p.h4
-rw-r--r--src/animation/frontend/qadditiveclipblend.cpp254
-rw-r--r--src/animation/frontend/qadditiveclipblend.h84
-rw-r--r--src/animation/frontend/qadditiveclipblend_p.h82
-rw-r--r--src/animation/frontend/qanimationaspect.cpp34
-rw-r--r--src/animation/frontend/qanimationclip.cpp78
-rw-r--r--src/animation/frontend/qanimationclip.h43
-rw-r--r--src/animation/frontend/qanimationclip_p.h43
-rw-r--r--src/animation/frontend/qanimationclipdata.cpp143
-rw-r--r--src/animation/frontend/qanimationclipdata.h101
-rw-r--r--src/animation/frontend/qanimationcliploader.cpp137
-rw-r--r--src/animation/frontend/qanimationcliploader.h92
-rw-r--r--src/animation/frontend/qanimationcliploader_p.h81
-rw-r--r--src/animation/frontend/qanimationcontroller.cpp390
-rw-r--r--src/animation/frontend/qanimationcontroller.h105
-rw-r--r--src/animation/frontend/qanimationcontroller_p.h86
-rw-r--r--src/animation/frontend/qanimationgroup.cpp212
-rw-r--r--src/animation/frontend/qanimationgroup.h89
-rw-r--r--src/animation/frontend/qanimationgroup_p.h77
-rw-r--r--src/animation/frontend/qblendedclipanimator.cpp279
-rw-r--r--src/animation/frontend/qblendedclipanimator.h19
-rw-r--r--src/animation/frontend/qblendedclipanimator_p.h13
-rw-r--r--src/animation/frontend/qchannel.cpp142
-rw-r--r--src/animation/frontend/qchannel.h98
-rw-r--r--src/animation/frontend/qchannelcomponent.cpp142
-rw-r--r--src/animation/frontend/qchannelcomponent.h98
-rw-r--r--src/animation/frontend/qchannelmapper.h2
-rw-r--r--src/animation/frontend/qchannelmapping.h2
-rw-r--r--src/animation/frontend/qclipanimator.cpp130
-rw-r--r--src/animation/frontend/qclipanimator.h26
-rw-r--r--src/animation/frontend/qclipanimator_p.h17
-rw-r--r--src/animation/frontend/qclipblendnodecreatedchange.cpp17
-rw-r--r--src/animation/frontend/qclipblendnodecreatedchange.h3
-rw-r--r--src/animation/frontend/qclipblendnodecreatedchange_p.h3
-rw-r--r--src/animation/frontend/qclipblendvalue.cpp112
-rw-r--r--src/animation/frontend/qclipblendvalue.h83
-rw-r--r--src/animation/frontend/qclipblendvalue_p.h (renamed from src/animation/frontend/qconductedclipanimator.h)46
-rw-r--r--src/animation/frontend/qkeyframe.cpp (renamed from src/animation/frontend/qconductedclipanimator.cpp)33
-rw-r--r--src/animation/frontend/qkeyframe.h160
-rw-r--r--src/animation/frontend/qkeyframeanimation.cpp415
-rw-r--r--src/animation/frontend/qkeyframeanimation.h112
-rw-r--r--src/animation/frontend/qkeyframeanimation_p.h88
-rw-r--r--src/animation/frontend/qlerpclipblend.cpp (renamed from src/animation/frontend/qlerpblend.cpp)128
-rw-r--r--src/animation/frontend/qlerpclipblend.h86
-rw-r--r--src/animation/frontend/qlerpclipblend_p.h (renamed from src/animation/frontend/qlerpblend_p.h)16
-rw-r--r--src/animation/frontend/qmorphinganimation.cpp453
-rw-r--r--src/animation/frontend/qmorphinganimation.h116
-rw-r--r--src/animation/frontend/qmorphinganimation_p.h95
-rw-r--r--src/animation/frontend/qmorphtarget.cpp188
-rw-r--r--src/animation/frontend/qmorphtarget.h83
-rw-r--r--src/animation/frontend/qmorphtarget_p.h76
-rw-r--r--src/animation/frontend/qvertexblendanimation.cpp339
-rw-r--r--src/animation/frontend/qvertexblendanimation.h96
-rw-r--r--src/animation/frontend/qvertexblendanimation_p.h86
66 files changed, 6634 insertions, 505 deletions
diff --git a/src/animation/frontend/frontend.pri b/src/animation/frontend/frontend.pri
index 9eeeede97..9ea438395 100644
--- a/src/animation/frontend/frontend.pri
+++ b/src/animation/frontend/frontend.pri
@@ -1,35 +1,76 @@
HEADERS += \
$$PWD/qanimationaspect.h \
$$PWD/qanimationaspect_p.h \
- $$PWD/qanimationclip.h \
- $$PWD/qanimationclip_p.h \
+ $$PWD/qabstractclipanimator.h \
+ $$PWD/qabstractclipanimator_p.h \
+ $$PWD/qabstractanimationclip.h \
+ $$PWD/qabstractanimationclip_p.h \
$$PWD/qabstractclipblendnode.h \
$$PWD/qabstractclipblendnode_p.h \
$$PWD/qclipanimator.h \
$$PWD/qclipanimator_p.h \
$$PWD/qblendedclipanimator.h \
$$PWD/qblendedclipanimator_p.h \
- $$PWD/qconductedclipanimator.h \
- $$PWD/qconductedclipanimator_p.h \
$$PWD/qchannelmapper.h \
$$PWD/qchannelmapper_p.h \
$$PWD/qchannelmapping.h \
$$PWD/qchannelmapping_p.h \
- $$PWD/qlerpblend.h \
- $$PWD/qlerpblend_p.h \
$$PWD/qclipblendnodecreatedchange.h \
- $$PWD/qclipblendnodecreatedchange_p.h
+ $$PWD/qclipblendnodecreatedchange_p.h \
+ $$PWD/qanimationcontroller.h \
+ $$PWD/qanimationcontroller_p.h \
+ $$PWD/qanimationgroup.h \
+ $$PWD/qanimationgroup_p.h \
+ $$PWD/qkeyframeanimation.h \
+ $$PWD/qkeyframeanimation_p.h \
+ $$PWD/qmorphinganimation.h \
+ $$PWD/qmorphinganimation_p.h \
+ $$PWD/qabstractanimation.h \
+ $$PWD/qabstractanimation_p.h \
+ $$PWD/qmorphtarget.h \
+ $$PWD/qmorphtarget_p.h \
+ $$PWD/qvertexblendanimation.h \
+ $$PWD/qvertexblendanimation_p.h \
+ $$PWD/qanimationcliploader.h \
+ $$PWD/qanimationclip_p.h \
+ $$PWD/qlerpclipblend.h \
+ $$PWD/qlerpclipblend_p.h \
+ $$PWD/qadditiveclipblend.h \
+ $$PWD/qadditiveclipblend_p.h \
+ $$PWD/qclipblendvalue.h \
+ $$PWD/qclipblendvalue_p.h \
+ $$PWD/qanimationclipdata.h \
+ $$PWD/qchannel.h \
+ $$PWD/qchannelcomponent.h \
+ $$PWD/qkeyframe.h \
+ $$PWD/qanimationclip.h \
+ $$PWD/qanimationclip_p.h
SOURCES += \
$$PWD/qanimationaspect.cpp \
- $$PWD/qanimationclip.cpp \
+ $$PWD/qabstractclipanimator.cpp \
+ $$PWD/qabstractanimationclip.cpp \
$$PWD/qabstractclipblendnode.cpp \
$$PWD/qclipanimator.cpp \
$$PWD/qblendedclipanimator.cpp \
- $$PWD/qconductedclipanimator.cpp \
$$PWD/qchannelmapper.cpp \
$$PWD/qchannelmapping.cpp \
- $$PWD/qlerpblend.cpp \
- $$PWD/qclipblendnodecreatedchange.cpp
+ $$PWD/qclipblendnodecreatedchange.cpp \
+ $$PWD/qanimationcontroller.cpp \
+ $$PWD/qanimationgroup.cpp \
+ $$PWD/qkeyframeanimation.cpp \
+ $$PWD/qmorphinganimation.cpp \
+ $$PWD/qabstractanimation.cpp \
+ $$PWD/qmorphtarget.cpp \
+ $$PWD/qvertexblendanimation.cpp \
+ $$PWD/qanimationcliploader.cpp \
+ $$PWD/qlerpclipblend.cpp \
+ $$PWD/qadditiveclipblend.cpp \
+ $$PWD/qclipblendvalue.cpp \
+ $$PWD/qanimationclipdata.cpp \
+ $$PWD/qchannel.cpp \
+ $$PWD/qchannelcomponent.cpp \
+ $$PWD/qkeyframe.cpp \
+ $$PWD/qanimationclip.cpp
INCLUDEPATH += $$PWD
diff --git a/src/animation/frontend/qabstractanimation.cpp b/src/animation/frontend/qabstractanimation.cpp
new file mode 100644
index 000000000..efac3f5ec
--- /dev/null
+++ b/src/animation/frontend/qabstractanimation.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** 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 "qabstractanimation.h"
+#include "Qt3DAnimation/private/qabstractanimation_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+/*!
+ \class Qt3DAnimation::QAbstractAnimation
+ \brief An abstract base class for Qt3D animations
+ \inmodule Qt3DAnimation
+ \since 5.9
+ \inherits QObject
+
+ Qt3DAnimation::QAbstractAnimation is an abstract base class for all animations.
+ Qt3DAnimation::QAbstractAnimation can not be directly instantiated, but rather
+ through its subclasses. QAbstractAnimation specifies common properties
+ for all Qt3D animations, such as animation name and type, current position and animation
+ duration, while leaving the actual animating for the subclasses.
+*/
+
+/*!
+ \qmltype AbstractAnimation
+ \brief An abstract base type for Qt3D animations
+ \inqmlmodule Qt3D.Animation
+ \since 5.9
+ \instantiates Qt3DAnimation::QAbstractAnimation
+
+ AbstractAnimation is an abstract base type for all animations.
+ AbstractAnimation can not be directly instantiated, but rather
+ through its subtypes. AbstractAnimation specifies common properties
+ for all Qt3D animations, such as animation type, current position and animation
+ duration, while leaving the actual animating for the subtypes.
+*/
+/*!
+ \enum QAbstractAnimation::AnimationType
+
+ This enumeration specifies the type of the animation
+ \value KeyframeAnimation Simple keyframe animation implementation for QTransform
+ \value MorphingAnimation Blend-shape morphing animation
+ \value VertexBlendAnimation Vertex-blend animation
+*/
+/*!
+ \property Qt3DAnimation::QAbstractAnimation::animationName
+ Holds the name of the animation.
+*/
+/*!
+ \property Qt3DAnimation::QAbstractAnimation::animationType
+ Holds the type of the animation.
+*/
+/*!
+ \property Qt3DAnimation::QAbstractAnimation::position
+ Holds the current position of the animation.
+*/
+/*!
+ \property Qt3DAnimation::QAbstractAnimation::duration
+ Holds the duration of the animation.
+*/
+
+/*!
+ \qmlproperty string AbstractAnimation::animationName
+ Holds the name of the animation.
+*/
+/*!
+ \qmlproperty enumeration AbstractAnimation::animationType
+ Holds the type of the animation.
+ \list
+ \li KeyframeAnimation
+ \li MorphingAnimation
+ \li VertexBlendAnimation
+ \endlist
+*/
+/*!
+ \qmlproperty real AbstractAnimation::position
+ Holds the current position of the animation.
+*/
+/*!
+ \qmlproperty real AbstractAnimation::duration
+ Holds the duration of the animation.
+*/
+
+QAbstractAnimationPrivate::QAbstractAnimationPrivate(QAbstractAnimation::AnimationType type)
+ : QObjectPrivate()
+ , m_animationType(type)
+ , m_position(0.0f)
+ , m_duration(0.0f)
+{
+
+}
+
+QAbstractAnimation::QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent)
+ : QObject(dd, parent)
+{
+
+}
+
+QString QAbstractAnimation::animationName() const
+{
+ Q_D(const QAbstractAnimation);
+ return d->m_animationName;
+}
+
+QAbstractAnimation::AnimationType QAbstractAnimation::animationType() const
+{
+ Q_D(const QAbstractAnimation);
+ return d->m_animationType;
+}
+
+float QAbstractAnimation::position() const
+{
+ Q_D(const QAbstractAnimation);
+ return d->m_position;
+}
+
+float QAbstractAnimation::duration() const
+{
+ Q_D(const QAbstractAnimation);
+ return d->m_duration;
+}
+
+void QAbstractAnimation::setAnimationName(const QString &name)
+{
+ Q_D(QAbstractAnimation);
+ if (name != d->m_animationName) {
+ d->m_animationName = name;
+ emit animationNameChanged(name);
+ }
+}
+
+void QAbstractAnimation::setPosition(float position)
+{
+ Q_D(QAbstractAnimation);
+ if (!qFuzzyCompare(position, d->m_position)) {
+ d->m_position = position;
+ emit positionChanged(position);
+ }
+}
+
+/*!
+ Sets the \a duration of the animation.
+*/
+void QAbstractAnimation::setDuration(float duration)
+{
+ Q_D(QAbstractAnimation);
+ if (!qFuzzyCompare(duration, d->m_duration)) {
+ d->m_duration = duration;
+ emit durationChanged(duration);
+ }
+}
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
diff --git a/src/animation/frontend/qabstractanimation.h b/src/animation/frontend/qabstractanimation.h
new file mode 100644
index 000000000..0c6fe865e
--- /dev/null
+++ b/src/animation/frontend/qabstractanimation.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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_QABSTRACTANIMATION_H
+#define QT3DANIMATION_QABSTRACTANIMATION_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qvector.h>
+
+#include <Qt3DAnimation/qt3danimation_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QAbstractAnimationPrivate;
+
+class QT3DANIMATIONSHARED_EXPORT QAbstractAnimation : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString animationName READ animationName WRITE setAnimationName NOTIFY animationNameChanged)
+ Q_PROPERTY(QAbstractAnimation::AnimationType animationType READ animationType CONSTANT)
+ Q_PROPERTY(float position READ position WRITE setPosition NOTIFY positionChanged)
+ Q_PROPERTY(float duration READ duration NOTIFY durationChanged)
+
+public:
+ enum AnimationType {
+ KeyframeAnimation = 1,
+ MorphingAnimation = 2,
+ VertexBlendAnimation = 3,
+ };
+ Q_ENUM(AnimationType)
+
+ QString animationName() const;
+ QAbstractAnimation::AnimationType animationType() const;
+ float position() const;
+ float duration() const;
+
+public Q_SLOTS:
+ void setAnimationName(const QString &name);
+ void setPosition(float position);
+
+protected:
+ explicit QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent = nullptr);
+
+ void setDuration(float duration);
+
+Q_SIGNALS:
+ void animationNameChanged(const QString &name);
+ void positionChanged(float position);
+ void durationChanged(float duration);
+
+private:
+ Q_DECLARE_PRIVATE(QAbstractAnimation)
+};
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QABSTRACTANIMATION_H
diff --git a/src/animation/frontend/qabstractanimation_p.h b/src/animation/frontend/qabstractanimation_p.h
new file mode 100644
index 000000000..e1c412b01
--- /dev/null
+++ b/src/animation/frontend/qabstractanimation_p.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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_QABSTRACTANIMATION_P_H
+#define QT3DANIMATION_QABSTRACTANIMATION_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 <private/qobject_p.h>
+#include <Qt3DAnimation/QAbstractAnimation>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class Q_AUTOTEST_EXPORT QAbstractAnimationPrivate : public QObjectPrivate
+{
+public:
+ QAbstractAnimationPrivate(QAbstractAnimation::AnimationType type);
+
+ QString m_animationName;
+ QAbstractAnimation::AnimationType m_animationType;
+ float m_position;
+ float m_duration;
+
+ Q_DECLARE_PUBLIC(QAbstractAnimation)
+};
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QANIMATIONCONTROLLER_P_H
diff --git a/src/animation/frontend/qabstractanimationclip.cpp b/src/animation/frontend/qabstractanimationclip.cpp
new file mode 100644
index 000000000..7e6df4d70
--- /dev/null
+++ b/src/animation/frontend/qabstractanimationclip.cpp
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 "qabstractanimationclip.h"
+#include "qabstractanimationclip_p.h"
+#include <Qt3DCore/qpropertyupdatedchange.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+QAbstractAnimationClipPrivate::QAbstractAnimationClipPrivate()
+ : Qt3DCore::QNodePrivate()
+ , m_duration(0.0f)
+{
+}
+
+void QAbstractAnimationClipPrivate::setDuration(float duration)
+{
+ if (qFuzzyCompare(duration, m_duration))
+ return;
+
+ Q_Q(QAbstractAnimationClip);
+ bool wasBlocked = q->blockNotifications(true);
+ m_duration = duration;
+ emit q->durationChanged(duration);
+ q->blockNotifications(wasBlocked);
+}
+
+/*!
+ \class Qt3DAnimation::QAbstractAnimationClip
+ \inherits Qt3DCore::QNode
+
+ \inmodule Qt3DAnimation
+ \since 5.9
+
+ \brief QAbstractAnimationClip is the base class for types providing key frame animation data.
+
+ To utilise the key frame animation framework in the Qt 3D Animation module
+ the animator component in use needs to be provided with the key frame animation data. The
+ animation data is provided by one of the concrete subclasses of QAbstractAnimationClip:
+
+ \list
+ \li Qt3DAnimation::QAnimationClip
+ \li Qt3DAnimation::QAnimationClipLoader
+ \endlist
+
+ QAnimationClip should be used when you want to create the animation data
+ programmatically within your application. The actual data is set with a
+ QAnimationClipData value type.
+
+ If you are loading baked animation data from a file, e.g. as created by an
+ artist, then use the QAnimationClipLoader class and set its \c source property.
+
+ Once the animation clip has been populated with data using the above
+ methods, the read-only duration property will be updated by the Qt 3D Animation
+ backend.
+
+ The typical usage of animation clips is:
+
+ \code
+ auto animator = new QClipAnimator();
+ auto clip = new QAnimationClipLoader();
+ clip->setSource(QUrl::fromLocalFile("bounce.json"));
+ animator->setClip(clip);
+ animator->setChannelMapper(...);
+ animator->setRunning(true);
+ \endcode
+
+ Animation clips are also used as the leaf node values in animation blend trees:
+
+ \code
+ // Create leaf nodes of blend tree
+ auto slideClipValue = new QClipBlendValue(
+ new QAnimationClipLoader(QUrl::fromLocalFile("slide.json")));
+ auto bounceClipValue = new QClipBlendValue(
+ new QAnimationClipLoader(QUrl::fromLocalFile("bounce.json")));
+
+ // Create blend tree inner node
+ auto additiveNode = new QAdditiveClipBlend();
+ additiveNode->setBaseClip(slideClipValue);
+ additiveNode->setAdditiveClip(bounceClipValue);
+ additiveNode->setAdditiveFactor(0.5f);
+
+ // Run the animator
+ auto animator = new QBlendedClipAnimator();
+ animator->setBlendTree(additiveNode);
+ animator->setChannelMapper(...);
+ animator->setRunning(true);
+ \endcode
+
+ \sa QAnimationClip, QAnimationClipLoader
+*/
+
+/*!
+ \internal
+*/
+QAbstractAnimationClip::QAbstractAnimationClip(QAbstractAnimationClipPrivate &dd,
+ Qt3DCore::QNode *parent)
+ : Qt3DCore::QNode(dd, parent)
+{
+}
+
+/*!
+ Destroys this animation clip.
+*/
+QAbstractAnimationClip::~QAbstractAnimationClip()
+{
+}
+
+/*!
+ \property QAbstractAnimationClip::duration
+
+ Holds the duration of the animation clip in seconds. Gets updated once the
+ animation data is provided to Qt 3D using one of the concrete subclasses.
+*/
+float QAbstractAnimationClip::duration() const
+{
+ Q_D(const QAbstractAnimationClip);
+ return d->m_duration;
+}
+
+/*!
+ \internal
+*/
+void QAbstractAnimationClip::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
+{
+ Q_D(QAbstractAnimationClip);
+ if (change->type() == Qt3DCore::PropertyUpdated) {
+ Qt3DCore::QPropertyUpdatedChangePtr e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change);
+ if (e->propertyName() == QByteArrayLiteral("duration"))
+ d->setDuration(e->value().toFloat());
+ }
+}
+
+} // namespace Qt3DAnimation
+
+QT_END_NAMESPACE
diff --git a/src/animation/frontend/qlerpblend.h b/src/animation/frontend/qabstractanimationclip.h
index 58fad7ff1..377725fa1 100644
--- a/src/animation/frontend/qlerpblend.h
+++ b/src/animation/frontend/qabstractanimationclip.h
@@ -34,45 +34,42 @@
**
****************************************************************************/
-#ifndef QT3DANIMATION_QLERPBLEND_H
-#define QT3DANIMATION_QLERPBLEND_H
+#ifndef QT3DANIMATION_QABSTRACTANIMATIONCLIP_H
+#define QT3DANIMATION_QABSTRACTANIMATIONCLIP_H
-#include <Qt3DAnimation/qabstractclipblendnode.h>
+#include <Qt3DAnimation/qt3danimation_global.h>
+#include <Qt3DCore/qnode.h>
+#include <QtCore/qurl.h>
QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
-class QLerpBlendPrivate;
+class QAbstractAnimationClipPrivate;
-class QT3DANIMATIONSHARED_EXPORT QLerpBlend : public QAbstractClipBlendNode
+class QT3DANIMATIONSHARED_EXPORT QAbstractAnimationClip : public Qt3DCore::QNode
{
Q_OBJECT
- Q_PROPERTY(float blendFactor READ blendFactor WRITE setBlendFactor NOTIFY blendFactorChanged)
+ Q_PROPERTY(float duration READ duration NOTIFY durationChanged)
public:
- explicit QLerpBlend(Qt3DCore::QNode *parent = nullptr);
- ~QLerpBlend();
+ ~QAbstractAnimationClip();
- float blendFactor() const;
-
-public Q_SLOTS:
- void setBlendFactor(float blendFactor);
+ float duration() const;
Q_SIGNALS:
- void blendFactorChanged(float blendFactor);
+ void durationChanged(float duration);
protected:
- explicit QLerpBlend(QLerpBlendPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+ QAbstractAnimationClip(QAbstractAnimationClipPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) Q_DECL_OVERRIDE;
private:
- Q_DECLARE_PRIVATE(QLerpBlend)
- Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const Q_DECL_OVERRIDE;
+ Q_DECLARE_PRIVATE(QAbstractAnimationClip)
};
-} // Qt3DAnimation
+} // namespace Qt3DAnimation
QT_END_NAMESPACE
-
-#endif // QT3DANIMATION_QLERPBLEND_H
+#endif // QT3DANIMATION_QABSTRACTANIMATIONCLIP_H
diff --git a/src/animation/frontend/qabstractanimationclip_p.h b/src/animation/frontend/qabstractanimationclip_p.h
new file mode 100644
index 000000000..8b74bee94
--- /dev/null
+++ b/src/animation/frontend/qabstractanimationclip_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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_QABSTRACTANIMATIONCLIP_P_H
+#define QT3DANIMATION_QABSTRACTANIMATIONCLIP_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DCore/private/qnode_p.h>
+#include "qabstractanimationclip.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QAbstractAnimationClipPrivate : public Qt3DCore::QNodePrivate
+{
+public:
+ QAbstractAnimationClipPrivate();
+
+ Q_DECLARE_PUBLIC(QAbstractAnimationClip)
+
+ void setDuration(float duration);
+
+ // Set from the backend
+ float m_duration;
+};
+
+} // namespace Qt3DAnimation
+
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QABSTRACTANIMATIONCLIP_P_H
diff --git a/src/animation/frontend/qabstractclipanimator.cpp b/src/animation/frontend/qabstractclipanimator.cpp
new file mode 100644
index 000000000..0d215b470
--- /dev/null
+++ b/src/animation/frontend/qabstractclipanimator.cpp
@@ -0,0 +1,241 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 "qabstractclipanimator.h"
+#include "qabstractclipanimator_p.h"
+#include <Qt3DAnimation/qchannelmapper.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+QAbstractClipAnimatorPrivate::QAbstractClipAnimatorPrivate()
+ : Qt3DCore::QComponentPrivate()
+ , m_mapper(nullptr)
+ , m_running(false)
+ , m_loops(1)
+{
+}
+
+/*!
+ \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)
+{
+}
+
+QAbstractClipAnimator::QAbstractClipAnimator(QAbstractClipAnimatorPrivate &dd, Qt3DCore::QNode *parent)
+ : Qt3DCore::QComponent(dd, parent)
+{
+}
+
+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);
+ return d->m_loops;
+}
+
+void QAbstractClipAnimator::setRunning(bool running)
+{
+ Q_D(QAbstractClipAnimator);
+ if (d->m_running == running)
+ return;
+
+ d->m_running = running;
+ emit runningChanged(running);
+}
+
+void QAbstractClipAnimator::setChannelMapper(QChannelMapper *mapping)
+{
+ Q_D(QAbstractClipAnimator);
+ if (d->m_mapper == mapping)
+ return;
+
+ if (d->m_mapper)
+ d->unregisterDestructionHelper(d->m_mapper);
+
+ if (mapping && !mapping->parent())
+ mapping->setParent(this);
+ d->m_mapper = mapping;
+
+ // Ensures proper bookkeeping
+ if (d->m_mapper)
+ d->registerDestructionHelper(d->m_mapper, &QAbstractClipAnimator::setChannelMapper, d->m_mapper);
+ emit channelMapperChanged(mapping);
+}
+
+void QAbstractClipAnimator::setLoopCount(int loops)
+{
+ Q_D(QAbstractClipAnimator);
+ if (d->m_loops == loops)
+ return;
+
+ d->m_loops = 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
new file mode 100644
index 000000000..bd38fd68b
--- /dev/null
+++ b/src/animation/frontend/qabstractclipanimator.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 QT3DANIMATION_QABSTRACTCLIPANIMATOR_H
+#define QT3DANIMATION_QABSTRACTCLIPANIMATOR_H
+
+#include <Qt3DAnimation/qt3danimation_global.h>
+#include <Qt3DCore/qcomponent.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QAnimationClip;
+class QChannelMapper;
+class QAbstractClipAnimatorPrivate;
+
+class QT3DANIMATIONSHARED_EXPORT QAbstractClipAnimator : public Qt3DCore::QComponent
+{
+ Q_OBJECT
+ Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
+ Q_PROPERTY(int loops READ loopCount WRITE setLoopCount NOTIFY loopCountChanged)
+ Q_PROPERTY(Qt3DAnimation::QChannelMapper *channelMapper READ channelMapper WRITE setChannelMapper NOTIFY channelMapperChanged)
+
+public:
+ enum Loops { Infinite = -1 };
+ Q_ENUM(Loops)
+
+ ~QAbstractClipAnimator();
+
+ bool isRunning() const;
+ Qt3DAnimation::QChannelMapper *channelMapper() const;
+ int loopCount() const;
+
+public Q_SLOTS:
+ void setRunning(bool running);
+ void setChannelMapper(Qt3DAnimation::QChannelMapper *channelMapper);
+ void setLoopCount(int loops);
+
+ void start();
+ void stop();
+
+Q_SIGNALS:
+ void runningChanged(bool running);
+ void channelMapperChanged(Qt3DAnimation::QChannelMapper *channelMapper);
+ void loopCountChanged(int loops);
+
+protected:
+ explicit QAbstractClipAnimator(Qt3DCore::QNode *parent = nullptr);
+ QAbstractClipAnimator(QAbstractClipAnimatorPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+
+private:
+ Q_DECLARE_PRIVATE(QAbstractClipAnimator)
+};
+
+} // namespace Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QABSTRACTCLIPANIMATOR_H
diff --git a/src/animation/frontend/qconductedclipanimator_p.h b/src/animation/frontend/qabstractclipanimator_p.h
index c50247fa2..58553c8c1 100644
--- a/src/animation/frontend/qconductedclipanimator_p.h
+++ b/src/animation/frontend/qabstractclipanimator_p.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef QT3DANIMATION_QCONDUCTEDCLIPANIMATOR_P_H
-#define QT3DANIMATION_QCONDUCTEDCLIPANIMATOR_P_H
+#ifndef QT3DANIMATION_QABSTRACTCLIPANIMATOR_P_H
+#define QT3DANIMATION_QABSTRACTCLIPANIMATOR_P_H
//
// W A R N I N G
@@ -57,19 +57,25 @@ QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
-class QConductedClipAnimatorPrivate : public Qt3DCore::QComponentPrivate
+class QChannelMapper;
+
+class QAbstractClipAnimatorPrivate : public Qt3DCore::QComponentPrivate
{
public:
- QConductedClipAnimatorPrivate();
+ QAbstractClipAnimatorPrivate();
- Q_DECLARE_PUBLIC(QConductedClipAnimator)
+ Q_DECLARE_PUBLIC(QAbstractClipAnimator)
- // TODO Add member variables
+ Qt3DAnimation::QChannelMapper *m_mapper;
+ bool m_running;
+ int m_loops;
};
-struct QConductedClipAnimatorData
+struct QAbstractClipAnimatorData
{
- // TODO: Add members that should be sent to the backend
+ Qt3DCore::QNodeId mapperId;
+ bool running;
+ int loops;
};
} // namespace Qt3DAnimation
@@ -77,4 +83,4 @@ struct QConductedClipAnimatorData
QT_END_NAMESPACE
-#endif // QT3DANIMATION_QCONDUCTEDCLIPANIMATOR_P_H
+#endif // QT3DANIMATION_QABSTRACTCLIPANIMATOR_P_H
diff --git a/src/animation/frontend/qabstractclipblendnode.cpp b/src/animation/frontend/qabstractclipblendnode.cpp
index 4154b4223..9860e969f 100644
--- a/src/animation/frontend/qabstractclipblendnode.cpp
+++ b/src/animation/frontend/qabstractclipblendnode.cpp
@@ -36,9 +36,6 @@
#include "qabstractclipblendnode.h"
#include "qabstractclipblendnode_p.h"
-#include <Qt3DCore/qpropertynodeaddedchange.h>
-#include <Qt3DCore/qpropertynoderemovedchange.h>
-#include <Qt3DAnimation/qanimationclip.h>
QT_BEGIN_NAMESPACE
@@ -49,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)
{
@@ -63,62 +131,6 @@ QAbstractClipBlendNode::~QAbstractClipBlendNode()
{
}
-void QAbstractClipBlendNode::addClip(QAnimationClip *clip)
-{
- Q_D(QAbstractClipBlendNode);
- if (!d->m_clips.contains(clip)) {
- d->m_clips.push_back(clip);
-
- // Ensures proper bookkeeping
- d->registerDestructionHelper(clip, &QAbstractClipBlendNode::removeClip, d->m_clips);
-
- // We need to add it as a child of the current node if it has been declared inline
- // Or not previously added as a child of the current node so that
- // 1) The backend gets notified about it's creation
- // 2) When the current node is destroyed, it gets destroyed as well
- if (!clip->parent())
- clip->setParent(this);
-
- if (d->m_changeArbiter != nullptr) {
- const auto change = Qt3DCore::QPropertyNodeAddedChangePtr::create(id(), clip);
- change->setPropertyName("clip");
- d->notifyObservers(change);
- }
- }
-}
-
-void QAbstractClipBlendNode::removeClip(QAnimationClip *clip)
-{
- Q_D(QAbstractClipBlendNode);
- if (d->m_changeArbiter != nullptr) {
- const auto change = Qt3DCore::QPropertyNodeRemovedChangePtr::create(id(), clip);
- change->setPropertyName("clip");
- d->notifyObservers(change);
- }
- d->m_clips.removeOne(clip);
- // Remove bookkeeping connection
- d->unregisterDestructionHelper(clip);
-}
-
-QVector<QAnimationClip *> QAbstractClipBlendNode::clips() const
-{
- Q_D(const QAbstractClipBlendNode);
- return d->m_clips;
-}
-
-QAbstractClipBlendNode *QAbstractClipBlendNode::parentClipBlendNode() const
-{
- QAbstractClipBlendNode *parentBlendClipNode = nullptr;
- QNode *parentN = parentNode();
- while (parentN != nullptr) {
- parentBlendClipNode = qobject_cast<QAbstractClipBlendNode *>(parentN);
- if (parentBlendClipNode != nullptr)
- break;
- parentN = parentN->parentNode();
- }
- return parentBlendClipNode;
-}
-
} // Qt3DAnimation
QT_END_NAMESPACE
diff --git a/src/animation/frontend/qabstractclipblendnode.h b/src/animation/frontend/qabstractclipblendnode.h
index 35714026c..d981bd7a5 100644
--- a/src/animation/frontend/qabstractclipblendnode.h
+++ b/src/animation/frontend/qabstractclipblendnode.h
@@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
-class QAnimationClip;
+class QAbstractAnimationClip;
class QAbstractClipBlendNodePrivate;
class QT3DANIMATIONSHARED_EXPORT QAbstractClipBlendNode : public Qt3DCore::QNode
@@ -53,16 +53,10 @@ class QT3DANIMATIONSHARED_EXPORT QAbstractClipBlendNode : public Qt3DCore::QNode
public:
~QAbstractClipBlendNode();
- QVector<QAnimationClip *> clips() const;
- QAbstractClipBlendNode *parentClipBlendNode() const;
- void addClip(QAnimationClip *clip);
- void removeClip(QAnimationClip *clip);
-
protected:
explicit QAbstractClipBlendNode(Qt3DCore::QNode *parent = nullptr);
explicit QAbstractClipBlendNode(QAbstractClipBlendNodePrivate &dd, Qt3DCore::QNode *parent = nullptr);
-
private:
Q_DECLARE_PRIVATE(QAbstractClipBlendNode)
};
diff --git a/src/animation/frontend/qabstractclipblendnode_p.h b/src/animation/frontend/qabstractclipblendnode_p.h
index 42e10f18c..3066682a5 100644
--- a/src/animation/frontend/qabstractclipblendnode_p.h
+++ b/src/animation/frontend/qabstractclipblendnode_p.h
@@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
-class QAnimationClip;
+class QAbstractAnimationClip;
class QAbstractClipBlendNode;
class QAbstractClipBlendNodePrivate : public Qt3DCore::QNodePrivate
@@ -63,7 +63,7 @@ public:
QAbstractClipBlendNodePrivate();
Q_DECLARE_PUBLIC(QAbstractClipBlendNode)
- QVector<QAnimationClip *> m_clips;
+ QVector<QAbstractAnimationClip *> m_clips;
};
} // namespace Qt3DAnimation
diff --git a/src/animation/frontend/qadditiveclipblend.cpp b/src/animation/frontend/qadditiveclipblend.cpp
new file mode 100644
index 000000000..58ef5e577
--- /dev/null
+++ b/src/animation/frontend/qadditiveclipblend.cpp
@@ -0,0 +1,254 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 "qadditiveclipblend.h"
+#include "qadditiveclipblend_p.h"
+#include <Qt3DAnimation/qclipblendnodecreatedchange.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+
+/*!
+ \qmltype AdditiveClipBlend
+ \instantiates Qt3DAnimation::QAdditiveClipBlend
+ \inqmlmodule Qt3D.Animation
+
+ \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 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
+ \inherits Qt3DAnimation::QAbstractClipBlendNode
+
+ \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 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
+*/
+
+QAdditiveClipBlendPrivate::QAdditiveClipBlendPrivate()
+ : QAbstractClipBlendNodePrivate()
+ , m_baseClip(nullptr)
+ , m_additiveClip(nullptr)
+ , m_additiveFactor(0.0f)
+{
+}
+
+QAdditiveClipBlend::QAdditiveClipBlend(Qt3DCore::QNode *parent)
+ : QAbstractClipBlendNode(*new QAdditiveClipBlendPrivate(), parent)
+{
+}
+
+QAdditiveClipBlend::QAdditiveClipBlend(QAdditiveClipBlendPrivate &dd, Qt3DCore::QNode *parent)
+ : QAbstractClipBlendNode(dd, parent)
+{
+}
+
+QAdditiveClipBlend::~QAdditiveClipBlend()
+{
+}
+
+Qt3DCore::QNodeCreatedChangeBasePtr QAdditiveClipBlend::createNodeCreationChange() const
+{
+ Q_D(const QAdditiveClipBlend);
+ auto creationChange = QClipBlendNodeCreatedChangePtr<QAdditiveClipBlendData>::create(this);
+ QAdditiveClipBlendData &data = creationChange->data;
+ data.baseClipId = Qt3DCore::qIdForNode(d->m_baseClip);
+ data.additiveClipId = Qt3DCore::qIdForNode(d->m_additiveClip);
+ data.additiveFactor = d->m_additiveFactor;
+ return creationChange;
+}
+
+/*!
+ \qmlproperty real AdditiveClipBlend::additiveFactor
+
+ Specifies the blending factor, typically between 0 and 1, to control the blending of
+ two animation clips.
+*/
+/*!
+ \property QAdditiveClipBlend::additiveFactor
+
+ Specifies the blending factor, typically between 0 and 1, to control the blending of
+ two animation clips.
+ */
+float QAdditiveClipBlend::additiveFactor() const
+{
+ Q_D(const QAdditiveClipBlend);
+ 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);
+ return d->m_additiveClip;
+}
+
+void QAdditiveClipBlend::setAdditiveFactor(float additiveFactor)
+{
+ Q_D(QAdditiveClipBlend);
+ if (d->m_additiveFactor == additiveFactor)
+ return;
+
+ d->m_additiveFactor = additiveFactor;
+ emit additiveFactorChanged(additiveFactor);
+}
+
+void QAdditiveClipBlend::setBaseClip(QAbstractClipBlendNode *baseClip)
+{
+ Q_D(QAdditiveClipBlend);
+ if (d->m_baseClip == baseClip)
+ return;
+
+ if (d->m_baseClip)
+ d->unregisterDestructionHelper(d->m_baseClip);
+
+ if (baseClip && !baseClip->parent())
+ baseClip->setParent(this);
+ d->m_baseClip = baseClip;
+
+ // Ensures proper bookkeeping
+ if (d->m_baseClip)
+ d->registerDestructionHelper(d->m_baseClip, &QAdditiveClipBlend::setBaseClip, d->m_baseClip);
+
+ emit baseClipChanged(baseClip);
+}
+
+void QAdditiveClipBlend::setAdditiveClip(QAbstractClipBlendNode *additiveClip)
+{
+ Q_D(QAdditiveClipBlend);
+ if (d->m_additiveClip == additiveClip)
+ return;
+
+ if (d->m_additiveClip)
+ d->unregisterDestructionHelper(d->m_additiveClip);
+
+ if (additiveClip && !additiveClip->parent())
+ additiveClip->setParent(this);
+ d->m_additiveClip = additiveClip;
+
+ // Ensures proper bookkeeping
+ if (d->m_additiveClip)
+ d->registerDestructionHelper(d->m_additiveClip, &QAdditiveClipBlend::setAdditiveClip, d->m_additiveClip);
+ emit additiveClipChanged(additiveClip);
+}
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
diff --git a/src/animation/frontend/qadditiveclipblend.h b/src/animation/frontend/qadditiveclipblend.h
new file mode 100644
index 000000000..11731c702
--- /dev/null
+++ b/src/animation/frontend/qadditiveclipblend.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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_QADDITIVECLIPBLEND_H
+#define QT3DANIMATION_QADDITIVECLIPBLEND_H
+
+#include <Qt3DAnimation/qabstractclipblendnode.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QAdditiveClipBlendPrivate;
+
+class QT3DANIMATIONSHARED_EXPORT QAdditiveClipBlend : public QAbstractClipBlendNode
+{
+ Q_OBJECT
+ Q_PROPERTY(Qt3DAnimation::QAbstractClipBlendNode *baseClip READ baseClip WRITE setBaseClip NOTIFY baseClipChanged)
+ Q_PROPERTY(Qt3DAnimation::QAbstractClipBlendNode *additiveClip READ additiveClip WRITE setAdditiveClip NOTIFY additiveClipChanged)
+ Q_PROPERTY(float additiveFactor READ additiveFactor WRITE setAdditiveFactor NOTIFY additiveFactorChanged)
+public:
+ explicit QAdditiveClipBlend(Qt3DCore::QNode *parent = nullptr);
+ ~QAdditiveClipBlend();
+
+ float additiveFactor() const;
+ Qt3DAnimation::QAbstractClipBlendNode *baseClip() const;
+ Qt3DAnimation::QAbstractClipBlendNode *additiveClip() const;
+
+public Q_SLOTS:
+ void setAdditiveFactor(float additiveFactor);
+ void setBaseClip(Qt3DAnimation::QAbstractClipBlendNode *baseClip);
+ void setAdditiveClip(Qt3DAnimation::QAbstractClipBlendNode *additiveClip);
+
+Q_SIGNALS:
+ void additiveFactorChanged(float additiveFactor);
+ void baseClipChanged(Qt3DAnimation::QAbstractClipBlendNode *baseClip);
+ void additiveClipChanged(Qt3DAnimation::QAbstractClipBlendNode *additiveClip);
+
+protected:
+ explicit QAdditiveClipBlend(QAdditiveClipBlendPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+
+private:
+ Q_DECLARE_PRIVATE(QAdditiveClipBlend)
+ Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const Q_DECL_OVERRIDE;
+};
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QADDITIVECLIPBLEND_H
diff --git a/src/animation/frontend/qadditiveclipblend_p.h b/src/animation/frontend/qadditiveclipblend_p.h
new file mode 100644
index 000000000..0c408c9ff
--- /dev/null
+++ b/src/animation/frontend/qadditiveclipblend_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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_QADDITIVEBLEND_P_H
+#define QT3DANIMATION_QADDITIVEBLEND_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 <Qt3DAnimation/private/qabstractclipblendnode_p.h>
+#include <Qt3DCore/qnodeid.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QAdditiveClipBlend;
+
+class QAdditiveClipBlendPrivate : public QAbstractClipBlendNodePrivate
+{
+public:
+ QAdditiveClipBlendPrivate();
+
+ Q_DECLARE_PUBLIC(QAdditiveClipBlend)
+ Qt3DAnimation::QAbstractClipBlendNode *m_baseClip;
+ Qt3DAnimation::QAbstractClipBlendNode *m_additiveClip;
+ float m_additiveFactor;
+};
+
+struct QAdditiveClipBlendData
+{
+ Qt3DCore::QNodeId baseClipId;
+ Qt3DCore::QNodeId additiveClipId;
+ float additiveFactor;
+};
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QADDITIVEBLEND_P_H
diff --git a/src/animation/frontend/qanimationaspect.cpp b/src/animation/frontend/qanimationaspect.cpp
index 3310a8b77..00f97d5b6 100644
--- a/src/animation/frontend/qanimationaspect.cpp
+++ b/src/animation/frontend/qanimationaspect.cpp
@@ -39,17 +39,20 @@
#include "qanimationaspect.h"
#include "qanimationaspect_p.h"
-#include <Qt3DAnimation/qanimationclip.h>
+#include <Qt3DAnimation/qabstractanimationclip.h>
#include <Qt3DAnimation/qblendedclipanimator.h>
#include <Qt3DAnimation/qclipanimator.h>
-#include <Qt3DAnimation/qconductedclipanimator.h>
#include <Qt3DAnimation/qchannelmapping.h>
#include <Qt3DAnimation/qchannelmapper.h>
-#include <Qt3DAnimation/qlerpblend.h>
+#include <Qt3DAnimation/qlerpclipblend.h>
+#include <Qt3DAnimation/qadditiveclipblend.h>
+#include <Qt3DAnimation/qclipblendvalue.h>
#include <Qt3DAnimation/private/handler_p.h>
#include <Qt3DAnimation/private/managers_p.h>
#include <Qt3DAnimation/private/nodefunctor_p.h>
-#include <Qt3DAnimation/private/lerpblend_p.h>
+#include <Qt3DAnimation/private/lerpclipblend_p.h>
+#include <Qt3DAnimation/private/clipblendvalue_p.h>
+#include <Qt3DAnimation/private/additiveclipblend_p.h>
QT_BEGIN_NAMESPACE
@@ -87,30 +90,33 @@ QAnimationAspect::QAnimationAspect(QAnimationAspectPrivate &dd, QObject *parent)
{
setObjectName(QStringLiteral("Animation Aspect"));
Q_D(QAnimationAspect);
- qRegisterMetaType<Qt3DAnimation::QAnimationClip*>();
+ qRegisterMetaType<Qt3DAnimation::QAnimationClipLoader*>();
qRegisterMetaType<Qt3DAnimation::QChannelMapper*>();
- registerBackendType<QAnimationClip>(
- QSharedPointer<Animation::NodeFunctor<Animation::AnimationClip, Animation::AnimationClipManager>>::create(d->m_handler.data(),
- d->m_handler->animationClipManager()));
+ registerBackendType<QAbstractAnimationClip>(
+ QSharedPointer<Animation::NodeFunctor<Animation::AnimationClip, Animation::AnimationClipLoaderManager>>::create(d->m_handler.data(),
+ d->m_handler->animationClipLoaderManager()));
registerBackendType<QClipAnimator>(
QSharedPointer<Animation::NodeFunctor<Animation::ClipAnimator, Animation::ClipAnimatorManager>>::create(d->m_handler.data(),
d->m_handler->clipAnimatorManager()));
registerBackendType<QBlendedClipAnimator>(
QSharedPointer<Animation::NodeFunctor<Animation::BlendedClipAnimator, Animation::BlendedClipAnimatorManager>>::create(d->m_handler.data(),
d->m_handler->blendedClipAnimatorManager()));
- registerBackendType<QConductedClipAnimator>(
- QSharedPointer<Animation::NodeFunctor<Animation::ConductedClipAnimator, Animation::ConductedClipAnimatorManager>>::create(d->m_handler.data(),
- d->m_handler->conductedClipAnimatorManager()));
registerBackendType<QChannelMapping>(
QSharedPointer<Animation::NodeFunctor<Animation::ChannelMapping, Animation::ChannelMappingManager>>::create(d->m_handler.data(),
d->m_handler->channelMappingManager()));
registerBackendType<QChannelMapper>(
QSharedPointer<Animation::NodeFunctor<Animation::ChannelMapper, Animation::ChannelMapperManager>>::create(d->m_handler.data(),
d->m_handler->channelMapperManager()));
- registerBackendType<QLerpBlend>(
- QSharedPointer<Animation::ClipBlendNodeFunctor<Animation::LerpBlend, Animation::ClipAnimatorManager>>::create(d->m_handler.data(),
- d->m_handler->clipBlendNodeManager()));
+ registerBackendType<QLerpClipBlend>(
+ QSharedPointer<Animation::ClipBlendNodeFunctor<Animation::LerpClipBlend, Animation::ClipAnimatorManager>>::create(d->m_handler.data(),
+ d->m_handler->clipBlendNodeManager()));
+ registerBackendType<QAdditiveClipBlend>(
+ QSharedPointer<Animation::ClipBlendNodeFunctor<Animation::AdditiveClipBlend, Animation::ClipAnimatorManager>>::create(d->m_handler.data(),
+ d->m_handler->clipBlendNodeManager()));
+ registerBackendType<QClipBlendValue>(
+ QSharedPointer<Animation::ClipBlendNodeFunctor<Animation::ClipBlendValue, Animation::ClipAnimatorManager>>::create(d->m_handler.data(),
+ d->m_handler->clipBlendNodeManager()));
}
/*! \internal */
diff --git a/src/animation/frontend/qanimationclip.cpp b/src/animation/frontend/qanimationclip.cpp
index 56fe3978c..c21d94b02 100644
--- a/src/animation/frontend/qanimationclip.cpp
+++ b/src/animation/frontend/qanimationclip.cpp
@@ -1,34 +1,37 @@
/****************************************************************************
**
** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: http://www.qt-project.org/legal
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL3$
+** $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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** 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.LGPLv3 included in the
+** 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.html.
+** 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 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.
+** 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$
**
@@ -36,37 +39,24 @@
#include "qanimationclip.h"
#include "qanimationclip_p.h"
-#include <Qt3DCore/qpropertyupdatedchange.h>
QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
QAnimationClipPrivate::QAnimationClipPrivate()
- : Qt3DCore::QNodePrivate()
- , m_duration(0.0f)
+ : QAbstractAnimationClipPrivate()
+ , m_clipData()
{
}
-void QAnimationClipPrivate::setDuration(float duration)
-{
- if (qFuzzyCompare(duration, m_duration))
- return;
-
- Q_Q(QAnimationClip);
- bool wasBlocked = q->blockNotifications(true);
- m_duration = duration;
- emit q->durationChanged(duration);
- q->blockNotifications(wasBlocked);
-}
-
QAnimationClip::QAnimationClip(Qt3DCore::QNode *parent)
- : Qt3DCore::QNode(*new QAnimationClipPrivate, parent)
+ : QAbstractAnimationClip(*new QAnimationClipPrivate, parent)
{
}
QAnimationClip::QAnimationClip(QAnimationClipPrivate &dd, Qt3DCore::QNode *parent)
- : Qt3DCore::QNode(dd, parent)
+ : QAbstractAnimationClip(dd, parent)
{
}
@@ -74,44 +64,28 @@ QAnimationClip::~QAnimationClip()
{
}
-QUrl QAnimationClip::source() const
+QAnimationClipData QAnimationClip::clipData() const
{
Q_D(const QAnimationClip);
- return d->m_source;
+ return d->m_clipData;
}
-float QAnimationClip::duration() const
-{
- Q_D(const QAnimationClip);
- return d->m_duration;
-}
-
-void QAnimationClip::setSource(QUrl source)
+void QAnimationClip::setClipData(const Qt3DAnimation::QAnimationClipData &clipData)
{
Q_D(QAnimationClip);
- if (d->m_source == source)
+ if (d->m_clipData == clipData)
return;
- d->m_source = source;
- emit sourceChanged(source);
-}
-
-void QAnimationClip::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
-{
- Q_D(QAnimationClip);
- if (change->type() == Qt3DCore::PropertyUpdated) {
- Qt3DCore::QPropertyUpdatedChangePtr e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change);
- if (e->propertyName() == QByteArrayLiteral("duration"))
- d->setDuration(e->value().toFloat());
- }
+ d->m_clipData = clipData;
+ emit clipDataChanged(clipData);
}
Qt3DCore::QNodeCreatedChangeBasePtr QAnimationClip::createNodeCreationChange() const
{
- auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QAnimationClipData>::create(this);
+ auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QAnimationClipChangeData>::create(this);
auto &data = creationChange->data;
Q_D(const QAnimationClip);
- data.source = d->m_source;
+ data.clipData = d->m_clipData;
return creationChange;
}
diff --git a/src/animation/frontend/qanimationclip.h b/src/animation/frontend/qanimationclip.h
index 55b1910fa..6e606c598 100644
--- a/src/animation/frontend/qanimationclip.h
+++ b/src/animation/frontend/qanimationclip.h
@@ -1,34 +1,37 @@
/****************************************************************************
**
** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: http://www.qt-project.org/legal
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL3$
+** $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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** 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.LGPLv3 included in the
+** 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.html.
+** 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 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.
+** 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$
**
@@ -37,9 +40,9 @@
#ifndef QT3DANIMATION_QANIMATIONCLIP_H
#define QT3DANIMATION_QANIMATIONCLIP_H
+#include <Qt3DAnimation/qabstractanimationclip.h>
#include <Qt3DAnimation/qt3danimation_global.h>
-#include <Qt3DCore/qnode.h>
-#include <QtCore/qurl.h>
+#include <Qt3DAnimation/qanimationclipdata.h>
QT_BEGIN_NAMESPACE
@@ -47,29 +50,25 @@ namespace Qt3DAnimation {
class QAnimationClipPrivate;
-class QT3DANIMATIONSHARED_EXPORT QAnimationClip : public Qt3DCore::QNode
+class QT3DANIMATIONSHARED_EXPORT QAnimationClip : public QAbstractAnimationClip
{
Q_OBJECT
- Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
- Q_PROPERTY(float duration READ duration NOTIFY durationChanged)
+ Q_PROPERTY(Qt3DAnimation::QAnimationClipData clipData READ clipData WRITE setClipData NOTIFY clipDataChanged)
public:
explicit QAnimationClip(Qt3DCore::QNode *parent = nullptr);
~QAnimationClip();
- QUrl source() const;
- float duration() const;
+ Qt3DAnimation::QAnimationClipData clipData() const;
public Q_SLOTS:
- void setSource(QUrl source);
+ void setClipData(const Qt3DAnimation::QAnimationClipData &clipData);
Q_SIGNALS:
- void sourceChanged(QUrl source);
- void durationChanged(float duration);
+ void clipDataChanged(Qt3DAnimation::QAnimationClipData clipData);
protected:
QAnimationClip(QAnimationClipPrivate &dd, Qt3DCore::QNode *parent = nullptr);
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) Q_DECL_OVERRIDE;
private:
Q_DECLARE_PRIVATE(QAnimationClip)
diff --git a/src/animation/frontend/qanimationclip_p.h b/src/animation/frontend/qanimationclip_p.h
index 5e3df0e6e..514d568af 100644
--- a/src/animation/frontend/qanimationclip_p.h
+++ b/src/animation/frontend/qanimationclip_p.h
@@ -1,34 +1,37 @@
/****************************************************************************
**
** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: http://www.qt-project.org/legal
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL3$
+** $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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** 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.LGPLv3 included in the
+** 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.html.
+** 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 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.
+** 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$
**
@@ -48,32 +51,26 @@
// We mean it.
//
-#include <Qt3DCore/private/qnode_p.h>
-#include "qanimationclip.h"
+#include <Qt3DAnimation/private/qabstractanimationclip_p.h>
+#include <Qt3DAnimation/qanimationclip.h>
QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
-class QAnimationClipPrivate : public Qt3DCore::QNodePrivate
+class QAnimationClipPrivate : public QAbstractAnimationClipPrivate
{
public:
QAnimationClipPrivate();
Q_DECLARE_PUBLIC(QAnimationClip)
- void setDuration(float duration);
-
- QUrl m_source;
-
- // Set from the backend
- float m_duration;
+ QAnimationClipData m_clipData;
};
-struct QAnimationClipData
+struct QAnimationClipChangeData
{
- QUrl source;
- bool running;
+ QAnimationClipData clipData;
};
} // namespace Qt3DAnimation
diff --git a/src/animation/frontend/qanimationclipdata.cpp b/src/animation/frontend/qanimationclipdata.cpp
new file mode 100644
index 000000000..ef3b59012
--- /dev/null
+++ b/src/animation/frontend/qanimationclipdata.cpp
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 "qanimationclipdata.h"
+
+#include <QtCore/qvector.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QAnimationClipDataPrivate
+{
+public:
+ QVector<QChannel> m_channels;
+ QString m_name;
+};
+
+QAnimationClipData::QAnimationClipData()
+ : d(new QAnimationClipDataPrivate)
+{
+}
+
+QAnimationClipData::QAnimationClipData(const QAnimationClipData &rhs)
+ : d(new QAnimationClipDataPrivate)
+{
+ *d = *(rhs.d);
+}
+
+QAnimationClipData &QAnimationClipData::operator=(const QAnimationClipData &rhs)
+{
+ if (this != &rhs)
+ *d = *(rhs.d);
+ return *this;
+}
+
+QAnimationClipData::~QAnimationClipData()
+{
+}
+
+void QAnimationClipData::setName(const QString &name)
+{
+ d->m_name = name;
+}
+
+QString QAnimationClipData::name() const
+{
+ return d->m_name;
+}
+
+int QAnimationClipData::channelCount() const
+{
+ return d->m_channels.size();
+}
+
+void QAnimationClipData::appendChannel(const QChannel &c)
+{
+ d->m_channels.append(c);
+}
+
+void QAnimationClipData::insertChannel(int index, const QChannel &c)
+{
+ d->m_channels.insert(index, c);
+}
+
+void QAnimationClipData::removeChannel(int index)
+{
+ d->m_channels.remove(index);
+}
+
+void QAnimationClipData::clearChannels()
+{
+ d->m_channels.clear();
+}
+
+bool QAnimationClipData::isValid() const Q_DECL_NOTHROW
+{
+ // TODO: Perform more thorough checks
+ return !d->m_channels.isEmpty();
+}
+
+QAnimationClipData::const_iterator QAnimationClipData::begin() const Q_DECL_NOTHROW
+{
+ return d->m_channels.begin();
+}
+
+QAnimationClipData::const_iterator QAnimationClipData::end() const Q_DECL_NOTHROW
+{
+ return d->m_channels.end();
+}
+
+
+bool operator==(const QAnimationClipData &lhs, const QAnimationClipData &rhs) Q_DECL_NOTHROW
+{
+ return lhs.d->m_name == rhs.d->m_name &&
+ lhs.d->m_channels == rhs.d->m_channels;
+}
+
+bool operator!=(const QAnimationClipData &lhs, const QAnimationClipData &rhs) Q_DECL_NOTHROW
+{
+ return lhs.d->m_name != rhs.d->m_name ||
+ lhs.d->m_channels != rhs.d->m_channels;
+}
+
+} // namespace Qt3DAnimation
+
+QT_END_NAMESPACE
diff --git a/src/animation/frontend/qanimationclipdata.h b/src/animation/frontend/qanimationclipdata.h
new file mode 100644
index 000000000..605b17208
--- /dev/null
+++ b/src/animation/frontend/qanimationclipdata.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 QT3DANIMATION_QANIMATIONCLIPDATA_H
+#define QT3DANIMATION_QANIMATIONCLIPDATA_H
+
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qstring.h>
+#include <Qt3DAnimation/qt3danimation_global.h>
+#include <Qt3DAnimation/qchannel.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QAnimationClipDataPrivate;
+
+class QT3DANIMATIONSHARED_EXPORT QAnimationClipData
+{
+public:
+ QAnimationClipData();
+ QAnimationClipData(const QAnimationClipData &);
+ QAnimationClipData &operator=(const QAnimationClipData &);
+ ~QAnimationClipData();
+
+ void setName(const QString &name);
+ QString name() const;
+
+ int channelCount() const;
+ void appendChannel(const QChannel &c);
+ void insertChannel(int index, const QChannel &c);
+ void removeChannel(int index);
+ void clearChannels();
+
+ bool isValid() const Q_DECL_NOTHROW;
+
+ // Iterator API
+ typedef const QChannel *const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ const_iterator begin() const Q_DECL_NOTHROW;
+ const_iterator cbegin() const Q_DECL_NOTHROW { return begin(); }
+ const_iterator end() const Q_DECL_NOTHROW;
+ const_iterator cend() const Q_DECL_NOTHROW { return end(); }
+ const_reverse_iterator rbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); }
+ const_reverse_iterator crbegin() const Q_DECL_NOTHROW { return rbegin(); }
+ const_reverse_iterator rend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); }
+ const_reverse_iterator crend() const Q_DECL_NOTHROW { return rend(); }
+
+ friend bool operator==(const QAnimationClipData &,
+ const QAnimationClipData &) Q_DECL_NOTHROW;
+ friend bool operator!=(const QAnimationClipData &,
+ const QAnimationClipData &) Q_DECL_NOTHROW;
+
+private:
+ QScopedPointer<QAnimationClipDataPrivate> d;
+};
+
+} // namespace Qt3DAnimation
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(Qt3DAnimation::QAnimationClipData)
+
+#endif // QT3DANIMATION_QANIMATIONCLIPDATA_H
diff --git a/src/animation/frontend/qanimationcliploader.cpp b/src/animation/frontend/qanimationcliploader.cpp
new file mode 100644
index 000000000..ed48438de
--- /dev/null
+++ b/src/animation/frontend/qanimationcliploader.cpp
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 "qanimationcliploader.h"
+#include "qanimationcliploader_p.h"
+#include <Qt3DCore/qpropertyupdatedchange.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+QAnimationClipLoaderPrivate::QAnimationClipLoaderPrivate()
+ : QAbstractAnimationClipPrivate()
+ , m_source()
+ , m_status(QAnimationClipLoader::NotReady)
+{
+}
+
+void QAnimationClipLoaderPrivate::setStatus(QAnimationClipLoader::Status status)
+{
+ Q_Q(QAnimationClipLoader);
+ if (status != m_status) {
+ m_status = status;
+ const bool blocked = q->blockNotifications(true);
+ emit q->statusChanged(m_status);
+ q->blockNotifications(blocked);
+ }
+}
+
+/*!
+ \enum QAnimationClipLoader::Status
+
+ This enum identifies the status of animation clip.
+
+ \value NotReady The clip has not been loaded yet
+ \value Ready The clip was successfully loaded
+ \value Error An error occurred while loading the clip
+*/
+
+QAnimationClipLoader::QAnimationClipLoader(Qt3DCore::QNode *parent)
+ : QAbstractAnimationClip(*new QAnimationClipLoaderPrivate, parent)
+{
+}
+
+QAnimationClipLoader::QAnimationClipLoader(const QUrl &source,
+ Qt3DCore::QNode *parent)
+ : QAbstractAnimationClip(*new QAnimationClipLoaderPrivate, parent)
+{
+ setSource(source);
+}
+
+QAnimationClipLoader::QAnimationClipLoader(QAnimationClipLoaderPrivate &dd, Qt3DCore::QNode *parent)
+ : QAbstractAnimationClip(dd, parent)
+{
+}
+
+QAnimationClipLoader::~QAnimationClipLoader()
+{
+}
+
+QUrl QAnimationClipLoader::source() const
+{
+ Q_D(const QAnimationClipLoader);
+ return d->m_source;
+}
+
+QAnimationClipLoader::Status QAnimationClipLoader::status() const
+{
+ Q_D(const QAnimationClipLoader);
+ return d->m_status;
+}
+
+void QAnimationClipLoader::setSource(const QUrl &source)
+{
+ Q_D(QAnimationClipLoader);
+ if (d->m_source == source)
+ return;
+
+ d->m_source = source;
+ emit sourceChanged(source);
+}
+
+void QAnimationClipLoader::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
+{
+ Q_D(QAnimationClipLoader);
+ if (change->type() == Qt3DCore::PropertyUpdated) {
+ const Qt3DCore::QPropertyUpdatedChangePtr e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change);
+ if (e->propertyName() == QByteArrayLiteral("status"))
+ d->setStatus(static_cast<QAnimationClipLoader::Status>(e->value().toInt()));
+ }
+}
+
+Qt3DCore::QNodeCreatedChangeBasePtr QAnimationClipLoader::createNodeCreationChange() const
+{
+ auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QAnimationClipLoaderData>::create(this);
+ auto &data = creationChange->data;
+ Q_D(const QAnimationClipLoader);
+ data.source = d->m_source;
+ return creationChange;
+}
+
+} // namespace Qt3DAnimation
+
+QT_END_NAMESPACE
diff --git a/src/animation/frontend/qanimationcliploader.h b/src/animation/frontend/qanimationcliploader.h
new file mode 100644
index 000000000..20f0f14da
--- /dev/null
+++ b/src/animation/frontend/qanimationcliploader.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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_QANIMATIONCLIPLOADER_H
+#define QT3DANIMATION_QANIMATIONCLIPLOADER_H
+
+#include <Qt3DAnimation/qt3danimation_global.h>
+#include <Qt3DAnimation/qabstractanimationclip.h>
+#include <QtCore/qurl.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QAnimationClipLoaderPrivate;
+
+class QT3DANIMATIONSHARED_EXPORT QAnimationClipLoader : public QAbstractAnimationClip
+{
+ Q_OBJECT
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+
+public:
+ explicit QAnimationClipLoader(Qt3DCore::QNode *parent = nullptr);
+ explicit QAnimationClipLoader(const QUrl &source,
+ Qt3DCore::QNode *parent = nullptr);
+ ~QAnimationClipLoader();
+
+ enum Status {
+ NotReady = 0,
+ Ready,
+ Error
+ };
+ Q_ENUM(Status) // LCOV_EXCL_LINE
+
+ QUrl source() const;
+ Status status() const;
+
+public Q_SLOTS:
+ void setSource(const QUrl &source);
+
+Q_SIGNALS:
+ void sourceChanged(const QUrl &source);
+ void statusChanged(Status status);
+
+protected:
+ explicit QAnimationClipLoader(QAnimationClipLoaderPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+ void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) Q_DECL_OVERRIDE;
+
+private:
+ Q_DECLARE_PRIVATE(QAnimationClipLoader)
+ Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const Q_DECL_OVERRIDE;
+};
+
+} // namespace Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QANIMATIONCLIPLOADER_H
diff --git a/src/animation/frontend/qanimationcliploader_p.h b/src/animation/frontend/qanimationcliploader_p.h
new file mode 100644
index 000000000..70b21dbb4
--- /dev/null
+++ b/src/animation/frontend/qanimationcliploader_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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_QANIMATIONCLIPLOADER_P_H
+#define QT3DANIMATION_QANIMATIONCLIPLOADER_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 <Qt3DAnimation/private/qabstractanimationclip_p.h>
+#include "qanimationcliploader.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QAnimationClipLoaderPrivate : public QAbstractAnimationClipPrivate
+{
+public:
+ QAnimationClipLoaderPrivate();
+
+ void setStatus(QAnimationClipLoader::Status status);
+
+ Q_DECLARE_PUBLIC(QAnimationClipLoader)
+
+ QUrl m_source;
+ QAnimationClipLoader::Status m_status;
+};
+
+struct QAnimationClipLoaderData
+{
+ QUrl source;
+};
+
+} // namespace Qt3DAnimation
+
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QANIMATIONCLIPLOADER_P_H
diff --git a/src/animation/frontend/qanimationcontroller.cpp b/src/animation/frontend/qanimationcontroller.cpp
new file mode 100644
index 000000000..d4c3c4005
--- /dev/null
+++ b/src/animation/frontend/qanimationcontroller.cpp
@@ -0,0 +1,390 @@
+/****************************************************************************
+**
+** 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 "qanimationcontroller.h"
+#include "qanimationgroup.h"
+
+#include <private/qanimationcontroller_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+/*!
+ \class Qt3DAnimation::QAnimationController
+ \brief A controller class for animations
+ \inmodule Qt3DAnimation
+ \since 5.9
+ \inherits QObject
+
+ Qt3DAnimation::QAnimationController class controls the selection and playback of animations.
+ The class can be used to find all animations from Qt3DCore::QEntity tree and create
+ \l {Qt3DAnimation::QAnimationGroup} {QAnimationGroups} from the animations with the same name.
+ The user can select which animation group is currently controlled with the animation
+ controller by setting the active animation. The animation position is then propagated to
+ that group after scaling and offsetting the provided position value with the
+ positionScale and positionOffset values.
+
+ \note that the animation controller doesn't have internal timer, but instead the user
+ is responsible for updating the position property in timely manner.
+*/
+
+/*!
+ \qmltype AnimationController
+ \brief A controller type for animations
+ \inqmlmodule Qt3D.Animation
+ \since 5.9
+ \instantiates Qt3DAnimation::QAnimationController
+
+ AnimationController type controls the selection and playback of animations.
+ The type can be used to find all animations from Entity tree and create
+ \l {AnimationGroup} {AnimationGroups} from the animations with the same name.
+ The user can select which animation group is currently controlled with the animation
+ controller by setting the active animation. The animation position is then propagated to
+ that group after scaling and offsetting the provided position value with the
+ positionScale and positionOffset values.
+
+ \note that the animation controller doesn't have internal timer, but instead the user
+ is responsible for updating the position property in timely manner.
+*/
+
+/*!
+ \property Qt3DAnimation::QAnimationController::activeAnimationGroup
+ Holds the currectly active animation group.
+*/
+/*!
+ \property Qt3DAnimation::QAnimationController::position
+ Holds the current position of the animation. When the position is set,
+ it is scaled and offset with positionScale/positionOffset and propagated
+ to the active animation group.
+*/
+/*!
+ \property Qt3DAnimation::QAnimationController::positionScale
+ Holds the position scale of the animation.
+*/
+/*!
+ \property Qt3DAnimation::QAnimationController::positionOffset
+ Holds the position offset of the animation.
+*/
+/*!
+ \property Qt3DAnimation::QAnimationController::entity
+ Holds the entity animations are gathered and grouped from. If the controller already
+ holds animations, they are cleared.
+*/
+/*!
+ \property Qt3DAnimation::QAnimationController::recursive
+ Holds whether the recursively search the entity tree when gathering animations from the entity.
+ If set to true, the animations are searched also from the child entities of the entity.
+ If set to false, only the entity passed to the controller is searched.
+*/
+
+/*!
+ \qmlproperty int AnimationController::activeAnimationGroup
+ Holds the currectly active animation group.
+*/
+/*!
+ \qmlproperty real AnimationController::position
+ Holds the current position of the animation. When the position is set,
+ it is scaled and offset with positionScale/positionOffset and propagated
+ to the active animation group.
+*/
+/*!
+ \qmlproperty real AnimationController::positionScale
+ Holds the position scale of the animation.
+*/
+/*!
+ \qmlproperty real AnimationController::positionOffset
+ Holds the position offset of the animation.
+*/
+/*!
+ \qmlproperty Entity AnimationController::entity
+ Holds the entity animations are gathered and grouped from. If the controller already
+ holds animations, they are cleared.
+*/
+/*!
+ \qmlproperty bool AnimationController::recursive
+ Holds whether the recursively search the entity tree when gathering animations from the entity.
+ If set to true, the animations are searched also from the child entities of the entity.
+ If set to false, only the entity passed to the controller is searched.
+*/
+/*!
+ \qmlproperty list<AnimationGroup> AnimationController::animationGroups
+ Holds the list of animation groups in the controller.
+*/
+/*!
+ \qmlmethod int Qt3D.Animation::AnimationController::getAnimationIndex(name)
+ Returns the index of the animation with \a name. Returns -1 if no AnimationGroup
+ with the given name is found.
+*/
+/*!
+ \qmlmethod AnimationGroup Qt3D.Animation::AnimationController::getGroup(index)
+ Returns the AnimationGroup with the given \a index.
+*/
+
+QAnimationControllerPrivate::QAnimationControllerPrivate()
+ : QObjectPrivate()
+ , m_activeAnimationGroup(0)
+ , m_position(0.0f)
+ , m_scaledPosition(0.0f)
+ , m_positionScale(1.0f)
+ , m_positionOffset(0.0f)
+ , m_entity(nullptr)
+ , m_recursive(true)
+{
+
+}
+
+void QAnimationControllerPrivate::updatePosition(float position)
+{
+ m_position = position;
+ m_scaledPosition = scaledPosition(position);
+ if (m_activeAnimationGroup >= 0 && m_activeAnimationGroup < m_animationGroups.size())
+ m_animationGroups[m_activeAnimationGroup]->setPosition(m_scaledPosition);
+}
+
+float QAnimationControllerPrivate::scaledPosition(float position) const
+{
+ return m_positionScale * position + m_positionOffset;
+}
+
+QAnimationGroup *QAnimationControllerPrivate::findGroup(const QString &name)
+{
+ for (QAnimationGroup *g : qAsConst(m_animationGroups)) {
+ if (g->name() == name)
+ return g;
+ }
+ return nullptr;
+}
+
+void QAnimationControllerPrivate::extractAnimations()
+{
+ Q_Q(QAnimationController);
+ if (!m_entity)
+ return;
+ QList<Qt3DAnimation::QAbstractAnimation *> animations
+ = m_entity->findChildren<Qt3DAnimation::QAbstractAnimation *>(QString(),
+ m_recursive ? Qt::FindChildrenRecursively : Qt::FindDirectChildrenOnly);
+ if (animations.size() > 0) {
+ for (Qt3DAnimation::QAbstractAnimation *a : animations) {
+ QAnimationGroup *group = findGroup(a->animationName());
+ if (!group) {
+ group = new QAnimationGroup(q);
+ group->setName(a->animationName());
+ m_animationGroups.push_back(group);
+ }
+ group->addAnimation(a);
+ }
+ }
+}
+void QAnimationControllerPrivate::clearAnimations()
+{
+ for (Qt3DAnimation::QAnimationGroup *a : qAsConst(m_animationGroups))
+ a->deleteLater();
+ m_animationGroups.clear();
+ m_activeAnimationGroup = 0;
+}
+
+/*!
+ Constructs a new QAnimationController with \a parent.
+ */
+QAnimationController::QAnimationController(QObject *parent)
+ : QObject(*new QAnimationControllerPrivate, parent)
+{
+
+}
+
+/*!
+ Returns the list of animation groups the conroller is currently holding.
+ */
+QVector<QAnimationGroup *> QAnimationController::animationGroupList()
+{
+ Q_D(QAnimationController);
+ return d->m_animationGroups;
+}
+
+int QAnimationController::activeAnimationGroup() const
+{
+ Q_D(const QAnimationController);
+ return d->m_activeAnimationGroup;
+}
+
+float QAnimationController::position() const
+{
+ Q_D(const QAnimationController);
+ return d->m_position;
+}
+
+float QAnimationController::positionScale() const
+{
+ Q_D(const QAnimationController);
+ return d->m_positionScale;
+}
+
+float QAnimationController::positionOffset() const
+{
+ Q_D(const QAnimationController);
+ return d->m_positionOffset;
+}
+
+Qt3DCore::QEntity *QAnimationController::entity() const
+{
+ Q_D(const QAnimationController);
+ return d->m_entity;
+}
+
+bool QAnimationController::recursive() const
+{
+ Q_D(const QAnimationController);
+ return d->m_recursive;
+}
+
+/*!
+ Sets the \a animationGroups for the controller. Old groups are cleared.
+ */
+void QAnimationController::setAnimationGroups(const QVector<Qt3DAnimation::QAnimationGroup *> &animationGroups)
+{
+ Q_D(QAnimationController);
+ d->m_animationGroups = animationGroups;
+ if (d->m_activeAnimationGroup >= d->m_animationGroups.size())
+ d->m_activeAnimationGroup = 0;
+ d->updatePosition(d->m_position);
+}
+
+/*!
+ Adds the given \a animationGroup to the controller.
+ */
+void QAnimationController::addAnimationGroup(Qt3DAnimation::QAnimationGroup *animationGroup)
+{
+ Q_D(QAnimationController);
+ if (!d->m_animationGroups.contains(animationGroup))
+ d->m_animationGroups.push_back(animationGroup);
+}
+
+/*!
+ Removes the given \a animationGroup from the controller.
+ */
+void QAnimationController::removeAnimationGroup(Qt3DAnimation::QAnimationGroup *animationGroup)
+{
+ Q_D(QAnimationController);
+ if (d->m_animationGroups.contains(animationGroup))
+ d->m_animationGroups.removeAll(animationGroup);
+ if (d->m_activeAnimationGroup >= d->m_animationGroups.size())
+ d->m_activeAnimationGroup = 0;
+}
+
+void QAnimationController::setActiveAnimationGroup(int index)
+{
+ Q_D(QAnimationController);
+ if (d->m_activeAnimationGroup != index) {
+ d->m_activeAnimationGroup = index;
+ d->updatePosition(d->m_position);
+ emit activeAnimationGroupChanged(index);
+ }
+}
+void QAnimationController::setPosition(float position)
+{
+ Q_D(QAnimationController);
+ if (!qFuzzyCompare(d->m_scaledPosition, d->scaledPosition(position))) {
+ d->updatePosition(position);
+ emit positionChanged(position);
+ }
+}
+
+void QAnimationController::setPositionScale(float scale)
+{
+ Q_D(QAnimationController);
+ if (!qFuzzyCompare(d->m_positionScale, scale)) {
+ d->m_positionScale = scale;
+ emit positionScaleChanged(scale);
+ }
+}
+
+void QAnimationController::setPositionOffset(float offset)
+{
+ Q_D(QAnimationController);
+ if (!qFuzzyCompare(d->m_positionOffset, offset)) {
+ d->m_positionOffset = offset;
+ emit positionOffsetChanged(offset);
+ }
+}
+
+void QAnimationController::setEntity(Qt3DCore::QEntity *entity)
+{
+ Q_D(QAnimationController);
+ if (d->m_entity != entity) {
+ d->clearAnimations();
+ d->m_entity = entity;
+ d->extractAnimations();
+ d->updatePosition(d->m_position);
+ emit entityChanged(entity);
+ }
+}
+
+void QAnimationController::setRecursive(bool recursive)
+{
+ Q_D(QAnimationController);
+ if (d->m_recursive != recursive) {
+ d->m_recursive = recursive;
+ emit recursiveChanged(recursive);
+ }
+}
+
+/*!
+ Returns the index of the animation with \a name. Returns -1 if no AnimationGroup
+ with the given name is found.
+*/
+int QAnimationController::getAnimationIndex(const QString &name) const
+{
+ Q_D(const QAnimationController);
+ for (int i = 0; i < d->m_animationGroups.size(); ++i) {
+ if (d->m_animationGroups[i]->name() == name)
+ return i;
+ }
+ return -1;
+}
+
+/*!
+ Returns the AnimationGroup with the given \a index.
+*/
+QAnimationGroup *QAnimationController::getGroup(int index) const
+{
+ Q_D(const QAnimationController);
+ return d->m_animationGroups.at(index);
+}
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
diff --git a/src/animation/frontend/qanimationcontroller.h b/src/animation/frontend/qanimationcontroller.h
new file mode 100644
index 000000000..ae3272517
--- /dev/null
+++ b/src/animation/frontend/qanimationcontroller.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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_QANIMATIONCONTROLLER_H
+#define QT3DANIMATION_QANIMATIONCONTROLLER_H
+
+#include <Qt3DAnimation/qkeyframeanimation.h>
+#include <Qt3DAnimation/qanimationgroup.h>
+#include <Qt3DCore/qentity.h>
+
+#include <Qt3DAnimation/qt3danimation_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QAnimationControllerPrivate;
+
+class QT3DANIMATIONSHARED_EXPORT QAnimationController : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int activeAnimationGroup READ activeAnimationGroup WRITE setActiveAnimationGroup NOTIFY activeAnimationGroupChanged)
+ Q_PROPERTY(float position READ position WRITE setPosition NOTIFY positionChanged)
+ Q_PROPERTY(float positionScale READ positionScale WRITE setPositionScale NOTIFY positionScaleChanged)
+ Q_PROPERTY(float positionOffset READ positionOffset WRITE setPositionOffset NOTIFY positionOffsetChanged)
+ Q_PROPERTY(Qt3DCore::QEntity *entity READ entity WRITE setEntity NOTIFY entityChanged)
+ Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged)
+
+public:
+ QAnimationController(QObject *parent = nullptr);
+
+ QVector<Qt3DAnimation::QAnimationGroup *> animationGroupList();
+
+ int activeAnimationGroup() const;
+ float position() const;
+ float positionScale() const;
+ float positionOffset() const;
+ Qt3DCore::QEntity *entity() const;
+ bool recursive() const;
+
+ void setAnimationGroups(const QVector<Qt3DAnimation::QAnimationGroup *> &animationGroups);
+ void addAnimationGroup(Qt3DAnimation::QAnimationGroup *animationGroups);
+ void removeAnimationGroup(Qt3DAnimation::QAnimationGroup *animationGroups);
+
+ Q_INVOKABLE int getAnimationIndex(const QString &name) const;
+ Q_INVOKABLE Qt3DAnimation::QAnimationGroup *getGroup(int index) const;
+
+public Q_SLOTS:
+ void setActiveAnimationGroup(int index);
+ void setPosition(float position);
+ void setPositionScale(float scale);
+ void setPositionOffset(float offset);
+ void setEntity(Qt3DCore::QEntity *entity);
+ void setRecursive(bool recursive);
+
+Q_SIGNALS:
+ void activeAnimationGroupChanged(int index);
+ void positionChanged(float position);
+ void positionScaleChanged(float scale);
+ void positionOffsetChanged(float offset);
+ void entityChanged(Qt3DCore::QEntity *entity);
+ void recursiveChanged(bool recursive);
+
+private:
+ Q_DECLARE_PRIVATE(QAnimationController)
+};
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QANIMATIONCONTROLLER_H
diff --git a/src/animation/frontend/qanimationcontroller_p.h b/src/animation/frontend/qanimationcontroller_p.h
new file mode 100644
index 000000000..c06484911
--- /dev/null
+++ b/src/animation/frontend/qanimationcontroller_p.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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_QANIMATIONCONTROLLER_P_H
+#define QT3DANIMATION_QANIMATIONCONTROLLER_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 <private/qobject_p.h>
+#include <Qt3DAnimation/QAnimationGroup>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QAnimationControllerPrivate : public QObjectPrivate
+{
+public:
+ QAnimationControllerPrivate();
+
+ QString m_name;
+ int m_activeAnimationGroup;
+ QVector<QAnimationGroup *> m_animationGroups;
+ float m_position;
+ float m_scaledPosition;
+ float m_positionScale;
+ float m_positionOffset;
+ Qt3DCore::QEntity *m_entity;
+ bool m_recursive;
+
+ void updatePosition(float position);
+ void extractAnimations();
+ void clearAnimations();
+ QAnimationGroup *findGroup(const QString &name);
+ float scaledPosition(float position) const;
+
+ Q_DECLARE_PUBLIC(QAnimationController)
+};
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QANIMATIONCONTROLLER_P_H
diff --git a/src/animation/frontend/qanimationgroup.cpp b/src/animation/frontend/qanimationgroup.cpp
new file mode 100644
index 000000000..365745662
--- /dev/null
+++ b/src/animation/frontend/qanimationgroup.cpp
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 "qanimationgroup.h"
+#include "Qt3DAnimation/private/qanimationgroup_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+/*!
+ \class Qt3DAnimation::QAnimationGroup
+ \brief A class grouping animations together
+ \inmodule Qt3DAnimation
+ \since 5.9
+ \inherits QObject
+
+ Qt3DAnimation::QAnimationGroup class is used to group multiple animations so that
+ they can act as one animation. The position set to the group is also set to
+ all animations in a group. The duration is the maximum of the individual animations.
+ The animations can be any supported animation type and do not have to have the same name.
+*/
+/*!
+ \qmltype AnimationGroup
+ \brief A type grouping animations together
+ \inqmlmodule Qt3D.Animation
+ \since 5.9
+ \inherits QObject
+
+ AnimationGroup type is used to group multiple animations so that
+ they can act as one animation. The position set to the group is also set to
+ all animations in a group. The duration is the maximum of the individual animations.
+ The animations can be any supported animation type and do not have to have the same name.
+*/
+
+/*!
+ \property Qt3DAnimation::QAnimationGroup::name
+ Holds the name of the animation group.
+*/
+/*!
+ \property Qt3DAnimation::QAnimationGroup::position
+ Holds the animation position.
+*/
+/*!
+ \property Qt3DAnimation::QAnimationGroup::duration
+ Holds the maximum duration of the animations in the group.
+ \readonly
+*/
+
+/*!
+ \qmlproperty string AnimationGroup::name
+ Holds the name of the animation group.
+*/
+/*!
+ \qmlproperty real AnimationGroup::position
+ Holds the animation position.
+*/
+/*!
+ \qmlproperty real AnimationGroup::duration
+ Holds the maximum duration of the animations in the group.
+ \readonly
+*/
+/*!
+ \qmlproperty list<AbstractAnimation> AnimationGroup::animations
+ Holds the list of animations in the animation group.
+*/
+
+QAnimationGroupPrivate::QAnimationGroupPrivate()
+ : QObjectPrivate()
+ , m_position(0.0f)
+ , m_duration(0.0f)
+{
+
+}
+
+void QAnimationGroupPrivate::updatePosition(float position)
+{
+ m_position = position;
+ for (QAbstractAnimation *aa : qAsConst(m_animations))
+ aa->setPosition(position);
+}
+
+/*!
+ Constructs an QAnimationGroup with \a parent.
+*/
+QAnimationGroup::QAnimationGroup(QObject *parent)
+ : QObject(*new QAnimationGroupPrivate, parent)
+{
+
+}
+
+QString QAnimationGroup::name() const
+{
+ Q_D(const QAnimationGroup);
+ return d->m_name;
+}
+
+/*!
+ Returns the list of animations in the group.
+ */
+QVector<Qt3DAnimation::QAbstractAnimation *> QAnimationGroup::animationList()
+{
+ Q_D(QAnimationGroup);
+ return d->m_animations;
+}
+
+float QAnimationGroup::position() const
+{
+ Q_D(const QAnimationGroup);
+ return d->m_position;
+}
+
+float QAnimationGroup::duration() const
+{
+ Q_D(const QAnimationGroup);
+ return d->m_duration;
+}
+
+void QAnimationGroup::setName(const QString &name)
+{
+ Q_D(QAnimationGroup);
+ if (d->m_name != name) {
+ d->m_name = name;
+ emit nameChanged(name);
+ }
+}
+
+/*!
+ Sets the \a animations to the group. Old animations are removed.
+ */
+void QAnimationGroup::setAnimations(const QVector<Qt3DAnimation::QAbstractAnimation *> &animations)
+{
+ Q_D(QAnimationGroup);
+ d->m_animations = animations;
+ d->m_duration = 0.0f;
+ for (const Qt3DAnimation::QAbstractAnimation *a : animations)
+ d->m_duration = qMax(d->m_duration, a->duration());
+}
+
+/*!
+ Adds new \a animation to the group.
+ */
+void QAnimationGroup::addAnimation(Qt3DAnimation::QAbstractAnimation *animation)
+{
+ Q_D(QAnimationGroup);
+ if (!d->m_animations.contains(animation)) {
+ d->m_animations.push_back(animation);
+ d->m_duration = qMax(d->m_duration, animation->duration());
+ }
+}
+
+/*!
+ Removes \a animation from the group.
+ */
+void QAnimationGroup::removeAnimation(Qt3DAnimation::QAbstractAnimation *animation)
+{
+ Q_D(QAnimationGroup);
+ if (!d->m_animations.contains(animation)) {
+ d->m_animations.removeAll(animation);
+ if (qFuzzyCompare(d->m_duration, animation->duration())) {
+ d->m_duration = 0.0f;
+ for (const Qt3DAnimation::QAbstractAnimation *a : d->m_animations)
+ d->m_duration = qMax(d->m_duration, a->duration());
+ }
+ }
+}
+
+void QAnimationGroup::setPosition(float position)
+{
+ Q_D(QAnimationGroup);
+ if (!qFuzzyCompare(d->m_position, position)) {
+ d->updatePosition(position);
+ emit positionChanged(position);
+ }
+}
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
diff --git a/src/animation/frontend/qanimationgroup.h b/src/animation/frontend/qanimationgroup.h
new file mode 100644
index 000000000..1e23c61ee
--- /dev/null
+++ b/src/animation/frontend/qanimationgroup.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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_QANIMATIONGROUP_H
+#define QT3DANIMATION_QANIMATIONGROUP_H
+
+#include <qobject.h>
+
+#include <Qt3DAnimation/qabstractanimation.h>
+
+#include <Qt3DAnimation/qt3danimation_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QAnimationGroupPrivate;
+
+class QT3DANIMATIONSHARED_EXPORT QAnimationGroup : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+ Q_PROPERTY(float position READ position WRITE setPosition NOTIFY positionChanged)
+ Q_PROPERTY(float duration READ duration NOTIFY durationChanged)
+
+public:
+ explicit QAnimationGroup(QObject *parent = nullptr);
+
+ QString name() const;
+ QVector<Qt3DAnimation::QAbstractAnimation *> animationList();
+ float position() const;
+ float duration() const;
+
+ void setAnimations(const QVector<Qt3DAnimation::QAbstractAnimation *> &animations);
+ void addAnimation(Qt3DAnimation::QAbstractAnimation *animation);
+ void removeAnimation(Qt3DAnimation::QAbstractAnimation *animation);
+
+public Q_SLOTS:
+ void setName(const QString &name);
+ void setPosition(float position);
+
+Q_SIGNALS:
+ void nameChanged(const QString &name);
+ void positionChanged(float position);
+ void durationChanged(float duration);
+
+private:
+
+ Q_DECLARE_PRIVATE(QAnimationGroup)
+};
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QANIMATIONGROUP_H
diff --git a/src/animation/frontend/qanimationgroup_p.h b/src/animation/frontend/qanimationgroup_p.h
new file mode 100644
index 000000000..1e13952aa
--- /dev/null
+++ b/src/animation/frontend/qanimationgroup_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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_QANIMATIONGROUP_P_H
+#define QT3DANIMATION_QANIMATIONGROUP_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 <private/qobject_p.h>
+#include <Qt3DAnimation/QAnimationGroup>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QAnimationGroupPrivate : public QObjectPrivate
+{
+public:
+ QAnimationGroupPrivate();
+
+ QString m_name;
+ QVector<Qt3DAnimation::QAbstractAnimation *> m_animations;
+ float m_position;
+ float m_duration;
+
+ void updatePosition(float position);
+
+ Q_DECLARE_PUBLIC(QAnimationGroup)
+};
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QANIMATIONGROUP_P_H
diff --git a/src/animation/frontend/qblendedclipanimator.cpp b/src/animation/frontend/qblendedclipanimator.cpp
index 8e0897b5c..e6b127bf1 100644
--- a/src/animation/frontend/qblendedclipanimator.cpp
+++ b/src/animation/frontend/qblendedclipanimator.cpp
@@ -46,21 +46,219 @@ QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
QBlendedClipAnimatorPrivate::QBlendedClipAnimatorPrivate()
- : Qt3DCore::QComponentPrivate()
+ : Qt3DAnimation::QAbstractClipAnimatorPrivate()
, m_blendTreeRoot(nullptr)
- , m_mapper(nullptr)
- , m_running(false)
- , m_loops(1)
{
}
+/*!
+ \qmltype BlendedClipAnimator
+ \instantiates Qt3DAnimation::QBlendedClipAnimator
+ \inqmlmodule Qt3D.Animation
+ \since 5.9
+
+ \brief BlendedClipAnimator is a component providing animation playback capabilities of a tree
+ of blend nodes.
+
+ 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.
+
+ 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
+ \since 5.9
+
+ \brief QBlendedClipAnimator is a component providing animation playback capabilities of a tree
+ of blend nodes.
+
+ 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.
+
+*/
QBlendedClipAnimator::QBlendedClipAnimator(Qt3DCore::QNode *parent)
- : Qt3DCore::QComponent(*new QBlendedClipAnimatorPrivate, parent)
+ : Qt3DAnimation::QAbstractClipAnimator(*new QBlendedClipAnimatorPrivate, parent)
{
}
+/*! \internal */
QBlendedClipAnimator::QBlendedClipAnimator(QBlendedClipAnimatorPrivate &dd, Qt3DCore::QNode *parent)
- : Qt3DCore::QComponent(dd, parent)
+ : Qt3DAnimation::QAbstractClipAnimator(dd, parent)
{
}
@@ -68,28 +266,23 @@ QBlendedClipAnimator::~QBlendedClipAnimator()
{
}
-QAbstractClipBlendNode *QBlendedClipAnimator::blendTree() const
-{
- Q_D(const QBlendedClipAnimator);
- return d->m_blendTreeRoot;
-}
+/*!
+ \qmlproperty AbstractClipBlendNode blendTree
-bool QBlendedClipAnimator::isRunning() const
-{
- Q_D(const QBlendedClipAnimator);
- return d->m_running;
-}
+ This property holds the root of the animation blend tree that will be evaluated before being
+ interpolated by the animator.
+*/
-QChannelMapper *QBlendedClipAnimator::channelMapper() const
-{
- Q_D(const QBlendedClipAnimator);
- return d->m_mapper;
-}
+/*!
+ \property blendTree
-int QBlendedClipAnimator::loops() const
+ 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);
- return d->m_loops;
+ return d->m_blendTreeRoot;
}
void QBlendedClipAnimator::setBlendTree(QAbstractClipBlendNode *blendTree)
@@ -112,45 +305,7 @@ void QBlendedClipAnimator::setBlendTree(QAbstractClipBlendNode *blendTree)
emit blendTreeChanged(blendTree);
}
-void QBlendedClipAnimator::setRunning(bool running)
-{
- Q_D(QBlendedClipAnimator);
- if (d->m_running == running)
- return;
-
- d->m_running = running;
- emit runningChanged(running);
-}
-
-void QBlendedClipAnimator::setLoops(int loops)
-{
- Q_D(QBlendedClipAnimator);
- if (d->m_loops == loops)
- return;
-
- d->m_loops = loops;
- emit loopsChanged(loops);
-}
-
-
-void QBlendedClipAnimator::setChannelMapper(QChannelMapper *mapping)
-{
- Q_D(QBlendedClipAnimator);
- if (d->m_mapper == mapping)
- return;
-
- if (d->m_mapper)
- d->unregisterDestructionHelper(d->m_mapper);
-
- if (mapping && !mapping->parent())
- mapping->setParent(this);
- d->m_mapper = mapping;
-
- if (d->m_mapper)
- d->registerDestructionHelper(d->m_mapper, &QBlendedClipAnimator::setChannelMapper, d->m_mapper);
- emit channelMapperChanged(mapping);
-}
-
+/*! \internal */
Qt3DCore::QNodeCreatedChangeBasePtr QBlendedClipAnimator::createNodeCreationChange() const
{
auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QBlendedClipAnimatorData>::create(this);
diff --git a/src/animation/frontend/qblendedclipanimator.h b/src/animation/frontend/qblendedclipanimator.h
index be1189f4f..c227a05cc 100644
--- a/src/animation/frontend/qblendedclipanimator.h
+++ b/src/animation/frontend/qblendedclipanimator.h
@@ -41,47 +41,34 @@
#define QT3DANIMATION_QBLENDEDCLIPANIMATOR_H
#include <Qt3DAnimation/qt3danimation_global.h>
-#include <Qt3DCore/qcomponent.h>
+#include <Qt3DAnimation/qabstractclipanimator.h>
QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
-class QChannelMapper;
class QAbstractClipBlendNode;
class QBlendedClipAnimatorPrivate;
-class QT3DANIMATIONSHARED_EXPORT QBlendedClipAnimator : public Qt3DCore::QComponent
+class QT3DANIMATIONSHARED_EXPORT QBlendedClipAnimator : public Qt3DAnimation::QAbstractClipAnimator
{
Q_OBJECT
Q_PROPERTY(Qt3DAnimation::QAbstractClipBlendNode *blendTree READ blendTree WRITE setBlendTree NOTIFY blendTreeChanged)
- Q_PROPERTY(Qt3DAnimation::QChannelMapper *channelMapper READ channelMapper WRITE setChannelMapper NOTIFY channelMapperChanged)
- Q_PROPERTY(int loops READ loops WRITE setLoops NOTIFY loopsChanged)
- Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
public:
explicit QBlendedClipAnimator(Qt3DCore::QNode *parent = nullptr);
~QBlendedClipAnimator();
- bool isRunning() const;
- Qt3DAnimation::QChannelMapper *channelMapper() const;
QAbstractClipBlendNode *blendTree() const;
- int loops() const;
public Q_SLOTS:
- void setRunning(bool running);
- void setChannelMapper(QChannelMapper *channelMapper);
void setBlendTree(QAbstractClipBlendNode * blendTree);
- void setLoops(int loops);
Q_SIGNALS:
void blendTreeChanged(QAbstractClipBlendNode * blendTree);
- void runningChanged(bool running);
- void channelMapperChanged(QChannelMapper *channelMapper);
- void loopsChanged(int loops);
protected:
- QBlendedClipAnimator(QBlendedClipAnimatorPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+ explicit QBlendedClipAnimator(QBlendedClipAnimatorPrivate &dd, Qt3DCore::QNode *parent = nullptr);
private:
Q_DECLARE_PRIVATE(QBlendedClipAnimator)
diff --git a/src/animation/frontend/qblendedclipanimator_p.h b/src/animation/frontend/qblendedclipanimator_p.h
index 47a8bbfd5..e874a528d 100644
--- a/src/animation/frontend/qblendedclipanimator_p.h
+++ b/src/animation/frontend/qblendedclipanimator_p.h
@@ -51,33 +51,26 @@
// We mean it.
//
-#include <Qt3DCore/private/qcomponent_p.h>
+#include <Qt3DAnimation/private/qabstractclipanimator_p.h>
QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
class QAbstractClipBlendNode;
-class QChannelMapper;
-class QBlendedClipAnimatorPrivate : public Qt3DCore::QComponentPrivate
+class QBlendedClipAnimatorPrivate : public Qt3DAnimation::QAbstractClipAnimatorPrivate
{
public:
QBlendedClipAnimatorPrivate();
Q_DECLARE_PUBLIC(QBlendedClipAnimator)
QAbstractClipBlendNode *m_blendTreeRoot;
- QChannelMapper *m_mapper;
- bool m_running;
- int m_loops;
};
-struct QBlendedClipAnimatorData
+struct QBlendedClipAnimatorData : public QAbstractClipAnimatorData
{
Qt3DCore::QNodeId blendTreeRootId;
- Qt3DCore::QNodeId mapperId;
- bool running;
- int loops;
};
} // namespace Qt3DAnimation
diff --git a/src/animation/frontend/qchannel.cpp b/src/animation/frontend/qchannel.cpp
new file mode 100644
index 000000000..9c74fad09
--- /dev/null
+++ b/src/animation/frontend/qchannel.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qchannel.h"
+
+#include <QtCore/qvector.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QChannelPrivate
+{
+public:
+ QVector<QChannelComponent> m_channelComponents;
+ QString m_name;
+};
+
+QChannel::QChannel()
+ : d(new QChannelPrivate)
+{
+}
+
+QChannel::QChannel(const QString &name)
+ : d(new QChannelPrivate)
+{
+ d->m_name = name;
+}
+
+QChannel::QChannel(const QChannel &rhs)
+ : d(new QChannelPrivate)
+{
+ *d = *(rhs.d);
+}
+
+QChannel &QChannel::operator=(const QChannel &rhs)
+{
+ if (this != &rhs)
+ *d = *(rhs.d);
+ return *this;
+}
+
+QChannel::~QChannel()
+{
+}
+
+void QChannel::setName(const QString &name)
+{
+ d->m_name = name;
+}
+
+QString QChannel::name() const
+{
+ return d->m_name;
+}
+
+int QChannel::channelComponentCount() const
+{
+ return d->m_channelComponents.size();
+}
+
+void QChannel::appendChannelComponent(const QChannelComponent &component)
+{
+ d->m_channelComponents.append(component);
+}
+
+void QChannel::insertChannelComponent(int index, const QChannelComponent &component)
+{
+ d->m_channelComponents.insert(index, component);
+}
+
+void QChannel::removeChannelComponent(int index)
+{
+ d->m_channelComponents.remove(index);
+}
+
+void QChannel::clearChannelComponents()
+{
+ d->m_channelComponents.clear();
+}
+
+QChannel::const_iterator QChannel::begin() const Q_DECL_NOTHROW
+{
+ return d->m_channelComponents.begin();
+}
+
+QChannel::const_iterator QChannel::end() const Q_DECL_NOTHROW
+{
+ return d->m_channelComponents.end();
+}
+
+bool operator==(const QChannel &lhs, const QChannel &rhs) Q_DECL_NOTHROW
+{
+ return lhs.d->m_name == rhs.d->m_name &&
+ lhs.d->m_channelComponents == rhs.d->m_channelComponents;
+}
+
+bool operator!=(const QChannel &lhs, const QChannel &rhs) Q_DECL_NOTHROW
+{
+ return lhs.d->m_name != rhs.d->m_name ||
+ lhs.d->m_channelComponents != rhs.d->m_channelComponents;
+}
+
+} // namespace Qt3DAnimation
+
+QT_END_NAMESPACE
diff --git a/src/animation/frontend/qchannel.h b/src/animation/frontend/qchannel.h
new file mode 100644
index 000000000..b94780689
--- /dev/null
+++ b/src/animation/frontend/qchannel.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DANIMATION_QCHANNEL_H
+#define QT3DANIMATION_QCHANNEL_H
+
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qstring.h>
+#include <Qt3DAnimation/qt3danimation_global.h>
+#include <Qt3DAnimation/qchannelcomponent.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QChannelPrivate;
+
+class QT3DANIMATIONSHARED_EXPORT QChannel
+{
+public:
+ QChannel();
+ explicit QChannel(const QString &name);
+ QChannel(const QChannel &);
+ QChannel &operator=(const QChannel &);
+ ~QChannel();
+
+ void setName(const QString &name);
+ QString name() const;
+
+ int channelComponentCount() const;
+ void appendChannelComponent(const QChannelComponent &component);
+ void insertChannelComponent(int index, const QChannelComponent &component);
+ void removeChannelComponent(int index);
+ void clearChannelComponents();
+
+ // Iterator API
+ typedef const QChannelComponent *const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ const_iterator begin() const Q_DECL_NOTHROW;
+ const_iterator cbegin() const Q_DECL_NOTHROW { return begin(); }
+ const_iterator end() const Q_DECL_NOTHROW;
+ const_iterator cend() const Q_DECL_NOTHROW { return end(); }
+ const_reverse_iterator rbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); }
+ const_reverse_iterator crbegin() const Q_DECL_NOTHROW { return rbegin(); }
+ const_reverse_iterator rend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); }
+ const_reverse_iterator crend() const Q_DECL_NOTHROW { return rend(); }
+
+ friend bool operator==(const QChannel &,
+ const QChannel &) Q_DECL_NOTHROW;
+ friend bool operator!=(const QChannel &,
+ const QChannel &) Q_DECL_NOTHROW;
+
+private:
+ QScopedPointer<QChannelPrivate> d;
+};
+
+} // namespace Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QCHANNEL_H
diff --git a/src/animation/frontend/qchannelcomponent.cpp b/src/animation/frontend/qchannelcomponent.cpp
new file mode 100644
index 000000000..1ecc5520c
--- /dev/null
+++ b/src/animation/frontend/qchannelcomponent.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qchannelcomponent.h"
+
+#include <QtCore/qvector.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QChannelComponentPrivate
+{
+public:
+ QVector<QKeyFrame> m_keyFrames;
+ QString m_name;
+};
+
+QChannelComponent::QChannelComponent()
+ : d(new QChannelComponentPrivate)
+{
+}
+
+QChannelComponent::QChannelComponent(const QString &name)
+ : d(new QChannelComponentPrivate)
+{
+ d->m_name = name;
+}
+
+QChannelComponent::QChannelComponent(const QChannelComponent &rhs)
+ : d(new QChannelComponentPrivate)
+{
+ *d = *(rhs.d);
+}
+
+QChannelComponent &QChannelComponent::operator=(const QChannelComponent &rhs)
+{
+ if (this != &rhs)
+ *d = *(rhs.d);
+ return *this;
+}
+
+QChannelComponent::~QChannelComponent()
+{
+}
+
+void QChannelComponent::setName(const QString &name)
+{
+ d->m_name = name;
+}
+
+QString QChannelComponent::name() const
+{
+ return d->m_name;
+}
+
+int QChannelComponent::keyFrameCount() const
+{
+ return d->m_keyFrames.size();
+}
+
+void QChannelComponent::appendKeyFrame(const QKeyFrame &kf)
+{
+ d->m_keyFrames.append(kf);
+}
+
+void QChannelComponent::insertKeyFrame(int index, const QKeyFrame &kf)
+{
+ d->m_keyFrames.insert(index, kf);
+}
+
+void QChannelComponent::removeKeyFrame(int index)
+{
+ d->m_keyFrames.remove(index);
+}
+
+void QChannelComponent::clearKeyFrames()
+{
+ d->m_keyFrames.clear();
+}
+
+QChannelComponent::const_iterator QChannelComponent::begin() const Q_DECL_NOTHROW
+{
+ return d->m_keyFrames.begin();
+}
+
+QChannelComponent::const_iterator QChannelComponent::end() const Q_DECL_NOTHROW
+{
+ return d->m_keyFrames.end();
+}
+
+bool operator==(const QChannelComponent &lhs, const QChannelComponent &rhs) Q_DECL_NOTHROW
+{
+ return lhs.d->m_name == rhs.d->m_name &&
+ lhs.d->m_keyFrames == rhs.d->m_keyFrames;
+}
+
+bool operator!=(const QChannelComponent &lhs, const QChannelComponent &rhs) Q_DECL_NOTHROW
+{
+ return lhs.d->m_name != rhs.d->m_name ||
+ lhs.d->m_keyFrames != rhs.d->m_keyFrames;
+}
+
+} // namespace Qt3DAnimation
+
+QT_END_NAMESPACE
diff --git a/src/animation/frontend/qchannelcomponent.h b/src/animation/frontend/qchannelcomponent.h
new file mode 100644
index 000000000..922073a85
--- /dev/null
+++ b/src/animation/frontend/qchannelcomponent.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DANIMATION_QCHANNELCOMPONENT_H
+#define QT3DANIMATION_QCHANNELCOMPONENT_H
+
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qstring.h>
+#include <Qt3DAnimation/qt3danimation_global.h>
+#include <Qt3DAnimation/qkeyframe.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QChannelComponentPrivate;
+
+class QT3DANIMATIONSHARED_EXPORT QChannelComponent
+{
+public:
+ QChannelComponent();
+ explicit QChannelComponent(const QString &name);
+ QChannelComponent(const QChannelComponent &);
+ QChannelComponent &operator=(const QChannelComponent &);
+ ~QChannelComponent();
+
+ void setName(const QString &name);
+ QString name() const;
+
+ int keyFrameCount() const;
+ void appendKeyFrame(const QKeyFrame &kf);
+ void insertKeyFrame(int index, const QKeyFrame &kf);
+ void removeKeyFrame(int index);
+ void clearKeyFrames();
+
+ // Iterator API
+ typedef const QKeyFrame *const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ const_iterator begin() const Q_DECL_NOTHROW;
+ const_iterator cbegin() const Q_DECL_NOTHROW { return begin(); }
+ const_iterator end() const Q_DECL_NOTHROW;
+ const_iterator cend() const Q_DECL_NOTHROW { return end(); }
+ const_reverse_iterator rbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); }
+ const_reverse_iterator crbegin() const Q_DECL_NOTHROW { return rbegin(); }
+ const_reverse_iterator rend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); }
+ const_reverse_iterator crend() const Q_DECL_NOTHROW { return rend(); }
+
+ friend bool operator==(const QChannelComponent &,
+ const QChannelComponent &) Q_DECL_NOTHROW;
+ friend bool operator!=(const QChannelComponent &,
+ const QChannelComponent &) Q_DECL_NOTHROW;
+
+private:
+ QScopedPointer<QChannelComponentPrivate> d;
+};
+
+} // namespace Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QCHANNELCOMPONENT_H
diff --git a/src/animation/frontend/qchannelmapper.h b/src/animation/frontend/qchannelmapper.h
index 399d92d5d..14319f29b 100644
--- a/src/animation/frontend/qchannelmapper.h
+++ b/src/animation/frontend/qchannelmapper.h
@@ -60,7 +60,7 @@ public:
QVector<QChannelMapping *> mappings() const;
protected:
- QChannelMapper(QChannelMapperPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+ explicit QChannelMapper(QChannelMapperPrivate &dd, Qt3DCore::QNode *parent = nullptr);
private:
Q_DECLARE_PRIVATE(QChannelMapper)
diff --git a/src/animation/frontend/qchannelmapping.h b/src/animation/frontend/qchannelmapping.h
index 0c4ca07f4..d768298fe 100644
--- a/src/animation/frontend/qchannelmapping.h
+++ b/src/animation/frontend/qchannelmapping.h
@@ -72,7 +72,7 @@ Q_SIGNALS:
void propertyChanged(QString property);
protected:
- QChannelMapping(QChannelMappingPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+ explicit QChannelMapping(QChannelMappingPrivate &dd, Qt3DCore::QNode *parent = nullptr);
private:
Q_DECLARE_PRIVATE(QChannelMapping)
diff --git a/src/animation/frontend/qclipanimator.cpp b/src/animation/frontend/qclipanimator.cpp
index e6c06c989..eb6c80aee 100644
--- a/src/animation/frontend/qclipanimator.cpp
+++ b/src/animation/frontend/qclipanimator.cpp
@@ -39,7 +39,7 @@
#include "qclipanimator.h"
#include "qclipanimator_p.h"
-#include <Qt3DAnimation/qanimationclip.h>
+#include <Qt3DAnimation/qabstractanimationclip.h>
#include <Qt3DAnimation/qchannelmapper.h>
QT_BEGIN_NAMESPACE
@@ -47,21 +47,66 @@ QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
QClipAnimatorPrivate::QClipAnimatorPrivate()
- : Qt3DCore::QComponentPrivate()
+ : Qt3DAnimation::QAbstractClipAnimatorPrivate()
, m_clip(nullptr)
- , m_mapper(nullptr)
- , m_running(false)
- , m_loops(1)
{
}
+/*!
+ \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)
- : Qt3DCore::QComponent(*new QClipAnimatorPrivate, parent)
+ : Qt3DAnimation::QAbstractClipAnimator(*new QClipAnimatorPrivate, parent)
{
}
+/*! \internal */
QClipAnimator::QClipAnimator(QClipAnimatorPrivate &dd, Qt3DCore::QNode *parent)
- : Qt3DCore::QComponent(dd, parent)
+ : Qt3DAnimation::QAbstractClipAnimator(dd, parent)
{
}
@@ -69,31 +114,26 @@ QClipAnimator::~QClipAnimator()
{
}
-QAnimationClip *QClipAnimator::clip() const
-{
- Q_D(const QClipAnimator);
- return d->m_clip;
-}
+/*!
+ \qmlproperty AbstractAnimationClip clip
-bool QClipAnimator::isRunning() const
-{
- Q_D(const QClipAnimator);
- return d->m_running;
-}
+ 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.
+*/
-QChannelMapper *QClipAnimator::channelMapper() const
-{
- Q_D(const QClipAnimator);
- return d->m_mapper;
-}
+/*!
+ \property clip
-int QClipAnimator::loops() const
+ 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);
- return d->m_loops;
+ return d->m_clip;
}
-void QClipAnimator::setClip(QAnimationClip *clip)
+void QClipAnimator::setClip(QAbstractAnimationClip *clip)
{
Q_D(QClipAnimator);
if (d->m_clip == clip)
@@ -112,45 +152,7 @@ void QClipAnimator::setClip(QAnimationClip *clip)
emit clipChanged(clip);
}
-void QClipAnimator::setRunning(bool running)
-{
- Q_D(QClipAnimator);
- if (d->m_running == running)
- return;
-
- d->m_running = running;
- emit runningChanged(running);
-}
-
-void QClipAnimator::setChannelMapper(QChannelMapper *mapping)
-{
- Q_D(QClipAnimator);
- if (d->m_mapper == mapping)
- return;
-
- if (d->m_mapper)
- d->unregisterDestructionHelper(d->m_mapper);
-
- if (mapping && !mapping->parent())
- mapping->setParent(this);
- d->m_mapper = mapping;
-
- // Ensures proper bookkeeping
- if (d->m_mapper)
- d->registerDestructionHelper(d->m_mapper, &QClipAnimator::setChannelMapper, d->m_mapper);
- emit channelMapperChanged(mapping);
-}
-
-void QClipAnimator::setLoops(int loops)
-{
- Q_D(QClipAnimator);
- if (d->m_loops == loops)
- return;
-
- d->m_loops = loops;
- emit loopsChanged(loops);
-}
-
+/*! \internal */
Qt3DCore::QNodeCreatedChangeBasePtr QClipAnimator::createNodeCreationChange() const
{
auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QClipAnimatorData>::create(this);
diff --git a/src/animation/frontend/qclipanimator.h b/src/animation/frontend/qclipanimator.h
index 176d6fc0c..311ac4ab0 100644
--- a/src/animation/frontend/qclipanimator.h
+++ b/src/animation/frontend/qclipanimator.h
@@ -41,44 +41,32 @@
#define QT3DANIMATION_QCLIPANIMATOR_H
#include <Qt3DAnimation/qt3danimation_global.h>
-#include <Qt3DCore/qcomponent.h>
+#include <Qt3DAnimation/qabstractclipanimator.h>
QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
-class QAnimationClip;
+class QAbstractAnimationClip;
class QChannelMapper;
class QClipAnimatorPrivate;
-class QT3DANIMATIONSHARED_EXPORT QClipAnimator : public Qt3DCore::QComponent
+class QT3DANIMATIONSHARED_EXPORT QClipAnimator : public Qt3DAnimation::QAbstractClipAnimator
{
Q_OBJECT
- Q_PROPERTY(Qt3DAnimation::QAnimationClip *clip READ clip WRITE setClip NOTIFY clipChanged)
- Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
- Q_PROPERTY(int loops READ loops WRITE setLoops NOTIFY loopsChanged)
- Q_PROPERTY(Qt3DAnimation::QChannelMapper *channelMapper READ channelMapper WRITE setChannelMapper NOTIFY channelMapperChanged)
+ Q_PROPERTY(Qt3DAnimation::QAbstractAnimationClip *clip READ clip WRITE setClip NOTIFY clipChanged)
public:
explicit QClipAnimator(Qt3DCore::QNode *parent = nullptr);
~QClipAnimator();
- Qt3DAnimation::QAnimationClip *clip() const;
- bool isRunning() const;
- Qt3DAnimation::QChannelMapper *channelMapper() const;
- int loops() const;
+ Qt3DAnimation::QAbstractAnimationClip *clip() const;
public Q_SLOTS:
- void setClip(Qt3DAnimation::QAnimationClip *clip);
- void setRunning(bool running);
- void setChannelMapper(Qt3DAnimation::QChannelMapper *channelMapper);
- void setLoops(int loops);
+ void setClip(Qt3DAnimation::QAbstractAnimationClip *clip);
Q_SIGNALS:
- void clipChanged(Qt3DAnimation::QAnimationClip *clip);
- void runningChanged(bool running);
- void channelMapperChanged(Qt3DAnimation::QChannelMapper *channelMapper);
- void loopsChanged(int loops);
+ void clipChanged(Qt3DAnimation::QAbstractAnimationClip *clip);
protected:
QClipAnimator(QClipAnimatorPrivate &dd, Qt3DCore::QNode *parent = nullptr);
diff --git a/src/animation/frontend/qclipanimator_p.h b/src/animation/frontend/qclipanimator_p.h
index 7bb9c526f..fe40ed442 100644
--- a/src/animation/frontend/qclipanimator_p.h
+++ b/src/animation/frontend/qclipanimator_p.h
@@ -51,34 +51,27 @@
// We mean it.
//
-#include <Qt3DCore/private/qcomponent_p.h>
-#include <Qt3DAnimation/qanimationclip.h>
+#include <Qt3DAnimation/private/qabstractclipanimator_p.h>
QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
-class QChannelMapper;
+class QAbstractAnimationClip;
-class QClipAnimatorPrivate : public Qt3DCore::QComponentPrivate
+class QClipAnimatorPrivate : public Qt3DAnimation::QAbstractClipAnimatorPrivate
{
public:
QClipAnimatorPrivate();
Q_DECLARE_PUBLIC(QClipAnimator)
- QAnimationClip *m_clip;
- Qt3DAnimation::QChannelMapper *m_mapper;
- bool m_running;
- int m_loops;
+ QAbstractAnimationClip *m_clip;
};
-struct QClipAnimatorData
+struct QClipAnimatorData : public QAbstractClipAnimatorData
{
Qt3DCore::QNodeId clipId;
- Qt3DCore::QNodeId mapperId;
- bool running;
- int loops;
};
} // namespace Qt3DAnimation
diff --git a/src/animation/frontend/qclipblendnodecreatedchange.cpp b/src/animation/frontend/qclipblendnodecreatedchange.cpp
index 9e9104066..9251442bb 100644
--- a/src/animation/frontend/qclipblendnodecreatedchange.cpp
+++ b/src/animation/frontend/qclipblendnodecreatedchange.cpp
@@ -37,7 +37,7 @@
#include "qclipblendnodecreatedchange.h"
#include "qclipblendnodecreatedchange_p.h"
#include <Qt3DAnimation/qabstractclipblendnode.h>
-#include <Qt3DAnimation/qanimationclip.h>
+#include <Qt3DAnimation/qabstractanimationclip.h>
QT_BEGIN_NAMESPACE
@@ -45,8 +45,6 @@ namespace Qt3DAnimation {
QClipBlendNodeCreatedChangeBasePrivate::QClipBlendNodeCreatedChangeBasePrivate(const QAbstractClipBlendNode *node)
: Qt3DCore::QNodeCreatedChangeBasePrivate(node)
- , m_parentClipBlendNodeId(Qt3DCore::qIdForNode(node->parentClipBlendNode()))
- , m_clips(Qt3DCore::qIdsForNodes(node->clips()))
{
}
@@ -59,19 +57,6 @@ QClipBlendNodeCreatedChangeBase::~QClipBlendNodeCreatedChangeBase()
{
}
-Qt3DCore::QNodeId QClipBlendNodeCreatedChangeBase::parentClipBlendNodeId() const
-{
- Q_D(const QClipBlendNodeCreatedChangeBase);
- return d->m_parentClipBlendNodeId;
-}
-
-Qt3DCore::QNodeIdVector QClipBlendNodeCreatedChangeBase::clips() const
-{
- Q_D(const QClipBlendNodeCreatedChangeBase);
- return d->m_clips;
-}
-
-
} // Qt3DAnimation
QT_END_NAMESPACE
diff --git a/src/animation/frontend/qclipblendnodecreatedchange.h b/src/animation/frontend/qclipblendnodecreatedchange.h
index b07d080bd..01f17d7ca 100644
--- a/src/animation/frontend/qclipblendnodecreatedchange.h
+++ b/src/animation/frontend/qclipblendnodecreatedchange.h
@@ -53,9 +53,6 @@ public:
explicit QClipBlendNodeCreatedChangeBase(const QAbstractClipBlendNode *node);
~QClipBlendNodeCreatedChangeBase();
- Qt3DCore::QNodeId parentClipBlendNodeId() const;
- Qt3DCore::QNodeIdVector clips() const;
-
private:
Q_DECLARE_PRIVATE(QClipBlendNodeCreatedChangeBase)
};
diff --git a/src/animation/frontend/qclipblendnodecreatedchange_p.h b/src/animation/frontend/qclipblendnodecreatedchange_p.h
index 0b853cd96..31342d3a8 100644
--- a/src/animation/frontend/qclipblendnodecreatedchange_p.h
+++ b/src/animation/frontend/qclipblendnodecreatedchange_p.h
@@ -60,9 +60,6 @@ class QClipBlendNodeCreatedChangeBasePrivate : public Qt3DCore::QNodeCreatedChan
{
public:
QClipBlendNodeCreatedChangeBasePrivate(const QAbstractClipBlendNode *node);
-
- Qt3DCore::QNodeId m_parentClipBlendNodeId;
- Qt3DCore::QNodeIdVector m_clips;
};
} // Qt3DAnimation
diff --git a/src/animation/frontend/qclipblendvalue.cpp b/src/animation/frontend/qclipblendvalue.cpp
new file mode 100644
index 000000000..d329f6722
--- /dev/null
+++ b/src/animation/frontend/qclipblendvalue.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qclipblendvalue.h"
+#include "qclipblendvalue_p.h"
+#include <Qt3DAnimation/qabstractanimationclip.h>
+#include <Qt3DAnimation/qclipblendnodecreatedchange.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+QClipBlendValuePrivate::QClipBlendValuePrivate()
+ : QAbstractClipBlendNodePrivate()
+ , m_clip(nullptr)
+{
+}
+
+QClipBlendValue::QClipBlendValue(Qt3DCore::QNode *parent)
+ : QAbstractClipBlendNode(*new QClipBlendValuePrivate(), parent)
+{
+}
+
+QClipBlendValue::QClipBlendValue(Qt3DAnimation::QAbstractAnimationClip *clip,
+ Qt3DCore::QNode *parent)
+ : QAbstractClipBlendNode(*new QClipBlendValuePrivate(), parent)
+{
+ setClip(clip);
+}
+
+QClipBlendValue::QClipBlendValue(QClipBlendValuePrivate &dd, Qt3DCore::QNode *parent)
+ : QAbstractClipBlendNode(dd, parent)
+{
+}
+
+QClipBlendValue::~QClipBlendValue()
+{
+}
+
+Qt3DAnimation::QAbstractAnimationClip *QClipBlendValue::clip() const
+{
+ Q_D(const QClipBlendValue);
+ return d->m_clip;
+}
+
+void QClipBlendValue::setClip(Qt3DAnimation::QAbstractAnimationClip *clip)
+{
+ Q_D(QClipBlendValue);
+ if (d->m_clip == clip)
+ return;
+
+ if (d->m_clip)
+ d->unregisterDestructionHelper(d->m_clip);
+
+ if (clip && !clip->parent())
+ clip->setParent(this);
+ d->m_clip = clip;
+
+ // Ensures proper bookkeeping
+ if (d->m_clip)
+ d->registerDestructionHelper(d->m_clip, &QClipBlendValue::setClip, d->m_clip);
+ emit clipChanged(clip);
+}
+
+Qt3DCore::QNodeCreatedChangeBasePtr QClipBlendValue::createNodeCreationChange() const
+{
+ Q_D(const QClipBlendValue);
+ auto creationChange = QClipBlendNodeCreatedChangePtr<QClipBlendValueData>::create(this);
+ QClipBlendValueData &data = creationChange->data;
+ data.clipId = Qt3DCore::qIdForNode(d->m_clip);
+ return creationChange;
+}
+
+} // namespace Qt3DAnimation
+
+QT_END_NAMESPACE
diff --git a/src/animation/frontend/qclipblendvalue.h b/src/animation/frontend/qclipblendvalue.h
new file mode 100644
index 000000000..b18bfb57b
--- /dev/null
+++ b/src/animation/frontend/qclipblendvalue.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DANIMATION_QCLIPBLENDVALUE_H
+#define QT3DANIMATION_QCLIPBLENDVALUE_H
+
+#include <Qt3DAnimation/qt3danimation_global.h>
+#include <Qt3DAnimation/qabstractclipblendnode.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QClipBlendValuePrivate;
+
+class QT3DANIMATIONSHARED_EXPORT QClipBlendValue : public Qt3DAnimation::QAbstractClipBlendNode
+{
+ Q_OBJECT
+ Q_PROPERTY(Qt3DAnimation::QAbstractAnimationClip *clip READ clip WRITE setClip NOTIFY clipChanged)
+
+public:
+ explicit QClipBlendValue(Qt3DCore::QNode *parent = nullptr);
+ explicit QClipBlendValue(Qt3DAnimation::QAbstractAnimationClip *clip,
+ Qt3DCore::QNode *parent = nullptr);
+ ~QClipBlendValue();
+
+ Qt3DAnimation::QAbstractAnimationClip *clip() const;
+
+public Q_SLOTS:
+ void setClip(Qt3DAnimation::QAbstractAnimationClip *clip);
+
+Q_SIGNALS:
+ void clipChanged(Qt3DAnimation::QAbstractAnimationClip *clip);
+
+protected:
+ explicit QClipBlendValue(QClipBlendValuePrivate &dd, Qt3DCore::QNode *parent = nullptr);
+
+private:
+ Q_DECLARE_PRIVATE(QClipBlendValue)
+ Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const Q_DECL_OVERRIDE;
+};
+
+} // namespace Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QCLIPBLENDVALUE_H
diff --git a/src/animation/frontend/qconductedclipanimator.h b/src/animation/frontend/qclipblendvalue_p.h
index 4364f6774..7a397a1b8 100644
--- a/src/animation/frontend/qconductedclipanimator.h
+++ b/src/animation/frontend/qclipblendvalue_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
@@ -37,40 +37,44 @@
**
****************************************************************************/
-#ifndef QT3DANIMATION_QCONDUCTEDCLIPANIMATOR_H
-#define QT3DANIMATION_QCONDUCTEDCLIPANIMATOR_H
+#ifndef QT3DANIMATION_QCLIPBLENDNODE_P_H
+#define QT3DANIMATION_QCLIPBLENDNODE_P_H
-#include <Qt3DAnimation/qt3danimation_global.h>
-#include <Qt3DCore/qcomponent.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 <Qt3DAnimation/private/qabstractclipblendnode_p.h>
+#include <Qt3DAnimation/qclipblendvalue.h>
QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
-class QConductedClipAnimatorPrivate;
-
-class QT3DANIMATIONSHARED_EXPORT QConductedClipAnimator : public Qt3DCore::QComponent
+class QClipBlendValuePrivate : public QAbstractClipBlendNodePrivate
{
- Q_OBJECT
- // TODO: Add property declarations
public:
- explicit QConductedClipAnimator(Qt3DCore::QNode *parent = nullptr);
- ~QConductedClipAnimator();
-
-public Q_SLOTS:
+ QClipBlendValuePrivate();
-Q_SIGNALS:
+ Q_DECLARE_PUBLIC(QClipBlendValue)
-protected:
- QConductedClipAnimator(QConductedClipAnimatorPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+ Qt3DAnimation::QAbstractAnimationClip *m_clip;
+};
-private:
- Q_DECLARE_PRIVATE(QConductedClipAnimator)
- Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const Q_DECL_OVERRIDE;
+struct QClipBlendValueData
+{
+ Qt3DCore::QNodeId clipId;
};
} // namespace Qt3DAnimation
QT_END_NAMESPACE
-#endif // QT3DANIMATION_QCONDUCTEDCLIPANIMATOR_H
+#endif // QT3DANIMATION_QCLIPBLENDNODE_P_H
diff --git a/src/animation/frontend/qconductedclipanimator.cpp b/src/animation/frontend/qkeyframe.cpp
index 29bdefe37..b3d339bf4 100644
--- a/src/animation/frontend/qconductedclipanimator.cpp
+++ b/src/animation/frontend/qkeyframe.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
@@ -36,40 +36,13 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include "qconductedclipanimator.h"
-#include "qconductedclipanimator_p.h"
+
+#include "qkeyframe.h"
QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
-QConductedClipAnimatorPrivate::QConductedClipAnimatorPrivate()
- : Qt3DCore::QComponentPrivate()
-{
-}
-
-QConductedClipAnimator::QConductedClipAnimator(Qt3DCore::QNode *parent)
- : Qt3DCore::QComponent(*new QConductedClipAnimatorPrivate, parent)
-{
-}
-
-QConductedClipAnimator::QConductedClipAnimator(QConductedClipAnimatorPrivate &dd, Qt3DCore::QNode *parent)
- : Qt3DCore::QComponent(dd, parent)
-{
-}
-
-QConductedClipAnimator::~QConductedClipAnimator()
-{
-}
-
-Qt3DCore::QNodeCreatedChangeBasePtr QConductedClipAnimator::createNodeCreationChange() const
-{
- auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QConductedClipAnimatorData>::create(this);
- auto &data = creationChange->data;
- Q_D(const QConductedClipAnimator);
- // TODO: Send data members in creation change
- return creationChange;
-}
} // namespace Qt3DAnimation
diff --git a/src/animation/frontend/qkeyframe.h b/src/animation/frontend/qkeyframe.h
new file mode 100644
index 000000000..7eabbeb17
--- /dev/null
+++ b/src/animation/frontend/qkeyframe.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DANIMATION_QKEYFRAME_H
+#define QT3DANIMATION_QKEYFRAME_H
+
+#include <QtGui/qvector2d.h>
+#include <Qt3DAnimation/qt3danimation_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QT3DANIMATIONSHARED_EXPORT QKeyFrame
+{
+public:
+ enum InterpolationType : quint8 {
+ ConstantInterpolation,
+ LinearInterpolation,
+ BezierInterpolation
+ };
+
+ Q_DECL_CONSTEXPR QKeyFrame() Q_DECL_NOTHROW
+ : m_coordinates()
+ , m_leftControlPoint()
+ , m_rightControlPoint()
+ , m_interpolationType(BezierInterpolation)
+ {
+ }
+
+ Q_DECL_CONSTEXPR explicit QKeyFrame(QVector2D coords) Q_DECL_NOTHROW
+ : m_coordinates(coords)
+ , m_leftControlPoint()
+ , m_rightControlPoint()
+ , m_interpolationType(LinearInterpolation)
+ {
+ }
+
+ Q_DECL_CONSTEXPR explicit QKeyFrame(QVector2D coords,
+ QVector2D lh,
+ QVector2D rh) Q_DECL_NOTHROW
+ : m_coordinates(coords)
+ , m_leftControlPoint(lh)
+ , m_rightControlPoint(rh)
+ , m_interpolationType(BezierInterpolation)
+ {
+ }
+
+ void setCoordinates(QVector2D coords) Q_DECL_NOTHROW
+ {
+ m_coordinates = coords;
+ }
+
+ Q_DECL_CONSTEXPR QVector2D coordinates() const Q_DECL_NOTHROW
+ {
+ return m_coordinates;
+ }
+
+ void setLeftControlPoint(QVector2D lh) Q_DECL_NOTHROW
+ {
+ m_leftControlPoint = lh;
+ }
+
+ Q_DECL_CONSTEXPR QVector2D leftControlPoint() const Q_DECL_NOTHROW
+ {
+ return m_leftControlPoint;
+ }
+
+ void setRightControlPoint(QVector2D rh) Q_DECL_NOTHROW
+ {
+ m_rightControlPoint = rh;
+ }
+
+ Q_DECL_CONSTEXPR QVector2D rightControlPoint() const Q_DECL_NOTHROW
+ {
+ return m_rightControlPoint;
+ }
+
+ void setInterpolationType(InterpolationType interp) Q_DECL_NOTHROW
+ {
+ m_interpolationType = interp;
+ }
+
+ Q_DECL_CONSTEXPR InterpolationType interpolationType() const Q_DECL_NOTHROW
+ {
+ return m_interpolationType;
+ }
+
+ friend inline bool operator==(const QKeyFrame &, const QKeyFrame &) Q_DECL_NOTHROW;
+ friend inline bool operator!=(const QKeyFrame &, const QKeyFrame &) Q_DECL_NOTHROW;
+
+private:
+ QVector2D m_coordinates;
+ QVector2D m_leftControlPoint;
+ QVector2D m_rightControlPoint;
+ InterpolationType m_interpolationType;
+};
+
+QT3D_DECLARE_TYPEINFO(Qt3DAnimation, QKeyFrame, Q_PRIMITIVE_TYPE)
+
+inline bool operator==(const QKeyFrame &lhs, const QKeyFrame &rhs) Q_DECL_NOTHROW
+{
+ if (lhs.m_interpolationType != rhs.m_interpolationType)
+ return false;
+
+ if (lhs.m_interpolationType == QKeyFrame::BezierInterpolation) {
+ return lhs.m_coordinates == rhs.m_coordinates &&
+ lhs.m_leftControlPoint == rhs.m_leftControlPoint &&
+ lhs.m_rightControlPoint == rhs.m_rightControlPoint;
+ }
+
+ return lhs.m_coordinates == rhs.m_coordinates;
+}
+
+inline bool operator!=(const QKeyFrame &lhs, const QKeyFrame &rhs) Q_DECL_NOTHROW
+{
+ return !(lhs == rhs);
+}
+
+} // namespace Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QKEYFRAME_H
diff --git a/src/animation/frontend/qkeyframeanimation.cpp b/src/animation/frontend/qkeyframeanimation.cpp
new file mode 100644
index 000000000..597b34cee
--- /dev/null
+++ b/src/animation/frontend/qkeyframeanimation.cpp
@@ -0,0 +1,415 @@
+/****************************************************************************
+**
+** 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 "qkeyframeanimation.h"
+#include "Qt3DAnimation/private/qkeyframeanimation_p.h"
+
+#include <cmath>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+/*!
+ \class Qt3DAnimation::QKeyframeAnimation
+ \brief A class implementing simple keyframe animation to a QTransform
+ \inmodule Qt3DAnimation
+ \since 5.9
+ \inherits Qt3DAnimation::QAbstractAnimation
+
+ A Qt3DAnimation::QKeyframeAnimation class implements simple keyframe animation
+ that can be used to animate \l QTransform. The keyframes consists of multiple
+ timed QTransforms, which are interpolated and applied to the target \l QTransform.
+ \l QEasingCurve is used between keyframes to control the interpolator. RepeatMode
+ can be set for when the position set to the QKeyframeAnimation is below or above
+ the values defined in the keyframe positions.
+*/
+
+/*!
+ \qmltype KeyframeAnimation
+ \brief A type implementing simple keyframe animation to a Transform
+ \inqmlmodule Qt3D.Animation
+ \since 5.9
+ \inherits AbstractAnimation
+ \instantiates Qt3DAnimation::QKeyframeAnimation
+
+ A KeyframeAnimation type implements simple keyframe animation
+ that can be used to animate \l Transform. The keyframes consists of multiple
+ 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.
+*/
+
+/*!
+ \property Qt3DAnimation::QKeyframeAnimation::framePositions
+ Holds the positions of the keyframes. Each position in the list specifies the position
+ of the corresponding keyframe with the same index. The values must be in an ascending order.
+ Values can be positive or negative and do not have any predefined unit.
+*/
+/*!
+ \property Qt3DAnimation::QKeyframeAnimation::target
+ Holds the target QTransform the animation is applied to.
+*/
+/*!
+ \property Qt3DAnimation::QKeyframeAnimation::easing
+ Holds the easing curve of the interpolator between keyframes.
+*/
+/*!
+ \property Qt3DAnimation::QKeyframeAnimation::targetName
+ Holds the name of the target transform. This is a convenience property making it
+ easier to match the target transform to the keyframe animation. The name
+ is usually same as the name of the parent entity of the target transform, but
+ does not have to be.
+*/
+/*!
+ \property Qt3DAnimation::QKeyframeAnimation::startMode
+ Holds the repeat mode for the position values less than the first frame position.
+*/
+/*!
+ \property Qt3DAnimation::QKeyframeAnimation::endMode
+ Holds the repeat mode for the position values greater than the last frame position.
+*/
+/*!
+ \enum QKeyframeAnimation::RepeatMode
+
+ This enumeration specifies how position values outside keyframe values are handled.
+ \value None The animation is not applied to the target transform.
+ \value Constant The edge keyframe value is used.
+ \value Repeat The animation is repeated.
+*/
+/*!
+ \qmlproperty list<real> KeyframeAnimation::framePositions
+ Holds the positions of the keyframes. Each position in the list specifies the position
+ of the corresponding keyframe. The values must be in an ascending order. Values can
+ be positive or negative and do not have any predefined unit.
+*/
+/*!
+ \qmlproperty Transform KeyframeAnimation::target
+ Holds the target Transform the animation is applied to.
+*/
+/*!
+ \qmlproperty EasingCurve KeyframeAnimation::easing
+ Holds the easing curve of the interpolator between keyframes.
+*/
+/*!
+ \qmlproperty string KeyframeAnimation::targetName
+ Holds the name of the target transform. This is a convenience property making it
+ easier to match the target transform to the keyframe animation. The name
+ is usually same as the name of the parent entity of the target transform, but
+ does not have to be.
+*/
+/*!
+ \qmlproperty enumeration KeyframeAnimation::startMode
+ Holds the repeat mode for the position values less than the first frame position.
+ \list
+ \li None
+ \li Constant
+ \li Repeat
+ \endlist
+*/
+/*!
+ \qmlproperty enumeration KeyframeAnimation::endMode
+ Holds the repeat mode for the position values greater than the last frame position.
+ \list
+ \li None
+ \li Constant
+ \li Repeat
+ \endlist
+*/
+/*!
+ \qmlproperty list<Transform> KeyframeAnimation::keyframes
+ Holds the list of keyframes in the keyframe animation.
+*/
+
+QKeyframeAnimationPrivate::QKeyframeAnimationPrivate()
+ : QAbstractAnimationPrivate(QAbstractAnimation::KeyframeAnimation)
+ , m_target(nullptr)
+ , m_minposition(0.0f)
+ , m_maxposition(0.0f)
+ , m_startMode(QKeyframeAnimation::Constant)
+ , m_endMode(QKeyframeAnimation::Constant)
+{
+
+}
+
+/*!
+ Constructs an QKeyframeAnimation with \a parent.
+*/
+QKeyframeAnimation::QKeyframeAnimation(QObject *parent)
+ : QAbstractAnimation(*new QKeyframeAnimationPrivate(), parent)
+{
+ Q_D(QKeyframeAnimation);
+ d->m_positionConnection = QObject::connect(this, &QAbstractAnimation::positionChanged,
+ this, &QKeyframeAnimation::updateAnimation);
+}
+
+
+void QKeyframeAnimation::setFramePositions(const QVector<float> &positions)
+{
+ Q_D(QKeyframeAnimation);
+ d->m_framePositions = positions;
+ d->m_position = -1.0f;
+ if (d->m_framePositions.size() == 0) {
+ d->m_minposition = d->m_maxposition = 0.0f;
+ return;
+ }
+ d->m_minposition = d->m_framePositions.first();
+ d->m_maxposition = d->m_framePositions.last();
+ float lastPos = d->m_minposition;
+ for (float p : qAsConst(d->m_framePositions)) {
+ if (p < lastPos || p > d->m_maxposition)
+ qWarning() << "positions not ordered correctly";
+ lastPos = p;
+ }
+ setDuration(d->m_maxposition);
+}
+
+/*!
+ Sets the \a keyframes of the animation. Old keyframes are cleared.
+ */
+void QKeyframeAnimation::setKeyframes(const QVector<Qt3DCore::QTransform *> &keyframes)
+{
+ Q_D(QKeyframeAnimation);
+ d->m_keyframes = keyframes;
+}
+
+// slerp which allows long path
+QQuaternion lslerp(QQuaternion q1, QQuaternion q2, float t)
+{
+ QQuaternion ret;
+ // Handle the easy cases first.
+ if (t <= 0.0f)
+ return q1;
+ else if (t >= 1.0f)
+ return q2;
+
+ float cos = qBound(-1.0f, QQuaternion::dotProduct(q1, q2), 1.0f);
+ float angle = std::acos(cos);
+ float sin = std::sin(angle);
+ if (!qFuzzyIsNull(sin)) {
+ float a = std::sin((1.0 - t) * angle) / sin;
+ float b = std::sin(t * angle) / sin;
+ ret = (q1 * a + q2 * b).normalized();
+ } else {
+ ret = q1 * (1.0f-t) + q2 * t;
+ }
+ return ret;
+}
+
+void QKeyframeAnimationPrivate::calculateFrame(float position)
+{
+ if (m_target && m_framePositions.size() > 0
+ && m_keyframes.size() == m_framePositions.size()) {
+ if (position < m_minposition) {
+ if (m_startMode == QKeyframeAnimation::None) {
+ return;
+ } else if (m_startMode == QKeyframeAnimation::Constant) {
+ m_target->setRotation(m_keyframes.first()->rotation());
+ m_target->setScale3D(m_keyframes.first()->scale3D());
+ m_target->setTranslation(m_keyframes.first()->translation());
+ return;
+ } else {
+ // must be repeat
+ position = std::fmod(-(position - m_minposition), m_maxposition - m_minposition)
+ + m_minposition;
+ }
+ } else if (position >= m_maxposition) {
+ if (m_endMode == QKeyframeAnimation::None) {
+ return;
+ } else if (m_endMode == QKeyframeAnimation::Constant) {
+ m_target->setRotation(m_keyframes.last()->rotation());
+ m_target->setScale3D(m_keyframes.last()->scale3D());
+ m_target->setTranslation(m_keyframes.last()->translation());
+ return;
+ } else {
+ // must be repeat
+ position = std::fmod(position - m_minposition, m_maxposition - m_minposition)
+ + m_minposition;
+ }
+ }
+ if (position >= m_minposition && position < m_maxposition) {
+ for (int i = 0; i < m_framePositions.size() - 1; i++) {
+ if (position >= m_framePositions.at(i)
+ && position < m_framePositions.at(i+1)) {
+ float ip = (position - m_framePositions.at(i))
+ / (m_framePositions.at(i+1) - m_framePositions.at(i));
+ float eIp = m_easing.valueForProgress(ip);
+ float eIip = 1.0f - eIp;
+
+ Qt3DCore::QTransform *a = m_keyframes.at(i);
+ Qt3DCore::QTransform *b = m_keyframes.at(i+1);
+
+ QVector3D s = a->scale3D() * eIip + b->scale3D() * eIp;
+ QVector3D t = a->translation() * eIip + b->translation() * eIp;
+ QQuaternion r = QQuaternion::slerp(a->rotation(), b->rotation(), eIp);
+
+ m_target->setRotation(r);
+ m_target->setScale3D(s);
+ m_target->setTranslation(t);
+ return;
+ }
+ }
+ }
+ }
+}
+
+void QKeyframeAnimation::updateAnimation(float position)
+{
+ Q_D(QKeyframeAnimation);
+ d->calculateFrame(position);
+}
+
+QVector<float> QKeyframeAnimation::framePositions() const
+{
+ Q_D(const QKeyframeAnimation);
+ return d->m_framePositions;
+}
+
+/*!
+ Returns the list of keyframes.
+ */
+QVector<Qt3DCore::QTransform *> QKeyframeAnimation::keyframeList() const
+{
+ Q_D(const QKeyframeAnimation);
+ return d->m_keyframes;
+}
+
+void QKeyframeAnimation::setTarget(Qt3DCore::QTransform *target)
+{
+ Q_D(QKeyframeAnimation);
+ if (d->m_target != target) {
+ d->m_target = target;
+ emit targetChanged(d->m_target);
+ d->m_position = -1.0f;
+
+ if (target) {
+ d->m_baseScale = target->scale3D();
+ d->m_baseTranslation = target->translation();
+ d->m_baseRotation = target->rotation();
+ }
+ }
+}
+
+QKeyframeAnimation::RepeatMode QKeyframeAnimation::startMode() const
+{
+ Q_D(const QKeyframeAnimation);
+ return d->m_startMode;
+}
+
+QKeyframeAnimation::RepeatMode QKeyframeAnimation::endMode() const
+{
+ Q_D(const QKeyframeAnimation);
+ return d->m_endMode;
+}
+
+void QKeyframeAnimation::setEasing(const QEasingCurve &easing)
+{
+ Q_D(QKeyframeAnimation);
+ if (d->m_easing != easing) {
+ d->m_easing = easing;
+ emit easingChanged(easing);
+ }
+}
+
+void QKeyframeAnimation::setTargetName(const QString &name)
+{
+ Q_D(QKeyframeAnimation);
+ if (d->m_targetName != name) {
+ d->m_targetName = name;
+ emit targetNameChanged(name);
+ }
+}
+
+void QKeyframeAnimation::setStartMode(QKeyframeAnimation::RepeatMode mode)
+{
+ Q_D(QKeyframeAnimation);
+ if (d->m_startMode != mode) {
+ d->m_startMode = mode;
+ emit startModeChanged(mode);
+ }
+}
+
+void QKeyframeAnimation::setEndMode(QKeyframeAnimation::RepeatMode mode)
+{
+ Q_D(QKeyframeAnimation);
+ if (mode != d->m_endMode) {
+ d->m_endMode = mode;
+ emit endModeChanged(mode);
+ }
+}
+
+/*!
+ Adds new \a keyframe at the end of the animation. The QTransform can
+ be added to the animation multiple times.
+ */
+void QKeyframeAnimation::addKeyframe(Qt3DCore::QTransform *keyframe)
+{
+ Q_D(QKeyframeAnimation);
+ d->m_keyframes.push_back(keyframe);
+}
+
+/*!
+ Removes a \a keyframe from the animation. If the same QTransform
+ is set as keyframe multiple times, all occurrences are removed.
+ */
+void QKeyframeAnimation::removeKeyframe(Qt3DCore::QTransform *keyframe)
+{
+ Q_D(QKeyframeAnimation);
+ d->m_keyframes.removeAll(keyframe);
+}
+
+QString QKeyframeAnimation::targetName() const
+{
+ Q_D(const QKeyframeAnimation);
+ return d->m_targetName;
+}
+
+QEasingCurve QKeyframeAnimation::easing() const
+{
+ Q_D(const QKeyframeAnimation);
+ return d->m_easing;
+}
+
+Qt3DCore::QTransform *QKeyframeAnimation::target() const
+{
+ Q_D(const QKeyframeAnimation);
+ return d->m_target;
+}
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
diff --git a/src/animation/frontend/qkeyframeanimation.h b/src/animation/frontend/qkeyframeanimation.h
new file mode 100644
index 000000000..19cb192b4
--- /dev/null
+++ b/src/animation/frontend/qkeyframeanimation.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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_QKEYFRAMEANIMATION_H
+#define QT3DANIMATION_QKEYFRAMEANIMATION_H
+
+#include <Qt3DCore/qtransform.h>
+
+#include <Qt3DAnimation/qabstractanimation.h>
+#include <Qt3DAnimation/qt3danimation_global.h>
+
+#include <QtCore/qeasingcurve.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QKeyframeAnimationPrivate;
+
+class QT3DANIMATIONSHARED_EXPORT QKeyframeAnimation : public QAbstractAnimation
+{
+ Q_OBJECT
+ Q_PROPERTY(QVector<float> framePositions READ framePositions WRITE setFramePositions NOTIFY framePositionsChanged)
+ Q_PROPERTY(Qt3DCore::QTransform *target READ target WRITE setTarget NOTIFY targetChanged)
+ Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged)
+ Q_PROPERTY(QString targetName READ targetName WRITE setTargetName NOTIFY targetNameChanged)
+ Q_PROPERTY(QKeyframeAnimation::RepeatMode startMode READ startMode WRITE setStartMode NOTIFY startModeChanged)
+ Q_PROPERTY(QKeyframeAnimation::RepeatMode endMode READ endMode WRITE setEndMode NOTIFY endModeChanged)
+
+public:
+ explicit QKeyframeAnimation(QObject *parent = nullptr);
+
+ enum RepeatMode
+ {
+ None,
+ Constant,
+ Repeat,
+ };
+ Q_ENUM(RepeatMode)
+
+ QVector<float> framePositions() const;
+ QVector<Qt3DCore::QTransform *> keyframeList() const;
+ Qt3DCore::QTransform *target() const;
+ QEasingCurve easing() const;
+ QString targetName() const;
+ RepeatMode startMode() const;
+ RepeatMode endMode() const;
+
+ void setKeyframes(const QVector<Qt3DCore::QTransform *> &keyframes);
+ void addKeyframe(Qt3DCore::QTransform *keyframe);
+ void removeKeyframe(Qt3DCore::QTransform *keyframe);
+
+public Q_SLOTS:
+ void setFramePositions(const QVector<float> &positions);
+ void setTarget(Qt3DCore::QTransform *target);
+ void setEasing(const QEasingCurve &easing);
+ void setTargetName(const QString &name);
+ void setStartMode(RepeatMode mode);
+ void setEndMode(RepeatMode mode);
+
+Q_SIGNALS:
+ void framePositionsChanged(const QVector<float> &positions);
+ void targetChanged(Qt3DCore::QTransform *target);
+ void easingChanged(const QEasingCurve &easing);
+ void targetNameChanged(const QString &name);
+ void startModeChanged(QKeyframeAnimation::RepeatMode startMode);
+ void endModeChanged(QKeyframeAnimation::RepeatMode endMode);
+
+private:
+ void updateAnimation(float position);
+
+ Q_DECLARE_PRIVATE(QKeyframeAnimation)
+};
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QKEYFRAMEANIMATION_H
diff --git a/src/animation/frontend/qkeyframeanimation_p.h b/src/animation/frontend/qkeyframeanimation_p.h
new file mode 100644
index 000000000..b9b1f8585
--- /dev/null
+++ b/src/animation/frontend/qkeyframeanimation_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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_QKEYFRAMEANIMATION_P_H
+#define QT3DANIMATION_QKEYFRAMEANIMATION_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 <private/qobject_p.h>
+#include <Qt3DAnimation/qkeyframeanimation.h>
+#include <private/qabstractanimation_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QKeyframeAnimationPrivate : public QAbstractAnimationPrivate
+{
+public:
+ QKeyframeAnimationPrivate();
+
+ void calculateFrame(float position);
+
+ QVector<float> m_framePositions;
+ QVector<Qt3DCore::QTransform *> m_keyframes;
+ Qt3DCore::QTransform *m_target;
+ QEasingCurve m_easing;
+ QString m_animationName;
+ QString m_targetName;
+ float m_minposition;
+ float m_maxposition;
+ QKeyframeAnimation::RepeatMode m_startMode;
+ QKeyframeAnimation::RepeatMode m_endMode;
+ QVector3D m_baseScale;
+ QVector3D m_baseTranslation;
+ QQuaternion m_baseRotation;
+ QMetaObject::Connection m_positionConnection;
+
+ Q_DECLARE_PUBLIC(QKeyframeAnimation)
+};
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QKEYFRAMEANIMATION_P_H
diff --git a/src/animation/frontend/qlerpblend.cpp b/src/animation/frontend/qlerpclipblend.cpp
index 661c70ef0..3b26adbaa 100644
--- a/src/animation/frontend/qlerpblend.cpp
+++ b/src/animation/frontend/qlerpclipblend.cpp
@@ -34,9 +34,8 @@
**
****************************************************************************/
-#include "qlerpblend.h"
-#include "qlerpblend_p.h"
-#include <Qt3DAnimation/qanimationclip.h>
+#include "qlerpclipblend.h"
+#include "qlerpclipblend_p.h"
#include <Qt3DAnimation/qclipblendnodecreatedchange.h>
QT_BEGIN_NAMESPACE
@@ -45,7 +44,7 @@ namespace Qt3DAnimation {
/*!
\qmltype LerpBlend
- \instantiates Qt3DAnimation::QLerpBlend
+ \instantiates Qt3DAnimation::QLerpClipBlend
\inqmlmodule Qt3D.Animation
\brief Performs a linear interpolation of two animation clips based on a
@@ -65,7 +64,7 @@ namespace Qt3DAnimation {
*/
/*!
- \class Qt3DAnimation::QLerpBlend
+ \class Qt3DAnimation::QLerpClipBlend
\inmodule Qt3DAnimation
\inherits Qt3DAnimation::QAbstractClipBlendNode
@@ -74,7 +73,7 @@ namespace Qt3DAnimation {
\since 5.9
- QLerpBlend can be useful to create advanced animation effects based on
+ QLerpClipBlend can be useful to create advanced animation effects based on
individual animation clips. For instance, given a player character,, lerp
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
@@ -85,31 +84,35 @@ namespace Qt3DAnimation {
\sa QBlendedClipAnimator
*/
-QLerpBlendPrivate::QLerpBlendPrivate()
+QLerpClipBlendPrivate::QLerpClipBlendPrivate()
: QAbstractClipBlendNodePrivate()
+ , m_startClip(nullptr)
+ , m_endClip(nullptr)
, m_blendFactor(0.0f)
{
}
-QLerpBlend::QLerpBlend(Qt3DCore::QNode *parent)
- : QAbstractClipBlendNode(*new QLerpBlendPrivate(), parent)
+QLerpClipBlend::QLerpClipBlend(Qt3DCore::QNode *parent)
+ : QAbstractClipBlendNode(*new QLerpClipBlendPrivate(), parent)
{
}
-QLerpBlend::QLerpBlend(QLerpBlendPrivate &dd, Qt3DCore::QNode *parent)
+QLerpClipBlend::QLerpClipBlend(QLerpClipBlendPrivate &dd, Qt3DCore::QNode *parent)
: QAbstractClipBlendNode(dd, parent)
{
}
-QLerpBlend::~QLerpBlend()
+QLerpClipBlend::~QLerpClipBlend()
{
}
-Qt3DCore::QNodeCreatedChangeBasePtr QLerpBlend::createNodeCreationChange() const
+Qt3DCore::QNodeCreatedChangeBasePtr QLerpClipBlend::createNodeCreationChange() const
{
- Q_D(const QLerpBlend);
- auto creationChange = QClipBlendNodeCreatedChangePtr<QLerpBlendData>::create(this);
- QLerpBlendData &data = creationChange->data;
+ Q_D(const QLerpClipBlend);
+ auto creationChange = QClipBlendNodeCreatedChangePtr<QLerpClipBlendData>::create(this);
+ QLerpClipBlendData &data = creationChange->data;
+ data.startClipId = Qt3DCore::qIdForNode(d->m_startClip);
+ data.endClipId = Qt3DCore::qIdForNode(d->m_endClip);
data.blendFactor = d->m_blendFactor;
return creationChange;
}
@@ -121,20 +124,61 @@ Qt3DCore::QNodeCreatedChangeBasePtr QLerpBlend::createNodeCreationChange() const
two animation clips.
*/
/*!
- \property QLerpBlend::blendFactor
+ \property QLerpClipBlend::blendFactor
Specifies the blending factor between 0 and 1 to control the blending of
two animation clips.
*/
-float QLerpBlend::blendFactor() const
+float QLerpClipBlend::blendFactor() const
{
- Q_D(const QLerpBlend);
+ Q_D(const QLerpClipBlend);
return d->m_blendFactor;
}
-void QLerpBlend::setBlendFactor(float blendFactor)
+/*!
+ \qmlproperty AbstractClipBlendNode LerpClipBlend::startClip
+
+ Holds the sub-tree that should be used as the start clip for this
+ lerp blend node. That is, the clip returned by this blend node when
+ the blendFactor is set to a value of 0.
+*/
+/*!
+ \property QLerpClipBlend::startClip
+
+ Holds the sub-tree that should be used as the start clip for this
+ lerp blend node. That is, the clip returned by this blend node when
+ the blendFactor is set to a value of 0.
+*/
+Qt3DAnimation::QAbstractClipBlendNode *QLerpClipBlend::startClip() const
{
- Q_D(QLerpBlend);
+ Q_D(const QLerpClipBlend);
+ return d->m_startClip;
+}
+
+/*!
+ \qmlproperty AbstractClipBlendNode LerpClipBlend::endClip
+
+ Holds the sub-tree that should be used as the end clip for this
+ lerp blend node. That is, the clip returned by this blend node when
+ the blendFactor is set to a value of 1.
+*/
+/*!
+ \property QLerpClipBlend::endClip
+
+ Holds the sub-tree that should be used as the start clip for this
+ lerp blend node. That is, the clip returned by this blend node when
+ the blendFactor is set to a value of 1.
+*/
+Qt3DAnimation::QAbstractClipBlendNode *QLerpClipBlend::endClip() const
+{
+ Q_D(const QLerpClipBlend);
+ return d->m_endClip;
+}
+
+void QLerpClipBlend::setBlendFactor(float blendFactor)
+{
+ Q_D(QLerpClipBlend);
+
if (d->m_blendFactor == blendFactor)
return;
@@ -142,6 +186,44 @@ void QLerpBlend::setBlendFactor(float blendFactor)
emit blendFactorChanged(blendFactor);
}
+void QLerpClipBlend::setStartClip(Qt3DAnimation::QAbstractClipBlendNode *startClip)
+{
+ Q_D(QLerpClipBlend);
+ if (d->m_startClip == startClip)
+ return;
+
+ if (d->m_startClip)
+ d->unregisterDestructionHelper(d->m_startClip);
+
+ if (startClip && !startClip->parent())
+ startClip->setParent(this);
+ d->m_startClip = startClip;
+
+ // Ensures proper bookkeeping
+ if (d->m_startClip)
+ d->registerDestructionHelper(d->m_startClip, &QLerpClipBlend::setStartClip, d->m_startClip);
+ emit startClipChanged(startClip);
+}
+
+void QLerpClipBlend::setEndClip(Qt3DAnimation::QAbstractClipBlendNode *endClip)
+{
+ Q_D(QLerpClipBlend);
+ if (d->m_endClip == endClip)
+ return;
+
+ if (d->m_endClip)
+ d->unregisterDestructionHelper(d->m_endClip);
+
+ if (endClip && !endClip->parent())
+ endClip->setParent(this);
+ d->m_endClip = endClip;
+
+ // Ensures proper bookkeeping
+ if (d->m_endClip)
+ d->registerDestructionHelper(d->m_endClip, &QLerpClipBlend::setEndClip, d->m_endClip);
+ emit endClipChanged(endClip);
+}
+
/*!
\qmlproperty list<AnimationClip> LerpBlend::clips
@@ -152,19 +234,19 @@ void QLerpBlend::setBlendFactor(float blendFactor)
/*!
- \fn void QLerpBlend::addClip(QAnimationClip *clip);
+ \fn void QLerpClipBlend::addClip(QAbstractAnimationClip *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 QLerpBlend::removeClip(QAnimationClip *clip);
+ \fn void QLerpClipBlend::removeClip(QAbstractAnimationClip *clip);
Removes a \a clip from the blending node's clips list.
*/
/*!
- \fn QVector<QAnimationClip *> QLerpBlend::clips() const;
+ \fn QVector<QAbstractAnimationClip *> QLerpClipBlend::clips() const;
Returns the list of QAnimationClip against which the blending is performed.
*/
diff --git a/src/animation/frontend/qlerpclipblend.h b/src/animation/frontend/qlerpclipblend.h
new file mode 100644
index 000000000..f6707a5a5
--- /dev/null
+++ b/src/animation/frontend/qlerpclipblend.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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_QLERPCLIPBLEND_H
+#define QT3DANIMATION_QLERPCLIPBLEND_H
+
+#include <Qt3DAnimation/qabstractclipblendnode.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QLerpClipBlendPrivate;
+
+class QT3DANIMATIONSHARED_EXPORT QLerpClipBlend : public QAbstractClipBlendNode
+{
+ Q_OBJECT
+ Q_PROPERTY(Qt3DAnimation::QAbstractClipBlendNode *startClip READ startClip WRITE setStartClip NOTIFY startClipChanged)
+ Q_PROPERTY(Qt3DAnimation::QAbstractClipBlendNode *endClip READ endClip WRITE setEndClip NOTIFY endClipChanged)
+ Q_PROPERTY(float blendFactor READ blendFactor WRITE setBlendFactor NOTIFY blendFactorChanged)
+
+public:
+ explicit QLerpClipBlend(Qt3DCore::QNode *parent = nullptr);
+ ~QLerpClipBlend();
+
+ float blendFactor() const;
+ Qt3DAnimation::QAbstractClipBlendNode *startClip() const;
+ Qt3DAnimation::QAbstractClipBlendNode *endClip() const;
+
+public Q_SLOTS:
+ void setBlendFactor(float blendFactor);
+ void setStartClip(Qt3DAnimation::QAbstractClipBlendNode * startClip);
+ void setEndClip(Qt3DAnimation::QAbstractClipBlendNode * endClip);
+
+Q_SIGNALS:
+ void blendFactorChanged(float blendFactor);
+ void startClipChanged(Qt3DAnimation::QAbstractClipBlendNode * startClip);
+ void endClipChanged(Qt3DAnimation::QAbstractClipBlendNode * endClip);
+
+protected:
+ explicit QLerpClipBlend(QLerpClipBlendPrivate &dd, Qt3DCore::QNode *parent = nullptr);
+
+private:
+ Q_DECLARE_PRIVATE(QLerpClipBlend)
+ Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const Q_DECL_OVERRIDE;
+};
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+
+#endif // QT3DANIMATION_QLERPCLIPBLEND_H
diff --git a/src/animation/frontend/qlerpblend_p.h b/src/animation/frontend/qlerpclipblend_p.h
index 035e6cf79..eee597059 100644
--- a/src/animation/frontend/qlerpblend_p.h
+++ b/src/animation/frontend/qlerpclipblend_p.h
@@ -50,25 +50,29 @@
#include <Qt3DAnimation/private/qabstractclipblendnode_p.h>
#include <Qt3DCore/qnodeid.h>
-#include "qlerpblend.h"
+#include "qlerpclipblend.h"
QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
-class QLerpBlend;
+class QLerpClipBlend;
-class QLerpBlendPrivate : public QAbstractClipBlendNodePrivate
+class QLerpClipBlendPrivate : public QAbstractClipBlendNodePrivate
{
public:
- QLerpBlendPrivate();
+ QLerpClipBlendPrivate();
- Q_DECLARE_PUBLIC(QLerpBlend)
+ Q_DECLARE_PUBLIC(QLerpClipBlend)
+ QAbstractClipBlendNode *m_startClip;
+ QAbstractClipBlendNode *m_endClip;
float m_blendFactor;
};
-struct QLerpBlendData
+struct QLerpClipBlendData
{
+ Qt3DCore::QNodeId startClipId;
+ Qt3DCore::QNodeId endClipId;
float blendFactor;
};
diff --git a/src/animation/frontend/qmorphinganimation.cpp b/src/animation/frontend/qmorphinganimation.cpp
new file mode 100644
index 000000000..3824b8d64
--- /dev/null
+++ b/src/animation/frontend/qmorphinganimation.cpp
@@ -0,0 +1,453 @@
+/****************************************************************************
+**
+** 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 "qmorphinganimation.h"
+#include <private/qmorphinganimation_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+/*!
+ \class Qt3DAnimation::QMorphingAnimation
+ \brief A class implementing blend-shape morphing animation
+ \inmodule Qt3DAnimation
+ \since 5.9
+ \inherits Qt3DAnimation::QAbstractAnimation
+
+ A Qt3DAnimation::QMorphingAnimation class implements blend-shape morphing animation
+ to a target \l {Qt3DRender::QGeometryRenderer}{QGeometryRenderer}. The QMorphingAnimation
+ sets the correct \l {Qt3DRender::QAttribute}{QAttributes} from the
+ \l {Qt3DAnimation::QMorphTarget}{morph targets} to the target
+ \l {Qt3DRender::QGeometryRenderer::geometry} {QGeometryRenderer::geometry} and calculates
+ interpolator for the current position. The actual blending between the attributes must
+ be implemented in the material. Qt3DAnimation::QMorphPhongMaterial implements material
+ with morphing support for phong lighting model. The blending happens between
+ 2 attributes - 'base' and 'target'. The names for the base and target attributes are taken from
+ the morph target names, where the base attribute retains the name it already has and the
+ target attribute name gets 'Target' appended to the name. The interpolator can be
+ set as a \l {Qt3DRender::QParameter}{QParameter} to the used material.
+ All morph targets in the animation should contain the attributes with same names as those
+ in the base geometry.
+
+*/
+/*!
+ \qmltype MorphingAnimation
+ \brief A type implementing blend-shape morphing animation
+ \inqmlmodule Qt3D.Animation
+ \since 5.9
+ \inherits AbstractAnimation
+ \instantiates Qt3DAnimation::QMorphingAnimation
+
+ A MorphingAnimation type implements blend-shape morphing animation
+ to a target \l GeometryRenderer. The MorphingAnimation sets the correct
+ \l {Attribute}{Attributes} from the morph targets to the target
+ \l {Qt3D.Render::GeometryRenderer::geometry}{GeometryRenderer::geometry} and calculates
+ interpolator for the current position. The actual blending between the attributes must
+ be implemented in the material. MorphPhongMaterial implements material
+ with morphing support for phong lighting model. The blending happens between
+ 2 attributes - 'base' and 'target'. The names for the base and target attributes are taken from
+ the morph target names, where the base attribute retains the name it already has and the
+ target attribute name gets 'Target' appended to the name. All morph targets in the animation
+ should contain the attributes with same names as those in the base geometry.
+
+*/
+/*!
+ \property Qt3DAnimation::QMorphingAnimation::targetPositions
+ Holds the position values of the morph target. Each position in the list specifies the position
+ of the corresponding morph target with the same index. The values must be in an ascending order.
+ Values can be positive or negative and do not have any predefined unit.
+*/
+/*!
+ \property Qt3DAnimation::QMorphingAnimation::interpolator
+ Holds the interpolator between base and target attributes.
+ \readonly
+*/
+/*!
+ \property Qt3DAnimation::QMorphingAnimation::target
+ Holds the target QGeometryRenderer the morphing animation is applied to.
+*/
+/*!
+ \property Qt3DAnimation::QMorphingAnimation::targetName
+ Holds the name of the target geometry. This is a convenience property making it
+ easier to match the target geometry to the morphing animation. The name
+ is usually same as the name of the parent entity of the target QGeometryRenderer, but
+ does not have to be.
+*/
+/*!
+ \property Qt3DAnimation::QMorphingAnimation::method
+ Holds the morphing method. The default is Relative.
+*/
+/*!
+ \property Qt3DAnimation::QMorphingAnimation::easing
+ Holds the easing curve of the interpolator between morph targets.
+*/
+/*!
+ \enum Qt3DAnimation::QMorphingAnimation::Method
+
+ This enumeration specifies the morphing method.
+ \value Normalized The blending should use the normalized formula;
+ V' = Vbase * (1.0 - sum(Wi)) + sum[Vi * Wi]
+ \value Relative The blending should use the relative formula;
+ V' = Vbase + sum[Vi * Wi]
+*/
+
+/*!
+ \qmlproperty list<real> MorphingAnimation::targetPositions
+ Holds the position values of the morph target. Each position in the list specifies the position
+ of the corresponding morph target with the same index. The values must be in an ascending order.
+ Values can be positive or negative and do not have any predefined unit.
+*/
+/*!
+ \qmlproperty real MorphingAnimation::interpolator
+ Holds the interpolator between base and target attributes.
+ \readonly
+*/
+/*!
+ \qmlproperty GeometryRenderer MorphingAnimation::target
+ Holds the target GeometryRenderer the morphing animation is applied to.
+*/
+/*!
+ \qmlproperty string MorphingAnimation::targetName
+ Holds the name of the target geometry. This is a convenience property making it
+ easier to match the target geometry to the morphing animation. The name
+ is usually same as the name of the parent entity of the target GeometryRenderer, but
+ does not have to be.
+*/
+/*!
+ \qmlproperty enumeration MorphingAnimation::method
+ Holds the morphing method. The default is Relative.
+ \list
+ \li Normalized
+ \li Relative
+ \endlist
+*/
+/*!
+ \qmlproperty EasingCurve MorphingAnimation::easing
+ Holds the easing curve of the interpolator between morph targets.
+*/
+/*!
+ \qmlproperty list<MorphTarget> MorphingAnimation::morphTargets
+ Holds the list of morph targets in the morphing animation.
+*/
+
+QMorphingAnimationPrivate::QMorphingAnimationPrivate()
+ : QAbstractAnimationPrivate(QAbstractAnimation::MorphingAnimation)
+ , m_minposition(0.0f)
+ , m_maxposition(0.0f)
+ , m_flattened(nullptr)
+ , m_method(QMorphingAnimation::Relative)
+ , m_interpolator(0.0f)
+ , m_target(nullptr)
+ , m_currentTarget(nullptr)
+{
+
+}
+
+QMorphingAnimationPrivate::~QMorphingAnimationPrivate()
+{
+ for (QVector<float> *weights : qAsConst(m_weights))
+ delete weights;
+}
+
+void QMorphingAnimationPrivate::updateAnimation(float position)
+{
+ Q_Q(QMorphingAnimation);
+ if (!m_target || !m_target->geometry())
+ return;
+
+ QVector<int> relevantValues;
+ float sum = 0.0f;
+ float interpolator = 0.0f;
+ m_morphKey.resize(m_morphTargets.size());
+
+ // calculate morph key
+ if (position < m_minposition) {
+ m_morphKey = *m_weights.first();
+ } else if (position >= m_maxposition) {
+ m_morphKey = *m_weights.last();
+ } else {
+ for (int i = 0; i < m_targetPositions.size() - 1; ++i) {
+ if (position >= m_targetPositions.at(i) && position < m_targetPositions.at(i + 1)) {
+ interpolator = (position - m_targetPositions.at(i))
+ / (m_targetPositions.at(i + 1) - m_targetPositions.at(i));
+ interpolator = m_easing.valueForProgress(interpolator);
+ float iip = 1.0f - interpolator;
+
+ for (int j = 0; j < m_morphTargets.size(); ++j) {
+ m_morphKey[j] = interpolator * m_weights.at(i + 1)->at(j)
+ + iip * m_weights.at(i)->at(j);
+ }
+ }
+ }
+ }
+
+ // check relevant values
+ for (int j = 0; j < m_morphKey.size(); ++j) {
+ sum += m_morphKey[j];
+ if (!qFuzzyIsNull(m_morphKey[j]))
+ relevantValues.push_back(j);
+ }
+
+ if (relevantValues.size() == 0 || qFuzzyIsNull(sum)) {
+ // only base is used
+ interpolator = 0.0f;
+ } else if (relevantValues.size() == 1) {
+ // one morph target has non-zero weight
+ setTargetInterpolated(relevantValues[0]);
+ interpolator = sum;
+ } else {
+ // more than one morph target has non-zero weight
+ // flatten morph targets to one
+ qWarning() << Q_FUNC_INFO << "Flattening required";
+ }
+
+ // Relative method uses negative interpolator, normalized uses positive
+ if (m_method == QMorphingAnimation::Relative)
+ interpolator = -interpolator;
+
+ if (!qFuzzyCompare(interpolator, m_interpolator)) {
+ m_interpolator = interpolator;
+ emit q->interpolatorChanged(m_interpolator);
+ }
+}
+
+void QMorphingAnimationPrivate::setTargetInterpolated(int morphTarget)
+{
+ QMorphTarget *target = m_morphTargets[morphTarget];
+ Qt3DRender::QGeometry *geometry = m_target->geometry();
+
+ // remove attributes from previous frame
+ if (m_currentTarget && (target != m_currentTarget)) {
+ const QVector<Qt3DRender::QAttribute *> targetAttributes = m_currentTarget->attributeList();
+ for (int i = 0; i < targetAttributes.size(); ++i)
+ geometry->removeAttribute(targetAttributes.at(i));
+ }
+
+ const QVector<Qt3DRender::QAttribute *> targetAttributes = target->attributeList();
+
+ // add attributes from current frame to the geometry
+ if (target != m_currentTarget) {
+ for (int i = 0; i < m_attributeNames.size(); ++i) {
+ QString targetName = m_attributeNames.at(i);
+ targetName.append(QLatin1String("Target"));
+ targetAttributes[i]->setName(targetName);
+ geometry->addAttribute(targetAttributes.at(i));
+ }
+ }
+ m_currentTarget = target;
+}
+
+/*!
+ Construct a new QMorphingAnimation with \a parent.
+ */
+QMorphingAnimation::QMorphingAnimation(QObject *parent)
+ : QAbstractAnimation(*new QMorphingAnimationPrivate, parent)
+{
+ Q_D(QMorphingAnimation);
+ d->m_positionConnection = QObject::connect(this, &QAbstractAnimation::positionChanged,
+ this, &QMorphingAnimation::updateAnimation);
+}
+
+QVector<float> QMorphingAnimation::targetPositions() const
+{
+ Q_D(const QMorphingAnimation);
+ return d->m_targetPositions;
+}
+
+float QMorphingAnimation::interpolator() const
+{
+ Q_D(const QMorphingAnimation);
+ return d->m_interpolator;
+}
+
+Qt3DRender::QGeometryRenderer *QMorphingAnimation::target() const
+{
+ Q_D(const QMorphingAnimation);
+ return d->m_target;
+}
+
+QString QMorphingAnimation::targetName() const
+{
+ Q_D(const QMorphingAnimation);
+ return d->m_targetName;
+}
+
+QMorphingAnimation::Method QMorphingAnimation::method() const
+{
+ Q_D(const QMorphingAnimation);
+ return d->m_method;
+}
+
+QEasingCurve QMorphingAnimation::easing() const
+{
+ Q_D(const QMorphingAnimation);
+ return d->m_easing;
+}
+
+/*!
+ Set morph \a targets to animation. Old targets are cleared.
+*/
+void QMorphingAnimation::setMorphTargets(const QVector<Qt3DAnimation::QMorphTarget *> &targets)
+{
+ Q_D(QMorphingAnimation);
+ d->m_morphTargets = targets;
+ d->m_attributeNames = targets[0]->attributeNames();
+ d->m_position = -1.0f;
+}
+
+/*!
+ Add new morph \a target at the end of the animation.
+*/
+void QMorphingAnimation::addMorphTarget(Qt3DAnimation::QMorphTarget *target)
+{
+ Q_D(QMorphingAnimation);
+ if (!d->m_morphTargets.contains(target)) {
+ d->m_morphTargets.push_back(target);
+ d->m_position = -1.0f;
+ if (d->m_attributeNames.empty())
+ d->m_attributeNames = target->attributeNames();
+ }
+}
+
+/*!
+ Remove morph \a target from the animation.
+*/
+void QMorphingAnimation::removeMorphTarget(Qt3DAnimation::QMorphTarget *target)
+{
+ Q_D(QMorphingAnimation);
+ d->m_morphTargets.removeAll(target);
+ d->m_position = -1.0f;
+}
+
+void QMorphingAnimation::setTargetPositions(const QVector<float> &targetPositions)
+{
+ Q_D(QMorphingAnimation);
+ d->m_targetPositions = targetPositions;
+ emit targetPositionsChanged(targetPositions);
+ d->m_minposition = targetPositions.first();
+ d->m_maxposition = targetPositions.last();
+ setDuration(d->m_targetPositions.last());
+ if (d->m_weights.size() < targetPositions.size()) {
+ d->m_weights.resize(targetPositions.size());
+ for (int i = 0; i < d->m_weights.size(); ++i) {
+ if (d->m_weights[i] == nullptr)
+ d->m_weights[i] = new QVector<float>();
+ }
+ }
+ d->m_position = -1.0f;
+}
+
+void QMorphingAnimation::setTarget(Qt3DRender::QGeometryRenderer *target)
+{
+ Q_D(QMorphingAnimation);
+ if (d->m_target != target) {
+ d->m_position = -1.0f;
+ d->m_target = target;
+ emit targetChanged(target);
+ }
+}
+
+/*!
+ Sets morph \a weights at \a positionIndex.
+*/
+void QMorphingAnimation::setWeights(int positionIndex, const QVector<float> &weights)
+{
+ Q_D(QMorphingAnimation);
+ if (d->m_weights.size() < positionIndex)
+ d->m_weights.resize(positionIndex + 1);
+ if (d->m_weights[positionIndex] == nullptr)
+ d->m_weights[positionIndex] = new QVector<float>();
+ *d->m_weights[positionIndex] = weights;
+ d->m_position = -1.0f;
+}
+
+/*!
+ Return morph weights at \a positionIndex.
+*/
+QVector<float> QMorphingAnimation::getWeights(int positionIndex)
+{
+ Q_D(QMorphingAnimation);
+ return *d->m_weights[positionIndex];
+}
+
+/*!
+ Return morph target list.
+*/
+QVector<Qt3DAnimation::QMorphTarget *> QMorphingAnimation::morphTargetList()
+{
+ Q_D(QMorphingAnimation);
+ return d->m_morphTargets;
+}
+
+void QMorphingAnimation::setTargetName(const QString name)
+{
+ Q_D(QMorphingAnimation);
+ if (d->m_targetName != name) {
+ d->m_targetName = name;
+ emit targetNameChanged(name);
+ }
+}
+
+void QMorphingAnimation::setMethod(QMorphingAnimation::Method method)
+{
+ Q_D(QMorphingAnimation);
+ if (d->m_method != method) {
+ d->m_method = method;
+ d->m_position = -1.0f;
+ emit methodChanged(method);
+ }
+}
+
+void QMorphingAnimation::setEasing(const QEasingCurve &easing)
+{
+ Q_D(QMorphingAnimation);
+ if (d->m_easing != easing) {
+ d->m_easing = easing;
+ d->m_position = -1.0f;
+ emit easingChanged(easing);
+ }
+}
+
+void QMorphingAnimation::updateAnimation(float position)
+{
+ Q_D(QMorphingAnimation);
+ d->updateAnimation(position);
+}
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
diff --git a/src/animation/frontend/qmorphinganimation.h b/src/animation/frontend/qmorphinganimation.h
new file mode 100644
index 000000000..2944fad91
--- /dev/null
+++ b/src/animation/frontend/qmorphinganimation.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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_QMORPHINGANIMATION_H
+#define QT3DANIMATION_QMORPHINGANIMATION_H
+
+#include <Qt3DRender/qgeometryrenderer.h>
+
+#include <Qt3DAnimation/qabstractanimation.h>
+#include <Qt3DAnimation/qmorphtarget.h>
+#include <Qt3DAnimation/qt3danimation_global.h>
+
+#include <QtCore/qeasingcurve.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QMorphingAnimationPrivate;
+
+class QT3DANIMATIONSHARED_EXPORT QMorphingAnimation : public QAbstractAnimation
+{
+ Q_OBJECT
+ Q_PROPERTY(QVector<float> targetPositions READ targetPositions WRITE setTargetPositions NOTIFY targetPositionsChanged)
+ Q_PROPERTY(float interpolator READ interpolator NOTIFY interpolatorChanged)
+ Q_PROPERTY(Qt3DRender::QGeometryRenderer *target READ target WRITE setTarget NOTIFY targetChanged)
+ Q_PROPERTY(QString targetName READ targetName WRITE setTargetName NOTIFY targetNameChanged)
+ Q_PROPERTY(QMorphingAnimation::Method method READ method WRITE setMethod NOTIFY methodChanged)
+ Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged)
+
+public:
+ enum Method
+ {
+ Normalized,
+ Relative
+ };
+ Q_ENUM(Method)
+
+ explicit QMorphingAnimation(QObject *parent = nullptr);
+
+ QVector<float> targetPositions() const;
+ float interpolator() const;
+ Qt3DRender::QGeometryRenderer *target() const;
+ QString targetName() const;
+ QMorphingAnimation::Method method() const;
+ QEasingCurve easing() const;
+
+ void setMorphTargets(const QVector<Qt3DAnimation::QMorphTarget *> &targets);
+ void addMorphTarget(Qt3DAnimation::QMorphTarget *target);
+ void removeMorphTarget(Qt3DAnimation::QMorphTarget *target);
+
+ void setWeights(int positionIndex, const QVector<float> &weights);
+ QVector<float> getWeights(int positionIndex);
+
+ QVector<Qt3DAnimation::QMorphTarget *> morphTargetList();
+
+public Q_SLOTS:
+ void setTargetPositions(const QVector<float> &targetPositions);
+ void setTarget(Qt3DRender::QGeometryRenderer *target);
+ void setTargetName(const QString name);
+ void setMethod(QMorphingAnimation::Method method);
+ void setEasing(const QEasingCurve &easing);
+
+Q_SIGNALS:
+ void targetPositionsChanged(const QVector<float> &targetPositions);
+ void interpolatorChanged(float interpolator);
+ void targetChanged(Qt3DRender::QGeometryRenderer *target);
+ void targetNameChanged(const QString &name);
+ void methodChanged(QMorphingAnimation::Method method);
+ void easingChanged(const QEasingCurve &easing);
+
+private:
+
+ void updateAnimation(float position);
+
+ Q_DECLARE_PRIVATE(QMorphingAnimation)
+};
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QMORPHINGANIMATION_H
diff --git a/src/animation/frontend/qmorphinganimation_p.h b/src/animation/frontend/qmorphinganimation_p.h
new file mode 100644
index 000000000..c306f3309
--- /dev/null
+++ b/src/animation/frontend/qmorphinganimation_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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_QMORPHINGANIMATION_P_H
+#define QT3DANIMATION_QMORPHINGANIMATION_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 <QtCore/qeasingcurve.h>
+#include <Qt3DAnimation/qmorphinganimation.h>
+
+#include <private/qobject_p.h>
+#include <private/qabstractanimation_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QMorphingAnimationPrivate : public QAbstractAnimationPrivate
+{
+public:
+ QMorphingAnimationPrivate();
+ ~QMorphingAnimationPrivate();
+
+ void updateAnimation(float position);
+ void setTargetInterpolated(int morphTarget);
+
+ float m_minposition;
+ float m_maxposition;
+ QVector<float> m_targetPositions;
+ QVector<QVector<float>*> m_weights;
+ QVector<float> m_morphKey;
+ QStringList m_attributeNames;
+ QVector<Qt3DAnimation::QMorphTarget *> m_morphTargets;
+ QMorphTarget *m_flattened;
+ QMorphingAnimation::Method m_method;
+ QEasingCurve m_easing;
+ float m_interpolator;
+ Qt3DRender::QGeometryRenderer *m_target;
+ QString m_targetName;
+
+ QMorphTarget *m_currentTarget;
+
+ QMetaObject::Connection m_positionConnection;
+
+ Q_DECLARE_PUBLIC(QMorphingAnimation)
+};
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QMORPHINGANIMATION_P_H
diff --git a/src/animation/frontend/qmorphtarget.cpp b/src/animation/frontend/qmorphtarget.cpp
new file mode 100644
index 000000000..9dc30b8ba
--- /dev/null
+++ b/src/animation/frontend/qmorphtarget.cpp
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** 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 "qmorphtarget.h"
+#include "Qt3DAnimation/private/qmorphtarget_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+/*!
+ \class Qt3DAnimation::QMorphTarget
+ \brief A class providing morph targets to blend-shape animation
+ \inmodule Qt3DAnimation
+ \since 5.9
+ \inherits QObject
+
+ A Qt3DAnimation::QMorphTarget class is a convenience class, which provides a list
+ of \l {Qt3DRender::QAttribute} {QAttributes}, which the QMorphingAnimation uses
+ to animate geometry. A QMorphTarget can also be created based on existing
+ \l Qt3DRender::QGeometry.
+
+*/
+/*!
+ \qmltype MorphTarget
+ \brief A type providing morph targets to blend-shape animation
+ \inqmlmodule Qt3D.Animation
+ \since 5.9
+ \inherits QtObject
+ \instantiates Qt3DAnimation::QMorphTarget
+
+ A MorphTarget type is a convenience type, which provides a list
+ of \l {Qt3D.Render::Attribute} {Attributes}, which the MorphingAnimation uses
+ to animate geometry. A MorphTarget can also be created based on existing
+ \l {Qt3D.Render::Geometry}{Geometry}.
+
+*/
+
+/*!
+ \property Qt3DAnimation::QMorphTarget::attributeNames
+ Holds a list of attribute names contained in the morph target.
+ \readonly
+*/
+
+/*!
+ \qmlproperty list<string> MorphTarget::attributeNames
+ Holds a list of attribute names contained in the morph target.
+ \readonly
+*/
+/*!
+ \qmlproperty list<Attribute> MorphTarget::attributes
+ Holds the list of attributes in the morph target.
+*/
+/*!
+ \qmlmethod MorphTarget Qt3D.Animation::MorphTarget::fromGeometry(geometry, stringList)
+ Returns a morph target based on the attributes defined by the given stringList from
+ the given geometry.
+*/
+
+QMorphTargetPrivate::QMorphTargetPrivate()
+ : QObjectPrivate()
+{
+
+}
+
+void QMorphTargetPrivate::updateAttributeNames()
+{
+ m_attributeNames.clear();
+ for (const Qt3DRender::QAttribute *attr : qAsConst(m_targetAttributes))
+ m_attributeNames.push_back(attr->name());
+}
+
+/*!
+ Constructs a QMorphTarget with given \a parent.
+*/
+QMorphTarget::QMorphTarget(QObject *parent)
+ : QObject(*new QMorphTargetPrivate, parent)
+{
+
+}
+
+/*!
+ Returns a list of attributes contained in the morph target.
+*/
+QVector<Qt3DRender::QAttribute *> QMorphTarget::attributeList() const
+{
+ Q_D(const QMorphTarget);
+ return d->m_targetAttributes;
+}
+
+QStringList QMorphTarget::attributeNames() const
+{
+ Q_D(const QMorphTarget);
+ return d->m_attributeNames;
+}
+
+/*!
+ Sets \a attributes to the morph target. Old attributes are cleared.
+*/
+void QMorphTarget::setAttributes(const QVector<Qt3DRender::QAttribute *> &attributes)
+{
+ Q_D(QMorphTarget);
+ d->m_targetAttributes = attributes;
+ d->m_attributeNames.clear();
+ for (const Qt3DRender::QAttribute *attr : attributes)
+ d->m_attributeNames.push_back(attr->name());
+
+ emit attributeNamesChanged(d->m_attributeNames);
+}
+
+/*!
+ Adds an \a attribute the morph target. An attribute with the same
+ name must not have been added previously to the morph target.
+*/
+void QMorphTarget::addAttribute(Qt3DRender::QAttribute *attribute)
+{
+ Q_D(QMorphTarget);
+ for (const Qt3DRender::QAttribute *attr : qAsConst(d->m_targetAttributes)) {
+ if (attr->name() == attribute->name())
+ return;
+ }
+ d->m_targetAttributes.push_back(attribute);
+ d->m_attributeNames.push_back(attribute->name());
+ emit attributeNamesChanged(d->m_attributeNames);
+}
+
+/*!
+ Removes an \a attribute from the morph target.
+*/
+void QMorphTarget::removeAttribute(Qt3DRender::QAttribute *attribute)
+{
+ Q_D(QMorphTarget);
+ if (d->m_targetAttributes.contains(attribute)) {
+ d->m_targetAttributes.removeAll(attribute);
+ d->updateAttributeNames();
+ emit attributeNamesChanged(d->m_attributeNames);
+ }
+}
+
+/*!
+ Returns a morph target based on the \a attributes in the given \a geometry.
+*/
+QMorphTarget *QMorphTarget::fromGeometry(Qt3DRender::QGeometry *geometry, const QStringList &attributes)
+{
+ QMorphTarget *target = new QMorphTarget();
+ for (Qt3DRender::QAttribute *attr : geometry->attributes()) {
+ if (attributes.contains(attr->name()))
+ target->addAttribute(attr);
+ }
+ return target;
+}
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
diff --git a/src/animation/frontend/qmorphtarget.h b/src/animation/frontend/qmorphtarget.h
new file mode 100644
index 000000000..0435924e1
--- /dev/null
+++ b/src/animation/frontend/qmorphtarget.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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_QMORPHTARGET_H
+#define QT3DANIMATION_QMORPHTARGET_H
+
+#include <Qt3DRender/qattribute.h>
+#include <Qt3DRender/qgeometry.h>
+
+#include <QtCore/qstringlist.h>
+
+#include <Qt3DAnimation/qt3danimation_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QMorphTargetPrivate;
+
+class QT3DANIMATIONSHARED_EXPORT QMorphTarget : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QStringList attributeNames READ attributeNames NOTIFY attributeNamesChanged)
+
+public:
+ explicit QMorphTarget(QObject *parent = nullptr);
+
+ QVector<Qt3DRender::QAttribute *> attributeList() const;
+ QStringList attributeNames() const;
+
+ void setAttributes(const QVector<Qt3DRender::QAttribute *> &attributes);
+ void addAttribute(Qt3DRender::QAttribute *attribute);
+ void removeAttribute(Qt3DRender::QAttribute *attribute);
+
+ Q_INVOKABLE static QMorphTarget *fromGeometry(Qt3DRender::QGeometry *geometry,
+ const QStringList &attributes);
+
+Q_SIGNALS:
+ void attributeNamesChanged(const QStringList &attributeNames);
+
+private:
+
+ Q_DECLARE_PRIVATE(QMorphTarget)
+};
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QMORPHTARGET_H
diff --git a/src/animation/frontend/qmorphtarget_p.h b/src/animation/frontend/qmorphtarget_p.h
new file mode 100644
index 000000000..1fc3734ae
--- /dev/null
+++ b/src/animation/frontend/qmorphtarget_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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_QMORPHTARGET_P_H
+#define QT3DANIMATION_QMORPHTARGET_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 <Qt3DAnimation/qmorphtarget.h>
+
+#include <private/qobject_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QMorphTargetPrivate : public QObjectPrivate
+{
+public:
+ QMorphTargetPrivate();
+
+ void updateAttributeNames();
+
+ QStringList m_attributeNames;
+ QVector<Qt3DRender::QAttribute *> m_targetAttributes;
+
+ Q_DECLARE_PUBLIC(QMorphTarget)
+};
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QMORPHTARGET_P_H
diff --git a/src/animation/frontend/qvertexblendanimation.cpp b/src/animation/frontend/qvertexblendanimation.cpp
new file mode 100644
index 000000000..3ddd83bf0
--- /dev/null
+++ b/src/animation/frontend/qvertexblendanimation.cpp
@@ -0,0 +1,339 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 "qvertexblendanimation.h"
+
+#include <private/qvertexblendanimation_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+/*!
+ \class Qt3DAnimation::QVertexBlendAnimation
+ \brief A class implementing vertex-blend morphing animation
+ \inmodule Qt3DAnimation
+ \since 5.9
+ \inherits Qt3DAnimation::QAbstractAnimation
+
+ A Qt3DAnimation::QVertexBlendAnimation class implements vertex-blend morphing animation
+ to a target \l {Qt3DRender::QGeometryRenderer}{QGeometryRenderer}. The QVertexBlendAnimation
+ sets the correct \l {Qt3DRender::QAttribute}{QAttributes} from the
+ \l {Qt3DAnimation::QMorphTarget}{morph targets} to the target
+ \l {Qt3DRender::QGeometryRenderer::geometry} {QGeometryRenderer::geometry} and calculates
+ interpolator for the current position. Unlike with QMorphingAnimation, where the blending is
+ controller with blend weights, the blending occurs between sequential morph targets.
+ The actual blending between the attributes must be implemented in the material.
+ Qt3DAnimation::QMorphPhongMaterial implements material with morphing support for phong
+ lighting model. The blending happens between 2 attributes - 'base' and 'target'.
+ The names for the base and target attributes are taken from the morph target names,
+ where the base attribute retains the name it already has and the target attribute name
+ gets 'Target' appended to the name. The interpolator can be set as
+ a \l {Qt3DRender::QParameter}{QParameter} to the used material.
+ All morph targets in the animation should contain the attributes with same names as those
+ in the base geometry.
+
+*/
+/*!
+ \qmltype VertexBlendAnimation
+ \brief A type implementing vertex-blend morphing animation
+ \inqmlmodule Qt3D.Animation
+ \since 5.9
+ \inherits AbstractAnimation
+ \instantiates Qt3DAnimation::QVertexBlendAnimation
+
+ A VertexBlendAnimation type implements vertex-blend morphing animation
+ to a target \l GeometryRenderer. The VertexBlendAnimation sets the correct
+ \l {Attribute}{Attributes} from the morph targets to the target
+ \l {Qt3D.Render::GeometryRenderer::geometry}{GeometryRenderer::geometry} and calculates
+ interpolator for the current position. Unlike with MorphingAnimation, where the blending is
+ controller with blend weights, the blending occurs between sequential morph targets.
+ The actual blending between the attributes must be implemented in the material.
+ MorphPhongMaterial implements material with morphing support for phong lighting model.
+ The blending happens between 2 attributes - 'base' and 'target'. The names for the base
+ and target attributes are taken from the morph target names, where the base attribute
+ retains the name it already has and the target attribute name gets 'Target' appended to
+ the name. All morph targets in the animation should contain the attributes with same names
+ as those in the base geometry.
+
+*/
+/*!
+ \property Qt3DAnimation::QVertexBlendAnimation::targetPositions
+ Holds the position values of the morph target. Each position in the list specifies the position
+ of the corresponding morph target with the same index. The values must be in an ascending order.
+ Values can be positive or negative and do not have any predefined unit.
+*/
+/*!
+ \property Qt3DAnimation::QVertexBlendAnimation::interpolator
+ Holds the interpolator between base and target attributes.
+ \readonly
+*/
+/*!
+ \property Qt3DAnimation::QVertexBlendAnimation::target
+ Holds the target QGeometryRenderer the morphing animation is applied to.
+*/
+/*!
+ \property Qt3DAnimation::QVertexBlendAnimation::targetName
+ Holds the name of the target geometry. This is a convenience property making it
+ easier to match the target geometry to the morphing animation. The name
+ is usually same as the name of the parent entity of the target QGeometryRenderer, but
+ does not have to be.
+*/
+
+/*!
+ \qmlproperty list<real> VertexBlendAnimation::targetPositions
+ Holds the position values of the morph target. Each position in the list specifies the position
+ of the corresponding morph target with the same index. The values must be in an ascending order.
+ Values can be positive or negative and do not have any predefined unit.
+*/
+/*!
+ \qmlproperty real VertexBlendAnimation::interpolator
+ Holds the interpolator between base and target attributes.
+ \readonly
+*/
+/*!
+ \qmlproperty GeometryRenderer VertexBlendAnimation::target
+ Holds the target GeometryRenderer the morphing animation is applied to.
+*/
+/*!
+ \qmlproperty string VertexBlendAnimation::targetName
+ Holds the name of the target geometry. This is a convenience property making it
+ easier to match the target geometry to the morphing animation. The name
+ 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)
+ , m_interpolator(0.0f)
+ , m_target(nullptr)
+ , m_currentBase(nullptr)
+ , m_currentTarget(nullptr)
+{
+
+}
+
+void QVertexBlendAnimationPrivate::getAttributesInPosition(float position, int *target0,
+ int *target1, float *interpolator)
+{
+ if (position < m_targetPositions.first()) {
+ *target0 = 0;
+ *target1 = qMin(1, m_targetPositions.size());
+ *interpolator = 0.0f;
+ } else if (position > m_targetPositions.last()) {
+ *target0 = qMax(m_targetPositions.size() - 2, 0);
+ *target1 = qMax(m_targetPositions.size() - 1, 0);
+ *interpolator = 1.0f;
+ } else {
+ for (int i = 0; i < m_targetPositions.size() - 1; i++) {
+ if (position >= m_targetPositions[i] && position < m_targetPositions[i + 1]) {
+ *target0 = i;
+ *target1 = i + 1;
+ float a = (position - m_targetPositions[i])
+ / (m_targetPositions[i + 1] - m_targetPositions[i]);
+ *interpolator = a;
+ }
+ }
+ }
+}
+
+void QVertexBlendAnimationPrivate::updateAnimation(float position)
+{
+ Q_Q(QVertexBlendAnimation);
+ if (!m_target || !m_target->geometry())
+ return;
+
+ Qt3DAnimation::QMorphTarget *base;
+ Qt3DAnimation::QMorphTarget *target;
+ int target0, target1;
+ float interpolator;
+ getAttributesInPosition(position, &target0, &target1, &interpolator);
+
+ base = m_morphTargets.at(target0);
+ target = m_morphTargets.at(target1);
+
+ Qt3DRender::QGeometry *geometry = m_target->geometry();
+
+ // remove attributes from previous frame
+ if ((m_currentBase && (base != m_currentBase))
+ || (m_currentTarget && (target != m_currentTarget))) {
+ const QVector<Qt3DRender::QAttribute *> baseAttributes = m_currentBase->attributeList();
+ const QVector<Qt3DRender::QAttribute *> targetAttributes = m_currentTarget->attributeList();
+ for (int i = 0; i < baseAttributes.size(); ++i) {
+ geometry->removeAttribute(baseAttributes.at(i));
+ geometry->removeAttribute(targetAttributes.at(i));
+ }
+ }
+
+ const QVector<Qt3DRender::QAttribute *> baseAttributes = base->attributeList();
+ const QVector<Qt3DRender::QAttribute *> targetAttributes = target->attributeList();
+ const QStringList attributeNames = base->attributeNames();
+
+ // add attributes from current frame to the geometry
+ if (base != m_currentBase || target != m_currentTarget) {
+ for (int i = 0; i < baseAttributes.size(); ++i) {
+ const QString baseName = attributeNames.at(i);
+ QString targetName = baseName;
+ targetName.append(QLatin1String("Target"));
+
+ baseAttributes[i]->setName(baseName);
+ geometry->addAttribute(baseAttributes.at(i));
+ targetAttributes[i]->setName(targetName);
+ geometry->addAttribute(targetAttributes.at(i));
+ }
+ }
+ m_currentBase = base;
+ m_currentTarget = target;
+
+ if (!qFuzzyCompare(interpolator, m_interpolator)) {
+ m_interpolator = interpolator;
+ emit q->interpolatorChanged(interpolator);
+ }
+}
+
+/*!
+ Construct a new QVertexBlendAnimation with \a parent.
+ */
+QVertexBlendAnimation::QVertexBlendAnimation(QObject *parent)
+ : QAbstractAnimation(*new QVertexBlendAnimationPrivate, parent)
+{
+ Q_D(QVertexBlendAnimation);
+ d->m_positionConnection = QObject::connect(this, &QAbstractAnimation::positionChanged,
+ this, &QVertexBlendAnimation::updateAnimation);
+}
+
+QVector<float> QVertexBlendAnimation::targetPositions() const
+{
+ Q_D(const QVertexBlendAnimation);
+ return d->m_targetPositions;
+}
+
+float QVertexBlendAnimation::interpolator() const
+{
+ Q_D(const QVertexBlendAnimation);
+ return d->m_interpolator;
+}
+
+Qt3DRender::QGeometryRenderer *QVertexBlendAnimation::target() const
+{
+ Q_D(const QVertexBlendAnimation);
+ return d->m_target;
+}
+
+QString QVertexBlendAnimation::targetName() const
+{
+ Q_D(const QVertexBlendAnimation);
+ return d->m_targetName;
+}
+
+/*!
+ Set morph \a targets to animation. Old targets are cleared.
+*/
+void QVertexBlendAnimation::setMorphTargets(const QVector<Qt3DAnimation::QMorphTarget *> &targets)
+{
+ Q_D(QVertexBlendAnimation);
+ d->m_morphTargets = targets;
+}
+
+/*!
+ Add new morph \a target at the end of the animation.
+*/
+void QVertexBlendAnimation::addMorphTarget(Qt3DAnimation::QMorphTarget *target)
+{
+ Q_D(QVertexBlendAnimation);
+ if (!d->m_morphTargets.contains(target))
+ d->m_morphTargets.push_back(target);
+}
+
+/*!
+ Remove morph \a target from the animation.
+*/
+void QVertexBlendAnimation::removeMorphTarget(Qt3DAnimation::QMorphTarget *target)
+{
+ Q_D(QVertexBlendAnimation);
+ d->m_morphTargets.removeAll(target);
+}
+
+void QVertexBlendAnimation::setTargetPositions(const QVector<float> &targetPositions)
+{
+ Q_D(QVertexBlendAnimation);
+ if (d->m_targetPositions == targetPositions)
+ return;
+ d->m_targetPositions = targetPositions;
+ emit targetPositionsChanged(targetPositions);
+ setDuration(d->m_targetPositions.last());
+}
+
+void QVertexBlendAnimation::setTarget(Qt3DRender::QGeometryRenderer *target)
+{
+ Q_D(QVertexBlendAnimation);
+ if (d->m_target != target) {
+ d->m_target = target;
+ emit targetChanged(target);
+ }
+}
+
+/*!
+ Return morph target list.
+*/
+QVector<Qt3DAnimation::QMorphTarget *> QVertexBlendAnimation::morphTargetList()
+{
+ Q_D(QVertexBlendAnimation);
+ return d->m_morphTargets;
+}
+
+void QVertexBlendAnimation::setTargetName(const QString name)
+{
+ Q_D(QVertexBlendAnimation);
+ if (d->m_targetName != name) {
+ d->m_targetName = name;
+ emit targetNameChanged(name);
+ }
+}
+
+void QVertexBlendAnimation::updateAnimation(float position)
+{
+ Q_D(QVertexBlendAnimation);
+ d->updateAnimation(position);
+}
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
diff --git a/src/animation/frontend/qvertexblendanimation.h b/src/animation/frontend/qvertexblendanimation.h
new file mode 100644
index 000000000..a7da2bcda
--- /dev/null
+++ b/src/animation/frontend/qvertexblendanimation.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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_QVERTEXBLENDANIMATION_H
+#define QT3DANIMATION_QVERTEXBLENDANIMATION_H
+
+#include <Qt3DRender/qgeometryrenderer.h>
+#include <Qt3DAnimation/qabstractanimation.h>
+#include <Qt3DAnimation/qmorphtarget.h>
+
+#include <Qt3DAnimation/qt3danimation_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QVertexBlendAnimationPrivate;
+
+class QT3DANIMATIONSHARED_EXPORT QVertexBlendAnimation : public QAbstractAnimation
+{
+ Q_OBJECT
+ Q_PROPERTY(QVector<float> targetPositions READ targetPositions WRITE setTargetPositions NOTIFY targetPositionsChanged)
+ Q_PROPERTY(float interpolator READ interpolator NOTIFY interpolatorChanged)
+ Q_PROPERTY(Qt3DRender::QGeometryRenderer *target READ target WRITE setTarget NOTIFY targetChanged)
+ Q_PROPERTY(QString targetName READ targetName WRITE setTargetName NOTIFY targetNameChanged)
+
+public:
+ explicit QVertexBlendAnimation(QObject *parent = nullptr);
+
+ QVector<float> targetPositions() const;
+ float interpolator() const;
+ Qt3DRender::QGeometryRenderer *target() const;
+ QString targetName() const;
+
+ void setMorphTargets(const QVector<Qt3DAnimation::QMorphTarget *> &targets);
+ void addMorphTarget(Qt3DAnimation::QMorphTarget *target);
+ void removeMorphTarget(Qt3DAnimation::QMorphTarget *target);
+
+ QVector<Qt3DAnimation::QMorphTarget *> morphTargetList();
+
+public Q_SLOTS:
+ void setTargetPositions(const QVector<float> &targetPositions);
+ void setTarget(Qt3DRender::QGeometryRenderer *target);
+ void setTargetName(const QString name);
+
+Q_SIGNALS:
+ void targetPositionsChanged(const QVector<float> &targetPositions);
+ void interpolatorChanged(float interpolator);
+ void targetChanged(Qt3DRender::QGeometryRenderer *target);
+ void targetNameChanged(const QString &name);
+
+private:
+
+ void updateAnimation(float position);
+
+ Q_DECLARE_PRIVATE(QVertexBlendAnimation)
+};
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QVERTEXBLENDANIMATION_H
diff --git a/src/animation/frontend/qvertexblendanimation_p.h b/src/animation/frontend/qvertexblendanimation_p.h
new file mode 100644
index 000000000..8f2609fc8
--- /dev/null
+++ b/src/animation/frontend/qvertexblendanimation_p.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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_QVERTEXBLENDANIMATION_P_H
+#define QT3DANIMATION_QVERTEXBLENDANIMATION_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 <Qt3DAnimation/qvertexblendanimation.h>
+
+#include <private/qobject_p.h>
+#include <private/qabstractanimation_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DAnimation {
+
+class QVertexBlendAnimationPrivate : public QAbstractAnimationPrivate
+{
+public:
+ QVertexBlendAnimationPrivate();
+
+ void getAttributesInPosition(float position, int *target0, int *target1, float *interpolator);
+ void updateAnimation(float position);
+
+ QVector<float> m_targetPositions;
+ QVector<Qt3DAnimation::QMorphTarget *> m_morphTargets;
+ float m_interpolator;
+ Qt3DRender::QGeometryRenderer *m_target;
+ QString m_targetName;
+ QMorphTarget *m_currentBase;
+ QMorphTarget *m_currentTarget;
+
+ QMetaObject::Connection m_positionConnection;
+
+ Q_DECLARE_PUBLIC(QVertexBlendAnimation)
+};
+
+} // Qt3DAnimation
+
+QT_END_NAMESPACE
+
+#endif // QT3DANIMATION_QVertexBlendANIMATION_P_H