void FluidHandler(MPGPParticle[] particles, int num_particles, List <MPGPColliderBase> colliders) { for (int i = 0; i < num_particles; ++i) { int hit = particles[i].hit_objid; if (particles[i].lifetime != 0.0f && hit != -1 && hit < colliders.Count) { MPGPColliderBase cscol = colliders[hit]; if (cscol != null && cscol.m_receive_collision) { particles[i].lifetime = 0.0f; ++numGoaled; } } } }
void FractionHandler(MPGPParticle[] particles, int num_particles, List <MPGPColliderBase> colliders) { for (int i = 0; i < num_particles; ++i) { int hit = particles[i].hit_objid; if (particles[i].lifetime != 0.0f && hit != -1 && hit < colliders.Count) { MPGPColliderBase cscol = colliders[hit]; if (cscol != null && cscol.m_receive_collision) { TSEntity tge = cscol.GetComponent <TSEntity>(); if (tge) { tge.OnHitParticle(ref particles[i]); } } } } }
void Update() { if (s_update_count++ == 0) { MPGPEmitter.UpdateAll(); MPGPForce.UpdateAll(); MPGPColliderBase.UpdateAll(); } if (m_writeback_to_cpu) { m_buf_particles[0].GetData(m_particles); m_buf_world_idata.GetData(m_world_idata); m_actions.ForEach((a) => { a.Invoke(); }); m_onetime_actions.ForEach((a) => { a.Invoke(); }); m_onetime_actions.Clear(); m_buf_particles[0].SetData(m_particles); m_buf_world_idata.SetData(m_world_idata); } m_world_data[0].num_max_particles = m_max_particles; m_world_data[0].SetWorldSize(transform.position, transform.localScale, (uint)m_world_div_x, (uint)m_world_div_y, (uint)m_world_div_z); m_world_data[0].timestep = Time.deltaTime * m_timescale; m_world_data[0].particle_size = m_particle_radius; m_world_data[0].particle_lifetime = m_lifetime; m_world_data[0].num_sphere_colliders = m_sphere_colliders.Count; m_world_data[0].num_capsule_colliders = m_capsule_colliders.Count; m_world_data[0].num_box_colliders = m_box_colliders.Count; m_world_data[0].num_forces = m_forces.Count; m_world_data[0].damping = m_damping; m_world_data[0].advection = m_advection; m_world_data[0].coord_scaler = m_coord_scaler; m_world_data[0].wall_stiffness = m_wall_stiffness; m_world_data[0].gbuffer_stiffness = m_gbuffer_stiffness; m_world_data[0].gbuffer_thickness = m_gbuffer_thickness; m_world_data[0].pressure_stiffness = m_pressure_stiffness; if (m_gbuffer_data != null) { var cam = m_gbuffer_data.GetCamera(); m_world_data[0].view_proj = m_gbuffer_data.GetMatrix_VP(); m_world_data[0].inv_view_proj = m_gbuffer_data.GetMatrix_InvVP(); m_world_data[0].rt_size = new Vector2(cam.pixelWidth, cam.pixelHeight); } m_sph_params[0].smooth_len = m_sph_smoothlen; m_sph_params[0].particle_mass = m_sph_particleMass; m_sph_params[0].pressure_stiffness = m_sph_pressureStiffness; m_sph_params[0].rest_density = m_sph_restDensity; m_sph_params[0].viscosity = m_sph_viscosity; m_buf_sphere_colliders.SetData(m_sphere_colliders.ToArray()); m_sphere_colliders.Clear(); m_buf_capsule_colliders.SetData(m_capsule_colliders.ToArray()); m_capsule_colliders.Clear(); m_buf_box_colliders.SetData(m_box_colliders.ToArray()); m_box_colliders.Clear(); m_buf_forces.SetData(m_forces.ToArray()); m_forces.Clear(); int num_cells = m_world_data[0].world_div_x * m_world_data[0].world_div_y * m_world_data[0].world_div_z; m_world_data[0].num_additional_particles = m_particles_to_add.Count; m_buf_world_data.SetData(m_world_data); MPGPWorldData csWorldData = m_world_data[0]; m_buf_sph_params.SetData(m_sph_params); // add new particles if (m_particles_to_add.Count > 0) { ComputeShader cs = m_cs_core; int kernel = kAddParticles; m_buf_particles_to_add.SetData(m_particles_to_add.ToArray()); cs.SetBuffer(kernel, "world_data", m_buf_world_data); cs.SetBuffer(kernel, "world_idata", m_buf_world_idata); cs.SetBuffer(kernel, "particles", m_buf_particles[0]); cs.SetBuffer(kernel, "particles_to_add", m_buf_particles_to_add); cs.Dispatch(kernel, m_particles_to_add.Count / BLOCK_SIZE + 1, 1, 1); m_particles_to_add.Clear(); } { // clear cells { ComputeShader cs = m_cs_hashgrid; int kernel = 0; cs.SetBuffer(kernel, "cells_rw", m_buf_cells); cs.Dispatch(kernel, num_cells / BLOCK_SIZE, 1, 1); } // generate hashes { ComputeShader cs = m_cs_hashgrid; int kernel = 1; cs.SetBuffer(kernel, "world_data", m_buf_world_data); cs.SetBuffer(kernel, "world_idata", m_buf_world_idata); cs.SetBuffer(kernel, "particles", m_buf_particles[0]); cs.SetBuffer(kernel, "sort_keys_rw", m_buf_sort_data[0]); cs.Dispatch(kernel, m_max_particles / BLOCK_SIZE, 1, 1); } // sort keys { m_bitonic_sort.BitonicSort(m_buf_sort_data[0], m_buf_sort_data[1], (uint)csWorldData.num_max_particles); } // reorder particles { ComputeShader cs = m_cs_hashgrid; int kernel = 2; cs.SetBuffer(kernel, "world_data", m_buf_world_data); cs.SetBuffer(kernel, "world_idata", m_buf_world_idata); cs.SetBuffer(kernel, "particles", m_buf_particles[0]); cs.SetBuffer(kernel, "particles_rw", m_buf_particles[1]); cs.SetBuffer(kernel, "sort_keys", m_buf_sort_data[0]); cs.SetBuffer(kernel, "cells_rw", m_buf_cells); cs.Dispatch(kernel, m_max_particles / BLOCK_SIZE, 1, 1); } // copy back { ComputeShader cs = m_cs_hashgrid; int kernel = 3; cs.SetBuffer(kernel, "particles", m_buf_particles[1]); cs.SetBuffer(kernel, "particles_rw", m_buf_particles[0]); cs.Dispatch(kernel, m_max_particles / BLOCK_SIZE, 1, 1); } } //{ // dbgSortData = new GPUSort.KIP[csWorldData.num_max_particles]; // cbSortData[0].GetData(dbgSortData); // uint prev = 0; // for (int i = 0; i < dbgSortData.Length; ++i) // { // if (prev > dbgSortData[i].key) // { // Debug.Log("sort bug: "+i); // break; // } // prev = dbgSortData[i].key; // } //} //dbgCellData = new CellData[num_cells]; //cbCells.GetData(dbgCellData); //for (int i = 0; i < num_cells; ++i ) //{ // if (dbgCellData[i].begin!=0) // { // Debug.Log("dbgCellData:" + dbgCellData[i].begin + "," + dbgCellData[i].end); // break; // } //} int num_active_blocks = m_max_particles / BLOCK_SIZE; // initialize intermediate data { ComputeShader cs = m_cs_core; int kernel = kPrepare; cs.SetBuffer(kernel, "world_data", m_buf_world_data); cs.SetBuffer(kernel, "particles", m_buf_particles[0]); cs.SetBuffer(kernel, "pimd", m_buf_imd); cs.SetBuffer(kernel, "cells", m_buf_cells); cs.Dispatch(kernel, num_active_blocks, 1, 1); } // particle interaction if (m_solver == MPGPWorld.Interaction.Impulse) { ComputeShader cs = m_cs_core; int kernel = m_dimension == MPGPWorld.Dimension.Dimendion3D ? kProcessInteraction_Impulse : kProcessInteraction_Impulse2D; cs.SetBuffer(kernel, "world_data", m_buf_world_data); cs.SetBuffer(kernel, "particles", m_buf_particles[0]); cs.SetBuffer(kernel, "pimd", m_buf_imd); cs.SetBuffer(kernel, "cells", m_buf_cells); cs.Dispatch(kernel, num_active_blocks, 1, 1); } else if (m_solver == MPGPWorld.Interaction.SPH) { ComputeShader cs = m_cs_core; int kernel = m_dimension == MPGPWorld.Dimension.Dimendion3D ? kProcessInteraction_SPH_Pass1 : kProcessInteraction_SPH_Pass12D; cs.SetBuffer(kernel, "world_data", m_buf_world_data); cs.SetBuffer(kernel, "sph_params", m_buf_sph_params); cs.SetBuffer(kernel, "particles", m_buf_particles[0]); cs.SetBuffer(kernel, "pimd", m_buf_imd); cs.SetBuffer(kernel, "cells", m_buf_cells); cs.Dispatch(kernel, num_active_blocks, 1, 1); kernel = m_dimension == MPGPWorld.Dimension.Dimendion3D ? kProcessInteraction_SPH_Pass2 : kProcessInteraction_SPH_Pass22D; cs.SetBuffer(kernel, "world_data", m_buf_world_data); cs.SetBuffer(kernel, "sph_params", m_buf_sph_params); cs.SetBuffer(kernel, "particles", m_buf_particles[0]); cs.SetBuffer(kernel, "pimd", m_buf_imd); cs.SetBuffer(kernel, "cells", m_buf_cells); cs.Dispatch(kernel, num_active_blocks, 1, 1); } else if (m_solver == MPGPWorld.Interaction.None) { // do nothing } // gbuffer collision if (m_process_gbuffer_collision && m_gbuffer_data != null) { var depth = m_gbuffer_data.GetGBuffer_Depth(); var normal = m_gbuffer_data.GetGBuffer_Normal(); if (depth != null && normal != null) { ComputeShader cs = m_cs_core; int kernel = kProcessGBufferCollision; cs.SetTexture(kernel, "gbuffer_normal", normal); cs.SetTexture(kernel, "gbuffer_depth", depth); cs.SetBuffer(kernel, "world_data", m_buf_world_data); cs.SetBuffer(kernel, "particles", m_buf_particles[0]); cs.SetBuffer(kernel, "pimd", m_buf_imd); cs.Dispatch(kernel, num_active_blocks, 1, 1); } else { m_gbuffer_data.m_enable_inv_matrices = true; m_gbuffer_data.m_enable_prev_depth = true; m_gbuffer_data.m_enable_prev_normal = true; } } // colliders if (m_process_colliders) { ComputeShader cs = m_cs_core; int kernel = kProcessColliders; cs.SetBuffer(kernel, "world_data", m_buf_world_data); cs.SetBuffer(kernel, "particles", m_buf_particles[0]); cs.SetBuffer(kernel, "pimd", m_buf_imd); cs.SetBuffer(kernel, "cells", m_buf_cells); cs.SetBuffer(kernel, "sphere_colliders", m_buf_sphere_colliders); cs.SetBuffer(kernel, "capsule_colliders", m_buf_capsule_colliders); cs.SetBuffer(kernel, "box_colliders", m_buf_box_colliders); cs.Dispatch(kernel, num_active_blocks, 1, 1); } // forces if (m_process_forces) { ComputeShader cs = m_cs_core; int kernel = kProcessForces; cs.SetBuffer(kernel, "world_data", m_buf_world_data); cs.SetBuffer(kernel, "particles", m_buf_particles[0]); cs.SetBuffer(kernel, "pimd", m_buf_imd); cs.SetBuffer(kernel, "cells", m_buf_cells); cs.SetBuffer(kernel, "forces", m_buf_forces); cs.Dispatch(kernel, num_active_blocks, 1, 1); } // integrate { ComputeShader cs = m_cs_core; int kernel = kIntegrate; cs.SetBuffer(kernel, "world_data", m_buf_world_data); cs.SetBuffer(kernel, "particles", m_buf_particles[0]); cs.SetBuffer(kernel, "pimd", m_buf_imd); cs.Dispatch(kernel, num_active_blocks, 1, 1); } }