[dali_1.2.36] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / linear-constrainer-impl.h
1 #ifndef __DALI_INTERNAL_LINEAR_CONSTRAINER_H__
2 #define __DALI_INTERNAL_LINEAR_CONSTRAINER_H__
3
4 /*
5  * Copyright (c) 2015 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/internal/event/animation/constrainer.h>
23 #include <dali/public-api/animation/linear-constrainer.h>
24 #include <dali/public-api/math/math-utils.h>
25
26 namespace Dali
27 {
28
29 namespace Internal
30 {
31
32 typedef IntrusivePtr<LinearConstrainer> LinearConstrainerPtr;
33
34 /**
35  * @brief Constraint functor to constraint properties given a linear map.
36  */
37 struct LinearConstraintFunctor
38 {
39   /**
40    * @brief Constructor.
41    *
42    * @param[in] value The list of values for the linear map (f(x) of the linear map)
43    * @param[in] progress Progress for each of the values normalized to [0,1] ( x of the linear map)
44    * @param[in] range The range of values in the input property which will be mapped to [0,1]
45    * @param[in] wrap Wrapping domain. Input property value will be wrapped in the domain [wrap.x,wrap.y] before mapping to [0,1]
46    *
47    * @note If progress is an empty vector, the values will be assumed to be equally spaced in the x-axis
48    */
49   LinearConstraintFunctor( Dali::Vector<float>& value, Dali::Vector<float>& progress, const Vector2& range, const Vector2& wrap )
50   :mValue(value),
51    mProgress(progress),
52    mRange(range),
53    mWrap(wrap)
54   {}
55
56   /**
57    * @brief Functor operator for float properties
58    *
59    * @param[out]  value Current value of the property
60    * @param[in]   inputs Contains the input property used as the parameter for the path
61    *
62    * @return The value of the linear map at the given parameter.
63    */
64   void operator()( float& value,
65                    const PropertyInputContainer& inputs)
66   {
67     size_t valueCount(  mValue.Size() );
68     if( valueCount == 0 )
69     {
70       //No values.
71     }
72     else if(valueCount == 1 )
73     {
74       value = mValue[0];
75     }
76     else
77     {
78       float inputWrapped = inputs[0]->GetFloat();
79       if( inputWrapped < mWrap.x || inputWrapped > mWrap.y )
80       {
81         inputWrapped = WrapInDomain(inputWrapped, mWrap.x, mWrap.y);
82       }
83
84       float t = (( inputWrapped - mRange.x ) / ( mRange.y-mRange.x ));
85
86       //Find min and max values and local t between them
87       size_t min(0);
88       size_t max(0);
89       float tLocal(0.0f);
90       if( mProgress.Size() < valueCount )
91       {
92         float step = 1.0f / (valueCount-1.0f);
93         float tLocation = t/step;
94         if( tLocation < 0)
95         {
96           min = 0;
97           max = 1;
98         }
99         else if( tLocation >= valueCount-1 )
100         {
101           min = max = valueCount-1;
102         }
103         else
104         {
105           min = static_cast<size_t>(tLocation);
106           max = min+1;
107         }
108
109         tLocal = (t - min*step) / step;
110       }
111       else
112       {
113         while( t >= mProgress[min] && min < valueCount-1 )
114         {
115           min++;
116         }
117
118         min--;
119         max = min+1;
120
121         if( min >= valueCount-1)
122         {
123           min = max = valueCount-1;
124           tLocal = 0.0f;
125         }
126         else
127         {
128           tLocal =(t - mProgress[min]) / ( mProgress[max]-mProgress[min]);
129         }
130       }
131
132       //Linear interpolation
133       value = (mValue[max]-mValue[min])*tLocal + mValue[min];
134     }
135   }
136
137
138   Dali::Vector<float> mValue;     ///< values for the linear map
139   Dali::Vector<float> mProgress;  ///< Progress for each of the values normalized to [0,1]
140   Vector2             mRange;     ///< The range of values in the input property which will be mapped to 0..1
141   Vector2             mWrap;      ///< Wrapping domain. Input property will be wrapped in this domain before being mapped to [0,1]
142 };
143
144 /**
145  * @brief A LinearConstrainer used to constraint properties given a linear map
146  */
147 class LinearConstrainer : public Constrainer
148 {
149 public:
150
151   /**
152    * Create a new LinearConstrainer
153    * @return A smart-pointer to the newly allocated LinearConstrainer.
154    */
155   static LinearConstrainer* New();
156
157 protected:
158
159   /**
160    * virtual destructor
161    */
162   virtual ~LinearConstrainer();
163
164 private:
165
166   /**
167    * @copydoc Dali::Internal::Object::GetDefaultPropertyCount()
168    */
169   virtual unsigned int GetDefaultPropertyCount() const;
170
171   /**
172    * @copydoc Dali::Internal::Object::GetDefaultPropertyIndices()
173    */
174   virtual void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const;
175
176   /**
177    * @copydoc Dali::Internal::Object::GetDefaultPropertyName()
178    */
179   virtual const char* GetDefaultPropertyName(Property::Index index) const;
180
181   /**
182    * @copydoc Dali::Internal::Object::GetDefaultPropertyIndex()
183    */
184   virtual Property::Index GetDefaultPropertyIndex(const std::string& name) const;
185
186   /**
187    * @copydoc Dali::Internal::Object::IsDefaultPropertyWritable()
188    */
189   virtual bool IsDefaultPropertyWritable(Property::Index index) const;
190
191   /**
192    * @copydoc Dali::Internal::Object::IsDefaultPropertyAnimatable()
193    */
194   virtual bool IsDefaultPropertyAnimatable(Property::Index index) const;
195
196   /**
197    * @copydoc Dali::Internal::Object::IsDefaultPropertyAConstraintInput()
198    */
199   virtual bool IsDefaultPropertyAConstraintInput( Property::Index index ) const;
200
201   /**
202    * @copydoc Dali::Internal::Object::GetDefaultPropertyType()
203    */
204   virtual Property::Type GetDefaultPropertyType(Property::Index index) const;
205
206   /**
207    * @copydoc Dali::Internal::Object::SetDefaultProperty()
208    */
209   virtual void SetDefaultProperty(Property::Index index, const Property::Value& propertyValue);
210
211    /**
212    * @copydoc Dali::Internal::Object::GetDefaultProperty()
213    */
214   virtual Property::Value GetDefaultProperty( Property::Index index ) const;
215
216 public:
217
218   /**
219    * @copydoc Dali::PathConstrainer::Apply
220    */
221   void Apply( Property target, Property source, const Vector2& range, const Vector2& wrap );
222
223 private:
224
225   //Constructor
226   LinearConstrainer();
227
228   // Undefined
229   LinearConstrainer(const LinearConstrainer&);
230
231   // Undefined
232   LinearConstrainer& operator=(const LinearConstrainer& rhs);
233
234   Dali::Vector<float> mValue;     ///< values for the linear map
235   Dali::Vector<float> mProgress;  ///< Progress for each of the values normalized to [0,1]
236 };
237
238 } // Internal
239
240 // Get impl of handle
241 inline Internal::LinearConstrainer& GetImplementation(Dali::LinearConstrainer& linearConstrainer)
242 {
243   DALI_ASSERT_ALWAYS( linearConstrainer && "LinearConstrainer handle is empty" );
244   Dali::RefObject& object = linearConstrainer.GetBaseObject();
245   return static_cast<Internal::LinearConstrainer&>(object);
246 }
247
248 inline const Internal::LinearConstrainer& GetImplementation(const Dali::LinearConstrainer& linearConstrainer)
249 {
250   DALI_ASSERT_ALWAYS( linearConstrainer && "LinearConstrainer handle is empty" );
251   const Dali::RefObject& object = linearConstrainer.GetBaseObject();
252   return static_cast<const Internal::LinearConstrainer&>(object);
253 }
254
255 } // Dali
256
257 #endif //__DALI_INTERNAL_PATH_CONSTRAINER_H__