Purge underscored header file barriers
[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) 2019 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     uint32_t valueCount = static_cast<uint32_t>(  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       uint32_t min(0);
88       uint32_t max(0);
89       float tLocal(0.0f);
90       if( mProgress.Size() < valueCount )
91       {
92         float step = 1.0f / (static_cast<float>( valueCount ) - 1.0f);
93         float tLocation = t / step;
94         if( tLocation < 0 )
95         {
96           min = 0;
97           max = 1;
98         }
99         else if( tLocation >= static_cast<float>( valueCount-1 ) )
100         {
101           min = max = valueCount-1;
102         }
103         else
104         {
105           min = static_cast<uint32_t>(tLocation);
106           max = min+1;
107         }
108
109         tLocal = (t - static_cast<float>(min)*step) / step;
110       }
111       else
112       {
113         while( ( min < valueCount-1 )&&( t >= mProgress[min] ) )
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::SetDefaultProperty()
168    */
169   virtual void SetDefaultProperty(Property::Index index, const Property::Value& propertyValue);
170
171   /**
172    * @copydoc Dali::Internal::Object::GetDefaultProperty()
173    */
174   virtual Property::Value GetDefaultProperty( Property::Index index ) const;
175
176  /**
177   * @copydoc Dali::Internal::Object::GetDefaultPropertyCurrentValue()
178   */
179  virtual Property::Value GetDefaultPropertyCurrentValue( Property::Index index ) const;
180
181 public:
182
183   /**
184    * @copydoc Dali::PathConstrainer::Apply
185    */
186   void Apply( Property target, Property source, const Vector2& range, const Vector2& wrap );
187
188 private:
189
190   //Constructor
191   LinearConstrainer();
192
193   // Undefined
194   LinearConstrainer(const LinearConstrainer&);
195
196   // Undefined
197   LinearConstrainer& operator=(const LinearConstrainer& rhs);
198
199   Dali::Vector<float> mValue;     ///< values for the linear map
200   Dali::Vector<float> mProgress;  ///< Progress for each of the values normalized to [0,1]
201 };
202
203 } // Internal
204
205 // Get impl of handle
206 inline Internal::LinearConstrainer& GetImplementation(Dali::LinearConstrainer& linearConstrainer)
207 {
208   DALI_ASSERT_ALWAYS( linearConstrainer && "LinearConstrainer handle is empty" );
209   Dali::RefObject& object = linearConstrainer.GetBaseObject();
210   return static_cast<Internal::LinearConstrainer&>(object);
211 }
212
213 inline const Internal::LinearConstrainer& GetImplementation(const Dali::LinearConstrainer& linearConstrainer)
214 {
215   DALI_ASSERT_ALWAYS( linearConstrainer && "LinearConstrainer handle is empty" );
216   const Dali::RefObject& object = linearConstrainer.GetBaseObject();
217   return static_cast<const Internal::LinearConstrainer&>(object);
218 }
219
220 } // Dali
221
222 #endif // DALI_INTERNAL_PATH_CONSTRAINER_H