Exemplo n.º 1
0
        void solveViscous()
        {
            float viscousStrength = fluidSystemDef.viscousStrength;

            for (int i = 0; i < bodyContactBuffer.Count; i++)
            {
                FluidParticleBodyContact contact = bodyContactBuffer [i];
                if ((contact.fp.flags & FluidParticleType.ViscousParticle) > 0)
                {
//				b2Vec2 v = b->GetLinearVelocityFromWorldPoint(p) -
//					m_velocityBuffer.data[a];
                    Vector2 v = contact.body.velocity - contact.fp.velocity;
                    Vector2 f = viscousStrength * contact.mass * contact.weight * v;
                    contact.fp.velocity += getParticleInvMass() * f;
//				b->ApplyLinearImpulse(-f, p, true);
                }
            }
            for (int i = 0; i < contactBuffer.Count; i++)
            {
                FluidParticleContact contact = contactBuffer [i];
                if ((contact.flags & FluidParticleType.ViscousParticle) > 0)
                {
                    Vector2 v = contact.b.velocity - contact.a.velocity;
                    Vector2 f = viscousStrength * contact.weight * v;
                    contact.a.velocity += f;
                    contact.b.velocity -= f;
                }
            }
        }
Exemplo n.º 2
0
        void solveDamping(float dt)
        {
            // reduces normal velocity of each contact
            float linearDamping    = fluidSystemDef.dampingStrength;
            float quadraticDamping = 1 / getCriticalVelocity(dt);

            for (int i = 0; i < bodyContactBuffer.Count; i++)
            {
                FluidParticleBodyContact contact = bodyContactBuffer [i];
                FluidParticle            a       = contact.fp;
                Vector2 p  = a.position;
                Vector2 v  = contact.body.velocity - a.velocity;
                float   vn = Vector2.Dot(v, contact.normal);
                if (vn < 0)
                {
                    float   damping = Mathf.Max(linearDamping * contact.weight, Mathf.Min(-quadraticDamping * vn, 0.5f));
                    Vector2 f       = damping * contact.mass * vn * contact.normal;
                    a.velocity += getParticleInvMass() * f;
                    contact.body.AddForceAtPosition(-f / dt, p);
                }
            }
            for (int i = 0; i < contactBuffer.Count; i++)
            {
                FluidParticleContact contact = contactBuffer [i];
                Vector2 v  = contact.b.velocity - contact.a.velocity;
                float   vn = Vector2.Dot(v, contact.normal);
                if (vn < 0)
                {
                    float   damping = Mathf.Max(linearDamping * contact.weight, Mathf.Min(-quadraticDamping * vn, 0.5f));
                    Vector2 f       = damping * vn * contact.normal;
                    contact.a.velocity += f;
                    contact.b.velocity -= f;
                }
            }
        }
Exemplo n.º 3
0
            public override void reportFixtureAndParticle(FluidFixtureShape fixture, FluidParticle fp)
            {
                float   d;
                Vector2 n;

                fixture.computeDistance(fp, out d, out n);
                if ((d < fluidSystem.particleDiameter) &&
                    ((fp.flags & FluidParticleType.WallParticle) == 0))
                {
                    Rigidbody2D b = fixture.GetComponent <Rigidbody2D> ();
                    //Vector2 bp = b.transform.position;
                    float bm = b.mass;

                    //				b2Vec2 bp = b->GetWorldCenter();
                    //				float32 bI =
                    //				b->GetInertia() - bm * b->GetLocalCenter().LengthSquared();
                    float invBm = bm > 0 ? 1 / bm : 0;
                    //				float32 invBI = bI > 0 ? 1 / bI : 0;
                    float invAm = (fp.flags & FluidParticleType.WallParticle) > 0 ? 0 : fluidSystem.getParticleInvMass();
                    //Vector2 rp = fp.position - bp;
                    //				float rpn = rp * n;
                    //				float32 rpn = b2Cross(rp, n);
                    //				float32 invM = invAm + invBm + invBI * rpn * rpn;
                    float invM = invAm + invBm;

                    FluidParticleBodyContact contact = new FluidParticleBodyContact
                    {
                        fp      = fp,
                        body    = b,
                        fixture = fixture,
                        weight  = 1 - d * fluidSystem.inverseDiameter,
                        normal  = -n,
                        mass    = invM > 0 ? 1 / invM : 0
                    };

                    if (fixture.isTrigger())
                    {
                        fluidSystem.triggerContactBuffer.Add(contact);
                        fixture.notifyOnTrigger(contact);
                    }
                    else
                    {
                        fluidSystem.bodyContactBuffer.Add(contact);
                    }
                    //				m_system->DetectStuckParticle(a);
                }
            }
