Bullet Collision Detection & Physics Library
btSoftMultiBodyDynamicsWorld.cpp
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16
19
20//softbody & helpers
26
27
29 btDispatcher* dispatcher,
30 btBroadphaseInterface* pairCache,
31 btMultiBodyConstraintSolver* constraintSolver,
32 btCollisionConfiguration* collisionConfiguration,
33 btSoftBodySolver *softBodySolver ) :
34 btMultiBodyDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration),
35 m_softBodySolver( softBodySolver ),
36 m_ownsSolver(false)
37{
38 if( !m_softBodySolver )
39 {
40 void* ptr = btAlignedAlloc(sizeof(btDefaultSoftBodySolver),16);
42 m_ownsSolver = true;
43 }
44
46 m_drawNodeTree = true;
47 m_drawFaceTree = false;
48 m_drawClusterTree = false;
49 m_sbi.m_broadphase = pairCache;
50 m_sbi.m_dispatcher = dispatcher;
51 m_sbi.m_sparsesdf.Initialize();
52 m_sbi.m_sparsesdf.Reset();
53
58 m_sbi.m_gravity.setValue(0,-10,0);
59
60 m_sbi.m_sparsesdf.Initialize();
61
62
63}
64
66{
67 if (m_ownsSolver)
68 {
71 }
72}
73
75{
77 {
78 BT_PROFILE("predictUnconstraintMotionSoftBody");
79 m_softBodySolver->predictMotion( float(timeStep) );
80 }
81}
82
84{
85
86 // Let the solver grab the soft bodies and if necessary optimize for it
88
90 {
91 btAssert( "Solver initialization failed\n" );
92 }
93
95
98
99 //self collisions
100 for ( int i=0;i<m_softBodies.size();i++)
101 {
103 psb->defaultCollisionHandler(psb);
104 }
105
108
109 // End solver-wise simulation step
110 // ///////////////////////////////
111
112}
113
115{
116 BT_PROFILE("solveSoftConstraints");
117
118 if(m_softBodies.size())
119 {
121 }
122
123 // Solve constraints solver-wise
125
126}
127
128void btSoftMultiBodyDynamicsWorld::addSoftBody(btSoftBody* body, int collisionFilterGroup, int collisionFilterMask)
129{
131
132 // Set the soft body solver that will deal with this body
133 // to be the world's solver
135
137 collisionFilterGroup,
138 collisionFilterMask);
139
140}
141
143{
144 m_softBodies.remove(body);
145
147}
148
150{
151 btSoftBody* body = btSoftBody::upcast(collisionObject);
152 if (body)
153 removeSoftBody(body);
154 else
156}
157
159{
161
162 if (getDebugDrawer())
163 {
164 int i;
165 for ( i=0;i<this->m_softBodies.size();i++)
166 {
167 btSoftBody* psb=(btSoftBody*)this->m_softBodies[i];
169 {
172 }
173
175 {
179 }
180 }
181 }
182}
183
184
185
186
188{
194
197
198 btSoftSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btSoftMultiBodyDynamicsWorld* world,btCollisionWorld::RayResultCallback& resultCallback)
199 :m_rayFromWorld(rayFromWorld),
200 m_rayToWorld(rayToWorld),
201 m_world(world),
202 m_resultCallback(resultCallback)
203 {
208
209 btVector3 rayDir = (rayToWorld-rayFromWorld);
210
211 rayDir.normalize ();
213 m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
214 m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
215 m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
216 m_signs[0] = m_rayDirectionInverse[0] < 0.0;
217 m_signs[1] = m_rayDirectionInverse[1] < 0.0;
218 m_signs[2] = m_rayDirectionInverse[2] < 0.0;
219
221
222 }
223
224
225
226 virtual bool process(const btBroadphaseProxy* proxy)
227 {
230 return false;
231
232 btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
233
234 //only perform raycast if filterMask matches
236 {
237 //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
238 //btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
239#if 0
240#ifdef RECALCULATE_AABB
241 btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
242 collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
243#else
244 //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
245 const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
246 const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
247#endif
248#endif
249 //btScalar hitLambda = m_resultCallback.m_closestHitFraction;
250 //culling already done by broadphase
251 //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
252 {
254 collisionObject,
255 collisionObject->getCollisionShape(),
256 collisionObject->getWorldTransform(),
258 }
259 }
260 return true;
261 }
262};
263
264void btSoftMultiBodyDynamicsWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
265{
266 BT_PROFILE("rayTest");
269 btSoftSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback);
270
271#ifndef USE_BRUTEFORCE_RAYBROADPHASE
272 m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB);
273#else
274 for (int i=0;i<this->getNumCollisionObjects();i++)
275 {
276 rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
277 }
278#endif //USE_BRUTEFORCE_RAYBROADPHASE
279
280}
281
282
283void btSoftMultiBodyDynamicsWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
284 btCollisionObject* collisionObject,
285 const btCollisionShape* collisionShape,
286 const btTransform& colObjWorldTransform,
287 RayResultCallback& resultCallback)
288{
289 if (collisionShape->isSoftBody()) {
290 btSoftBody* softBody = btSoftBody::upcast(collisionObject);
291 if (softBody) {
292 btSoftBody::sRayCast softResult;
293 if (softBody->rayTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult))
294 {
295
296 if (softResult.fraction<= resultCallback.m_closestHitFraction)
297 {
298
300 shapeInfo.m_shapePart = 0;
301 shapeInfo.m_triangleIndex = softResult.index;
302 // get the normal
303 btVector3 rayDir = rayToTrans.getOrigin() - rayFromTrans.getOrigin();
304 btVector3 normal=-rayDir;
305 normal.normalize();
306
307 if (softResult.feature == btSoftBody::eFeature::Face)
308 {
309 normal = softBody->m_faces[softResult.index].m_normal;
310 if (normal.dot(rayDir) > 0) {
311 // normal always point toward origin of the ray
312 normal = -normal;
313 }
314 }
315
317 (collisionObject,
318 &shapeInfo,
319 normal,
320 softResult.fraction);
321 bool normalInWorldSpace = true;
322 resultCallback.addSingleResult(rayResult,normalInWorldSpace);
323 }
324 }
325 }
326 }
327 else {
328 btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans,collisionObject,collisionShape,colObjWorldTransform,resultCallback);
329 }
330}
331
332
334{
335 int i;
336 //serialize all collision objects
337 for (i=0;i<m_collisionObjects.size();i++)
338 {
341 {
342 int len = colObj->calculateSerializeBufferSize();
343 btChunk* chunk = serializer->allocate(len,1);
344 const char* structType = colObj->serialize(chunk->m_oldPtr, serializer);
345 serializer->finalizeChunk(chunk,structType,BT_SOFTBODY_CODE,colObj);
346 }
347 }
348
349}
350
352{
353
354 serializer->startSerialization();
355
356 serializeDynamicsWorldInfo( serializer);
357
358 serializeSoftBodies(serializer);
359
360 serializeRigidBodies(serializer);
361
362 serializeCollisionObjects(serializer);
363
364 serializer->finishSerialization();
365}
366
367
#define btAlignedFree(ptr)
#define btAlignedAlloc(size, alignment)
#define BT_PROFILE(name)
Definition: btQuickprof.h:215
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
#define btAssert(x)
Definition: btScalar.h:131
#define BT_SOFTBODY_CODE
Definition: btSerializer.h:118
int size() const
return the number of elements in the array
void remove(const T &key)
void push_back(const T &_Val)
The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs.
virtual void rayTest(const btVector3 &rayFrom, const btVector3 &rayTo, btBroadphaseRayCallback &rayCallback, const btVector3 &aabbMin=btVector3(0, 0, 0), const btVector3 &aabbMax=btVector3(0, 0, 0))=0
void * m_oldPtr
Definition: btSerializer.h:56
btCollisionConfiguration allows to configure Bullet collision detection stack allocator size,...
btCollisionObject can be used to manage collision detection objects.
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
btTransform & getWorldTransform()
btBroadphaseProxy * getBroadphaseHandle()
int getInternalType() const
reserved for Bullet internal usage
virtual int calculateSerializeBufferSize() const
const btCollisionShape * getCollisionShape() const
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
bool isSoftBody() const
virtual void getAabb(const btTransform &t, btVector3 &aabbMin, btVector3 &aabbMax) const =0
getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t.
virtual btIDebugDraw * getDebugDrawer()
btBroadphaseInterface * m_broadphasePairCache
virtual void removeCollisionObject(btCollisionObject *collisionObject)
virtual void addCollisionObject(btCollisionObject *collisionObject, int collisionFilterGroup=btBroadphaseProxy::DefaultFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter)
btAlignedObjectArray< btCollisionObject * > m_collisionObjects
int getNumCollisionObjects() const
btIDebugDraw * m_debugDrawer
static void rayTestSingle(const btTransform &rayFromTrans, const btTransform &rayToTrans, btCollisionObject *collisionObject, const btCollisionShape *collisionShape, const btTransform &colObjWorldTransform, RayResultCallback &resultCallback)
rayTestSingle performs a raycast call and calls the resultCallback.
void serializeCollisionObjects(btSerializer *serializer)
void serializeRigidBodies(btSerializer *serializer)
virtual void internalSingleStepSimulation(btScalar timeStep)
void serializeDynamicsWorldInfo(btSerializer *serializer)
virtual void removeCollisionObject(btCollisionObject *collisionObject)
removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise ca...
virtual void predictUnconstraintMotion(btScalar timeStep)
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:76
virtual int getDebugMode() const =0
The btMultiBodyDynamicsWorld adds Featherstone multi body dynamics to Bullet This implementation is s...
virtual btChunk * allocate(size_t size, int numElements)=0
virtual void finishSerialization()=0
virtual void startSerialization()=0
virtual void finalizeChunk(btChunk *chunk, const char *structType, int chunkCode, void *oldPtr)=0
virtual void solveConstraints(float solverdt)=0
Solve constraints for a set of soft bodies.
float getTimeScale()
Return the timescale that the simulation is using.
virtual void predictMotion(float solverdt)=0
Predict motion of soft bodies into next timestep.
virtual bool checkInitialized()=0
Ensure that this solver is initialized.
virtual ~btSoftBodySolver()
virtual void updateSoftBodies()=0
Perform necessary per-step updates of soft bodies such as recomputing normals and bounding boxes.
virtual void optimize(btAlignedObjectArray< btSoftBody * > &softBodies, bool forceUpdate=false)=0
Optimize soft bodies in this solver.
The btSoftBody is an class to simulate cloth and volumetric soft bodies.
Definition: btSoftBody.h:72
void defaultCollisionHandler(const btCollisionObjectWrapper *pcoWrap)
bool rayTest(const btVector3 &rayFrom, const btVector3 &rayTo, sRayCast &results)
Ray casting using rayFrom and rayTo in worldspace, (not direction!)
void setSoftBodySolver(btSoftBodySolver *softBodySolver)
Definition: btSoftBody.h:910
tFaceArray m_faces
Definition: btSoftBody.h:661
static void solveClusters(const btAlignedObjectArray< btSoftBody * > &bodies)
static const btSoftBody * upcast(const btCollisionObject *colObj)
Definition: btSoftBody.h:936
btSoftBodySolver * m_softBodySolver
Solver classes that encapsulate multiple soft bodies for solving.
virtual void predictUnconstraintMotion(btScalar timeStep)
static void rayTestSingle(const btTransform &rayFromTrans, const btTransform &rayToTrans, btCollisionObject *collisionObject, const btCollisionShape *collisionShape, const btTransform &colObjWorldTransform, RayResultCallback &resultCallback)
rayTestSingle performs a raycast call and calls the resultCallback.
virtual void internalSingleStepSimulation(btScalar timeStep)
virtual void serialize(btSerializer *serializer)
Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (see B...
void solveSoftBodiesConstraints(btScalar timeStep)
virtual void removeCollisionObject(btCollisionObject *collisionObject)
removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise ca...
void addSoftBody(btSoftBody *body, int collisionFilterGroup=btBroadphaseProxy::DefaultFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter)
virtual void rayTest(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, RayResultCallback &resultCallback) const
rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback This ...
btSoftMultiBodyDynamicsWorld(btDispatcher *dispatcher, btBroadphaseInterface *pairCache, btMultiBodyConstraintSolver *constraintSolver, btCollisionConfiguration *collisionConfiguration, btSoftBodySolver *softBodySolver=0)
void serializeSoftBodies(btSerializer *serializer)
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
void setIdentity()
Set this transformation to the identity.
Definition: btTransform.h:172
btVector3 & getOrigin()
Return the origin vector translation.
Definition: btTransform.h:117
void setOrigin(const btVector3 &origin)
Set the translational element.
Definition: btTransform.h:150
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:84
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition: btVector3.h:235
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:652
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition: btVector3.h:309
The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
btVector3 m_rayDirectionInverse
added some cached data to accelerate ray-AABB tests
LocalShapeInfo gives extra information for complex shapes Currently, only btTriangleMeshShape is avai...
RayResultCallback is used to report new raycast results.
virtual bool needsCollision(btBroadphaseProxy *proxy0) const
virtual btScalar addSingleResult(LocalRayResult &rayResult, bool normalInWorldSpace)=0
static void DrawNodeTree(btSoftBody *psb, btIDebugDraw *idraw, int mindepth=0, int maxdepth=-1)
static void DrawFaceTree(btSoftBody *psb, btIDebugDraw *idraw, int mindepth=0, int maxdepth=-1)
static void DrawClusterTree(btSoftBody *psb, btIDebugDraw *idraw, int mindepth=0, int maxdepth=-1)
static void Draw(btSoftBody *psb, btIDebugDraw *idraw, int drawflags=fDrawFlags::Std)
static void DrawFrame(btSoftBody *psb, btIDebugDraw *idraw)
btScalar air_density
Definition: btSoftBody.h:45
btDispatcher * m_dispatcher
Definition: btSoftBody.h:51
btScalar water_density
Definition: btSoftBody.h:46
btSparseSdf< 3 > m_sparsesdf
Definition: btSoftBody.h:53
btVector3 m_gravity
Definition: btSoftBody.h:52
btVector3 water_normal
Definition: btSoftBody.h:49
btScalar water_offset
Definition: btSoftBody.h:47
btBroadphaseInterface * m_broadphase
Definition: btSoftBody.h:50
eFeature::_ feature
soft body
Definition: btSoftBody.h:166
btScalar fraction
feature index
Definition: btSoftBody.h:168
int index
feature type
Definition: btSoftBody.h:167
const btSoftMultiBodyDynamicsWorld * m_world
btSoftSingleRayCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, const btSoftMultiBodyDynamicsWorld *world, btCollisionWorld::RayResultCallback &resultCallback)
btCollisionWorld::RayResultCallback & m_resultCallback
virtual bool process(const btBroadphaseProxy *proxy)