summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/extras/animations/animations.pri26
-rw-r--r--src/extras/animations/qabstractanimation.cpp112
-rw-r--r--src/extras/animations/qabstractanimation.h93
-rw-r--r--src/extras/animations/qabstractanimation_p.h75
-rw-r--r--src/extras/animations/qanimationcontroller.cpp252
-rw-r--r--src/extras/animations/qanimationcontroller.h105
-rw-r--r--src/extras/animations/qanimationcontroller_p.h84
-rw-r--r--src/extras/animations/qanimationgroup.cpp125
-rw-r--r--src/extras/animations/qanimationgroup.h89
-rw-r--r--src/extras/animations/qanimationgroup_p.h77
-rw-r--r--src/extras/animations/qkeyframeanimation.cpp262
-rw-r--r--src/extras/animations/qkeyframeanimation.h112
-rw-r--r--src/extras/animations/qkeyframeanimation_p.h89
-rw-r--r--src/extras/animations/qmorphinganimation.cpp280
-rw-r--r--src/extras/animations/qmorphinganimation.h116
-rw-r--r--src/extras/animations/qmorphinganimation_p.h93
-rw-r--r--src/extras/animations/qmorphtarget.cpp120
-rw-r--r--src/extras/animations/qmorphtarget.h83
-rw-r--r--src/extras/animations/qmorphtarget_p.h76
-rw-r--r--src/extras/animations/qvertexblendanimation.cpp234
-rw-r--r--src/extras/animations/qvertexblendanimation.h96
-rw-r--r--src/extras/animations/qvertexblendanimation_p.h86
-rw-r--r--src/extras/defaults/defaults.pri9
-rw-r--r--src/extras/defaults/qmorphphongmaterial.cpp291
-rw-r--r--src/extras/defaults/qmorphphongmaterial.h92
-rw-r--r--src/extras/defaults/qmorphphongmaterial_p.h108
-rw-r--r--src/extras/extras.pro1
-rw-r--r--src/extras/extras.qrc2
-rw-r--r--src/extras/shaders/es2/morphphong.vert32
-rw-r--r--src/extras/shaders/gl3/morphphong.vert34
-rw-r--r--src/plugins/sceneparsers/assimp/assimpimporter.cpp349
-rw-r--r--src/plugins/sceneparsers/assimp/assimpimporter.h8
-rw-r--r--src/quick3d/imports/extras/defaults.qrc21
-rw-r--r--src/quick3d/imports/extras/importsextras.pro2
-rw-r--r--src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp20
-rw-r--r--src/quick3d/quick3dextras/items/items.pri15
-rw-r--r--src/quick3d/quick3dextras/items/quick3danimationcontroller.cpp95
-rw-r--r--src/quick3d/quick3dextras/items/quick3danimationcontroller_p.h89
-rw-r--r--src/quick3d/quick3dextras/items/quick3danimationgroup.cpp99
-rw-r--r--src/quick3d/quick3dextras/items/quick3danimationgroup_p.h91
-rw-r--r--src/quick3d/quick3dextras/items/quick3dkeyframeanimation.cpp101
-rw-r--r--src/quick3d/quick3dextras/items/quick3dkeyframeanimation_p.h92
-rw-r--r--src/quick3d/quick3dextras/items/quick3dmorphinganimation.cpp97
-rw-r--r--src/quick3d/quick3dextras/items/quick3dmorphinganimation_p.h92
-rw-r--r--src/quick3d/quick3dextras/items/quick3dmorphtarget.cpp93
-rw-r--r--src/quick3d/quick3dextras/items/quick3dmorphtarget_p.h85
-rw-r--r--src/quick3d/quick3dextras/quick3dextras.pro4
47 files changed, 4595 insertions, 12 deletions
diff --git a/src/extras/animations/animations.pri b/src/extras/animations/animations.pri
new file mode 100644
index 000000000..71d6099fc
--- /dev/null
+++ b/src/extras/animations/animations.pri
@@ -0,0 +1,26 @@
+HEADERS += \
+ $$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
+
+SOURCES += \
+ $$PWD/qanimationcontroller.cpp \
+ $$PWD/qanimationgroup.cpp \
+ $$PWD/qkeyframeanimation.cpp \
+ $$PWD/qmorphinganimation.cpp \
+ $$PWD/qabstractanimation.cpp \
+ $$PWD/qmorphtarget.cpp \
+ $$PWD/qvertexblendanimation.cpp
+
+INCLUDEPATH += $$PWD
diff --git a/src/extras/animations/qabstractanimation.cpp b/src/extras/animations/qabstractanimation.cpp
new file mode 100644
index 000000000..f87455c18
--- /dev/null
+++ b/src/extras/animations/qabstractanimation.cpp
@@ -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$
+**
+****************************************************************************/
+
+#include "qabstractanimation.h"
+#include "Qt3DExtras/private/qabstractanimation_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+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);
+ }
+}
+
+void QAbstractAnimation::setDuration(float duration)
+{
+ Q_D(QAbstractAnimation);
+ if (!qFuzzyCompare(duration, d->m_duration)) {
+ d->m_duration = duration;
+ emit durationChanged(duration);
+ }
+}
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/animations/qabstractanimation.h b/src/extras/animations/qabstractanimation.h
new file mode 100644
index 000000000..242fe293a
--- /dev/null
+++ b/src/extras/animations/qabstractanimation.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** 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 QT3DEXTRAS_QABSTRACTANIMATION_H
+#define QT3DEXTRAS_QABSTRACTANIMATION_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qvector.h>
+
+#include <Qt3DExtras/qt3dextras_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QAbstractAnimationPrivate;
+
+class QT3DEXTRASSHARED_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,
+ };
+
+ 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)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QABSTRACTANIMATION_H
diff --git a/src/extras/animations/qabstractanimation_p.h b/src/extras/animations/qabstractanimation_p.h
new file mode 100644
index 000000000..1370ef2c7
--- /dev/null
+++ b/src/extras/animations/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 QT3DEXTRAS_QABSTRACTANIMATION_P_H
+#define QT3DEXTRAS_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 <Qt3DExtras/QAbstractAnimation>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class 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)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QANIMATIONCONTROLLER_P_H
diff --git a/src/extras/animations/qanimationcontroller.cpp b/src/extras/animations/qanimationcontroller.cpp
new file mode 100644
index 000000000..adef3d45c
--- /dev/null
+++ b/src/extras/animations/qanimationcontroller.cpp
@@ -0,0 +1,252 @@
+/****************************************************************************
+**
+** 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 "qanimationcontroller.h"
+#include "qanimationgroup.h"
+
+#include <private/qanimationcontroller_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+QAnimationControllerPrivate::QAnimationControllerPrivate()
+ : QObjectPrivate()
+ , m_activeAnimationGroup(0)
+ , m_position(0.0f)
+ , m_positionScale(1.0f)
+ , m_positionOffset(0.0f)
+ , m_entity(nullptr)
+ , m_recursive(true)
+{
+
+}
+
+void QAnimationControllerPrivate::updatePosition(float position)
+{
+ m_position = position;
+ if (m_activeAnimationGroup >= 0 && m_activeAnimationGroup < m_animationGroups.size()) {
+ const float pos = m_positionScale * position + m_positionOffset;
+ m_animationGroups[m_activeAnimationGroup]->setPosition(pos);
+ }
+}
+
+QAnimationGroup *QAnimationControllerPrivate::findGroup(const QString &name)
+{
+ for (QAnimationGroup *g : m_animationGroups) {
+ if (g->name() == name)
+ return g;
+ }
+ return nullptr;
+}
+
+void QAnimationControllerPrivate::extractAnimations()
+{
+ Q_Q(QAnimationController);
+ if (!m_entity)
+ return;
+ QList<Qt3DExtras::QAbstractAnimation *> animations
+ = m_entity->findChildren<Qt3DExtras::QAbstractAnimation *>(QString(),
+ m_recursive ? Qt::FindChildrenRecursively : Qt::FindDirectChildrenOnly);
+ if (animations.size() > 0) {
+ for (Qt3DExtras::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 (Qt3DExtras::QAnimationGroup *a : m_animationGroups)
+ a->deleteLater();
+ m_animationGroups.clear();
+ m_activeAnimationGroup = 0;
+}
+
+QAnimationController::QAnimationController(QObject *parent)
+ : QObject(*new QAnimationControllerPrivate, parent)
+{
+
+}
+
+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;
+}
+
+void QAnimationController::setAnimationGroups(const QVector<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);
+}
+
+void QAnimationController::addAnimationGroup(Qt3DExtras::QAnimationGroup *animationGroup)
+{
+ Q_D(QAnimationController);
+ if (!d->m_animationGroups.contains(animationGroup))
+ d->m_animationGroups.push_back(animationGroup);
+}
+
+void QAnimationController::removeAnimationGroup(Qt3DExtras::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_position, 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);
+ }
+}
+
+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;
+}
+
+QAnimationGroup *QAnimationController::getGroup(int index) const
+{
+ Q_D(const QAnimationController);
+ return d->m_animationGroups.at(index);
+}
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/animations/qanimationcontroller.h b/src/extras/animations/qanimationcontroller.h
new file mode 100644
index 000000000..4ee32dd8b
--- /dev/null
+++ b/src/extras/animations/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 QT3DEXTRAS_QANIMATIONCONTROLLER_H
+#define QT3DEXTRAS_QANIMATIONCONTROLLER_H
+
+#include <Qt3DExtras/qkeyframeanimation.h>
+#include <Qt3DExtras/qanimationgroup.h>
+#include <Qt3DCore/qentity.h>
+
+#include <Qt3DExtras/qt3dextras_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QAnimationControllerPrivate;
+
+class QT3DEXTRASSHARED_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<Qt3DExtras::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<Qt3DExtras::QAnimationGroup *> &animationGroups);
+ void addAnimationGroup(Qt3DExtras::QAnimationGroup *animationGroups);
+ void removeAnimationGroup(Qt3DExtras::QAnimationGroup *animationGroups);
+
+ Q_INVOKABLE int getAnimationIndex(const QString &name) const;
+ Q_INVOKABLE Qt3DExtras::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)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QANIMATIONCONTROLLER_H
diff --git a/src/extras/animations/qanimationcontroller_p.h b/src/extras/animations/qanimationcontroller_p.h
new file mode 100644
index 000000000..dd5079ef5
--- /dev/null
+++ b/src/extras/animations/qanimationcontroller_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** 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 QT3DEXTRAS_QANIMATIONCONTROLLER_P_H
+#define QT3DEXTRAS_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 <Qt3DExtras/QAnimationGroup>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QAnimationControllerPrivate : public QObjectPrivate
+{
+public:
+ QAnimationControllerPrivate();
+
+ QString m_name;
+ int m_activeAnimationGroup;
+ QVector<QAnimationGroup *> m_animationGroups;
+ float m_position;
+ 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);
+
+ Q_DECLARE_PUBLIC(QAnimationController)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QANIMATIONCONTROLLER_P_H
diff --git a/src/extras/animations/qanimationgroup.cpp b/src/extras/animations/qanimationgroup.cpp
new file mode 100644
index 000000000..e9febe811
--- /dev/null
+++ b/src/extras/animations/qanimationgroup.cpp
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** 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 "Qt3DExtras/private/qanimationgroup_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+QAnimationGroupPrivate::QAnimationGroupPrivate()
+ : QObjectPrivate()
+ , m_position(0.0f)
+ , m_duration(0.0f)
+{
+
+}
+
+void QAnimationGroupPrivate::updatePosition(float position)
+{
+ m_position = position;
+ for (QAbstractAnimation *aa : m_animations)
+ aa->setPosition(position);
+}
+
+QAnimationGroup::QAnimationGroup(QObject *parent)
+ : QObject(*new QAnimationGroupPrivate, parent)
+{
+
+}
+
+QString QAnimationGroup::name() const
+{
+ Q_D(const QAnimationGroup);
+ return d->m_name;
+}
+
+QVector<Qt3DExtras::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);
+ }
+}
+
+void QAnimationGroup::setAnimations(const QVector<Qt3DExtras::QAbstractAnimation *> &animations)
+{
+ Q_D(QAnimationGroup);
+ d->m_animations = animations;
+ d->m_duration = 0.0f;
+ for (const Qt3DExtras::QAbstractAnimation *a : animations)
+ d->m_duration = qMax(d->m_duration, a->duration());
+}
+
+void QAnimationGroup::addAnimation(QAbstractAnimation *animation)
+{
+ Q_D(QAnimationGroup);
+ d->m_animations.push_back(animation);
+ d->m_duration = qMax(d->m_duration, animation->duration());
+}
+
+void QAnimationGroup::setPosition(float position)
+{
+ Q_D(QAnimationGroup);
+ if (!qFuzzyCompare(d->m_position, position)) {
+ d->updatePosition(position);
+ emit positionChanged(position);
+ }
+}
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/animations/qanimationgroup.h b/src/extras/animations/qanimationgroup.h
new file mode 100644
index 000000000..4595a2082
--- /dev/null
+++ b/src/extras/animations/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 QT3DEXTRAS_QANIMATIONGROUP_H
+#define QT3DEXTRAS_QANIMATIONGROUP_H
+
+#include <qobject.h>
+
+#include <Qt3DExtras/qabstractanimation.h>
+
+#include <Qt3DExtras/qt3dextras_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QAnimationGroupPrivate;
+
+class QT3DEXTRASSHARED_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<Qt3DExtras::QAbstractAnimation *> animationList();
+ float position() const;
+ float duration() const;
+
+ void setAnimations(const QVector<Qt3DExtras::QAbstractAnimation *> &animations);
+ void addAnimation(Qt3DExtras::QAbstractAnimation *animation);
+ void removeAnimation(Qt3DExtras::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)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QANIMATIONGROUP_H
diff --git a/src/extras/animations/qanimationgroup_p.h b/src/extras/animations/qanimationgroup_p.h
new file mode 100644
index 000000000..cffe44636
--- /dev/null
+++ b/src/extras/animations/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 QT3DEXTRAS_QANIMATIONGROUP_P_H
+#define QT3DEXTRAS_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 <Qt3DExtras/QAnimationGroup>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QAnimationGroupPrivate : public QObjectPrivate
+{
+public:
+ QAnimationGroupPrivate();
+
+ QString m_name;
+ QVector<Qt3DExtras::QAbstractAnimation *> m_animations;
+ float m_position;
+ float m_duration;
+
+ void updatePosition(float position);
+
+ Q_DECLARE_PUBLIC(QAnimationGroup)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QANIMATIONGROUP_P_H
diff --git a/src/extras/animations/qkeyframeanimation.cpp b/src/extras/animations/qkeyframeanimation.cpp
new file mode 100644
index 000000000..425cbe0df
--- /dev/null
+++ b/src/extras/animations/qkeyframeanimation.cpp
@@ -0,0 +1,262 @@
+/****************************************************************************
+**
+** 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 "qkeyframeanimation.h"
+#include "Qt3DExtras/private/qkeyframeanimation_p.h"
+
+#include <cmath>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+QKeyframeAnimationPrivate::QKeyframeAnimationPrivate()
+ : QAbstractAnimationPrivate(QAbstractAnimation::KeyframeAnimation)
+ , m_minposition(0.0f)
+ , m_maxposition(0.0f)
+ , m_prevPosition(-1.0f)
+ , m_target(nullptr)
+ , m_startMode(QKeyframeAnimation::Constant)
+ , m_endMode(QKeyframeAnimation::Constant)
+{
+
+}
+
+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_prevPosition = -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 : d->m_framePositions) {
+ if (p < lastPos || p > d->m_maxposition)
+ qWarning() << "positions not ordered correctly";
+ lastPos = p;
+ }
+ setDuration(d->m_maxposition);
+}
+
+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()
+ && m_prevPosition != m_position) {
+ if (m_position >= m_minposition && m_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;
+ }
+ }
+ } else if (position < m_minposition) {
+ m_target->setRotation(m_keyframes.first()->rotation());
+ m_target->setScale3D(m_keyframes.first()->scale3D());
+ m_target->setTranslation(m_keyframes.first()->translation());
+ } else {
+ m_target->setRotation(m_keyframes.last()->rotation());
+ m_target->setScale3D(m_keyframes.last()->scale3D());
+ m_target->setTranslation(m_keyframes.last()->translation());
+ }
+ m_prevPosition = m_position;
+ }
+}
+
+void QKeyframeAnimation::updateAnimation(float position)
+{
+ Q_D(QKeyframeAnimation);
+ d->calculateFrame(position);
+}
+
+QVector<float> QKeyframeAnimation::framePositions() const
+{
+ Q_D(const QKeyframeAnimation);
+ return d->m_framePositions;
+}
+
+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_prevPosition = -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(QEasingCurve::Type easing)
+{
+ Q_D(QKeyframeAnimation);
+ if (d->m_easing.type() != easing) {
+ d->m_easing.setType(easing);
+ emit easingChanged(easing);
+ }
+}
+
+void QKeyframeAnimation::setTargetName(const QString &name)
+{
+ Q_D(QKeyframeAnimation);
+ 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);
+ }
+}
+
+void QKeyframeAnimation::addKeyframe(Qt3DCore::QTransform *keyframe)
+{
+ Q_D(QKeyframeAnimation);
+ d->m_keyframes.push_back(keyframe);
+}
+
+QString QKeyframeAnimation::targetName() const
+{
+ Q_D(const QKeyframeAnimation);
+ return d->m_targetName;
+}
+
+QEasingCurve::Type QKeyframeAnimation::easing() const
+{
+ Q_D(const QKeyframeAnimation);
+ return d->m_easing.type();
+}
+
+Qt3DCore::QTransform *QKeyframeAnimation::target() const
+{
+ Q_D(const QKeyframeAnimation);
+ return d->m_target;
+}
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/animations/qkeyframeanimation.h b/src/extras/animations/qkeyframeanimation.h
new file mode 100644
index 000000000..178c9dbf1
--- /dev/null
+++ b/src/extras/animations/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 QT3DEXTRAS_QKEYFRAMEANIMATION_H
+#define QT3DEXTRAS_QKEYFRAMEANIMATION_H
+
+#include <Qt3DCore/qtransform.h>
+
+#include <Qt3DExtras/qabstractanimation.h>
+#include <Qt3DExtras/qt3dextras_global.h>
+
+#include <QtCore/qeasingcurve.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QKeyframeAnimationPrivate;
+
+class QT3DEXTRASSHARED_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::Type 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::Type 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(QEasingCurve::Type 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(QEasingCurve::Type easing);
+ void targetNameChanged(const QString &name);
+ void startModeChanged(RepeatMode startMode);
+ void endModeChanged(RepeatMode endMode);
+
+private:
+ void updateAnimation(float position);
+
+ Q_DECLARE_PRIVATE(QKeyframeAnimation)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QKEYFRAMEANIMATION_H
diff --git a/src/extras/animations/qkeyframeanimation_p.h b/src/extras/animations/qkeyframeanimation_p.h
new file mode 100644
index 000000000..0095b9432
--- /dev/null
+++ b/src/extras/animations/qkeyframeanimation_p.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 QT3DEXTRAS_QKEYFRAMEANIMATION_P_H
+#define QT3DEXTRAS_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 <Qt3DExtras/qkeyframeanimation.h>
+#include <private/qabstractanimation_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QKeyframeAnimationPrivate : public QAbstractAnimationPrivate
+{
+public:
+ QKeyframeAnimationPrivate();
+
+ void calculateFrame(float position);
+
+ float m_prevPosition;
+ 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)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QKEYFRAMEANIMATION_P_H
diff --git a/src/extras/animations/qmorphinganimation.cpp b/src/extras/animations/qmorphinganimation.cpp
new file mode 100644
index 000000000..e7fe05147
--- /dev/null
+++ b/src/extras/animations/qmorphinganimation.cpp
@@ -0,0 +1,280 @@
+/****************************************************************************
+**
+** 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 "qmorphinganimation.h"
+#include <private/qmorphinganimation_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+QMorphingAnimationPrivate::QMorphingAnimationPrivate()
+ : QAbstractAnimationPrivate(QAbstractAnimation::MorphingAnimation)
+ , m_flattened(nullptr)
+ , m_method(QMorphingAnimation::Relative)
+ , m_interpolator(0.0f)
+ , m_target(nullptr)
+ , m_currentTarget(nullptr)
+{
+ m_easing.setType(QEasingCurve::InOutCubic);
+}
+
+QMorphingAnimationPrivate::~QMorphingAnimationPrivate()
+{
+ for (QVector<float> *weights : m_weights)
+ delete weights;
+}
+
+void QMorphingAnimationPrivate::updateAnimation(float position)
+{
+ Q_Q(QMorphingAnimation);
+ if (!m_target || !m_target->geometry())
+ return;
+
+ m_morphKey.resize(m_morphTargets.size());
+
+ for (int i = 0; i < m_targetPositions.size() - 1; ++i) {
+ if (position > m_targetPositions.at(i) && position <= m_targetPositions.at(i + 1)) {
+ float 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;
+ float sum = 0.0f;
+ QVector<int> relevantValues;
+ 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);
+ 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";
+ }
+ if (!qFuzzyCompare(interpolator, m_interpolator)) {
+ if (m_method == QMorphingAnimation::Normalized)
+ m_interpolator = interpolator;
+ else
+ m_interpolator = -interpolator;
+ emit q->interpolatorChanged(m_interpolator);
+ }
+ return;
+ }
+ }
+}
+
+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("Target");
+ targetAttributes[i]->setName(targetName);
+ geometry->addAttribute(targetAttributes.at(i));
+ }
+ }
+ m_currentTarget = target;
+}
+
+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::Type QMorphingAnimation::easing() const
+{
+ Q_D(const QMorphingAnimation);
+ return d->m_easing.type();
+}
+
+void QMorphingAnimation::setMorphTargets(const QVector<Qt3DExtras::QMorphTarget *> &targets)
+{
+ Q_D(QMorphingAnimation);
+ d->m_morphTargets = targets;
+ d->m_attributeNames = targets[0]->attributeNames();
+}
+
+void QMorphingAnimation::addMorphTarget(Qt3DExtras::QMorphTarget *target)
+{
+ Q_D(QMorphingAnimation);
+ if (!d->m_morphTargets.contains(target))
+ d->m_morphTargets.push_back(target);
+}
+
+void QMorphingAnimation::removeMorphTarget(Qt3DExtras::QMorphTarget *target)
+{
+ Q_D(QMorphingAnimation);
+ d->m_morphTargets.removeAll(target);
+}
+
+void QMorphingAnimation::setTargetPositions(const QVector<float> &targetPositions)
+{
+ Q_D(QMorphingAnimation);
+ d->m_targetPositions = targetPositions;
+ emit targetPositionsChanged(targetPositions);
+ 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>();
+ }
+ }
+}
+
+void QMorphingAnimation::setTarget(Qt3DRender::QGeometryRenderer *target)
+{
+ Q_D(QMorphingAnimation);
+ if (d->m_target != target) {
+ d->m_target = target;
+ emit targetChanged(target);
+ }
+}
+
+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;
+}
+
+QVector<float> QMorphingAnimation::getWeights(int positionIndex)
+{
+ Q_D(QMorphingAnimation);
+ return *d->m_weights[positionIndex];
+}
+
+QVector<Qt3DExtras::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;
+ emit methodChanged(method);
+ }
+}
+
+void QMorphingAnimation::setEasing(QEasingCurve::Type easing)
+{
+ Q_D(QMorphingAnimation);
+ if (d->m_easing.type() != easing) {
+ d->m_easing.setType(easing);
+ emit easingChanged(easing);
+ }
+}
+
+void QMorphingAnimation::updateAnimation(float position)
+{
+ Q_D(QMorphingAnimation);
+ d->updateAnimation(position);
+}
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/animations/qmorphinganimation.h b/src/extras/animations/qmorphinganimation.h
new file mode 100644
index 000000000..f8ca71ec9
--- /dev/null
+++ b/src/extras/animations/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 QT3DEXTRAS_QMORPHINGANIMATION_H
+#define QT3DEXTRAS_QMORPHINGANIMATION_H
+
+#include <Qt3DRender/qgeometryrenderer.h>
+
+#include <Qt3DExtras/qabstractanimation.h>
+#include <Qt3DExtras/qmorphtarget.h>
+#include <Qt3DExtras/qt3dextras_global.h>
+
+#include <QtCore/qeasingcurve.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QMorphingAnimationPrivate;
+
+class QT3DEXTRASSHARED_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::Type 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::Type easing() const;
+
+ void setMorphTargets(const QVector<Qt3DExtras::QMorphTarget *> &targets);
+ void addMorphTarget(Qt3DExtras::QMorphTarget *target);
+ void removeMorphTarget(Qt3DExtras::QMorphTarget *target);
+
+ void setWeights(int positionIndex, const QVector<float> &weights);
+ QVector<float> getWeights(int positionIndex);
+
+ QVector<Qt3DExtras::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(QEasingCurve::Type 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(QEasingCurve::Type easing);
+
+private:
+
+ void updateAnimation(float position);
+
+ Q_DECLARE_PRIVATE(QMorphingAnimation)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QMORPHINGANIMATION_H
diff --git a/src/extras/animations/qmorphinganimation_p.h b/src/extras/animations/qmorphinganimation_p.h
new file mode 100644
index 000000000..e4a18f199
--- /dev/null
+++ b/src/extras/animations/qmorphinganimation_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** 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 QT3DEXTRAS_QMORPHINGANIMATION_P_H
+#define QT3DEXTRAS_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 <Qt3DExtras/qmorphinganimation.h>
+
+#include <private/qobject_p.h>
+#include <private/qabstractanimation_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QMorphingAnimationPrivate : public QAbstractAnimationPrivate
+{
+public:
+ QMorphingAnimationPrivate();
+ ~QMorphingAnimationPrivate();
+
+ void updateAnimation(float position);
+ void setTargetInterpolated(int morphTarget);
+
+ QVector<float> m_targetPositions;
+ QVector<QVector<float>*> m_weights;
+ QVector<float> m_morphKey;
+ QStringList m_attributeNames;
+ QVector<Qt3DExtras::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)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QMORPHINGANIMATION_P_H
diff --git a/src/extras/animations/qmorphtarget.cpp b/src/extras/animations/qmorphtarget.cpp
new file mode 100644
index 000000000..0c327a490
--- /dev/null
+++ b/src/extras/animations/qmorphtarget.cpp
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** 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 "qmorphtarget.h"
+#include "Qt3DExtras/private/qmorphtarget_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+QMorphTargetPrivate::QMorphTargetPrivate()
+ : QObjectPrivate()
+{
+
+}
+
+void QMorphTargetPrivate::updateAttributeNames()
+{
+ m_attributeNames.clear();
+ for (const Qt3DRender::QAttribute *attr : m_targetAttributes)
+ m_attributeNames.push_back(attr->name());
+}
+
+QMorphTarget::QMorphTarget(QObject *parent)
+ : QObject(*new QMorphTargetPrivate, parent)
+{
+
+}
+
+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;
+}
+
+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);
+}
+
+void QMorphTarget::addAttribute(Qt3DRender::QAttribute *attribute)
+{
+ Q_D(QMorphTarget);
+ for (const Qt3DRender::QAttribute *attr : 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);
+}
+
+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);
+ }
+}
+
+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;
+}
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/animations/qmorphtarget.h b/src/extras/animations/qmorphtarget.h
new file mode 100644
index 000000000..64c3037cb
--- /dev/null
+++ b/src/extras/animations/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 QT3DEXTRAS_QMORPHTARGET_H
+#define QT3DEXTRAS_QMORPHTARGET_H
+
+#include <Qt3DRender/qattribute.h>
+#include <Qt3DRender/qgeometry.h>
+
+#include <QtCore/qstringlist.h>
+
+#include <Qt3DExtras/qt3dextras_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QMorphTargetPrivate;
+
+class QT3DEXTRASSHARED_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)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QMORPHTARGET_H
diff --git a/src/extras/animations/qmorphtarget_p.h b/src/extras/animations/qmorphtarget_p.h
new file mode 100644
index 000000000..7d42f8eb4
--- /dev/null
+++ b/src/extras/animations/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 QT3DEXTRAS_QMORPHTARGET_P_H
+#define QT3DEXTRAS_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 <Qt3DExtras/qmorphtarget.h>
+
+#include <private/qobject_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QMorphTargetPrivate : public QObjectPrivate
+{
+public:
+ QMorphTargetPrivate();
+
+ void updateAttributeNames();
+
+ QStringList m_attributeNames;
+ QVector<Qt3DRender::QAttribute *> m_targetAttributes;
+
+ Q_DECLARE_PUBLIC(QMorphTarget)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QMORPHTARGET_P_H
diff --git a/src/extras/animations/qvertexblendanimation.cpp b/src/extras/animations/qvertexblendanimation.cpp
new file mode 100644
index 000000000..1b45992fe
--- /dev/null
+++ b/src/extras/animations/qvertexblendanimation.cpp
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** 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 Qt3DExtras {
+
+QVertexBlendAnimationPrivate::QVertexBlendAnimationPrivate()
+ : QAbstractAnimationPrivate(QAbstractAnimation::VertexBlendAnimation)
+ , 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;
+ }
+ }
+ }
+}
+
+static Qt3DRender::QAttribute *findAttribute(QVector<Qt3DRender::QAttribute *> &attributes,
+ QString name)
+{
+ for (Qt3DRender::QAttribute *gattr : attributes) {
+ if (gattr->name() == name)
+ return gattr;
+ }
+ return nullptr;
+}
+
+void QVertexBlendAnimationPrivate::updateAnimation(float position)
+{
+ Q_Q(QVertexBlendAnimation);
+ if (!m_target || !m_target->geometry())
+ return;
+
+ Qt3DExtras::QMorphTarget *base;
+ Qt3DExtras::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("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);
+ }
+}
+
+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;
+}
+
+void QVertexBlendAnimation::setMorphTargets(const QVector<Qt3DExtras::QMorphTarget *> &targets)
+{
+ Q_D(QVertexBlendAnimation);
+ d->m_morphTargets = targets;
+}
+
+void QVertexBlendAnimation::addMorphTarget(Qt3DExtras::QMorphTarget *target)
+{
+ Q_D(QVertexBlendAnimation);
+ if (!d->m_morphTargets.contains(target))
+ d->m_morphTargets.push_back(target);
+}
+
+void QVertexBlendAnimation::removeMorphTarget(Qt3DExtras::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);
+ }
+}
+
+QVector<Qt3DExtras::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);
+}
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/animations/qvertexblendanimation.h b/src/extras/animations/qvertexblendanimation.h
new file mode 100644
index 000000000..ebd313e83
--- /dev/null
+++ b/src/extras/animations/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 QT3DEXTRAS_QVERTEXBLENDANIMATION_H
+#define QT3DEXTRAS_QVERTEXBLENDANIMATION_H
+
+#include <Qt3DRender/qgeometryrenderer.h>
+#include <Qt3DExtras/qabstractanimation.h>
+#include <Qt3DExtras/qmorphtarget.h>
+
+#include <Qt3DExtras/qt3dextras_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QVertexBlendAnimationPrivate;
+
+class QT3DEXTRASSHARED_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<Qt3DExtras::QMorphTarget *> &targets);
+ void addMorphTarget(Qt3DExtras::QMorphTarget *target);
+ void removeMorphTarget(Qt3DExtras::QMorphTarget *target);
+
+ QVector<Qt3DExtras::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)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QVERTEXBLENDANIMATION_H
diff --git a/src/extras/animations/qvertexblendanimation_p.h b/src/extras/animations/qvertexblendanimation_p.h
new file mode 100644
index 000000000..812953e04
--- /dev/null
+++ b/src/extras/animations/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 QT3DEXTRAS_QVERTEXBLENDANIMATION_P_H
+#define QT3DEXTRAS_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 <Qt3DExtras/qvertexblendanimation.h>
+
+#include <private/qobject_p.h>
+#include <private/qabstractanimation_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+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<Qt3DExtras::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)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QVertexBlendANIMATION_P_H
diff --git a/src/extras/defaults/defaults.pri b/src/extras/defaults/defaults.pri
index 04cd87246..21ef6fef6 100644
--- a/src/extras/defaults/defaults.pri
+++ b/src/extras/defaults/defaults.pri
@@ -4,7 +4,6 @@ HEADERS += \
$$PWD/qphongmaterial.h \
$$PWD/qphongmaterial_p.h \
$$PWD/qdiffusemapmaterial_p.h \
- $$PWD/qdiffusemapmaterial.h \
$$PWD/qnormaldiffusespecularmapmaterial.h \
$$PWD/qnormaldiffusespecularmapmaterial_p.h \
$$PWD/qnormaldiffusemapmaterial.h \
@@ -27,7 +26,10 @@ HEADERS += \
$$PWD/qfirstpersoncameracontroller.h \
$$PWD/qfirstpersoncameracontroller_p.h \
$$PWD/qorbitcameracontroller.h \
- $$PWD/qorbitcameracontroller_p.h
+ $$PWD/qorbitcameracontroller_p.h \
+ $$PWD/qmorphphongmaterial.h \
+ $$PWD/qmorphphongmaterial_p.h \
+ $$PWD/qdiffusemapmaterial.h
SOURCES += \
$$PWD/qphongmaterial.cpp \
@@ -43,5 +45,6 @@ SOURCES += \
$$PWD/qphongalphamaterial.cpp \
$$PWD/qt3dwindow.cpp \
$$PWD/qfirstpersoncameracontroller.cpp \
- $$PWD/qorbitcameracontroller.cpp
+ $$PWD/qorbitcameracontroller.cpp \
+ $$PWD/qmorphphongmaterial.cpp
diff --git a/src/extras/defaults/qmorphphongmaterial.cpp b/src/extras/defaults/qmorphphongmaterial.cpp
new file mode 100644
index 000000000..22f520de5
--- /dev/null
+++ b/src/extras/defaults/qmorphphongmaterial.cpp
@@ -0,0 +1,291 @@
+/****************************************************************************
+**
+** 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 "qmorphphongmaterial.h"
+#include "qmorphphongmaterial_p.h"
+#include <Qt3DRender/qfilterkey.h>
+#include <Qt3DRender/qmaterial.h>
+#include <Qt3DRender/qeffect.h>
+#include <Qt3DRender/qtechnique.h>
+#include <Qt3DRender/qshaderprogram.h>
+#include <Qt3DRender/qparameter.h>
+#include <Qt3DRender/qrenderpass.h>
+#include <Qt3DRender/qgraphicsapifilter.h>
+#include <QUrl>
+#include <QVector3D>
+#include <QVector4D>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+QMorphPhongMaterialPrivate::QMorphPhongMaterialPrivate()
+ : QMaterialPrivate()
+ , m_phongEffect(new QEffect())
+ , m_ambientParameter(new QParameter(QStringLiteral("ka"), QColor::fromRgbF(0.05f, 0.05f, 0.05f, 1.0f)))
+ , m_diffuseParameter(new QParameter(QStringLiteral("kd"), QColor::fromRgbF(0.7f, 0.7f, 0.7f, 1.0f)))
+ , m_specularParameter(new QParameter(QStringLiteral("ks"), QColor::fromRgbF(0.01f, 0.01f, 0.01f, 1.0f)))
+ , m_shininessParameter(new QParameter(QStringLiteral("shininess"), 150.0f))
+ , m_interpolatorParameter(new QParameter(QStringLiteral("interpolator"), 0.0f))
+ , m_phongGL3Technique(new QTechnique())
+ , m_phongGL2Technique(new QTechnique())
+ , m_phongES2Technique(new QTechnique())
+ , m_phongGL3RenderPass(new QRenderPass())
+ , m_phongGL2RenderPass(new QRenderPass())
+ , m_phongES2RenderPass(new QRenderPass())
+ , m_phongGL3Shader(new QShaderProgram())
+ , m_phongGL2ES2Shader(new QShaderProgram())
+ , m_filterKey(new QFilterKey)
+{
+}
+
+void QMorphPhongMaterialPrivate::init()
+{
+ connect(m_ambientParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QMorphPhongMaterialPrivate::handleAmbientChanged);
+ connect(m_diffuseParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QMorphPhongMaterialPrivate::handleDiffuseChanged);
+ connect(m_specularParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QMorphPhongMaterialPrivate::handleSpecularChanged);
+ connect(m_shininessParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QMorphPhongMaterialPrivate::handleShininessChanged);
+ connect(m_interpolatorParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QMorphPhongMaterialPrivate::handleInterpolatorChanged);
+
+ m_phongGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/morphphong.vert"))));
+ m_phongGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/phong.frag"))));
+ m_phongGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/morphphong.vert"))));
+ m_phongGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/phong.frag"))));
+
+ m_phongGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_phongGL3Technique->graphicsApiFilter()->setMajorVersion(3);
+ m_phongGL3Technique->graphicsApiFilter()->setMinorVersion(1);
+ m_phongGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
+
+ m_phongGL2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_phongGL2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_phongGL2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_phongGL2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ m_phongES2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES);
+ m_phongES2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_phongES2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_phongES2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ m_phongGL3RenderPass->setShaderProgram(m_phongGL3Shader);
+ m_phongGL2RenderPass->setShaderProgram(m_phongGL2ES2Shader);
+ m_phongES2RenderPass->setShaderProgram(m_phongGL2ES2Shader);
+
+ m_phongGL3Technique->addRenderPass(m_phongGL3RenderPass);
+ m_phongGL2Technique->addRenderPass(m_phongGL2RenderPass);
+ m_phongES2Technique->addRenderPass(m_phongES2RenderPass);
+
+ Q_Q(QMorphPhongMaterial);
+ m_filterKey->setParent(q);
+ m_filterKey->setName(QStringLiteral("renderingStyle"));
+ m_filterKey->setValue(QStringLiteral("forward"));
+
+ m_phongGL3Technique->addFilterKey(m_filterKey);
+ m_phongGL2Technique->addFilterKey(m_filterKey);
+ m_phongES2Technique->addFilterKey(m_filterKey);
+
+ m_phongEffect->addTechnique(m_phongGL3Technique);
+ m_phongEffect->addTechnique(m_phongGL2Technique);
+ m_phongEffect->addTechnique(m_phongES2Technique);
+
+ m_phongEffect->addParameter(m_ambientParameter);
+ m_phongEffect->addParameter(m_diffuseParameter);
+ m_phongEffect->addParameter(m_specularParameter);
+ m_phongEffect->addParameter(m_shininessParameter);
+ m_phongEffect->addParameter(m_interpolatorParameter);
+
+ q->setEffect(m_phongEffect);
+}
+
+void QMorphPhongMaterialPrivate::handleAmbientChanged(const QVariant &var)
+{
+ Q_Q(QMorphPhongMaterial);
+ emit q->ambientChanged(var.value<QColor>());
+}
+
+void QMorphPhongMaterialPrivate::handleDiffuseChanged(const QVariant &var)
+{
+ Q_Q(QMorphPhongMaterial);
+ emit q->diffuseChanged(var.value<QColor>());
+}
+
+void QMorphPhongMaterialPrivate::handleSpecularChanged(const QVariant &var)
+{
+ Q_Q(QMorphPhongMaterial);
+ emit q->specularChanged(var.value<QColor>());
+}
+
+void QMorphPhongMaterialPrivate::handleShininessChanged(const QVariant &var)
+{
+ Q_Q(QMorphPhongMaterial);
+ emit q->shininessChanged(var.toFloat());
+}
+
+void QMorphPhongMaterialPrivate::handleInterpolatorChanged(const QVariant &var)
+{
+ Q_Q(QMorphPhongMaterial);
+ emit q->interpolatorChanged(var.toFloat());
+}
+
+/*!
+ \class Qt3DExtras::QMorphPhongMaterial
+ \brief The QMorphPhongMaterial class provides a default implementation of the phong lighting effect.
+ \inmodule Qt3DExtras
+ \since 5.7
+ \inherits Qt3DRender::QMaterial
+
+ The phong lighting effect is based on the combination of 3 lighting components ambient, diffuse
+ and specular. The relative strengths of these components are controlled by means of their
+ reflectivity coefficients which are modelled as RGB triplets:
+
+ \list
+ \li Ambient is the color that is emitted by an object without any other light source.
+ \li Diffuse is the color that is emitted for rought surface reflections with the lights.
+ \li Specular is the color emitted for shiny surface reflections with the lights.
+ \li The shininess of a surface is controlled by a float property.
+ \endlist
+
+ This material uses an effect with a single render pass approach and performs per fragment
+ lighting. Techniques are provided for OpenGL 2, OpenGL 3 or above as well as OpenGL ES 2.
+*/
+
+/*!
+ Constructs a new QMorphPhongMaterial instance with parent object \a parent.
+*/
+QMorphPhongMaterial::QMorphPhongMaterial(QNode *parent)
+ : QMaterial(*new QMorphPhongMaterialPrivate, parent)
+{
+ Q_D(QMorphPhongMaterial);
+ d->init();
+}
+
+/*!
+ Destroys the QMorphPhongMaterial.
+*/
+QMorphPhongMaterial::~QMorphPhongMaterial()
+{
+}
+
+/*!
+ \property QMorphPhongMaterial::ambient
+
+ Holds the ambient color.
+*/
+QColor QMorphPhongMaterial::ambient() const
+{
+ Q_D(const QMorphPhongMaterial);
+ return d->m_ambientParameter->value().value<QColor>();
+}
+
+/*!
+ \property QMorphPhongMaterial::diffuse
+
+ Holds the diffuse color.
+*/
+QColor QMorphPhongMaterial::diffuse() const
+{
+ Q_D(const QMorphPhongMaterial);
+ return d->m_diffuseParameter->value().value<QColor>();
+}
+
+/*!
+ \property QMorphPhongMaterial::specular
+
+ Holds the specular color.
+*/
+QColor QMorphPhongMaterial::specular() const
+{
+ Q_D(const QMorphPhongMaterial);
+ return d->m_specularParameter->value().value<QColor>();
+}
+
+/*!
+ \property QMorphPhongMaterial::shininess
+
+ Holds the shininess exponent.
+*/
+float QMorphPhongMaterial::shininess() const
+{
+ Q_D(const QMorphPhongMaterial);
+ return d->m_shininessParameter->value().toFloat();
+}
+
+float QMorphPhongMaterial::interpolator() const
+{
+ Q_D(const QMorphPhongMaterial);
+ return d->m_interpolatorParameter->value().toFloat();
+}
+
+void QMorphPhongMaterial::setAmbient(const QColor &ambient)
+{
+ Q_D(QMorphPhongMaterial);
+ d->m_ambientParameter->setValue(ambient);
+}
+
+void QMorphPhongMaterial::setDiffuse(const QColor &diffuse)
+{
+ Q_D(QMorphPhongMaterial);
+ d->m_diffuseParameter->setValue(diffuse);
+}
+
+void QMorphPhongMaterial::setSpecular(const QColor &specular)
+{
+ Q_D(QMorphPhongMaterial);
+ d->m_specularParameter->setValue(specular);
+}
+
+void QMorphPhongMaterial::setShininess(float shininess)
+{
+ Q_D(QMorphPhongMaterial);
+ d->m_shininessParameter->setValue(shininess);
+}
+
+void QMorphPhongMaterial::setInterpolator(float interpolator)
+{
+ Q_D(QMorphPhongMaterial);
+ d->m_interpolatorParameter->setValue(interpolator);
+}
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/defaults/qmorphphongmaterial.h b/src/extras/defaults/qmorphphongmaterial.h
new file mode 100644
index 000000000..3b65088b1
--- /dev/null
+++ b/src/extras/defaults/qmorphphongmaterial.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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 QT3DEXTRAS_QMORPHPHONGMATERIAL_H
+#define QT3DEXTRAS_QMORPHPHONGMATERIAL_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qmaterial.h>
+#include <QColor>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QMorphPhongMaterialPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QMorphPhongMaterial : public Qt3DRender::QMaterial
+{
+ Q_OBJECT
+ Q_PROPERTY(QColor ambient READ ambient WRITE setAmbient NOTIFY ambientChanged)
+ Q_PROPERTY(QColor diffuse READ diffuse WRITE setDiffuse NOTIFY diffuseChanged)
+ Q_PROPERTY(QColor specular READ specular WRITE setSpecular NOTIFY specularChanged)
+ Q_PROPERTY(float shininess READ shininess WRITE setShininess NOTIFY shininessChanged)
+ Q_PROPERTY(float interpolator READ interpolator WRITE setInterpolator NOTIFY interpolatorChanged)
+
+public:
+ explicit QMorphPhongMaterial(Qt3DCore::QNode *parent = nullptr);
+ ~QMorphPhongMaterial();
+
+ QColor ambient() const;
+ QColor diffuse() const;
+ QColor specular() const;
+ float shininess() const;
+ float interpolator() const;
+
+public Q_SLOTS:
+ void setAmbient(const QColor &ambient);
+ void setDiffuse(const QColor &diffuse);
+ void setSpecular(const QColor &specular);
+ void setShininess(float shininess);
+ void setInterpolator(float interpolator);
+
+Q_SIGNALS:
+ void ambientChanged(const QColor &ambient);
+ void diffuseChanged(const QColor &diffuse);
+ void specularChanged(const QColor &specular);
+ void shininessChanged(float shininess);
+ void interpolatorChanged(float interpolator);
+
+private:
+ Q_DECLARE_PRIVATE(QMorphPhongMaterial)
+};
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QMORPHPHONGMATERIAL_H
+
diff --git a/src/extras/defaults/qmorphphongmaterial_p.h b/src/extras/defaults/qmorphphongmaterial_p.h
new file mode 100644
index 000000000..25bff9042
--- /dev/null
+++ b/src/extras/defaults/qmorphphongmaterial_p.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** 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 QT3DEXTRAS_QMORPHPHONGMATERIAL_P_H
+#define QT3DEXTRAS_QMORPHPHONGMATERIAL_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 <Qt3DRender/private/qmaterial_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QFilterKey;
+class QEffect;
+class QTechnique;
+class QParameter;
+class QShaderProgram;
+class QRenderPass;
+
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QMorphPhongMaterial;
+
+class QMorphPhongMaterialPrivate : public Qt3DRender::QMaterialPrivate
+{
+public:
+ QMorphPhongMaterialPrivate();
+
+ void init();
+
+ void handleAmbientChanged(const QVariant &var);
+ void handleDiffuseChanged(const QVariant &var);
+ void handleSpecularChanged(const QVariant &var);
+ void handleShininessChanged(const QVariant &var);
+ void handleInterpolatorChanged(const QVariant &var);
+
+ Qt3DRender::QEffect *m_phongEffect;
+ Qt3DRender::QParameter *m_ambientParameter;
+ Qt3DRender::QParameter *m_diffuseParameter;
+ Qt3DRender::QParameter *m_specularParameter;
+ Qt3DRender::QParameter *m_shininessParameter;
+ Qt3DRender::QParameter *m_interpolatorParameter;
+ Qt3DRender::QTechnique *m_phongGL3Technique;
+ Qt3DRender::QTechnique *m_phongGL2Technique;
+ Qt3DRender::QTechnique *m_phongES2Technique;
+ Qt3DRender::QRenderPass *m_phongGL3RenderPass;
+ Qt3DRender::QRenderPass *m_phongGL2RenderPass;
+ Qt3DRender::QRenderPass *m_phongES2RenderPass;
+ Qt3DRender::QShaderProgram *m_phongGL3Shader;
+ Qt3DRender::QShaderProgram *m_phongGL2ES2Shader;
+ Qt3DRender::QFilterKey *m_filterKey;
+
+ Q_DECLARE_PUBLIC(QMorphPhongMaterial)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QPHONGMATERIAL_P_H
+
+
diff --git a/src/extras/extras.pro b/src/extras/extras.pro
index d723554ca..d11172005 100644
--- a/src/extras/extras.pro
+++ b/src/extras/extras.pro
@@ -9,6 +9,7 @@ DEFINES += QT_NO_FOREACH
load(qt_module)
+include (animations/animations.pri)
include (geometries/geometries.pri)
include (3dtext/3dtext.pri)
include (defaults/defaults.pri)
diff --git a/src/extras/extras.qrc b/src/extras/extras.qrc
index e7b1c1d9a..121bfd029 100644
--- a/src/extras/extras.qrc
+++ b/src/extras/extras.qrc
@@ -39,5 +39,7 @@
<file>shaders/gl3/unlittexture.frag</file>
<file>shaders/es2/unlittexture.frag</file>
<file>shaders/es2/unlittexture.vert</file>
+ <file>shaders/gl3/morphphong.vert</file>
+ <file>shaders/es2/morphphong.vert</file>
</qresource>
</RCC>
diff --git a/src/extras/shaders/es2/morphphong.vert b/src/extras/shaders/es2/morphphong.vert
new file mode 100644
index 000000000..d091e87c0
--- /dev/null
+++ b/src/extras/shaders/es2/morphphong.vert
@@ -0,0 +1,32 @@
+attribute vec3 vertexPosition;
+attribute vec3 vertexNormal;
+attribute vec3 vertexPositionTarget;
+attribute vec3 vertexNormalTarget;
+
+varying vec3 worldPosition;
+varying vec3 worldNormal;
+
+uniform mat4 modelMatrix;
+uniform mat3 modelNormalMatrix;
+uniform mat4 modelViewProjection;
+uniform float interpolator;
+
+void main()
+{
+ vec3 morphPos;
+ vec3 morphNormal;
+ if (interpolator > 0.0) {
+ // normalized
+ morphPos = mix(vertexPosition, vertexPositionTarget, interpolator);
+ morphNormal = normalize(mix(vertexNormal, vertexNormalTarget, interpolator));
+ } else {
+ // relative
+ morphPos = vertexPosition + vertexPositionTarget * abs(interpolator);
+ morphNormal = normalize(vertexNormal + vertexNormalTarget * abs(interpolator));
+ }
+
+ worldNormal = normalize( modelNormalMatrix * morphPos );
+ worldPosition = vec3( modelMatrix * vec4( morphPos, 1.0 ) );
+
+ gl_Position = modelViewProjection * vec4( morphPos, 1.0 );
+}
diff --git a/src/extras/shaders/gl3/morphphong.vert b/src/extras/shaders/gl3/morphphong.vert
new file mode 100644
index 000000000..c74fbdcff
--- /dev/null
+++ b/src/extras/shaders/gl3/morphphong.vert
@@ -0,0 +1,34 @@
+#version 150 core
+
+in vec3 vertexPosition;
+in vec3 vertexNormal;
+in vec3 vertexPositionTarget;
+in vec3 vertexNormalTarget;
+
+out vec3 worldPosition;
+out vec3 worldNormal;
+
+uniform mat4 modelMatrix;
+uniform mat3 modelNormalMatrix;
+uniform mat4 modelViewProjection;
+uniform float interpolator;
+
+void main()
+{
+ vec3 morphPos;
+ vec3 morphNormal;
+ if (interpolator > 0.0) {
+ // normalized
+ morphPos = mix(vertexPosition, vertexPositionTarget, interpolator);
+ morphNormal = normalize(mix(vertexNormal, vertexNormalTarget, interpolator));
+ } else {
+ // relative
+ morphPos = vertexPosition + vertexPositionTarget * abs(interpolator);
+ morphNormal = normalize(vertexNormal + vertexNormalTarget * abs(interpolator));
+ }
+
+ worldNormal = normalize( modelNormalMatrix * morphPos );
+ worldPosition = vec3( modelMatrix * vec4( morphPos, 1.0 ) );
+
+ gl_Position = modelViewProjection * vec4( morphPos, 1.0 );
+}
diff --git a/src/plugins/sceneparsers/assimp/assimpimporter.cpp b/src/plugins/sceneparsers/assimp/assimpimporter.cpp
index dba13a291..66c219fe9 100644
--- a/src/plugins/sceneparsers/assimp/assimpimporter.cpp
+++ b/src/plugins/sceneparsers/assimp/assimpimporter.cpp
@@ -51,9 +51,12 @@
#include <Qt3DRender/qattribute.h>
#include <Qt3DRender/qtexture.h>
#include <Qt3DRender/qtextureimagedatagenerator.h>
+#include <Qt3DExtras/qmorphphongmaterial.h>
#include <Qt3DExtras/qdiffusemapmaterial.h>
#include <Qt3DExtras/qdiffusespecularmapmaterial.h>
#include <Qt3DExtras/qphongmaterial.h>
+#include <Qt3DExtras/qkeyframeanimation.h>
+#include <Qt3DExtras/qmorphinganimation.h>
#include <QFileInfo>
#include <QColor>
#include <qmath.h>
@@ -413,7 +416,15 @@ Qt3DCore::QEntity *AssimpImporter::scene(const QString &id)
// Builds the Qt3D scene using the Assimp aiScene
// and the various dicts filled previously by parse
- return node(rootNode);
+ Qt3DCore::QEntity *n = node(rootNode);
+ if (m_scene->m_animations.size() > 0) {
+ qWarning() << "No target found for " << m_scene->m_animations.size() << " animations!";
+
+ for (Qt3DExtras::QKeyframeAnimation *anim : m_scene->m_animations)
+ delete anim;
+ m_scene->m_animations.clear();
+ }
+ return n;
}
/*!
@@ -429,6 +440,17 @@ Qt3DCore::QEntity *AssimpImporter::node(const QString &id)
return node(n);
}
+template <typename T>
+void findAnimationsForNode(QVector<T *> &animations, QVector<T *> &result, const QString &name)
+{
+ for (T *anim : animations) {
+ if (anim->targetName() == name) {
+ result.push_back(anim);
+ animations.removeAll(anim);
+ }
+ }
+}
+
/*!
* Returns a Node from an Assimp aiNode \a node.
*/
@@ -442,13 +464,54 @@ Qt3DCore::QEntity *AssimpImporter::node(aiNode *node)
// Add Meshes to the node
for (uint i = 0; i < node->mNumMeshes; i++) {
uint meshIdx = node->mMeshes[i];
+ QMaterial *material = nullptr;
QGeometryRenderer *mesh = m_scene->m_meshes[meshIdx];
// mesh material
uint materialIndex = m_scene->m_aiScene->mMeshes[meshIdx]->mMaterialIndex;
+
if (m_scene->m_materials.contains(materialIndex))
- entityNode->addComponent(m_scene->m_materials[materialIndex]);
- // mesh
- entityNode->addComponent(mesh);
+ material = m_scene->m_materials[materialIndex];
+
+ QList<Qt3DExtras::QMorphingAnimation *> morphingAnimations
+ = mesh->findChildren<Qt3DExtras::QMorphingAnimation *>();
+ if (morphingAnimations.size() > 0) {
+ material = new Qt3DExtras::QMorphPhongMaterial(entityNode);
+
+ QVector<Qt3DExtras::QMorphingAnimation *> animations;
+ findAnimationsForNode<Qt3DExtras::QMorphingAnimation>(m_scene->m_morphAnimations,
+ animations,
+ aiStringToQString(node->mName));
+ const auto morphTargetList = morphingAnimations.at(0)->morphTargetList();
+ for (Qt3DExtras::QMorphingAnimation *anim : animations) {
+ anim->setParent(entityNode);
+ anim->setTarget(mesh);
+ anim->setMorphTargets(morphTargetList);
+ }
+
+ for (int j = 0; j < animations.size(); ++j) {
+ QObject::connect(animations[j], &Qt3DExtras::QMorphingAnimation::interpolatorChanged,
+ (Qt3DExtras::QMorphPhongMaterial *)material,
+ &Qt3DExtras::QMorphPhongMaterial::setInterpolator);
+ }
+ morphingAnimations[0]->deleteLater();
+ }
+
+ if (node->mNumMeshes == 1) {
+ if (material)
+ entityNode->addComponent(material);
+ // mesh
+ entityNode->addComponent(mesh);
+ } else {
+ QEntity *childEntity = QAbstractNodeFactory::createNode<Qt3DCore::QEntity>("QEntity");
+ if (material)
+ childEntity->addComponent(material);
+ childEntity->addComponent(mesh);
+ childEntity->setParent(entityNode);
+
+ Qt3DCore::QTransform *transform
+ = QAbstractNodeFactory::createNode<Qt3DCore::QTransform>("QTransform");
+ childEntity->addComponent(transform);
+ }
}
// Add Children to Node
@@ -467,6 +530,16 @@ Qt3DCore::QEntity *AssimpImporter::node(aiNode *node)
transform->setMatrix(qTransformMatrix);
entityNode->addComponent(transform);
+ QVector<Qt3DExtras::QKeyframeAnimation *> animations;
+ findAnimationsForNode<Qt3DExtras::QKeyframeAnimation>(m_scene->m_animations,
+ animations,
+ aiStringToQString(node->mName));
+
+ for (Qt3DExtras::QKeyframeAnimation *anim : animations) {
+ anim->setTarget(transform);
+ anim->setParent(entityNode);
+ }
+
// Add Camera
if (m_scene->m_cameras.contains(node))
m_scene->m_cameras[node]->setParent(entityNode);
@@ -497,7 +570,6 @@ void AssimpImporter::readSceneFile(const QString &path)
m_scene->m_aiScene = m_scene->m_importer->ReadFile(path.toUtf8().constData(),
aiProcess_SortByPType|
aiProcess_Triangulate|
- aiProcess_JoinIdenticalVertices|
aiProcess_GenSmoothNormals|
aiProcess_FlipUVs);
if (m_scene->m_aiScene == nullptr) {
@@ -713,8 +785,136 @@ void AssimpImporter::loadMesh(uint meshIndex)
m_scene->m_meshes[meshIndex] = geometryRenderer;
+ if (mesh->mNumAnimMeshes > 0) {
+
+ aiAnimMesh *animesh = mesh->mAnimMeshes[0];
+
+ if (animesh->mNumVertices != mesh->mNumVertices)
+ return;
+
+ Qt3DExtras::QMorphingAnimation *morphingAnimation
+ = new Qt3DExtras::QMorphingAnimation(geometryRenderer);
+ QVector<QString> names;
+ QVector<Qt3DExtras::QMorphTarget *> targets;
+ uint voff = 0;
+ uint noff = 0;
+ uint tanoff = 0;
+ uint texoff = 0;
+ uint coloff = 0;
+ uint offset = 0;
+ if (animesh->mVertices) {
+ names.push_back(VERTICES_ATTRIBUTE_NAME);
+ offset += 3;
+ }
+ if (animesh->mNormals) {
+ names.push_back(NORMAL_ATTRIBUTE_NAME);
+ noff = offset;
+ offset += 3;
+ }
+ if (animesh->mTangents) {
+ names.push_back(TANGENT_ATTRIBUTE_NAME);
+ tanoff = offset;
+ offset += 3;
+ }
+ if (animesh->mTextureCoords[0]) {
+ names.push_back(TEXTCOORD_ATTRIBUTE_NAME);
+ texoff = offset;
+ offset += 2;
+ }
+ if (animesh->mColors[0]) {
+ names.push_back(COLOR_ATTRIBUTE_NAME);
+ coloff = offset;
+ }
+
+ ushort clumpSize = (animesh->mVertices ? 3 : 0)
+ + (animesh->mNormals ? 3 : 0)
+ + (animesh->mTangents ? 3 : 0)
+ + (animesh->mColors[0] ? 4 : 0)
+ + (animesh->mTextureCoords[0] ? 2 : 0);
+
+
+ for (uint i = 0; i < mesh->mNumAnimMeshes; i++) {
+ aiAnimMesh *animesh = mesh->mAnimMeshes[i];
+ Qt3DExtras::QMorphTarget *target = new Qt3DExtras::QMorphTarget(geometryRenderer);
+ targets.push_back(target);
+ QVector<QAttribute *> attributes;
+ QByteArray targetBufferArray;
+ targetBufferArray.resize(clumpSize * mesh->mNumVertices * sizeof(float));
+ float *dst = reinterpret_cast<float *>(targetBufferArray.data());
+
+ for (uint j = 0; j < mesh->mNumVertices; j++) {
+ if (animesh->mVertices) {
+ *dst++ = animesh->mVertices[j].x;
+ *dst++ = animesh->mVertices[j].y;
+ *dst++ = animesh->mVertices[j].z;
+ }
+ if (animesh->mNormals) {
+ *dst++ = animesh->mNormals[j].x;
+ *dst++ = animesh->mNormals[j].y;
+ *dst++ = animesh->mNormals[j].z;
+ }
+ if (animesh->mTangents) {
+ *dst++ = animesh->mTangents[j].x;
+ *dst++ = animesh->mTangents[j].y;
+ *dst++ = animesh->mTangents[j].z;
+ }
+ if (animesh->mTextureCoords[0]) {
+ *dst++ = animesh->mTextureCoords[0][j].x;
+ *dst++ = animesh->mTextureCoords[0][j].y;
+ }
+ if (animesh->mColors[0]) {
+ *dst++ = animesh->mColors[0][j].r;
+ *dst++ = animesh->mColors[0][j].g;
+ *dst++ = animesh->mColors[0][j].b;
+ *dst++ = animesh->mColors[0][j].a;
+ }
+ }
+
+ Qt3DRender::QBuffer *targetBuffer
+ = QAbstractNodeFactory::createNode<Qt3DRender::QBuffer>("QBuffer");
+ targetBuffer->setData(targetBufferArray);
+ targetBuffer->setParent(meshGeometry);
+
+ if (animesh->mVertices) {
+ attributes.push_back(createAttribute(targetBuffer, VERTICES_ATTRIBUTE_NAME,
+ QAttribute::Float, 3,
+ animesh->mNumVertices, voff * sizeof(float),
+ clumpSize * sizeof(float), meshGeometry));
+ }
+ if (animesh->mNormals) {
+ attributes.push_back(createAttribute(targetBuffer, NORMAL_ATTRIBUTE_NAME,
+ QAttribute::Float, 3,
+ animesh->mNumVertices, noff * sizeof(float),
+ clumpSize * sizeof(float), meshGeometry));
+ }
+ if (animesh->mTangents) {
+ attributes.push_back(createAttribute(targetBuffer, TANGENT_ATTRIBUTE_NAME,
+ QAttribute::Float, 3,
+ animesh->mNumVertices, tanoff * sizeof(float),
+ clumpSize * sizeof(float), meshGeometry));
+ }
+ if (animesh->mTextureCoords[0]) {
+ attributes.push_back(createAttribute(targetBuffer, TEXTCOORD_ATTRIBUTE_NAME,
+ QAttribute::Float, 2,
+ animesh->mNumVertices, texoff * sizeof(float),
+ clumpSize * sizeof(float), meshGeometry));
+ }
+ if (animesh->mColors[0]) {
+ attributes.push_back(createAttribute(targetBuffer, COLOR_ATTRIBUTE_NAME,
+ QAttribute::Float, 4,
+ animesh->mNumVertices, coloff * sizeof(float),
+ clumpSize * sizeof(float), meshGeometry));
+ }
+ target->setAttributes(attributes);
+ }
+ morphingAnimation->setMorphTargets(targets);
+ morphingAnimation->setTargetName(aiStringToQString(mesh->mName));
+ morphingAnimation->setTarget(geometryRenderer);
+ }
+
qCDebug(AssimpImporterLog) << Q_FUNC_INFO << " Mesh " << aiStringToQString(mesh->mName)
- << " Vertices " << mesh->mNumVertices << " Faces " << mesh->mNumFaces << " Indices " << indices;
+ << " Vertices " << mesh->mNumVertices << " Faces "
+ << mesh->mNumFaces << " Indices " << indices;
}
/*!
@@ -790,10 +990,145 @@ void AssimpImporter::loadCamera(uint cameraIndex)
m_scene->m_cameras[cameraNode] = camera;
}
+int findTimeIndex(const QVector<float> &times, float time) {
+ for (int i = 0; i < times.size(); i++) {
+ if (qFuzzyCompare(times[i], time))
+ return i;
+ }
+ return -1;
+}
+
+void insertAtTime(QVector<float> &positions, QVector<Qt3DCore::QTransform *> &tranforms,
+ Qt3DCore::QTransform *t, float time)
+{
+ if (positions.size() == 0) {
+ positions.push_back(time);
+ tranforms.push_back(t);
+ } else if (time < positions.first()) {
+ positions.push_front(time);
+ tranforms.push_front(t);
+ } else if (time > positions.last()) {
+ positions.push_back(time);
+ tranforms.push_back(t);
+ } else {
+ qWarning() << "Insert new key in the middle of the keyframe not implemented.";
+ }
+}
+
// OPTIONAL
void AssimpImporter::loadAnimation(uint animationIndex)
{
- Q_UNUSED(animationIndex);
+ aiAnimation *assimpAnim = m_scene->m_aiScene->mAnimations[animationIndex];
+ qCDebug(AssimpImporterLog) << "load Animation: "<< aiStringToQString(assimpAnim->mName);
+ double tickScale = 1.0;
+ if (!qFuzzyIsNull(assimpAnim->mTicksPerSecond))
+ tickScale = 1.0 / assimpAnim->mTicksPerSecond;
+
+ /* keyframe animations */
+ for (uint i = 0; i < assimpAnim->mNumChannels; ++i) {
+ aiNodeAnim *nodeAnim = assimpAnim->mChannels[i];
+ aiNode *targetNode = m_scene->m_aiScene->mRootNode->FindNode(nodeAnim->mNodeName);
+
+ Qt3DExtras::QKeyframeAnimation *kfa = new Qt3DExtras::QKeyframeAnimation();
+ QVector<float> positions;
+ QVector<Qt3DCore::QTransform*> transforms;
+ if ((nodeAnim->mNumPositionKeys > 1)
+ || !(nodeAnim->mNumPositionKeys == 1 && nodeAnim->mPositionKeys[0].mValue.x == 0
+ && nodeAnim->mPositionKeys[0].mValue.y == 0
+ && nodeAnim->mPositionKeys[0].mValue.z == 0)) {
+ for (uint j = 0; j < nodeAnim->mNumPositionKeys; j++) {
+ positions.push_back(nodeAnim->mPositionKeys[j].mTime);
+ Qt3DCore::QTransform *t = new Qt3DCore::QTransform();
+ t->setTranslation(QVector3D(nodeAnim->mPositionKeys[j].mValue.x,
+ nodeAnim->mPositionKeys[j].mValue.y,
+ nodeAnim->mPositionKeys[j].mValue.z));
+ transforms.push_back(t);
+ }
+ }
+ if ((nodeAnim->mNumRotationKeys > 1) ||
+ !(nodeAnim->mNumRotationKeys == 1 && nodeAnim->mRotationKeys[0].mValue.x == 0
+ && nodeAnim->mRotationKeys[0].mValue.y == 0
+ && nodeAnim->mRotationKeys[0].mValue.z == 0
+ && nodeAnim->mRotationKeys[0].mValue.w == 1)) {
+ for (uint j = 0; j < nodeAnim->mNumRotationKeys; j++) {
+ int index = findTimeIndex(positions, nodeAnim->mRotationKeys[j].mTime);
+ if (index >= 0) {
+ Qt3DCore::QTransform *t = transforms[index];
+ t->setRotation(QQuaternion(nodeAnim->mRotationKeys[j].mValue.w,
+ nodeAnim->mRotationKeys[j].mValue.x,
+ nodeAnim->mRotationKeys[j].mValue.y,
+ nodeAnim->mRotationKeys[j].mValue.z));
+ } else {
+ Qt3DCore::QTransform *t = new Qt3DCore::QTransform();
+ t->setRotation(QQuaternion(nodeAnim->mRotationKeys[j].mValue.w,
+ nodeAnim->mRotationKeys[j].mValue.x,
+ nodeAnim->mRotationKeys[j].mValue.y,
+ nodeAnim->mRotationKeys[j].mValue.z));
+ insertAtTime(positions, transforms, t, nodeAnim->mRotationKeys[j].mTime);
+ }
+ }
+ }
+ if ((nodeAnim->mNumScalingKeys > 1)
+ || !(nodeAnim->mNumScalingKeys == 1 && nodeAnim->mScalingKeys[0].mValue.x == 1
+ && nodeAnim->mScalingKeys[0].mValue.y == 1
+ && nodeAnim->mScalingKeys[0].mValue.z == 1)) {
+ for (uint j = 0; j < nodeAnim->mNumScalingKeys; j++) {
+ int index = findTimeIndex(positions, nodeAnim->mScalingKeys[j].mTime);
+ if (index >= 0) {
+ Qt3DCore::QTransform *t = transforms[index];
+ t->setScale3D(QVector3D(nodeAnim->mScalingKeys[j].mValue.x,
+ nodeAnim->mScalingKeys[j].mValue.y,
+ nodeAnim->mScalingKeys[j].mValue.z));
+ } else {
+ Qt3DCore::QTransform *t = new Qt3DCore::QTransform();
+ t->setScale3D(QVector3D(nodeAnim->mScalingKeys[j].mValue.x,
+ nodeAnim->mScalingKeys[j].mValue.y,
+ nodeAnim->mScalingKeys[j].mValue.z));
+ insertAtTime(positions, transforms, t, nodeAnim->mScalingKeys[j].mTime);
+ }
+ }
+ }
+ for (int j = 0; j < positions.size(); ++j)
+ positions[j] = positions[j] * tickScale;
+ kfa->setFramePositions(positions);
+ kfa->setKeyframes(transforms);
+ kfa->setAnimationName(QString(assimpAnim->mName.C_Str()));
+ kfa->setTargetName(QString(targetNode->mName.C_Str()));
+ m_scene->m_animations.push_back(kfa);
+ }
+ /* mesh morph animations */
+ for (uint i = 0; i < assimpAnim->mNumMorphMeshChannels; ++i) {
+ aiMeshMorphAnim *morphAnim = assimpAnim->mMorphMeshChannels[i];
+ aiNode *targetNode = m_scene->m_aiScene->mRootNode->FindNode(morphAnim->mName);
+ aiMesh *mesh = m_scene->m_aiScene->mMeshes[targetNode->mMeshes[0]];
+
+ Qt3DExtras::QMorphingAnimation *morphingAnimation = new Qt3DExtras::QMorphingAnimation;
+ QVector<float> positions;
+ positions.resize(morphAnim->mNumKeys);
+ // set so that weights array is allocated to correct size in morphingAnimation
+ morphingAnimation->setTargetPositions(positions);
+ for (unsigned int j = 0; j < morphAnim->mNumKeys; ++j) {
+ aiMeshMorphKey &key = morphAnim->mKeys[j];
+ positions[j] = key.mTime * tickScale;
+
+ QVector<float> weights;
+ weights.resize(key.mNumValuesAndWeights);
+ for (int k = 0; k < weights.size(); k++) {
+ const unsigned int value = key.mValues[k];
+ if (value < key.mNumValuesAndWeights)
+ weights[value] = key.mWeights[k];
+ }
+ morphingAnimation->setWeights(j, weights);
+ }
+
+ morphingAnimation->setTargetPositions(positions);
+ morphingAnimation->setAnimationName(QString(assimpAnim->mName.C_Str()));
+ morphingAnimation->setTargetName(QString(targetNode->mName.C_Str()));
+ morphingAnimation->setMethod((mesh->mMethod == aiMorphingMethod_MORPH_NORMALIZED)
+ ? Qt3DExtras::QMorphingAnimation::Normalized
+ : Qt3DExtras::QMorphingAnimation::Relative);
+ m_scene->m_morphAnimations.push_back(morphingAnimation);
+ }
}
/*!
diff --git a/src/plugins/sceneparsers/assimp/assimpimporter.h b/src/plugins/sceneparsers/assimp/assimpimporter.h
index fb60713b8..0d2c0c9e5 100644
--- a/src/plugins/sceneparsers/assimp/assimpimporter.h
+++ b/src/plugins/sceneparsers/assimp/assimpimporter.h
@@ -61,6 +61,7 @@
#include <QMap>
#include <QDir>
+#include <QVector>
#include <QLoggingCategory>
QT_BEGIN_NAMESPACE
@@ -71,6 +72,11 @@ namespace Qt3DCore {
class QCamera;
}
+namespace Qt3DExtras {
+class QKeyframeAnimation;
+class QMorphingAnimation;
+}
+
namespace Qt3DRender {
class QMaterial;
@@ -138,6 +144,8 @@ private:
QMap<QString, QAbstractTexture *> m_materialTextures;
QMap<aiNode*, Qt3DCore::QEntity*> m_cameras;
QHash<aiTextureType, QString> m_textureToParameterName;
+ QVector<Qt3DExtras::QKeyframeAnimation *> m_animations;
+ QVector<Qt3DExtras::QMorphingAnimation *> m_morphAnimations;
// QMap<aiNode*, Light*> m_lights;
};
diff --git a/src/quick3d/imports/extras/defaults.qrc b/src/quick3d/imports/extras/defaults.qrc
new file mode 100644
index 000000000..7b07aafab
--- /dev/null
+++ b/src/quick3d/imports/extras/defaults.qrc
@@ -0,0 +1,21 @@
+<RCC>
+<qresource prefix="/qt-project.org/imports/Qt3D/Extras/">
+<file alias="defaults/qml/DefaultEffect.qml">defaults/qml/DefaultEffect.qml</file>
+<file alias="defaults/qml/DefaultAlphaEffect.qml">defaults/qml/DefaultAlphaEffect.qml</file>
+<file alias="defaults/qml/PhongMaterial.qml">defaults/qml/PhongMaterial.qml</file>
+<file alias="defaults/qml/DiffuseMapMaterial.qml">defaults/qml/DiffuseMapMaterial.qml</file>
+<file alias="defaults/qml/DiffuseSpecularMapMaterial.qml">defaults/qml/DiffuseSpecularMapMaterial.qml</file>
+<file alias="defaults/qml/NormalDiffuseMapMaterial.qml">defaults/qml/NormalDiffuseMapMaterial.qml</file>
+<file alias="defaults/qml/NormalDiffuseMapAlphaMaterial.qml">defaults/qml/NormalDiffuseMapAlphaMaterial.qml</file>
+<file alias="defaults/qml/NormalDiffuseSpecularMapMaterial.qml">defaults/qml/NormalDiffuseSpecularMapMaterial.qml</file>
+<file alias="defaults/qml/ForwardRenderer.qml">defaults/qml/ForwardRenderer.qml</file>
+<file alias="defaults/qml/PerVertexColorMaterial.qml">defaults/qml/PerVertexColorMaterial.qml</file>
+<file alias="defaults/qml/SkyboxEntity.qml">defaults/qml/SkyboxEntity.qml</file>
+<file alias="defaults/qml/GoochMaterial.qml">defaults/qml/GoochMaterial.qml</file>
+<file alias="defaults/qml/PhongAlphaMaterial.qml">defaults/qml/PhongAlphaMaterial.qml</file>
+<file alias="defaults/qml/TextureMaterial.qml">defaults/qml/TextureMaterial.qml</file>
+<file alias="defaults/qml/OrbitCameraController.qml">defaults/qml/OrbitCameraController.qml</file>
+<file alias="defaults/qml/FirstPersonCameraController.qml">defaults/qml/FirstPersonCameraController.qml</file>
+<file alias="defaults/qml/NormalDiffuseMapAlphaEffect.qml">defaults/qml/NormalDiffuseMapAlphaEffect.qml</file>
+</qresource>
+</RCC>
diff --git a/src/quick3d/imports/extras/importsextras.pro b/src/quick3d/imports/extras/importsextras.pro
index acc993fa7..6a70238f4 100644
--- a/src/quick3d/imports/extras/importsextras.pro
+++ b/src/quick3d/imports/extras/importsextras.pro
@@ -3,7 +3,7 @@ TARGET = quick3dextrasplugin
TARGETPATH = Qt3D/Extras
IMPORT_VERSION = 2.0
-QT += core-private qml qml-private quick quick-private 3dcore 3dcore-private 3dquick 3dquick-private 3dextras 3dlogic
+QT += core-private qml qml-private quick quick-private 3dcore 3dcore-private 3dquick 3dquick-private 3dextras 3dlogic 3dquickextras 3dquickextras-private
# Qt3D is free of Q_FOREACH - make sure it stays that way:
DEFINES += QT_NO_FOREACH
diff --git a/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp b/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp
index 7d695ea5b..55af6432b 100644
--- a/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp
+++ b/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp
@@ -52,6 +52,19 @@
#include <Qt3DExtras/qcylindergeometry.h>
#include <Qt3DExtras/qtext3dgeometry.h>
#include <Qt3DExtras/qtext3dmesh.h>
+#include <Qt3DExtras/qkeyframeanimation.h>
+#include <Qt3DExtras/qanimationcontroller.h>
+#include <Qt3DExtras/qabstractanimation.h>
+#include <Qt3DExtras/qmorphinganimation.h>
+#include <Qt3DExtras/qanimationgroup.h>
+#include <Qt3DExtras/qmorphtarget.h>
+
+#include <Qt3DQuickExtras/private/quick3dkeyframeanimation_p.h>
+#include <Qt3DQuickExtras/private/quick3danimationgroup_p.h>
+#include <Qt3DQuickExtras/private/quick3danimationcontroller_p.h>
+#include <Qt3DQuickExtras/private/quick3dmorphtarget_p.h>
+#include <Qt3DQuickExtras/private/quick3dmorphinganimation_p.h>
+
#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
@@ -106,6 +119,13 @@ void Qt3DQuick3DExtrasPlugin::registerTypes(const char *uri)
qmlRegisterType<Qt3DExtras::QText3DGeometry>(uri, 2, 2, "Text3DGeometry");
qmlRegisterType<Qt3DExtras::QText3DMesh>(uri, 2, 2, "Text3DMesh");
+ qmlRegisterUncreatableType<Qt3DExtras::QAbstractAnimation>(uri, 2, 0, "AbstractAnimation", QStringLiteral("AbstractAnimation is abstract"));
+ qmlRegisterExtendedType<Qt3DExtras::QKeyframeAnimation, Qt3DExtras::Quick::QQuick3DKeyframeAnimation>(uri, 2, 2, "KeyframeAnimation");
+ qmlRegisterExtendedType<Qt3DExtras::QAnimationGroup, Qt3DExtras::Quick::QQuick3DAnimationGroup>(uri, 2, 2, "AnimationGroup");
+ qmlRegisterExtendedType<Qt3DExtras::QAnimationController, Qt3DExtras::Quick::QQuick3DAnimationController>(uri, 2, 2, "AnimationController");
+ qmlRegisterExtendedType<Qt3DExtras::QMorphingAnimation, Qt3DExtras::Quick::QQuick3DMorphingAnimation>(uri, 2, 2, "MorphingAnimation");
+ qmlRegisterExtendedType<Qt3DExtras::QMorphTarget, Qt3DExtras::Quick::QQuick3DMorphTarget>(uri, 2, 2, "MorphTarget");
+
// Register types provided as QML files compiled into the plugin
for (int i = 0; i < int(sizeof(qmldir) / sizeof(qmldir[0])); i++) {
auto path = QLatin1String("qrc:/qt-project.org/imports/Qt3D/Extras/defaults/qml/");
diff --git a/src/quick3d/quick3dextras/items/items.pri b/src/quick3d/quick3dextras/items/items.pri
new file mode 100644
index 000000000..cdb1e1245
--- /dev/null
+++ b/src/quick3d/quick3dextras/items/items.pri
@@ -0,0 +1,15 @@
+HEADERS += \
+ $$PWD/quick3danimationcontroller_p.h \
+ $$PWD/quick3danimationgroup_p.h \
+ $$PWD/quick3dkeyframeanimation_p.h \
+ $$PWD/quick3dmorphinganimation_p.h \
+ $$PWD/quick3dmorphtarget_p.h
+
+SOURCES += \
+ $$PWD/quick3danimationcontroller.cpp \
+ $$PWD/quick3danimationgroup.cpp \
+ $$PWD/quick3dkeyframeanimation.cpp \
+ $$PWD/quick3dmorphinganimation.cpp \
+ $$PWD/quick3dmorphtarget.cpp
+
+INCLUDEPATH += $$PWD
diff --git a/src/quick3d/quick3dextras/items/quick3danimationcontroller.cpp b/src/quick3d/quick3dextras/items/quick3danimationcontroller.cpp
new file mode 100644
index 000000000..4aceb0d55
--- /dev/null
+++ b/src/quick3d/quick3dextras/items/quick3danimationcontroller.cpp
@@ -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$
+**
+****************************************************************************/
+
+#include "quick3danimationcontroller_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+namespace Quick {
+
+QQuick3DAnimationController::QQuick3DAnimationController(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QQmlListProperty<QAnimationGroup> QQuick3DAnimationController::animationGroups()
+{
+ return QQmlListProperty<QAnimationGroup>(this, 0,
+ &QQuick3DAnimationController::appendAnimationGroup,
+ &QQuick3DAnimationController::animationGroupCount,
+ &QQuick3DAnimationController::animationGroupAt,
+ &QQuick3DAnimationController::clearAnimationGroups);
+}
+
+
+void QQuick3DAnimationController::appendAnimationGroup(QQmlListProperty<QAnimationGroup> *list, QAnimationGroup *bar)
+{
+ QQuick3DAnimationController *controller = qobject_cast<QQuick3DAnimationController *>(list->object);
+ if (controller)
+ controller->parentAnimationController()->addAnimationGroup(bar);
+}
+
+int QQuick3DAnimationController::animationGroupCount(QQmlListProperty<QAnimationGroup> *list)
+{
+ QQuick3DAnimationController *controller = qobject_cast<QQuick3DAnimationController *>(list->object);
+ if (controller)
+ return controller->parentAnimationController()->animationGroupList().count();
+ return 0;
+}
+
+QAnimationGroup *QQuick3DAnimationController::animationGroupAt(QQmlListProperty<QAnimationGroup> *list, int index)
+{
+ QQuick3DAnimationController *controller = qobject_cast<QQuick3DAnimationController *>(list->object);
+ if (controller)
+ return qobject_cast<QAnimationGroup *>(controller->parentAnimationController()->getGroup(index));
+ return nullptr;
+}
+
+void QQuick3DAnimationController::clearAnimationGroups(QQmlListProperty<QAnimationGroup> *list)
+{
+ QQuick3DAnimationController *controller = qobject_cast<QQuick3DAnimationController *>(list->object);
+ if (controller) {
+ QVector<QAnimationGroup *> emptyList;
+ controller->parentAnimationController()->setAnimationGroups(emptyList);
+ }
+}
+
+
+} // namespace Quick
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/quick3d/quick3dextras/items/quick3danimationcontroller_p.h b/src/quick3d/quick3dextras/items/quick3danimationcontroller_p.h
new file mode 100644
index 000000000..82ad29e2c
--- /dev/null
+++ b/src/quick3d/quick3dextras/items/quick3danimationcontroller_p.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 QT3DEXTRAS_QUICK_QUICK3DANIMATIONCONTROLLER_P_H
+#define QT3DEXTRAS_QUICK_QUICK3DANIMATIONCONTROLLER_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 <Qt3DQuickExtras/qt3dquickextras_global.h>
+#include <QQmlListProperty>
+#include <Qt3DExtras/QAnimationController>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+namespace Quick {
+
+class QT3DQUICKEXTRASSHARED_EXPORT QQuick3DAnimationController : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QQmlListProperty<Qt3DExtras::QAnimationGroup> animationGroups READ animationGroups)
+
+public:
+
+ explicit QQuick3DAnimationController(QObject *parent = nullptr);
+
+ inline Qt3DExtras::QAnimationController *parentAnimationController() const
+ {
+ return qobject_cast<Qt3DExtras::QAnimationController *>(parent());
+ }
+
+ QQmlListProperty<Qt3DExtras::QAnimationGroup> animationGroups();
+
+private:
+
+ static void appendAnimationGroup(QQmlListProperty<Qt3DExtras::QAnimationGroup> *list, Qt3DExtras::QAnimationGroup *bar);
+ static QAnimationGroup *animationGroupAt(QQmlListProperty<Qt3DExtras::QAnimationGroup> *list, int index);
+ static int animationGroupCount(QQmlListProperty<Qt3DExtras::QAnimationGroup> *list);
+ static void clearAnimationGroups(QQmlListProperty<Qt3DExtras::QAnimationGroup> *list);
+};
+
+} // namespace Quick
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DRENDER_RENDER_QUICK_QUICK3DEFFECT_P_H
diff --git a/src/quick3d/quick3dextras/items/quick3danimationgroup.cpp b/src/quick3d/quick3dextras/items/quick3danimationgroup.cpp
new file mode 100644
index 000000000..3e3813227
--- /dev/null
+++ b/src/quick3d/quick3dextras/items/quick3danimationgroup.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** 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 "quick3danimationgroup_p.h"
+
+#include <Qt3DExtras/qabstractanimation.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+namespace Quick {
+
+QQuick3DAnimationGroup::QQuick3DAnimationGroup(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QQmlListProperty<Qt3DExtras::QAbstractAnimation> QQuick3DAnimationGroup::animations()
+{
+ return QQmlListProperty<Qt3DExtras::QAbstractAnimation>(this, 0,
+ &QQuick3DAnimationGroup::appendAnimation,
+ &QQuick3DAnimationGroup::animationCount,
+ &QQuick3DAnimationGroup::animationAt,
+ &QQuick3DAnimationGroup::clearAnimation);
+}
+
+
+void QQuick3DAnimationGroup::appendAnimation(QQmlListProperty<Qt3DExtras::QAbstractAnimation> *list,
+ Qt3DExtras::QAbstractAnimation *animation)
+{
+ QQuick3DAnimationGroup *animationGroup = qobject_cast<QQuick3DAnimationGroup *>(list->object);
+ if (animationGroup)
+ animationGroup->parentAnimationGroup()->addAnimation(animation);
+}
+
+int QQuick3DAnimationGroup::animationCount(QQmlListProperty<Qt3DExtras::QAbstractAnimation> *list)
+{
+ QQuick3DAnimationGroup *animationGroup = qobject_cast<QQuick3DAnimationGroup *>(list->object);
+ if (animationGroup)
+ return animationGroup->parentAnimationGroup()->animationList().count();
+ return 0;
+}
+
+Qt3DExtras::QAbstractAnimation *QQuick3DAnimationGroup::animationAt(QQmlListProperty<Qt3DExtras::QAbstractAnimation> *list, int index)
+{
+ QQuick3DAnimationGroup *animationGroup = qobject_cast<QQuick3DAnimationGroup *>(list->object);
+ if (animationGroup) {
+ return qobject_cast<Qt3DExtras::QAbstractAnimation *>(
+ animationGroup->parentAnimationGroup()->animationList().at(index));
+ }
+ return nullptr;
+}
+
+void QQuick3DAnimationGroup::clearAnimation(QQmlListProperty<Qt3DExtras::QAbstractAnimation> *list)
+{
+ QQuick3DAnimationGroup *animationGroup = qobject_cast<QQuick3DAnimationGroup *>(list->object);
+ if (animationGroup) {
+ QVector<Qt3DExtras::QAbstractAnimation *> emptyList;
+ animationGroup->parentAnimationGroup()->setAnimations(emptyList);
+ }
+}
+
+} // namespace Quick
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/quick3d/quick3dextras/items/quick3danimationgroup_p.h b/src/quick3d/quick3dextras/items/quick3danimationgroup_p.h
new file mode 100644
index 000000000..c7140c946
--- /dev/null
+++ b/src/quick3d/quick3dextras/items/quick3danimationgroup_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** 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 QT3DEXTRAS_QUICK_QUICK3DANIMATIONGROUP_P_H
+#define QT3DEXTRAS_QUICK_QUICK3DANIMATIONGROUP_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQml/qqmllist.h>
+#include <Qt3DExtras/qabstractanimation.h>
+#include <Qt3DExtras/qanimationgroup.h>
+
+#include <Qt3DQuickExtras/qt3dquickextras_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+namespace Quick {
+
+class QT3DQUICKEXTRASSHARED_EXPORT QQuick3DAnimationGroup : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QQmlListProperty<Qt3DExtras::QAbstractAnimation> animations READ animations)
+
+public:
+
+ explicit QQuick3DAnimationGroup(QObject *parent = nullptr);
+
+ inline Qt3DExtras::QAnimationGroup *parentAnimationGroup() const
+ {
+ return qobject_cast<Qt3DExtras::QAnimationGroup *>(parent());
+ }
+
+ QQmlListProperty<Qt3DExtras::QAbstractAnimation> animations();
+
+private:
+
+ static void appendAnimation(QQmlListProperty<Qt3DExtras::QAbstractAnimation> *list, Qt3DExtras::QAbstractAnimation *animation);
+ static Qt3DExtras::QAbstractAnimation *animationAt(QQmlListProperty<Qt3DExtras::QAbstractAnimation> *list, int index);
+ static int animationCount(QQmlListProperty<Qt3DExtras::QAbstractAnimation> *list);
+ static void clearAnimation(QQmlListProperty<Qt3DExtras::QAbstractAnimation> *list);
+};
+
+} // namespace Quick
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DRENDER_RENDER_QUICK_QUICK3DEFFECT_P_H
diff --git a/src/quick3d/quick3dextras/items/quick3dkeyframeanimation.cpp b/src/quick3d/quick3dextras/items/quick3dkeyframeanimation.cpp
new file mode 100644
index 000000000..cfd9ca7d2
--- /dev/null
+++ b/src/quick3d/quick3dextras/items/quick3dkeyframeanimation.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** 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 "quick3dkeyframeanimation_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+namespace Quick {
+
+QQuick3DKeyframeAnimation::QQuick3DKeyframeAnimation(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QQmlListProperty<Qt3DCore::QTransform> QQuick3DKeyframeAnimation::keyframes()
+{
+ return QQmlListProperty<Qt3DCore::QTransform>(this, 0,
+ &QQuick3DKeyframeAnimation::appendKeyframe,
+ &QQuick3DKeyframeAnimation::keyframeCount,
+ &QQuick3DKeyframeAnimation::keyframeAt,
+ &QQuick3DKeyframeAnimation::clearKeyframes);
+}
+
+void QQuick3DKeyframeAnimation::appendKeyframe(QQmlListProperty<Qt3DCore::QTransform> *list,
+ Qt3DCore::QTransform *transform)
+{
+ QQuick3DKeyframeAnimation *keyframeAnimation
+ = qobject_cast<QQuick3DKeyframeAnimation *>(list->object);
+ if (keyframeAnimation)
+ keyframeAnimation->parentKeyframeAnimation()->addKeyframe(transform);
+}
+
+int QQuick3DKeyframeAnimation::keyframeCount(QQmlListProperty<Qt3DCore::QTransform> *list)
+{
+ QQuick3DKeyframeAnimation *keyframeAnimation
+ = qobject_cast<QQuick3DKeyframeAnimation *>(list->object);
+ if (keyframeAnimation)
+ return keyframeAnimation->parentKeyframeAnimation()->keyframeList().count();
+ return 0;
+}
+
+Qt3DCore::QTransform *QQuick3DKeyframeAnimation::keyframeAt(QQmlListProperty<Qt3DCore::QTransform> *list,
+ int index)
+{
+ QQuick3DKeyframeAnimation *keyframeAnimation
+ = qobject_cast<QQuick3DKeyframeAnimation *>(list->object);
+ if (keyframeAnimation) {
+ return qobject_cast<Qt3DCore::QTransform *>(
+ keyframeAnimation->parentKeyframeAnimation()->keyframeList().at(index));
+ }
+ return nullptr;
+}
+
+void QQuick3DKeyframeAnimation::clearKeyframes(QQmlListProperty<Qt3DCore::QTransform> *list)
+{
+ QQuick3DKeyframeAnimation *keyframeAnimation
+ = qobject_cast<QQuick3DKeyframeAnimation *>(list->object);
+ if (keyframeAnimation) {
+ QVector<Qt3DCore::QTransform *> emptyList;
+ keyframeAnimation->parentKeyframeAnimation()->setKeyframes(emptyList);
+ }
+}
+
+} // namespace Quick
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/quick3d/quick3dextras/items/quick3dkeyframeanimation_p.h b/src/quick3d/quick3dextras/items/quick3dkeyframeanimation_p.h
new file mode 100644
index 000000000..e8309de9e
--- /dev/null
+++ b/src/quick3d/quick3dextras/items/quick3dkeyframeanimation_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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 QT3DEXTRAS_QUICK_QUICK3DKEYFRAMEANIMATION_P_H
+#define QT3DEXTRAS_QUICK_QUICK3DKEYFRAMEANIMATION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQml/qqmllist.h>
+
+#include <Qt3DExtras/qkeyframeanimation.h>
+
+#include <Qt3DQuickExtras/qt3dquickextras_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+namespace Quick {
+
+class QT3DQUICKEXTRASSHARED_EXPORT QQuick3DKeyframeAnimation : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QQmlListProperty<Qt3DCore::QTransform> keyframes READ keyframes)
+
+public:
+ QQuick3DKeyframeAnimation(QObject *parent = nullptr);
+
+ inline QKeyframeAnimation *parentKeyframeAnimation() const
+ {
+ return qobject_cast<QKeyframeAnimation *>(parent());
+ }
+
+ QQmlListProperty<Qt3DCore::QTransform> keyframes();
+
+private:
+
+ static void appendKeyframe(QQmlListProperty<Qt3DCore::QTransform> *list,
+ Qt3DCore::QTransform *transform);
+ static Qt3DCore::QTransform *keyframeAt(QQmlListProperty<Qt3DCore::QTransform> *list,
+ int index);
+ static int keyframeCount(QQmlListProperty<Qt3DCore::QTransform> *list);
+ static void clearKeyframes(QQmlListProperty<Qt3DCore::QTransform> *list);
+};
+
+} // namespace Quick
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QUICK_QUICK3DKEYFRAMEANIMATION_P_H
diff --git a/src/quick3d/quick3dextras/items/quick3dmorphinganimation.cpp b/src/quick3d/quick3dextras/items/quick3dmorphinganimation.cpp
new file mode 100644
index 000000000..61636f06d
--- /dev/null
+++ b/src/quick3d/quick3dextras/items/quick3dmorphinganimation.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** 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 "quick3dmorphinganimation_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+namespace Quick {
+
+QQuick3DMorphingAnimation::QQuick3DMorphingAnimation(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QQmlListProperty<Qt3DExtras::QMorphTarget> QQuick3DMorphingAnimation::morphTargets()
+{
+ return QQmlListProperty<Qt3DExtras::QMorphTarget>(this, 0,
+ &QQuick3DMorphingAnimation::appendMorphTarget,
+ &QQuick3DMorphingAnimation::morphTargetCount,
+ &QQuick3DMorphingAnimation::morphTargetAt,
+ &QQuick3DMorphingAnimation::clearMorphTargets);
+}
+
+void QQuick3DMorphingAnimation::appendMorphTarget(QQmlListProperty<Qt3DExtras::QMorphTarget> *list,
+ Qt3DExtras::QMorphTarget *morphTarget)
+{
+ QQuick3DMorphingAnimation *animation = qobject_cast<QQuick3DMorphingAnimation *>(list->object);
+ if (animation)
+ animation->parentMorphingAnimation()->addMorphTarget(morphTarget);
+}
+
+int QQuick3DMorphingAnimation::morphTargetCount(QQmlListProperty<Qt3DExtras::QMorphTarget> *list)
+{
+ QQuick3DMorphingAnimation *animation = qobject_cast<QQuick3DMorphingAnimation *>(list->object);
+ if (animation)
+ return animation->parentMorphingAnimation()->morphTargetList().count();
+ return 0;
+}
+
+Qt3DExtras::QMorphTarget *QQuick3DMorphingAnimation::morphTargetAt(QQmlListProperty<Qt3DExtras::QMorphTarget> *list,
+ int index)
+{
+ QQuick3DMorphingAnimation *animation = qobject_cast<QQuick3DMorphingAnimation *>(list->object);
+ if (animation) {
+ return qobject_cast<Qt3DExtras::QMorphTarget *>(
+ animation->parentMorphingAnimation()->morphTargetList().at(index));
+ }
+ return nullptr;
+}
+
+void QQuick3DMorphingAnimation::clearMorphTargets(QQmlListProperty<Qt3DExtras::QMorphTarget> *list)
+{
+ QQuick3DMorphingAnimation *animation = qobject_cast<QQuick3DMorphingAnimation *>(list->object);
+ if (animation) {
+ QVector<Qt3DExtras::QMorphTarget *> emptyList;
+ animation->parentMorphingAnimation()->setMorphTargets(emptyList);
+ }
+}
+
+} // namespace Quick
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/quick3d/quick3dextras/items/quick3dmorphinganimation_p.h b/src/quick3d/quick3dextras/items/quick3dmorphinganimation_p.h
new file mode 100644
index 000000000..5f052fd04
--- /dev/null
+++ b/src/quick3d/quick3dextras/items/quick3dmorphinganimation_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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 QT3DEXTRAS_QUICK_QUICK3DMORPHINGANIMATION_P_H
+#define QT3DEXTRAS_QUICK_QUICK3DMORPHINGANIMATION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQml/qqmllist.h>
+
+#include <Qt3DExtras/qmorphinganimation.h>
+
+#include <Qt3DQuickExtras/qt3dquickextras_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+namespace Quick {
+
+class QT3DQUICKEXTRASSHARED_EXPORT QQuick3DMorphingAnimation : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QQmlListProperty<Qt3DExtras::QMorphTarget> morphTargets READ morphTargets)
+
+public:
+ QQuick3DMorphingAnimation(QObject *parent = nullptr);
+
+ inline QMorphingAnimation *parentMorphingAnimation() const
+ {
+ return qobject_cast<QMorphingAnimation *>(parent());
+ }
+
+ QQmlListProperty<Qt3DExtras::QMorphTarget> morphTargets();
+
+private:
+
+ static void appendMorphTarget(QQmlListProperty<Qt3DExtras::QMorphTarget> *list,
+ Qt3DExtras::QMorphTarget *morphTarget);
+ static Qt3DExtras::QMorphTarget *morphTargetAt(QQmlListProperty<Qt3DExtras::QMorphTarget> *list,
+ int index);
+ static int morphTargetCount(QQmlListProperty<Qt3DExtras::QMorphTarget> *list);
+ static void clearMorphTargets(QQmlListProperty<Qt3DExtras::QMorphTarget> *list);
+};
+
+} // namespace Quick
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QUICK_QUICK3DMORPHINGANIMATION_P_H
diff --git a/src/quick3d/quick3dextras/items/quick3dmorphtarget.cpp b/src/quick3d/quick3dextras/items/quick3dmorphtarget.cpp
new file mode 100644
index 000000000..8c1b9f0c1
--- /dev/null
+++ b/src/quick3d/quick3dextras/items/quick3dmorphtarget.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** 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 "quick3dmorphtarget_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+namespace Quick {
+
+QQuick3DMorphTarget::QQuick3DMorphTarget(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QQmlListProperty<Qt3DRender::QAttribute> QQuick3DMorphTarget::attributes()
+{
+ return QQmlListProperty<Qt3DRender::QAttribute>(this, 0,
+ &QQuick3DMorphTarget::appendAttribute,
+ &QQuick3DMorphTarget::attributeCount,
+ &QQuick3DMorphTarget::attributeAt,
+ &QQuick3DMorphTarget::clearAttributes);
+}
+
+void QQuick3DMorphTarget::appendAttribute(QQmlListProperty<Qt3DRender::QAttribute> *list, Qt3DRender::QAttribute *bar)
+{
+ QQuick3DMorphTarget *target = qobject_cast<QQuick3DMorphTarget *>(list->object);
+ if (target)
+ target->parentMorphTarget()->addAttribute(bar);
+}
+
+int QQuick3DMorphTarget::attributeCount(QQmlListProperty<Qt3DRender::QAttribute> *list)
+{
+ QQuick3DMorphTarget *target = qobject_cast<QQuick3DMorphTarget *>(list->object);
+ if (target)
+ return target->parentMorphTarget()->attributeList().count();
+ return 0;
+}
+
+Qt3DRender::QAttribute *QQuick3DMorphTarget::attributeAt(QQmlListProperty<Qt3DRender::QAttribute> *list, int index)
+{
+ QQuick3DMorphTarget *target = qobject_cast<QQuick3DMorphTarget *>(list->object);
+ if (target)
+ return qobject_cast<Qt3DRender::QAttribute *>(target->parentMorphTarget()->attributeList().at(index));
+ return nullptr;
+}
+
+void QQuick3DMorphTarget::clearAttributes(QQmlListProperty<Qt3DRender::QAttribute> *list)
+{
+ QQuick3DMorphTarget *target = qobject_cast<QQuick3DMorphTarget *>(list->object);
+ if (target) {
+ QVector<Qt3DRender::QAttribute *> emptyList;
+ target->parentMorphTarget()->setAttributes(emptyList);
+ }
+}
+
+} // namespace Quick
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/quick3d/quick3dextras/items/quick3dmorphtarget_p.h b/src/quick3d/quick3dextras/items/quick3dmorphtarget_p.h
new file mode 100644
index 000000000..e5c664370
--- /dev/null
+++ b/src/quick3d/quick3dextras/items/quick3dmorphtarget_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** 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 QT3DEXTRAS_QUICK_QUICK3DMORPHTARGET_P_H
+#define QT3DEXTRAS_QUICK_QUICK3DMORPHTARGET_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 <Qt3DQuickExtras/qt3dquickextras_global.h>
+#include <QQmlListProperty>
+#include <Qt3DExtras/QMorphTarget>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+namespace Quick {
+
+class QT3DQUICKEXTRASSHARED_EXPORT QQuick3DMorphTarget : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QQmlListProperty<Qt3DRender::QAttribute> attributes READ attributes)
+
+public:
+ QQuick3DMorphTarget(QObject *parent = nullptr);
+
+ inline QMorphTarget *parentMorphTarget() const { return qobject_cast<QMorphTarget *>(parent()); }
+
+ QQmlListProperty<Qt3DRender::QAttribute> attributes();
+
+private:
+
+ static void appendAttribute(QQmlListProperty<Qt3DRender::QAttribute> *list, Qt3DRender::QAttribute *bar);
+ static Qt3DRender::QAttribute *attributeAt(QQmlListProperty<Qt3DRender::QAttribute> *list, int index);
+ static int attributeCount(QQmlListProperty<Qt3DRender::QAttribute> *list);
+ static void clearAttributes(QQmlListProperty<Qt3DRender::QAttribute> *list);
+};
+
+} // namespace Quick
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QUICK_QUICK3DMORPHTARGET_P_H
diff --git a/src/quick3d/quick3dextras/quick3dextras.pro b/src/quick3d/quick3dextras/quick3dextras.pro
index 8965e9f5d..4f103765c 100644
--- a/src/quick3d/quick3dextras/quick3dextras.pro
+++ b/src/quick3d/quick3dextras/quick3dextras.pro
@@ -1,7 +1,7 @@
TARGET = Qt3DQuickExtras
MODULE = 3dquickextras
-QT += core core-private qml qml-private 3dcore 3dinput 3dquick 3drender 3drender-private 3dlogic
+QT += core core-private qml qml-private 3dcore 3dinput 3dquick 3drender 3drender-private 3dlogic 3dextras
CONFIG -= precompile_header
# Qt3D is free of Q_FOREACH - make sure it stays that way:
@@ -23,4 +23,6 @@ HEADERS += \
# otherwise mingw headers do not declare common functions like ::strcasecmp
win32-g++*:QMAKE_CXXFLAGS_CXX11 = -std=gnu++0x
+include(./items/items.pri)
+
load(qt_module)