Merge pull request #2509 from xhan0619/separate-bending-stiffness

Separate in-plane and bending stiffness for mass spring model
This commit is contained in:
erwincoumans
2019-12-04 07:34:28 -08:00
committed by GitHub
7 changed files with 52 additions and 37 deletions

View File

@@ -422,11 +422,12 @@ B3_SHARED_API int b3LoadSoftBodySetFrictionCoefficient(b3SharedMemoryCommandHand
return 0; return 0;
} }
B3_SHARED_API int b3LoadSoftBodyUseBendingSprings(b3SharedMemoryCommandHandle commandHandle, int useBendingSprings) B3_SHARED_API int b3LoadSoftBodyUseBendingSprings(b3SharedMemoryCommandHandle commandHandle, int useBendingSprings, double bendingStiffness)
{ {
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle; struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
b3Assert(command->m_type == CMD_LOAD_SOFT_BODY); b3Assert(command->m_type == CMD_LOAD_SOFT_BODY);
command->m_loadSoftBodyArguments.m_useBendingSprings = useBendingSprings; command->m_loadSoftBodyArguments.m_useBendingSprings = useBendingSprings;
command->m_loadSoftBodyArguments.m_springBendingStiffness = bendingStiffness;
command->m_updateFlags |= LOAD_SOFT_BODY_ADD_BENDING_SPRINGS; command->m_updateFlags |= LOAD_SOFT_BODY_ADD_BENDING_SPRINGS;
return 0; return 0;
} }

View File

@@ -643,7 +643,7 @@ extern "C"
B3_SHARED_API int b3LoadSoftBodySetSelfCollision(b3SharedMemoryCommandHandle commandHandle, int useSelfCollision); B3_SHARED_API int b3LoadSoftBodySetSelfCollision(b3SharedMemoryCommandHandle commandHandle, int useSelfCollision);
B3_SHARED_API int b3LoadSoftBodyUseFaceContact(b3SharedMemoryCommandHandle commandHandle, int useFaceContact); B3_SHARED_API int b3LoadSoftBodyUseFaceContact(b3SharedMemoryCommandHandle commandHandle, int useFaceContact);
B3_SHARED_API int b3LoadSoftBodySetFrictionCoefficient(b3SharedMemoryCommandHandle commandHandle, double frictionCoefficient); B3_SHARED_API int b3LoadSoftBodySetFrictionCoefficient(b3SharedMemoryCommandHandle commandHandle, double frictionCoefficient);
B3_SHARED_API int b3LoadSoftBodyUseBendingSprings(b3SharedMemoryCommandHandle commandHandle, int useBendingSprings); B3_SHARED_API int b3LoadSoftBodyUseBendingSprings(b3SharedMemoryCommandHandle commandHandle, int useBendingSprings, double bendingStiffness);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitCreateSoftBodyAnchorConstraintCommand(b3PhysicsClientHandle physClient, int softBodyUniqueId, int nodeIndex, int bodyUniqueId, int linkIndex, const double bodyFramePosition[3]); B3_SHARED_API b3SharedMemoryCommandHandle b3InitCreateSoftBodyAnchorConstraintCommand(b3PhysicsClientHandle physClient, int softBodyUniqueId, int nodeIndex, int bodyUniqueId, int linkIndex, const double bodyFramePosition[3]);

View File

