diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp index e0325702a8d..1f5a4a8a36c 100644 --- a/editor/plugins/particles_editor_plugin.cpp +++ b/editor/plugins/particles_editor_plugin.cpp @@ -40,7 +40,6 @@ bool ParticlesEditorBase::_generate(PoolVector &points, PoolVector triangle_area_map; - print_line("geometry size: " + itos(geometry.size())); for (int i = 0; i < geometry.size(); i++) { @@ -300,6 +299,10 @@ void ParticlesEditor::_menu_option(int p_option) { CPUParticles *cpu_particles = memnew(CPUParticles); cpu_particles->convert_from_particles(node); + cpu_particles->set_name(node->get_name()); + cpu_particles->set_transform(node->get_transform()); + cpu_particles->set_visible(node->is_visible()); + cpu_particles->set_pause_mode(node->get_pause_mode()); undo_redo->create_action("Replace Particles by CPUParticles"); undo_redo->add_do_method(node, "replace_by", cpu_particles); diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp index 2e897c1c73b..c3b01963164 100644 --- a/scene/3d/cpu_particles.cpp +++ b/scene/3d/cpu_particles.cpp @@ -25,6 +25,8 @@ void CPUParticles::set_emitting(bool p_emitting) { update_mutex->lock(); #endif VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread"); + VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_REDRAW_FRAME_IF_VISIBLE, true); + #ifndef NO_THREADS update_mutex->unlock(); #endif @@ -446,6 +448,8 @@ float rand_from_seed_m1_p1(uint32_t &seed) { void CPUParticles::_particles_process(float p_delta) { + p_delta *= speed_scale; + int pcount = particles.size(); PoolVector::Write w = particles.write(); @@ -475,7 +479,7 @@ void CPUParticles::_particles_process(float p_delta) { if (!emitting && !p.active) continue; - float restart_time = float(i) / float(pcount); + float restart_time = (float(i) / float(pcount)) * lifetime; float local_delta = p_delta; if (randomness_ratio > 0.0) { @@ -643,7 +647,7 @@ void CPUParticles::_particles_process(float p_delta) { uint32_t alt_seed = p.seed; p.time += local_delta; - p.custom[1] += p.time / lifetime; + p.custom[1] = p.time / lifetime; float tex_linear_velocity = 0.0; if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { @@ -979,6 +983,7 @@ void CPUParticles::_notification(int p_what) { update_mutex->lock(); #endif VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread"); + VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_REDRAW_FRAME_IF_VISIBLE, true); #ifndef NO_THREADS update_mutex->unlock(); #endif @@ -992,6 +997,7 @@ void CPUParticles::_notification(int p_what) { update_mutex->lock(); #endif VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread"); + VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_REDRAW_FRAME_IF_VISIBLE, false); #ifndef NO_THREADS update_mutex->unlock(); #endif @@ -1018,6 +1024,8 @@ void CPUParticles::_notification(int p_what) { update_mutex->lock(); #endif VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread"); + VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_REDRAW_FRAME_IF_VISIBLE, false); + #ifndef NO_THREADS update_mutex->unlock(); #endif diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 0b37d266e77..731a61890cc 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -104,10 +104,12 @@ public: VS::ShadowCastingSetting cast_shadows; + //fit in 32 bits bool mirror : 8; bool receive_shadows : 8; bool visible : 8; - bool baked_light : 8; //this flag is only to know if it actually did use baked light + bool baked_light : 4; //this flag is only to know if it actually did use baked light + bool redraw_if_visible : 4; float depth; //used for sorting @@ -131,6 +133,7 @@ public: depth_layer = 0; layer_mask = 1; baked_light = false; + redraw_if_visible = false; lightmap_capture = NULL; } }; diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index 34a1f1458ad..887cd7429a9 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -820,6 +820,11 @@ void VisualServerScene::instance_geometry_set_flag(RID p_instance, VS::InstanceF instance->baked_light = p_enabled; } break; + case VS::INSTANCE_FLAG_REDRAW_FRAME_IF_VISIBLE: { + + instance->redraw_if_visible = p_enabled; + + } break; } } void VisualServerScene::instance_geometry_set_cast_shadows_setting(RID p_instance, VS::ShadowCastingSetting p_shadow_casting_setting) { @@ -1873,6 +1878,10 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca InstanceGeometryData *geom = static_cast(ins->base_data); + if (ins->redraw_if_visible) { + VisualServerRaster::redraw_request(); + } + if (ins->base_type == VS::INSTANCE_PARTICLES) { //particles visible? process them VSG::storage->particles_request_process(ins->base); diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index a48f1cccae2..143e56b8489 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -2066,6 +2066,7 @@ void VisualServer::_bind_methods() { BIND_ENUM_CONSTANT(INSTANCE_GEOMETRY_MASK); BIND_ENUM_CONSTANT(INSTANCE_FLAG_USE_BAKED_LIGHT); + BIND_ENUM_CONSTANT(INSTANCE_FLAG_REDRAW_FRAME_IF_VISIBLE); BIND_ENUM_CONSTANT(INSTANCE_FLAG_MAX); BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_OFF); diff --git a/servers/visual_server.h b/servers/visual_server.h index 968cb852ed9..a76cad24a2f 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -805,6 +805,7 @@ public: enum InstanceFlags { INSTANCE_FLAG_USE_BAKED_LIGHT, + INSTANCE_FLAG_REDRAW_FRAME_IF_VISIBLE, INSTANCE_FLAG_MAX };