diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2017-04-19 19:27:58 +0100 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2017-04-27 12:47:40 +0000 |
commit | 6ccffde7abdfbddf6768293a813a382527ad591b (patch) | |
tree | 1877ad18106deecefe960ca11ffdab79ca0cb445 | |
parent | 14c00da0a623a74f01337cb5dd8c7fa506197014 (diff) |
Document QBlendedClipAnimator
Change-Id: Ic2505c1f2bfbcf3790f38634cf58b41c219c3525
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
-rw-r--r-- | src/animation/frontend/qblendedclipanimator.cpp | 208 |
1 files changed, 199 insertions, 9 deletions
diff --git a/src/animation/frontend/qblendedclipanimator.cpp b/src/animation/frontend/qblendedclipanimator.cpp index 971f4e1e7..e6b127bf1 100644 --- a/src/animation/frontend/qblendedclipanimator.cpp +++ b/src/animation/frontend/qblendedclipanimator.cpp @@ -55,32 +55,208 @@ QBlendedClipAnimatorPrivate::QBlendedClipAnimatorPrivate() \qmltype BlendedClipAnimator \instantiates Qt3DAnimation::QBlendedClipAnimator \inqmlmodule Qt3D.Animation + \since 5.9 - \brief Performs an animation based on a tree of blend nodes + \brief BlendedClipAnimator is a component providing animation playback capabilities of a tree + of blend nodes. - \note The blend node tree should only be edited when the clip is not - running + An instance of BlendedClipAnimator can be aggregated by an Entity to add the ability to play + back animation clips and to apply the calculated animation values to properties of QObjects. - \since 5.9 + Whereas a ClipAnimator gets its animation data from a single animation clip, + BlendedClipAnimator can blend together multiple clips. The animation data is obtained by + evaluating a so called \e {blend tree}. A blend tree is a hierarchical tree structure where the + leaf nodes are value nodes that encapsulate an animation clip (AbstractAnimationClip); and the + internal nodes represent blending operations that operate on the nodes pointed to by their + operand properties. + + To associate a blend tree with a BlendedClipAnimator, set the animator's blendTree property to + point at the root node of your blend tree: + + \badcode + BlendedClipAnimator { + blendTree: AdditiveClipBlend { + .... + } + } + \endcode + + A blend tree can be constructed from the following node types: + + \note The blend node tree should only be edited when the animator is not running. + + \list + \li Qt3D.Animation.ClipBlendValue + \li Qt3D.Animation.LerpClipBlend + \li Qt3D.Animation.AdditiveClipBlend + \endlist + + Additional node types will be added over time. + + As an example consider the following blend tree: + + \badcode + Clip0---- + | + Lerp Node---- + | | + Clip1---- Additive Node + | + Clip2---- + \endcode + + This can be created and used as follows: + + \badcode + BlendedClipAnimator { + blendTree: AdditiveClipBlend { + baseClip: LerpClipBlend { + startClip: ClipBlendValue { + clip: AnimationClipLoader { source: "walk.json" } + } + + endClip: ClipBlendValue { + clip: AnimationClipLoader { source: "run.json" } + } + } + + additiveClip: ClipBlendValue { + clip: AnimationClipLoader { source: "wave-arm.json" } + } + } + + channelMapper: ChannelMapper {...} + running: true + } + \endcode + + By authoring a set of animation clips and blending between them dynamically at runtime with a + blend tree, we open up a huge set of possible resulting animations. As some simple examples of + the above blend tree, where alpha is the additive factor and beta is the lerp blend factor we + can get a 2D continuum of possible animations: + + \badcode + (alpha = 0, beta = 1) Running, No arm waving --- (alpha = 1, beta = 1) Running, Arm waving + | | + | | + | | + (alpha = 0, beta = 0) Walking, No arm waving --- (alpha = 0, beta = 1) Running, No arm waving + \endcode + + More complex blend trees offer even more flexibility for combining your animation clips. Note + that the values used to control the blend tree (alpha and beta above) are simple properties on + the blend nodes. This means, that these properties themselves can also be controlled by + the animation framework. */ /*! \class Qt3DAnimation::QBlendedClipAnimator + \inherits Qt3DAnimation::QAbstractClipAnimator + \inmodule Qt3DAnimation - \inherits Qt3DCore::QComponent + \since 5.9 - \brief Performs an animation based on a tree of blend nodes + \brief QBlendedClipAnimator is a component providing animation playback capabilities of a tree + of blend nodes. - \note The blend node tree should only be edited when the clip is not - running + An instance of QBlendedClipAnimator can be aggregated by a QEntity to add the ability to play + back animation clips and to apply the calculated animation values to properties of QObjects. + + Whereas a QClipAnimator gets its animation data from a single animation clip, + QBlendedClipAnimator can blend together multiple clips. The animation data is obtained by + evaluating a so called \e {blend tree}. A blend tree is a hierarchical tree structure where the + leaf nodes are value nodes that encapsulate an animation clip (QAbstractAnimationClip); and the + internal nodes represent blending operations that operate on the nodes pointed to by their + operand properties. + + To associate a blend tree with a QBlendedClipAnimator, set the animator's blendTree property to + point at the root node of your blend tree: + + \badcode + auto blendTreeRoot = new QAdditiveClipBlend(); + ... + auto animator = new QBlendedClipAnimator(); + animator->setBlendTree(blendTreeRoot); + \endcode + + A blend tree can be constructed from the following node types: + + \note The blend node tree should only be edited when the animator is not running. + + \list + \li Qt3DAnimation::QClipBlendValue + \li Qt3DAnimation::QLerpClipBlend + \li Qt3DAnimation::QAdditiveClipBlend + \endlist + + Additional node types will be added over time. + + As an example consider the following blend tree: + + \badcode + Clip0---- + | + Lerp Node---- + | | + Clip1---- Additive Node + | + Clip2---- + \endcode + + This can be created and used as follows: + + \code + // Create leaf nodes of blend tree + auto clip0 = new QClipBlendValue( + new QAnimationClipLoader(QUrl::fromLocalFile("walk.json"))); + auto clip1 = new QClipBlendValue( + new QAnimationClipLoader(QUrl::fromLocalFile("run.json"))); + auto clip2 = new QClipBlendValue( + new QAnimationClipLoader(QUrl::fromLocalFile("wave-arm.json"))); + + // Create blend tree inner nodes + auto lerpNode = new QLerpClipBlend(); + lerpNode->setStartClip(clip0); + lerpNode->setEndClip(clip1); + lerpNode->setBlendFactor(0.5f); // Half-walk, half-run + + auto additiveNode = new QAdditiveClipBlend(); + additiveNode->setBaseClip(lerpNode); // Comes from lerp sub-tree + additiveNode->setAdditiveClip(clip2); + additiveNode->setAdditiveFactor(1.0f); // Wave arm fully + + // Run the animator + auto animator = new QBlendedClipAnimator(); + animator->setBlendTree(additiveNode); + animator->setChannelMapper(...); + animator->setRunning(true); + \endcode + + By authoring a set of animation clips and blending between them dynamically at runtime with a + blend tree, we open up a huge set of possible resulting animations. As some simple examples of + the above blend tree, where alpha is the additive factor and beta is the lerp blend factor we + can get a 2D continuum of possible animations: + + \badcode + (alpha = 0, beta = 1) Running, No arm waving --- (alpha = 1, beta = 1) Running, Arm waving + | | + | | + | | + (alpha = 0, beta = 0) Walking, No arm waving --- (alpha = 0, beta = 1) Running, No arm waving + \endcode + + More complex blend trees offer even more flexibility for combining your animation clips. Note + that the values used to control the blend tree (alpha and beta above) are simple properties on + the blend nodes. This means, that these properties themselves can also be controlled by + the animation framework. - \since 5.9 */ QBlendedClipAnimator::QBlendedClipAnimator(Qt3DCore::QNode *parent) : Qt3DAnimation::QAbstractClipAnimator(*new QBlendedClipAnimatorPrivate, parent) { } +/*! \internal */ QBlendedClipAnimator::QBlendedClipAnimator(QBlendedClipAnimatorPrivate &dd, Qt3DCore::QNode *parent) : Qt3DAnimation::QAbstractClipAnimator(dd, parent) { @@ -90,6 +266,19 @@ QBlendedClipAnimator::~QBlendedClipAnimator() { } +/*! + \qmlproperty AbstractClipBlendNode blendTree + + This property holds the root of the animation blend tree that will be evaluated before being + interpolated by the animator. +*/ + +/*! + \property blendTree + + This property holds the root of the animation blend tree that will be evaluated before being + interpolated by the animator. +*/ QAbstractClipBlendNode *QBlendedClipAnimator::blendTree() const { Q_D(const QBlendedClipAnimator); @@ -116,6 +305,7 @@ void QBlendedClipAnimator::setBlendTree(QAbstractClipBlendNode *blendTree) emit blendTreeChanged(blendTree); } +/*! \internal */ Qt3DCore::QNodeCreatedChangeBasePtr QBlendedClipAnimator::createNodeCreationChange() const { auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QBlendedClipAnimatorData>::create(this); |