// Emit will return a particle list, which will be rendered
    public void updateParticles(float dt)
    {
        int currentEmission = 0;

        currentTimeEmission += dt;

        // add particle
        // if current number of particle is lower than total we can add particles
        // since we work on emissions per second, one second need to past after timeLastEmission
        if (particleCount < totalParticles && currentTimeEmission > emissionRateSec)
        {
            while (currentEmission < emitsPerRate)
            {
                particles[particleCount] = new SandParticle(pos + new Vector3(Random.Range(-1.0f, 1.0f) * posVar.x, Random.Range(-1.0f, 1.0f) * posVar.y, Random.Range(-1.0f, 1.0f) * posVar.z),
                                                            20 * fromRotationToDirection(yaw + Random.Range(-1.0f, 1.0f) * yawVar, pitch + Random.Range(-1.0f, 1.0f) * pitchVar));
                ++currentEmission;
                ++particleCount;
            }
            currentTimeEmission = 0;
        }

        // update particles
        for (int i = 0; i < particleCount; i++)
        {
            particles[i].updateParticle(dt, particles, particleCount);
        }
    }
Example #2
0
    public void updateParticle(float dt, SandParticle[] otherParticles, int aliveParticles) {
        // Update forces
        if (applyForce) {
            Fl = forceHit;
            applyForce = false;
        } else {
            Fl.Set(0, 0, 0);
        }

        // Integrate Velocities (Runge Kutta)
        a = evaluate(position, linearMomentum, angMomentum, 0, new Derivative());
        b = evaluate(position, linearMomentum, angMomentum, dt * 0.5f, a);
        c = evaluate(position, linearMomentum, angMomentum, dt * 0.5f, b);
        d = evaluate(position, linearMomentum, angMomentum, dt, c);

        position = position + ((1.0f / 6.0f) * (a.dx + 2.0f * (b.dx + c.dx) + d.dx)) * dt;
        rotation = addQuaToQua(rotation, multiplyQuaByScalar((angVelocityQua * rotation), 0.5f * dt));

        // collision and stuff        
        collision(dt, otherParticles, aliveParticles);

        // Momentum
        linearMomentum = linearMomentum + ((1.0f / 6.0f) * (a.dm + 2.0f * (b.dm + c.dm) + d.dm)) * dt;
        //if (linearMomentum.magnitude < 0.001)
            //linearMomentum.Set(0, 0, 0);

        angMomentum = angMomentum + ((1.0f / 6.0f) * (a.dam + 2.0f * (b.dam + c.dam) + d.dam)) * dt;
        //if (angMomentum.magnitude < 0.001)
            //angMomentum.Set(0, 0, 0);        

        // Velocity
        linearVelocity = linearMomentum / mass;
        angVelocity = Vector3.Scale(new Vector3(1.0f / inertiaTensor.x, 1.0f / inertiaTensor.y, 1.0f / inertiaTensor.z), angMomentum);
        angVelocityQua = new Quaternion(angVelocity.x, angVelocity.y, angVelocity.z, 0);

        // Natural Roll ?
        naturalRoll = (Mathf.Abs(linearVelocity.magnitude - (radius * angVelocity.magnitude)) < 0.1);
    }
Example #3
0
    // Emit will return a particle list, which will be rendered
    public void updateParticles(float dt) {
        int currentEmission = 0;
        currentTimeEmission += dt;

        // add particle
        // if current number of particle is lower than total we can add particles
        // since we work on emissions per second, one second need to past after timeLastEmission
        if (particleCount < totalParticles && currentTimeEmission > emissionRateSec) {
            while (currentEmission < emitsPerRate)
            {
                particles[particleCount] = new SandParticle(pos + new Vector3(Random.Range(-1.0f, 1.0f) * posVar.x, Random.Range(-1.0f, 1.0f) * posVar.y, Random.Range(-1.0f, 1.0f) * posVar.z),
                                                            20 * fromRotationToDirection(yaw + Random.Range(-1.0f, 1.0f) * yawVar, pitch + Random.Range(-1.0f, 1.0f) * pitchVar));
                ++currentEmission;
                ++particleCount;
            }
            currentTimeEmission = 0;
        }
        
        // update particles
        for (int i = 0; i < particleCount; i++) {
                particles[i].updateParticle(dt, particles, particleCount);
        }
    }
