PBD算法模拟软体无法正常运动

我采用PBD算法来模拟软体,主要遵循四步,先执行presolve,然后执行solveedge,再执行solvevolume,最后执行postsolve,如果不执行最后一步的话,我的物体是可以正常按照重力下落的,但是加上最后一步就会动一下就卡住不懂了,这是为什么?附代码如下:

public void preSolve(float dt)
    {
        for(int i=0;i<pos.Count;i++)
        {           
            velocity[i] += gravity * dt;
            prePos[i] = pos[i];
            pos[i] += velocity[i] * dt;
            //collision处理,当y<0时把pos挪到0
            //if(pos[i].y<0)
            //{
            //    pos[i] = prePos[i];
            //}
        } 
    }

    float edgeCompliance = 100f;
    //边约束
    public void SolveEdge(float dt)
    {
        float alpha = edgeCompliance / dt / dt;
        Vector3 grads = Vector3.zero;
        for(int i=0;i<edgeContaint.Count;i++)
        {

            int p1 = edgeContaint[i].a;
            int p2 = edgeContaint[i].b;
            float length = edgeContaint[i].length;

            grads = pos[p1] - pos[p2];
            float dis = grads.magnitude;
            grads = grads.normalized;
            float C = dis - length;
            float w = 2;//我这里就假设质量都为1了
            float s = -C/(w + alpha);

            pos[p1] += grads * s;
            pos[p2] += grads * (-s);
        }
    }

    float volumeCompliance = 0;
    public void SolveVolume(float dt)
    {
        float alpha = volumeCompliance / dt / dt;
        List<Vector3> grads = new List<Vector3>(new Vector3[4]);
        for(int i=0;i<tetContaint.Count;i++)
        {
            int x1 = tetContaint[i].a;
            int x2 = tetContaint[i].b;
            int x3 = tetContaint[i].c;
            int x4 = tetContaint[i].d;
            float initVolume = tetContaint[i].initVolume;//初始的体积
            float curVolume = ComputeVolume(x1, x2, x3, x4);//当前的体积

            grads[0] = Vector3.Cross(pos[x4] - pos[x2], pos[x3] - pos[x2]);
            grads[1] = Vector3.Cross(pos[x3] - pos[x1], pos[x4] - pos[x1]);
            grads[2] = Vector3.Cross(pos[x4] - pos[x1], pos[x2] - pos[x1]);
            grads[3] = Vector3.Cross(pos[x2] - pos[x1], pos[x3] - pos[x1]);

            float d1 = grads[0].magnitude;
            float d2 = grads[1].magnitude;
            float d3 = grads[2].magnitude;
            float d4 = grads[3].magnitude;
            float w = Mathf.Sqrt(d1) + Mathf.Sqrt(d2) + Mathf.Sqrt(d3) + Mathf.Sqrt(d4);//这里也是把质量当作1,如果不为1,每个点还需要×质量的倒数

            float C = (curVolume - initVolume) * 6;
            float s = -C / (w + alpha);

            pos[x1] += s * grads[0];
            pos[x2] += s * grads[1];
            pos[x3] += s * grads[2];
            pos[x4] += s * grads[3];
        }
    }

    public void PostSolve(float dt)
    {
        for(int i=0;i<pos.Count;i++)
        {
            velocity[i] = (pos[i] - prePos[i]) / dt;
        }
    }

你的代码看起来是在实现PBD(Position Based Dynamics)算法,这是一种常用于物理模拟的方法,特别是在模拟软体动力学时。你的问题是在执行PostSolve步骤后,物体会停止移动。这可能是由于多种原因,以下是一些可能的原因:

  1. 约束解决的顺序:在PBD中,约束的解决顺序可能会影响最终的结果。你可能需要尝试不同的解决顺序,或者在一个迭代中多次解决约束。

  2. 约束的弹性:在你的代码中,你使用了edgeCompliancevolumeCompliance来表示约束的弹性。这些值可能需要进行调整。如果它们太大或太小,可能会导致物体停止移动。

  3. 碰撞处理:你的代码中有一段处理碰撞的代码被注释掉了。如果物体在运动过程中碰到了其他物体或者场景的边界,没有正确的碰撞处理可能会导致物体停止移动。

  4. 时间步长:你的代码中使用了dt作为时间步长。如果这个值太大或者太小,也可能会影响物体的运动。

  5. 初始条件:物体的初始位置和速度可能会影响其运动。你可能需要检查这些初始条件是否设置得合理。

以上只是一些可能的原因,具体的问题可能需要你根据你的应用场景和需求进行调试和分析。如果你能提供更多的信息,例如你的物体的初始状态,你的场景设置,以及你期望的结果,我可能能提供更具体的建议。