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