summaryrefslogtreecommitdiff
path: root/scene/3d/particles.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/3d/particles.cpp')
-rw-r--r--scene/3d/particles.cpp45
1 files changed, 28 insertions, 17 deletions
diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp
index 821f1a5a78..fda4647141 100644
--- a/scene/3d/particles.cpp
+++ b/scene/3d/particles.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -42,8 +42,7 @@ PoolVector<Face3> Particles::get_faces(uint32_t p_usage_flags) const {
void Particles::set_emitting(bool p_emitting) {
- emitting = p_emitting;
- VS::get_singleton()->particles_set_emitting(particles, emitting);
+ VS::get_singleton()->particles_set_emitting(particles, p_emitting);
}
void Particles::set_amount(int p_amount) {
@@ -63,7 +62,7 @@ void Particles::set_one_shot(bool p_one_shot) {
one_shot = p_one_shot;
VS::get_singleton()->particles_set_one_shot(particles, one_shot);
- if (!one_shot && emitting)
+ if (!one_shot && is_emitting())
VisualServer::get_singleton()->particles_restart(particles);
}
@@ -113,7 +112,7 @@ void Particles::set_speed_scale(float p_scale) {
bool Particles::is_emitting() const {
- return emitting;
+ return VS::get_singleton()->particles_get_emitting(particles);
}
int Particles::get_amount() const {
@@ -598,6 +597,11 @@ void ParticlesMaterial::_update_shader() {
code += "}\n";
code += "\n";
+ code += "float rand_from_seed_m1_p1(inout uint seed) {\n";
+ code += " return rand_from_seed(seed)*2.0-1.0;\n";
+ code += "}\n";
+ code += "\n";
+
//improve seed quality
code += "uint hash(uint x) {\n";
code += " x = ((x >> uint(16)) ^ x) * uint(73244475);\n";
@@ -614,6 +618,8 @@ void ParticlesMaterial::_update_shader() {
code += " float scale_rand = rand_from_seed(alt_seed);\n";
code += " float hue_rot_rand = rand_from_seed(alt_seed);\n";
code += " float anim_offset_rand = rand_from_seed(alt_seed);\n";
+ code += " float pi = 3.14159;\n";
+ code += " float degree_to_rad = pi / 180.0;\n";
code += "\n";
if (emission_shape >= EMISSION_SHAPE_POINTS) {
@@ -638,23 +644,28 @@ void ParticlesMaterial::_update_shader() {
else
code += " float tex_anim_offset = 0.0;\n";
+ code += " float spread_rad = spread*degree_to_rad;\n";
+
if (flags[FLAG_DISABLE_Z]) {
- code += " float angle1 = (rand_from_seed(alt_seed)*2.0-1.0)*spread/180.0*3.1416;\n";
- code += " vec3 rot = vec3( cos(angle1), sin(angle1),0.0 );\n";
+ code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed)*spread_rad;\n";
+ code += " vec3 rot = vec3( cos(angle1_rad), sin(angle1_rad),0.0 );\n";
code += " VELOCITY = rot*initial_linear_velocity*mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
} else {
//initiate velocity spread in 3D
- code += " float angle1 = rand_from_seed(alt_seed)*spread*3.1416;\n";
- code += " float angle2 = rand_from_seed(alt_seed)*20.0*3.1416; // make it more random like\n";
- code += " vec3 rot_xz = vec3( sin(angle1), 0.0, cos(angle1) );\n";
- code += " vec3 rot = vec3( cos(angle2)*rot_xz.x,sin(angle2)*rot_xz.x, rot_xz.z);\n";
- code += " VELOCITY = rot*initial_linear_velocity*mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
+ code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed)*spread_rad;\n";
+ code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed)*spread_rad*(1.0-flatness);\n";
+ code += " vec3 direction_xz = vec3( sin(angle1_rad), 0, cos(angle1_rad));\n";
+ code += " vec3 direction_yz = vec3( 0, sin(angle2_rad), cos(angle2_rad));\n";
+ code += " direction_yz.z = direction_yz.z / sqrt(direction_yz.z); //better uniform distribution\n";
+ code += " vec3 direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n";
+ code += " direction = normalize(direction);\n";
+ code += " VELOCITY = direction*initial_linear_velocity*mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
}
code += " float base_angle = (initial_angle+tex_angle)*mix(1.0,angle_rand,initial_angle_random);\n";
- code += " CUSTOM.x = base_angle*3.1416/180.0;\n"; //angle
+ code += " CUSTOM.x = base_angle*degree_to_rad;\n"; //angle
code += " CUSTOM.y = 0.0;\n"; //phase
code += " CUSTOM.z = (anim_offset+tex_anim_offset)*mix(1.0,anim_offset_rand,anim_offset_random);\n"; //animation offset (0-1)
switch (emission_shape) {
@@ -777,7 +788,7 @@ void ParticlesMaterial::_update_shader() {
code += " float orbit_amount = (orbit_velocity+tex_orbit_velocity)*mix(1.0,rand_from_seed(alt_seed),orbit_velocity_random);\n";
code += " if (orbit_amount!=0.0) {\n";
- code += " float ang = orbit_amount * DELTA * 3.1416 * 2.0;\n";
+ code += " float ang = orbit_amount * DELTA * pi * 2.0;\n";
code += " mat2 rot = mat2(vec2(cos(ang),-sin(ang)),vec2(sin(ang),cos(ang)));\n";
code += " TRANSFORM[3].xy-=diff.xy;\n";
code += " TRANSFORM[3].xy+=rot * diff.xy;\n";
@@ -800,7 +811,7 @@ void ParticlesMaterial::_update_shader() {
code += " }\n";
code += " float base_angle = (initial_angle+tex_angle)*mix(1.0,angle_rand,initial_angle_random);\n";
code += " base_angle += CUSTOM.y*LIFETIME*(angular_velocity+tex_angular_velocity)*mix(1.0,rand_from_seed(alt_seed)*2.0-1.0,angular_velocity_random);\n";
- code += " CUSTOM.x = base_angle*3.1416/180.0;\n"; //angle
+ code += " CUSTOM.x = base_angle*degree_to_rad;\n"; //angle
code += " CUSTOM.z = (anim_offset+tex_anim_offset)*mix(1.0,anim_offset_rand,anim_offset_random)+CUSTOM.y*(anim_speed+tex_anim_speed)*mix(1.0,rand_from_seed(alt_seed),anim_speed_random);\n"; //angle
if (flags[FLAG_ANIM_LOOP]) {
code += " CUSTOM.z = mod(CUSTOM.z,1.0);\n"; //loop
@@ -821,7 +832,7 @@ void ParticlesMaterial::_update_shader() {
else
code += " float tex_hue_variation = 0.0;\n";
- code += " float hue_rot_angle = (hue_variation+tex_hue_variation)*3.1416*2.0*mix(1.0,hue_rot_rand*2.0-1.0,hue_variation_random);\n";
+ code += " float hue_rot_angle = (hue_variation+tex_hue_variation)*pi*2.0*mix(1.0,hue_rot_rand*2.0-1.0,hue_variation_random);\n";
code += " float hue_rot_c = cos(hue_rot_angle);\n";
code += " float hue_rot_s = sin(hue_rot_angle);\n";
code += " mat4 hue_rot_mat = mat4( vec4(0.299, 0.587, 0.114, 0.0),\n";