Bullet Collision Detection & Physics Library: btDeformableMultiBodyConstraintSolver.cpp Source File

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 #include "btDeformableMultiBodyConstraintSolver.h"
17 #include <iostream>
18 // override the iterations method to include deformable/multibody contact
19 btScalar btDeformableMultiBodyConstraintSolver::solveDeformableGroupIterations(btCollisionObject** bodies, int numBodies, btCollisionObject** deformableBodies, int numDeformableBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer)
20 {
21 {
23 solveGroupCacheFriendlySplitImpulseIterations(bodies, numBodies, deformableBodies, numDeformableBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer);
24
25 int maxIterations = m_maxOverrideNumSolverIterations > infoGlobal.m_numIterations ? m_maxOverrideNumSolverIterations : infoGlobal.m_numIterations;
26 for (int iteration = 0; iteration < maxIterations; iteration++)
27 {
28 // 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
29
30 // solve rigid/rigid in solver body
31 m_leastSquaresResidual = solveSingleIteration(iteration, bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer);
32 // solver body velocity -> rigid body velocity
33 solverBodyWriteBack(infoGlobal);
34 btScalar deformableResidual = m_deformableSolver->solveContactConstraints(deformableBodies, numDeformableBodies, infoGlobal);
35 // update rigid body velocity in rigid/deformable contact
36 m_leastSquaresResidual = btMax(m_leastSquaresResidual, deformableResidual);
37 // solver body velocity <- rigid body velocity
38 writeToSolverBody(bodies, numBodies, infoGlobal);
39
40 if (m_leastSquaresResidual <= infoGlobal.m_leastSquaresResidualThreshold || (iteration >= (maxIterations - 1)))
41 {
42 #ifdef VERBOSE_RESIDUAL_PRINTF
43 if (iteration >= (maxIterations - 1))
44 printf("residual = %f at iteration #%d\n", m_leastSquaresResidual, iteration);
45 #endif
46 m_analyticsData.m_numSolverCalls++;
47 m_analyticsData.m_numIterationsUsed = iteration + 1;
48 m_analyticsData.m_islandId = -2;
49 if (numBodies > 0)
50 m_analyticsData.m_islandId = bodies[0]->getCompanionId();
51 m_analyticsData.m_numBodies = numBodies;
52 m_analyticsData.m_numContactManifolds = numManifolds;
53 m_analyticsData.m_remainingLeastSquaresResidual = m_leastSquaresResidual;
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
75 m_tmpMultiBodyConstraints = 0;
76 m_tmpNumMultiBodyConstraints = 0;
77 }
78
79 void btDeformableMultiBodyConstraintSolver::writeToSolverBody(btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal)
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
95 void btDeformableMultiBodyConstraintSolver::solverBodyWriteBack(const btContactSolverInfo& infoGlobal)
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, btCollisionObject** deformableBodies, int numDeformableBodies, 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 {
115 for (iteration = 0; iteration < infoGlobal.m_numIterations; iteration++)
116 {
117 btScalar leastSquaresResidual = 0.f;
118 {
119 int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
120 int j;
121 for (j = 0; j < numPoolConstraints; j++)
122 {
123 const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
124
125 btScalar residual = resolveSplitPenetrationImpulse(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold);
126 leastSquaresResidual = btMax(leastSquaresResidual, residual * residual);
127 }
128 // solve the position correction between deformable and rigid/multibody
129 // btScalar residual = m_deformableSolver->solveSplitImpulse(infoGlobal);
130 btScalar residual = m_deformableSolver->m_objective->m_projection.solveSplitImpulse(deformableBodies, numDeformableBodies, 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 if (iteration >= (infoGlobal.m_numIterations - 1))
137 printf("split impulse residual = %f at iteration #%d\n", leastSquaresResidual, iteration);
138 #endif
139 break;
140 }
141 }
142 }
143 }
144 }
btSolverBody
The btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packe...
Definition: btSolverBody.h:105
btTypedConstraint
TypedConstraint is the baseclass for Bullet constraints and vehicles.
Definition: btTypedConstraint.h:76
btCollisionObject
btCollisionObject can be used to manage collision detection objects.
Definition: btCollisionObject.h:50
btRigidBody
The btRigidBody is the main class for rigid body objects.
Definition: btRigidBody.h:60
btSolverBody::m_linearVelocity
btVector3 m_linearVelocity
Definition: btSolverBody.h:115
btContactSolverInfo
Definition: btContactSolverInfo.h:76
btSequentialImpulseConstraintSolver::resolveSplitPenetrationImpulse
btScalar resolveSplitPenetrationImpulse(btSolverBody &bodyA, btSolverBody &bodyB, const btSolverConstraint &contactConstraint)
Definition: btSequentialImpulseConstraintSolver.h:139
btSolverConstraint
1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and fr...
Definition: btSolverConstraint.h:31
btRigidBody::getAngularVelocity
const btVector3 & getAngularVelocity() const
Definition: btRigidBody.h:437
btScalar
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:314
btDeformableMultiBodyConstraintSolver::solveGroupCacheFriendlySplitImpulseIterations
virtual void solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject **bodies, int numBodies, btCollisionObject **deformableBodies, int numDeformableBodies, btPersistentManifold **manifoldPtr, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &infoGlobal, btIDebugDraw *debugDrawer)
Definition: btDeformableMultiBodyConstraintSolver.cpp:108
btDispatcher
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:77
btMultiBodyConstraintSolver::solveGroupCacheFriendlyFinish
virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject **bodies, int numBodies, const btContactSolverInfo &infoGlobal)
Definition: btMultiBodyConstraintSolver.cpp:1588
btMultiBodyConstraint
Definition: btMultiBodyConstraint.h:57
btDeformableMultiBodyConstraintSolver::solverBodyWriteBack
void solverBodyWriteBack(const btContactSolverInfo &infoGlobal)
Definition: btDeformableMultiBodyConstraintSolver.cpp:95
btDeformableBackwardEulerObjective::m_projection
btDeformableContactProjection m_projection
Definition: btDeformableBackwardEulerObjective.h:39
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:203
btDeformableContactProjection::solveSplitImpulse
btScalar solveSplitImpulse(btCollisionObject **deformableBodies, int numDeformableBodies, const btContactSolverInfo &infoGlobal)
Definition: btDeformableContactProjection.cpp:61
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:27
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
btDeformableBodySolver::solveContactConstraints
virtual btScalar solveContactConstraints(btCollisionObject **deformableBodies, int numDeformableBodies, const btContactSolverInfo &infoGlobal)
Definition: btDeformableBodySolver.cpp:256
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:19
btContactSolverInfoData::m_splitImpulse
int m_splitImpulse
Definition: btContactSolverInfo.h:56
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:65
btRigidBody::getLinearVelocity
const btVector3 & getLinearVelocity() const
Definition: btRigidBody.h:433
btContactSolverInfoData::m_leastSquaresResidualThreshold
btScalar m_leastSquaresResidualThreshold
Definition: btContactSolverInfo.h:67
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
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
btSequentialImpulseConstraintSolver::getOrInitSolverBody
int getOrInitSolverBody(btCollisionObject &body, btScalar timeStep)
Definition: btSequentialImpulseConstraintSolver.cpp:691
btDeformableBodySolver::m_objective
btDeformableBackwardEulerObjective * m_objective
Definition: btDeformableBodySolver.h:51
btContactSolverInfoData::m_numIterations
int m_numIterations
Definition: btContactSolverInfo.h:44
BT_PROFILE
#define BT_PROFILE(name)
Definition: btQuickprof.h:198
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:457
btDeformableMultiBodyConstraintSolver::m_deformableSolver
btDeformableBodySolver * m_deformableSolver
Definition: btDeformableMultiBodyConstraintSolver.h:34