diff options
author | Rémi Verschelde <remi@verschelde.fr> | 2021-08-12 15:44:55 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-12 15:44:55 +0200 |
commit | fdddfa02fdd97684fdb8f0d355d9f7420792a6dc (patch) | |
tree | 4c250daa261d4f8a07d62faee378584c21aec660 | |
parent | f54c5707b5d2f77a7d112c1cf5c2494751e0dace (diff) | |
parent | d7e059ff84615676ab59c6ebf6016b35cd1a910f (diff) |
Merge pull request #51567 from mortarroad/master-fix-cpu-particles-spread
Fix CPU Particles spread
-rw-r--r-- | scene/3d/cpu_particles_3d.cpp | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index 2377c618aa..5a358e1917 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -710,15 +710,28 @@ void CPUParticles3D::_particles_process(double p_delta) { p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp((real_t)1.0, real_t(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]); } else { //initiate velocity spread in 3D - real_t angle1_rad = Math::atan2(direction.x, direction.z) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread); - real_t angle2_rad = Math::atan2(direction.y, Math::abs(direction.z)) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * spread); + real_t angle1_rad = Math::deg2rad((Math::randf() * (real_t)2.0 - (real_t)1.0) * spread); + real_t angle2_rad = Math::deg2rad((Math::randf() * (real_t)2.0 - (real_t)1.0) * ((real_t)1.0 - flatness) * spread); Vector3 direction_xz = Vector3(Math::sin(angle1_rad), 0, Math::cos(angle1_rad)); Vector3 direction_yz = Vector3(0, Math::sin(angle2_rad), Math::cos(angle2_rad)); - direction_yz.z = direction_yz.z / MAX(0.0001, Math::sqrt(ABS(direction_yz.z))); //better uniform distribution - Vector3 direction = Vector3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z); - direction.normalize(); - p.velocity = direction * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp((real_t)1.0, real_t(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]); + Vector3 spread_direction = Vector3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z); + Vector3 direction_nrm = direction; + if (direction_nrm.length_squared() > 0) { + direction_nrm.normalize(); + } else { + direction_nrm = Vector3(0, 0, 1); + } + // rotate spread to direction + Vector3 binormal = Vector3(0.0, 1.0, 0.0).cross(direction_nrm); + if (binormal.length_squared() < 0.00000001) { + // direction is parallel to Y. Choose Z as the binormal. + binormal = Vector3(0.0, 0.0, 1.0); + } + binormal.normalize(); + Vector3 normal = binormal.cross(direction_nrm); + spread_direction = binormal * spread_direction.x + normal * spread_direction.y + direction_nrm * spread_direction.z; + p.velocity = spread_direction * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp((real_t)1.0, real_t(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]); } real_t base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp((real_t)1.0, p.angle_rand, randomness[PARAM_ANGLE]); |