Exemplo n.º 1
0
    void ComputeForce()
    {
        for (int i = 0; i < count; i++)
        {
            float2 fpress = 0;
            float2 fvisc  = 0;

            WaterParticle2D pi = particles[i];
            for (int j = 0; j < count; j++)
            {
                WaterParticle2D pj = particles[j];
                if (i == j)
                {
                    continue;
                }

                float2 rij = pj.x - pi.x;
                float  r   = math.length(rij);
                if (r < H)
                {
                    fpress += -math.normalize(rij) * MASS * (pi.p + pj.p) / (2f * pj.rho) * SPIKY_GRAD * math.pow(H - r, 2);
                    fvisc  += VISC * MASS * (pj.v - pi.v) / pj.rho * VISC_LAP * (H - r);
                }
            }

            float2 fgrav = G * pi.rho;
            pi.f         = fpress + fvisc + fgrav;
            particles[i] = pi;
        }
    }
Exemplo n.º 2
0
    void Integrate()
    {
        for (int i = 0; i < count; i++)
        {
            WaterParticle2D p = particles[i];
            p.v += Time.deltaTime * p.f / p.rho;
            p.x += Time.deltaTime * p.v;

            if (p.x.x - EPS < 0.0f)
            {
                p.v.x *= BOUND_DAMPING;
                p.x.x  = EPS;
            }
            if (p.x.x + EPS > VIEW_WIDTH)
            {
                p.v.x *= BOUND_DAMPING;
                p.x.x  = VIEW_WIDTH - EPS;
            }
            if (p.x.y - EPS < 0.0f)
            {
                p.v.y *= BOUND_DAMPING;
                p.x.y  = EPS;
            }
            if (p.x.y + EPS > VIEW_HEIGHT)
            {
                p.v.y *= BOUND_DAMPING;
                p.x.y  = VIEW_HEIGHT - EPS;
            }
            particles[i] = p;
        }
    }
Exemplo n.º 3
0
        public void Execute(int index)
        {
            float2 forcePressure  = 0;
            float2 forceViscosity = 0;

            WaterParticle2D pi = particles[index];

            for (int i = 0; i < cellOffset.Length; i++)
            {
                float2 position    = pi.position + (float2)cellOffset[i] * particleRadius;
                int    bucketIndex = GridHashUtilities.Hash(position, particleRadius);

                NativeMultiHashMapIterator <int> iterator;
                bool hasValue = hashMap.TryGetFirstValue(bucketIndex, out int j, out iterator);

                while (hasValue)
                {
                    if (index == j)
                    {
                        hasValue = hashMap.TryGetNextValue(out j, ref iterator);
                        continue;
                    }

                    WaterParticle2D pj   = readOnlyParticles[j]; // particles[j];
                    float2          diff = pj.position - pi.position;

                    float distanceSquared = math.lengthsq(diff);
                    if (distanceSquared < particleRadiusSquared)
                    {
                        float  distance      = math.sqrt(distanceSquared);
                        float  radiusRatio   = particleRadius - distance;
                        float2 normalizedDir = diff / distance;

                        forcePressure  += -normalizedDir * MASS * (pi.pressure + pj.pressure) / (2f * pj.density) * SPIKY_GRAD * radiusRatio * radiusRatio;
                        forceViscosity += VISC * MASS * (pj.velocity - pi.velocity) / pj.density * VISC_LAP * (particleRadius - distance);
                    }
                    hasValue = hashMap.TryGetNextValue(out j, ref iterator);
                }
            }

            float2 forceFravity = GRAVITY * pi.density;

            pi.force         = forcePressure + forceViscosity + forceFravity;
            particles[index] = pi;
        }
Exemplo n.º 4
0
 void ComputeDensityPressure()
 {
     for (int i = 0; i < count; i++)
     {
         WaterParticle2D pi = particles[i];
         pi.rho = 0;
         for (int j = 0; j < count; j++)
         {
             WaterParticle2D pj  = particles[j];
             float2          rij = pj.x - pi.x;
             float           r2  = math.lengthsq(rij);
             if (r2 < HSQ)
             {
                 pi.rho += MASS * POLY6 * math.pow(HSQ - r2, 3);
             }
         }
         //pi.p = GAS_CONST2 * (math.pow(pi.rho / REST_DENS, 7) - 1);
         pi.p         = GAS_CONST * (pi.rho - REST_DENS);
         particles[i] = pi;
     }
 }
