[SRUK] Initial copy from Tizen 2.2 version
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / key-frame-channel.h
1 #ifndef __DALI_INTERNAL_KEY_FRAME_CHANNEL_H__
2 #define __DALI_INTERNAL_KEY_FRAME_CHANNEL_H__
3
4 //
5 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
6 //
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
10 //
11 //     http://floralicense.org/license/
12 //
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.
18 //
19
20 // INTERNAL INCLUDES
21 #include <dali/public-api/common/vector-wrapper.h>
22 #include <dali/internal/event/animation/progress-value.h>
23
24 namespace Dali
25 {
26 namespace Internal
27 {
28
29 class KeyFrameChannelBase
30 {
31 public:
32   enum KeyFrameChannelId
33   {
34     Translate, Rotate, Scale,
35   };
36
37   KeyFrameChannelBase(KeyFrameChannelId channel_id)
38   : mChannelId(channel_id)
39   {
40   }
41
42   virtual ~KeyFrameChannelBase()
43   {
44   }
45
46   KeyFrameChannelId GetId() const
47   {
48     return mChannelId;
49   }
50
51   virtual bool IsActive(float progress) = 0;
52
53 protected:
54   KeyFrameChannelId       mChannelId;
55 };
56
57
58 template <typename V>
59 class KeyFrameChannel : public KeyFrameChannelBase
60 {
61 public:
62   typedef std::vector<ProgressValue<V> > ProgressValues;
63
64   KeyFrameChannel(KeyFrameChannelId channel_id, ProgressValues& values )
65   : KeyFrameChannelBase(channel_id),
66     mValues(values)
67   {
68   }
69
70
71   virtual ~KeyFrameChannel()
72   {
73   }
74
75   bool IsActive (float progress);
76
77   V GetValue(float progress) const;
78
79   bool FindInterval(typename ProgressValues::iterator& start,
80                     typename ProgressValues::iterator& end,
81                     float progress) const;
82
83   ProgressValues& mValues;
84 };
85
86 template <class V>
87 bool KeyFrameChannel<V>::IsActive (float progress)
88 {
89   bool active = false;
90   if(!mValues.empty())
91   {
92     ProgressValue<V>& first = mValues.front();
93     ProgressValue<V>& last  = mValues.back();
94
95     if (progress >= first.GetProgress() && progress <= last.GetProgress() )
96     {
97       active = true;
98     }
99   }
100   return active;
101 }
102
103 /**
104  * Use a linear search to find the interval containing progress
105  * TODO: Use binary search instead
106  */
107 template <class V>
108 bool KeyFrameChannel<V>::FindInterval(
109   typename ProgressValues::iterator& start,
110   typename ProgressValues::iterator& end,
111   float progress) const
112 {
113   bool found = false;
114   typename std::vector<ProgressValue<V> >::iterator iter = mValues.begin();
115   typename std::vector<ProgressValue<V> >::iterator prevIter = iter;
116
117   while(iter != mValues.end() && iter->GetProgress() <= progress)
118   {
119     prevIter = iter;
120     ++iter;
121   }
122
123   if(iter == mValues.end())
124   {
125     --prevIter;
126     --iter;
127   }
128
129   if(prevIter->GetProgress() <= progress
130      &&
131      iter->GetProgress() > progress)
132   {
133     found = true;
134     start = prevIter;
135     end   = iter;
136   }
137
138   return found;
139 }
140
141 template <class V>
142 V KeyFrameChannel<V>::GetValue (float progress) const
143 {
144   ProgressValue<V>&  firstPV =  mValues.front();
145
146   typename std::vector<ProgressValue<V> >::iterator start;
147   typename std::vector<ProgressValue<V> >::iterator end;
148
149   V interpolatedV;
150   if(FindInterval(start, end, progress))
151   {
152     float frameProgress = (progress - start->GetProgress()) / (end->GetProgress() - start->GetProgress());
153
154     interpolatedV = Interpolate(*start, *end, frameProgress);
155   }
156   else if(progress <= firstPV.GetProgress())
157   {
158     interpolatedV = firstPV.GetValue(); // This should probably be initial value...
159   }
160   else
161   {
162     interpolatedV = mValues.back().GetValue(); // Sticks at end value
163   }
164
165   return interpolatedV;
166 }
167
168 typedef KeyFrameChannel<float>      KeyFrameChannelNumber;
169 typedef KeyFrameChannel<Vector2>    KeyFrameChannelVector2;
170 typedef KeyFrameChannel<Vector3>    KeyFrameChannelVector3;
171 typedef KeyFrameChannel<Vector4>    KeyFrameChannelVector4;
172 typedef KeyFrameChannel<Quaternion> KeyFrameChannelQuaternion;
173 typedef KeyFrameChannel<AngleAxis>  KeyFrameChannelAngleAxis;
174
175
176 } // Internal
177 } // namespace Dali
178
179 #endif // __DALI_INTERNAL_KEY_FRAME_CHANNEL_H__