add initial support for soft body / cloth serialization, and updated SerializeDemo to load soft bodies/cloth.

Serializes soft body nodes (vertices), links, faces, tetrahedra, materials, anchors with rigid bodies.
Some todo's are serialization of pose, constraints between soft bodies
This commit is contained in:
erwin.coumans
2010-12-01 05:55:08 +00:00
parent c6524b3fb5
commit 032c6bfe2c
18 changed files with 1257 additions and 461 deletions

View File

@@ -18,10 +18,11 @@ ${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletFileLoader
${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletWorldImporter
)
ADD_DEFINITIONS(-DDESERIALIZE_SOFT_BODIES)
IF (USE_GLUT)
LINK_LIBRARIES(
OpenGLSupport BulletWorldImporter BulletDynamics BulletCollision BulletFileLoader LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
OpenGLSupport BulletWorldImporter BulletSoftBody BulletDynamics BulletCollision BulletFileLoader LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
)
IF (WIN32)
@@ -59,7 +60,7 @@ IF (USE_GLUT)
ELSE (USE_GLUT)
LINK_LIBRARIES(
OpenGLSupport BulletWorldImporter BulletDynamics BulletCollision BulletFileLoader LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
OpenGLSupport BulletWorldImporter BulletSoftBody BulletDynamics BulletCollision BulletFileLoader LinearMath ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
)
ADD_EXECUTABLE(AppSerializeDemo

View File

@@ -15,6 +15,7 @@ subject to the following restrictions:
#define TEST_SERIALIZATION 1
//#define DESERIALIZE_SOFT_BODIES 1
#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
#define CREATE_NEW_BULLETFILE 1
@@ -48,6 +49,12 @@ subject to the following restrictions:
#include <stdio.h> //printf debugging
#ifdef DESERIALIZE_SOFT_BODIES
#include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
#endif
void SerializeDemo::clientMoveAndDisplay()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -89,10 +96,17 @@ void SerializeDemo::displayCallback(void) {
void SerializeDemo::setupEmptyDynamicsWorld()
{
///collision configuration contains default setup for memory, collision setup
//m_collisionConfiguration = new btDefaultCollisionConfiguration();
#ifdef DESERIALIZE_SOFT_BODIES
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
#else
m_collisionConfiguration = new btDefaultCollisionConfiguration();
#endif //DESERIALIZE_SOFT_BODIES
//m_collisionConfiguration->setConvexConvexMultipointIterations();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
@@ -104,14 +118,151 @@ void SerializeDemo::setupEmptyDynamicsWorld()
btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;
m_solver = sol;
#ifdef DESERIALIZE_SOFT_BODIES
m_dynamicsWorld = new btSoftRigidDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
#else
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
#endif //DESERIALIZE_SOFT_BODIES
btGImpactCollisionAlgorithm::registerAlgorithm((btCollisionDispatcher*)m_dynamicsWorld->getDispatcher());
//btGImpactCollisionAlgorithm::registerAlgorithm((btCollisionDispatcher*)m_dynamicsWorld->getDispatcher());
m_dynamicsWorld->setGravity(btVector3(0,-10,0));
}
btAlignedObjectArray<btVector3> vtx;
btAlignedObjectArray<btScalar> masses;
#ifdef DESERIALIZE_SOFT_BODIES
#include "BulletSoftBody/btSoftBodyData.h"
class MySoftBulletWorldImporter : public btBulletWorldImporter
{
btSoftRigidDynamicsWorld* m_softRigidWorld;
public:
MySoftBulletWorldImporter(btSoftRigidDynamicsWorld* world)
:btBulletWorldImporter(world),
m_softRigidWorld(world)
{
}
virtual bool convertAllObjects( bParse::btBulletFile* bulletFile2)
{
bool result = btBulletWorldImporter::convertAllObjects(bulletFile2);
int i;
//now the soft bodies
for (i=0;i<bulletFile2->m_softBodies.size();i++)
{
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
{
btAssert(0); //not yet
//btSoftBodyFloatData* colObjData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i];
} else
{
btSoftBodyFloatData* colObjData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i];
int i;
int numNodes = colObjData->m_numNodes;
for (i=0;i<colObjData->m_numLinks;i++)
{
SoftBodyLinkData& link = colObjData->m_links[i];
}
vtx.resize(numNodes);
masses.resize(numNodes);
for (i=0;i<numNodes;i++)
{
SoftBodyNodeData& node = colObjData->m_nodes[i];
vtx[i].deSerializeFloat(node.m_position);
masses[i] = node.m_inverseMass? 1./node.m_inverseMass : 0.f;
}
btSoftBody* psb=new btSoftBody(&m_softRigidWorld->getWorldInfo(),numNodes,&vtx[0],&masses[0]);
#if 0
for (i=0;i<numNodes;i++)
{
SoftBodyNodeData& node = colObjData->m_nodes[i];
if (!node.m_inverseMass)
{
btScalar mass = node.m_inverseMass? 1.f/node.m_inverseMass : 0;
psb->setMass(i,mass);
}
}
#endif
for (i=0;i<colObjData->m_numLinks;i++)
{
SoftBodyLinkData& link = colObjData->m_links[i];
psb->appendLink(link.m_nodeIndices[0],link.m_nodeIndices[1]);
}
for (i=0;i<colObjData->m_numFaces;i++)
{
SoftBodyFaceData& face = colObjData->m_faces[i];
psb->appendFace(face.m_nodeIndices[0],face.m_nodeIndices[1],face.m_nodeIndices[2]);
}
// psb->randomizeConstraints();
//psb->updateNormals();
//psb->updateBounds();
//psb->updateConstants();
psb->m_cfg.piterations=colObjData->m_config.m_positionIterations;
psb->m_cfg.diterations=colObjData->m_config.m_driftIterations;
psb->m_cfg.citerations=colObjData->m_config.m_clusterIterations;
psb->m_cfg.viterations=colObjData->m_config.m_velocityIterations;
//psb->setTotalMass(0.1);
psb->m_cfg.aeromodel = (btSoftBody::eAeroModel::_)colObjData->m_config.m_aeroModel;
psb->m_cfg.kLF = colObjData->m_config.m_lift;
psb->m_cfg.kDG = colObjData->m_config.m_drag;
//psb->addForce(btVector3(0,2,0),0);
//anchors
for (i=0;i<colObjData->m_numAnchors;i++)
{
btCollisionObject** colAptr = m_bodyMap.find(colObjData->m_anchors[i].m_rigidBody);
if (colAptr && *colAptr)
{
btRigidBody* body = btRigidBody::upcast(*colAptr);
if (body)
{
bool disableCollision = false;
btVector3 localPivot;
localPivot.deSerializeFloat(colObjData->m_anchors[i].m_localFrame);
psb->appendAnchor(colObjData->m_anchors[i].m_nodeIndex,body,localPivot, disableCollision);
}
}
}
m_softRigidWorld->getWorldInfo().m_dispatcher = m_softRigidWorld->getDispatcher();
m_softRigidWorld->addSoftBody(psb);
}
}
return result;
}
};
#endif //DESERIALIZE_SOFT_BODIES
void SerializeDemo::initPhysics()
{
setTexturing(true);
@@ -121,7 +272,11 @@ void SerializeDemo::initPhysics()
setupEmptyDynamicsWorld();
#ifdef DESERIALIZE_SOFT_BODIES
btBulletWorldImporter* fileLoader = new MySoftBulletWorldImporter((btSoftRigidDynamicsWorld*)m_dynamicsWorld);
#else
btBulletWorldImporter* fileLoader = new btBulletWorldImporter(m_dynamicsWorld);
#endif //DESERIALIZE_SOFT_BODIES
// fileLoader->setVerboseMode(true);
if (!fileLoader->loadFile("testFile.bullet"))
@@ -247,7 +402,7 @@ void SerializeDemo::initPhysics()
fclose(f2);
}
clientResetScene();
//clientResetScene();
}

View File

@@ -53,6 +53,7 @@ static float waveheight = 5.f;
const float TRIANGLE_SIZE=8.f;
#define DEMO_MODE_TIMEOUT 500.f
#ifdef _DEBUG
@@ -1388,12 +1389,12 @@ void SoftDemo::clientMoveAndDisplay()
if (sDemoMode)
{
static int demoCounter = 500;
demoCounter--;
static float demoCounter = DEMO_MODE_TIMEOUT;
demoCounter-= dt;
if (demoCounter<0)
{
demoCounter=500;
demoCounter=DEMO_MODE_TIMEOUT;
current_demo++;
current_demo=current_demo%(sizeof(demofncs)/sizeof(demofncs[0]));
clientResetScene();

View File

@@ -164,6 +164,11 @@ void btBulletFile::parseData()
// listID->push_back((bStructHandle*)id);
}
if (dataChunk.code == BT_SOFTBODY_CODE)
{
m_softBodies.push_back((bStructHandle*) id);
}
if (dataChunk.code == BT_RIGIDBODY_CODE)
{
m_rigidBodies.push_back((bStructHandle*) id);

View File

@@ -38,6 +38,8 @@ namespace bParse {
public:
btAlignedObjectArray<bStructHandle*> m_softBodies;
btAlignedObjectArray<bStructHandle*> m_rigidBodies;
btAlignedObjectArray<bStructHandle*> m_collisionObjects;

View File

@@ -6,6 +6,7 @@
#include "BulletCollision/Gimpact/btGImpactShape.h"
//#define USE_INTERNAL_EDGE_UTILITY
#ifdef USE_INTERNAL_EDGE_UTILITY
#include "BulletCollision/CollisionDispatch/btInternalEdgeUtility.h"
@@ -476,6 +477,10 @@ bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFil
bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile2)
{
m_shapeMap.clear();
m_bodyMap.clear();
int i;
for (i=0;i<bulletFile2->m_bvhs.size();i++)
@@ -496,7 +501,7 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
btHashMap<btHashPtr,btCollisionShape*> shapeMap;
for (i=0;i<bulletFile2->m_collisionShapes.size();i++)
{
@@ -505,7 +510,7 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
if (shape)
{
// printf("shapeMap.insert(%x,%x)\n",shapeData,shape);
shapeMap.insert(shapeData,shape);
m_shapeMap.insert(shapeData,shape);
}
if (shape&& shapeData->m_name)
@@ -516,7 +521,12 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
}
}
btHashMap<btHashPtr,btCollisionObject*> bodyMap;
for (i=0;i<bulletFile2->m_rigidBodies.size();i++)
{
@@ -526,7 +536,7 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
btScalar mass = btScalar(colObjData->m_inverseMass? 1.f/colObjData->m_inverseMass : 0.f);
btVector3 localInertia;
localInertia.setZero();
btCollisionShape** shapePtr = shapeMap.find(colObjData->m_collisionObjectData.m_collisionShape);
btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionObjectData.m_collisionShape);
if (shapePtr && *shapePtr)
{
btTransform startTransform;
@@ -555,7 +565,7 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
}
}
#endif //USE_INTERNAL_EDGE_UTILITY
bodyMap.insert(colObjData,body);
m_bodyMap.insert(colObjData,body);
} else
{
printf("error: no shape found\n");
@@ -567,7 +577,7 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
btScalar mass = btScalar(colObjData->m_inverseMass? 1.f/colObjData->m_inverseMass : 0.f);
btVector3 localInertia;
localInertia.setZero();
btCollisionShape** shapePtr = shapeMap.find(colObjData->m_collisionObjectData.m_collisionShape);
btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionObjectData.m_collisionShape);
if (shapePtr && *shapePtr)
{
btTransform startTransform;
@@ -594,7 +604,7 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
}
}
#endif //USE_INTERNAL_EDGE_UTILITY
bodyMap.insert(colObjData,body);
m_bodyMap.insert(colObjData,body);
} else
{
printf("error: no shape found\n");
@@ -607,7 +617,7 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
{
btCollisionObjectDoubleData* colObjData = (btCollisionObjectDoubleData*)bulletFile2->m_collisionObjects[i];
btCollisionShape** shapePtr = shapeMap.find(colObjData->m_collisionShape);
btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape);
if (shapePtr && *shapePtr)
{
btTransform startTransform;
@@ -625,7 +635,7 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
}
}
#endif //USE_INTERNAL_EDGE_UTILITY
bodyMap.insert(colObjData,body);
m_bodyMap.insert(colObjData,body);
} else
{
printf("error: no shape found\n");
@@ -634,7 +644,7 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
} else
{
btCollisionObjectFloatData* colObjData = (btCollisionObjectFloatData*)bulletFile2->m_collisionObjects[i];
btCollisionShape** shapePtr = shapeMap.find(colObjData->m_collisionShape);
btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape);
if (shapePtr && *shapePtr)
{
btTransform startTransform;
@@ -652,7 +662,7 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
}
}
#endif //USE_INTERNAL_EDGE_UTILITY
bodyMap.insert(colObjData,body);
m_bodyMap.insert(colObjData,body);
} else
{
printf("error: no shape found\n");
@@ -666,8 +676,8 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
for (i=0;i<bulletFile2->m_constraints.size();i++)
{
btTypedConstraintData* constraintData = (btTypedConstraintData*)bulletFile2->m_constraints[i];
btCollisionObject** colAptr = bodyMap.find(constraintData->m_rbA);
btCollisionObject** colBptr = bodyMap.find(constraintData->m_rbB);
btCollisionObject** colAptr = m_bodyMap.find(constraintData->m_rbA);
btCollisionObject** colBptr = m_bodyMap.find(constraintData->m_rbB);
btRigidBody* rbA = 0;
btRigidBody* rbB = 0;

View File

@@ -80,6 +80,9 @@ protected:
btHashMap<btHashString,btTypedConstraint*> m_nameConstraintMap;
btHashMap<btHashPtr,const char*> m_objectNameMap;
btHashMap<btHashPtr,btCollisionShape*> m_shapeMap;
btHashMap<btHashPtr,btCollisionObject*> m_bodyMap;
//methods
btTriangleIndexVertexArray* createMeshInterface(btStridingMeshInterfaceData& meshData);
@@ -106,7 +109,7 @@ public:
bool loadFileFromMemory(bParse::btBulletFile* file);
//call make sure bulletFile2 has been parsed, either using btBulletFile::parse or btBulletWorldImporter::loadFileFromMemory
bool convertAllObjects(bParse::btBulletFile* file);
virtual bool convertAllObjects(bParse::btBulletFile* file);
void setVerboseMode(bool verboseDumpAllTypes)
{

View File

@@ -144,7 +144,7 @@ typedef unsigned long uintptr_t;
#include "BulletDynamics/ConstraintSolver/btSliderConstraint.h"
#include "BulletDynamics/Dynamics/btRigidBody.h"
#include "BulletSoftBody/btSoftBodyData.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -183,7 +183,7 @@ char *includefiles[] = {
"../../../src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h",
"../../../src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h",
"../../../src/BulletDynamics/ConstraintSolver/btSliderConstraint.h",
"../../../src/BulletSoftBody/btSoftBodyData.h",
// empty string to indicate end of includefiles
""
};

View File

@@ -20,6 +20,7 @@ SET(BulletSoftBody_SRCS
SET(BulletSoftBody_HDRS
btSoftBody.h
btSoftBodyData.h
btSoftBodyConcaveCollisionAlgorithm.h
btSoftBodyHelpers.h
btSoftBodyRigidBodyCollisionConfiguration.h

View File

@@ -47,7 +47,10 @@ void btDefaultSoftBodySolver::updateSoftBodies( )
for ( int i=0; i < m_softBodySet.size(); i++)
{
btSoftBody* psb=(btSoftBody*)m_softBodySet[i];
psb->integrateMotion();
if (psb->isActive())
{
psb->integrateMotion();
}
}
} // updateSoftBodies
@@ -62,7 +65,10 @@ void btDefaultSoftBodySolver::solveConstraints( float solverdt )
for(int i=0; i < m_softBodySet.size(); ++i)
{
btSoftBody* psb = static_cast<btSoftBody*>(m_softBodySet[i]);
psb->solveConstraints();
if (psb->isActive())
{
psb->solveConstraints();
}
}
} // btDefaultSoftBodySolver::solveConstraints
@@ -122,7 +128,10 @@ void btDefaultSoftBodySolver::predictMotion( float timeStep )
{
btSoftBody* psb = m_softBodySet[i];
psb->predictMotion(timeStep);
if (psb->isActive())
{
psb->predictMotion(timeStep);
}
}
}

View File

@@ -16,6 +16,8 @@ subject to the following restrictions:
#include "btSoftBodyInternals.h"
#include "BulletSoftBody/btSoftBodySolvers.h"
#include "btSoftBodyData.h"
#include "LinearMath/btSerializer.h"
//
btSoftBody::btSoftBody(btSoftBodyWorldInfo* worldInfo,int node_count, const btVector3* x, const btScalar* m)
@@ -337,7 +339,15 @@ void btSoftBody::appendTetra(int node0,
}
//
void btSoftBody::appendAnchor(int node,btRigidBody* body, bool disableCollisionBetweenLinkedBodies)
{
btVector3 local = body->getWorldTransform().inverse()*m_nodes[node].m_x;
appendAnchor(node,body,local,disableCollisionBetweenLinkedBodies);
}
//
void btSoftBody::appendAnchor(int node,btRigidBody* body, const btVector3& localPivot,bool disableCollisionBetweenLinkedBodies)
{
if (disableCollisionBetweenLinkedBodies)
{
@@ -350,7 +360,7 @@ void btSoftBody::appendAnchor(int node,btRigidBody* body, bool disableCollisio
Anchor a;
a.m_node = &m_nodes[node];
a.m_body = body;
a.m_local = body->getInterpolationWorldTransform().inverse()*a.m_node->m_x;
a.m_local = localPivot;
a.m_node->m_battach = 1;
m_anchors.push_back(a);
}
@@ -1957,7 +1967,7 @@ bool btSoftBody::checkContact( btCollisionObject* colObj,
btVector3 nrm;
btCollisionShape *shp = colObj->getCollisionShape();
btRigidBody *tmpRigid = btRigidBody::upcast(colObj);
const btTransform &wtr = tmpRigid ? tmpRigid->getInterpolationWorldTransform() : colObj->getWorldTransform();
const btTransform &wtr = tmpRigid ? tmpRigid->getWorldTransform() : colObj->getWorldTransform();
btScalar dst =
m_worldInfo->m_sparsesdf.Evaluate(
wtr.invXform(x),
@@ -2388,7 +2398,10 @@ void btSoftBody::applyClusters(bool drift)
}
for(i=0;i<deltas.size();++i)
{
if(weights[i]>0) m_nodes[i].m_x+=deltas[i]/weights[i];
if(weights[i]>0)
{
m_nodes[i].m_x+=deltas[i]/weights[i];
}
}
}
@@ -2729,7 +2742,7 @@ void btSoftBody::PSolve_Anchors(btSoftBody* psb,btScalar kst,btScalar ti)
for(int i=0,ni=psb->m_anchors.size();i<ni;++i)
{
const Anchor& a=psb->m_anchors[i];
const btTransform& t=a.m_body->getInterpolationWorldTransform();
const btTransform& t=a.m_body->getWorldTransform();
Node& n=*a.m_node;
const btVector3 wa=t*a.m_local;
const btVector3 va=a.m_body->getVelocityInLocalPoint(a.m_c1)*dt;
@@ -2891,7 +2904,8 @@ void btSoftBody::defaultCollisionHandler(btCollisionObject* pco)
{
btSoftColliders::CollideSDF_RS docollide;
btRigidBody* prb1=btRigidBody::upcast(pco);
btTransform wtr=prb1 ? prb1->getInterpolationWorldTransform() : pco->getWorldTransform();
//btTransform wtr=prb1 ? prb1->getWorldTransform() : pco->getWorldTransform();
btTransform wtr=pco->getWorldTransform();
const btTransform ctr=pco->getWorldTransform();
const btScalar timemargin=(wtr.getOrigin()-ctr.getOrigin()).length();
@@ -2899,7 +2913,7 @@ void btSoftBody::defaultCollisionHandler(btCollisionObject* pco)
btVector3 mins;
btVector3 maxs;
ATTRIBUTE_ALIGNED16(btDbvtVolume) volume;
pco->getCollisionShape()->getAabb( pco->getInterpolationWorldTransform(),
pco->getCollisionShape()->getAabb( pco->getWorldTransform(),
mins,
maxs);
volume=btDbvtVolume::FromMM(mins,maxs);
@@ -2986,3 +3000,205 @@ const btVector3& btSoftBody::getWindVelocity()
{
return m_windVelocity;
}
int btSoftBody::calculateSerializeBufferSize() const
{
int sz = sizeof(btSoftBodyData);
return sz;
}
///fills the dataBuffer and returns the struct name (and 0 on failure)
const char* btSoftBody::serialize(void* dataBuffer, class btSerializer* serializer) const
{
btSoftBodyData* sbd = (btSoftBodyData*) dataBuffer;
btCollisionObject::serialize(&sbd->m_collisionObjectData, serializer);
sbd->m_numMaterials = m_materials.size();
sbd->m_materials = sbd->m_numMaterials? (SoftBodyMaterialData**) serializer->getUniquePointer((void*)&m_materials): 0;
if (sbd->m_materials)
{
int sz = sizeof(SoftBodyMaterialData*);
int numElem = sbd->m_numMaterials;
btChunk* chunk = serializer->allocate(sz,numElem);
//SoftBodyMaterialData** memPtr = chunk->m_oldPtr;
SoftBodyMaterialData** memPtr = (SoftBodyMaterialData**)chunk->m_oldPtr;
for (int i=0;i<numElem;i++,memPtr++)
{
btSoftBody::Material* mat = m_materials[i];
*memPtr = mat ? (SoftBodyMaterialData*)serializer->getUniquePointer((void*)mat) : 0;
if (!serializer->findPointer(mat))
{
//serialize it here
btChunk* chunk = serializer->allocate(sizeof(SoftBodyMaterialData),1);
SoftBodyMaterialData* memPtr = (SoftBodyMaterialData*)chunk->m_oldPtr;
memPtr->m_flags = mat->m_flags;
memPtr->m_angularStiffness = mat->m_kAST;
memPtr->m_linearStiffness = mat->m_kLST;
memPtr->m_volumeStiffness = mat->m_kVST;
serializer->finalizeChunk(chunk,"SoftBodyMaterialData",BT_SBMATERIAL_CODE,mat);
}
}
serializer->finalizeChunk(chunk,"SoftBodyMaterialData",BT_ARRAY_CODE,(void*) &m_materials);
}
sbd->m_numNodes = m_nodes.size();
sbd->m_nodes = sbd->m_numNodes ? (SoftBodyNodeData*)serializer->getUniquePointer((void*)&m_nodes[0]): 0;
if (sbd->m_nodes)
{
int sz = sizeof(SoftBodyNodeData);
int numElem = sbd->m_numNodes;
btChunk* chunk = serializer->allocate(sz,numElem);
SoftBodyNodeData* memPtr = (SoftBodyNodeData*)chunk->m_oldPtr;
for (int i=0;i<numElem;i++,memPtr++)
{
m_nodes[i].m_f.serializeFloat( memPtr->m_accumulatedForce);
memPtr->m_area = m_nodes[i].m_area;
memPtr->m_attach = m_nodes[i].m_battach;
memPtr->m_inverseMass = m_nodes[i].m_im;
memPtr->m_material = m_nodes[i].m_material? (SoftBodyMaterialData*)serializer->getUniquePointer((void*) m_nodes[i].m_material):0;
m_nodes[i].m_n.serializeFloat(memPtr->m_normal);
m_nodes[i].m_x.serializeFloat(memPtr->m_position);
m_nodes[i].m_q.serializeFloat(memPtr->m_previousPosition);
m_nodes[i].m_v.serializeFloat(memPtr->m_velocity);
}
serializer->finalizeChunk(chunk,"SoftBodyNodeData",BT_SBNODE_CODE,(void*) &m_nodes[0]);
}
sbd->m_numLinks = m_links.size();
sbd->m_links = sbd->m_numLinks? (SoftBodyLinkData*) serializer->getUniquePointer((void*)&m_links[0]):0;
if (sbd->m_links)
{
int sz = sizeof(SoftBodyLinkData);
int numElem = sbd->m_numLinks;
btChunk* chunk = serializer->allocate(sz,numElem);
SoftBodyLinkData* memPtr = (SoftBodyLinkData*)chunk->m_oldPtr;
for (int i=0;i<numElem;i++,memPtr++)
{
memPtr->m_bbending = m_links[i].m_bbending;
memPtr->m_c0 = m_links[i].m_c0;
memPtr->m_c1 = m_links[i].m_c1;
memPtr->m_c2 = m_links[i].m_c2;
m_links[i].m_c3.serializeFloat(memPtr->m_c3);
memPtr->m_material = m_links[i].m_material? (SoftBodyMaterialData*)serializer->getUniquePointer((void*) m_links[i].m_material):0;
memPtr->m_nodeIndices[0] = m_links[i].m_n[0] ? m_links[i].m_n[0] - &m_nodes[0]: -1;
memPtr->m_nodeIndices[1] = m_links[i].m_n[1] ? m_links[i].m_n[1] - &m_nodes[0]: -1;
btAssert(memPtr->m_nodeIndices[0]<m_nodes.size());
btAssert(memPtr->m_nodeIndices[1]<m_nodes.size());
memPtr->m_restLength = m_links[i].m_rl;
}
serializer->finalizeChunk(chunk,"SoftBodyLinkData",BT_ARRAY_CODE,(void*) &m_links[0]);
}
sbd->m_numFaces = m_faces.size();
sbd->m_faces = sbd->m_numFaces? (SoftBodyFaceData*) serializer->getUniquePointer((void*)&m_faces[0]):0;
if (sbd->m_faces)
{
int sz = sizeof(SoftBodyFaceData);
int numElem = sbd->m_numFaces;
btChunk* chunk = serializer->allocate(sz,numElem);
SoftBodyFaceData* memPtr = (SoftBodyFaceData*)chunk->m_oldPtr;
for (int i=0;i<numElem;i++,memPtr++)
{
memPtr->m_material = m_faces[i].m_material ? (SoftBodyMaterialData*) serializer->getUniquePointer((void*)m_faces[i].m_material): 0;
m_faces[i].m_normal.serializeFloat( memPtr->m_normal);
for (int j=0;j<3;j++)
{
memPtr->m_nodeIndices[j] = m_faces[i].m_n[j]? m_faces[i].m_n[j] - &m_nodes[0]: -1;
}
memPtr->m_restArea = m_faces[i].m_ra;
}
serializer->finalizeChunk(chunk,"SoftBodyFaceData",BT_ARRAY_CODE,(void*) &m_faces[0]);
}
sbd->m_numTetrahedra = m_tetras.size();
sbd->m_tetrahedra = sbd->m_numTetrahedra ? (SoftBodyTetraData*) serializer->getUniquePointer((void*)&m_tetras[0]):0;
if (sbd->m_tetrahedra)
{
int sz = sizeof(SoftBodyTetraData);
int numElem = sbd->m_numTetrahedra;
btChunk* chunk = serializer->allocate(sz,numElem);
SoftBodyTetraData* memPtr = (SoftBodyTetraData*)chunk->m_oldPtr;
for (int i=0;i<numElem;i++,memPtr++)
{
for (int j=0;j<4;j++)
{
m_tetras[i].m_c0[j].serializeFloat( memPtr->m_c0[j] );
memPtr->m_nodeIndices[j] = m_tetras[j].m_n[j]? m_tetras[j].m_n[j]-&m_nodes[0] : -1;
}
memPtr->m_c1 = m_tetras[i].m_c1;
memPtr->m_c2 = m_tetras[i].m_c2;
memPtr->m_material = m_tetras[i].m_material ? (SoftBodyMaterialData*)serializer->getUniquePointer((void*) m_tetras[i].m_material): 0;
memPtr->m_restVolume = m_tetras[i].m_rv;
}
serializer->finalizeChunk(chunk,"SoftBodyTetraData",BT_ARRAY_CODE,(void*) &m_tetras[0]);
}
sbd->m_numAnchors = m_anchors.size();
sbd->m_anchors = sbd->m_numAnchors ? (SoftRigidAnchorData*) serializer->getUniquePointer((void*)&m_anchors[0]):0;
if (sbd->m_anchors)
{
int sz = sizeof(SoftRigidAnchorData);
int numElem = sbd->m_numAnchors;
btChunk* chunk = serializer->allocate(sz,numElem);
SoftRigidAnchorData* memPtr = (SoftRigidAnchorData*)chunk->m_oldPtr;
for (int i=0;i<numElem;i++,memPtr++)
{
m_anchors[i].m_c0.serializeFloat(memPtr->m_c0);
m_anchors[i].m_c1.serializeFloat(memPtr->m_c1);
memPtr->m_c2 = m_anchors[i].m_c2;
m_anchors[i].m_local.serializeFloat(memPtr->m_localFrame);
memPtr->m_nodeIndex = m_anchors[i].m_node? m_anchors[i].m_node-&m_nodes[0]: -1;
memPtr->m_rigidBody = m_anchors[i].m_body? (btRigidBodyData*) serializer->getUniquePointer((void*)m_anchors[i].m_body): 0;
btAssert(memPtr->m_nodeIndex < m_nodes.size());
}
serializer->finalizeChunk(chunk,"SoftRigidAnchorData",BT_ARRAY_CODE,(void*) &m_anchors[0]);
}
sbd->m_config.m_baumgarte = m_cfg.kVCF;
sbd->m_config.m_pressure = m_cfg.kPR;
sbd->m_config.m_aeroModel = this->m_cfg.aeromodel;
sbd->m_config.m_lift = m_cfg.kLF;
sbd->m_config.m_drag = m_cfg.kDG;
sbd->m_config.m_positionIterations = m_cfg.piterations;
sbd->m_config.m_driftIterations = m_cfg.diterations;
sbd->m_config.m_clusterIterations = m_cfg.citerations;
sbd->m_config.m_velocityIterations = m_cfg.viterations;
sbd->m_config.m_maxVolume = m_cfg.maxvolume;
sbd->m_config.m_damping = m_cfg.kDP;
sbd->m_config.m_poseMatch = m_cfg.kMT;
sbd->m_config.m_collisionFlags = m_cfg.collisions;
sbd->m_config.m_volume = m_cfg.kVC;
sbd->m_config.m_rigidContactHardness = m_cfg.kCHR;
sbd->m_config.m_kineticContactHardness = m_cfg.kKHR;
sbd->m_config.m_softContactHardness = m_cfg.kSHR;
sbd->m_config.m_anchorHardness = m_cfg.kAHR;
sbd->m_config.m_timeScale = m_cfg.timescale;
sbd->m_config.m_maxVolume = m_cfg.maxvolume;
sbd->m_config.m_softRigidClusterHardness = m_cfg.kSRHR_CL;
sbd->m_config.m_softKineticClusterHardness = m_cfg.kSKHR_CL;
sbd->m_config.m_softSoftClusterHardness = m_cfg.kSSHR_CL;
sbd->m_config.m_softRigidClusterImpulseSplit = m_cfg.kSR_SPLT_CL;
sbd->m_config.m_softKineticClusterImpulseSplit = m_cfg.kSK_SPLT_CL;
sbd->m_config.m_softSoftClusterImpulseSplit = m_cfg.kSS_SPLT_CL;
//not yet
sbd->m_pose = 0;
return btSoftBodyDataName;
}

View File

@@ -27,6 +27,14 @@ subject to the following restrictions:
#include "btSparseSDF.h"
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
//#ifdef BT_USE_DOUBLE_PRECISION
//#define btRigidBodyData btRigidBodyDoubleData
//#define btRigidBodyDataName "btRigidBodyDoubleData"
//#else
#define btSoftBodyData btSoftBodyFloatData
#define btSoftBodyDataName "btSoftBodyFloatData"
//#endif //BT_USE_DOUBLE_PRECISION
class btBroadphaseInterface;
class btDispatcher;
@@ -366,7 +374,11 @@ public:
void activate() const
{
if(m_rigid) m_rigid->activate();
if(m_rigid)
m_rigid->activate();
if (m_collisionObject)
m_collisionObject->activate();
}
const btMatrix3x3& invWorldInertia() const
{
@@ -730,6 +742,7 @@ public:
/* Append anchor */
void appendAnchor( int node,
btRigidBody* body, bool disableCollisionBetweenLinkedBodies=false);
void appendAnchor(int node,btRigidBody* body, const btVector3& localPivot,bool disableCollisionBetweenLinkedBodies=false);
/* Append linear joint */
void appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1);
void appendLinearJoint(const LJoint::Specs& specs,Body body=Body());
@@ -911,8 +924,18 @@ public:
static psolver_t getSolver(ePSolver::_ solver);
static vsolver_t getSolver(eVSolver::_ solver);
virtual int calculateSerializeBufferSize() const;
///fills the dataBuffer and returns the struct name (and 0 on failure)
virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const;
//virtual void serializeSingleObject(class btSerializer* serializer) const;
};
#endif //_BT_SOFT_BODY_H

View File

@@ -0,0 +1,161 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_SOFTBODY_FLOAT_DATA
#define BT_SOFTBODY_FLOAT_DATA
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
struct SoftBodyMaterialData
{
float m_linearStiffness;
float m_angularStiffness;
float m_volumeStiffness;
int m_flags;
};
struct SoftBodyNodeData
{
SoftBodyMaterialData *m_material;
btVector3FloatData m_position;
btVector3FloatData m_previousPosition;
btVector3FloatData m_velocity;
btVector3FloatData m_accumulatedForce;
btVector3FloatData m_normal;
float m_inverseMass;
float m_area;
int m_attach;
int m_pad;
};
struct SoftBodyLinkData
{
SoftBodyMaterialData *m_material;
int m_nodeIndices[2]; // Node pointers
btVector3FloatData m_c3; // gradient
float m_restLength; // Rest length
int m_bbending; // Bending link
float m_c0; // (ima+imb)*kLST
float m_c1; // rl^2
float m_c2; // |gradient|^2/c0
int m_pad;
};
struct SoftBodyFaceData
{
btVector3FloatData m_normal; // Normal
SoftBodyMaterialData *m_material;
int m_nodeIndices[3]; // Node pointers
float m_restArea; // Rest area
};
struct SoftBodyTetraData
{
btVector3FloatData m_c0[4]; // gradients
SoftBodyMaterialData *m_material;
int m_nodeIndices[4]; // Node pointers
float m_restVolume; // Rest volume
float m_c1; // (4*kVST)/(im0+im1+im2+im3)
float m_c2; // m_c1/sum(|g0..3|^2)
int m_pad;
};
struct SoftRigidAnchorData
{
btMatrix3x3FloatData m_c0; // Impulse matrix
btVector3FloatData m_c1; // Relative anchor
btVector3FloatData m_localFrame; // Anchor position in body space
btRigidBodyData *m_rigidBody;
int m_nodeIndex; // Node pointer
float m_c2; // ima*dt
};
struct SoftBodyConfigData
{
int m_aeroModel; // Aerodynamic model (default: V_Point)
float m_baumgarte; // Velocities correction factor (Baumgarte)
float m_damping; // Damping coefficient [0,1]
float m_drag; // Drag coefficient [0,+inf]
float m_lift; // Lift coefficient [0,+inf]
float m_pressure; // Pressure coefficient [-inf,+inf]
float m_volume; // Volume conversation coefficient [0,+inf]
float m_dynamicFriction; // Dynamic friction coefficient [0,1]
float m_poseMatch; // Pose matching coefficient [0,1]
float m_rigidContactHardness; // Rigid contacts hardness [0,1]
float m_kineticContactHardness; // Kinetic contacts hardness [0,1]
float m_softContactHardness; // Soft contacts hardness [0,1]
float m_anchorHardness; // Anchors hardness [0,1]
float m_softRigidClusterHardness; // Soft vs rigid hardness [0,1] (cluster only)
float m_softKineticClusterHardness; // Soft vs kinetic hardness [0,1] (cluster only)
float m_softSoftClusterHardness; // Soft vs soft hardness [0,1] (cluster only)
float m_softRigidClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only)
float m_softKineticClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only)
float m_softSoftClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only)
float m_maxVolume; // Maximum volume ratio for pose
float m_timeScale; // Time scale
int m_velocityIterations; // Velocities solver iterations
int m_positionIterations; // Positions solver iterations
int m_driftIterations; // Drift solver iterations
int m_clusterIterations; // Cluster solver iterations
int m_collisionFlags; // Collisions flags
};
struct SoftBodyPoseData
{
btMatrix3x3FloatData m_rot; // Rotation
btMatrix3x3FloatData m_scale; // Scale
btMatrix3x3FloatData m_aqq; // Base scaling
btVector3FloatData m_positions; // Reference positions
btVector3FloatData m_com; // COM
int m_bvolume; // Is valid
int m_bframe; // Is frame
float m_restVolume; // Rest volume
int m_numPositions;
float *m_weights; // Weights
int m_numWeigts;
int m_pad;
};
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct btSoftBodyFloatData
{
btCollisionObjectFloatData m_collisionObjectData;
SoftBodyPoseData *m_pose;
SoftBodyMaterialData **m_materials;
SoftBodyNodeData *m_nodes;
SoftBodyLinkData *m_links;
SoftBodyFaceData *m_faces;
SoftBodyTetraData *m_tetrahedra;
SoftRigidAnchorData *m_anchors;
int m_numMaterials;
int m_numNodes;
int m_numLinks;
int m_numFaces;
int m_numTetrahedra;
int m_numAnchors;
SoftBodyConfigData m_config;
};
#endif //BT_SOFTBODY_FLOAT_DATA

View File

@@ -22,7 +22,7 @@ subject to the following restrictions:
#include "btSoftBodyHelpers.h"
#include "btSoftBodySolvers.h"
#include "btDefaultSoftBodySolver.h"
#include "LinearMath/btSerializer.h"
btSoftRigidDynamicsWorld::btSoftRigidDynamicsWorld(
@@ -51,6 +51,15 @@ btSoftRigidDynamicsWorld::btSoftRigidDynamicsWorld(
m_sbi.m_sparsesdf.Initialize();
m_sbi.m_sparsesdf.Reset();
m_sbi.air_density = (btScalar)1.2;
m_sbi.water_density = 0;
m_sbi.water_offset = 0;
m_sbi.water_normal = btVector3(0,0,0);
m_sbi.m_gravity.setValue(0,-10,0);
m_sbi.m_sparsesdf.Initialize();
}
btSoftRigidDynamicsWorld::~btSoftRigidDynamicsWorld()
@@ -303,3 +312,38 @@ void btSoftRigidDynamicsWorld::rayTestSingle(const btTransform& rayFromTrans,con
btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans,collisionObject,collisionShape,colObjWorldTransform,resultCallback);
}
}
void btSoftRigidDynamicsWorld::serializeSoftBodies(btSerializer* serializer)
{
int i;
//serialize all collision objects
for (i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
if (colObj->getInternalType() & btCollisionObject::CO_SOFT_BODY)
{
int len = colObj->calculateSerializeBufferSize();
btChunk* chunk = serializer->allocate(len,1);
const char* structType = colObj->serialize(chunk->m_oldPtr, serializer);
serializer->finalizeChunk(chunk,structType,BT_SOFTBODY_CODE,colObj);
}
}
}
void btSoftRigidDynamicsWorld::serialize(btSerializer* serializer)
{
serializer->startSerialization();
serializeSoftBodies(serializer);
serializeRigidBodies(serializer);
serializeCollisionObjects(serializer);
serializer->finishSerialization();
}

View File

@@ -44,6 +44,7 @@ protected:
void solveSoftBodiesConstraints( btScalar timeStep );
void serializeSoftBodies(btSerializer* serializer);
public:
@@ -95,6 +96,7 @@ public:
const btTransform& colObjWorldTransform,
RayResultCallback& resultCallback);
virtual void serialize(btSerializer* serializer);
};

