1 | // Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #ifndef QT3DANIMATION_ANIMATION_FCURVE_P_H |
5 | #define QT3DANIMATION_ANIMATION_FCURVE_P_H |
6 | |
7 | // |
8 | // W A R N I N G |
9 | // ------------- |
10 | // |
11 | // This file is not part of the Qt API. It exists for the convenience |
12 | // of other Qt classes. This header file may change from version to |
13 | // version without notice, or even be removed. |
14 | // |
15 | // We mean it. |
16 | // |
17 | |
18 | #include "keyframe_p.h" |
19 | #include "functionrangefinder_p.h" |
20 | |
21 | #include <Qt3DAnimation/qchannel.h> |
22 | #include <Qt3DAnimation/qchannelcomponent.h> |
23 | #include <Qt3DAnimation/qkeyframe.h> |
24 | #include <QtCore/qlist.h> |
25 | |
26 | #ifndef QT_NO_DEBUG_STREAM |
27 | #include <QtCore/qdebug.h> |
28 | #endif |
29 | |
30 | QT_BEGIN_NAMESPACE |
31 | |
32 | namespace Qt3DAnimation { |
33 | namespace Animation { |
34 | |
35 | class Q_AUTOTEST_EXPORT FCurve |
36 | { |
37 | public: |
38 | FCurve(); |
39 | |
40 | int keyframeCount() const { return m_localTimes.size(); } |
41 | void appendKeyframe(float localTime, const Keyframe &keyframe); |
42 | void clearKeyframes() { m_localTimes.clear(); m_keyframes.clear(); } |
43 | |
44 | const float &localTime(int index) const { return m_localTimes[index]; } |
45 | float &localTime(int index) { return m_localTimes[index]; } |
46 | const Keyframe &keyframe(int index) const { return m_keyframes[index]; } |
47 | Keyframe &keyframe(int index) { return m_keyframes[index]; } |
48 | |
49 | float startTime() const; |
50 | float endTime() const; |
51 | |
52 | float evaluateAtTime(float localTime) const; |
53 | float evaluateAtTime(float localTime, int lowerBound) const; |
54 | float evaluateAtTimeAsSlerp(float localTime, int lowerBound, float halfTheta, float sinHalfTheta, float reverseQ1) const; |
55 | int lowerKeyframeBound(float localTime) const; |
56 | |
57 | void read(const QJsonObject &json); |
58 | void setFromQChannelComponent(const QChannelComponent &qcc); |
59 | |
60 | private: |
61 | QList<float> m_localTimes; |
62 | QList<Keyframe> m_keyframes; |
63 | |
64 | FunctionRangeFinder m_rangeFinder; |
65 | }; |
66 | |
67 | #ifndef QT_NO_DEBUG_STREAM |
68 | inline QDebug operator<<(QDebug dbg, const FCurve &fcurve) |
69 | { |
70 | QDebugStateSaver saver(dbg); |
71 | dbg << "Keyframe Count = " << fcurve.keyframeCount() << Qt::endl; |
72 | for (int i = 0; i < fcurve.keyframeCount(); ++i) { |
73 | const Keyframe &kf = fcurve.keyframe(index: i); |
74 | switch (kf.interpolation) { |
75 | case QKeyFrame::BezierInterpolation: { |
76 | dbg << "t = " << fcurve.localTime(index: i) |
77 | << ", value = " << kf.value |
78 | << ", leftHandle = " << kf.leftControlPoint |
79 | << ", rightHandle = " << kf.rightControlPoint |
80 | << Qt::endl; |
81 | break; |
82 | } |
83 | case QKeyFrame::ConstantInterpolation: |
84 | case QKeyFrame::LinearInterpolation: { |
85 | dbg << "t = " << fcurve.localTime(index: i) |
86 | << ", value = " << kf.value |
87 | << Qt::endl; |
88 | break; |
89 | } |
90 | } |
91 | } |
92 | return dbg; |
93 | } |
94 | #endif |
95 | |
96 | struct ChannelComponent |
97 | { |
98 | QString name; |
99 | FCurve fcurve; |
100 | |
101 | void read(const QJsonObject &json); |
102 | void setFromQChannelComponent(const QChannelComponent &qcc); |
103 | }; |
104 | |
105 | #ifndef QT_NO_DEBUG_STREAM |
106 | inline QDebug operator<<(QDebug dbg, const ChannelComponent &channelComponent) |
107 | { |
108 | QDebugStateSaver saver(dbg); |
109 | dbg << "Channel Component Name: " << channelComponent.name << Qt::endl |
110 | << "FCurve:" << channelComponent.fcurve << Qt::endl; |
111 | return dbg; |
112 | } |
113 | #endif |
114 | |
115 | struct Channel |
116 | { |
117 | QString name; |
118 | qsizetype jointIndex = -1; |
119 | QVector<ChannelComponent> channelComponents; |
120 | |
121 | void read(const QJsonObject &json); |
122 | void setFromQChannel(const QChannel &qch); |
123 | }; |
124 | |
125 | #ifndef QT_NO_DEBUG_STREAM |
126 | inline QDebug operator<<(QDebug dbg, const Channel &channel) |
127 | { |
128 | QDebugStateSaver saver(dbg); |
129 | dbg << "Channel Name: " << channel.name << Qt::endl |
130 | << "Channels:" << channel.channelComponents.size() << Qt::endl; |
131 | |
132 | for (const auto &channelComponent : std::as_const(t: channel.channelComponents)) { |
133 | dbg << channelComponent; |
134 | } |
135 | return dbg; |
136 | } |
137 | #endif |
138 | |
139 | } // namespace Animation |
140 | } // namespace Qt3DAnimation |
141 | |
142 | QT_END_NAMESPACE |
143 | |
144 | #endif // QT3DANIMATION_ANIMATION_FCURVE_P_H |
145 | |