@@ -8069,7 +8069,7 @@ bool PhysicsServerCommandProcessor::processLoadSoftBodyCommand(const struct Shar
{ {
collisionMargin = clientCmd.m_loadSoftBodyArguments.m_collisionMargin; collisionMargin = clientCmd.m_loadSoftBodyArguments.m_collisionMargin;
} }
btScalar spring_bending_stiffness = 0;
{ {
btSoftBody* psb = NULL; btSoftBody* psb = NULL;
@@ -8136,7 +8136,7 @@ bool PhysicsServerCommandProcessor::processLoadSoftBodyCommand(const struct Shar
} }
} }
#ifndef SKIP_DEFORMABLE_BODY #ifndef SKIP_DEFORMABLE_BODY
btScalar spring_elastic_stiffness, spring_damping_stiffness; btScalar spring_elastic_stiffness, spring_damping_stiffness;
if (clientCmd.m_updateFlags & LOAD_SOFT_BODY_ADD_MASS_SPRING_FORCE) if (clientCmd.m_updateFlags & LOAD_SOFT_BODY_ADD_MASS_SPRING_FORCE)
{ {
btDeformableMultiBodyDynamicsWorld* deformWorld = getDeformableWorld(); btDeformableMultiBodyDynamicsWorld* deformWorld = getDeformableWorld();
@@ -8144,7 +8144,11 @@ bool PhysicsServerCommandProcessor::processLoadSoftBodyCommand(const struct Shar
{ {
spring_elastic_stiffness = clientCmd.m_loadSoftBodyArguments.m_springElasticStiffness; spring_elastic_stiffness = clientCmd.m_loadSoftBodyArguments.m_springElasticStiffness;
spring_damping_stiffness = clientCmd.m_loadSoftBodyArguments.m_springDampingStiffness; spring_damping_stiffness = clientCmd.m_loadSoftBodyArguments.m_springDampingStiffness;
btDeformableLagrangianForce* springForce = new btDeformableMassSpringForce(spring_elastic_stiffness, spring_damping_stiffness, false); if (clientCmd.m_updateFlags & LOAD_SOFT_BODY_ADD_BENDING_SPRINGS)
{
spring_bending_stiffness = clientCmd.m_loadSoftBodyArguments.m_springBendingStiffness;
}
btDeformableLagrangianForce* springForce = new btDeformableMassSpringForce(spring_elastic_stiffness, spring_damping_stiffness, false, spring_bending_stiffness);
deformWorld->addForce(psb, springForce); deformWorld->addForce(psb, springForce);
m_data->m_lf.push_back(springForce); m_data->m_lf.push_back(springForce);
} }
@@ -8177,12 +8181,16 @@ bool PhysicsServerCommandProcessor::processLoadSoftBodyCommand(const struct Shar
deformWorld->addForce(psb, neohookeanForce); deformWorld->addForce(psb, neohookeanForce);
m_data->m_lf.push_back(neohookeanForce); m_data->m_lf.push_back(neohookeanForce);
} }
btScalar spring_elastic_stiffness, spring_damping_stiffness; btScalar spring_elastic_stiffness, spring_damping_stiffness;
if (clientCmd.m_updateFlags & LOAD_SOFT_BODY_ADD_MASS_SPRING_FORCE) if (clientCmd.m_updateFlags & LOAD_SOFT_BODY_ADD_MASS_SPRING_FORCE)
{ {
spring_elastic_stiffness = clientCmd.m_loadSoftBodyArguments.m_springElasticStiffness; spring_elastic_stiffness = clientCmd.m_loadSoftBodyArguments.m_springElasticStiffness;
spring_damping_stiffness = clientCmd.m_loadSoftBodyArguments.m_springDampingStiffness; spring_damping_stiffness = clientCmd.m_loadSoftBodyArguments.m_springDampingStiffness;
btDeformableLagrangianForce* springForce = new btDeformableMassSpringForce(spring_elastic_stiffness, spring_damping_stiffness, true); if (clientCmd.m_updateFlags & LOAD_SOFT_BODY_ADD_BENDING_SPRINGS)
{
spring_bending_stiffness = clientCmd.m_loadSoftBodyArguments.m_springBendingStiffness;
}
btDeformableLagrangianForce* springForce = new btDeformableMassSpringForce(spring_elastic_stiffness, spring_damping_stiffness, true, spring_bending_stiffness);
deformWorld->addForce(psb, springForce); deformWorld->addForce(psb, springForce);
m_data->m_lf.push_back(springForce); m_data->m_lf.push_back(springForce);
} }
@@ -8257,19 +8265,18 @@ bool PhysicsServerCommandProcessor::processLoadSoftBodyCommand(const struct Shar
friction_coeff = loadSoftBodyArgs.m_frictionCoeff; friction_coeff = loadSoftBodyArgs.m_frictionCoeff;
} }
psb->m_cfg.kDF = friction_coeff; psb->m_cfg.kDF = friction_coeff;
bool use_bending_spring = false;
bool use_bending_spring = true;
if (clientCmd.m_updateFlags & LOAD_SOFT_BODY_ADD_BENDING_SPRINGS) if (clientCmd.m_updateFlags & LOAD_SOFT_BODY_ADD_BENDING_SPRINGS)
{ {
use_bending_spring = loadSoftBodyArgs.m_useBendingSprings; use_bending_spring = loadSoftBodyArgs.m_useBendingSprings;
if (use_bending_spring)
{
psb->generateBendingConstraints(2);
}
} }
btSoftBody::Material* pm = psb->appendMaterial(); btSoftBody::Material* pm = psb->appendMaterial();
pm->m_flags -= btSoftBody::fMaterial::DebugDraw; pm->m_flags -= btSoftBody::fMaterial::DebugDraw;
if (use_bending_spring)
{
psb->generateBendingConstraints(2,pm);
}
// turn on the collision flag for deformable // turn on the collision flag for deformable
// collision between deformable and rigid // collision between deformable and rigid
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD; psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;

View File

@@ -523,18 +523,19 @@ struct LoadSoftBodyArgs
double m_mass; double m_mass;
double m_collisionMargin; double m_collisionMargin;
double m_initialPosition[3]; double m_initialPosition[3];
double m_initialOrientation[4]; double m_initialOrientation[4];
double m_springElasticStiffness; double m_springElasticStiffness;
double m_springDampingStiffness; double m_springDampingStiffness;
double m_corotatedMu; double m_springBendingStiffness;
double m_corotatedLambda; double m_corotatedMu;
int m_useBendingSprings; double m_corotatedLambda;
double m_collisionHardness; int m_useBendingSprings;
double m_useSelfCollision; double m_collisionHardness;
double m_frictionCoeff; double m_useSelfCollision;
double m_NeoHookeanMu; double m_frictionCoeff;
double m_NeoHookeanLambda; double m_NeoHookeanMu;
double m_NeoHookeanDamping; double m_NeoHookeanLambda;
double m_NeoHookeanDamping;
int m_useFaceContact; int m_useFaceContact;
char m_simFileName[MAX_FILENAME_LENGTH]; char m_simFileName[MAX_FILENAME_LENGTH];
}; };

