Пример #1
0
        public void Draw(Graphics g)
        {
            foreach (ParticleGroup x in particle_groups)
            {
                x.Draw(g);

                if (draw_aabb)
                {
                    AABBox a = x.aabb();
                    g.DrawRectangle(Pens.BurlyWood, (float)a.x1, (float)a.y1, (float)(a.x2 - a.x1), (float)(a.y2 - a.y1));
                }
            }

            g.DrawLine(Pens.Black, 0, (float)limit_Y, g.VisibleClipBounds.Width, (float)limit_Y);
        }
Пример #2
0
        public void Update()
        {
            system_step = (system_step + 1) % system_step_mod;

            if (autospawn && (system_step % particle_spawn_mod == 1))
            {
                Spawn(spring_size);
            }

            // 1: Remove old particles
            List <ParticleGroup> to_remove = new List <ParticleGroup>();

            foreach (ParticleGroup x in particle_groups)
            {
                if (Math.Abs((System_step - x.born) % system_step_mod) > lifetime)
                {
                    to_remove.Add(x);
                }
            }

            foreach (ParticleGroup x in to_remove)
            {
                particle_groups.Remove(x);
            }

            for (int ti = 0; (ti < 1) || (normal_time && (ti) * dt < (presentation_interval / 1000.0)); ti++)     //normalize for human time
            //3: external forces
            {
                foreach (ParticleGroup x in particle_groups)
                {
                    foreach (Particle p in x.particles)
                    {
                        p.velocity += dt * g_acceleration;
                    }
                }

                //4: damp velocities
                foreach (ParticleGroup x in particle_groups)
                {
                    foreach (Particle p in x.particles)
                    {
                        //p.velocity += kd * x.velocity +  - p.velocity;
                        p.velocity = kd * p.velocity;
                    }
                }

                //5: predict positions (simple explicit euler)
                foreach (ParticleGroup x in particle_groups)
                {
                    foreach (Particle p in x.particles)
                    {
                        p.q = p.position + dt * p.velocity;
                    }
                }

                List <CollisionPair> collisions = new List <CollisionPair>();
                //6: detect and construct collision constraints
                if (compute_collisions)
                {
                    foreach (ParticleGroup pg1 in particle_groups)
                    {
                        AABBox aabb = pg1.aabb();
                        foreach (ParticleGroup pg2 in particle_groups)
                        {
                            if (pg1 != pg2)
                            {
                                foreach (Particle p in pg2.particles)
                                {
                                    if (aabb.is_inside(p.q))
                                    {
                                        collisions.Add(new CollisionPair(p, pg1));
                                    }
                                }
                            }
                        }
                    }
                }


                //7: apply "projection" several times on all constraints
                for (int i = 0; i < ns; i++)
                {
                    foreach (ParticleGroup x in particle_groups)
                    {
                        // DistanceConstraints of springs
                        x.ProjectDistanceConstraints(in_k);
                        x.ProjectFloorConstraints(limit_X, limit_Y, in_k);
                    }

                    if (compute_collisions)
                    {
                        foreach (CollisionPair c in collisions)
                        {
                            c.pg.ProjectCollisionConstraint(c.p);
                        }
                    }
                }


                //8: find correct velocities
                foreach (ParticleGroup x in particle_groups)
                {
                    foreach (Particle p in x.particles)
                    {
                        p.velocity = (1.0 / dt) * (p.q - p.position);
                        p.position = p.q;
                    }
                }

                //9: apply friction and resistution impulses on velocities
                //no friction or resistution is needed
            }
        }