Bullet Collision Detection & Physics Library
btDeformableMultiBodyConstraintSolver.cpp
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 
18 #include <iostream>
19 // override the iterations method to include deformable/multibody contact
20 btScalar btDeformableMultiBodyConstraintSolver::solveDeformableGroupIterations(btCollisionObject** bodies,int numBodies,btCollisionObject** deformableBodies,int numDeformableBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
21 {
22  {
24  solveGroupCacheFriendlySplitImpulseIterations(bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer);
25 
27  for (int iteration = 0; iteration < maxIterations; iteration++)
28  {
29  // rigid bodies are solved using solver body velocity, but rigid/deformable contact directly uses the velocity of the actual rigid body. So we have to do the following: Solve one iteration of the rigid/rigid contact, get the updated velocity in the solver body and update the velocity of the underlying rigid body. Then solve the rigid/deformable contact. Finally, grab the (once again) updated rigid velocity and update the velocity of the wrapping solver body
30 
31  // solve rigid/rigid in solver body
32  m_leastSquaresResidual = solveSingleIteration(iteration, bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer);
33  // solver body velocity -> rigid body velocity
34  solverBodyWriteBack(infoGlobal);
35  btScalar deformableResidual = m_deformableSolver->solveContactConstraints(deformableBodies,numDeformableBodies);
36  // update rigid body velocity in rigid/deformable contact
38  // solver body velocity <- rigid body velocity
39  writeToSolverBody(bodies, numBodies, infoGlobal);
40 
41  if (m_leastSquaresResidual <= infoGlobal.m_leastSquaresResidualThreshold || (iteration >= (maxIterations - 1)))
42  {
43 #ifdef VERBOSE_RESIDUAL_PRINTF
44  printf("residual = %f at iteration #%d\n", m_leastSquaresResidual, iteration);
45 #endif
49  if (numBodies>0)
51  m_analyticsData.m_numBodies = numBodies;
54  break;
55  }
56  }
57  }
58  return 0.f;
59 }
60 
61 void btDeformableMultiBodyConstraintSolver::solveDeformableBodyGroup(btCollisionObject * *bodies, int numBodies, btCollisionObject * *deformableBodies, int numDeformableBodies, btPersistentManifold** manifold, int numManifolds, btTypedConstraint** constraints, int numConstraints, btMultiBodyConstraint** multiBodyConstraints, int numMultiBodyConstraints, const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btDispatcher* dispatcher)
62 {
63  m_tmpMultiBodyConstraints = multiBodyConstraints;
64  m_tmpNumMultiBodyConstraints = numMultiBodyConstraints;
65 
66  // inherited from MultiBodyConstraintSolver
67  solveGroupCacheFriendlySetup(bodies, numBodies, manifold, numManifolds, constraints, numConstraints, info, debugDrawer);
68 
69  // overriden
70  solveDeformableGroupIterations(bodies, numBodies, deformableBodies, numDeformableBodies, manifold, numManifolds, constraints, numConstraints, info, debugDrawer);
71 
72  // inherited from MultiBodyConstraintSolver
73  solveGroupCacheFriendlyFinish(bodies, numBodies, info);
74 
77 }
78 
80 {
81  for (int i = 0; i < numBodies; i++)
82  {
83  int bodyId = getOrInitSolverBody(*bodies[i], infoGlobal.m_timeStep);
84 
85  btRigidBody* body = btRigidBody::upcast(bodies[i]);
86  if (body && body->getInvMass())
87  {
88  btSolverBody& solverBody = m_tmpSolverBodyPool[bodyId];
89  solverBody.m_linearVelocity = body->getLinearVelocity() - solverBody.m_deltaLinearVelocity;
90  solverBody.m_angularVelocity = body->getAngularVelocity() - solverBody.m_deltaAngularVelocity;
91  }
92  }
93 }
94 
96 {
97  for (int i = 0; i < m_tmpSolverBodyPool.size(); i++)
98  {
99  btRigidBody* body = m_tmpSolverBodyPool[i].m_originalBody;
100  if (body)
101  {
102  m_tmpSolverBodyPool[i].m_originalBody->setLinearVelocity(m_tmpSolverBodyPool[i].m_linearVelocity + m_tmpSolverBodyPool[i].m_deltaLinearVelocity);
103  m_tmpSolverBodyPool[i].m_originalBody->setAngularVelocity(m_tmpSolverBodyPool[i].m_angularVelocity+m_tmpSolverBodyPool[i].m_deltaAngularVelocity);
104  }
105  }
106 }
107 
108 void btDeformableMultiBodyConstraintSolver::solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer)
109 {
110  BT_PROFILE("solveGroupCacheFriendlySplitImpulseIterations");
111  int iteration;
112  if (infoGlobal.m_splitImpulse)
113  {
114  {
116  for (iteration = 0; iteration < infoGlobal.m_numIterations; iteration++)
117  {
118  btScalar leastSquaresResidual = 0.f;
119  {
120  int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
121  int j;
122  for (j = 0; j < numPoolConstraints; j++)
123  {
125 
126  btScalar residual = resolveSplitPenetrationImpulse(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold);
127  leastSquaresResidual = btMax(leastSquaresResidual, residual * residual);
128  }
129  // solve the position correction between deformable and rigid/multibody
130  btScalar residual = m_deformableSolver->solveSplitImpulse(infoGlobal);
131  leastSquaresResidual = btMax(leastSquaresResidual, residual * residual);
132  }
133  if (leastSquaresResidual <= infoGlobal.m_leastSquaresResidualThreshold || iteration >= (infoGlobal.m_numIterations - 1))
134  {
135 #ifdef VERBOSE_RESIDUAL_PRINTF
136  printf("residual = %f at iteration #%d\n", leastSquaresResidual, iteration);
137 #endif
138  break;
139  }
140  }
141  }
142  }
143 }
btSolverBody
The btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packe...
Definition: btSolverBody.h:103
btDeformableBodySolver::solveContactConstraints
btScalar solveContactConstraints(btCollisionObject **deformableBodies, int numDeformableBodies)
Definition: btDeformableBodySolver.cpp:237
btTypedConstraint
TypedConstraint is the baseclass for Bullet constraints and vehicles.
Definition: btTypedConstraint.h:74
btCollisionObject
btCollisionObject can be used to manage collision detection objects.
Definition: btCollisionObject.h:48
btRigidBody
The btRigidBody is the main class for rigid body objects.
Definition: btRigidBody.h:59
btSolverBody::m_linearVelocity
btVector3 m_linearVelocity
Definition: btSolverBody.h:115
btContactSolverInfo
Definition: btContactSolverInfo.h:72
btSequentialImpulseConstraintSolver::resolveSplitPenetrationImpulse
btScalar resolveSplitPenetrationImpulse(btSolverBody &bodyA, btSolverBody &bodyB, const btSolverConstraint &contactConstraint)
Definition: btSequentialImpulseConstraintSolver.h:139
maxIterations
int maxIterations
Definition: btQuantizedBvh.cpp:349
btSolverConstraint
1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and fr...
Definition: btSolverConstraint.h:29
btRigidBody::getAngularVelocity
const btVector3 & getAngularVelocity() const
Definition: btRigidBody.h:402
btScalar
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:314
btDispatcher
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:76
btMultiBodyConstraintSolver::solveGroupCacheFriendlyFinish
virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject **bodies, int numBodies, const btContactSolverInfo &infoGlobal)
Definition: btMultiBodyConstraintSolver.cpp:1583
btMultiBodyConstraint
Definition: btMultiBodyConstraint.h:40
btDeformableMultiBodyConstraintSolver::solverBodyWriteBack
void solverBodyWriteBack(const btContactSolverInfo &infoGlobal)
Definition: btDeformableMultiBodyConstraintSolver.cpp:95
btMultiBodyConstraintSolver::solveSingleIteration
virtual btScalar solveSingleIteration(int iteration, btCollisionObject **bodies, int numBodies, btPersistentManifold **manifoldPtr, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &infoGlobal, btIDebugDraw *debugDrawer)
Definition: btMultiBodyConstraintSolver.cpp:28
btMax
const T & btMax(const T &a, const T &b)
Definition: btMinMax.h:27
btSolverBody::m_angularVelocity
btVector3 m_angularVelocity
Definition: btSolverBody.h:116
btMultiBodyConstraintSolver::solveGroupCacheFriendlySetup
virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject **bodies, int numBodies, btPersistentManifold **manifoldPtr, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &infoGlobal, btIDebugDraw *debugDrawer)
Definition: btMultiBodyConstraintSolver.cpp:198
btSolverAnalyticsData::m_islandId
int m_islandId
Definition: btSequentialImpulseConstraintSolver.h:41
btSolverAnalyticsData::m_remainingLeastSquaresResidual
double m_remainingLeastSquaresResidual
Definition: btSequentialImpulseConstraintSolver.h:46
btSolverAnalyticsData::m_numIterationsUsed
int m_numIterationsUsed
Definition: btSequentialImpulseConstraintSolver.h:45
btMultiBodyConstraintSolver::m_tmpNumMultiBodyConstraints
int m_tmpNumMultiBodyConstraints
Definition: btMultiBodyConstraintSolver.h:43
btIDebugDraw
The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations.
Definition: btIDebugDraw.h:26
btDeformableMultiBodyConstraintSolver.h
btContactSolverInfoData::m_timeStep
btScalar m_timeStep
Definition: btContactSolverInfo.h:42
btRigidBody::getInvMass
btScalar getInvMass() const
Definition: btRigidBody.h:263
btSequentialImpulseConstraintSolver::m_orderTmpConstraintPool
btAlignedObjectArray< int > m_orderTmpConstraintPool
Definition: btSequentialImpulseConstraintSolver.h:62
btSequentialImpulseConstraintSolver::m_analyticsData
btSolverAnalyticsData m_analyticsData
Definition: btSequentialImpulseConstraintSolver.h:212
btDeformableMultiBodyConstraintSolver::solveDeformableGroupIterations
virtual btScalar solveDeformableGroupIterations(btCollisionObject **bodies, int numBodies, btCollisionObject **deformableBodies, int numDeformableBodies, btPersistentManifold **manifoldPtr, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &infoGlobal, btIDebugDraw *debugDrawer)
Definition: btDeformableMultiBodyConstraintSolver.cpp:20
btContactSolverInfoData::m_splitImpulse
int m_splitImpulse
Definition: btContactSolverInfo.h:54
btSolverAnalyticsData::m_numBodies
int m_numBodies
Definition: btSequentialImpulseConstraintSolver.h:42
btSolverBody::m_deltaAngularVelocity
btVector3 m_deltaAngularVelocity
Definition: btSolverBody.h:109
btDeformableMultiBodyConstraintSolver::solveDeformableBodyGroup
virtual void solveDeformableBodyGroup(btCollisionObject **bodies, int numBodies, btCollisionObject **deformableBodies, int numDeformableBodies, btPersistentManifold **manifold, int numManifolds, btTypedConstraint **constraints, int numConstraints, btMultiBodyConstraint **multiBodyConstraints, int numMultiBodyConstraints, const btContactSolverInfo &info, btIDebugDraw *debugDrawer, btDispatcher *dispatcher)
Definition: btDeformableMultiBodyConstraintSolver.cpp:61
btSequentialImpulseConstraintSolver::m_maxOverrideNumSolverIterations
int m_maxOverrideNumSolverIterations
Definition: btSequentialImpulseConstraintSolver.h:66
btPersistentManifold
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
Definition: btPersistentManifold.h:63
btRigidBody::getLinearVelocity
const btVector3 & getLinearVelocity() const
Definition: btRigidBody.h:398
btContactSolverInfoData::m_leastSquaresResidualThreshold
btScalar m_leastSquaresResidualThreshold
Definition: btContactSolverInfo.h:65
btSolverConstraint::m_solverBodyIdA
int m_solverBodyIdA
Definition: btSolverConstraint.h:62
btSolverAnalyticsData::m_numContactManifolds
int m_numContactManifolds
Definition: btSequentialImpulseConstraintSolver.h:43
btSequentialImpulseConstraintSolver::m_tmpSolverContactConstraintPool
btConstraintArray m_tmpSolverContactConstraintPool
Definition: btSequentialImpulseConstraintSolver.h:57
btDeformableBodySolver::solveSplitImpulse
btScalar solveSplitImpulse(const btContactSolverInfo &infoGlobal)
Definition: btDeformableBodySolver.cpp:244
btSequentialImpulseConstraintSolver::m_tmpSolverBodyPool
btAlignedObjectArray< btSolverBody > m_tmpSolverBodyPool
Definition: btSequentialImpulseConstraintSolver.h:56
btSolverBody::m_deltaLinearVelocity
btVector3 m_deltaLinearVelocity
Definition: btSolverBody.h:108
btMultiBodyConstraintSolver::m_tmpMultiBodyConstraints
btMultiBodyConstraint ** m_tmpMultiBodyConstraints
Definition: btMultiBodyConstraintSolver.h:42
btSolverConstraint::m_solverBodyIdB
int m_solverBodyIdB
Definition: btSolverConstraint.h:63
btSolverAnalyticsData::m_numSolverCalls
int m_numSolverCalls
Definition: btSequentialImpulseConstraintSolver.h:44
btSequentialImpulseConstraintSolver::m_leastSquaresResidual
btScalar m_leastSquaresResidual
Definition: btSequentialImpulseConstraintSolver.h:83
btDeformableMultiBodyConstraintSolver::solveGroupCacheFriendlySplitImpulseIterations
virtual void solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject **bodies, int numBodies, btPersistentManifold **manifoldPtr, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &infoGlobal, btIDebugDraw *debugDrawer)
Definition: btDeformableMultiBodyConstraintSolver.cpp:108
btSequentialImpulseConstraintSolver::getOrInitSolverBody
int getOrInitSolverBody(btCollisionObject &body, btScalar timeStep)
Definition: btSequentialImpulseConstraintSolver.cpp:689
btContactSolverInfoData::m_numIterations
int m_numIterations
Definition: btContactSolverInfo.h:44
btDeformableBodySolver::splitImpulseSetup
void splitImpulseSetup(const btContactSolverInfo &infoGlobal)
Definition: btDeformableBodySolver.cpp:250
BT_PROFILE
#define BT_PROFILE(name)
Definition: btQuickprof.h:197
btDeformableMultiBodyConstraintSolver::writeToSolverBody
void writeToSolverBody(btCollisionObject **bodies, int numBodies, const btContactSolverInfo &infoGlobal)
Definition: btDeformableMultiBodyConstraintSolver.cpp:79
btRigidBody::upcast
static const btRigidBody * upcast(const btCollisionObject *colObj)
to keep collision detection and dynamics separate we don't store a rigidbody pointer but a rigidbody ...
Definition: btRigidBody.h:189
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition: btAlignedObjectArray.h:142
btCollisionObject::getCompanionId
int getCompanionId() const
Definition: btCollisionObject.h:446
btDeformableMultiBodyConstraintSolver::m_deformableSolver
btDeformableBodySolver * m_deformableSolver
Definition: btDeformableMultiBodyConstraintSolver.h:35