1 #ifndef __DALI_INTERNAL_KEY_FRAMES_H__
2 #define __DALI_INTERNAL_KEY_FRAMES_H__
5 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
7 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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.
21 #include <dali/public-api/common/vector-wrapper.h>
22 #include <dali/public-api/animation/key-frames.h>
23 #include <dali/public-api/object/base-object.h>
24 #include <dali/public-api/animation/alpha-functions.h>
25 #include <dali/internal/event/animation/progress-value.h>
26 #include <dali/internal/event/animation/key-frame-channel.h>
34 typedef IntrusivePtr<KeyFrames> KeyFramesPtr;
38 * KeyFrames class is responsible for creating and building a specialized KeyFrame class
39 * from the Property::Value type used in Add.
41 class KeyFrames : public BaseObject
44 static KeyFrames* New();
47 * Instantiate an empty KeyFrames object
56 * Don't allow copy constructor
58 KeyFrames(const KeyFrames& rhs);
61 * Don't allow copy operator
63 KeyFrames& operator=(const KeyFrames& rhs);
66 * Create a specialization from the given type, and store it to the mSpec
69 void CreateKeyFramesSpec(Property::Type type);
73 * Get the type of this key frame.
74 * An empty key frame will return Property::NONE, wheras an initialised
75 * key frame object will return the type of it's first element.
76 * @return the Property::Type of the key frame values
78 Property::Type GetType() const;
81 * Add a key frame. The first key frame to be added denotes the type
82 * of all subsequent key frames. If a value with a different type is
83 * added, it will throw a run time assert.
84 * @param[in] time The time (between 0 and 1)
85 * @param[in] value The value of the keyframe at the given time
86 * @param[in] alpha An alpha function to blend between this key frame and the
89 void Add(float time, Property::Value value, AlphaFunction alpha);
92 * Return the key frames without specialization. The GetSpecialization methods
93 * below will convert to the specialized objects.
95 KeyFrameSpec* GetKeyFramesBase() const;
98 Dali::Property::Type mType; // Type of the specialization
99 IntrusivePtr<KeyFrameSpec> mKeyFrames; // Pointer to the specialized key frame object
104 * This is the base class for the individual template specializations, allowing a ptr to be
105 * stored in the handle object above. It inherits from RefObject to allow smart pointers
106 * to be used for the specializations. Note that the derived template class below
107 * allows for a copy constructor so that the specialization object can be cloned before
108 * being passed to the scene-graph for animation.
110 class KeyFrameSpec : public RefObject
116 virtual unsigned int GetNumberOfKeyFrames() const = 0;
121 * A reference counted object may only be deleted by calling Unreference()
123 virtual ~KeyFrameSpec() {}
128 * The base template class for each key frame specialization. It stores a vector of
129 * ProgressValue pairs in mPVs, and uses the existing interface for KeyFrameChannel
130 * to point at this vector.
131 * TODO: Incorporate KeyFrameChannel into this base template
134 class KeyFrameBaseSpec : public KeyFrameSpec
137 typedef ProgressValue<V> PV;
138 typedef std::vector<PV> PVContainer;
140 PVContainer mPVs; // The ProgressValue pairs
141 KeyFrameChannel<V>* mKeyFrames; // The key frame interpolator
144 static KeyFrameBaseSpec<V>* New()
146 return new KeyFrameBaseSpec<V>();
149 static KeyFrameBaseSpec<V>* Clone(const KeyFrameBaseSpec<V>& keyFrames)
151 return new KeyFrameBaseSpec<V>(keyFrames);
157 KeyFrameBaseSpec<V>()
159 mKeyFrames = new KeyFrameChannel<V>(KeyFrameChannelBase::Translate, mPVs);
165 * Allow cloning of this object
167 KeyFrameBaseSpec<V>(const KeyFrameBaseSpec<V>& keyFrames)
168 : mPVs(keyFrames.mPVs)
170 mKeyFrames = new KeyFrameChannel<V>(KeyFrameChannelBase::Translate, mPVs);
174 * Destructor. Ensure progress value pairs are cleared down
176 virtual ~KeyFrameBaseSpec<V>()
184 * Add a key frame to the progress value vector. Key frames should be added
185 * in time order (this method does not sort the vector by time)
186 * @param[in] t - progress
187 * @param[in] v - value
188 * @param[in] alpha - Alpha function for blending to the next keyframe
190 void AddKeyFrame(float t, V v, AlphaFunction alpha)
192 // TODO:: Support alpha
193 mPVs.push_back(PV(t, v));
197 * Get the number of key frames
198 * @return The size of the progress value vector
200 virtual unsigned int GetNumberOfKeyFrames() const
207 * @param[in] index The index of the key frame to fetch
208 * @param[out] time The progress of the given key frame
209 * @param[out] value The value of the given key frame
211 virtual void GetKeyFrame(unsigned int index, float& time, V& value) const
213 DALI_ASSERT_ALWAYS( index < mPVs.size() && "KeyFrame index is out of bounds" );
214 time = mPVs[index].mProgress;
215 value = mPVs[index].mValue;
219 * Return whether the progress is valid for the range of keyframes. (The first
220 * keyframe doesn't have to start at 0, and the last doesn't have to end at 1.0)
221 * @param[in] progress The progress to test
222 * @return True if the progress is valid for this object
224 bool IsActive(float progress) const
226 return mKeyFrames->IsActive(progress);
230 * Return an interpolated value for the given progress.
231 * @param[in] progress The progress to test
232 * @return The interpolated value
234 V GetValue(float progress) const
236 return mKeyFrames->GetValue(progress);
240 typedef KeyFrameBaseSpec<float> KeyFrameNumber;
241 typedef KeyFrameBaseSpec<bool> KeyFrameBoolean;
242 typedef KeyFrameBaseSpec<Vector2> KeyFrameVector2;
243 typedef KeyFrameBaseSpec<Vector3> KeyFrameVector3;
244 typedef KeyFrameBaseSpec<Vector4> KeyFrameVector4;
245 typedef KeyFrameBaseSpec<Quaternion> KeyFrameQuaternion;
247 typedef IntrusivePtr<KeyFrameBoolean> KeyFrameBooleanPtr;
248 typedef IntrusivePtr<KeyFrameNumber> KeyFrameNumberPtr;
249 typedef IntrusivePtr<KeyFrameVector2> KeyFrameVector2Ptr;
250 typedef IntrusivePtr<KeyFrameVector3> KeyFrameVector3Ptr;
251 typedef IntrusivePtr<KeyFrameVector4> KeyFrameVector4Ptr;
252 typedef IntrusivePtr<KeyFrameQuaternion> KeyFrameQuaternionPtr;
255 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameBoolean*& keyFrameSpec)
257 keyFrameSpec = static_cast<Internal::KeyFrameBoolean*>(keyFrames.GetKeyFramesBase());
260 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameBoolean*& keyFrameSpec)
262 keyFrameSpec = static_cast<const Internal::KeyFrameBoolean*>(keyFrames.GetKeyFramesBase());
266 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameNumber*& keyFrameSpec)
268 keyFrameSpec = static_cast<Internal::KeyFrameNumber*>(keyFrames.GetKeyFramesBase());
271 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameNumber*& keyFrameSpec)
273 keyFrameSpec = static_cast<const Internal::KeyFrameNumber*>(keyFrames.GetKeyFramesBase());
276 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameVector2*& keyFrameSpec)
278 keyFrameSpec = static_cast<Internal::KeyFrameVector2*>(keyFrames.GetKeyFramesBase());
281 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameVector2*& keyFrameSpec)
283 keyFrameSpec = static_cast<const Internal::KeyFrameVector2*>(keyFrames.GetKeyFramesBase());
286 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameVector3*& keyFrameSpec)
288 keyFrameSpec = static_cast<Internal::KeyFrameVector3*>(keyFrames.GetKeyFramesBase());
291 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameVector3*& keyFrameSpec)
293 keyFrameSpec = static_cast<const Internal::KeyFrameVector3*>(keyFrames.GetKeyFramesBase());
296 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameVector4*& keyFrameSpec)
298 keyFrameSpec = static_cast<Internal::KeyFrameVector4*>(keyFrames.GetKeyFramesBase());
301 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameVector4*& keyFrameSpec)
303 keyFrameSpec = static_cast<const Internal::KeyFrameVector4*>(keyFrames.GetKeyFramesBase());
306 inline void GetSpecialization(Internal::KeyFrames& keyFrames, Internal::KeyFrameQuaternion*& keyFrameSpec)
308 keyFrameSpec = static_cast<Internal::KeyFrameQuaternion*>(keyFrames.GetKeyFramesBase());
311 inline void GetSpecialization(const Internal::KeyFrames& keyFrames, const Internal::KeyFrameQuaternion*& keyFrameSpec)
313 keyFrameSpec = static_cast<const Internal::KeyFrameQuaternion*>(keyFrames.GetKeyFramesBase());
319 // Get impl of handle
320 inline Internal::KeyFrames& GetImplementation(Dali::KeyFrames& keyFrames)
322 DALI_ASSERT_ALWAYS( keyFrames && "KeyFrames handle is empty" );
323 Dali::RefObject& object = keyFrames.GetBaseObject();
324 return static_cast<Internal::KeyFrames&>(object);
327 inline const Internal::KeyFrames& GetImplementation(const Dali::KeyFrames& keyFrames)
329 DALI_ASSERT_ALWAYS( keyFrames && "KeyFrames handle is empty" );
330 const Dali::RefObject& object = keyFrames.GetBaseObject();
331 return static_cast<const Internal::KeyFrames&>(object);
337 #endif //__DALI_INTERNAL_KEY_FRAMES_H__