Bullet Collision Detection & Physics Library
btDeformableBackwardEulerObjective.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 
17 #include "btPreconditioner.h"
18 #include "LinearMath/btQuickprof.h"
19 
21 : m_softBodies(softBodies)
22 , m_projection(softBodies)
23 , m_backupVelocity(backup_v)
24 , m_implicit(false)
25 {
27 }
28 
30 {
31  delete m_preconditioner;
32 }
33 
35 {
36  BT_PROFILE("reinitialize");
37  if (dt > 0)
38  {
39  setDt(dt);
40  }
41  if(nodeUpdated)
42  {
43  updateId();
44  }
45  for (int i = 0; i < m_lf.size(); ++i)
46  {
47  m_lf[i]->reinitialize(nodeUpdated);
48  }
49  m_projection.reinitialize(nodeUpdated);
50  m_preconditioner->reinitialize(nodeUpdated);
51 }
52 
54 {
55  m_dt = dt;
56 }
57 
59 {
60  BT_PROFILE("multiply");
61  // add in the mass term
62  size_t counter = 0;
63  for (int i = 0; i < m_softBodies.size(); ++i)
64  {
65  btSoftBody* psb = m_softBodies[i];
66  for (int j = 0; j < psb->m_nodes.size(); ++j)
67  {
68  const btSoftBody::Node& node = psb->m_nodes[j];
69  b[counter] = (node.m_im == 0) ? btVector3(0,0,0) : x[counter] / node.m_im;
70  ++counter;
71  }
72  }
73 
74  for (int i = 0; i < m_lf.size(); ++i)
75  {
76  // add damping matrix
77  m_lf[i]->addScaledDampingForceDifferential(-m_dt, x, b);
78  if (m_implicit)
79  {
80  m_lf[i]->addScaledElasticForceDifferential(-m_dt*m_dt, x, b);
81  }
82  }
83 }
84 
86 {
87  for (int i = 0; i < m_softBodies.size(); ++i)
88  {
89  btSoftBody* psb = m_softBodies[i];
90  for (int j = 0; j < psb->m_nodes.size(); ++j)
91  {
92  btSoftBody::Node& node = psb->m_nodes[j];
93  node.m_v = m_backupVelocity[node.index] + dv[node.index];
94  }
95  }
96 }
97 
99 {
100  size_t counter = 0;
101  for (int i = 0; i < m_softBodies.size(); ++i)
102  {
103  btSoftBody* psb = m_softBodies[i];
104  if (!psb->isActive())
105  {
106  counter += psb->m_nodes.size();
107  continue;
108  }
109  for (int j = 0; j < psb->m_nodes.size(); ++j)
110  {
111  btScalar one_over_mass = (psb->m_nodes[j].m_im == 0) ? 0 : psb->m_nodes[j].m_im;
112  psb->m_nodes[j].m_v += one_over_mass * force[counter++];
113  }
114  }
115  if (setZero)
116  {
117  for (int i = 0; i < force.size(); ++i)
118  force[i].setZero();
119  }
120 }
121 
123 {
124  BT_PROFILE("computeResidual");
125  // add implicit force
126  for (int i = 0; i < m_lf.size(); ++i)
127  {
128  if (m_implicit)
129  {
130  m_lf[i]->addScaledForces(dt, residual);
131  }
132  else
133  {
134  m_lf[i]->addScaledDampingForce(dt, residual);
135  }
136  }
137  m_projection.project(residual);
138 }
139 
141 {
142  btScalar mag = 0;
143  for (int i = 0; i < residual.size(); ++i)
144  {
145  mag += residual[i].length2();
146  }
147  return std::sqrt(mag);
148 }
149 
151 {
152  btScalar e = 0;
153  for (int i = 0; i < m_lf.size(); ++i)
154  {
155  e += m_lf[i]->totalEnergy(dt);
156  }
157  return e;
158 }
159 
161 {
162  for (int i = 0; i < m_softBodies.size(); ++i)
163  {
164  m_softBodies[i]->advanceDeformation();
165  }
166 
167  for (int i = 0; i < m_lf.size(); ++i)
168  {
169  m_lf[i]->addScaledExplicitForce(m_dt, force);
170  }
171  applyForce(force, true);
172 }
173 
175 {
176  size_t counter = 0;
177  for (int i = 0; i < m_softBodies.size(); ++i)
178  {
179  btSoftBody* psb = m_softBodies[i];
180  for (int j = 0; j < psb->m_nodes.size(); ++j)
181  {
182  dv[counter] = psb->m_nodes[j].m_im * residual[counter];
183  ++counter;
184  }
185  }
186 }
187 
188 //set constraints as projections
190 {
192 }
193 
195 {
197 }
btDeformableBackwardEulerObjective::m_lf
btAlignedObjectArray< btDeformableLagrangianForce * > m_lf
Definition: btDeformableBackwardEulerObjective.h:35
btDeformableContactProjection::reinitialize
virtual void reinitialize(bool nodeUpdated)
Definition: btDeformableContactProjection.cpp:485
Preconditioner::reinitialize
virtual void reinitialize(bool nodeUpdated)=0
btDeformableContactProjection::setConstraints
virtual void setConstraints()
Definition: btDeformableContactProjection.cpp:111
btScalar
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:314
btDeformableBackwardEulerObjective::setDt
void setDt(btScalar dt)
Definition: btDeformableBackwardEulerObjective.cpp:53
btDeformableBackwardEulerObjective::applyForce
void applyForce(TVStack &force, bool setZero)
Definition: btDeformableBackwardEulerObjective.cpp:98
btDeformableBackwardEulerObjective::m_implicit
bool m_implicit
Definition: btDeformableBackwardEulerObjective.h:41
btDeformableBackwardEulerObjective::m_projection
btDeformableContactProjection m_projection
Definition: btDeformableBackwardEulerObjective.h:38
btDeformableBackwardEulerObjective::btDeformableBackwardEulerObjective
btDeformableBackwardEulerObjective(btAlignedObjectArray< btSoftBody * > &softBodies, const TVStack &backup_v)
Definition: btDeformableBackwardEulerObjective.cpp:20
btDeformableContactProjection::applyDynamicFriction
virtual void applyDynamicFriction(TVStack &f)
Definition: btDeformableContactProjection.cpp:434
btDeformableBackwardEulerObjective::m_dt
btScalar m_dt
Definition: btDeformableBackwardEulerObjective.h:34
btDeformableBackwardEulerObjective::reinitialize
void reinitialize(bool nodeUpdated, btScalar dt)
Definition: btDeformableBackwardEulerObjective.cpp:34
btDeformableBackwardEulerObjective::m_preconditioner
Preconditioner * m_preconditioner
Definition: btDeformableBackwardEulerObjective.h:37
btDeformableBackwardEulerObjective::setConstraints
void setConstraints()
Definition: btDeformableBackwardEulerObjective.cpp:189
btSoftBody::Node
Definition: btSoftBody.h:255
btDeformableBackwardEulerObjective::applyDynamicFriction
void applyDynamicFriction(TVStack &r)
Definition: btDeformableBackwardEulerObjective.cpp:194
btDeformableBackwardEulerObjective::updateId
virtual void updateId()
Definition: btDeformableBackwardEulerObjective.h:98
btDeformableBackwardEulerObjective::updateVelocity
void updateVelocity(const TVStack &dv)
Definition: btDeformableBackwardEulerObjective.cpp:85
btDeformableBackwardEulerObjective::computeResidual
void computeResidual(btScalar dt, TVStack &residual)
Definition: btDeformableBackwardEulerObjective.cpp:122
btDeformableBackwardEulerObjective::computeNorm
btScalar computeNorm(const TVStack &residual) const
Definition: btDeformableBackwardEulerObjective.cpp:140
btVector3
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:80
btDeformableContactProjection::project
virtual void project(TVStack &x)
Definition: btDeformableContactProjection.cpp:206
btSoftBody::Node::index
int index
Definition: btSoftBody.h:268
btDeformableBackwardEulerObjective::initialGuess
void initialGuess(TVStack &dv, const TVStack &residual)
Definition: btDeformableBackwardEulerObjective.cpp:174
btAlignedObjectArray< btSoftBody * >
btDeformableBackwardEulerObjective::~btDeformableBackwardEulerObjective
virtual ~btDeformableBackwardEulerObjective()
Definition: btDeformableBackwardEulerObjective.cpp:29
btDeformableBackwardEulerObjective::multiply
void multiply(const TVStack &x, TVStack &b) const
Definition: btDeformableBackwardEulerObjective.cpp:58
btSoftBody
The btSoftBody is an class to simulate cloth and volumetric soft bodies.
Definition: btSoftBody.h:72
btDeformableBackwardEulerObjective::totalEnergy
btScalar totalEnergy(btScalar dt)
Definition: btDeformableBackwardEulerObjective.cpp:150
btDeformableBackwardEulerObjective::m_backupVelocity
const TVStack & m_backupVelocity
Definition: btDeformableBackwardEulerObjective.h:39
btQuickprof.h
btDeformableBackwardEulerObjective::m_softBodies
btAlignedObjectArray< btSoftBody * > & m_softBodies
Definition: btDeformableBackwardEulerObjective.h:36
btCollisionObject::isActive
bool isActive() const
Definition: btCollisionObject.h:294
btDeformableBackwardEulerObjective::applyExplicitForce
void applyExplicitForce(TVStack &force)
Definition: btDeformableBackwardEulerObjective.cpp:160
MassPreconditioner
Definition: btPreconditioner.h:44
btSoftBody::Node::m_im
btScalar m_im
Definition: btSoftBody.h:264
btSoftBody::Node::m_v
btVector3 m_v
Definition: btSoftBody.h:259
btPreconditioner.h
BT_PROFILE
#define BT_PROFILE(name)
Definition: btQuickprof.h:197
btDeformableBackwardEulerObjective.h
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition: btAlignedObjectArray.h:142
btSoftBody::m_nodes
tNodeArray m_nodes
Definition: btSoftBody.h:777