License conversion from Flora to Apache 2.0
[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 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
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
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
21 // INTERNAL INCLUDES
22 #include <dali/public-api/common/vector-wrapper.h>
23 #include <dali/internal/event/animation/progress-value.h>
24
25 namespace Dali
26 {
27 namespace Internal
28 {
29
30 class KeyFrameChannelBase
31 {
32 public:
33   enum KeyFrameChannelId
34   {
35     Translate, Rotate, Scale,
36   };
37
38   KeyFrameChannelBase(KeyFrameChannelId channel_id)
39   : mChannelId(channel_id)
40   {
41   }
42
43   virtual ~KeyFrameChannelBase()
44   {
45   }
46
47   KeyFrameChannelId GetId() const
48   {
49     return mChannelId;
50   }
51
52   virtual bool IsActive(float progress) = 0;
53
54 protected:
55   KeyFrameChannelId       mChannelId;
56 };
57
58
59 template <typename V>
60 class KeyFrameChannel : public KeyFrameChannelBase
61 {
62 public:
63   typedef std::vector<ProgressValue<V> > ProgressValues;
64
65   KeyFrameChannel(KeyFrameChannelId channel_id, ProgressValues& values )
66   : KeyFrameChannelBase(channel_id),
67     mValues(values)
68   {
69   }
70
71
72   virtual ~KeyFrameChannel()
73   {
74   }
75
76   bool IsActive (float progress);
77
78   V GetValue(float progress) const;
79
80   bool FindInterval(typename ProgressValues::iterator& start,
81                     typename ProgressValues::iterator& end,
82                     float progress) const;
83
84   ProgressValues& mValues;
85 };
86
87 template <class V>
88 bool KeyFrameChannel<V>::IsActive (float progress)
89 {
90   bool active = false;
91   if(!mValues.empty())
92   {
93     ProgressValue<V>& first = mValues.front();
94
95     if( progress >= first.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 = firstPV.GetValue();
150   if(progress >= mValues.back().GetProgress() )
151   {
152     interpolatedV = mValues.back().GetValue(); // This should probably be last value...
153   }
154   else if(FindInterval(start, end, progress))
155   {
156     float frameProgress = (progress - start->GetProgress()) / (end->GetProgress() - start->GetProgress());
157
158     interpolatedV = Interpolate(*start, *end, frameProgress);
159   }
160
161   return interpolatedV;
162 }
163
164 typedef KeyFrameChannel<float>      KeyFrameChannelNumber;
165 typedef KeyFrameChannel<Vector2>    KeyFrameChannelVector2;
166 typedef KeyFrameChannel<Vector3>    KeyFrameChannelVector3;
167 typedef KeyFrameChannel<Vector4>    KeyFrameChannelVector4;
168 typedef KeyFrameChannel<Quaternion> KeyFrameChannelQuaternion;
169 typedef KeyFrameChannel<AngleAxis>  KeyFrameChannelAngleAxis;
170
171
172 } // Internal
173 } // namespace Dali
174
175 #endif // __DALI_INTERNAL_KEY_FRAME_CHANNEL_H__