View File

@@ -7,8 +7,8 @@
//Please don't replace an existing magic number: //Please don't replace an existing magic number:
//instead, only ADD a new one at the top, comment-out previous one //instead, only ADD a new one at the top, comment-out previous one
#define SHARED_MEMORY_MAGIC_NUMBER 201911280
#define SHARED_MEMORY_MAGIC_NUMBER 201911180 //#define SHARED_MEMORY_MAGIC_NUMBER 201911180
//#define SHARED_MEMORY_MAGIC_NUMBER 201909030 //#define SHARED_MEMORY_MAGIC_NUMBER 201909030
//#define SHARED_MEMORY_MAGIC_NUMBER 201908110 //#define SHARED_MEMORY_MAGIC_NUMBER 201908110
//#define SHARED_MEMORY_MAGIC_NUMBER 201908050 //#define SHARED_MEMORY_MAGIC_NUMBER 201908050

View File

@@ -1973,7 +1973,7 @@ static PyObject* pybullet_loadSoftBody(PyObject* self, PyObject* args, PyObject*
int physicsClientId = 0; int physicsClientId = 0;
int flags = 0; int flags = 0;
static char* kwlist[] = {"fileName", "basePosition", "baseOrientation", "scale", "mass", "collisionMargin", "physicsClientId", "useMassSpring", "useBendingSprings", "useNeoHookean", "springElasticStiffness", "springDampingStiffness", "NeoHookeanMu", "NeoHookeanLambda", "NeoHookeanDamping", "frictionCoeff", "useFaceContact", "useSelfCollision", NULL}; static char* kwlist[] = {"fileName", "basePosition", "baseOrientation", "scale", "mass", "collisionMargin", "physicsClientId", "useMassSpring", "useBendingSprings", "useNeoHookean", "springElasticStiffness", "springDampingStiffness", "springBendingStiffness", "NeoHookeanMu", "NeoHookeanLambda", "NeoHookeanDamping", "frictionCoeff", "useFaceContact", "useSelfCollision", NULL};
int bodyUniqueId = -1; int bodyUniqueId = -1;
const char* fileName = ""; const char* fileName = "";
@@ -1985,6 +1985,7 @@ static PyObject* pybullet_loadSoftBody(PyObject* self, PyObject* args, PyObject*
int useNeoHookean = 0; int useNeoHookean = 0;
double springElasticStiffness = 1; double springElasticStiffness = 1;
double springDampingStiffness = 0.1; double springDampingStiffness = 0.1;
double springBendingStiffness = 0.1;
double NeoHookeanMu = 1; double NeoHookeanMu = 1;
double NeoHookeanLambda = 1; double NeoHookeanLambda = 1;
double NeoHookeanDamping = 0.1; double NeoHookeanDamping = 0.1;
@@ -2002,7 +2003,7 @@ static PyObject* pybullet_loadSoftBody(PyObject* self, PyObject* args, PyObject*
PyObject* basePosObj = 0; PyObject* basePosObj = 0;
PyObject* baseOrnObj = 0; PyObject* baseOrnObj = 0;
if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|OOdddiiiiddddddii", kwlist, &fileName, &basePosObj, &baseOrnObj, &scale, &mass, &collisionMargin, &physicsClientId, &useMassSpring, &useBendingSprings, &useNeoHookean, &springElasticStiffness, &springDampingStiffness, &NeoHookeanMu, &NeoHookeanLambda, &NeoHookeanDamping, &frictionCoeff, &useFaceContact, &useSelfCollision)) if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|OOdddiiiidddddddii", kwlist, &fileName, &basePosObj, &baseOrnObj, &scale, &mass, &collisionMargin, &physicsClientId, &useMassSpring, &useBendingSprings, &useNeoHookean, &springElasticStiffness, &springDampingStiffness, &springBendingStiffness, &NeoHookeanMu, &NeoHookeanLambda, &NeoHookeanDamping, &frictionCoeff, &useFaceContact, &useSelfCollision))
{ {
return NULL; return NULL;
} }
@@ -2058,7 +2059,7 @@ static PyObject* pybullet_loadSoftBody(PyObject* self, PyObject* args, PyObject*
if (useMassSpring) if (useMassSpring)
{ {
b3LoadSoftBodyAddMassSpringForce(command, springElasticStiffness, springDampingStiffness); b3LoadSoftBodyAddMassSpringForce(command, springElasticStiffness, springDampingStiffness);
b3LoadSoftBodyUseBendingSprings(command, useBendingSprings); b3LoadSoftBodyUseBendingSprings(command, useBendingSprings, springBendingStiffness);
} }
if (useNeoHookean) if (useNeoHookean)
{ {

View File

@@ -23,14 +23,18 @@ class btDeformableMassSpringForce : public btDeformableLagrangianForce
// If true, the damping force will be in the direction of the spring // If true, the damping force will be in the direction of the spring
// If false, the damping force will be in the direction of the velocity // If false, the damping force will be in the direction of the velocity
bool m_momentum_conserving; bool m_momentum_conserving;
btScalar m_elasticStiffness, m_dampingStiffness; btScalar m_elasticStiffness, m_dampingStiffness, m_bendingStiffness;
public: public:
typedef btAlignedObjectArray<btVector3> TVStack; typedef btAlignedObjectArray<btVector3> TVStack;
btDeformableMassSpringForce() : m_momentum_conserving(false), m_elasticStiffness(1), m_dampingStiffness(0.05) btDeformableMassSpringForce() : m_momentum_conserving(false), m_elasticStiffness(1), m_dampingStiffness(0.05)
{ {
} }
btDeformableMassSpringForce(btScalar k, btScalar d, bool conserve_angular = true) : m_momentum_conserving(conserve_angular), m_elasticStiffness(k), m_dampingStiffness(d) btDeformableMassSpringForce(btScalar k, btScalar d, bool conserve_angular = true, double bending_k = -1) : m_momentum_conserving(conserve_angular), m_elasticStiffness(k), m_dampingStiffness(d), m_bendingStiffness(bending_k)
{ {
if (m_bendingStiffness < btScalar(0))
{
m_bendingStiffness = m_elasticStiffness;
}
} }
virtual void addScaledForces(btScalar scale, TVStack& force) virtual void addScaledForces(btScalar scale, TVStack& force)
@@ -103,7 +107,8 @@ public:
// elastic force // elastic force
btVector3 dir = (node2->m_q - node1->m_q); btVector3 dir = (node2->m_q - node1->m_q);
btVector3 dir_normalized = (dir.norm() > SIMD_EPSILON) ? dir.normalized() : btVector3(0,0,0); btVector3 dir_normalized = (dir.norm() > SIMD_EPSILON) ? dir.normalized() : btVector3(0,0,0);
btVector3 scaled_force = scale * m_elasticStiffness * (dir - dir_normalized * r); btScalar scaled_stiffness = scale * (link.m_bbending ? m_bendingStiffness : m_elasticStiffness);
btVector3 scaled_force = scaled_stiffness * (dir - dir_normalized * r);
force[id1] += scaled_force; force[id1] += scaled_force;
force[id2] -= scaled_force; force[id2] -= scaled_force;
} }
@@ -212,7 +217,6 @@ public:
{ {
continue; continue;
} }
btScalar scaled_k = m_elasticStiffness * scale;
for (int j = 0; j < psb->m_links.size(); ++j) for (int j = 0; j < psb->m_links.size(); ++j)
{ {
const btSoftBody::Link& link = psb->m_links[j]; const btSoftBody::Link& link = psb->m_links[j];
@@ -227,6 +231,7 @@ public:
btVector3 dir_normalized = (dir_norm > SIMD_EPSILON) ? dir.normalized() : btVector3(0,0,0); btVector3 dir_normalized = (dir_norm > SIMD_EPSILON) ? dir.normalized() : btVector3(0,0,0);
btVector3 dx_diff = dx[id1] - dx[id2]; btVector3 dx_diff = dx[id1] - dx[id2];
btVector3 scaled_df = btVector3(0,0,0); btVector3 scaled_df = btVector3(0,0,0);
btScalar scaled_k = scale * (link.m_bbending ? m_bendingStiffness : m_elasticStiffness);
if (dir_norm > SIMD_EPSILON) if (dir_norm > SIMD_EPSILON)
{ {
scaled_df -= scaled_k * dir_normalized.dot(dx_diff) * dir_normalized; scaled_df -= scaled_k * dir_normalized.dot(dx_diff) * dir_normalized;