• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef RENDER_SERVICE_CLIENT_CORE_ANIMATION_RS_VALUE_ESTIMATOR_H
17 #define RENDER_SERVICE_CLIENT_CORE_ANIMATION_RS_VALUE_ESTIMATOR_H
18 
19 #include <memory>
20 
21 #include "rs_spring_model.h"
22 
23 #include "animation/rs_animation_common.h"
24 #include "animation/rs_interpolator.h"
25 #include "common/rs_color.h"
26 #include "common/rs_macros.h"
27 #include "common/rs_matrix3.h"
28 #include "common/rs_vector2.h"
29 #include "common/rs_vector4.h"
30 #include "modifier/rs_modifier_type.h"
31 #include "render/rs_filter.h"
32 
33 namespace OHOS {
34 namespace Rosen {
35 class RSRenderPropertyBase;
36 template<typename T>
37 class RSRenderAnimatableProperty;
38 
39 class RSB_EXPORT RSValueEstimator {
40 public:
41     template<typename T>
Estimate(float fraction,const T & startValue,const T & endValue)42     T Estimate(float fraction, const T& startValue, const T& endValue)
43     {
44         return startValue * (1.0f - fraction) + endValue * fraction;
45     }
46 
47     Quaternion Estimate(float fraction, const Quaternion& startValue, const Quaternion& endValue);
48 
49     std::shared_ptr<RSFilter> Estimate(
50         float fraction, const std::shared_ptr<RSFilter>& startValue, const std::shared_ptr<RSFilter>& endValue);
51 
EstimateFraction(const std::shared_ptr<RSInterpolator> & interpolator)52     virtual float EstimateFraction(const std::shared_ptr<RSInterpolator>& interpolator)
53     {
54         return 0.0f;
55     }
56 
EstimateFraction(const std::shared_ptr<RSInterpolator> & interpolator,float targetFraction,int duration)57     virtual float EstimateFraction(const std::shared_ptr<RSInterpolator>& interpolator,
58         float targetFraction, int duration)
59     {
60         return 0.0f;
61     }
62 
InitCurveAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & property,const std::shared_ptr<RSRenderPropertyBase> & startValue,const std::shared_ptr<RSRenderPropertyBase> & endValue,const std::shared_ptr<RSRenderPropertyBase> & lastValue)63     virtual void InitCurveAnimationValue(const std::shared_ptr<RSRenderPropertyBase>& property,
64         const std::shared_ptr<RSRenderPropertyBase>& startValue,
65         const std::shared_ptr<RSRenderPropertyBase>& endValue,
66         const std::shared_ptr<RSRenderPropertyBase>& lastValue) {}
67 
InitKeyframeAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & property,std::vector<std::tuple<float,std::shared_ptr<RSRenderPropertyBase>,std::shared_ptr<RSInterpolator>>> & keyframes,const std::shared_ptr<RSRenderPropertyBase> & lastValue)68     virtual void InitKeyframeAnimationValue(const std::shared_ptr<RSRenderPropertyBase>& property,
69         std::vector<std::tuple<float, std::shared_ptr<RSRenderPropertyBase>,
70         std::shared_ptr<RSInterpolator>>>& keyframes,
71         const std::shared_ptr<RSRenderPropertyBase>& lastValue) {}
72 
InitDurationKeyframeAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & property,std::vector<std::tuple<float,float,std::shared_ptr<RSRenderPropertyBase>,std::shared_ptr<RSInterpolator>>> & keyframes,const std::shared_ptr<RSRenderPropertyBase> & lastValue)73     virtual void InitDurationKeyframeAnimationValue(const std::shared_ptr<RSRenderPropertyBase>& property,
74         std::vector<std::tuple<float, float, std::shared_ptr<RSRenderPropertyBase>,
75         std::shared_ptr<RSInterpolator>>>& keyframes,
76         const std::shared_ptr<RSRenderPropertyBase>& lastValue) {}
77 
78     virtual void UpdateAnimationValue(const float fraction, const bool isAdditive) = 0;
79 };
80 
81 template<typename T>
82 class RSB_EXPORT_TMP RSCurveValueEstimator : public RSValueEstimator {
83 public:
84     RSCurveValueEstimator() = default;
85     virtual ~RSCurveValueEstimator() = default;
86 
InitCurveAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & property,const std::shared_ptr<RSRenderPropertyBase> & startValue,const std::shared_ptr<RSRenderPropertyBase> & endValue,const std::shared_ptr<RSRenderPropertyBase> & lastValue)87     void InitCurveAnimationValue(const std::shared_ptr<RSRenderPropertyBase>& property,
88         const std::shared_ptr<RSRenderPropertyBase>& startValue,
89         const std::shared_ptr<RSRenderPropertyBase>& endValue,
90         const std::shared_ptr<RSRenderPropertyBase>& lastValue) override
91     {
92         auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(property);
93         auto animatableStartValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(startValue);
94         auto animatableEndValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(endValue);
95         auto animatableLastValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(lastValue);
96         if (animatableProperty && animatableStartValue && animatableEndValue && animatableLastValue) {
97             property_ = animatableProperty;
98             startValue_ = animatableStartValue->Get();
99             endValue_ = animatableEndValue->Get();
100             lastValue_ = animatableLastValue->Get();
101         }
102     }
103 
UpdateAnimationValue(const float fraction,const bool isAdditive)104     void UpdateAnimationValue(const float fraction, const bool isAdditive) override
105     {
106         auto animationValue = GetAnimationValue(fraction, isAdditive);
107         if (property_ != nullptr) {
108             property_->Set(animationValue);
109         }
110     }
111 
GetAnimationValue(const float fraction,const bool isAdditive)112     T GetAnimationValue(const float fraction, const bool isAdditive)
113     {
114         auto interpolationValue = RSValueEstimator::Estimate(fraction, startValue_, endValue_);
115         auto animationValue = interpolationValue;
116         if (isAdditive && property_ != nullptr) {
117             animationValue = property_->Get() + (interpolationValue - lastValue_);
118         }
119         lastValue_ = interpolationValue;
120         return animationValue;
121     }
122 
EstimateFraction(const std::shared_ptr<RSInterpolator> & interpolator)123     float EstimateFraction(const std::shared_ptr<RSInterpolator>& interpolator) override
124     {
125         return 0.0f;
126     }
127 
EstimateFraction(const std::shared_ptr<RSInterpolator> & interpolator,float targetFraction,int duration)128     float EstimateFraction(const std::shared_ptr<RSInterpolator>& interpolator,
129         float targetFraction, int duration) override
130     {
131         if (interpolator == nullptr || duration <= 0) {
132             return FRACTION_MIN;
133         }
134         int secondTime = std::ceil(static_cast<float>(duration) / SECOND_TO_MS);
135         if (secondTime <= 0) {
136             return FRACTION_MIN;
137         }
138         auto frameTimes = MAX_FRAME_TIME_FRACTION * secondTime;
139         float lastFraction = FRACTION_MIN;
140         for (int time = 1; time <= frameTimes; time++) {
141             float frameFraction = static_cast<float>(time) / frameTimes;
142             frameFraction = std::clamp(frameFraction, 0.0f, 1.0f);
143             float fraction = interpolator->Interpolate(frameFraction);
144             if (lastFraction <= targetFraction && fraction >= targetFraction) {
145                 return frameFraction;
146             }
147             lastFraction = fraction;
148         }
149         return FRACTION_MIN;
150     }
151 private:
152     T startValue_ {};
153     T endValue_ {};
154     T lastValue_ {};
155     std::shared_ptr<RSRenderAnimatableProperty<T>> property_;
156 };
157 
158 template<>
159 float RSCurveValueEstimator<float>::EstimateFraction(const std::shared_ptr<RSInterpolator>& interpolator);
160 
161 extern template class RSCurveValueEstimator<float>;
162 
163 template<typename T>
164 class RSKeyframeValueEstimator : public RSValueEstimator {
165 public:
166     RSKeyframeValueEstimator() = default;
167     virtual ~RSKeyframeValueEstimator() = default;
168 
InitKeyframeAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & property,std::vector<std::tuple<float,std::shared_ptr<RSRenderPropertyBase>,std::shared_ptr<RSInterpolator>>> & keyframes,const std::shared_ptr<RSRenderPropertyBase> & lastValue)169     void InitKeyframeAnimationValue(const std::shared_ptr<RSRenderPropertyBase>& property,
170         std::vector<std::tuple<float, std::shared_ptr<RSRenderPropertyBase>,
171         std::shared_ptr<RSInterpolator>>>& keyframes,
172         const std::shared_ptr<RSRenderPropertyBase>& lastValue) override
173     {
174         auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(property);
175         auto animatableLastValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(lastValue);
176         if (animatableProperty && animatableLastValue) {
177             property_ = animatableProperty;
178             lastValue_ = animatableLastValue->Get();
179         }
180         for (const auto& keyframe : keyframes) {
181             auto keyframeValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(std::get<1>(keyframe));
182             if (keyframeValue != nullptr) {
183                 keyframes_.push_back({ std::get<0>(keyframe), keyframeValue->Get(), std::get<2>(keyframe) });
184             }
185         }
186     }
187 
InitDurationKeyframeAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & property,std::vector<std::tuple<float,float,std::shared_ptr<RSRenderPropertyBase>,std::shared_ptr<RSInterpolator>>> & keyframes,const std::shared_ptr<RSRenderPropertyBase> & lastValue)188     void InitDurationKeyframeAnimationValue(const std::shared_ptr<RSRenderPropertyBase>& property,
189         std::vector<std::tuple<float, float, std::shared_ptr<RSRenderPropertyBase>,
190         std::shared_ptr<RSInterpolator>>>& keyframes,
191         const std::shared_ptr<RSRenderPropertyBase>& lastValue) override
192     {
193         auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(property);
194         auto animatableLastValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(lastValue);
195         if (animatableProperty && animatableLastValue) {
196             property_ = animatableProperty;
197             lastValue_ = animatableLastValue->Get();
198         }
199         for (const auto& keyframe : keyframes) {
200             auto keyframeValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(std::get<2>(keyframe));
201             if (keyframeValue != nullptr) {
202                 durationKeyframes_.push_back(
203                     { std::get<0>(keyframe), std::get<1>(keyframe), keyframeValue->Get(), std::get<3>(keyframe) });
204             }
205         }
206     }
207 
UpdateAnimationValue(const float fraction,const bool isAdditive)208     void UpdateAnimationValue(const float fraction, const bool isAdditive) override
209     {
210         auto animationValue = GetAnimationValue(fraction, isAdditive);
211         if (property_ != nullptr) {
212             property_->Set(animationValue);
213         }
214     }
215 
GetAnimationValue(const float fraction,const bool isAdditive)216     T GetAnimationValue(const float fraction, const bool isAdditive)
217     {
218         if (!(durationKeyframes_.empty())) {
219             return GetDurationKeyframeAnimationValue(fraction, isAdditive);
220         }
221         float preKeyframeFraction = std::get<0>(keyframes_.front());
222         auto preKeyframeValue = std::get<1>(keyframes_.front());
223         for (const auto& keyframe : keyframes_) {
224             // the index of tuple
225             float keyframeFraction = std::get<0>(keyframe);
226             auto keyframeValue = std::get<1>(keyframe);
227             auto keyframeInterpolator = std::get<2>(keyframe);
228             if (fraction <= keyframeFraction) {
229                 if (ROSEN_EQ(keyframeFraction, preKeyframeFraction)) {
230                     continue;
231                 }
232 
233                 float intervalFraction = (fraction - preKeyframeFraction) / (keyframeFraction - preKeyframeFraction);
234                 auto interpolationValue = RSValueEstimator::Estimate(
235                     keyframeInterpolator->Interpolate(intervalFraction), preKeyframeValue, keyframeValue);
236                 auto animationValue = interpolationValue;
237                 if (isAdditive && property_ != nullptr) {
238                     animationValue = property_->Get() + (interpolationValue - lastValue_);
239                 }
240                 lastValue_ = interpolationValue;
241                 return animationValue;
242             }
243 
244             preKeyframeFraction = keyframeFraction;
245             preKeyframeValue = keyframeValue;
246         }
247         return preKeyframeValue;
248     }
249 
GetDurationKeyframeAnimationValue(const float fraction,const bool isAdditive)250     T GetDurationKeyframeAnimationValue(const float fraction, const bool isAdditive)
251     {
252         auto preKeyframeValue = std::get<2>(durationKeyframes_.front());
253         auto animationValue = preKeyframeValue;
254         bool bInFraction = false;
255         for (const auto& keyframe : durationKeyframes_) {
256             float startFraction = std::get<0>(keyframe);
257             float endFraction = std::get<1>(keyframe);
258             auto keyframeValue = std::get<2>(keyframe);
259             auto keyframeInterpolator = std::get<3>(keyframe);
260             if (fraction < startFraction) {
261                 break;
262             }
263             if ((fraction > startFraction) && (fraction <= endFraction)) {
264                 bInFraction = true;
265                 float intervalFraction = (fraction - startFraction) / (endFraction - startFraction);
266                 auto interpolationValue = RSValueEstimator::Estimate(
267                     keyframeInterpolator->Interpolate(intervalFraction), preKeyframeValue, keyframeValue);
268                 animationValue = interpolationValue;
269                 if (isAdditive && property_ != nullptr) {
270                     animationValue = property_->Get() + (interpolationValue - lastValue_);
271                 }
272                 lastValue_ = interpolationValue;
273                 preKeyframeValue = animationValue;
274                 continue;
275             }
276             if (ROSEN_EQ(fraction, startFraction) && ROSEN_EQ(startFraction, endFraction)) {
277                 bInFraction = true;
278                 animationValue = keyframeValue;
279                 preKeyframeValue = keyframeValue;
280                 lastValue_ = keyframeValue;
281                 continue;
282             }
283             preKeyframeValue = keyframeValue;
284         }
285         if (!bInFraction) {
286             animationValue = preKeyframeValue;
287             lastValue_ = preKeyframeValue;
288         }
289         return animationValue;
290     }
291 
292 private:
293     std::vector<std::tuple<float, T, std::shared_ptr<RSInterpolator>>> keyframes_;
294     std::vector<std::tuple<float, float, T, std::shared_ptr<RSInterpolator>>> durationKeyframes_;
295     T lastValue_ {};
296     std::shared_ptr<RSRenderAnimatableProperty<T>> property_;
297 };
298 
299 enum class RSValueEstimatorType : int16_t {
300     INVALID = 0,
301     CURVE_VALUE_ESTIMATOR,
302     KEYFRAME_VALUE_ESTIMATOR,
303     PATH_VALUE_ESTIMATOR,
304 };
305 
306 class RSB_EXPORT RSSpringValueEstimatorBase {
307 public:
308     RSSpringValueEstimatorBase() = default;
309     virtual ~RSSpringValueEstimatorBase() = default;
310 
SetResponse(const float response)311     virtual void SetResponse(const float response) {}
SetMinimumAmplitudeRatio(const float minimumAmplitudeRatio)312     virtual void SetMinimumAmplitudeRatio(const float minimumAmplitudeRatio) {}
SetDampingRatio(const float dampingRatio)313     virtual void SetDampingRatio(const float dampingRatio) {}
GetResponse()314     virtual float GetResponse() const
315     {
316         return 0.0f;
317     }
GetDampingRatio()318     virtual float GetDampingRatio() const
319     {
320         return 0.0f;
321     }
SetInitialVelocity(const std::shared_ptr<RSRenderPropertyBase> & initialVelocity)322     virtual void SetInitialVelocity(const std::shared_ptr<RSRenderPropertyBase>& initialVelocity) {}
InitRSSpringValueEstimator(const std::shared_ptr<RSRenderPropertyBase> & property,const std::shared_ptr<RSRenderPropertyBase> & startValue,const std::shared_ptr<RSRenderPropertyBase> & endValue,const std::shared_ptr<RSRenderPropertyBase> & lastValue)323     virtual void InitRSSpringValueEstimator(const std::shared_ptr<RSRenderPropertyBase>& property,
324         const std::shared_ptr<RSRenderPropertyBase>& startValue, const std::shared_ptr<RSRenderPropertyBase>& endValue,
325         const std::shared_ptr<RSRenderPropertyBase>& lastValue)
326     {}
UpdateStartValueAndLastValue(const std::shared_ptr<RSRenderPropertyBase> & startValue,const std::shared_ptr<RSRenderPropertyBase> & lastValue)327     virtual void UpdateStartValueAndLastValue(
328         const std::shared_ptr<RSRenderPropertyBase>& startValue, const std::shared_ptr<RSRenderPropertyBase>& lastValue)
329     {}
UpdateAnimationValue(const float time,const bool isAdditive)330     virtual void UpdateAnimationValue(const float time, const bool isAdditive) {}
GetAnimationProperty()331     virtual std::shared_ptr<RSRenderPropertyBase> GetAnimationProperty() const
332     {
333         return nullptr;
334     }
GetPropertyVelocity(float time)335     virtual std::shared_ptr<RSRenderPropertyBase> GetPropertyVelocity(float time) const
336     {
337         return nullptr;
338     }
UpdateDuration()339     virtual float UpdateDuration()
340     {
341         return 0.0f;
342     }
UpdateSpringParameters()343     virtual void UpdateSpringParameters() {}
344 };
345 
346 template<typename T>
347 class RSSpringValueEstimator : public RSSpringValueEstimatorBase {
348 public:
RSSpringValueEstimator()349     RSSpringValueEstimator() : RSSpringValueEstimatorBase()
350     {
351         InitSpringModel();
352     }
353 
354     ~RSSpringValueEstimator() override = default;
355 
InitSpringModel()356     void InitSpringModel()
357     {
358         if (!springModel_) {
359             springModel_ = std::make_shared<RSSpringModel<T>>();
360         }
361     }
362 
SetResponse(const float response)363     void SetResponse(const float response) override
364     {
365         if (springModel_) {
366             springModel_->response_ = response;
367         }
368     }
369 
SetMinimumAmplitudeRatio(const float minimumAmplitudeRatio)370     void SetMinimumAmplitudeRatio(const float minimumAmplitudeRatio) override
371     {
372         if (springModel_) {
373             springModel_->minimumAmplitudeRatio_ = minimumAmplitudeRatio;
374         }
375     }
376 
SetDampingRatio(const float dampingRatio)377     void SetDampingRatio(const float dampingRatio) override
378     {
379         if (springModel_) {
380             springModel_->dampingRatio_ = std::clamp(dampingRatio, SPRING_MIN_DAMPING_RATIO, SPRING_MAX_DAMPING_RATIO);
381         }
382     }
383 
GetResponse()384     float GetResponse() const override
385     {
386         if (springModel_) {
387             return springModel_->response_;
388         }
389         return 0.0f;
390     }
391 
GetDampingRatio()392     float GetDampingRatio() const override
393     {
394         if (springModel_) {
395             return springModel_->dampingRatio_;
396         }
397         return 0.0f;
398     }
399 
SetInitialVelocity(const std::shared_ptr<RSRenderPropertyBase> & initialVelocity)400     void SetInitialVelocity(const std::shared_ptr<RSRenderPropertyBase>& initialVelocity) override
401     {
402         auto animatableInitialVelocity = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(initialVelocity);
403         if (animatableInitialVelocity != nullptr && springModel_ != nullptr) {
404             springModel_->initialVelocity_ = animatableInitialVelocity->Get();
405         }
406     }
407 
InitRSSpringValueEstimator(const std::shared_ptr<RSRenderPropertyBase> & property,const std::shared_ptr<RSRenderPropertyBase> & startValue,const std::shared_ptr<RSRenderPropertyBase> & endValue,const std::shared_ptr<RSRenderPropertyBase> & lastValue)408     void InitRSSpringValueEstimator(const std::shared_ptr<RSRenderPropertyBase>& property,
409         const std::shared_ptr<RSRenderPropertyBase>& startValue, const std::shared_ptr<RSRenderPropertyBase>& endValue,
410         const std::shared_ptr<RSRenderPropertyBase>& lastValue) override
411     {
412         auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(property);
413         auto animatableStartValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(startValue);
414         auto animatableEndValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(endValue);
415         auto animatableLastValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(lastValue);
416         if (animatableProperty && animatableStartValue && animatableEndValue && animatableLastValue) {
417             property_ = animatableProperty;
418             startValue_ = animatableStartValue->Get();
419             endValue_ = animatableEndValue->Get();
420             lastValue_ = animatableLastValue->Get();
421             if (springModel_) {
422                 springModel_->initialOffset_ = startValue_ - endValue_;
423             }
424         }
425     }
426 
UpdateStartValueAndLastValue(const std::shared_ptr<RSRenderPropertyBase> & startValue,const std::shared_ptr<RSRenderPropertyBase> & lastValue)427     void UpdateStartValueAndLastValue(const std::shared_ptr<RSRenderPropertyBase>& startValue,
428         const std::shared_ptr<RSRenderPropertyBase>& lastValue) override
429     {
430         auto animatableStartValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(startValue);
431         auto animatableLastValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(lastValue);
432         if (animatableStartValue && animatableLastValue) {
433             startValue_ = animatableStartValue->Get();
434             lastValue_ = animatableLastValue->Get();
435             if (springModel_) {
436                 springModel_->initialOffset_ = startValue_ - endValue_;
437             }
438         }
439     }
440 
UpdateAnimationValue(const float time,const bool isAdditive)441     void UpdateAnimationValue(const float time, const bool isAdditive) override
442     {
443         auto animationValue = GetAnimationValue(time, isAdditive);
444         if (property_ != nullptr) {
445             property_->Set(animationValue);
446         }
447     }
448 
GetAnimationValue(const float time,const bool isAdditive)449     T GetAnimationValue(const float time, const bool isAdditive)
450     {
451         T currentValue = startValue_;
452         constexpr static float TIME_THRESHOLD = 1e-3f;
453         if (ROSEN_EQ(time, duration_, TIME_THRESHOLD)) {
454             currentValue = endValue_;
455         } else if (springModel_) {
456             currentValue = springModel_->CalculateDisplacement(time) + endValue_;
457         }
458 
459         auto animationValue = currentValue;
460         if (isAdditive && property_) {
461             animationValue = property_->Get() + currentValue - lastValue_;
462         }
463         lastValue_ = currentValue;
464         return animationValue;
465     }
466 
GetAnimationProperty()467     std::shared_ptr<RSRenderPropertyBase> GetAnimationProperty() const override
468     {
469         return std::make_shared<RSRenderAnimatableProperty<T>>(lastValue_);
470     }
471 
GetPropertyVelocity(float time)472     std::shared_ptr<RSRenderPropertyBase> GetPropertyVelocity(float time) const override
473     {
474         if (!springModel_) {
475             return nullptr;
476         }
477         constexpr float TIME_INTERVAL = 1e-6f; // 1 microsecond
478         T velocity = (springModel_->CalculateDisplacement(time + TIME_INTERVAL) -
479             springModel_->CalculateDisplacement(time)) * (1 / TIME_INTERVAL);
480         return std::make_shared<RSRenderAnimatableProperty<T>>(velocity);
481     }
482 
UpdateDuration()483     float UpdateDuration() override
484     {
485         if (springModel_) {
486             duration_ = springModel_->EstimateDuration();
487         }
488         return duration_;
489     }
490 
UpdateSpringParameters()491     void UpdateSpringParameters() override
492     {
493         if (springModel_) {
494             springModel_->CalculateSpringParameters();
495         }
496     }
497 
498 private:
499     T startValue_ {};
500     T endValue_ {};
501     T lastValue_ {};
502     float duration_ = 0.3f;
503     std::shared_ptr<RSSpringModel<T>> springModel_;
504     std::shared_ptr<RSRenderAnimatableProperty<T>> property_;
505 };
506 } // namespace Rosen
507 } // namespace OHOS
508 
509 #endif // RENDER_SERVICE_CLIENT_CORE_ANIMATION_RS_VALUE_ESTIMATOR_H
510