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 #include "animation/rs_render_path_animation.h"
17
18 #include "animation/rs_value_estimator.h"
19 #include "pipeline/rs_canvas_render_node.h"
20 #include "platform/common/rs_log.h"
21 #include "render/rs_path.h"
22
23 namespace OHOS {
24 namespace Rosen {
RSRenderPathAnimation(AnimationId id,const PropertyId & propertyId,const std::shared_ptr<RSRenderPropertyBase> & originPosition,const std::shared_ptr<RSRenderPropertyBase> & startPosition,const std::shared_ptr<RSRenderPropertyBase> & endPosition,float originRotation,const std::shared_ptr<RSPath> & animationPath)25 RSRenderPathAnimation::RSRenderPathAnimation(AnimationId id, const PropertyId& propertyId,
26 const std::shared_ptr<RSRenderPropertyBase>& originPosition,
27 const std::shared_ptr<RSRenderPropertyBase>& startPosition,
28 const std::shared_ptr<RSRenderPropertyBase>& endPosition, float originRotation,
29 const std::shared_ptr<RSPath>& animationPath) : RSRenderPropertyAnimation(id, propertyId, originPosition),
30 originRotation_(originRotation), startValue_(startPosition), endValue_(endPosition),
31 animationPath_(animationPath)
32 {}
33
SetInterpolator(const std::shared_ptr<RSInterpolator> & interpolator)34 void RSRenderPathAnimation::SetInterpolator(const std::shared_ptr<RSInterpolator>& interpolator)
35 {
36 interpolator_ = interpolator;
37 }
38
GetInterpolator() const39 const std::shared_ptr<RSInterpolator>& RSRenderPathAnimation::GetInterpolator() const
40 {
41 return interpolator_;
42 }
43
SetRotationMode(const RotationMode & rotationMode)44 void RSRenderPathAnimation::SetRotationMode(const RotationMode& rotationMode)
45 {
46 if (IsStarted()) {
47 ROSEN_LOGE("Failed to enable rotate, path animation has started!");
48 return;
49 }
50
51 rotationMode_ = rotationMode;
52 }
53
GetRotationMode() const54 RotationMode RSRenderPathAnimation::GetRotationMode() const
55 {
56 return rotationMode_;
57 }
58
SetBeginFraction(float fraction)59 void RSRenderPathAnimation::SetBeginFraction(float fraction)
60 {
61 if (IsStarted()) {
62 ROSEN_LOGE("Failed to set begin fraction, path animation has started!");
63 return;
64 }
65
66 if (fraction < FRACTION_MIN || fraction > FRACTION_MAX || fraction > endFraction_) {
67 ROSEN_LOGE("Failed to set begin fraction, invalid value:%f", fraction);
68 return;
69 }
70
71 beginFraction_ = fraction;
72 }
73
GetBeginFraction() const74 float RSRenderPathAnimation::GetBeginFraction() const
75 {
76 return beginFraction_;
77 }
78
SetEndFraction(float fraction)79 void RSRenderPathAnimation::SetEndFraction(float fraction)
80 {
81 if (IsStarted()) {
82 ROSEN_LOGE("Failed to set end fraction, path animation has started!");
83 return;
84 }
85
86 if (fraction < FRACTION_MIN || fraction > FRACTION_MAX || fraction < beginFraction_) {
87 ROSEN_LOGE("Failed to set end fraction, invalid value:%f", fraction);
88 return;
89 }
90
91 endFraction_ = fraction;
92 }
93
GetEndFraction() const94 float RSRenderPathAnimation::GetEndFraction() const
95 {
96 return endFraction_;
97 }
98
SetIsNeedPath(const bool isNeedPath)99 void RSRenderPathAnimation::SetIsNeedPath(const bool isNeedPath)
100 {
101 isNeedPath_ = isNeedPath;
102 }
103
SetPathNeedAddOrigin(bool needAddOrigin)104 void RSRenderPathAnimation::SetPathNeedAddOrigin(bool needAddOrigin)
105 {
106 if (IsStarted()) {
107 ROSEN_LOGE("Failed to set need Add Origin, path animation has started!");
108 return;
109 }
110
111 needAddOrigin_ = needAddOrigin;
112 }
113
SetRotationId(const PropertyId id)114 void RSRenderPathAnimation::SetRotationId(const PropertyId id)
115 {
116 rotationId_ = id;
117 }
118
Marshalling(Parcel & parcel) const119 bool RSRenderPathAnimation::Marshalling(Parcel& parcel) const
120 {
121 if (!RSRenderPropertyAnimation::Marshalling(parcel)) {
122 ROSEN_LOGE("RSRenderPathAnimation::Marshalling, RenderPropertyAnimation failed");
123 return false;
124 }
125 if (!(parcel.WriteFloat(originRotation_) && parcel.WriteFloat(beginFraction_) && parcel.WriteFloat(endFraction_) &&
126 RSMarshallingHelper::Marshalling(parcel, animationPath_) &&
127 parcel.WriteInt32(static_cast<std::underlying_type<RotationMode>::type>(rotationMode_)) &&
128 parcel.WriteBool(isNeedPath_) && parcel.WriteBool(needAddOrigin_) && interpolator_ != nullptr &&
129 interpolator_->Marshalling(parcel) && RSRenderPropertyBase::Marshalling(parcel, startValue_) &&
130 RSRenderPropertyBase::Marshalling(parcel, endValue_) && parcel.WriteUint64(rotationId_))) {
131 ROSEN_LOGE("RSRenderPathAnimation::Marshalling, write failed");
132 return false;
133 }
134 return true;
135 }
136
Unmarshalling(Parcel & parcel)137 RSRenderPathAnimation* RSRenderPathAnimation::Unmarshalling(Parcel& parcel)
138 {
139 RSRenderPathAnimation* renderPathAnimation = new RSRenderPathAnimation();
140
141 if (!renderPathAnimation->ParseParam(parcel)) {
142 ROSEN_LOGE("RSRenderPathAnimation::Unmarshalling, Parse RenderProperty Fail");
143 delete renderPathAnimation;
144 return nullptr;
145 }
146 return renderPathAnimation;
147 }
148
ParseParam(Parcel & parcel)149 bool RSRenderPathAnimation::ParseParam(Parcel& parcel)
150 {
151 if (!RSRenderPropertyAnimation::ParseParam(parcel)) {
152 ROSEN_LOGE("RSRenderPathAnimation::ParseParam, Parse RenderProperty Fail");
153 return false;
154 }
155
156 int32_t rotationMode;
157 bool isNeedPath = true;
158 if (!(parcel.ReadFloat(originRotation_) && parcel.ReadFloat(beginFraction_) &&
159 parcel.ReadFloat(endFraction_) && RSMarshallingHelper::Unmarshalling(parcel, animationPath_) &&
160 parcel.ReadInt32(rotationMode) && parcel.ReadBool(isNeedPath) && parcel.ReadBool(needAddOrigin_))) {
161 ROSEN_LOGE("RSRenderPathAnimation::ParseParam, Parse PathAnimation Failed");
162 return false;
163 }
164
165 std::shared_ptr<RSInterpolator> interpolator(RSInterpolator::Unmarshalling(parcel));
166 if (interpolator == nullptr) {
167 ROSEN_LOGE("RSRenderPathAnimation::ParseParam, Unmarshalling interpolator failed");
168 return false;
169 }
170
171 if (!(RSRenderPropertyBase::Unmarshalling(parcel, startValue_) &&
172 RSRenderPropertyBase::Unmarshalling(parcel, endValue_) && parcel.ReadUint64(rotationId_))) {
173 ROSEN_LOGE("RSRenderPathAnimation::ParseParam, Parse values failed");
174 return false;
175 }
176 SetInterpolator(interpolator);
177 SetRotationMode(static_cast<RotationMode>(rotationMode));
178 SetIsNeedPath(isNeedPath);
179 return true;
180 }
181
OnAnimate(float fraction)182 void RSRenderPathAnimation::OnAnimate(float fraction)
183 {
184 if (animationPath_ == nullptr) {
185 ROSEN_LOGE("Failed to animate motion path, path is null!");
186 return;
187 }
188
189 Vector2f position;
190 float tangent = 0;
191 GetPosTanValue(fraction, position, tangent);
192 auto valueVector2f = std::static_pointer_cast<RSRenderAnimatableProperty<Vector2f>>(GetOriginValue());
193 if (GetOriginValue()->GetPropertyType() == RSRenderPropertyType::PROPERTY_VECTOR2F) {
194 UpdateVector2fPathValue(position);
195 SetPathValue(position, tangent);
196 return;
197 }
198
199 if (!isNeedPath_) {
200 if (valueEstimator_ == nullptr) {
201 return;
202 }
203 valueEstimator_->UpdateAnimationValue(interpolator_->Interpolate(fraction), GetAdditive());
204 return;
205 }
206
207 auto vector4fValueEstimator = std::static_pointer_cast<RSCurveValueEstimator<Vector4f>>(valueEstimator_);
208 if (vector4fValueEstimator != nullptr) {
209 auto animationValue =
210 vector4fValueEstimator->GetAnimationValue(interpolator_->Interpolate(fraction), GetAdditive());
211 UpdateVector4fPathValue(animationValue, position);
212 SetPathValue(animationValue, tangent);
213 }
214 }
215
OnRemoveOnCompletion()216 void RSRenderPathAnimation::OnRemoveOnCompletion()
217 {
218 auto target = GetTarget();
219 if (target == nullptr) {
220 ROSEN_LOGE("Failed to remove on completion, target is null!");
221 return;
222 }
223
224 target->GetMutableRenderProperties().SetRotation(originRotation_);
225 RSRenderPropertyAnimation::OnRemoveOnCompletion();
226 }
227
SetPathValue(const Vector2f & value,float tangent)228 void RSRenderPathAnimation::SetPathValue(const Vector2f& value, float tangent)
229 {
230 SetRotationValue(tangent);
231 auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector2f>>(property_);
232 if (animatableProperty != nullptr) {
233 animatableProperty->Set(value);
234 }
235 }
236
SetPathValue(const Vector4f & value,float tangent)237 void RSRenderPathAnimation::SetPathValue(const Vector4f& value, float tangent)
238 {
239 SetRotationValue(tangent);
240 auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(property_);
241 if (animatableProperty != nullptr) {
242 animatableProperty->Set(value);
243 }
244 }
245
SetRotationValue(const float tangent)246 void RSRenderPathAnimation::SetRotationValue(const float tangent)
247 {
248 switch (GetRotationMode()) {
249 case RotationMode::ROTATE_AUTO:
250 SetRotation(tangent);
251 break;
252 case RotationMode::ROTATE_AUTO_REVERSE:
253 SetRotation(tangent + 180.0f);
254 break;
255 case RotationMode::ROTATE_NONE:
256 break;
257 default:
258 ROSEN_LOGE("Unknow rotate mode!");
259 break;
260 }
261 }
262
SetRotation(const float tangent)263 void RSRenderPathAnimation::SetRotation(const float tangent)
264 {
265 auto target = GetTarget();
266 if (target == nullptr) {
267 ROSEN_LOGE("Failed to set rotation value, target is null!");
268 return;
269 }
270
271 auto modifier = target->GetModifier(rotationId_);
272 if (modifier != nullptr) {
273 auto property = std::static_pointer_cast<RSRenderProperty<float>>(modifier->GetProperty());
274 if (property != nullptr) {
275 property->Set(tangent);
276 }
277 }
278 }
279
GetPosTanValue(float fraction,Vector2f & position,float & tangent)280 void RSRenderPathAnimation::GetPosTanValue(float fraction, Vector2f& position, float& tangent)
281 {
282 float distance = animationPath_->GetDistance();
283 float progress = GetBeginFraction() * (FRACTION_MAX - fraction) + GetEndFraction() * fraction;
284 animationPath_->GetPosTan(distance * progress, position, tangent);
285 }
286
UpdateVector2fPathValue(Vector2f & value)287 void RSRenderPathAnimation::UpdateVector2fPathValue(Vector2f& value)
288 {
289 if (needAddOrigin_) {
290 auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector2f>>(GetOriginValue());
291 if (animatableProperty) {
292 value += animatableProperty->Get();
293 }
294 }
295 }
296
UpdateVector4fPathValue(Vector4f & value,const Vector2f & position)297 void RSRenderPathAnimation::UpdateVector4fPathValue(Vector4f& value, const Vector2f& position)
298 {
299 value[0] = position[0];
300 value[1] = position[1];
301 if (needAddOrigin_) {
302 auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(GetOriginValue());
303 if (animatableProperty) {
304 value[0] += animatableProperty->Get()[0];
305 value[1] += animatableProperty->Get()[1];
306 }
307 }
308 }
309
InitValueEstimator()310 void RSRenderPathAnimation::InitValueEstimator()
311 {
312 if (valueEstimator_ == nullptr) {
313 valueEstimator_ = property_->CreateRSValueEstimator(RSValueEstimatorType::CURVE_VALUE_ESTIMATOR);
314 }
315 valueEstimator_->InitCurveAnimationValue(property_, startValue_, endValue_, lastValue_);
316 }
317 } // namespace Rosen
318 } // namespace OHOS
319