예제 #1
0
    // Update is called once per frame
    void Update()
    {
        Debug.DrawLine(new Vector3(0, 0), new Vector3(x, 0));
        Debug.DrawLine(new Vector3(0, 0), new Vector3(0, y));
        Debug.DrawLine(new Vector3(x, 0), new Vector3(x, y));
        Debug.DrawLine(new Vector3(0, y), new Vector3(x, y));

        // Spatial hashing
        SpatialHash2D sh2d = new SpatialHash2D(x, y, h);

        foreach (Point point in listPoint)
        {
            sh2d.Insert(point);
        }

        PVFS(listPoint, sh2d, g, Y, x, y, k, knear, pnear, h, r0, foutside);
    }
예제 #2
0
    public static void PVFS(List <Point> listPoint, SpatialHash2D sh2d, float g, Vector3 Y, float boundaryX, float boundaryY, float k, float knear, float pnear, float h, float r0, float foutside)
    {
        foreach (Point point in listPoint)
        {
            // Apply gravity
            point.pos = point.transform.position;

            point.v = Vdt(point.m, g, point.cd, Y, point.v);

            // save previous position
            point.prevPos = point.pos;

            // advance to predicted position
            point.pos = Pdt(point.v, point.pos);
        }

        // modify velocities with pairwise viscosity impulses
        //  applyViscosity

        // add and remove springs, change rest lengths
        //  adjustSprings

        // modify positions according to springs,
        // double density relaxation, and collisions

        //  applySpringDisplacements

        //  doubleDensityRelaxation
        foreach (Point pointI in listPoint)
        {
            float   r     = 0;
            float   rnear = 0;
            float   p;
            float   q;
            Vector3 dirIJ;
            // compute density and near-density

            List <Point> neighborhood = sh2d.GetNearby(pointI);

            foreach (Point pointJ in neighborhood)
            {
                dirIJ = pointJ.pos - pointI.pos;
                q     = dirIJ.magnitude / h;

                if (q < 1)
                {
                    r     += Mathf.Pow(1 - q, 2);
                    rnear += Mathf.Pow(1 - q, 3);
                }
            }

            // compute pressure and near-pressure

            p     = k * (r - r0);
            pnear = knear * rnear;

            Vector3 dx = Vector3.zero;

            foreach (Point pointJ in neighborhood)
            {
                dirIJ = pointJ.pos - pointI.pos;
                q     = dirIJ.magnitude / h;

                if (q < 1)
                {
                    Vector3 D = (Time.fixedDeltaTime * Time.fixedDeltaTime) / pointI.m * (p * (1 - q) + pnear * Mathf.Pow(1 - q, 2)) * dirIJ.normalized;
                    pointJ.pos += D / 2;
                    dx          = dx - D / 2;
                }
            }

            pointI.pos += dx;
        }

        //resolveCollisions

        // use previous position to compute next velocity
        foreach (Point pointI in listPoint)
        {
            // Clamp
            if (pointI.pos.y < 0)
            {
                pointI.pos += Vector3.up * (new Vector3(pointI.pos.x, 0) - pointI.pos).magnitude * foutside * (Time.fixedDeltaTime * Time.fixedDeltaTime) / pointI.m;
            }
            if (pointI.pos.y > boundaryY)
            {
                pointI.pos += Vector3.down * (new Vector3(pointI.pos.x, boundaryY) - pointI.pos).magnitude * foutside * (Time.fixedDeltaTime * Time.fixedDeltaTime) / pointI.m;
            }
            if (pointI.pos.x < 0)
            {
                pointI.pos += Vector3.right * (new Vector3(0, pointI.pos.y) - pointI.pos).magnitude * foutside * (Time.fixedDeltaTime * Time.fixedDeltaTime) / pointI.m;
            }
            if (pointI.pos.x > boundaryX)
            {
                pointI.pos += Vector3.left * (new Vector3(boundaryX, pointI.pos.y) - pointI.pos).magnitude * foutside * (Time.fixedDeltaTime * Time.fixedDeltaTime) / pointI.m;
            }

            pointI.transform.position = pointI.pos;

            pointI.v = (pointI.pos - pointI.prevPos) / Time.fixedDeltaTime;
        }
    }