Bullet Collision Detection & Physics Library: btDeformableLinearElasticityForce.h Source File

Bullet Collision Detection & Physics Library

btDeformableLinearElasticityForce.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_LINEAR_ELASTICITY_H
17#define BT_LINEAR_ELASTICITY_H
18
19#include "btDeformableLagrangianForce.h"
20#include "LinearMath/btQuickprof.h"
21#include "btSoftBodyInternals.h"
22#define TETRA_FLAT_THRESHOLD 0.01
23 class btDeformableLinearElasticityForce : public btDeformableLagrangianForce
24{
25public:
26 typedef btAlignedObjectArray<btVector3> TVStack;
27 btScalar m_mu, m_lambda;
28 btScalar m_E, m_nu; // Young's modulus and Poisson ratio
29 btScalar m_damping_alpha, m_damping_beta;
30 btDeformableLinearElasticityForce() : m_mu(1), m_lambda(1), m_damping_alpha(0.01), m_damping_beta(0.01)
31 {
32 updateYoungsModulusAndPoissonRatio();
33 }
34
35 btDeformableLinearElasticityForce(btScalar mu, btScalar lambda, btScalar damping_alpha = 0.01, btScalar damping_beta = 0.01) : m_mu(mu), m_lambda(lambda), m_damping_alpha(damping_alpha), m_damping_beta(damping_beta)
36 {
37 updateYoungsModulusAndPoissonRatio();
38 }
39
40 void updateYoungsModulusAndPoissonRatio()
41 {
42 // conversion from Lame Parameters to Young's modulus and Poisson ratio
43 // https://en.wikipedia.org/wiki/Lam%C3%A9_parameters
44 m_E = m_mu * (3 * m_lambda + 2 * m_mu) / (m_lambda + m_mu);
45 m_nu = m_lambda * 0.5 / (m_mu + m_lambda);
46 }
47
48 void updateLameParameters()
49 {
50 // conversion from Young's modulus and Poisson ratio to Lame Parameters
51 // https://en.wikipedia.org/wiki/Lam%C3%A9_parameters
52 m_mu = m_E * 0.5 / (1 + m_nu);
53 m_lambda = m_E * m_nu / ((1 + m_nu) * (1 - 2 * m_nu));
54 }
55
56 void setYoungsModulus(btScalar E)
57 {
58 m_E = E;
59 updateLameParameters();
60 }
61
62 void setPoissonRatio(btScalar nu)
63 {
64 m_nu = nu;
65 updateLameParameters();
66 }
67
68 void setDamping(btScalar damping_alpha, btScalar damping_beta)
69 {
70 m_damping_alpha = damping_alpha;
71 m_damping_beta = damping_beta;
72 }
73
74 void setLameParameters(btScalar mu, btScalar lambda)
75 {
76 m_mu = mu;
77 m_lambda = lambda;
78 updateYoungsModulusAndPoissonRatio();
79 }
80
81 virtual void addScaledForces(btScalar scale, TVStack& force)
82 {
83 addScaledDampingForce(scale, force);
84 addScaledElasticForce(scale, force);
85 }
86
87 virtual void addScaledExplicitForce(btScalar scale, TVStack& force)
88 {
89 addScaledElasticForce(scale, force);
90 }
91
92 // The damping matrix is calculated using the time n state as described in https://www.math.ucla.edu/~jteran/papers/GSSJT15.pdf to allow line search
93 virtual void addScaledDampingForce(btScalar scale, TVStack& force)
94 {
95 if (m_damping_alpha == 0 && m_damping_beta == 0)
96 return;
97 btScalar mu_damp = m_damping_beta * m_mu;
98 btScalar lambda_damp = m_damping_beta * m_lambda;
99 int numNodes = getNumNodes();
100 btAssert(numNodes <= force.size());
101 btVector3 grad_N_hat_1st_col = btVector3(-1, -1, -1);
102 for (int i = 0; i < m_softBodies.size(); ++i)
103 {
104 btSoftBody* psb = m_softBodies[i];
105 if (!psb->isActive())
106 {
107 continue;
108 }
109 for (int j = 0; j < psb->m_tetras.size(); ++j)
110 {
111 bool close_to_flat = (psb->m_tetraScratches[j].m_J < TETRA_FLAT_THRESHOLD);
112 btSoftBody::Tetra& tetra = psb->m_tetras[j];
113 btSoftBody::Node* node0 = tetra.m_n[0];
114 btSoftBody::Node* node1 = tetra.m_n[1];
115 btSoftBody::Node* node2 = tetra.m_n[2];
116 btSoftBody::Node* node3 = tetra.m_n[3];
117 size_t id0 = node0->index;
118 size_t id1 = node1->index;
119 size_t id2 = node2->index;
120 size_t id3 = node3->index;
121 btMatrix3x3 dF = DsFromVelocity(node0, node1, node2, node3) * tetra.m_Dm_inverse;
122 if (!close_to_flat)
123 {
124 dF = psb->m_tetraScratches[j].m_corotation.transpose() * dF;
125 }
126 btMatrix3x3 I;
127 I.setIdentity();
128 btMatrix3x3 dP = (dF + dF.transpose()) * mu_damp + I * ((dF[0][0] + dF[1][1] + dF[2][2]) * lambda_damp);
129 btMatrix3x3 df_on_node123 = dP * tetra.m_Dm_inverse.transpose();
130 if (!close_to_flat)
131 {
132 df_on_node123 = psb->m_tetraScratches[j].m_corotation * df_on_node123;
133 }
134 btVector3 df_on_node0 = df_on_node123 * grad_N_hat_1st_col;
135 // damping force differential
136 btScalar scale1 = scale * tetra.m_element_measure;
137 force[id0] -= scale1 * df_on_node0;
138 force[id1] -= scale1 * df_on_node123.getColumn(0);
139 force[id2] -= scale1 * df_on_node123.getColumn(1);
140 force[id3] -= scale1 * df_on_node123.getColumn(2);
141 }
142 for (int j = 0; j < psb->m_nodes.size(); ++j)
143 {
144 const btSoftBody::Node& node = psb->m_nodes[j];
145 size_t id = node.index;
146 if (node.m_im > 0)
147 {
148 force[id] -= scale * node.m_v / node.m_im * m_damping_alpha;
149 }
150 }
151 }
152 }
153
154 virtual double totalElasticEnergy(btScalar dt)
155 {
156 double energy = 0;
157 for (int i = 0; i < m_softBodies.size(); ++i)
158 {
159 btSoftBody* psb = m_softBodies[i];
160 if (!psb->isActive())
161 {
162 continue;
163 }
164 for (int j = 0; j < psb->m_tetraScratches.size(); ++j)
165 {
166 btSoftBody::Tetra& tetra = psb->m_tetras[j];
167 btSoftBody::TetraScratch& s = psb->m_tetraScratches[j];
168 energy += tetra.m_element_measure * elasticEnergyDensity(s);
169 }
170 }
171 return energy;
172 }
173
174 // The damping energy is formulated as in https://www.math.ucla.edu/~jteran/papers/GSSJT15.pdf to allow line search
175 virtual double totalDampingEnergy(btScalar dt)
176 {
177 double energy = 0;
178 int sz = 0;
179 for (int i = 0; i < m_softBodies.size(); ++i)
180 {
181 btSoftBody* psb = m_softBodies[i];
182 if (!psb->isActive())
183 {
184 continue;
185 }
186 for (int j = 0; j < psb->m_nodes.size(); ++j)
187 {
188 sz = btMax(sz, psb->m_nodes[j].index);
189 }
190 }
191 TVStack dampingForce;
192 dampingForce.resize(sz + 1);
193 for (int i = 0; i < dampingForce.size(); ++i)
194 dampingForce[i].setZero();
195 addScaledDampingForce(0.5, dampingForce);
196 for (int i = 0; i < m_softBodies.size(); ++i)
197 {
198 btSoftBody* psb = m_softBodies[i];
199 for (int j = 0; j < psb->m_nodes.size(); ++j)
200 {
201 const btSoftBody::Node& node = psb->m_nodes[j];
202 energy -= dampingForce[node.index].dot(node.m_v) / dt;
203 }
204 }
205 return energy;
206 }
207
208 double elasticEnergyDensity(const btSoftBody::TetraScratch& s)
209 {
210 double density = 0;
211 btMatrix3x3 epsilon = (s.m_F + s.m_F.transpose()) * 0.5 - btMatrix3x3::getIdentity();
212 btScalar trace = epsilon[0][0] + epsilon[1][1] + epsilon[2][2];
213 density += m_mu * (epsilon[0].length2() + epsilon[1].length2() + epsilon[2].length2());
214 density += m_lambda * trace * trace * 0.5;
215 return density;
216 }
217
218 virtual void addScaledElasticForce(btScalar scale, TVStack& force)
219 {
220 int numNodes = getNumNodes();
221 btAssert(numNodes <= force.size());
222 btVector3 grad_N_hat_1st_col = btVector3(-1, -1, -1);
223 for (int i = 0; i < m_softBodies.size(); ++i)
224 {
225 btSoftBody* psb = m_softBodies[i];
226 if (!psb->isActive())
227 {
228 continue;
229 }
230 btScalar max_p = psb->m_cfg.m_maxStress;
231 for (int j = 0; j < psb->m_tetras.size(); ++j)
232 {
233 btSoftBody::Tetra& tetra = psb->m_tetras[j];
234 btMatrix3x3 P;
235 firstPiola(psb->m_tetraScratches[j], P);
236#if USE_SVD
237 if (max_p > 0)
238 {
239 // since we want to clamp the principal stress to max_p, we only need to
240 // calculate SVD when sigma_0^2 + sigma_1^2 + sigma_2^2 > max_p * max_p
241 btScalar trPTP = (P[0].length2() + P[1].length2() + P[2].length2());
242 if (trPTP > max_p * max_p)
243 {
244 btMatrix3x3 U, V;
245 btVector3 sigma;
246 singularValueDecomposition(P, U, sigma, V);
247 sigma[0] = btMin(sigma[0], max_p);
248 sigma[1] = btMin(sigma[1], max_p);
249 sigma[2] = btMin(sigma[2], max_p);
250 sigma[0] = btMax(sigma[0], -max_p);
251 sigma[1] = btMax(sigma[1], -max_p);
252 sigma[2] = btMax(sigma[2], -max_p);
253 btMatrix3x3 Sigma;
254 Sigma.setIdentity();
255 Sigma[0][0] = sigma[0];
256 Sigma[1][1] = sigma[1];
257 Sigma[2][2] = sigma[2];
258 P = U * Sigma * V.transpose();
259 }
260 }
261#endif
262 // btVector3 force_on_node0 = P * (tetra.m_Dm_inverse.transpose()*grad_N_hat_1st_col);
263 btMatrix3x3 force_on_node123 = psb->m_tetraScratches[j].m_corotation * P * tetra.m_Dm_inverse.transpose();
264 btVector3 force_on_node0 = force_on_node123 * grad_N_hat_1st_col;
265
266 btSoftBody::Node* node0 = tetra.m_n[0];
267 btSoftBody::Node* node1 = tetra.m_n[1];
268 btSoftBody::Node* node2 = tetra.m_n[2];
269 btSoftBody::Node* node3 = tetra.m_n[3];
270 size_t id0 = node0->index;
271 size_t id1 = node1->index;
272 size_t id2 = node2->index;
273 size_t id3 = node3->index;
274
275 // elastic force
276 btScalar scale1 = scale * tetra.m_element_measure;
277 force[id0] -= scale1 * force_on_node0;
278 force[id1] -= scale1 * force_on_node123.getColumn(0);
279 force[id2] -= scale1 * force_on_node123.getColumn(1);
280 force[id3] -= scale1 * force_on_node123.getColumn(2);
281 }
282 }
283 }
284
285 virtual void buildDampingForceDifferentialDiagonal(btScalar scale, TVStack& diagA) {}
286
287 // The damping matrix is calculated using the time n state as described in https://www.math.ucla.edu/~jteran/papers/GSSJT15.pdf to allow line search
288 virtual void addScaledDampingForceDifferential(btScalar scale, const TVStack& dv, TVStack& df)
289 {
290 if (m_damping_alpha == 0 && m_damping_beta == 0)
291 return;
292 btScalar mu_damp = m_damping_beta * m_mu;
293 btScalar lambda_damp = m_damping_beta * m_lambda;
294 int numNodes = getNumNodes();
295 btAssert(numNodes <= df.size());
296 btVector3 grad_N_hat_1st_col = btVector3(-1, -1, -1);
297 for (int i = 0; i < m_softBodies.size(); ++i)
298 {
299 btSoftBody* psb = m_softBodies[i];
300 if (!psb->isActive())
301 {
302 continue;
303 }
304 for (int j = 0; j < psb->m_tetras.size(); ++j)
305 {
306 bool close_to_flat = (psb->m_tetraScratches[j].m_J < TETRA_FLAT_THRESHOLD);
307 btSoftBody::Tetra& tetra = psb->m_tetras[j];
308 btSoftBody::Node* node0 = tetra.m_n[0];
309 btSoftBody::Node* node1 = tetra.m_n[1];
310 btSoftBody::Node* node2 = tetra.m_n[2];
311 btSoftBody::Node* node3 = tetra.m_n[3];
312 size_t id0 = node0->index;
313 size_t id1 = node1->index;
314 size_t id2 = node2->index;
315 size_t id3 = node3->index;
316 btMatrix3x3 dF = Ds(id0, id1, id2, id3, dv) * tetra.m_Dm_inverse;
317 if (!close_to_flat)
318 {
319 dF = psb->m_tetraScratches[j].m_corotation.transpose() * dF;
320 }
321 btMatrix3x3 I;
322 I.setIdentity();
323 btMatrix3x3 dP = (dF + dF.transpose()) * mu_damp + I * ((dF[0][0] + dF[1][1] + dF[2][2]) * lambda_damp);
324 btMatrix3x3 df_on_node123 = dP * tetra.m_Dm_inverse.transpose();
325 if (!close_to_flat)
326 {
327 df_on_node123 = psb->m_tetraScratches[j].m_corotation * df_on_node123;
328 }
329 btVector3 df_on_node0 = df_on_node123 * grad_N_hat_1st_col;
330
331 // damping force differential
332 btScalar scale1 = scale * tetra.m_element_measure;
333 df[id0] -= scale1 * df_on_node0;
334 df[id1] -= scale1 * df_on_node123.getColumn(0);
335 df[id2] -= scale1 * df_on_node123.getColumn(1);
336 df[id3] -= scale1 * df_on_node123.getColumn(2);
337 }
338 for (int j = 0; j < psb->m_nodes.size(); ++j)
339 {
340 const btSoftBody::Node& node = psb->m_nodes[j];
341 size_t id = node.index;
342 if (node.m_im > 0)
343 {
344 df[id] -= scale * dv[id] / node.m_im * m_damping_alpha;
345 }
346 }
347 }
348 }
349
350 virtual void addScaledElasticForceDifferential(btScalar scale, const TVStack& dx, TVStack& df)
351 {
352 int numNodes = getNumNodes();
353 btAssert(numNodes <= df.size());
354 btVector3 grad_N_hat_1st_col = btVector3(-1, -1, -1);
355 for (int i = 0; i < m_softBodies.size(); ++i)
356 {
357 btSoftBody* psb = m_softBodies[i];
358 if (!psb->isActive())
359 {
360 continue;
361 }
362 for (int j = 0; j < psb->m_tetras.size(); ++j)
363 {
364 btSoftBody::Tetra& tetra = psb->m_tetras[j];
365 btSoftBody::Node* node0 = tetra.m_n[0];
366 btSoftBody::Node* node1 = tetra.m_n[1];
367 btSoftBody::Node* node2 = tetra.m_n[2];
368 btSoftBody::Node* node3 = tetra.m_n[3];
369 size_t id0 = node0->index;
370 size_t id1 = node1->index;
371 size_t id2 = node2->index;
372 size_t id3 = node3->index;
373 btMatrix3x3 dF = psb->m_tetraScratches[j].m_corotation.transpose() * Ds(id0, id1, id2, id3, dx) * tetra.m_Dm_inverse;
374 btMatrix3x3 dP;
375 firstPiolaDifferential(psb->m_tetraScratches[j], dF, dP);
376 // btVector3 df_on_node0 = dP * (tetra.m_Dm_inverse.transpose()*grad_N_hat_1st_col);
377 btMatrix3x3 df_on_node123 = psb->m_tetraScratches[j].m_corotation * dP * tetra.m_Dm_inverse.transpose();
378 btVector3 df_on_node0 = df_on_node123 * grad_N_hat_1st_col;
379
380 // elastic force differential
381 btScalar scale1 = scale * tetra.m_element_measure;
382 df[id0] -= scale1 * df_on_node0;
383 df[id1] -= scale1 * df_on_node123.getColumn(0);
384 df[id2] -= scale1 * df_on_node123.getColumn(1);
385 df[id3] -= scale1 * df_on_node123.getColumn(2);
386 }
387 }
388 }
389
390 void firstPiola(const btSoftBody::TetraScratch& s, btMatrix3x3& P)
391 {
392 btMatrix3x3 corotated_F = s.m_corotation.transpose() * s.m_F;
393
394 btMatrix3x3 epsilon = (corotated_F + corotated_F.transpose()) * 0.5 - btMatrix3x3::getIdentity();
395 btScalar trace = epsilon[0][0] + epsilon[1][1] + epsilon[2][2];
396 P = epsilon * btScalar(2) * m_mu + btMatrix3x3::getIdentity() * m_lambda * trace;
397 }
398
399 // Let P be the first piola stress.
400 // This function calculates the dP = dP/dF * dF
401 void firstPiolaDifferential(const btSoftBody::TetraScratch& s, const btMatrix3x3& dF, btMatrix3x3& dP)
402 {
403 btScalar trace = (dF[0][0] + dF[1][1] + dF[2][2]);
404 dP = (dF + dF.transpose()) * m_mu + btMatrix3x3::getIdentity() * m_lambda * trace;
405 }
406
407 // Let Q be the damping stress.
408 // This function calculates the dP = dQ/dF * dF
409 void firstPiolaDampingDifferential(const btSoftBody::TetraScratch& s, const btMatrix3x3& dF, btMatrix3x3& dP)
410 {
411 btScalar mu_damp = m_damping_beta * m_mu;
412 btScalar lambda_damp = m_damping_beta * m_lambda;
413 btScalar trace = (dF[0][0] + dF[1][1] + dF[2][2]);
414 dP = (dF + dF.transpose()) * mu_damp + btMatrix3x3::getIdentity() * lambda_damp * trace;
415 }
416
417 virtual void addScaledHessian(btScalar scale)
418 {
419 btVector3 grad_N_hat_1st_col = btVector3(-1, -1, -1);
420 for (int i = 0; i < m_softBodies.size(); ++i)
421 {
422 btSoftBody* psb = m_softBodies[i];
423 if (!psb->isActive())
424 {
425 continue;
426 }
427 for (int j = 0; j < psb->m_tetras.size(); ++j)
428 {
429 btSoftBody::Tetra& tetra = psb->m_tetras[j];
430 btMatrix3x3 P;
431 firstPiola(psb->m_tetraScratches[j], P); // make sure scratch is evaluated at x_n + dt * vn
432 btMatrix3x3 force_on_node123 = psb->m_tetraScratches[j].m_corotation * P * tetra.m_Dm_inverse.transpose();
433 btVector3 force_on_node0 = force_on_node123 * grad_N_hat_1st_col;
434 btSoftBody::Node* node0 = tetra.m_n[0];
435 btSoftBody::Node* node1 = tetra.m_n[1];
436 btSoftBody::Node* node2 = tetra.m_n[2];
437 btSoftBody::Node* node3 = tetra.m_n[3];
438 btScalar scale1 = scale * (scale + m_damping_beta) * tetra.m_element_measure; // stiff and stiffness-damping terms;
439 node0->m_effectiveMass += OuterProduct(force_on_node0, force_on_node0) * scale1;
440 node1->m_effectiveMass += OuterProduct(force_on_node123.getColumn(0), force_on_node123.getColumn(0)) * scale1;
441 node2->m_effectiveMass += OuterProduct(force_on_node123.getColumn(1), force_on_node123.getColumn(1)) * scale1;
442 node3->m_effectiveMass += OuterProduct(force_on_node123.getColumn(2), force_on_node123.getColumn(2)) * scale1;
443 }
444 for (int j = 0; j < psb->m_nodes.size(); ++j)
445 {
446 btSoftBody::Node& node = psb->m_nodes[j];
447 if (node.m_im > 0)
448 {
449 btMatrix3x3 I;
450 I.setIdentity();
451 node.m_effectiveMass += I * (scale * (1.0 / node.m_im) * m_damping_alpha);
452 }
453 }
454 }
455 }
456
457 virtual btDeformableLagrangianForceType getForceType()
458 {
459 return BT_LINEAR_ELASTICITY_FORCE;
460 }
461};
462#endif /* BT_LINEAR_ELASTICITY_H */
btDeformableLagrangianForce.h
btDeformableLagrangianForceType
btDeformableLagrangianForceType
Definition btDeformableLagrangianForce.h:24
BT_LINEAR_ELASTICITY_FORCE
@ BT_LINEAR_ELASTICITY_FORCE
Definition btDeformableLagrangianForce.h:29
TETRA_FLAT_THRESHOLD
#define TETRA_FLAT_THRESHOLD
Definition btDeformableLinearElasticityForce.h:22
singularValueDecomposition
void singularValueDecomposition(const btMatrix2x2 &A, GivensRotation &U, const btMatrix2x2 &Sigma, GivensRotation &V, const btScalar tol=64 *std::numeric_limits< btScalar >::epsilon())
2x2 SVD (singular value decomposition) A=USV'
Definition btImplicitQRSVD.h:469
btMax
const T & btMax(const T &a, const T &b)
Definition btMinMax.h:27
btMin
const T & btMin(const T &a, const T &b)
Definition btMinMax.h:21
btQuickprof.h
btScalar
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition btScalar.h:314
btAssert
#define btAssert(x)
Definition btScalar.h:153
btSoftBodyInternals.h
OuterProduct
static btMatrix3x3 OuterProduct(const btScalar *v1, const btScalar *v2, const btScalar *v3, const btScalar *u1, const btScalar *u2, const btScalar *u3, int ndof)
Definition btSoftBodyInternals.h:924
btAlignedObjectArray
The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods It...
Definition btAlignedObjectArray.h:46
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition btAlignedObjectArray.h:142
btAlignedObjectArray::resize
void resize(int newsize, const T &fillData=T())
Definition btAlignedObjectArray.h:203
btCollisionObject::isActive
bool isActive() const
Definition btCollisionObject.h:306
btDeformableLagrangianForce::Ds
virtual btMatrix3x3 Ds(int id0, int id1, int id2, int id3, const TVStack &dx)
Definition btDeformableLagrangianForce.h:105
btDeformableLagrangianForce::DsFromVelocity
virtual btMatrix3x3 DsFromVelocity(const btSoftBody::Node *n0, const btSoftBody::Node *n1, const btSoftBody::Node *n2, const btSoftBody::Node *n3)
Definition btDeformableLagrangianForce.h:114
btDeformableLagrangianForce::getNumNodes
virtual int getNumNodes()
Definition btDeformableLagrangianForce.h:78
btDeformableLagrangianForce::btDeformableLagrangianForce
btDeformableLagrangianForce()
Definition btDeformableLagrangianForce.h:45
btDeformableLagrangianForce::m_softBodies
btAlignedObjectArray< btSoftBody * > m_softBodies
Definition btDeformableLagrangianForce.h:42
btDeformableLinearElasticityForce::btDeformableLinearElasticityForce
btDeformableLinearElasticityForce()
Definition btDeformableLinearElasticityForce.h:30
btDeformableLinearElasticityForce::getForceType
virtual btDeformableLagrangianForceType getForceType()
Definition btDeformableLinearElasticityForce.h:457
btDeformableLinearElasticityForce::addScaledElasticForceDifferential
virtual void addScaledElasticForceDifferential(btScalar scale, const TVStack &dx, TVStack &df)
Definition btDeformableLinearElasticityForce.h:350
btDeformableLinearElasticityForce::buildDampingForceDifferentialDiagonal
virtual void buildDampingForceDifferentialDiagonal(btScalar scale, TVStack &diagA)
Definition btDeformableLinearElasticityForce.h:285
btDeformableLinearElasticityForce::m_lambda
btScalar m_lambda
Definition btDeformableLinearElasticityForce.h:27
btDeformableLinearElasticityForce::setDamping
void setDamping(btScalar damping_alpha, btScalar damping_beta)
Definition btDeformableLinearElasticityForce.h:68
btDeformableLinearElasticityForce::addScaledExplicitForce
virtual void addScaledExplicitForce(btScalar scale, TVStack &force)
Definition btDeformableLinearElasticityForce.h:87
btDeformableLinearElasticityForce::TVStack
btAlignedObjectArray< btVector3 > TVStack
Definition btDeformableLinearElasticityForce.h:26
btDeformableLinearElasticityForce::firstPiolaDampingDifferential
void firstPiolaDampingDifferential(const btSoftBody::TetraScratch &s, const btMatrix3x3 &dF, btMatrix3x3 &dP)
Definition btDeformableLinearElasticityForce.h:409
btDeformableLinearElasticityForce::btDeformableLinearElasticityForce
btDeformableLinearElasticityForce(btScalar mu, btScalar lambda, btScalar damping_alpha=0.01, btScalar damping_beta=0.01)
Definition btDeformableLinearElasticityForce.h:35
btDeformableLinearElasticityForce::setPoissonRatio
void setPoissonRatio(btScalar nu)
Definition btDeformableLinearElasticityForce.h:62
btDeformableLinearElasticityForce::m_damping_beta
btScalar m_damping_beta
Definition btDeformableLinearElasticityForce.h:29
btDeformableLinearElasticityForce::addScaledElasticForce
virtual void addScaledElasticForce(btScalar scale, TVStack &force)
Definition btDeformableLinearElasticityForce.h:218
btDeformableLinearElasticityForce::firstPiola
void firstPiola(const btSoftBody::TetraScratch &s, btMatrix3x3 &P)
Definition btDeformableLinearElasticityForce.h:390
btDeformableLinearElasticityForce::updateLameParameters
void updateLameParameters()
Definition btDeformableLinearElasticityForce.h:48
btDeformableLinearElasticityForce::addScaledForces
virtual void addScaledForces(btScalar scale, TVStack &force)
Definition btDeformableLinearElasticityForce.h:81
btDeformableLinearElasticityForce::m_mu
btScalar m_mu
Definition btDeformableLinearElasticityForce.h:27
btDeformableLinearElasticityForce::m_nu
btScalar m_nu
Definition btDeformableLinearElasticityForce.h:28
btDeformableLinearElasticityForce::elasticEnergyDensity
double elasticEnergyDensity(const btSoftBody::TetraScratch &s)
Definition btDeformableLinearElasticityForce.h:208
btDeformableLinearElasticityForce::totalDampingEnergy
virtual double totalDampingEnergy(btScalar dt)
Definition btDeformableLinearElasticityForce.h:175
btDeformableLinearElasticityForce::totalElasticEnergy
virtual double totalElasticEnergy(btScalar dt)
Definition btDeformableLinearElasticityForce.h:154
btDeformableLinearElasticityForce::addScaledDampingForce
virtual void addScaledDampingForce(btScalar scale, TVStack &force)
Definition btDeformableLinearElasticityForce.h:93
btDeformableLinearElasticityForce::addScaledDampingForceDifferential
virtual void addScaledDampingForceDifferential(btScalar scale, const TVStack &dv, TVStack &df)
Definition btDeformableLinearElasticityForce.h:288
btDeformableLinearElasticityForce::addScaledHessian
virtual void addScaledHessian(btScalar scale)
Definition btDeformableLinearElasticityForce.h:417
btDeformableLinearElasticityForce::firstPiolaDifferential
void firstPiolaDifferential(const btSoftBody::TetraScratch &s, const btMatrix3x3 &dF, btMatrix3x3 &dP)
Definition btDeformableLinearElasticityForce.h:401
btDeformableLinearElasticityForce::setYoungsModulus
void setYoungsModulus(btScalar E)
Definition btDeformableLinearElasticityForce.h:56
btDeformableLinearElasticityForce::setLameParameters
void setLameParameters(btScalar mu, btScalar lambda)
Definition btDeformableLinearElasticityForce.h:74
btDeformableLinearElasticityForce::updateYoungsModulusAndPoissonRatio
void updateYoungsModulusAndPoissonRatio()
Definition btDeformableLinearElasticityForce.h:40
btDeformableLinearElasticityForce::m_E
btScalar m_E
Definition btDeformableLinearElasticityForce.h:28
btDeformableLinearElasticityForce::m_damping_alpha
btScalar m_damping_alpha
Definition btDeformableLinearElasticityForce.h:29
btMatrix3x3
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition btMatrix3x3.h:50
btMatrix3x3::transpose
btMatrix3x3 transpose() const
Return the transpose of the matrix.
Definition btMatrix3x3.h:1049
btMatrix3x3::getIdentity
static const btMatrix3x3 & getIdentity()
Definition btMatrix3x3.h:350
btMatrix3x3::setIdentity
void setIdentity()
Set the matrix to the identity.
Definition btMatrix3x3.h:323
btMatrix3x3::getColumn
btVector3 getColumn(int i) const
Get a column of the matrix as a vector.
Definition btMatrix3x3.h:142
btSoftBody
The btSoftBody is an class to simulate cloth and volumetric soft bodies.
Definition btSoftBody.h:75
btSoftBody::m_tetras
tTetraArray m_tetras
Definition btSoftBody.h:819
btSoftBody::m_cfg
Config m_cfg
Definition btSoftBody.h:808
btSoftBody::m_tetraScratches
btAlignedObjectArray< TetraScratch > m_tetraScratches
Definition btSoftBody.h:820
btSoftBody::m_nodes
tNodeArray m_nodes
Definition btSoftBody.h:814
btVector3
btVector3 can be used to represent 3D points and vectors.
Definition btVector3.h:82
btSoftBody::Config::m_maxStress
btScalar m_maxStress
Definition btSoftBody.h:740
btSoftBody::Node
Definition btSoftBody.h:268
btSoftBody::Node::m_im
btScalar m_im
Definition btSoftBody.h:275
btSoftBody::Node::m_v
btVector3 m_v
Definition btSoftBody.h:271
btSoftBody::Node::index
int index
Definition btSoftBody.h:280
btSoftBody::Node::m_effectiveMass
btMatrix3x3 m_effectiveMass
Definition btSoftBody.h:282
btSoftBody::TetraScratch
Definition btSoftBody.h:332
btSoftBody::TetraScratch::m_F
btMatrix3x3 m_F
Definition btSoftBody.h:333
btSoftBody::TetraScratch::m_corotation
btMatrix3x3 m_corotation
Definition btSoftBody.h:337
btSoftBody::Tetra
Definition btSoftBody.h:317
btSoftBody::Tetra::m_element_measure
btScalar m_element_measure
Definition btSoftBody.h:326
btSoftBody::Tetra::m_Dm_inverse
btMatrix3x3 m_Dm_inverse
Definition btSoftBody.h:324
btSoftBody::Tetra::m_n
Node * m_n[4]
Definition btSoftBody.h:318