diff --git a/doc/en/particles.md b/doc/en/particles.md index 47ab8ac3c..66d3858d5 100644 --- a/doc/en/particles.md +++ b/doc/en/particles.md @@ -22,6 +22,7 @@ Particles are a table, all fields of which are optional. | max_angular_vel | Maximum angular velocity (radians per sec). Non-negative. | 0.0 | | spawn_shape | Shape of particle spawn area. (ball/sphere/box) | ball | | spawn_spread | Size of particle spawn area. | {0, 0, 0} | +| spawn_offset | Offset of particle spawn area. | {0, 0, 0} | | random_sub_uv | Size of random texture subregion (1 - entire texture will be used). | 1.0 | ## *gfx.particles* library diff --git a/doc/ru/particles.md b/doc/ru/particles.md index 90af27f15..445ded593 100644 --- a/doc/ru/particles.md +++ b/doc/ru/particles.md @@ -23,6 +23,7 @@ | max_angular_vel | Максимальная угловая скорость (радианы в сек.). Неотрицательное. | 0.0 | | spawn_shape | Форма области спавна частиц. (ball/sphere/box) | ball | | spawn_spread | Размер области спавна частиц. | {0, 0, 0} | +| spawn_offset | Смещение области спавна частиц. | {0, 0, 0} | | random_sub_uv | Размер случайного подрегиона текстуры (1 - будет использована вся текстура). | 1.0 | ## Библиотека *gfx.particles* diff --git a/src/graphics/render/Emitter.cpp b/src/graphics/render/Emitter.cpp index 7e10daae9..cc7450f9f 100644 --- a/src/graphics/render/Emitter.cpp +++ b/src/graphics/render/Emitter.cpp @@ -103,6 +103,7 @@ void Emitter::update( glm::vec3 spawnOffset = generate_coord(preset.spawnShape); spawnOffset *= preset.spawnSpread; + spawnOffset += preset.spawnOffset; particle.position = position + spawnOffset; particle.lifetime *= 1.0f - preset.lifetimeSpread * random.randFloat(); diff --git a/src/presets/ParticlesPreset.cpp b/src/presets/ParticlesPreset.cpp index df129f1ff..c7e741ac6 100644 --- a/src/presets/ParticlesPreset.cpp +++ b/src/presets/ParticlesPreset.cpp @@ -28,7 +28,8 @@ dv::value ParticlesPreset::serialize() const { root["angle_spread"] = angleSpread; root["min_angular_vel"] = minAngularVelocity; root["max_angular_vel"] = maxAngularVelocity; - root["spawn_spread"] = dv::to_value(size); + root["spawn_spread"] = dv::to_value(spawnSpread); + root["spawn_offset"] = dv::to_value(spawnOffset); root["spawn_shape"] = ParticleSpawnShapeMeta.getName(spawnShape); root["random_sub_uv"] = randomSubUV; return root; @@ -47,9 +48,7 @@ void ParticlesPreset::deserialize(const dv::value& src) { src.at("min_angular_vel").get(minAngularVelocity); src.at("max_angular_vel").get(maxAngularVelocity); src.at("random_sub_uv").get(randomSubUV); - if (src.has("velocity")) { - dv::get_vec(src["velocity"], velocity); - } + dv::get_vec(src, "velocity", velocity); if (src.has("acceleration")) { dv::get_vec(src["acceleration"], acceleration); } @@ -57,12 +56,9 @@ void ParticlesPreset::deserialize(const dv::value& src) { dv::get_vec(src["size"], size); } src.at("size_spread").get(sizeSpread); - if (src.has("spawn_spread")) { - dv::get_vec(src["spawn_spread"], spawnSpread); - } - if (src.has("explosion")) { - dv::get_vec(src["explosion"], explosion); - } + dv::get_vec(src, "spawn_spread", spawnSpread); + dv::get_vec(src, "spawn_offset", spawnOffset); + dv::get_vec(src, "explosion", explosion); if (src.has("spawn_shape")) { ParticleSpawnShapeMeta.getItem(src["spawn_shape"].asString(), spawnShape); } diff --git a/src/presets/ParticlesPreset.hpp b/src/presets/ParticlesPreset.hpp index dd5a66d5e..63e075271 100644 --- a/src/presets/ParticlesPreset.hpp +++ b/src/presets/ParticlesPreset.hpp @@ -60,6 +60,8 @@ struct ParticlesPreset : public Serializable { ParticleSpawnShape spawnShape = ParticleSpawnShape::BALL; /// @brief Spawn spread glm::vec3 spawnSpread {}; + /// @brief Particles spawn zone offset + glm::vec3 spawnOffset {}; /// @brief Texture name std::string texture = ""; /// @brief Size of random sub-uv region