Example #4
0
    void collision(float dt, SandParticle[] otherParticles, int aliveParticles)
    {
        Vector3 pos;
        float distance;

        float kn = 0.1f;
        float ys = 0.3f;
        float u = 0.05f;
        float ks = 20;

        penaltyFl.Set(0, 0, 0);
        penaltyFt.Set(0, 0, 0);

        //floorCollision = (transform.position.y <= 0.5);
        if (transform.position.y <= radius)
        {
            distance = Vector3.Distance(new Vector3(transform.position.x, 0, transform.position.z), transform.position);
            Vector3 N = Vector3.Normalize(new Vector3(transform.position.x, 0, transform.position.z) - transform.position);
            Vector3 relativeVelocity = linearVelocity;

            float e = radius - distance;
            float ep = Vector3.Dot(relativeVelocity, N);

            Vector3 Fn = -(60 * Mathf.Pow(e, 3 / 2) + 40 * ep * Mathf.Pow(e, 1 / 2)) * N;

            penaltyFl += Fn;
        }
        
        for (int i = 0; i < aliveParticles; ++i)
        {
            pos = otherParticles[i].position;
            distance = Vector3.Distance(pos, transform.position);

            if (distance <= radius + 0.5f)
            {
                Vector3 N = Vector3.Normalize(pos - transform.position);
                Vector3 relativeVelocity = linearVelocity - otherParticles[i].linearVelocity;

                float e = (radius + 0.5f) - distance;
                float ep = Vector3.Dot(relativeVelocity, N);
                Vector3 tangentialVelocity = relativeVelocity - ep * N;

                Vector3 Fn = -(kn * Mathf.Pow(e, 3 / 2) + ys * ep * Mathf.Pow(e, 1 / 2)) * N;
                Vector3 Ft = -Mathf.Min(u * Fn.magnitude, ks * tangentialVelocity.magnitude) * Vector3.Cross(N / 2, tangentialVelocity).normalized;

                penaltyFl += Fn; //-(kn * Mathf.Pow(e, 3 / 2) - ys * penetrationRate1 * Mathf.Pow(e, 1 / 2)) * N;
                penaltyFt += Ft; // 0.3f * Vector3.Cross(new Vector3(0, -0.5f, 0), N / 2);
            }
        }
    }
