diff options
Diffstat (limited to 'src/animation/frontend/qanimationcontroller.cpp')
-rw-r--r-- | src/animation/frontend/qanimationcontroller.cpp | 390 |
1 files changed, 390 insertions, 0 deletions
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 |