示例#1
0
    Dictionary <int, ParticleAggregate> PartitionParticles(PhysicalParticle[] particles, Vector3 cell_size)
    {
        Dictionary <int, ParticleAggregate> spatial_hash = new Dictionary <int, ParticleAggregate>();

        for (int i = 0; i < particles.Length; i++)
        {
            PhysicalParticle p = particles[i];
            int x_ind          = Mathf.FloorToInt(p.position.x / cell_size.x);
            int y_ind          = Mathf.FloorToInt(p.position.y / cell_size.y);
            int z_ind          = Mathf.FloorToInt(p.position.z / cell_size.z);
            int hash           = x_ind * 113 + y_ind * 12769 + z_ind * 1442897;

            ParticleAggregate bucket;
            if (!spatial_hash.TryGetValue(hash, out bucket))
            {
                bucket             = new ParticleAggregate();
                spatial_hash[hash] = bucket;
            }
            bucket.particles.Add(p);
            bucket.center_of_mass += p.position * p.mass;
            bucket.total_mass     += p.mass;
        }
        foreach (KeyValuePair <int, ParticleAggregate> pair in spatial_hash)
        {
            pair.Value.center_of_mass /= pair.Value.total_mass;
        }
        return(spatial_hash);
    }
示例#2
0
    Vector3 HashingForce(Dictionary <int, ParticleAggregate> spatial_hash, ParticleAggregate curr_bucket, PhysicalParticle particle, float deltaT)
    {
        ParticleAggregate other_bucket;
        Vector3           total_force = Vector3.zero;

        foreach (KeyValuePair <int, ParticleAggregate> other_cell in spatial_hash)
        {
            other_bucket = other_cell.Value;
            if (curr_bucket == other_bucket)
            {
                continue;
            }
            Vector3 position_difference = other_bucket.center_of_mass - particle.position;
            float   distance            = position_difference.magnitude;
            if (distance < MIN_DISTANCE)
            {
                continue;
            }
            float pd_cubed = distance * distance * distance;
            total_force += other_bucket.total_mass * particle.mass / pd_cubed * position_difference;
        }
        foreach (PhysicalParticle other_particle in curr_bucket.particles)
        {
            if (other_particle == particle)
            {
                continue;
            }
            Vector3 position_difference = other_particle.position - particle.position;
            float   distance            = position_difference.magnitude;
            if (distance < MIN_DISTANCE)
            {
                continue;
            }
            float pd_cubed = distance * distance * distance;
            total_force += other_particle.mass * particle.mass / pd_cubed * position_difference;
        }
        total_force *= GRAVITATIONAL_CONSTANT;
        //Debug.Log(total_force);
        return(total_force);
    }
示例#3
0
    void hash_gravity_worker_func()
    {
        KeyValuePair <int, ParticleAggregate> curr_item;

        while (!should_stop)
        {
            if (!need_updating || (curr_spatial_hash == null && next_spatial_hash == null))
            {
                continue;
            }
            lock (hash_lock)
            {
                if (curr_spatial_hash == null)
                {
                    curr_spatial_hash = next_spatial_hash;
                    iter = curr_spatial_hash.GetEnumerator();
                }
                curr_item = iter.Current;
                if (!iter.MoveNext())
                {
                    need_updating = false;
                    if (next_spatial_hash != null)
                    {
                        curr_spatial_hash = next_spatial_hash;
                    }
                    iter = curr_spatial_hash.GetEnumerator();
                }
            }
            ParticleAggregate curr_bucket = curr_item.Value;
            if (curr_bucket == null)
            {
                continue;
            }
            foreach (PhysicalParticle particle in curr_bucket.particles)
            {
                particle.totalForce = HashingForce(curr_spatial_hash, curr_bucket, particle, this.deltaT);
                //Debug.Log("Force: " + total_force + "\t Velocity: " + particle.velocity + "\t dt: " + this.deltaT);
            }
        }
    }