Created a KX_SoftBodyDeformer for real-time soft bodies.

Added SetDeformer/GetDeformer() to KX_GameObject.
Store mapping between graphics/soft body vertices (work-in-progress)
Real-time soft body integration is still very premature, but
for a quick preview, see this testfile:
http://bulletphysics.com/ftp/pub/test/index.php?dir=blender/&file=soft_test.blend
This commit is contained in:
Erwin Coumans 2008-09-24 03:12:10 +00:00
parent 7eae8d0c7b
commit 3b09c0b0d5
17 changed files with 369 additions and 64 deletions

@ -46,6 +46,7 @@ IMPLICIT_CONVEX_SHAPES_START_HERE,
CONCAVE_SHAPES_START_HERE,
//keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!
TRIANGLE_MESH_SHAPE_PROXYTYPE,
SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE,
///used for demo integration FAST/Swift collision library and Bullet
FAST_CONCAVE_MESH_PROXYTYPE,
//terrain

@ -117,5 +117,5 @@ const btVector3& btScaledBvhTriangleMeshShape::getLocalScaling() const
void btScaledBvhTriangleMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
{
///don't make this a movable object!
btAssert(0);
// btAssert(0);
}

@ -39,7 +39,7 @@ public:
virtual int getShapeType() const
{
//use un-used 'FAST_CONCAVE_MESH_PROXYTYPE' for now, later add SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE to btBroadphaseProxy.h
return FAST_CONCAVE_MESH_PROXYTYPE;
return SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE;
}
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
@ -49,6 +49,16 @@ public:
virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
btBvhTriangleMeshShape* getChildShape()
{
return m_bvhTriMeshShape;
}
const btBvhTriangleMeshShape* getChildShape() const
{
return m_bvhTriMeshShape;
}
//debugging
virtual const char* getName()const {return "SCALEDBVHTRIANGLEMESH";}

@ -29,7 +29,7 @@ subject to the following restrictions:
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
class btBroadphaseInterface;
class btCollisionDispatcher;
class btDispatcher;
/* btSoftBodyWorldInfo */
struct btSoftBodyWorldInfo
@ -39,7 +39,7 @@ struct btSoftBodyWorldInfo
btScalar water_offset;
btVector3 water_normal;
btBroadphaseInterface* m_broadphase;
btCollisionDispatcher* m_dispatcher;
btDispatcher* m_dispatcher;
btVector3 m_gravity;
btSparseSdf<3> m_sparsesdf;
};
@ -607,6 +607,7 @@ public:
virtual ~btSoftBody();
/* Check for existing link */
btAlignedObjectArray<int> m_userIndexMapping;
virtual void setCollisionShape(btCollisionShape* collisionShape)
{

@ -21,6 +21,10 @@ subject to the following restrictions:
#include "btSoftBody.h"
#include "btSoftBodyHelpers.h"
btSoftRigidDynamicsWorld::btSoftRigidDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration)
:btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration)
{
@ -28,6 +32,11 @@ m_drawFlags = fDrawFlags::Std;
m_drawNodeTree = true;
m_drawFaceTree = false;
m_drawClusterTree = false;
m_sbi.m_broadphase = pairCache;
m_sbi.m_dispatcher = dispatcher;
m_sbi.m_sparsesdf.Initialize();
m_sbi.m_sparsesdf.Reset();
}
btSoftRigidDynamicsWorld::~btSoftRigidDynamicsWorld()

