Browse Source

Merge pull request #93837 from Calinou/gpuparticles-fix-inherit-velocity-physics

Fix GPUParticles Inherit Velocity breaking with physics movement
Rémi Verschelde 1 year ago
parent
commit
f3ba14be60
2 changed files with 28 additions and 17 deletions
  1. 14 9
      scene/2d/gpu_particles_2d.cpp
  2. 14 8
      scene/3d/gpu_particles_3d.cpp

+ 14 - 9
scene/2d/gpu_particles_2d.cpp

@@ -688,6 +688,7 @@ void GPUParticles2D::_notification(int p_what) {
 				RS::get_singleton()->particles_set_speed_scale(particles, 0);
 			}
 			set_process_internal(true);
+			set_physics_process_internal(true);
 			previous_position = get_global_position();
 		} break;
 
@@ -711,15 +712,6 @@ void GPUParticles2D::_notification(int p_what) {
 		} break;
 
 		case NOTIFICATION_INTERNAL_PROCESS: {
-			const Vector3 velocity = Vector3((get_global_position() - previous_position).x, (get_global_position() - previous_position).y, 0.0) /
-					get_process_delta_time();
-
-			if (velocity != previous_velocity) {
-				RS::get_singleton()->particles_set_emitter_velocity(particles, velocity);
-				previous_velocity = velocity;
-			}
-			previous_position = get_global_position();
-
 			if (one_shot) {
 				time += get_process_delta_time();
 				if (time > emission_time) {
@@ -739,6 +731,19 @@ void GPUParticles2D::_notification(int p_what) {
 				}
 			}
 		} break;
+
+		case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
+			// Update velocity in physics process, so that velocity calculations remain correct
+			// if the physics tick rate is lower than the rendered framerate (especially without physics interpolation).
+			const Vector3 velocity = Vector3((get_global_position() - previous_position).x, (get_global_position() - previous_position).y, 0.0) /
+					get_physics_process_delta_time();
+
+			if (velocity != previous_velocity) {
+				RS::get_singleton()->particles_set_emitter_velocity(particles, velocity);
+				previous_velocity = velocity;
+			}
+			previous_position = get_global_position();
+		} break;
 	}
 }
 

+ 14 - 8
scene/3d/gpu_particles_3d.cpp

@@ -459,14 +459,6 @@ void GPUParticles3D::_notification(int p_what) {
 		// Use internal process when emitting and one_shot is on so that when
 		// the shot ends the editor can properly update.
 		case NOTIFICATION_INTERNAL_PROCESS: {
-			const Vector3 velocity = (get_global_position() - previous_position) / get_process_delta_time();
-
-			if (velocity != previous_velocity) {
-				RS::get_singleton()->particles_set_emitter_velocity(particles, velocity);
-				previous_velocity = velocity;
-			}
-			previous_position = get_global_position();
-
 			if (one_shot) {
 				time += get_process_delta_time();
 				if (time > emission_time) {
@@ -487,8 +479,21 @@ void GPUParticles3D::_notification(int p_what) {
 			}
 		} break;
 
+		case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
+			// Update velocity in physics process, so that velocity calculations remain correct
+			// if the physics tick rate is lower than the rendered framerate (especially without physics interpolation).
+			const Vector3 velocity = (get_global_position() - previous_position) / get_physics_process_delta_time();
+
+			if (velocity != previous_velocity) {
+				RS::get_singleton()->particles_set_emitter_velocity(particles, velocity);
+				previous_velocity = velocity;
+			}
+			previous_position = get_global_position();
+		} break;
+
 		case NOTIFICATION_ENTER_TREE: {
 			set_process_internal(false);
+			set_physics_process_internal(false);
 			if (sub_emitter != NodePath()) {
 				_attach_sub_emitter();
 			}
@@ -499,6 +504,7 @@ void GPUParticles3D::_notification(int p_what) {
 			}
 			previous_position = get_global_transform().origin;
 			set_process_internal(true);
+			set_physics_process_internal(true);
 		} break;
 
 		case NOTIFICATION_EXIT_TREE: {