View File

@@ -30,7 +30,7 @@ subject to the following restrictions:
#include <float.h>
/* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/
#define BT_BULLET_VERSION 277
#define BT_BULLET_VERSION 278
inline int btGetVersion()
{

File diff suppressed because it is too large Load Diff

View File

@@ -111,6 +111,7 @@ public:
# define MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) )
#endif
#define BT_SOFTBODY_CODE MAKE_ID('S','B','D','Y')
#define BT_COLLISIONOBJECT_CODE MAKE_ID('C','O','B','J')
#define BT_RIGIDBODY_CODE MAKE_ID('R','B','D','Y')
#define BT_CONSTRAINT_CODE MAKE_ID('C','O','N','S')
@@ -119,10 +120,11 @@ public:
#define BT_TRIANLGE_INFO_MAP MAKE_ID('T','M','A','P')
#define BT_SHAPE_CODE MAKE_ID('S','H','A','P')
#define BT_ARRAY_CODE MAKE_ID('A','R','A','Y')
#define BT_SBMATERIAL_CODE MAKE_ID('S','B','M','T')
#define BT_SBNODE_CODE MAKE_ID('S','B','N','D')
#define BT_DNA_CODE MAKE_ID('D','N','A','1')
struct btPointerUid
{
union
@@ -453,7 +455,7 @@ public:
m_buffer[9] = '2';
m_buffer[10] = '7';
m_buffer[11] = '7';
m_buffer[11] = '8';
}