Fix GPUParticles Inherit Velocity breaking with physics movement

GPUParticles' Inherit Velocity property used to act strangely
if the physics tick rate was lower than the rendered FPS, as velocity
was tracked in the process and not in the physics process. This
means that on certain rendered frames, the velocity was effectively
0 since there was no movement since the last rendered frame.
This commit is contained in:
Hugo Locurcio 2024-07-02 01:46:57 +02:00
parent 9425535602
commit 33e1f570ff
No known key found for this signature in database
GPG Key ID: 39E8F8BE30B0A49C
2 changed files with 28 additions and 17 deletions

View File

@ -688,6 +688,7 @@ void GPUParticles2D::_notification(int p_what) {
RS::get_singleton()->particles_set_speed_scale(particles, 0); RS::get_singleton()->particles_set_speed_scale(particles, 0);
} }
set_process_internal(true); set_process_internal(true);
set_physics_process_internal(true);
previous_position = get_global_position(); previous_position = get_global_position();
} break; } break;
@ -711,15 +712,6 @@ void GPUParticles2D::_notification(int p_what) {
} break; } break;
case NOTIFICATION_INTERNAL_PROCESS: { 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) { if (one_shot) {
time += get_process_delta_time(); time += get_process_delta_time();
if (time > emission_time) { if (time > emission_time) {
@ -739,6 +731,19 @@ void GPUParticles2D::_notification(int p_what) {
} }
} }
} break; } 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;
} }
} }

View File

@ -459,14 +459,6 @@ void GPUParticles3D::_notification(int p_what) {
// Use internal process when emitting and one_shot is on so that when // Use internal process when emitting and one_shot is on so that when
// the shot ends the editor can properly update. // the shot ends the editor can properly update.
case NOTIFICATION_INTERNAL_PROCESS: { 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) { if (one_shot) {
time += get_process_delta_time(); time += get_process_delta_time();
if (time > emission_time) { if (time > emission_time) {
@ -487,8 +479,21 @@ void GPUParticles3D::_notification(int p_what) {
} }
} break; } 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: { case NOTIFICATION_ENTER_TREE: {
set_process_internal(false); set_process_internal(false);
set_physics_process_internal(false);
if (sub_emitter != NodePath()) { if (sub_emitter != NodePath()) {
_attach_sub_emitter(); _attach_sub_emitter();
} }
@ -499,6 +504,7 @@ void GPUParticles3D::_notification(int p_what) {
} }
previous_position = get_global_transform().origin; previous_position = get_global_transform().origin;
set_process_internal(true); set_process_internal(true);
set_physics_process_internal(true);
} break; } break;
case NOTIFICATION_EXIT_TREE: { case NOTIFICATION_EXIT_TREE: {