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