f663285dc17ef247a678471ebe65b9449eae26d6
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / path-constrainer-impl.h
1 #ifndef DALI_INTERNAL_PATH_CONSTRAINER_H
2 #define DALI_INTERNAL_PATH_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/devel-api/animation/path-constrainer.h>
24 #include <dali/public-api/math/math-utils.h>
25 #include <dali/internal/event/animation/path-impl.h>
26
27 namespace Dali
28 {
29
30 namespace Internal
31 {
32
33 typedef IntrusivePtr<PathConstrainer> PathConstrainerPtr;
34
35 /**
36  * @brief Constraint functor to constraint properties to paths.
37  *
38  * Vector3 properties will be constrained to the position of the path and
39  * Rotation properties will be constrained to follow the tangent of the path
40  * given a forward vector in object's local space.
41  */
42 struct PathConstraintFunctor
43 {
44   /**
45    * @brief Constructor.
46    *
47    * @param[in] path The path used in the constraint
48    * @param[in] range The range of values in the input property which will be mapped to [0,1]
49    * @param[in] wrap Wrapping domain. Input property value will be wrapped in the domain [wrap.x,wrap.y] before mapping to [0,1]
50    */
51   PathConstraintFunctor(PathPtr path, const Vector2& range, const Vector2& wrap ):mPath(path),mRange(range),mWrap(wrap){}
52
53   /**
54    * @brief Constructor.
55    *
56    * @param[in] path The path used in the constraint
57    * @param[in] range The range of values in the input property which will be mapped to 0..1
58    * @param[in] forward Vector in object space which will be aligned with the tangent of the path
59    * @param[in] wrap Wrapping domain. Input property value will be wrapped in the domain [wrap.x,wrap.y] before mapping to [0,1]
60    */
61   PathConstraintFunctor(PathPtr path, const Vector2& range,const Vector3& forward, const Vector2& wrap ):mPath(path),mForward(forward),mRange(range),mWrap(wrap){}
62
63   /**
64    * @brief Functor operator for Vector3 properties
65    *
66    * @param[in,out] position Current value of the property
67    * @param[in]     inputs Contains the input property used as the parameter for the path
68    *
69    * @return The position of the path at the given parameter.
70    */
71   void operator()( Vector3& position,
72                    const PropertyInputContainer& inputs)
73   {
74     float inputWrapped = inputs[0]->GetFloat();
75     if( inputWrapped < mWrap.x || inputWrapped > mWrap.y )
76     {
77       inputWrapped = WrapInDomain(inputWrapped, mWrap.x, mWrap.y);
78     }
79
80     float t = ( inputWrapped - mRange.x ) / ( mRange.y-mRange.x );
81
82     Vector3 tangent;
83     mPath->Sample( t, position, tangent );
84   }
85
86   /**
87    * @brief Functor operator for Quaternion properties
88    *
89    * @param[in,out] current Current value of the property
90    * @param[in]     inputs Contains the input property used as the parameter for the path
91    *
92    * @return The rotation which will align the forward vector and the tangent of the path at the given parameter.
93    */
94   void operator()( Quaternion& current,
95                    const PropertyInputContainer& inputs)
96   {
97     float inputWrapped = inputs[0]->GetFloat();
98     if( inputWrapped < mWrap.x || inputWrapped > mWrap.y )
99     {
100       inputWrapped = WrapInDomain(inputWrapped, mWrap.x, mWrap.y);
101     }
102
103     float t = ( inputWrapped - mRange.x ) / ( mRange.y-mRange.x );
104
105     Vector3 position, tangent;
106     mPath->Sample( t, position, tangent );
107     current = Quaternion( mForward, tangent );
108   }
109
110   PathPtr     mPath;      ///< The path used
111   Vector3     mForward;   ///< Vector in object space which will be aligned with the tangent of the path
112   Vector2     mRange;     ///< The range of values in the input property which will be mapped to 0..1
113   Vector2     mWrap;      ///< Wrapping domain. Input property will be wrapped in this domain before being mapped to [0,1]
114 };
115
116 /**
117  * @brief A PathConstrainer used to constraint properties to a path
118  */
119 class PathConstrainer : public Constrainer
120 {
121 public:
122
123   /**
124    * Create a new PathConstrainer
125    * @return A smart-pointer to the newly allocated PathConstrainer.
126    */
127   static PathConstrainer* New();
128
129 protected:
130
131   /**
132    * virtual destructor
133    */
134   virtual ~PathConstrainer();
135
136 private:
137
138   /**
139    * @copydoc Dali::Internal::Object::SetDefaultProperty()
140    */
141   virtual void SetDefaultProperty(Property::Index index, const Property::Value& propertyValue);
142
143   /**
144    * @copydoc Dali::Internal::Object::GetDefaultProperty()
145    */
146   virtual Property::Value GetDefaultProperty( Property::Index index ) const;
147
148  /**
149   * @copydoc Dali::Internal::Object::GetDefaultPropertyCurrentValue()
150   */
151  virtual Property::Value GetDefaultPropertyCurrentValue( Property::Index index ) const;
152
153 public:
154
155   /**
156    * @copydoc Dali::PathConstrainer::Apply
157    */
158   void Apply( Property target, Property source, const Vector2& range, const Vector2& wrap );
159
160 private:
161
162   //Constructor
163   PathConstrainer();
164
165   // Undefined
166   PathConstrainer(const PathConstrainer&);
167
168   // Undefined
169   PathConstrainer& operator=(const PathConstrainer& rhs);
170
171   PathPtr mPath;    ///< The path used in the constraints
172   Vector3 mForward; ///< Vector in object space which will be aligned with the tangent of the path
173 };
174
175 } // Internal
176
177 // Get impl of handle
178 inline Internal::PathConstrainer& GetImplementation(Dali::PathConstrainer& pathConstrainer)
179 {
180   DALI_ASSERT_ALWAYS( pathConstrainer && "PathConstrainer handle is empty" );
181   Dali::RefObject& object = pathConstrainer.GetBaseObject();
182   return static_cast<Internal::PathConstrainer&>(object);
183 }
184
185 inline const Internal::PathConstrainer& GetImplementation(const Dali::PathConstrainer& pathConstrainer)
186 {
187   DALI_ASSERT_ALWAYS( pathConstrainer && "PathConstrainer handle is empty" );
188   const Dali::RefObject& object = pathConstrainer.GetBaseObject();
189   return static_cast<const Internal::PathConstrainer&>(object);
190 }
191
192 } // Dali
193
194 #endif // DALI_INTERNAL_PATH_CONSTRAINER_H