1 #ifndef DALI_INTERNAL_LINEAR_CONSTRAINER_H
2 #define DALI_INTERNAL_LINEAR_CONSTRAINER_H
5 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
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>
30 typedef IntrusivePtr<LinearConstrainer> LinearConstrainerPtr;
33 * @brief Constraint functor to constraint properties given a linear map.
35 struct LinearConstraintFunctor
40 * @param[in] value The list of values for the linear map (f(x) of the linear map)
41 * @param[in] progress Progress for each of the values normalized to [0,1] ( x of the linear map)
42 * @param[in] range The range of values in the input property which will be mapped to [0,1]
43 * @param[in] wrap Wrapping domain. Input property value will be wrapped in the domain [wrap.x,wrap.y] before mapping to [0,1]
45 * @note If progress is an empty vector, the values will be assumed to be equally spaced in the x-axis
47 LinearConstraintFunctor(Dali::Vector<float>& value, Dali::Vector<float>& progress, const Vector2& range, const Vector2& wrap)
56 * @brief Functor operator for float properties
58 * @param[out] value Current value of the property
59 * @param[in] inputs Contains the input property used as the parameter for the path
61 * @return The value of the linear map at the given parameter.
63 void operator()(float& value,
64 const PropertyInputContainer& inputs)
66 uint32_t valueCount = static_cast<uint32_t>(mValue.Size());
71 else if(valueCount == 1)
77 float inputWrapped = inputs[0]->GetFloat();
78 if(inputWrapped < mWrap.x || inputWrapped > mWrap.y)
80 inputWrapped = WrapInDomain(inputWrapped, mWrap.x, mWrap.y);
83 float t = ((inputWrapped - mRange.x) / (mRange.y - mRange.x));
85 //Find min and max values and local t between them
89 if(mProgress.Size() < valueCount)
91 float step = 1.0f / (static_cast<float>(valueCount) - 1.0f);
92 float tLocation = t / step;
98 else if(tLocation >= static_cast<float>(valueCount - 1))
100 min = max = valueCount - 1;
104 min = static_cast<uint32_t>(tLocation);
108 tLocal = (t - static_cast<float>(min) * step) / step;
112 while((min < valueCount - 1) && (t >= mProgress[min]))
120 if(min >= valueCount - 1)
122 min = max = valueCount - 1;
127 tLocal = (t - mProgress[min]) / (mProgress[max] - mProgress[min]);
131 //Linear interpolation
132 value = (mValue[max] - mValue[min]) * tLocal + mValue[min];
136 Dali::Vector<float> mValue; ///< values for the linear map
137 Dali::Vector<float> mProgress; ///< Progress for each of the values normalized to [0,1]
138 Vector2 mRange; ///< The range of values in the input property which will be mapped to 0..1
139 Vector2 mWrap; ///< Wrapping domain. Input property will be wrapped in this domain before being mapped to [0,1]
143 * @brief A LinearConstrainer used to constraint properties given a linear map
145 class LinearConstrainer : public Constrainer
149 * Create a new LinearConstrainer
150 * @return A smart-pointer to the newly allocated LinearConstrainer.
152 static LinearConstrainer* New();
158 ~LinearConstrainer() override;
162 * @copydoc Dali::Internal::Object::SetDefaultProperty()
164 void SetDefaultProperty(Property::Index index, const Property::Value& propertyValue) override;
167 * @copydoc Dali::Internal::Object::GetDefaultProperty()
169 Property::Value GetDefaultProperty(Property::Index index) const override;
172 * @copydoc Dali::Internal::Object::GetDefaultPropertyCurrentValue()
174 Property::Value GetDefaultPropertyCurrentValue(Property::Index index) const override;
178 * @copydoc Dali::PathConstrainer::Apply
180 void Apply(Property target, Property source, const Vector2& range, const Vector2& wrap) override;
187 LinearConstrainer(const LinearConstrainer&);
190 LinearConstrainer& operator=(const LinearConstrainer& rhs);
192 Dali::Vector<float> mValue; ///< values for the linear map
193 Dali::Vector<float> mProgress; ///< Progress for each of the values normalized to [0,1]
196 } // namespace Internal
198 // Get impl of handle
199 inline Internal::LinearConstrainer& GetImplementation(Dali::LinearConstrainer& linearConstrainer)
201 DALI_ASSERT_ALWAYS(linearConstrainer && "LinearConstrainer handle is empty");
202 Dali::RefObject& object = linearConstrainer.GetBaseObject();
203 return static_cast<Internal::LinearConstrainer&>(object);
206 inline const Internal::LinearConstrainer& GetImplementation(const Dali::LinearConstrainer& linearConstrainer)
208 DALI_ASSERT_ALWAYS(linearConstrainer && "LinearConstrainer handle is empty");
209 const Dali::RefObject& object = linearConstrainer.GetBaseObject();
210 return static_cast<const Internal::LinearConstrainer&>(object);
215 #endif // DALI_INTERNAL_PATH_CONSTRAINER_H