diff options
Diffstat (limited to 'scene/3d/cpu_particles.cpp')
-rw-r--r-- | scene/3d/cpu_particles.cpp | 187 |
1 files changed, 82 insertions, 105 deletions
diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp index cddbe4bbbb..eefda96caa 100644 --- a/scene/3d/cpu_particles.cpp +++ b/scene/3d/cpu_particles.cpp @@ -1017,140 +1017,125 @@ void CPUParticles::_particles_process(float p_delta) { } void CPUParticles::_update_particle_data_buffer() { -#ifndef NO_THREADS - update_mutex->lock(); -#endif + MutexLock lock(update_mutex); - { + int pc = particles.size(); - int pc = particles.size(); + int *ow; + int *order = NULL; - int *ow; - int *order = NULL; + float *w = particle_data.ptrw(); + const Particle *r = particles.ptr(); + float *ptr = w; - float *w = particle_data.ptrw(); - const Particle *r = particles.ptr(); - float *ptr = w; + if (draw_order != DRAW_ORDER_INDEX) { + ow = particle_order.ptrw(); + order = ow; - if (draw_order != DRAW_ORDER_INDEX) { - ow = particle_order.ptrw(); - order = ow; + for (int i = 0; i < pc; i++) { + order[i] = i; + } + if (draw_order == DRAW_ORDER_LIFETIME) { + SortArray<int, SortLifetime> sorter; + sorter.compare.particles = r; + sorter.sort(order, pc); + } else if (draw_order == DRAW_ORDER_VIEW_DEPTH) { + Camera *c = get_viewport()->get_camera(); + if (c) { + Vector3 dir = c->get_global_transform().basis.get_axis(2); //far away to close + + if (local_coords) { + + // will look different from Particles in editor as this is based on the camera in the scenetree + // and not the editor camera + dir = inv_emission_transform.xform(dir).normalized(); + } else { + dir = dir.normalized(); + } - for (int i = 0; i < pc; i++) { - order[i] = i; - } - if (draw_order == DRAW_ORDER_LIFETIME) { - SortArray<int, SortLifetime> sorter; + SortArray<int, SortAxis> sorter; sorter.compare.particles = r; + sorter.compare.axis = dir; sorter.sort(order, pc); - } else if (draw_order == DRAW_ORDER_VIEW_DEPTH) { - Camera *c = get_viewport()->get_camera(); - if (c) { - Vector3 dir = c->get_global_transform().basis.get_axis(2); //far away to close - - if (local_coords) { - - // will look different from Particles in editor as this is based on the camera in the scenetree - // and not the editor camera - dir = inv_emission_transform.xform(dir).normalized(); - } else { - dir = dir.normalized(); - } - - SortArray<int, SortAxis> sorter; - sorter.compare.particles = r; - sorter.compare.axis = dir; - sorter.sort(order, pc); - } } } + } - for (int i = 0; i < pc; i++) { - - int idx = order ? order[i] : i; + for (int i = 0; i < pc; i++) { - Transform t = r[idx].transform; + int idx = order ? order[i] : i; - if (!local_coords) { - t = inv_emission_transform * t; - } + Transform t = r[idx].transform; - if (r[idx].active) { - ptr[0] = t.basis.elements[0][0]; - ptr[1] = t.basis.elements[0][1]; - ptr[2] = t.basis.elements[0][2]; - ptr[3] = t.origin.x; - ptr[4] = t.basis.elements[1][0]; - ptr[5] = t.basis.elements[1][1]; - ptr[6] = t.basis.elements[1][2]; - ptr[7] = t.origin.y; - ptr[8] = t.basis.elements[2][0]; - ptr[9] = t.basis.elements[2][1]; - ptr[10] = t.basis.elements[2][2]; - ptr[11] = t.origin.z; - } else { - zeromem(ptr, sizeof(float) * 12); - } + if (!local_coords) { + t = inv_emission_transform * t; + } - Color c = r[idx].color; + if (r[idx].active) { + ptr[0] = t.basis.elements[0][0]; + ptr[1] = t.basis.elements[0][1]; + ptr[2] = t.basis.elements[0][2]; + ptr[3] = t.origin.x; + ptr[4] = t.basis.elements[1][0]; + ptr[5] = t.basis.elements[1][1]; + ptr[6] = t.basis.elements[1][2]; + ptr[7] = t.origin.y; + ptr[8] = t.basis.elements[2][0]; + ptr[9] = t.basis.elements[2][1]; + ptr[10] = t.basis.elements[2][2]; + ptr[11] = t.origin.z; + } else { + zeromem(ptr, sizeof(float) * 12); + } - ptr[12] = c.r; - ptr[13] = c.g; - ptr[14] = c.b; - ptr[15] = c.a; + Color c = r[idx].color; - ptr[16] = r[idx].custom[0]; - ptr[17] = r[idx].custom[1]; - ptr[18] = r[idx].custom[2]; - ptr[19] = r[idx].custom[3]; + ptr[12] = c.r; + ptr[13] = c.g; + ptr[14] = c.b; + ptr[15] = c.a; - ptr += 20; - } + ptr[16] = r[idx].custom[0]; + ptr[17] = r[idx].custom[1]; + ptr[18] = r[idx].custom[2]; + ptr[19] = r[idx].custom[3]; - can_update = true; + ptr += 20; } -#ifndef NO_THREADS - update_mutex->unlock(); -#endif + can_update = true; } void CPUParticles::_set_redraw(bool p_redraw) { if (redraw == p_redraw) return; redraw = p_redraw; -#ifndef NO_THREADS - update_mutex->lock(); -#endif - if (redraw) { - VS::get_singleton()->connect_compat("frame_pre_draw", this, "_update_render_thread"); - VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true); - VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1); - } else { - if (VS::get_singleton()->is_connected_compat("frame_pre_draw", this, "_update_render_thread")) { - VS::get_singleton()->disconnect_compat("frame_pre_draw", this, "_update_render_thread"); + + { + MutexLock lock(update_mutex); + + if (redraw) { + VS::get_singleton()->connect_compat("frame_pre_draw", this, "_update_render_thread"); + VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true); + VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1); + } else { + if (VS::get_singleton()->is_connected_compat("frame_pre_draw", this, "_update_render_thread")) { + VS::get_singleton()->disconnect_compat("frame_pre_draw", this, "_update_render_thread"); + } + VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, false); + VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0); } - VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, false); - VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0); } -#ifndef NO_THREADS - update_mutex->unlock(); -#endif } void CPUParticles::_update_render_thread() { -#ifndef NO_THREADS - update_mutex->lock(); -#endif + MutexLock lock(update_mutex); + if (can_update) { VS::get_singleton()->multimesh_set_buffer(multimesh, particle_data); can_update = false; //wait for next time } - -#ifndef NO_THREADS - update_mutex->unlock(); -#endif } void CPUParticles::_notification(int p_what) { @@ -1556,16 +1541,8 @@ CPUParticles::CPUParticles() { can_update = false; set_color(Color(1, 1, 1, 1)); - -#ifndef NO_THREADS - update_mutex = Mutex::create(); -#endif } CPUParticles::~CPUParticles() { VS::get_singleton()->free(multimesh); - -#ifndef NO_THREADS - memdelete(update_mutex); -#endif } |