Exemplo n.º 5
0
        public void Execute(int index)
        {
            WaterParticle2D pi = particles[index];

            pi.density = 0;

            for (int i = 0; i < cellOffset.Length; i++)
            {
                float2 position    = pi.position + (float2)cellOffset[i] * particleRadius;
                int    bucketIndex = GridHashUtilities.Hash(position, particleRadius);

                NativeMultiHashMapIterator <int> iterator;
                bool hasValue = hashMap.TryGetFirstValue(bucketIndex, out int j, out iterator);

                while (hasValue)
                {
                    WaterParticle2D pj = readOnlyParticles[j]; // particles[j];

                    float2 diff       = pj.position - pi.position;
                    float  distanceSq = math.lengthsq(diff);
                    if (distanceSq < particleRadiusSquared)
                    {
                        float ratio = particleRadius - math.sqrt(distanceSq);
                        pi.density += MASS * POLY6 * ratio * ratio * ratio;

                        //float squaredRatio = particleRadiusSquared - distanceSq;
                        //pi.density += MASS * POLY6 * squaredRatio * squaredRatio * squaredRatio;
                    }

                    hasValue = hashMap.TryGetNextValue(out j, ref iterator);
                }
            }

            pi.pressure      = GAS_CONST * (pi.density - REST_DENS);
            particles[index] = pi;
        }
Exemplo n.º 6
0
        public void Execute(int i)
        {
            WaterParticle2D p = particles[i];

            p.velocity += deltaTime * p.force / p.density;

            float2 previousPosition = p.position;
            int2   prevPos          = GridHashUtilities.Quantize(p.position, collisionScale);
            float2 step             = deltaTime * p.velocity;

            p.position += step;

            float velocityMagnitude = math.length(p.velocity);

            if (velocityMagnitude < math.FLT_MIN_NORMAL)
            {
                particles[i] = p;

                return;
            }

            float2 radiusEdgePosition = p.position + (p.velocity / velocityMagnitude) * particleRadius;

            //find grid position
            int2 newPos = GridHashUtilities.Quantize(radiusEdgePosition, collisionScale);

            if (newPos.x < 0 ||  newPos.x >= sizeArray || newPos.y < 0 || newPos.y >= sizeArray)
            {
                //out of bound
                return;
            }


            bool movedInSameGrid = prevPos.x == newPos.x &&
                                   prevPos.y == newPos.y;
            bool hasCollision = colArray[newPos.y * sizeArray + newPos.x] == 1;

            if (!movedInSameGrid && hasCollision)
            {
                //left collision
                if (prevPos.x > newPos.x)
                {
                    p.velocity.x *= BOUND_DAMPING;
                    p.position.x  = (prevPos.x * collisionScale) + particleRadius;
                }
                //right collision
                else if (prevPos.x < newPos.x)
                {
                    p.velocity.x *= BOUND_DAMPING;
                    p.position.x  = (newPos.x * collisionScale) - particleRadius;
                }

                //bottom collision
                if (prevPos.y > newPos.y)
                {
                    p.velocity.y *= BOUND_DAMPING;
                    p.position.y  = (prevPos.y * collisionScale) + particleRadius;
                }
                //up collision
                else if (prevPos.y < newPos.y)
                {
                    p.velocity.y *= BOUND_DAMPING;
                    p.position.y  = (newPos.y * collisionScale) - particleRadius;
                }
            }

            //test if have collision

            //reflect velocity on normal?

            //replace position


            //if (p.position.x - particleRadius < -VIEW_WIDTH)
            //{
            //    p.velocity.x *= BOUND_DAMPING;
            //    p.position.x = -VIEW_WIDTH + particleRadius;
            //}
            //if (p.position.x + particleRadius > VIEW_WIDTH)
            //{
            //    p.velocity.x *= BOUND_DAMPING;
            //    p.position.x = VIEW_WIDTH - particleRadius;
            //}
            //if (p.position.y - particleRadius < -VIEW_HEIGHT)
            //{
            //    p.velocity.y *= BOUND_DAMPING;
            //    p.position.y = -VIEW_HEIGHT + particleRadius;
            //}
            //if (p.position.y + particleRadius > VIEW_HEIGHT)
            //{
            //    p.velocity.y *= BOUND_DAMPING;
            //    p.position.y = VIEW_HEIGHT - particleRadius;
            //}
            particles[i] = p;
        }