Bullet Collision Detection & Physics Library
btSoftRigidDynamicsWorld.cpp
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
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
18
19//softbody & helpers
20#include "btSoftBody.h"
21#include "btSoftBodyHelpers.h"
22#include "btSoftBodySolvers.h"
25
32 m_softBodySolver(softBodySolver),
33 m_ownsSolver(false)
34{
36 {
37 void* ptr = btAlignedAlloc(sizeof(btDefaultSoftBodySolver), 16);
39 m_ownsSolver = true;
40 }
41
43 m_drawNodeTree = true;
44 m_drawFaceTree = false;
45 m_drawClusterTree = false;
50
54 m_sbi.water_normal = btVector3(0, 0, 0);
55 m_sbi.m_gravity.setValue(0, -10, 0);
56
58}
59
61{
62 if (m_ownsSolver)
63 {
66 }
67}
68
70{
72 {
73 BT_PROFILE("predictUnconstraintMotionSoftBody");
74 m_softBodySolver->predictMotion(float(timeStep));
75 }
76}
77
79{
80 // Let the solver grab the soft bodies and if necessary optimize for it
82
84 {
85 btAssert("Solver initialization failed\n");
86 }
87
89
92
93 //self collisions
94 for (int i = 0; i < m_softBodies.size(); i++)
95 {
98 }
99
102
103 // End solver-wise simulation step
104 // ///////////////////////////////
105}
106
108{
109 BT_PROFILE("solveSoftConstraints");
110
111 if (m_softBodies.size())
112 {
114 }
115
116 // Solve constraints solver-wise
118}
119
121{
123
124 // Set the soft body solver that will deal with this body
125 // to be the world's solver
127
131}
132
134{
135 m_softBodies.remove(body);
136
138}
139
141{
143 if (body)
144 removeSoftBody(body);
145 else
147}
148
150{
152
153 if (getDebugDrawer())
154 {
155 int i;
156 for (i = 0; i < this->m_softBodies.size(); i++)
157 {
158 btSoftBody* psb = (btSoftBody*)this->m_softBodies[i];
160 {
163 }
164
166 {
170 }
171 }
172 }
173}
174
176{
182
185
189 m_world(world),
191 {
196
197 btVector3 rayDir = (rayToWorld - rayFromWorld);
198
199 rayDir.normalize();
201 m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
202 m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
203 m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
204 m_signs[0] = m_rayDirectionInverse[0] < 0.0;
205 m_signs[1] = m_rayDirectionInverse[1] < 0.0;
206 m_signs[2] = m_rayDirectionInverse[2] < 0.0;
207
209 }
210
211 virtual bool process(const btBroadphaseProxy* proxy)
212 {
215 return false;
216
218
219 //only perform raycast if filterMask matches
220 if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
221 {
222 //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
223 //btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
224#if 0
225#ifdef RECALCULATE_AABB
227 collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
228#else
229 //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
230 const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
231 const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
232#endif
233#endif
234 //btScalar hitLambda = m_resultCallback.m_closestHitFraction;
235 //culling already done by broadphase
236 //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
237 {
240 collisionObject->getCollisionShape(),
241 collisionObject->getWorldTransform(),
243 }
244 }
245 return true;
246 }
247};
248
250{
251 BT_PROFILE("rayTest");
255
256#ifndef USE_BRUTEFORCE_RAYBROADPHASE
258#else
259 for (int i = 0; i < this->getNumCollisionObjects(); i++)
260 {
261 rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
262 }
263#endif //USE_BRUTEFORCE_RAYBROADPHASE
264}
265
271{
272 if (collisionShape->isSoftBody())
273 {
275 if (softBody)
276 {
278 if (softBody->rayTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult))
279 {
280 if (softResult.fraction <= resultCallback.m_closestHitFraction)
281 {
284 shapeInfo.m_triangleIndex = softResult.index;
285 // get the normal
286 btVector3 rayDir = rayToTrans.getOrigin() - rayFromTrans.getOrigin();
287 btVector3 normal = -rayDir;
288 normal.normalize();
289
291 {
292 normal = softBody->m_faces[softResult.index].m_normal;
293 if (normal.dot(rayDir) > 0)
294 {
295 // normal always point toward origin of the ray
296 normal = -normal;
297 }
298 }
299
301 &shapeInfo,
302 normal,
303 softResult.fraction);
304 bool normalInWorldSpace = true;
306 }
307 }
308 }
309 }
310 else
311 {
313 }
314}
315
317{
318 int i;
319 //serialize all collision objects
320 for (i = 0; i < m_collisionObjects.size(); i++)
321 {
323 if (colObj->getInternalType() & btCollisionObject::CO_SOFT_BODY)
324 {
325 int len = colObj->calculateSerializeBufferSize();
326 btChunk* chunk = serializer->allocate(len, 1);
327 const char* structType = colObj->serialize(chunk->m_oldPtr, serializer);
329 }
330 }
331}
332
334{
335 serializer->startSerialization();
336
338
340
342
344
345 serializer->finishSerialization();
346}
#define btAlignedFree(ptr)
#define btAlignedAlloc(size, alignment)
const T & btMax(const T &a, const T &b)
Definition btMinMax.h:27
#define BT_PROFILE(name)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition btScalar.h:314
#define btAssert(x)
Definition btScalar.h:153
#define BT_SOFTBODY_CODE
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
btCollisionConfiguration allows to configure Bullet collision detection stack allocator size,...
btCollisionObject can be used to manage collision detection objects.
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
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)
btDiscreteDynamicsWorld provides discrete rigid body simulation those classes replace the obsolete Cc...
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 ...
virtual int getDebugMode() const =0
virtual void predictMotion(btScalar solverdt)=0
Predict motion of soft bodies into next timestep.
float getTimeScale()
Return the timescale that the simulation is using.
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 solveConstraints(btScalar solverdt)=0
Solve constraints for a set of soft bodies.
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:75
void defaultCollisionHandler(const btCollisionObjectWrapper *pcoWrap)
void setSoftBodySolver(btSoftBodySolver *softBodySolver)
static void solveClusters(const btAlignedObjectArray< btSoftBody * > &bodies)
static const btSoftBody * upcast(const btCollisionObject *colObj)
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 serializeSoftBodies(btSerializer *serializer)
void removeSoftBody(btSoftBody *body)
btSoftBodySolver * m_softBodySolver
Solver classes that encapsulate multiple soft bodies for solving.
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 ...
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 predictUnconstraintMotion(btScalar timeStep)
virtual void serialize(btSerializer *serializer)
Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (see B...
virtual void internalSingleStepSimulation(btScalar timeStep)
btSoftRigidDynamicsWorld(btDispatcher *dispatcher, btBroadphaseInterface *pairCache, btConstraintSolver *constraintSolver, btCollisionConfiguration *collisionConfiguration, btSoftBodySolver *softBodySolver=0)
virtual void removeCollisionObject(btCollisionObject *collisionObject)
removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise ca...
void solveSoftBodiesConstraints(btScalar timeStep)
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition btTransform.h:30
void setIdentity()
Set this transformation to the identity.
void setOrigin(const btVector3 &origin)
Set the translational element.
btVector3 can be used to represent 3D points and vectors.
Definition btVector3.h:82
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition btVector3.h:229
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition btVector3.h:640
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition btVector3.h:303
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
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)
btDispatcher * m_dispatcher
Definition btSoftBody.h:55
btScalar water_density
Definition btSoftBody.h:50
btSparseSdf< 3 > m_sparsesdf
Definition btSoftBody.h:57
btVector3 m_gravity
Definition btSoftBody.h:56
btVector3 water_normal
Definition btSoftBody.h:53
btScalar water_offset
Definition btSoftBody.h:51
btBroadphaseInterface * m_broadphase
Definition btSoftBody.h:54
const btSoftMultiBodyDynamicsWorld * m_world
const btSoftRigidDynamicsWorld * m_world
btCollisionWorld::RayResultCallback & m_resultCallback
virtual bool process(const btBroadphaseProxy *proxy)
btSoftSingleRayCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, const btSoftRigidDynamicsWorld *world, btCollisionWorld::RayResultCallback &resultCallback)
void Initialize(int hashsize=2383, int clampCells=256 *1024)