1/****************************************************************************
2**
3** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
4** Contact: http://www.qt-project.org/legal
5**
6** This file is part of the Qt3D module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL3$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or later as published by the Free
28** Software Foundation and appearing in the file LICENSE.GPL included in
29** the packaging of this file. Please review the following information to
30** ensure the GNU General Public License version 2.0 requirements will be
31** met: http://www.gnu.org/licenses/gpl-2.0.html.
32**
33** $QT_END_LICENSE$
34**
35****************************************************************************/
36
37#include "evaluateclipanimatorjob_p.h"
38#include <Qt3DCore/private/qaspectjob_p.h>
39#include <Qt3DCore/private/qaspectmanager_p.h>
40#include <Qt3DAnimation/qclipanimator.h>
41#include <Qt3DAnimation/private/handler_p.h>
42#include <Qt3DAnimation/private/managers_p.h>
43#include <Qt3DAnimation/private/animationlogging_p.h>
44#include <Qt3DAnimation/private/animationutils_p.h>
45#include <Qt3DAnimation/private/job_common_p.h>
46
47QT_BEGIN_NAMESPACE
48
49namespace Qt3DAnimation {
50namespace Animation {
51
52
53EvaluateClipAnimatorJob::EvaluateClipAnimatorJob()
54 : AbstractEvaluateClipAnimatorJob()
55 , m_handler(nullptr)
56{
57 SET_JOB_RUN_STAT_TYPE(this, JobTypes::EvaluateClipAnimator, 0)
58}
59
60void EvaluateClipAnimatorJob::run()
61{
62 Q_ASSERT(m_handler);
63
64 ClipAnimator *clipAnimator = m_handler->clipAnimatorManager()->data(handle: m_clipAnimatorHandle);
65 Q_ASSERT(clipAnimator);
66 const bool running = clipAnimator->isRunning();
67 const bool seeking = clipAnimator->isSeeking();
68 if (!running && !seeking) {
69 m_handler->setClipAnimatorRunning(handle: m_clipAnimatorHandle, running: false);
70 return;
71 }
72
73 const qint64 globalTimeNS = m_handler->simulationTime();
74
75 Clock *clock = m_handler->clockManager()->lookupResource(id: clipAnimator->clockId());
76
77 // Evaluate the fcurves
78 AnimationClip *clip = m_handler->animationClipLoaderManager()->lookupResource(id: clipAnimator->clipId());
79 Q_ASSERT(clip);
80
81 const qint64 nsSincePreviousFrame = seeking ? toNsecs(seconds: clip->duration() * clipAnimator->normalizedLocalTime())
82 : clipAnimator->nsSincePreviousFrame(currentGlobalTimeNS: globalTimeNS);
83
84 // Prepare for evaluation (convert global time to local time ....)
85 const AnimatorEvaluationData animatorEvaluationData = evaluationDataForAnimator(animator: clipAnimator,
86 clock,
87 nsSincePreviousFrame);
88
89 const ClipEvaluationData preEvaluationDataForClip = evaluationDataForClip(clip, animatorData: animatorEvaluationData);
90 const ClipResults rawClipResults = evaluateClipAtPhase(clip, phase: preEvaluationDataForClip.normalizedLocalTime);
91
92 // Reformat the clip results into the layout used by this animator/blend tree
93 const ClipFormat clipFormat = clipAnimator->clipFormat();
94 ClipResults formattedClipResults = formatClipResults(rawClipResults, format: clipFormat.sourceClipIndices);
95
96 if (preEvaluationDataForClip.isFinalFrame)
97 clipAnimator->setRunning(false);
98
99 clipAnimator->setCurrentLoop(preEvaluationDataForClip.currentLoop);
100 clipAnimator->setLastGlobalTimeNS(globalTimeNS);
101 clipAnimator->setLastLocalTime(preEvaluationDataForClip.localTime);
102 clipAnimator->setLastNormalizedLocalTime(preEvaluationDataForClip.normalizedLocalTime);
103
104 // Prepare property changes (if finalFrame it also prepares the change for the running property for the frontend)
105 auto record = prepareAnimationRecord(animatorId: clipAnimator->peerId(),
106 mappingDataVec: clipAnimator->mappingData(),
107 channelResults: formattedClipResults,
108 finalFrame: preEvaluationDataForClip.isFinalFrame,
109 normalizedLocalTime: preEvaluationDataForClip.normalizedLocalTime);
110
111 // Trigger callbacks either on this thread or by notifying the gui thread.
112 auto callbacks = prepareCallbacks(mappingDataVec: clipAnimator->mappingData(), channelResults: formattedClipResults);
113
114 // Update the normalized time on the backend node so that
115 // frontend <-> backend sync will not mark things dirty
116 // unless the frontend normalized time really is different
117 clipAnimator->setNormalizedLocalTime(normalizedLocalTime: record.normalizedTime, allowMarkDirty: false);
118
119 setPostFrameData(record, callbacks);
120}
121
122} // namespace Animation
123} // namespace Qt3DAnimation
124
125QT_END_NAMESPACE
126

source code of qt3d/src/animation/backend/evaluateclipanimatorjob.cpp