ParticleSim.Update C# (CSharp) Method

Update() public method

public Update ( ) : void
return void
    void Update()
    {
        Vector3 gridOrigin = new Vector3(-0.5f *gridScale * particle_Cel_Dim, 0f, 0f);

        // reset array
           // ParticleCels = new particle_cel[Particle_Cel_Dim, Particle_Cel_Dim];
        for (int y = 0; y < particle_Cel_Dim; ++y)
        {
            for (int x = 0; x < particle_Cel_Dim; ++x)
            {
                ParticleCels[y, x].Density = 0;
                //ParticleCels[y, x].VelocityTimesDensity = Vector3.zero;

                /*
                // borders test
                if (x==0 || y==0 || x==Particle_Cel_Dim-1 || y==Particle_Cel_Dim-1)
                {
                    ParticleCels[y, x].Density = 1;
                }else{
                    ParticleCels[y, x].Density = 0;
                }*/

                /*
                // update obstacle maps test
                for (int i = 0; i < obstacles.Length; i++)
                {
                    float distance = (new Vector3(x,y,0)-(obstacles[i].position-GridOrigin)*InvGridScale).sqrMagnitude*2f;
                    if (distance>Particle_Cel_Dim) distance=Particle_Cel_Dim;
                    ParticleCels[y, x].Density += Mathf.Clamp((Particle_Cel_Dim-distance),0,Particle_Cel_Dim);
                }

                // test perlin map
                ParticleCels[y, x].Density = Mathf.PerlinNoise(2.2f+x*0.06f,2.2f+y*0.06f);
                if (ParticleCels[y, x].Density<0.4f) ParticleCels[y, x].Density=0;
                if (ParticleCels[y, x].Density>0.4f) ParticleCels[y, x].Density*=9999f;
                */

            }
        }

        // (re)spawn particle
        for (int particleSpawnIndex = 0; particleSpawnIndex < spawnRate; ++particleSpawnIndex)
        {
            NextParticle=(NextParticle+1) % particlesAmount;

            // set initial values
            particles[NextParticle].P = transform.position+new Vector3(Random.Range(-0.05f, 0.05f), Random.Range(-0.05f, 0.05f), 0); // start position
        //			particles[NextParticle].dP = new Vector3(Random.Range(-0.07f,0.07f),0.85f,0)*7; // start speed, global direction
            particles[NextParticle].dP = transform.TransformDirection(new Vector3(Random.Range(-0.01f,0.01f),7f*Random.Range(0.98f,1f),0f)); // start speed in local transform direction
            particles[NextParticle].ddP = new Vector3(0f, -9.81f, 0f); // gravity
            particles[NextParticle].Col = initialColor;
            float randomVal = Random.Range(-0.25f, -1f);
            particles[NextParticle].dColor = new Vector4(0,0,0,randomVal); // deltaColor

            sprites[NextParticle].transform.position = Vector3.zero;
            sprites[NextParticle].transform.localScale = Vector3.one;
        }

        // map particles to grid & add cell density
        for (int particleIndex = 0; particleIndex < particles.Length; ++particleIndex)
        {
            Vector3 P = InvGridScale * (particles[particleIndex].P - gridOrigin);

            int X = (int)P.x;
            int Y = (int)P.y;

            if (X < 0) X = 0;
            if (X > particle_Cel_Dim-1) X = particle_Cel_Dim-1;
            if (Y < 0) Y = 0;
            if (Y > particle_Cel_Dim - 1) Y = particle_Cel_Dim - 1;

            float densityFromAlpha = particles[particleIndex].Col.w;

            ParticleCels[Y, X].Density += densityFromAlpha;
            ParticleCels[Y, X].VelocityTimesDensity += densityFromAlpha*particles[particleIndex].dP;
        }

        if (debugMode)
        {
            // draw preview grid
            for (int y = 0; y < particle_Cel_Dim; ++y)
            {
                for (int x = 0; x < particle_Cel_Dim; ++x)
                {

                    float alpha = Clamp01(0.1f*ParticleCels[y, x].Density);
                    Color cellColor = new Color(alpha,alpha,alpha,1);

                    Vector3 gridPos = gridScale*new Vector3(x, y, 0f) + gridOrigin;

                    Debug.DrawLine(gridPos,gridPos+new Vector3(1,0,0)*gridScale,cellColor);
                    Debug.DrawLine(gridPos, gridPos + new Vector3(0, 1, 0)*gridScale, cellColor);
                }
            }
        }

        // simulate
        for (int particleIndex = 0; particleIndex < particles.Length; ++particleIndex)
        {
            // snap to grid
            Vector3 P = InvGridScale * (particles[particleIndex].P - gridOrigin);
            int X = (int)P.x;
            int Y = (int)P.y;

            // clamp to edges
            if (X < 1) X = 1;
            if (X > particle_Cel_Dim-2) X = particle_Cel_Dim-2;
            if (Y < 1) Y = 1;
            if (Y > particle_Cel_Dim - 2) Y = particle_Cel_Dim - 2;

            // get neighbour cell values
            float celCenterDensity = ParticleCels[Y, X].Density;
            float celLeftDensity = ParticleCels[Y, X-1].Density;
            float celRightDensity = ParticleCels[Y, X+1].Density;
            float celDownDensity = ParticleCels[Y-1, X].Density;
            float celUpDensity = ParticleCels[Y+1, X].Density;

            // calculate direction from cell density
            Vector3 dispersion = Vector3.zero;
            float dispersionCoeffifient = 0.5f; // multiplier of pushing force

            /* original dispersion
            dispersion += dispersionCoeffifient*(celCenterDensity-celLeftDensity)*new Vector3(-1f,0f,0f);
            dispersion += dispersionCoeffifient*(celCenterDensity-celRightDensity)*new Vector3(1f,0f,0f);
            dispersion += dispersionCoeffifient*(celCenterDensity-celDownDensity)*new Vector3(0f,-1f,0f);
            dispersion += dispersionCoeffifient*(celCenterDensity-celUpDensity)*new Vector3(0f,1f,0f);
            */

            // check which side the particle is more (left or right from particle system x)
            float centerDistanceX = (particles[particleIndex].P.x-transform.position.x);
            dispersion += dispersionCoeffifient*(celCenterDensity-celLeftDensity)*new Vector3(-1f+centerDistanceX,0f,0f);
            dispersion += dispersionCoeffifient*(celCenterDensity-celRightDensity)*new Vector3(1f+centerDistanceX,0f,0f);
            dispersion += dispersionCoeffifient*(celCenterDensity-celDownDensity)*new Vector3(0f,-1f,0f);
            dispersion += dispersionCoeffifient*(celCenterDensity-celUpDensity)*new Vector3(0f,1f,0f);

            Vector3 ddP = particles[particleIndex].ddP+(enableDispersion?dispersion:Vector3.zero);

            // debug test
        //			if (particleIndex<1) Debug.Log(particles[particleIndex].dP);

            // calculate movement & color
            particles[particleIndex].P += (0.5f*Mathf.Sqrt(Time.deltaTime)*Time.deltaTime*ddP + Time.deltaTime*particles[particleIndex].dP);
            particles[particleIndex].dP += Time.deltaTime*ddP;
            particles[particleIndex].Col += Time.deltaTime*particles[particleIndex].dColor;

            // ground collision & bounce
            if (groundPlaneCollision && particles[particleIndex].P.y<groundY)
            {
                float coefficientOfRestitution = 0.3f;
                float coefficientOfFriction = 0.7f;
                particles[particleIndex].P.y = -particles[particleIndex].P.y;
                particles[particleIndex].dP.y = -coefficientOfRestitution*particles[particleIndex].dP.y;
                particles[particleIndex].dP.x = coefficientOfFriction*particles[particleIndex].dP.x;
            }

            /*
            // TEST max speed clamp
            if (particles[ParticleIndex].dP.sqrMagnitude>maxSpeed)
            {
                particles[ParticleIndex].dP = particles[ParticleIndex].dP.normalized*maxSpeed;
            }*/

            // clamp colors
            particles[particleIndex].Col.x = Clamp01(particles[particleIndex].Col.x);
            particles[particleIndex].Col.y = Clamp01(particles[particleIndex].Col.y);
            particles[particleIndex].Col.z = Clamp01(particles[particleIndex].Col.z);
            particles[particleIndex].Col.w = Clamp01(particles[particleIndex].Col.w);

            // fix particle sudden spawn by making it transparent first, not working smoothly
            if (particles[particleIndex].Col.w>0.9f)
            {
                particles[particleIndex].Col.w = 0.9f*Clamp01MapToRange(1f,(particles[particleIndex].Col.w),0.9f);
            }

            // set position, color, scale
            sprites[particleIndex].transform.position = particles[particleIndex].P;
            sprites[particleIndex].color = (Color)particles[particleIndex].Col;
            var scaler = particles[particleIndex].Col.w;
            sprites[particleIndex].transform.localScale = new Vector3(scaler, scaler, scaler)*0.75f; // scale test
        }
    }