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;
             }
         }
     }
 }
示例#2
0
 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]);
                 }
             }
         }
     }
 }
示例#3
0
    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);
        }
    }