@ -13,12 +13,12 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
#ifndef BT_SOFT_RIGID_DYNAMICS_WORLD_H
#define BT_SOFT_RIGID_DYNAMICS_WORLD_H
class btSoftBody;
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
#include "btSoftBody.h"
typedef btAlignedObjectArray<btSoftBody*> btSoftBodyArray;
class btSoftRigidDynamicsWorld : public btDiscreteDynamicsWorld
@ -29,6 +29,7 @@ class btSoftRigidDynamicsWorld : public btDiscreteDynamicsWorld
bool m_drawNodeTree;
bool m_drawFaceTree;
bool m_drawClusterTree;
btSoftBodyWorldInfo m_sbi;
protected:
@ -41,7 +42,6 @@ protected:
void solveSoftBodiesConstraints();
public:
btSoftRigidDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration);
@ -57,6 +57,15 @@ public:
int getDrawFlags() const { return(m_drawFlags); }
void setDrawFlags(int f) { m_drawFlags=f; }
btSoftBodyWorldInfo& getWorldInfo()
{
return m_sbi;
}
const btSoftBodyWorldInfo& getWorldInfo() const
{
return m_sbi;
}
btSoftBodyArray& getSoftBodyArray()
{

@ -869,6 +869,8 @@ bool HullLibrary::CleanupVertices(unsigned int svcount,
{
if ( svcount == 0 ) return false;
m_vertexIndexMapping.resize(0);
#define EPSILON btScalar(0.000001) /* close enough to consider two btScalaring point numbers to be 'the same'. */
@ -1027,6 +1029,7 @@ bool HullLibrary::CleanupVertices(unsigned int svcount,
v[0] = px;
v[1] = py;
v[2] = pz;
}
break;
@ -1041,6 +1044,7 @@ bool HullLibrary::CleanupVertices(unsigned int svcount,
dest[2] = pz;
vcount++;
}
m_vertexIndexMapping.push_back(j);
}
}
@ -1116,13 +1120,22 @@ bool HullLibrary::CleanupVertices(unsigned int svcount,
void HullLibrary::BringOutYourDead(const btVector3* verts,unsigned int vcount, btVector3* overts,unsigned int &ocount,unsigned int *indices,unsigned indexcount)
{
btAlignedObjectArray<int>tmpIndices;
tmpIndices.resize(m_vertexIndexMapping.size());
int i;
for (i=0;i<m_vertexIndexMapping.size();i++)
{
tmpIndices[i] = m_vertexIndexMapping[i];
}
TUIntArray usedIndices;
usedIndices.resize(static_cast<int>(vcount));
memset(&usedIndices[0],0,sizeof(unsigned int)*vcount);
ocount = 0;
for (unsigned int i=0; i<indexcount; i++)
for (i=0; i<indexcount; i++)
{
unsigned int v = indices[i]; // original array index
@ -1141,11 +1154,19 @@ void HullLibrary::BringOutYourDead(const btVector3* verts,unsigned int vcount, b
overts[ocount][1] = verts[v][1];
overts[ocount][2] = verts[v][2];
for (int k=0;k<m_vertexIndexMapping.size();k++)
{
if (tmpIndices[k]==v)
m_vertexIndexMapping[k]=ocount;
}
ocount++; // increment output vert count
btAssert( ocount >=0 && ocount <= vcount );
usedIndices[static_cast<int>(v)] = ocount; // assign new index remapping
}
}

@ -192,6 +192,9 @@ class HullLibrary
public:
btAlignedObjectArray<int> m_vertexIndexMapping;
HullError CreateConvexHull(const HullDesc& desc, // describes the input request
HullResult& result); // contains the resulst
HullError ReleaseResult(HullResult &result); // release memory allocated for this result, we are done with it.

@ -743,7 +743,8 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
}
// Determine if we need to make a skinned mesh
if (mesh->dvert || mesh->key) {
if (mesh->dvert || mesh->key || ((blenderobj->gameflag & OB_SOFT_BODY) != 0))
{
meshobj = new BL_SkinMeshObject(mesh, lightlayer);
skinMesh = true;
}
@ -1554,20 +1555,20 @@ static KX_GameObject *gameobject_from_blenderobject(
// not that we can have shape keys without dvert!
BL_ShapeDeformer *dcont = new BL_ShapeDeformer((BL_DeformableGameObject*)gameobj,
ob, (BL_SkinMeshObject*)meshobj);
((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
if (bHasArmature)
dcont->LoadShapeDrivers(ob->parent);
} else if (bHasArmature) {
BL_SkinDeformer *dcont = new BL_SkinDeformer((BL_DeformableGameObject*)gameobj,
ob, (BL_SkinMeshObject*)meshobj);
((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
} else if (bHasDvert) {
// this case correspond to a mesh that can potentially deform but not with the
// object to which it is attached for the moment. A skin mesh was created in
// BL_ConvertMesh() so must create a deformer too!
BL_MeshDeformer *dcont = new BL_MeshDeformer((BL_DeformableGameObject*)gameobj,
ob, (BL_SkinMeshObject*)meshobj);
((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
}
MT_Point3 min = MT_Point3(center) - MT_Vector3(extents);
@ -2193,8 +2194,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
if (obj && blenderobj->parent && blenderobj->parent->type==OB_ARMATURE && blenderobj->partype==PARSKEL){
KX_GameObject *par = converter->FindGameObject(blenderobj->parent);
if (par && obj->m_pDeformer)
((BL_SkinDeformer*)obj->m_pDeformer)->SetArmature((BL_ArmatureObject*) par);
if (par && obj->GetDeformer())
((BL_SkinDeformer*)obj->GetDeformer())->SetArmature((BL_ArmatureObject*) par);
}
}
}

@ -83,9 +83,21 @@ public:
return (m_pDeformer) ? ((BL_MeshDeformer*)m_pDeformer)->GetMesh()->key : NULL;
}
virtual void SetDeformer(class RAS_Deformer* deformer)
{
m_pDeformer = deformer;
}
virtual class RAS_Deformer* GetDeformer()
{
return m_pDeformer;
}
public:
RAS_Deformer *m_pDeformer;
protected:
RAS_Deformer *m_pDeformer;
class BL_ShapeActionActuator *m_activeAct;
double m_lastframe;
Object* m_blendobj;

@ -87,7 +87,7 @@ void BL_SkinMeshObject::UpdateBuckets(void* clientobj,double* oglmatrix,bool use
continue;
RAS_MeshSlot *slot = *it->m_slots[clientobj];
slot->m_pDeformer = ((BL_DeformableGameObject*)clientobj)->m_pDeformer;
slot->m_pDeformer = ((BL_DeformableGameObject*)clientobj)->GetDeformer();
}
RAS_MeshObject::UpdateBuckets(clientobj, oglmatrix, useObjectColor, rgbavec, visible, culled);

@ -38,6 +38,8 @@
#include "RAS_MeshObject.h"
#include "KX_Scene.h"
#include "SYS_System.h"
#include "BL_SkinMeshObject.h"
#include "BulletSoftBody/btSoftBody.h"
#include "PHY_Pro.h" //todo cleanup
#include "KX_ClientObjectInfo.h"
@ -765,7 +767,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
}
case KX_BOUNDMESH:
{
if (!ci.m_mass)
if (!ci.m_mass ||objprop->m_softbody)
{
// mesh shapes can be shared, check first if we already have a shape on that mesh
class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, false);
@ -988,6 +990,112 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
physicscontroller->SetObject(gameobj->GetSGNode());
class KX_SoftBodyDeformer : public RAS_Deformer
{
btSoftBody* m_softBody;
class BL_SkinMeshObject* m_pMeshObject;
class BL_DeformableGameObject* m_gameobj;
public:
KX_SoftBodyDeformer(btSoftBody* softBody,BL_SkinMeshObject* pMeshObject,BL_DeformableGameObject* gameobj)
: m_softBody(softBody),
m_pMeshObject(pMeshObject),
m_gameobj(gameobj)
{
//printf("KX_SoftBodyDeformer\n");
};
virtual ~KX_SoftBodyDeformer()
{
//printf("~KX_SoftBodyDeformer\n");
};
virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map)
{
//printf("relink\n");
}
virtual bool Apply(class RAS_IPolyMaterial *polymat)
{
//printf("apply\n");
RAS_MeshSlot::iterator it;
RAS_MeshMaterial *mmat;
RAS_MeshSlot *slot;
size_t i;
// update the vertex in m_transverts
Update();
// The vertex cache can only be updated for this deformer:
// Duplicated objects with more than one ploymaterial (=multiple mesh slot per object)
// share the same mesh (=the same cache). As the rendering is done per polymaterial
// cycling through the objects, the entire mesh cache cannot be updated in one shot.
mmat = m_pMeshObject->GetMeshMaterial(polymat);
if(!mmat->m_slots[(void*)m_gameobj])
return true;
slot = *mmat->m_slots[(void*)m_gameobj];
// for each array
for(slot->begin(it); !slot->end(it); slot->next(it))
{
// for each vertex
// copy the untransformed data from the original mvert
int count = 0;
{
for(i=it.startvertex; i<it.endvertex; i++,count++)
{
}
}
btSoftBody::tNodeArray& nodes(m_softBody->m_nodes);
if (count == m_softBody->m_userIndexMapping.size())
{
int index = 0;
for(i=it.startvertex; i<it.endvertex; i++,index++) {
RAS_TexVert& v = it.vertex[i];
MT_Point3 pt (
nodes[m_softBody->m_userIndexMapping[index]].m_x.getX(),
nodes[m_softBody->m_userIndexMapping[index]].m_x.getY(),
nodes[m_softBody->m_userIndexMapping[index]].m_x.getZ());
v.SetXYZ(pt);
//(m_transverts[v.getOrigIndex()]);
}
}
}
return true;
}
virtual bool Update(void)
{
//printf("update\n");
return true;//??
}
virtual RAS_Deformer *GetReplica()
{
//printf("getReplica\n");
return 0;
}
protected:
//class RAS_MeshObject *m_pMesh;
};
///test for soft bodies
if (objprop->m_softbody && physicscontroller)
{
btSoftBody* softBody = physicscontroller->GetSoftBody();
if (softBody && gameobj->GetMesh(0))
{
//should be a mesh then, so add a soft body deformer
KX_SoftBodyDeformer* softbodyDeformer = new KX_SoftBodyDeformer(softBody, (BL_SkinMeshObject*)gameobj->GetMesh(0),(BL_DeformableGameObject*)gameobj);
gameobj->SetDeformer(softbodyDeformer);
}
}
}

@ -332,6 +332,14 @@ public:
m_pPhysicsController1 = physicscontroller;
}
virtual class RAS_Deformer* GetDeformer()
{
return 0;
}
virtual void SetDeformer(class RAS_Deformer* deformer)
{
}
/**
* @section Coordinate system manipulation functions

@ -977,10 +977,10 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
{
BL_DeformableGameObject* newobj = static_cast<BL_DeformableGameObject*>( gameobj );
if (newobj->m_pDeformer)
if (newobj->GetDeformer())
{
delete newobj->m_pDeformer;
newobj->m_pDeformer = NULL;
delete newobj->GetDeformer();
newobj->SetDeformer(NULL);
}
if (mesh->IsDeformed())
@ -1030,7 +1030,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
NULL
);
}
newobj->m_pDeformer = shapeDeformer;
newobj->SetDeformer( shapeDeformer);
}
else if (bHasArmature)
{
@ -1042,14 +1042,14 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
static_cast<BL_ArmatureObject*>( parentobj )
);
releaseParent= false;
newobj->m_pDeformer = skinDeformer;
newobj->SetDeformer(skinDeformer);
}
else if (bHasDvert)
{
BL_MeshDeformer* meshdeformer = new BL_MeshDeformer(
newobj, oldblendobj, static_cast<BL_SkinMeshObject*>(mesh)
);
newobj->m_pDeformer = meshdeformer;
newobj->SetDeformer(meshdeformer);
}
// release parent reference if its not being used

@ -20,7 +20,11 @@ subject to the following restrictions:
#include "CcdPhysicsEnvironment.h"
#include "RAS_MeshObject.h"
#include "BulletSoftBody/btSoftBody.h"
#include "BulletSoftBody//btSoftBodyInternals.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "LinearMath/btConvexHull.h"
#include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
class BP_Proxy;
@ -135,11 +139,7 @@ btSoftBody* CcdPhysicsController::GetSoftBody()
#include "BulletSoftBody/btSoftBodyHelpers.h"
btVector3 pts[3] = {btVector3(0,0,0),
btVector3(0,1,0),
btVector3(1,1,0)};
int triangles[3] = {0,1,2};
btSoftBodyWorldInfo sbi;
void CcdPhysicsController::CreateRigidbody()
{
@ -151,8 +151,13 @@ void CcdPhysicsController::CreateRigidbody()
//create a collision object
int shapeType = m_cci.m_collisionShape ? m_cci.m_collisionShape->getShapeType() : 0;
//disable soft body until first sneak preview is ready
if (0)//m_cci.m_bSoft)
if (m_cci.m_bSoft && m_cci.m_collisionShape &&
(shapeType == CONVEX_HULL_SHAPE_PROXYTYPE))
//(shapeType == TRIANGLE_MESH_SHAPE_PROXYTYPE) |
//(shapeType == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE)))
{
btRigidBody::btRigidBodyConstructionInfo rbci(m_cci.m_mass,m_bulletMotionState,m_collisionShape,m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
rbci.m_linearDamping = m_cci.m_linearDamping;
@ -161,54 +166,161 @@ void CcdPhysicsController::CreateRigidbody()
rbci.m_restitution = m_cci.m_restitution;
sbi.m_broadphase = this->m_cci.m_physicsEnv->getBroadphase();
sbi.m_dispatcher = (btCollisionDispatcher*) m_cci.m_physicsEnv->getDispatcher();
int nodecount = 0;
int numtriangles = 1;
btVector3 p = trans.getOrigin();
btVector3 p(0,0,0);// = getOrigin();
btScalar h = 1.f;
btSoftRigidDynamicsWorld* softDynaWorld = (btSoftRigidDynamicsWorld*)m_cci.m_physicsEnv->getDynamicsWorld();
PHY__Vector3 grav;
m_cci.m_physicsEnv->getGravity(grav);
sbi.m_gravity.setValue(grav[0],grav[1],grav[2]);
grav[0] = softDynaWorld->getGravity().getX();
grav[1] = softDynaWorld->getGravity().getY();
grav[2] = softDynaWorld->getGravity().getZ();
softDynaWorld->getWorldInfo().m_gravity.setValue(grav[0],grav[1],grav[2]); //??
const btVector3 c[]={ p+h*btVector3(-1,-1,-1),
p+h*btVector3(+1,-1,-1),
p+h*btVector3(-1,+1,-1),
p+h*btVector3(+1,+1,-1),
p+h*btVector3(-1,-1,+1),
p+h*btVector3(+1,-1,+1),
p+h*btVector3(-1,+1,+1),
p+h*btVector3(+1,+1,+1)};
int i=0;
const int n=15;
//btSoftBody* psb=btSoftBodyHelpers::CreateRope(sbi, btVector3(-10,0,i*0.25),btVector3(10,0,i*0.25), 16,1+2);
btSoftBody* psb = btSoftBodyHelpers::CreateFromConvexHull(sbi,c,8);
m_object = psb;//btSoftBodyHelpers::CreateFromTriMesh(sbi,&pts[0].getX(),triangles,numtriangles);
btSoftBody* psb = 0;
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RS;//btSoftBody::fCollision::CL_SS+ btSoftBody::fCollision::CL_RS;
if (m_cci.m_collisionShape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE)
{
btConvexHullShape* convexHull = (btConvexHullShape* )m_cci.m_collisionShape;
btAlignedObjectArray<btVector3> transformedVertices;
transformedVertices.resize(convexHull->getNumPoints());
for (int i=0;i<convexHull->getNumPoints();i++)
{
transformedVertices[i] = trans(convexHull->getPoints()[i]);
}
sbi.m_sparsesdf.Reset();
sbi.m_sparsesdf.Initialize();
//psb = btSoftBodyHelpers::CreateFromConvexHull(sbi,&transformedVertices[0],convexHull->getNumPoints());
psb->generateBendingConstraints(2);
{
int nvertices = convexHull->getNumPoints();
const btVector3* vertices = &transformedVertices[0];
btSoftBodyWorldInfo& worldInfo = softDynaWorld->getWorldInfo();
psb->m_cfg.kDF=1;
psb->activate();
psb->setActivationState(1);
psb->setDeactivationTime(1.f);
psb->m_cfg.piterations = 4;
HullDesc hdsc(QF_TRIANGLES,nvertices,vertices);
HullResult hres;
HullLibrary hlib;/*??*/
hdsc.mMaxVertices=nvertices;
hlib.CreateConvexHull(hdsc,hres);
psb=new btSoftBody(&worldInfo,(int)hres.mNumOutputVertices,
&hres.m_OutputVertices[0],0);
for(int i=0;i<(int)hres.mNumFaces;++i)
{
const int idx[]={ hres.m_Indices[i*3+0],
hres.m_Indices[i*3+1],
hres.m_Indices[i*3+2]};
if(idx[0]<idx[1]) psb->appendLink( idx[0],idx[1]);
if(idx[1]<idx[2]) psb->appendLink( idx[1],idx[2]);
if(idx[2]<idx[0]) psb->appendLink( idx[2],idx[0]);
psb->appendFace(idx[0],idx[1],idx[2]);
}
{
for (int i=0;i<hlib.m_vertexIndexMapping.size();i++)
psb->m_userIndexMapping.push_back(hlib.m_vertexIndexMapping[i]);
//psb->m_userIndexMapping.push_back(hres.m_Indices[i]);
}
hlib.ReleaseResult(hres);
psb->randomizeConstraints();
}
} else
{
/*
if (m_cci.m_collisionShape->getShapeType() ==SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE)
{
btScaledBvhTriangleMeshShape* scaledtrimeshshape = (btScaledBvhTriangleMeshShape*) m_cci.m_collisionShape;
btBvhTriangleMeshShape* trimeshshape = scaledtrimeshshape->getChildShape();
///only deal with meshes that have 1 sub part/component, for now
if (trimeshshape->getMeshInterface()->getNumSubParts()==1)
{
unsigned char* vertexBase;
PHY_ScalarType vertexType;
int numverts;
int vertexstride;
unsigned char* indexbase;
int indexstride;
int numtris;
PHY_ScalarType indexType;
trimeshshape->getMeshInterface()->getLockedVertexIndexBase(&vertexBase,numverts,vertexType,vertexstride,&indexbase,indexstride,numtris,indexType);
psb = btSoftBodyHelpers::CreateFromTriMesh(sbi,(const btScalar*)vertexBase,(const int*)indexbase,numtris);
}
} else
{
btBvhTriangleMeshShape* trimeshshape = (btBvhTriangleMeshShape*) m_cci.m_collisionShape;
///only deal with meshes that have 1 sub part/component, for now
if (trimeshshape->getMeshInterface()->getNumSubParts()==1)
{
unsigned char* vertexBase;
PHY_ScalarType vertexType;
int numverts;
int vertexstride;
unsigned char* indexbase;
int indexstride;
int numtris;
PHY_ScalarType indexType;
trimeshshape->getMeshInterface()->getLockedVertexIndexBase(&vertexBase,numverts,vertexType,vertexstride,&indexbase,indexstride,numtris,indexType);
psb = btSoftBodyHelpers::CreateFromTriMesh(sbi,(const btScalar*)vertexBase,(const int*)indexbase,numtris);
}
//psb = btSoftBodyHelpers::CreateFromTriMesh(sbi,&pts[0].getX(),triangles,numtriangles);
}
*/
}
m_object = psb;
//psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RS;//btSoftBody::fCollision::CL_SS+ btSoftBody::fCollision::CL_RS;
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RS + btSoftBody::fCollision::CL_SS;
//btSoftBody::Material* pm=psb->appendMaterial();
btSoftBody::Material* pm=psb->m_materials[0];
pm->m_kLST = 0.1f;
//pm->m_kAST = 0.01f;
//pm->m_kVST = 0.001f;
psb->generateBendingConstraints(2,pm);
/*
psb->m_cfg.kDF = 0.1f;//1.f;
psb->m_cfg.kDP = 0.0001;
//psb->m_cfg.kDP = 0.005;
psb->m_cfg.kCHR = 0.1;
//psb->m_cfg.kVCF = 0.1f;
psb->m_cfg.kVCF = 0.0001f;
//psb->m_cfg.kAHR = 0.1f;
psb->m_cfg.kAHR = 0.0001f;
psb->m_cfg.kMT = 0.1f;
//psb->m_cfg.kDF=1;
*/
// psb->activate();
// psb->setActivationState(1);
// psb->setDeactivationTime(1.f);
//psb->m_cfg.piterations = 4;
//psb->m_materials[0]->m_kLST = 0.1+(i/(btScalar)(n-1))*0.9;
psb->setTotalMass(20);
psb->setTotalMass(m_cci.m_mass);
psb->generateClusters(64);
psb->setCollisionFlags(0);
m_object->setCollisionShape(rbci.m_collisionShape);
// m_object->setCollisionShape(rbci.m_collisionShape);
btTransform startTrans;
if (rbci.m_motionState)
@ -218,8 +330,13 @@ void CcdPhysicsController::CreateRigidbody()
{
startTrans = rbci.m_startWorldTransform;
}
startTrans.setIdentity();
m_object->setWorldTransform(startTrans);
m_object->setInterpolationWorldTransform(startTrans);
m_MotionState->setWorldPosition(0,0,0);
m_MotionState->setWorldOrientation(0,0,0,1);
} else
{

@ -452,6 +452,8 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
}
void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctrl)
{
//also remove constraint

@ -216,7 +216,10 @@ protected:
void SyncMotionStates(float timeStep);
class btSoftRigidDynamicsWorld* getDynamicsWorld()
{
return m_dynamicsWorld;
}
class btConstraintSolver* GetConstraintSolver();