Browse Source

Fix issues with CPUParticles and related conversion from Particles. Closes #20126

Juan Linietsky 7 years ago
parent
commit
ec85fd554b

+ 4 - 1
editor/plugins/particles_editor_plugin.cpp

@@ -40,7 +40,6 @@ bool ParticlesEditorBase::_generate(PoolVector<Vector3> &points, PoolVector<Vect
 
 
 		float area_accum = 0;
 		float area_accum = 0;
 		Map<float, int> triangle_area_map;
 		Map<float, int> triangle_area_map;
-		print_line("geometry size: " + itos(geometry.size()));
 
 
 		for (int i = 0; i < geometry.size(); i++) {
 		for (int i = 0; i < geometry.size(); i++) {
 
 
@@ -300,6 +299,10 @@ void ParticlesEditor::_menu_option(int p_option) {
 
 
 			CPUParticles *cpu_particles = memnew(CPUParticles);
 			CPUParticles *cpu_particles = memnew(CPUParticles);
 			cpu_particles->convert_from_particles(node);
 			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->create_action("Replace Particles by CPUParticles");
 			undo_redo->add_do_method(node, "replace_by", cpu_particles);
 			undo_redo->add_do_method(node, "replace_by", cpu_particles);

+ 10 - 2
scene/3d/cpu_particles.cpp

@@ -25,6 +25,8 @@ void CPUParticles::set_emitting(bool p_emitting) {
 			update_mutex->lock();
 			update_mutex->lock();
 #endif
 #endif
 			VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread");
 			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
 #ifndef NO_THREADS
 			update_mutex->unlock();
 			update_mutex->unlock();
 #endif
 #endif
@@ -446,6 +448,8 @@ float rand_from_seed_m1_p1(uint32_t &seed) {
 
 
 void CPUParticles::_particles_process(float p_delta) {
 void CPUParticles::_particles_process(float p_delta) {
 
 
+	p_delta *= speed_scale;
+
 	int pcount = particles.size();
 	int pcount = particles.size();
 	PoolVector<Particle>::Write w = particles.write();
 	PoolVector<Particle>::Write w = particles.write();
 
 
@@ -475,7 +479,7 @@ void CPUParticles::_particles_process(float p_delta) {
 		if (!emitting && !p.active)
 		if (!emitting && !p.active)
 			continue;
 			continue;
 
 
-		float restart_time = float(i) / float(pcount);
+		float restart_time = (float(i) / float(pcount)) * lifetime;
 		float local_delta = p_delta;
 		float local_delta = p_delta;
 
 
 		if (randomness_ratio > 0.0) {
 		if (randomness_ratio > 0.0) {
@@ -643,7 +647,7 @@ void CPUParticles::_particles_process(float p_delta) {
 			uint32_t alt_seed = p.seed;
 			uint32_t alt_seed = p.seed;
 
 
 			p.time += local_delta;
 			p.time += local_delta;
-			p.custom[1] += p.time / lifetime;
+			p.custom[1] = p.time / lifetime;
 
 
 			float tex_linear_velocity = 0.0;
 			float tex_linear_velocity = 0.0;
 			if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
 			if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
@@ -979,6 +983,7 @@ void CPUParticles::_notification(int p_what) {
 			update_mutex->lock();
 			update_mutex->lock();
 #endif
 #endif
 			VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread");
 			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
 #ifndef NO_THREADS
 			update_mutex->unlock();
 			update_mutex->unlock();
 #endif
 #endif
@@ -992,6 +997,7 @@ void CPUParticles::_notification(int p_what) {
 			update_mutex->lock();
 			update_mutex->lock();
 #endif
 #endif
 			VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread");
 			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
 #ifndef NO_THREADS
 			update_mutex->unlock();
 			update_mutex->unlock();
 #endif
 #endif
@@ -1018,6 +1024,8 @@ void CPUParticles::_notification(int p_what) {
 				update_mutex->lock();
 				update_mutex->lock();
 #endif
 #endif
 				VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread");
 				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
 #ifndef NO_THREADS
 				update_mutex->unlock();
 				update_mutex->unlock();
 #endif
 #endif

+ 4 - 1
servers/visual/rasterizer.h

@@ -104,10 +104,12 @@ public:
 
 
 		VS::ShadowCastingSetting cast_shadows;
 		VS::ShadowCastingSetting cast_shadows;
 
 
+		//fit in 32 bits
 		bool mirror : 8;
 		bool mirror : 8;
 		bool receive_shadows : 8;
 		bool receive_shadows : 8;
 		bool visible : 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
 		float depth; //used for sorting
 
 
@@ -131,6 +133,7 @@ public:
 			depth_layer = 0;
 			depth_layer = 0;
 			layer_mask = 1;
 			layer_mask = 1;
 			baked_light = false;
 			baked_light = false;
+			redraw_if_visible = false;
 			lightmap_capture = NULL;
 			lightmap_capture = NULL;
 		}
 		}
 	};
 	};

+ 9 - 0
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;
 			instance->baked_light = p_enabled;
 
 
 		} break;
 		} 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) {
 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<InstanceGeometryData *>(ins->base_data);
 			InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(ins->base_data);
 
 
+			if (ins->redraw_if_visible) {
+				VisualServerRaster::redraw_request();
+			}
+
 			if (ins->base_type == VS::INSTANCE_PARTICLES) {
 			if (ins->base_type == VS::INSTANCE_PARTICLES) {
 				//particles visible? process them
 				//particles visible? process them
 				VSG::storage->particles_request_process(ins->base);
 				VSG::storage->particles_request_process(ins->base);

+ 1 - 0
servers/visual_server.cpp

@@ -2066,6 +2066,7 @@ void VisualServer::_bind_methods() {
 	BIND_ENUM_CONSTANT(INSTANCE_GEOMETRY_MASK);
 	BIND_ENUM_CONSTANT(INSTANCE_GEOMETRY_MASK);
 
 
 	BIND_ENUM_CONSTANT(INSTANCE_FLAG_USE_BAKED_LIGHT);
 	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(INSTANCE_FLAG_MAX);
 
 
 	BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_OFF);
 	BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_OFF);

+ 1 - 0
servers/visual_server.h

@@ -805,6 +805,7 @@ public:
 
 
 	enum InstanceFlags {
 	enum InstanceFlags {
 		INSTANCE_FLAG_USE_BAKED_LIGHT,
 		INSTANCE_FLAG_USE_BAKED_LIGHT,
+		INSTANCE_FLAG_REDRAW_FRAME_IF_VISIBLE,
 		INSTANCE_FLAG_MAX
 		INSTANCE_FLAG_MAX
 	};
 	};