Download

NvPhysX Flex issue

I use NVIDIA Flex 1.1.0 released to make a shovel dirt demo.
https://youtube.com/watch?v=EzoC4i0_FqA
The sands fall out from the shovel strangely during moving. I thought it is caused by the friction coefficient but it still exists no matter how I adjust the coefficient. Anyone running into a similar issue?

My demo is modified from the FLEX official demo. The critical code of this scene is shown below.



class TestScene : public Scene

{
public:
    TestScene(const char* name): Scene(name){}
    ~TestScene() {
        delete meshpointer;
    }
    virtual void Initialize() {

        Mesh* contents = ImportMesh(GetFilePathByPlatform("../../data/bunny.ply").c_str());
        contents->Normalize();
        meshpointer = ImportMesh(GetFilePathByPlatform("../../data/shovel.obj").c_str());
        meshpointer->Normalize();

        toolmeshid = CreateTriangleMesh(meshpointer);

        Mesh* bowl = ImportMesh(GetFilePathByPlatform("../../data/bowl.obj").c_str());
        bowl->Normalize();
        bowlid = CreateTriangleMesh(bowl);





        g_params.gravity[1] = -9.8;
        float radius = 0.1f;
        g_params.radius = radius;
        g_params.dynamicFriction = 5.5f;
        g_params.staticFriction = 5.5f;
        g_params.particleCollisionMargin = g_params.radius*0.05f;

        float size = 5.2f;
        const float spacing = g_params.radius;
        int phase = NvFlexMakePhase(0, eNvFlexPhaseSelfCollide);

        CreateParticleShape(contents, Vec3(13, 5, 0), size, 0.0f, spacing, Vec3(0.0f, 0.0f, 0.0f), 1.0f, false, 0, phase, false, 0.0f);
        g_numSubsteps = 2;
        mTime = 0.0f;
        frames = 0;
        all = 0;
        waitframes = 400;
        unload = Vec3(90, 0, -120);
        load = Vec3(90, 0, -60);
        lasttime = 0;



        pos = Vec3();
        rot = Angle2Quat(Vec3(90, 0, -110));
        AddTriangleMesh(toolmeshid, pos, rot, 4.f);
        AddTriangleMesh(bowlid, Vec3(15, 2, 2), Quat(), 7.f);
        AddTriangleMesh(bowlid, Vec3(6, 2, 2), Quat(), 7.f);
        anc1 = Vec3(15, 2.1f, 1.5f);
        anc2 = Vec3(15, 6.1f, 1.5f);
        anc3 = Vec3(7, 6.1f, 1.5f);

    }


    Quat Angle2Quat(Vec3 angles) {

        const float pi = 3.1415926535;
        float pitch, yaw, roll;
        roll = angles.x / 180.*pi;
        pitch = angles.y / 180.*pi;
        yaw = angles.z / 180.*pi;
        Mat44 Rx, Ry, Rz;
        Rx = RotationMatrix(roll, Vec3(1, 0, 0));
        Ry = RotationMatrix(pitch, Vec3(0, 1, 0));
        Rz = RotationMatrix(yaw, Vec3(0, 0, 1));
        Mat44 rot = Rx*Ry*Rz;
        Quat q = Quat();
        float a[4][4];
        //printf("%d %d
", sizeof(rot.columns),sizeof(float));
        memcpy(a, rot.columns, sizeof(rot.columns));

        float trace = a[0][0] + a[1][1] + a[2][2]; // I removed + 1.0f; see discussion with Ethan
        if (trace > 0) {// I changed M_EPSILON to 0
            float s = 0.5f / sqrtf(trace + 1.0f);
            q.w = 0.25f / s;
            q.x = (a[2][1] - a[1][2]) * s;
            q.y = (a[0][2] - a[2][0]) * s;
            q.z = (a[1][0] - a[0][1]) * s;
        }
        else {
            if (a[0][0] > a[1][1] && a[0][0] > a[2][2]) {
                float s = 2.0f * sqrtf(1.0f + a[0][0] - a[1][1] - a[2][2]);
                q.w = (a[2][1] - a[1][2]) / s;
                q.x = 0.25f * s;
                q.y = (a[0][1] + a[1][0]) / s;
                q.z = (a[0][2] + a[2][0]) / s;
            }
            else if (a[1][1] > a[2][2]) {
                float s = 2.0f * sqrtf(1.0f + a[1][1] - a[0][0] - a[2][2]);
                q.w = (a[0][2] - a[2][0]) / s;
                q.x = (a[0][1] + a[1][0]) / s;
                q.y = 0.25f * s;
                q.z = (a[1][2] + a[2][1]) / s;
            }
            else {
                float s = 2.0f * sqrtf(1.0f + a[2][2] - a[0][0] - a[1][1]);
                q.w = (a[1][0] - a[0][1]) / s;
                q.x = (a[0][2] + a[2][0]) / s;
                q.y = (a[1][2] + a[2][1]) / s;
                q.z = 0.25f * s;
            }
        }
        return q;
    }

    void Update() {

        if(frames >= waitframes)
        if (frames < 500 + waitframes) {
            int t = frames - waitframes - lasttime;
            Vec3 dt = (anc1 - anc2) / 500.f;
            pos = anc2 + dt*t;
            rot = Angle2Quat(unload);
        }
        else if (frames < 1000 + waitframes ) {
            lasttime = 500;

            int t = frames - waitframes - lasttime;
            Vec3 dr = (load - unload)/500.f;
            pos = anc1;
            rot = Angle2Quat(unload + dr*t);
        }
        else if (frames < 2000 + waitframes) {
            lasttime = 1000;

            int t = frames - waitframes - lasttime;
            Vec3 dt = (anc2 - anc1)/1000.f;
            pos = anc1 + dt*t;
            rot = Angle2Quat(load);
        }
        else if (frames < 3000 + waitframes) {
            lasttime = 2000;

            int t = frames - waitframes - lasttime;
            Vec3 dt = (anc3 - anc2)/1000.f;
            pos = anc2 + dt*t;
            rot = Angle2Quat(load);
        }
        else if (frames < 3500 + waitframes ) {
            lasttime = 3000;

            int t = frames - waitframes - lasttime;
            Vec3 dr = (unload - load) / 500.f;
            pos = anc3;
            rot = Angle2Quat(load + dr*t);
        }
        else if(frames >= 3600 + waitframes){
            frames = waitframes;
            lasttime = 0;
        }


        g_buffers->shapePrevPositions[0] = Vec4(prevPos, 0.0f);
        g_buffers->shapePrevRotations[0] = prevRot;
        g_buffers->shapePositions[0] = Vec4(pos, 0.0f);
        g_buffers->shapeRotations[0] = rot;


        prevPos = pos;
        prevRot = rot;

        UpdateShapes();
        frames++;
    }

    NvFlexTriangleMeshId toolmeshid,bowlid;
    Vec3 pos, prevPos, anc1, anc2, anc3, unload, load;
    Quat rot, prevRot;
    float mTime;
    Mesh *meshpointer;
    int all;
    int frames;
    int waitframes;
    int lasttime;

};



Sorry for the lateness of this video :slight_smile: