I use NVIDIA Flex 1.1.0 released to make a shovel dirt demo.
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;
};