Example #5
0
    void collision(float dt, SandParticle[] otherParticles, int aliveParticles) {
        Vector3 pos;
        float distance;

        float kn = 60;
        float ys = 3;
        float u = 0.05f;
        float ks = 20;

        penaltyFl.Set(0, 0, 0);
        penaltyFt.Set(0, 0, 0);

        //floorCollision = (transform.position.y <= 0.5);
        if (position.y <= radius)
        {
            distance = Vector3.Distance(new Vector3(position.x, 0, position.z), position);
            Vector3 N = Vector3.Normalize(new Vector3(position.x, 0, position.z) - position);
            Vector3 relativeVelocity = linearVelocity;

            float e = 0.5f - distance;
            float ep = Vector3.Dot(relativeVelocity, N);

            Vector3 Fn = -(40 * Mathf.Pow(e, 3 / 2) + 10 * ep * Mathf.Pow(e, 1 / 2)) * N;

            penaltyFl += Fn;
        }

        // walls
        pos = GameObject.Find("Wall1").transform.position;
        distance = Vector3.Distance(new Vector3(pos.x, position.y, position.z), position);
        if (distance <= 1)
        {
            Vector3 N = Vector3.Normalize(new Vector3(pos.x, position.y, position.z) - position);
            Vector3 relativeVelocity = linearVelocity;

            float e = 1 - distance;
            float ep = Vector3.Dot(relativeVelocity, N);

            Vector3 Fn = -(50 * Mathf.Pow(e, 3 / 2) + 40 * ep * Mathf.Pow(e, 1 / 2)) * N;

            penaltyFl += Fn;
        }

        pos = GameObject.Find("Wall2").transform.position;
        distance = Vector3.Distance(new Vector3(pos.x, position.y, position.z), position);
        if (distance <= 1)
        {
            Vector3 N = Vector3.Normalize(new Vector3(pos.x, position.y, position.z) - position);
            Vector3 relativeVelocity = linearVelocity;

            float e = 1 - distance;
            float ep = Vector3.Dot(relativeVelocity, N);

            Vector3 Fn = -(50 * Mathf.Pow(e, 3 / 2) + 40 * ep * Mathf.Pow(e, 1 / 2)) * N;

            penaltyFl += Fn;
        }

        pos = GameObject.Find("Wall3").transform.position;
        distance = Vector3.Distance(new Vector3(position.x, position.y, pos.z), position);
        if (distance <= 1)
        {
            Vector3 N = Vector3.Normalize(new Vector3(position.x, position.y, pos.z) - position);
            Vector3 relativeVelocity = linearVelocity;

            float e = 1 - distance;
            float ep = Vector3.Dot(relativeVelocity, N);

            Vector3 Fn = -(50 * Mathf.Pow(e, 3 / 2) + 40 * ep * Mathf.Pow(e, 1 / 2)) * N;

            penaltyFl += Fn;
        }

        pos = GameObject.Find("Wall4").transform.position;
        distance = Vector3.Distance(new Vector3(position.x, position.y, pos.z), position);
        if (distance <= 1)
        {
            Vector3 N = Vector3.Normalize(new Vector3(position.x, position.y, pos.z) - position);
            Vector3 relativeVelocity = linearVelocity;

            float e = 1 - distance;
            float ep = Vector3.Dot(relativeVelocity, N);

            Vector3 Fn = -(50 * Mathf.Pow(e, 3 / 2) + 40 * ep * Mathf.Pow(e, 1 / 2)) * N;

            penaltyFl += Fn;
        }

        //obj collisions
        pos = GameObject.Find("Obj1").transform.position;
        distance = Vector3.Distance(pos, position);
        if (distance <= 8) {
            Vector3 N = Vector3.Normalize(pos - position);
            Vector3 relativeVelocity = linearVelocity;

            float e = 8 - distance;
            float ep = Vector3.Dot(relativeVelocity, N);
            Vector3 tangentialVelocity = relativeVelocity - ep * N;

            Vector3 Fn = -(50 * Mathf.Pow(e, 3 / 2) + 30 * ep * Mathf.Pow(e, 1 / 2)) * N;
            Fn += 0.7f * Vector3.Normalize(linearVelocity);//Add some value to affect the friction
            Vector3 Ft = -Mathf.Min(0.5f * Fn.magnitude, 100 * tangentialVelocity.magnitude) * Vector3.Cross(N / 2, tangentialVelocity).normalized;

            penaltyFl += Fn; //-(kn * Mathf.Pow(e, 3 / 2) - ys * penetrationRate1 * Mathf.Pow(e, 1 / 2)) * N;
            penaltyFt += Ft; // 0.3f * Vector3.Cross(new Vector3(0, -0.5f, 0), N / 2);
        }

        pos = GameObject.Find("Obj2").transform.position;
        distance = Vector3.Distance(pos, position);
        if (distance <= 5.5f)
        {
            Vector3 N = Vector3.Normalize(pos - position);
            Vector3 relativeVelocity = linearVelocity;

            float e = 5.5f - distance;
            float ep = Vector3.Dot(relativeVelocity, N);
            Vector3 tangentialVelocity = relativeVelocity - ep * N;

            Vector3 Fn = -(50 * Mathf.Pow(e, 3 / 2) + 30 * ep * Mathf.Pow(e, 1 / 2)) * N;
            Fn += 0.7f * Vector3.Normalize(linearVelocity);//Add some value to affect the friction
            Vector3 Ft = -Mathf.Min(0.5f * Fn.magnitude, 100 * tangentialVelocity.magnitude) * Vector3.Cross(N / 2, tangentialVelocity).normalized;

            penaltyFl += Fn; //-(kn * Mathf.Pow(e, 3 / 2) - ys * penetrationRate1 * Mathf.Pow(e, 1 / 2)) * N;
            penaltyFt += Ft; // 0.3f * Vector3.Cross(new Vector3(0, -0.5f, 0), N / 2);
        }

        pos = GameObject.Find("Obj3").transform.position;
        distance = Vector3.Distance(pos, position);
        if (distance <= 4.5f)
        {
            Vector3 N = Vector3.Normalize(pos - position);
            Vector3 relativeVelocity = linearVelocity;

            float e = 4.5f - distance;
            float ep = Vector3.Dot(relativeVelocity, N);
            Vector3 tangentialVelocity = relativeVelocity - ep * N;

            Vector3 Fn = -(50 * Mathf.Pow(e, 3 / 2) + 30 * ep * Mathf.Pow(e, 1 / 2)) * N;
            Fn += 0.7f * Vector3.Normalize(linearVelocity);//Add some value to affect the friction
            Vector3 Ft = -Mathf.Min(0.5f * Fn.magnitude, 100 * tangentialVelocity.magnitude) * Vector3.Cross(N / 2, tangentialVelocity).normalized;

            penaltyFl += Fn; //-(kn * Mathf.Pow(e, 3 / 2) - ys * penetrationRate1 * Mathf.Pow(e, 1 / 2)) * N;
            penaltyFt += Ft; // 0.3f * Vector3.Cross(new Vector3(0, -0.5f, 0), N / 2);
        }

        // Sphere
        pos = GameObject.Find("Sphere").transform.position;
        distance = Vector3.Distance(pos, position);

        if (distance <= radius + 5 )
        {
            Vector3 N = Vector3.Normalize(pos - position);
            Vector3 relativeVelocity = linearVelocity - GameObject.Find("Sphere").GetComponent<MetalSphere>().linearVelocity;

            float e = (radius + 5) - distance;
            float ep = Vector3.Dot(relativeVelocity, N);
            Vector3 tangentialVelocity = relativeVelocity - ep * N;

            Vector3 Fn = -(60 * Mathf.Pow(e, 3 / 2) + 60 * ep * Mathf.Pow(e, 1 / 2)) * N;
            Vector3 Ft = -Mathf.Min(u * Fn.magnitude, ks * tangentialVelocity.magnitude) * Vector3.Cross(N / 2, tangentialVelocity).normalized;

            penaltyFl += Fn; //-(kn * Mathf.Pow(e, 3 / 2) - ys * penetrationRate1 * Mathf.Pow(e, 1 / 2)) * N;
            penaltyFt += Ft; // 0.3f * Vector3.Cross(new Vector3(0, -0.5f, 0), N / 2);
        }

        // sphere objs
        for (int i = 1; i < 81; ++i)
        {
            pos = GameObject.Find("Sphere (" + i + ")").transform.position;
            distance = Vector3.Distance(pos, position);

            if (distance <= 2 * radius && distance != 0)
            {
                Vector3 N = Vector3.Normalize(pos - position);
                Vector3 relativeVelocity = linearVelocity;

                float e = 1 - distance;
                float ep = Vector3.Dot(relativeVelocity, N);
                Vector3 tangentialVelocity = relativeVelocity - ep * N;

                Vector3 Fn = -(60 * Mathf.Pow(e, 3 / 2) + 40 * ep * Mathf.Pow(e, 1 / 2)) * N;
                Vector3 Ft = -Mathf.Min(u * Fn.magnitude, ks * tangentialVelocity.magnitude) * Vector3.Cross(N / 2, tangentialVelocity).normalized;

                penaltyFl += Fn; //-(kn * Mathf.Pow(e, 3 / 2) - ys * penetrationRate1 * Mathf.Pow(e, 1 / 2)) * N;
                penaltyFt += Ft; // 0.3f * Vector3.Cross(new Vector3(0, -0.5f, 0), N / 2);
            }
        }

        for (int i = 0; i < aliveParticles; ++i)
        {
            pos = otherParticles[i].position;
            distance = Vector3.Distance(pos, position);

            if (distance <= 2*radius && distance != 0)
            {
                Vector3 N = Vector3.Normalize(pos - position);
                Vector3 relativeVelocity = linearVelocity - otherParticles[i].linearVelocity;

                float e = 1 - distance;
                float ep = Vector3.Dot(relativeVelocity, N);
                Vector3 tangentialVelocity = relativeVelocity - ep * N;

                Vector3 Fn = -(kn * Mathf.Pow(e, 3 / 2) + ys * ep * Mathf.Pow(e, 1 / 2)) * N;
                Vector3 Ft = -Mathf.Min(u * Fn.magnitude, ks * tangentialVelocity.magnitude) * Vector3.Cross(N / 2, tangentialVelocity).normalized;

                penaltyFl += Fn; //-(kn * Mathf.Pow(e, 3 / 2) - ys * penetrationRate1 * Mathf.Pow(e, 1 / 2)) * N;
                penaltyFt += Ft; // 0.3f * Vector3.Cross(new Vector3(0, -0.5f, 0), N / 2);
            }
        }
    }