1 #ifndef DALI_INTERNAL_KEY_FRAME_CHANNEL_H
2 #define DALI_INTERNAL_KEY_FRAME_CHANNEL_H
5 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 #include <dali/internal/event/animation/progress-value.h>
23 #include <dali/public-api/animation/animation.h>
24 #include <dali/public-api/common/vector-wrapper.h>
31 class KeyFrameChannelBase
34 enum KeyFrameChannelId
36 Translate, Rotate, Scale,
39 KeyFrameChannelBase(KeyFrameChannelId channel_id)
40 : mChannelId(channel_id)
44 virtual ~KeyFrameChannelBase() = default;
46 KeyFrameChannelId GetId() const
51 virtual bool IsActive(float progress) = 0;
54 KeyFrameChannelId mChannelId;
59 class KeyFrameChannel : public KeyFrameChannelBase
62 using ProgressValues = std::vector<ProgressValue<V> >;
64 KeyFrameChannel(KeyFrameChannelId channel_id, ProgressValues& values )
65 : KeyFrameChannelBase(channel_id),
70 ~KeyFrameChannel() override = default;
72 bool IsActive (float progress) override;
74 V GetValue(float progress, Dali::Animation::Interpolation interpolation) const;
76 bool FindInterval(typename ProgressValues::iterator& start,
77 typename ProgressValues::iterator& end,
78 float progress) const;
80 ProgressValues& mValues;
84 bool KeyFrameChannel<V>::IsActive (float progress)
89 ProgressValue<V>& first = mValues.front();
91 if( progress >= first.GetProgress() )
100 * Use a linear search to find the interval containing progress
103 bool KeyFrameChannel<V>::FindInterval(
104 typename ProgressValues::iterator& start,
105 typename ProgressValues::iterator& end,
106 float progress) const
109 typename std::vector<ProgressValue<V> >::iterator iter = mValues.begin();
110 typename std::vector<ProgressValue<V> >::iterator prevIter = iter;
112 while(iter != mValues.end() && iter->GetProgress() <= progress)
118 if(iter == mValues.end())
124 if(prevIter->GetProgress() <= progress
126 iter->GetProgress() > progress)
137 V KeyFrameChannel<V>::GetValue (float progress, Dali::Animation::Interpolation interpolation) const
139 ProgressValue<V>& firstPV = mValues.front();
141 typename std::vector<ProgressValue<V> >::iterator start;
142 typename std::vector<ProgressValue<V> >::iterator end;
144 V interpolatedV = firstPV.GetValue();
145 if(progress >= mValues.back().GetProgress() )
147 interpolatedV = mValues.back().GetValue(); // This should probably be last value...
149 else if(FindInterval(start, end, progress))
151 float frameProgress = (progress - start->GetProgress()) / (end->GetProgress() - start->GetProgress());
153 if( interpolation == Dali::Animation::LINEAR )
155 Interpolate(interpolatedV, start->GetValue(), end->GetValue(), frameProgress);
159 //Calculate prev and next values
161 if( start != mValues.begin() )
163 prev = (start-1)->GetValue();
167 //Project next value through start point
168 prev = start->GetValue() + (start->GetValue()-(start+1)->GetValue());
172 if( end != mValues.end()-1)
174 next = (end+1)->GetValue();
178 //Project prev value through end point
179 next = end->GetValue() + (end->GetValue()-(end-1)->GetValue());
182 CubicInterpolate(interpolatedV, prev, start->GetValue(), end->GetValue(), next, frameProgress);
186 return interpolatedV;
189 using KeyFrameChannelNumber = KeyFrameChannel<float>;
190 using KeyFrameChannelVector2 = KeyFrameChannel<Vector2>;
191 using KeyFrameChannelVector3 = KeyFrameChannel<Vector3>;
192 using KeyFrameChannelVector4 = KeyFrameChannel<Vector4>;
193 using KeyFrameChannelQuaternion = KeyFrameChannel<Quaternion>;
194 using KeyFrameChannelAngleAxis = KeyFrameChannel<AngleAxis>;
199 #endif // DALI_INTERNAL_KEY_FRAME_CHANNEL_H