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 }; 66 67 class RSB_EXPORT PerlinNoise2D { 68 private: 69 std::vector<int> p; // Permutation vector 70 float Fade(float t); 71 float Lerp(float t, float a, float b); 72 float Grad(int hash, float x, float y); 73 float noiseScale_ { 0.0 }; 74 float noiseFrequency_ { 0.0 }; 75 float noiseAmplitude_ { 0.0 }; 76 77 public: 78 PerlinNoise2D(float noiseScale, float noiseFrequency, float noiseAmplitude); 79 float Noise(float x, float y); 80 Vector2f Curl(float x, float y); 81 }; 82 83 class ParticleNoiseFields { 84 public: 85 std::vector<std::shared_ptr<ParticleNoiseField>> fields_; 86 87 ParticleNoiseFields() = default; 88 AddField(const std::shared_ptr<ParticleNoiseField> & field)89 void AddField(const std::shared_ptr<ParticleNoiseField>& field) 90 { 91 fields_.push_back(field); 92 } 93 RemoveField(size_t index)94 void RemoveField(size_t index) 95 { 96 if (index < fields_.size()) { 97 fields_.erase(fields_.begin() + index); 98 } 99 } 100 GetField(size_t index)101 std::shared_ptr<ParticleNoiseField> GetField(size_t index) 102 { 103 if (index < fields_.size()) { 104 return fields_[index]; 105 } 106 return nullptr; 107 } 108 GetFieldCount()109 size_t GetFieldCount() const 110 { 111 return fields_.size(); 112 } 113 ApplyAllFields(const Vector2f & position,float deltaTime)114 Vector2f ApplyAllFields(const Vector2f& position, float deltaTime) 115 { 116 Vector2f totalEffect = {0.0f, 0.0f}; 117 for (auto& field : fields_) { 118 totalEffect += (field->ApplyField(position, deltaTime) + field->ApplyCurlNoise(position)); 119 } 120 return totalEffect; 121 } 122 ClearFields()123 void ClearFields() 124 { 125 fields_.clear(); 126 } 127 128 bool operator==(const ParticleNoiseFields& rhs) const 129 { 130 return fields_ == rhs.fields_; 131 } 132 133 void Dump(std::string& out) const; 134 }; 135 136 } // namespace Rosen 137 } // namespace OHOS 138 139 #endif // ROSEN_ENGINE_CORE_ANIMATION_RS_NOISE_FIELD_H 140