1 /*
2 * Copyright (c) 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_particle_animation.h"
17
18 #include <memory>
19
20 #include "rs_profiler.h"
21
22 #include "animation/rs_value_estimator.h"
23 #include "command/rs_animation_command.h"
24 #include "common/rs_optional_trace.h"
25 #include "platform/common/rs_log.h"
26 #include "transaction/rs_marshalling_helper.h"
27
28 namespace OHOS {
29 namespace Rosen {
RSRenderParticleAnimation(AnimationId id,const PropertyId & propertyId,const std::vector<std::shared_ptr<ParticleRenderParams>> & particlesRenderParams)30 RSRenderParticleAnimation::RSRenderParticleAnimation(AnimationId id, const PropertyId& propertyId,
31 const std::vector<std::shared_ptr<ParticleRenderParams>>& particlesRenderParams)
32 : RSRenderPropertyAnimation(id, propertyId), particlesRenderParams_(particlesRenderParams),
33 particleSystem_(std::make_shared<RSRenderParticleSystem>(particlesRenderParams_))
34 {}
35
DumpAnimationType(std::string & out) const36 void RSRenderParticleAnimation::DumpAnimationType(std::string& out) const
37 {
38 out += "Type:RSRenderParticleAnimation";
39 }
40
Animate(int64_t time)41 bool RSRenderParticleAnimation::Animate(int64_t time)
42 {
43 RS_OPTIONAL_TRACE_NAME("RSRenderParticleAnimation::Animate");
44 auto target = GetTarget();
45 if (!target) {
46 return true;
47 } else if (!target->GetRenderProperties().GetVisible()) {
48 target->RemoveModifier(property_->GetId());
49 return true;
50 }
51
52 int64_t deltaTime = time - animationFraction_.GetLastFrameTime();
53 animationFraction_.SetLastFrameTime(time);
54 if (particleSystem_ != nullptr) {
55 particleSystem_->Emit(
56 deltaTime, renderParticleVector_.renderParticleVector_, renderParticleVector_.imageVector_);
57 particleSystem_->UpdateParticle(deltaTime, renderParticleVector_.renderParticleVector_);
58 }
59 auto property = std::static_pointer_cast<RSRenderProperty<RSRenderParticleVector>>(property_);
60 if (property) {
61 property->Set(renderParticleVector_);
62 }
63
64 if (particleSystem_ == nullptr || particleSystem_->IsFinish(renderParticleVector_.renderParticleVector_)) {
65 if (target) {
66 target->RemoveModifier(property_->GetId());
67 }
68 return true;
69 }
70 return false;
71 }
72
UpdateEmitter(const std::vector<std::shared_ptr<EmitterUpdater>> & emitterUpdaters)73 void RSRenderParticleAnimation::UpdateEmitter(const std::vector<std::shared_ptr<EmitterUpdater>>& emitterUpdaters)
74 {
75 if (emitterUpdaters.empty()) {
76 return;
77 }
78 for (auto emitterUpdater : emitterUpdaters) {
79 if (emitterUpdater) {
80 uint32_t index = emitterUpdater->emitterIndex_;
81 if (index >= particlesRenderParams_.size()) {
82 continue;
83 }
84 if (particlesRenderParams_[index] == nullptr) {
85 continue;
86 }
87 if (emitterUpdater->position_.has_value() &&
88 emitterUpdater->position_.value() != particlesRenderParams_[index]->emitterConfig_.position_) {
89 particlesRenderParams_[index]->emitterConfig_.position_ = emitterUpdater->position_.value();
90 }
91 if (emitterUpdater->emitSize_.has_value() &&
92 emitterUpdater->emitSize_.value() != particlesRenderParams_[index]->emitterConfig_.emitSize_) {
93 particlesRenderParams_[index]->emitterConfig_.emitSize_ = emitterUpdater->emitSize_.value();
94 }
95 if (emitterUpdater->emitRate_.has_value() &&
96 emitterUpdater->emitRate_.value() != particlesRenderParams_[index]->emitterConfig_.emitRate_) {
97 particlesRenderParams_[index]->emitterConfig_.emitRate_ = emitterUpdater->emitRate_.value();
98 }
99 }
100 }
101 if (particleSystem_) {
102 particleSystem_->UpdateEmitter(particlesRenderParams_);
103 } else {
104 particleSystem_ = std::make_shared<RSRenderParticleSystem>(particlesRenderParams_);
105 }
106 }
107
UpdateNoiseField(const std::shared_ptr<ParticleNoiseFields> & particleNoiseFields)108 void RSRenderParticleAnimation::UpdateNoiseField(const std::shared_ptr<ParticleNoiseFields>& particleNoiseFields)
109 {
110 if (particleNoiseFields == nullptr) {
111 return;
112 } else if (particleNoiseFields_ != nullptr && *particleNoiseFields_ == *particleNoiseFields) {
113 return;
114 }
115 particleNoiseFields_ = particleNoiseFields;
116 if (particleSystem_) {
117 particleSystem_->UpdateNoiseField(particleNoiseFields);
118 }
119 }
120
OnAttach()121 void RSRenderParticleAnimation::OnAttach()
122 {
123 auto target = GetTarget();
124 if (target == nullptr) {
125 ROSEN_LOGE("RSRenderParticleAnimation::OnAttach, target is nullptr");
126 return;
127 }
128 auto particleAnimations = target->GetAnimationManager().GetParticleAnimations();
129 if (!particleAnimations.empty()) {
130 for (const auto& pair : particleAnimations) {
131 target->RemoveModifier(pair.first);
132 target->GetAnimationManager().RemoveAnimation(pair.second);
133 target->GetAnimationManager().UnregisterParticleAnimation(pair.first, pair.second);
134 }
135 }
136 target->GetAnimationManager().RegisterParticleAnimation(GetPropertyId(), GetAnimationId());
137 }
138
OnDetach()139 void RSRenderParticleAnimation::OnDetach()
140 {
141 auto target = GetTarget();
142 if (target == nullptr) {
143 ROSEN_LOGE("RSRenderParticleAnimation::OnDetach, target is nullptr");
144 return;
145 }
146 if (particleSystem_ != nullptr) {
147 particleSystem_->ClearEmitter();
148 particleSystem_.reset();
149 }
150 auto propertyId = GetPropertyId();
151 auto id = GetAnimationId();
152 target->GetAnimationManager().UnregisterParticleAnimation(propertyId, id);
153 }
154
Marshalling(Parcel & parcel) const155 bool RSRenderParticleAnimation::Marshalling(Parcel& parcel) const
156 {
157 auto id = GetAnimationId();
158 if (!(parcel.WriteUint64(id))) {
159 ROSEN_LOGE("RSRenderParticleAnimation::Marshalling, write id failed");
160 return false;
161 }
162 if (!parcel.WriteUint64(propertyId_)) {
163 ROSEN_LOGE("RSRenderParticleAnimation::Marshalling, write PropertyId failed");
164 return false;
165 }
166 if (!RSMarshallingHelper::Marshalling(parcel, particlesRenderParams_)) {
167 ROSEN_LOGE("RSRenderParticleAnimation::Marshalling, write particlesRenderParams failed");
168 return false;
169 }
170 return true;
171 }
172
Unmarshalling(Parcel & parcel)173 RSRenderParticleAnimation* RSRenderParticleAnimation::Unmarshalling(Parcel& parcel)
174 {
175 RSRenderParticleAnimation* renderParticleAnimation = new RSRenderParticleAnimation();
176 if (!renderParticleAnimation->ParseParam(parcel)) {
177 ROSEN_LOGE("RSRenderParticleAnimation::Unmarshalling, failed");
178 delete renderParticleAnimation;
179 return nullptr;
180 }
181 return renderParticleAnimation;
182 }
183
ParseParam(Parcel & parcel)184 bool RSRenderParticleAnimation::ParseParam(Parcel& parcel)
185 {
186 AnimationId id = 0;
187 if (!parcel.ReadUint64(id)) {
188 ROSEN_LOGE("RSRenderParticleAnimation::ParseParam, Unmarshalling animationId failed");
189 return false;
190 }
191 RS_PROFILER_PATCH_NODE_ID(parcel, id);
192 SetAnimationId(id);
193 if (!(parcel.ReadUint64(propertyId_) && RSMarshallingHelper::Unmarshalling(parcel, particlesRenderParams_))) {
194 ROSEN_LOGE("RSRenderParticleAnimation::ParseParam, Unmarshalling failed");
195 return false;
196 }
197 RS_PROFILER_PATCH_NODE_ID(parcel, propertyId_);
198 particleSystem_ = std::make_shared<RSRenderParticleSystem>(particlesRenderParams_);
199 return true;
200 }
201
202 } // namespace Rosen
203 } // namespace OHOS
204