Exemplo n.º 4
0
 public void notifyOnTrigger(FluidParticleBodyContact bodyContact)
 {
     foreach (GameObject receiver in listeners.ToArray())
     {
         MonoBehaviour[] components = receiver.GetComponents <MonoBehaviour> ();
         foreach (MonoBehaviour component in components)
         {
             if (component is IFluidFixtureTriggerListener)
             {
                 if (component.enabled)
                 {
                     IFluidFixtureTriggerListener l = component as IFluidFixtureTriggerListener;
                     l.fluidOnTrigger(bodyContact);
                 }
             }
         }
     }
 }
Exemplo n.º 5
0
 void computeWeight()
 {
     for (int i = 0; i < count; i++)
     {
         particleBuffer [i].weight = 0;
     }
     for (int i = 0; i < bodyContactBuffer.Count; i++)
     {
         FluidParticleBodyContact contact = bodyContactBuffer [i];
         contact.fp.weight += contact.weight;
     }
     for (int i = 0; i < contactBuffer.Count; i++)
     {
         FluidParticleContact contact = contactBuffer [i];
         contact.a.weight += contact.weight;
         contact.b.weight += contact.weight;
     }
 }
Exemplo n.º 6
0
        void solvePressure(float dt)
        {
            // calculates pressure as a linear function of density
            float criticalPressure  = getCriticalPressure(dt);
            float pressurePerWeight = fluidSystemDef.pressureStrength * criticalPressure;
            float maxPressure       = maxParticlePressure * criticalPressure;

            for (int i = 0; i < count; i++)
            {
                FluidParticle fp = particleBuffer [i];
                float         h  = pressurePerWeight * Mathf.Max(0f, fp.weight - minParticleWeight);
                fp.accumulation = Mathf.Min(h, maxPressure);
            }
            //		// ignores particles which have their own repulsive force
            //		if (m_allParticleFlags & k_noPressureFlags)
            //		{
            //			for (int32 i = 0; i < m_count; i++)
            //			{
            //				if (m_flagsBuffer.data[i] & k_noPressureFlags)
            //				{
            //					m_accumulationBuffer[i] = 0;
            //				}
            //			}
            //		}
            // static pressure
            if ((allParticleFlags & FluidParticleType.StaticPressureParticle) > 0)
            {
                for (int i = 0; i < count; i++)
                {
                    FluidParticle fp = particleBuffer [i];
                    if ((fp.flags & FluidParticleType.StaticPressureParticle) > 0)
                    {
                        fp.accumulation += fp.staticPressure;
                    }
                }
            }
            // applies pressure between each particles in contact
            float velocityPerPressure = dt / (fluidSystemDef.density * particleDiameter);

            for (int i = 0; i < bodyContactBuffer.Count; i++)
            {
                FluidParticleBodyContact contact = bodyContactBuffer [i];
                FluidParticle            a       = contact.fp;
                Rigidbody2D b = contact.body;
                Vector2     p = a.position;
                float       h = a.accumulation + pressurePerWeight * contact.weight;
                Vector2     f = velocityPerPressure * contact.weight * contact.mass * h * contact.normal;
                a.velocity -= getParticleInvMass() * f;
                b.AddForceAtPosition(f / dt, p);
            }

            float strength = fluidSystemDef.temperaturMixingStrength;

            for (int i = 0; i < contactBuffer.Count; i++)
            {
                FluidParticleContact contact = contactBuffer [i];
                FluidParticle        a       = contact.a;
                FluidParticle        b       = contact.b;

                float   h = a.accumulation + b.accumulation;
                Vector2 f = velocityPerPressure * contact.weight * h * contact.normal;
                a.velocity -= f;
                b.velocity += f;

                float t = (b.temperature - a.temperature) * strength;
                a.temperature += t;
                b.temperature -= t;

                if (Mathf.Abs(a.mass - b.mass) >= 0.01f)
                {
                    if (b.mass < a.mass)
                    {
                        a = contact.b;
                        b = contact.a;
                    }
                    a.velocity.y += fluidSystemDef.densityStrength;
                    b.velocity.y -= fluidSystemDef.densityStrength;
                }
                else if (Mathf.Abs(a.temperature - b.temperature) >= 0.1f)
                {
                    if (b.temperature > a.temperature)
                    {
                        a = contact.b;
                        b = contact.a;
                    }
                    a.velocity.y += fluidSystemDef.temperatureStrength;
                    b.velocity.y -= fluidSystemDef.temperatureStrength;
                }
            }
        }