1 #ifndef __DALI_INTERNAL_KEY_FRAMES_H__
2 #define __DALI_INTERNAL_KEY_FRAMES_H__
5 * Copyright (c) 2017 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/public-api/common/vector-wrapper.h>
23 #include <dali/public-api/animation/key-frames.h>
24 #include <dali/public-api/object/base-object.h>
25 #include <dali/public-api/animation/alpha-function.h>
26 #include <dali/internal/event/animation/progress-value.h>
27 #include <dali/internal/event/animation/key-frame-channel.h>
35 typedef IntrusivePtr<KeyFrames> KeyFramesPtr;
39 * KeyFrames class is responsible for creating and building a specialized KeyFrame class
40 * from the Property::Value type used in Add.
42 class KeyFrames : public BaseObject
45 static KeyFrames* New();
48 * Instantiate an empty KeyFrames object
57 * Don't allow copy constructor
59 KeyFrames(const KeyFrames& rhs);
62 * Don't allow copy operator
64 KeyFrames& operator=(const KeyFrames& rhs);
67 * Create a specialization from the given type, and store it to the mSpec
70 void CreateKeyFramesSpec(Property::Type type);
74 * Get the type of this key frame.
75 * An empty key frame will return Property::NONE, wheras an initialised
76 * key frame object will return the type of it's first element.
77 * @return the Property::Type of the key frame values
79 Property::Type GetType() const;
82 * Add a key frame. The first key frame to be added denotes the type
83 * of all subsequent key frames. If a value with a different type is
84 * added, it will throw a run time assert.
85 * @param[in] time The time (between 0 and 1)
86 * @param[in] value The value of the keyframe at the given time
87 * @param[in] alpha An alpha function to blend between this key frame and the
90 void Add(float time, Property::Value value, AlphaFunction alpha);
93 * Return the key frames without specialization. The GetSpecialization methods
94 * below will convert to the specialized objects.
96 KeyFrameSpec* GetKeyFramesBase() const;
99 * Return the value of the last key frame.
101 Dali::Property::Value GetLastKeyFrameValue() const;
104 Dali::Property::Type mType; // Type of the specialization
105 IntrusivePtr<KeyFrameSpec> mKeyFrames; // Pointer to the specialized key frame object
110 * This is the base class for the individual template specializations, allowing a ptr to be
111 * stored in the handle object above. It inherits from RefObject to allow smart pointers
112 * to be used for the specializations. Note that the derived template class below
113 * allows for a copy constructor so that the specialization object can be cloned before
114 * being passed to the scene-graph for animation.
116 class KeyFrameSpec : public RefObject
122 virtual unsigned int GetNumberOfKeyFrames() const = 0;
125 * Get the key frame value as a Property::Value.
126 * @param[in] index The index of the key frame to fetch
127 * @param[out] value The value of the given key frame
129 virtual void GetKeyFrameAsValue( unsigned int index, Property::Value& value ) = 0;
134 * A reference counted object may only be deleted by calling Unreference()
136 virtual ~KeyFrameSpec() {}
141 * The base template class for each key frame specialization. It stores a vector of
142 * ProgressValue pairs in mPVs, and uses the existing interface for KeyFrameChannel
143 * to point at this vector.
146 class KeyFrameBaseSpec : public KeyFrameSpec
149 typedef ProgressValue<V> PV;
150 typedef std::vector<PV> PVContainer;
152 PVContainer mPVs; // The ProgressValue pairs
153 KeyFrameChannel<V>* mKeyFrames; // The key frame interpolator
156 static KeyFrameBaseSpec<V>* New()
158 return new KeyFrameBaseSpec<V>();
161 static KeyFrameBaseSpec<V>* Clone(const KeyFrameBaseSpec<V>& keyFrames)
163 return new KeyFrameBaseSpec<V>(keyFrames);
169 KeyFrameBaseSpec<V>()
171 mKeyFrames = new KeyFrameChannel<V>(KeyFrameChannelBase::Translate, mPVs);
177 * Allow cloning of this object
179 KeyFrameBaseSpec<V>(const KeyFrameBaseSpec<V>& keyFrames)
180 : mPVs(keyFrames.mPVs)
182 mKeyFrames = new KeyFrameChannel<V>(KeyFrameChannelBase::Translate, mPVs);
185 KeyFrameBaseSpec<V>& operator=( const KeyFrameBaseSpec<V>& keyFrames )
187 if( this != &keyFrames )
190 mPVs = keyFrames.mPVs;
192 mKeyFrames = new KeyFrameChannel<V>(KeyFrameChannelBase::Translate, mPVs);
198 * Destructor. Ensure progress value pairs are cleared down
200 virtual ~KeyFrameBaseSpec<V>()
208 * Add a key frame to the progress value vector. Key frames should be added
209 * in time order (this method does not sort the vector by time)
210 * @param[in] t - progress
211 * @param[in] v - value
212 * @param[in] alpha - Alpha function for blending to the next keyframe
214 void AddKeyFrame(float t, V v, AlphaFunction alpha)
216 mPVs.push_back(PV(t, v));
220 * Get the number of key frames
221 * @return The size of the progress value vector
223 virtual unsigned int GetNumberOfKeyFrames() const
230 * @param[in] index The index of the key frame to fetch
231 * @param[out] time The progress of the given key frame
232 * @param[out] value The value of the given key frame
234 virtual void GetKeyFrame(unsigned int index, float& time, V& value) const
236 DALI_ASSERT_ALWAYS( index < mPVs.size() && "KeyFrame index is out of bounds" );
237 time = mPVs[index].mProgress;
238 value = mPVs[index].mValue;
242 * @copydoc KeyFrameSpec::GetKeyFrameAsValue()
244 virtual void GetKeyFrameAsValue( unsigned int index, Property::Value& value )
246 value = mPVs[index].mValue;
250 * Return whether the progress is valid for the range of keyframes. (The first
251 * keyframe doesn't have to start at 0, and the last doesn't have to end at 1.0)
252 * @param[in] progress The progress to test
253 * @return True if the progress is valid for this object
255 bool IsActive(float progress) const
257 return mKeyFrames->IsActive(progress);
261 * Return an interpolated value for the given progress.
262 * @param[in] progress The progress to test
263 * @return The interpolated value
265 V GetValue(float progress, Dali::Animation::Interpolation interpolation) const
267 return mKeyFrames->GetValue(progress, interpolation);
271 typedef KeyFrameBaseSpec<float> KeyFrameNumber;
272 typedef KeyFrameBaseSpec<bool> KeyFrameBoolean;
273 typedef KeyFrameBaseSpec<int> KeyFrameInteger;
274 typedef KeyFrameBaseSpec<Vector2> KeyFrameVector2;
275 typedef KeyFrameBaseSpec<Vector3> KeyFrameVector3;
276 typedef KeyFrameBaseSpec<Vector4> KeyFrameVector4;
277 typedef KeyFrameBaseSpec<Quaternion> KeyFrameQuaternion;
279 typedef IntrusivePtr<KeyFrameBoolean> KeyFrameBooleanPtr;
280 typedef IntrusivePtr<KeyFrameNumber> KeyFrameNumberPtr;
281 typedef IntrusivePtr<KeyFrameInteger> KeyFrameIntegerPtr;
282 typedef IntrusivePtr<KeyFrameVector2> KeyFrameVector2Ptr;
283 typedef IntrusivePtr<KeyFrameVector3> KeyFrameVector3Ptr;
284 typedef IntrusivePtr<KeyFrameVector4> KeyFrameVector4Ptr;
285 typedef IntrusivePtr<KeyFrameQuaternion> KeyFrameQuaternionPtr;
288 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameBoolean*& keyFrameSpec)
290 keyFrameSpec = static_cast<Internal::KeyFrameBoolean*>(keyFrames.GetKeyFramesBase());
293 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameBoolean*& keyFrameSpec)
295 keyFrameSpec = static_cast<const Internal::KeyFrameBoolean*>(keyFrames.GetKeyFramesBase());
298 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameNumber*& keyFrameSpec)
300 keyFrameSpec = static_cast<Internal::KeyFrameNumber*>(keyFrames.GetKeyFramesBase());
303 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameNumber*& keyFrameSpec)
305 keyFrameSpec = static_cast<const Internal::KeyFrameNumber*>(keyFrames.GetKeyFramesBase());
308 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameInteger*& keyFrameSpec)
310 keyFrameSpec = static_cast<Internal::KeyFrameInteger*>(keyFrames.GetKeyFramesBase());
313 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameInteger*& keyFrameSpec)
315 keyFrameSpec = static_cast<const Internal::KeyFrameInteger*>(keyFrames.GetKeyFramesBase());
318 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameVector2*& keyFrameSpec)
320 keyFrameSpec = static_cast<Internal::KeyFrameVector2*>(keyFrames.GetKeyFramesBase());
323 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameVector2*& keyFrameSpec)
325 keyFrameSpec = static_cast<const Internal::KeyFrameVector2*>(keyFrames.GetKeyFramesBase());
328 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameVector3*& keyFrameSpec)
330 keyFrameSpec = static_cast<Internal::KeyFrameVector3*>(keyFrames.GetKeyFramesBase());
333 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameVector3*& keyFrameSpec)
335 keyFrameSpec = static_cast<const Internal::KeyFrameVector3*>(keyFrames.GetKeyFramesBase());
338 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameVector4*& keyFrameSpec)
340 keyFrameSpec = static_cast<Internal::KeyFrameVector4*>(keyFrames.GetKeyFramesBase());
343 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameVector4*& keyFrameSpec)
345 keyFrameSpec = static_cast<const Internal::KeyFrameVector4*>(keyFrames.GetKeyFramesBase());
348 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameQuaternion*& keyFrameSpec)
350 keyFrameSpec = static_cast<Internal::KeyFrameQuaternion*>(keyFrames.GetKeyFramesBase());
353 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameQuaternion*& keyFrameSpec)
355 keyFrameSpec = static_cast<const Internal::KeyFrameQuaternion*>(keyFrames.GetKeyFramesBase());
361 // Get impl of handle
362 inline Internal::KeyFrames& GetImplementation(Dali::KeyFrames& keyFrames)
364 DALI_ASSERT_ALWAYS( keyFrames && "KeyFrames handle is empty" );
365 Dali::RefObject& object = keyFrames.GetBaseObject();
366 return static_cast<Internal::KeyFrames&>(object);
369 inline const Internal::KeyFrames& GetImplementation(const Dali::KeyFrames& keyFrames)
371 DALI_ASSERT_ALWAYS( keyFrames && "KeyFrames handle is empty" );
372 const Dali::RefObject& object = keyFrames.GetBaseObject();
373 return static_cast<const Internal::KeyFrames&>(object);
379 #endif //__DALI_INTERNAL_KEY_FRAMES_H__