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
24#include "btSoftBodyHelpers.h"
26#include <functional>
28
34
36
38{
54
57
58protected:
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
71public:
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
82
84
89
91 {
92 return (const btMultiBodyDynamicsWorld*)(this);
93 }
94
99
100 virtual void predictUnconstraintMotion(btScalar timeStep);
101
102 virtual void addSoftBody(btSoftBody* body, int collisionFilterGroup = btBroadphaseProxy::DefaultFilter, int collisionFilterMask = btBroadphaseProxy::AllFilter);
103
108
110 {
111 return m_softBodies;
112 }
113
115 {
116 return m_sbi;
117 }
118
120 {
121 return m_sbi;
122 }
123
124 void reinitialize(btScalar timeStep);
125
126 void applyRigidBodyGravity(btScalar timeStep);
127
128 void beforeSolverCallbacks(btScalar timeStep);
129
130 void afterSolverCallbacks(btScalar timeStep);
131
133
135
137
138 void removeSoftBody(btSoftBody* body);
139
140 void removeCollisionObject(btCollisionObject* collisionObject);
141
142 int getDrawFlags() const { return (m_drawFlags); }
143 void setDrawFlags(int f) { m_drawFlags = f; }
144
145 void setupConstraints();
146
148
150
152
153 void sortConstraints();
154
156
157 void setImplicit(bool implicit)
158 {
159 m_implicit = implicit;
160 }
161
162 void setLineSearch(bool lineSearch)
163 {
164 m_lineSearch = lineSearch;
165 }
166
167 void setUseProjection(bool useProjection)
168 {
169 m_useProjection = useProjection;
170 }
171
172 void applyRepulsionForce(btScalar timeStep);
173
175
177 {
183
186
188 : m_rayFromWorld(rayFromWorld),
189 m_rayToWorld(rayToWorld),
190 m_world(world),
191 m_resultCallback(resultCallback)
192 {
193 m_rayFromTrans.setIdentity();
195 m_rayToTrans.setIdentity();
196 m_rayToTrans.setOrigin(m_rayToWorld);
197
198 btVector3 rayDir = (rayToWorld - rayFromWorld);
199
200 rayDir.normalize();
202 m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
203 m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
204 m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
205 m_signs[0] = m_rayDirectionInverse[0] < 0.0;
206 m_signs[1] = m_rayDirectionInverse[1] < 0.0;
207 m_signs[2] = m_rayDirectionInverse[2] < 0.0;
208
210 }
211
212 virtual bool process(const btBroadphaseProxy* proxy)
213 {
215 if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
216 return false;
217
218 btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
219
220 //only perform raycast if filterMask matches
221 if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
222 {
223 //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
224 //btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
225#if 0
226#ifdef RECALCULATE_AABB
227 btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
228 collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
229#else
230 //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
231 const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
232 const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
233#endif
234#endif
235 //btScalar hitLambda = m_resultCallback.m_closestHitFraction;
236 //culling already done by broadphase
237 //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
238 {
239 m_world->rayTestSingle(m_rayFromTrans, m_rayToTrans,
240 collisionObject,
241 collisionObject->getCollisionShape(),
242 collisionObject->getWorldTransform(),
244 }
245 }
246 return true;
247 }
248 };
249
250 void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
251 {
252 BT_PROFILE("rayTest");
255 btDeformableSingleRayCallback rayCB(rayFromWorld, rayToWorld, this, resultCallback);
256
257#ifndef USE_BRUTEFORCE_RAYBROADPHASE
258 m_broadphasePairCache->rayTest(rayFromWorld, rayToWorld, rayCB);
259#else
260 for (int i = 0; i < this->getNumCollisionObjects(); i++)
261 {
262 rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
263 }
264#endif //USE_BRUTEFORCE_RAYBROADPHASE
265 }
266
267 void rayTestSingle(const btTransform& rayFromTrans, const btTransform& rayToTrans,
268 btCollisionObject* collisionObject,
269 const btCollisionShape* collisionShape,
270 const btTransform& colObjWorldTransform,
271 RayResultCallback& resultCallback) const
272 {
273 if (collisionShape->isSoftBody())
274 {
275 btSoftBody* softBody = btSoftBody::upcast(collisionObject);
276 if (softBody)
277 {
278 btSoftBody::sRayCast softResult;
279 if (softBody->rayFaceTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult))
280 {
281 if (softResult.fraction <= resultCallback.m_closestHitFraction)
282 {
284 shapeInfo.m_shapePart = 0;
285 shapeInfo.m_triangleIndex = softResult.index;
286 // get the normal
287 btVector3 rayDir = rayToTrans.getOrigin() - rayFromTrans.getOrigin();
288 btVector3 normal = -rayDir;
289 normal.normalize();
290 {
291 normal = softBody->m_faces[softResult.index].m_normal;
292 if (normal.dot(rayDir) > 0)
293 {
294 // normal always point toward origin of the ray
295 normal = -normal;
296 }
297 }
298
299 btCollisionWorld::LocalRayResult rayResult(collisionObject,
300 &shapeInfo,
301 normal,
302 softResult.fraction);
303 bool normalInWorldSpace = true;
304 resultCallback.addSingleResult(rayResult, normalInWorldSpace);
305 }
306 }
307 }
308 }
309 else
310 {
311 btCollisionWorld::rayTestSingle(rayFromTrans, rayToTrans, collisionObject, collisionShape, colObjWorldTransform, resultCallback);
312 }
313 }
314};
315
316#endif //BT_DEFORMABLE_MULTIBODY_DYNAMICS_WORLD_H
btAlignedObjectArray< btSoftBody * > btSoftBodyArray
btDynamicsWorldType
@ BT_DEFORMABLE_MULTIBODY_DYNAMICS_WORLD
#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
The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods It...
The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs.
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)
const btSoftBodyWorldInfo & getWorldInfo() const
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)
void rayTestSingle(const btTransform &rayFromTrans, const btTransform &rayToTrans, btCollisionObject *collisionObject, const btCollisionShape *collisionShape, const btTransform &colObjWorldTransform, RayResultCallback &resultCallback) 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 btDynamicsWorldType getWorldType() const
void removeForce(btSoftBody *psb, btDeformableLagrangianForce *force)
virtual void internalSingleStepSimulation(btScalar timeStep)
virtual int stepSimulation(btScalar timeStep, int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.))
if maxSubSteps > 0, it will interpolate motion between fixedTimeStep's
virtual const btMultiBodyDynamicsWorld * getMultiBodyDynamicsWorld() const
DeformableBodyInplaceSolverIslandCallback * m_solverDeformableBodyIslandCallback
btDeformableBodySolver * m_deformableBodySolver
Solver classes that encapsulate multiple deformable bodies for solving.
virtual btMultiBodyDynamicsWorld * getMultiBodyDynamicsWorld()
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
btMultiBodyDynamicsWorld(btDispatcher *dispatcher, btBroadphaseInterface *pairCache, btMultiBodyConstraintSolver *constraintSolver, btCollisionConfiguration *collisionConfiguration)
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:815
static const btSoftBody * upcast(const btCollisionObject *colObj)
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.
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
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 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