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