Bullet Collision Detection & Physics Library
btDeformableMultiBodyDynamicsWorld.h
Go to the documentation of this file.
1 /*
2  Written by Xuchen Han <xuchenhan2015@u.northwestern.edu>
3 
4  Bullet Continuous Collision Detection and Physics Library
5  Copyright (c) 2019 Google Inc. http://bulletphysics.org
6  This software is provided 'as-is', without any express or implied warranty.
7  In no event will the authors be held liable for any damages arising from the use of this software.
8  Permission is granted to anyone to use this software for any purpose,
9  including commercial applications, and to alter it and redistribute it freely,
10  subject to the following restrictions:
11  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.
12  2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13  3. This notice may not be removed or altered from any source distribution.
14  */
15 
16 #ifndef BT_DEFORMABLE_MULTIBODY_DYNAMICS_WORLD_H
17 #define BT_DEFORMABLE_MULTIBODY_DYNAMICS_WORLD_H
18 
22 // #include "btDeformableBodySolver.h"
24 #include "btSoftBodyHelpers.h"
26 #include <functional>
28 
34 
36 
38 {
50  bool m_implicit;
54 
57 
58 protected:
59  virtual void internalSingleStepSimulation(btScalar timeStep);
60 
61  virtual void integrateTransforms(btScalar timeStep);
62 
63  void positionCorrection(btScalar timeStep);
64 
65  void solveConstraints(btScalar timeStep);
66 
67  void updateActivationState(btScalar timeStep);
68 
69  void clearGravity();
70 
71 public:
72  btDeformableMultiBodyDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btDeformableMultiBodyConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration, btDeformableBodySolver* deformableBodySolver = 0);
73 
74  virtual int stepSimulation(btScalar timeStep, int maxSubSteps = 1, btScalar fixedTimeStep = btScalar(1.) / btScalar(60.));
75 
76  virtual void debugDrawWorld();
77 
79  {
80  m_solverCallback = cb;
81  }
82 
84 
86  {
87  return (btMultiBodyDynamicsWorld*)(this);
88  }
89 
91  {
92  return (const btMultiBodyDynamicsWorld*)(this);
93  }
94 
96  {
98  }
99 
100  virtual void predictUnconstraintMotion(btScalar timeStep);
101 
102  virtual void addSoftBody(btSoftBody* body, int collisionFilterGroup = btBroadphaseProxy::DefaultFilter, int collisionFilterMask = btBroadphaseProxy::AllFilter);
103 
105  {
106  return m_softBodies;
107  }
108 
110  {
111  return m_softBodies;
112  }
113 
115  {
116  return m_sbi;
117  }
118 
120  {
121  return m_sbi;
122  }
123 
124  virtual void setGravity(const btVector3& gravity);
125 
126  void reinitialize(btScalar timeStep);
127 
128  void applyRigidBodyGravity(btScalar timeStep);
129 
130  void beforeSolverCallbacks(btScalar timeStep);
131 
132  void afterSolverCallbacks(btScalar timeStep);
133 
135 
137 
138  void removeSoftBodyForce(btSoftBody* psb);
139 
140  void removeSoftBody(btSoftBody* body);
141 
142  void removeCollisionObject(btCollisionObject* collisionObject);
143 
144  int getDrawFlags() const { return (m_drawFlags); }
145  void setDrawFlags(int f) { m_drawFlags = f; }
146 
147  void setupConstraints();
148 
150 
152 
154 
155  void sortConstraints();
156 
157  void softBodySelfCollision();
158 
159  void setImplicit(bool implicit)
160  {
161  m_implicit = implicit;
162  }
163 
164  void setLineSearch(bool lineSearch)
165  {
166  m_lineSearch = lineSearch;
167  }
168 
169  void setUseProjection(bool useProjection)
170  {
171  m_useProjection = useProjection;
172  }
173 
174  void applyRepulsionForce(btScalar timeStep);
175 
176  void performGeometricCollisions(btScalar timeStep);
177 
179  {
185 
188 
190  : m_rayFromWorld(rayFromWorld),
191  m_rayToWorld(rayToWorld),
192  m_world(world),
193  m_resultCallback(resultCallback)
194  {
199 
200  btVector3 rayDir = (rayToWorld - rayFromWorld);
201 
202  rayDir.normalize();
204  m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
205  m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
206  m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
207  m_signs[0] = m_rayDirectionInverse[0] < 0.0;
208  m_signs[1] = m_rayDirectionInverse[1] < 0.0;
209  m_signs[2] = m_rayDirectionInverse[2] < 0.0;
210 
212  }
213 
214  virtual bool process(const btBroadphaseProxy* proxy)
215  {
218  return false;
219 
220  btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
221 
222  //only perform raycast if filterMask matches
223  if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
224  {
225  //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
226  //btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
227 #if 0
228 #ifdef RECALCULATE_AABB
229  btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
230  collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
231 #else
232  //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
233  const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
234  const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
235 #endif
236 #endif
237  //btScalar hitLambda = m_resultCallback.m_closestHitFraction;
238  //culling already done by broadphase
239  //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
240  {
242  collisionObject,
243  collisionObject->getCollisionShape(),
244  collisionObject->getWorldTransform(),
246  }
247  }
248  return true;
249  }
250  };
251 
252  void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
253  {
254  BT_PROFILE("rayTest");
257  btDeformableSingleRayCallback rayCB(rayFromWorld, rayToWorld, this, resultCallback);
258 
259 #ifndef USE_BRUTEFORCE_RAYBROADPHASE
260  m_broadphasePairCache->rayTest(rayFromWorld, rayToWorld, rayCB);
261 #else
262  for (int i = 0; i < this->getNumCollisionObjects(); i++)
263  {
264  rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
265  }
266 #endif //USE_BRUTEFORCE_RAYBROADPHASE
267  }
268 
269  void rayTestSingle(const btTransform& rayFromTrans, const btTransform& rayToTrans,
270  btCollisionObject* collisionObject,
271  const btCollisionShape* collisionShape,
272  const btTransform& colObjWorldTransform,
273  RayResultCallback& resultCallback) const
274  {
275  if (collisionShape->isSoftBody())
276  {
277  btSoftBody* softBody = btSoftBody::upcast(collisionObject);
278  if (softBody)
279  {
280  btSoftBody::sRayCast softResult;
281  if (softBody->rayFaceTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult))
282  {
283  if (softResult.fraction <= resultCallback.m_closestHitFraction)
284  {
286  shapeInfo.m_shapePart = 0;
287  shapeInfo.m_triangleIndex = softResult.index;
288  // get the normal
289  btVector3 rayDir = rayToTrans.getOrigin() - rayFromTrans.getOrigin();
290  btVector3 normal = -rayDir;
291  normal.normalize();
292  {
293  normal = softBody->m_faces[softResult.index].m_normal;
294  if (normal.dot(rayDir) > 0)
295  {
296  // normal always point toward origin of the ray
297  normal = -normal;
298  }
299  }
300 
301  btCollisionWorld::LocalRayResult rayResult(collisionObject,
302  &shapeInfo,
303  normal,
304  softResult.fraction);
305  bool normalInWorldSpace = true;
306  resultCallback.addSingleResult(rayResult, normalInWorldSpace);
307  }
308  }
309  }
310  }
311  else
312  {
313  btCollisionWorld::rayTestSingle(rayFromTrans, rayToTrans, collisionObject, collisionShape, colObjWorldTransform, resultCallback);
314  }
315  }
316 };
317 
318 #endif //BT_DEFORMABLE_MULTIBODY_DYNAMICS_WORLD_H
btAlignedObjectArray< btSoftBody * > btSoftBodyArray
btDynamicsWorldType
@ BT_DEFORMABLE_MULTIBODY_DYNAMICS_WORLD
#define BT_PROFILE(name)
Definition: btQuickprof.h:198
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:314
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.
btTransform & getWorldTransform()
btBroadphaseProxy * getBroadphaseHandle()
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.
btBroadphaseInterface * m_broadphasePairCache
btAlignedObjectArray< btCollisionObject * > m_collisionObjects
int getNumCollisionObjects() const
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(* btSolverCallback)(btScalar time, btDeformableMultiBodyDynamicsWorld *world)
btDeformableMultiBodyDynamicsWorld(btDispatcher *dispatcher, btBroadphaseInterface *pairCache, btDeformableMultiBodyConstraintSolver *constraintSolver, btCollisionConfiguration *collisionConfiguration, btDeformableBodySolver *deformableBodySolver=0)
void removeCollisionObject(btCollisionObject *collisionObject)
removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise ca...
virtual void addSoftBody(btSoftBody *body, int collisionFilterGroup=btBroadphaseProxy::DefaultFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter)
virtual void predictUnconstraintMotion(btScalar timeStep)
void rayTestSingle(const btTransform &rayFromTrans, const btTransform &rayToTrans, btCollisionObject *collisionObject, const btCollisionShape *collisionShape, const btTransform &colObjWorldTransform, RayResultCallback &resultCallback) const
virtual const btMultiBodyDynamicsWorld * getMultiBodyDynamicsWorld() const
void addForce(btSoftBody *psb, btDeformableLagrangianForce *force)
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 ...
virtual btMultiBodyDynamicsWorld * getMultiBodyDynamicsWorld()
virtual btDynamicsWorldType getWorldType() const
void removeForce(btSoftBody *psb, btDeformableLagrangianForce *force)
virtual void internalSingleStepSimulation(btScalar timeStep)
const btSoftBodyWorldInfo & getWorldInfo() const
virtual int stepSimulation(btScalar timeStep, int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.))
if maxSubSteps > 0, it will interpolate motion between fixedTimeStep's
DeformableBodyInplaceSolverIslandCallback * m_solverDeformableBodyIslandCallback
virtual void setGravity(const btVector3 &gravity)
btDeformableBodySolver * m_deformableBodySolver
Solver classes that encapsulate multiple deformable bodies for solving.
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:77
The btMultiBodyDynamicsWorld adds Featherstone multi body dynamics to Bullet This implementation is s...
The btSoftBody is an class to simulate cloth and volumetric soft bodies.
Definition: btSoftBody.h:75
bool rayFaceTest(const btVector3 &rayFrom, const btVector3 &rayTo, sRayCast &results)
tFaceArray m_faces
Definition: btSoftBody.h:817
static const btSoftBody * upcast(const btCollisionObject *colObj)
Definition: btSoftBody.h:1157
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:30
btVector3 & getOrigin()
Return the origin vector translation.
Definition: btTransform.h:114
void setIdentity()
Set this transformation to the identity.
Definition: btTransform.h:167
void setOrigin(const btVector3 &origin)
Set the translational element.
Definition: btTransform.h:147
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:82
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition: btVector3.h:303
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition: btVector3.h:229
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
btDeformableSingleRayCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, const btDeformableMultiBodyDynamicsWorld *world, btCollisionWorld::RayResultCallback &resultCallback)
btScalar fraction
feature index
Definition: btSoftBody.h:206
int index
feature type
Definition: btSoftBody.h:205