• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 ROSEN_ENGINE_CORE_ANIMATION_RS_NOISE_FIELD_H
17 #define ROSEN_ENGINE_CORE_ANIMATION_RS_NOISE_FIELD_H
18 #include <algorithm>
19 #include <cmath>
20 #include <random>
21 
22 #include "rs_render_particle.h"
23 
24 namespace OHOS {
25 namespace Rosen {
26 class RSB_EXPORT ParticleNoiseField {
27 public:
28     int fieldStrength_ { 0 };
29     ShapeType fieldShape_;
30     Vector2f fieldSize_;
31     Vector2f fieldCenter_;
32     uint16_t fieldFeather_ { 0 };
33     float noiseScale_ { 0.0 };
34     float noiseFrequency_ { 0.0 };
35     float noiseAmplitude_ { 0.0 };
36 
ParticleNoiseField(const int fieldStrength,const ShapeType & fieldShape,const Vector2f & fieldSize,const Vector2f & fieldCenter,uint16_t fieldFeather,float noiseScale,float noiseFrequency,float noiseAmplitude)37     explicit ParticleNoiseField(const int fieldStrength, const ShapeType& fieldShape, const Vector2f& fieldSize,
38         const Vector2f& fieldCenter, uint16_t fieldFeather, float noiseScale, float noiseFrequency,
39         float noiseAmplitude)
40         : fieldStrength_(fieldStrength), fieldShape_(fieldShape), fieldSize_(fieldSize), fieldCenter_(fieldCenter),
41           fieldFeather_(fieldFeather), noiseScale_(noiseScale), noiseFrequency_(noiseFrequency),
42           noiseAmplitude_(noiseAmplitude)
43     {}
44     ParticleNoiseField(const ParticleNoiseField& config) = default;
45     ParticleNoiseField& operator=(const ParticleNoiseField& config) = default;
46     ~ParticleNoiseField() = default;
47     float CalculateFeatherEffect(float distanceToEdge, float featherWidth);
48     Vector2f ApplyField(const Vector2f& position, float deltaTime);
49     Vector2f ApplyCurlNoise(const Vector2f& position);
50 
51     bool operator==(const ParticleNoiseField& rhs) const
52     {
53         bool equal = (this->fieldStrength_ == rhs.fieldStrength_) && (this->fieldShape_ == rhs.fieldShape_) &&
54                      (this->fieldSize_ == rhs.fieldSize_) && (this->fieldCenter_ == rhs.fieldCenter_) &&
55                      (this->fieldFeather_ == rhs.fieldFeather_) && (this->noiseScale_ == rhs.noiseScale_) &&
56                      (this->noiseFrequency_ == rhs.noiseFrequency_) && (this->noiseAmplitude_ == rhs.noiseAmplitude_);
57         return equal;
58     }
59 
60 private:
61     bool IsPointInField(
62         const Vector2f& point, const ShapeType& fieldShape, const Vector2f& fieldCenter, float width, float height);
63     float CalculateDistanceToRectangleEdge(
64         const Vector2f& position, const Vector2f& direction, const Vector2f& center, const Vector2f& size);
65     float CalculateDistanceToEllipseEdge(
66         const Vector2f& direction, const Vector2f& center, const Vector2f& axes);
67 };
68 
69 class RSB_EXPORT PerlinNoise2D {
70 private:
71     std::vector<int> p; // Permutation vector
72     float Fade(float t);
73     float Lerp(float t, float a, float b);
74     float Grad(int hash, float x, float y);
75     float noiseScale_ { 0.0 };
76     float noiseFrequency_ { 0.0 };
77     float noiseAmplitude_ { 0.0 };
78 
79 public:
80     PerlinNoise2D(float noiseScale, float noiseFrequency, float noiseAmplitude);
81     float Noise(float x, float y);
82     Vector2f Curl(float x, float y);
83 };
84 
85 class ParticleNoiseFields {
86 public:
87     std::vector<std::shared_ptr<ParticleNoiseField>> fields_;
88 
89     ParticleNoiseFields() = default;
90 
AddField(const std::shared_ptr<ParticleNoiseField> & field)91     void AddField(const std::shared_ptr<ParticleNoiseField>& field)
92     {
93         fields_.push_back(field);
94     }
95 
RemoveField(size_t index)96     void RemoveField(size_t index)
97     {
98         if (index < fields_.size()) {
99             fields_.erase(fields_.begin() + index);
100         }
101     }
102 
GetField(size_t index)103     std::shared_ptr<ParticleNoiseField> GetField(size_t index)
104     {
105         if (index < fields_.size()) {
106             return fields_[index];
107         }
108         return nullptr;
109     }
110 
GetFieldCount()111     size_t GetFieldCount() const
112     {
113         return fields_.size();
114     }
115 
ApplyAllFields(const Vector2f & position,float deltaTime)116     Vector2f ApplyAllFields(const Vector2f& position, float deltaTime)
117     {
118         Vector2f totalEffect = {0.0f, 0.0f};
119         for (auto& field : fields_) {
120             totalEffect += (field->ApplyField(position, deltaTime) + field->ApplyCurlNoise(position));
121         }
122         return totalEffect;
123     }
124 
ClearFields()125     void ClearFields()
126     {
127         fields_.clear();
128     }
129 
130     bool operator==(const ParticleNoiseFields& rhs) const
131     {
132         return fields_ == rhs.fields_;
133     }
134 
135     void Dump(std::string& out) const;
136 };
137 
138 } // namespace Rosen
139 } // namespace OHOS
140 
141 #endif // ROSEN_ENGINE_CORE_ANIMATION_RS_NOISE_FIELD_H
142