1 | /* |
---|
2 | Bullet Continuous Collision Detection and Physics Library |
---|
3 | Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ |
---|
4 | |
---|
5 | This software is provided 'as-is', without any express or implied warranty. |
---|
6 | In no event will the authors be held liable for any damages arising from the use of this software. |
---|
7 | Permission is granted to anyone to use this software for any purpose, |
---|
8 | including commercial applications, and to alter it and redistribute it freely, |
---|
9 | subject to the following restrictions: |
---|
10 | |
---|
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 | ///btSoftBody implementation by Nathanael Presson |
---|
16 | |
---|
17 | #ifndef _BT_SOFT_BODY_H |
---|
18 | #define _BT_SOFT_BODY_H |
---|
19 | |
---|
20 | #include "LinearMath/btAlignedObjectArray.h" |
---|
21 | #include "LinearMath/btPoint3.h" |
---|
22 | #include "LinearMath/btTransform.h" |
---|
23 | #include "LinearMath/btIDebugDraw.h" |
---|
24 | #include "BulletDynamics/Dynamics/btRigidBody.h" |
---|
25 | |
---|
26 | #include "BulletCollision/CollisionShapes/btConcaveShape.h" |
---|
27 | #include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" |
---|
28 | #include "btSparseSDF.h" |
---|
29 | #include "BulletCollision/BroadphaseCollision/btDbvt.h" |
---|
30 | |
---|
31 | class btBroadphaseInterface; |
---|
32 | class btDispatcher; |
---|
33 | |
---|
34 | /* btSoftBodyWorldInfo */ |
---|
35 | struct btSoftBodyWorldInfo |
---|
36 | { |
---|
37 | btScalar air_density; |
---|
38 | btScalar water_density; |
---|
39 | btScalar water_offset; |
---|
40 | btVector3 water_normal; |
---|
41 | btBroadphaseInterface* m_broadphase; |
---|
42 | btDispatcher* m_dispatcher; |
---|
43 | btVector3 m_gravity; |
---|
44 | btSparseSdf<3> m_sparsesdf; |
---|
45 | }; |
---|
46 | |
---|
47 | |
---|
48 | /// btSoftBody is work-in-progress |
---|
49 | class btSoftBody : public btCollisionObject |
---|
50 | { |
---|
51 | public: |
---|
52 | // |
---|
53 | // Enumerations |
---|
54 | // |
---|
55 | |
---|
56 | ///eAeroModel |
---|
57 | struct eAeroModel { enum _ { |
---|
58 | V_Point, ///Vertex normals are oriented toward velocity |
---|
59 | V_TwoSided, ///Vertex normals are fliped to match velocity |
---|
60 | V_OneSided, ///Vertex normals are taken as it is |
---|
61 | F_TwoSided, ///Face normals are fliped to match velocity |
---|
62 | F_OneSided, ///Face normals are taken as it is |
---|
63 | END |
---|
64 | };}; |
---|
65 | |
---|
66 | ///eVSolver : velocities solvers |
---|
67 | struct eVSolver { enum _ { |
---|
68 | Linear, ///Linear solver |
---|
69 | END |
---|
70 | };}; |
---|
71 | |
---|
72 | ///ePSolver : positions solvers |
---|
73 | struct ePSolver { enum _ { |
---|
74 | Linear, ///Linear solver |
---|
75 | Anchors, ///Anchor solver |
---|
76 | RContacts, ///Rigid contacts solver |
---|
77 | SContacts, ///Soft contacts solver |
---|
78 | END |
---|
79 | };}; |
---|
80 | |
---|
81 | ///eSolverPresets |
---|
82 | struct eSolverPresets { enum _ { |
---|
83 | Positions, |
---|
84 | Velocities, |
---|
85 | Default = Positions, |
---|
86 | END |
---|
87 | };}; |
---|
88 | |
---|
89 | ///eFeature |
---|
90 | struct eFeature { enum _ { |
---|
91 | None, |
---|
92 | Node, |
---|
93 | Link, |
---|
94 | Face, |
---|
95 | END |
---|
96 | };}; |
---|
97 | |
---|
98 | typedef btAlignedObjectArray<eVSolver::_> tVSolverArray; |
---|
99 | typedef btAlignedObjectArray<ePSolver::_> tPSolverArray; |
---|
100 | |
---|
101 | // |
---|
102 | // Flags |
---|
103 | // |
---|
104 | |
---|
105 | ///fCollision |
---|
106 | struct fCollision { enum _ { |
---|
107 | RVSmask = 0x000f, ///Rigid versus soft mask |
---|
108 | SDF_RS = 0x0001, ///SDF based rigid vs soft |
---|
109 | CL_RS = 0x0002, ///Cluster vs convex rigid vs soft |
---|
110 | |
---|
111 | SVSmask = 0x00f0, ///Rigid versus soft mask |
---|
112 | VF_SS = 0x0010, ///Vertex vs face soft vs soft handling |
---|
113 | CL_SS = 0x0020, ///Cluster vs cluster soft vs soft handling |
---|
114 | /* presets */ |
---|
115 | Default = SDF_RS, |
---|
116 | END |
---|
117 | };}; |
---|
118 | |
---|
119 | ///fMaterial |
---|
120 | struct fMaterial { enum _ { |
---|
121 | DebugDraw = 0x0001, /// Enable debug draw |
---|
122 | /* presets */ |
---|
123 | Default = DebugDraw, |
---|
124 | END |
---|
125 | };}; |
---|
126 | |
---|
127 | // |
---|
128 | // API Types |
---|
129 | // |
---|
130 | |
---|
131 | /* sRayCast */ |
---|
132 | struct sRayCast |
---|
133 | { |
---|
134 | btSoftBody* body; /// soft body |
---|
135 | eFeature::_ feature; /// feature type |
---|
136 | int index; /// feature index |
---|
137 | btScalar time; /// time of impact (rayorg+raydir*time) |
---|
138 | }; |
---|
139 | |
---|
140 | /* ImplicitFn */ |
---|
141 | struct ImplicitFn |
---|
142 | { |
---|
143 | virtual btScalar Eval(const btVector3& x)=0; |
---|
144 | }; |
---|
145 | |
---|
146 | // |
---|
147 | // Internal types |
---|
148 | // |
---|
149 | |
---|
150 | typedef btAlignedObjectArray<btScalar> tScalarArray; |
---|
151 | typedef btAlignedObjectArray<btVector3> tVector3Array; |
---|
152 | |
---|
153 | /* sCti is Softbody contact info */ |
---|
154 | struct sCti |
---|
155 | { |
---|
156 | btRigidBody* m_body; /* Rigid body */ |
---|
157 | btVector3 m_normal; /* Outward normal */ |
---|
158 | btScalar m_offset; /* Offset from origin */ |
---|
159 | }; |
---|
160 | |
---|
161 | /* sMedium */ |
---|
162 | struct sMedium |
---|
163 | { |
---|
164 | btVector3 m_velocity; /* Velocity */ |
---|
165 | btScalar m_pressure; /* Pressure */ |
---|
166 | btScalar m_density; /* Density */ |
---|
167 | }; |
---|
168 | |
---|
169 | /* Base type */ |
---|
170 | struct Element |
---|
171 | { |
---|
172 | void* m_tag; // User data |
---|
173 | Element() : m_tag(0) {} |
---|
174 | }; |
---|
175 | /* Material */ |
---|
176 | struct Material : Element |
---|
177 | { |
---|
178 | btScalar m_kLST; // Linear stiffness coefficient [0,1] |
---|
179 | btScalar m_kAST; // Area/Angular stiffness coefficient [0,1] |
---|
180 | btScalar m_kVST; // Volume stiffness coefficient [0,1] |
---|
181 | int m_flags; // Flags |
---|
182 | }; |
---|
183 | |
---|
184 | /* Feature */ |
---|
185 | struct Feature : Element |
---|
186 | { |
---|
187 | Material* m_material; // Material |
---|
188 | }; |
---|
189 | /* Node */ |
---|
190 | struct Node : Feature |
---|
191 | { |
---|
192 | btVector3 m_x; // Position |
---|
193 | btVector3 m_q; // Previous step position |
---|
194 | btVector3 m_v; // Velocity |
---|
195 | btVector3 m_f; // Force accumulator |
---|
196 | btVector3 m_n; // Normal |
---|
197 | btScalar m_im; // 1/mass |
---|
198 | btScalar m_area; // Area |
---|
199 | btDbvtNode* m_leaf; // Leaf data |
---|
200 | int m_battach:1; // Attached |
---|
201 | }; |
---|
202 | /* Link */ |
---|
203 | struct Link : Feature |
---|
204 | { |
---|
205 | Node* m_n[2]; // Node pointers |
---|
206 | btScalar m_rl; // Rest length |
---|
207 | int m_bbending:1; // Bending link |
---|
208 | btScalar m_c0; // (ima+imb)*kLST |
---|
209 | btScalar m_c1; // rl^2 |
---|
210 | btScalar m_c2; // |gradient|^2/c0 |
---|
211 | btVector3 m_c3; // gradient |
---|
212 | }; |
---|
213 | /* Face */ |
---|
214 | struct Face : Feature |
---|
215 | { |
---|
216 | Node* m_n[3]; // Node pointers |
---|
217 | btVector3 m_normal; // Normal |
---|
218 | btScalar m_ra; // Rest area |
---|
219 | btDbvtNode* m_leaf; // Leaf data |
---|
220 | }; |
---|
221 | /* RContact */ |
---|
222 | struct RContact |
---|
223 | { |
---|
224 | sCti m_cti; // Contact infos |
---|
225 | Node* m_node; // Owner node |
---|
226 | btMatrix3x3 m_c0; // Impulse matrix |
---|
227 | btVector3 m_c1; // Relative anchor |
---|
228 | btScalar m_c2; // ima*dt |
---|
229 | btScalar m_c3; // Friction |
---|
230 | btScalar m_c4; // Hardness |
---|
231 | }; |
---|
232 | /* SContact */ |
---|
233 | struct SContact |
---|
234 | { |
---|
235 | Node* m_node; // Node |
---|
236 | Face* m_face; // Face |
---|
237 | btVector3 m_weights; // Weigths |
---|
238 | btVector3 m_normal; // Normal |
---|
239 | btScalar m_margin; // Margin |
---|
240 | btScalar m_friction; // Friction |
---|
241 | btScalar m_cfm[2]; // Constraint force mixing |
---|
242 | }; |
---|
243 | /* Anchor */ |
---|
244 | struct Anchor |
---|
245 | { |
---|
246 | Node* m_node; // Node pointer |
---|
247 | btVector3 m_local; // Anchor position in body space |
---|
248 | btRigidBody* m_body; // Body |
---|
249 | btMatrix3x3 m_c0; // Impulse matrix |
---|
250 | btVector3 m_c1; // Relative anchor |
---|
251 | btScalar m_c2; // ima*dt |
---|
252 | }; |
---|
253 | /* Note */ |
---|
254 | struct Note : Element |
---|
255 | { |
---|
256 | const char* m_text; // Text |
---|
257 | btVector3 m_offset; // Offset |
---|
258 | int m_rank; // Rank |
---|
259 | Node* m_nodes[4]; // Nodes |
---|
260 | btScalar m_coords[4]; // Coordinates |
---|
261 | }; |
---|
262 | /* Pose */ |
---|
263 | struct Pose |
---|
264 | { |
---|
265 | bool m_bvolume; // Is valid |
---|
266 | bool m_bframe; // Is frame |
---|
267 | btScalar m_volume; // Rest volume |
---|
268 | tVector3Array m_pos; // Reference positions |
---|
269 | tScalarArray m_wgh; // Weights |
---|
270 | btVector3 m_com; // COM |
---|
271 | btMatrix3x3 m_rot; // Rotation |
---|
272 | btMatrix3x3 m_scl; // Scale |
---|
273 | btMatrix3x3 m_aqq; // Base scaling |
---|
274 | }; |
---|
275 | /* Cluster */ |
---|
276 | struct Cluster |
---|
277 | { |
---|
278 | btAlignedObjectArray<Node*> m_nodes; |
---|
279 | tScalarArray m_masses; |
---|
280 | tVector3Array m_framerefs; |
---|
281 | btTransform m_framexform; |
---|
282 | btScalar m_idmass; |
---|
283 | btScalar m_imass; |
---|
284 | btMatrix3x3 m_locii; |
---|
285 | btMatrix3x3 m_invwi; |
---|
286 | btVector3 m_com; |
---|
287 | btVector3 m_vimpulses[2]; |
---|
288 | btVector3 m_dimpulses[2]; |
---|
289 | int m_nvimpulses; |
---|
290 | int m_ndimpulses; |
---|
291 | btVector3 m_lv; |
---|
292 | btVector3 m_av; |
---|
293 | btDbvtNode* m_leaf; |
---|
294 | btScalar m_ndamping; |
---|
295 | btScalar m_ldamping; |
---|
296 | btScalar m_adamping; |
---|
297 | btScalar m_matching; |
---|
298 | bool m_collide; |
---|
299 | Cluster() : m_leaf(0),m_ndamping(0),m_ldamping(0),m_adamping(0),m_matching(0) {} |
---|
300 | }; |
---|
301 | /* Impulse */ |
---|
302 | struct Impulse |
---|
303 | { |
---|
304 | btVector3 m_velocity; |
---|
305 | btVector3 m_drift; |
---|
306 | int m_asVelocity:1; |
---|
307 | int m_asDrift:1; |
---|
308 | Impulse() : m_velocity(0,0,0),m_drift(0,0,0),m_asVelocity(0),m_asDrift(0) {} |
---|
309 | Impulse operator -() const |
---|
310 | { |
---|
311 | Impulse i=*this; |
---|
312 | i.m_velocity=-i.m_velocity; |
---|
313 | i.m_drift=-i.m_drift; |
---|
314 | return(i); |
---|
315 | } |
---|
316 | Impulse operator*(btScalar x) const |
---|
317 | { |
---|
318 | Impulse i=*this; |
---|
319 | i.m_velocity*=x; |
---|
320 | i.m_drift*=x; |
---|
321 | return(i); |
---|
322 | } |
---|
323 | }; |
---|
324 | /* Body */ |
---|
325 | struct Body |
---|
326 | { |
---|
327 | Cluster* m_soft; |
---|
328 | btRigidBody* m_rigid; |
---|
329 | Body() : m_soft(0),m_rigid(0) {} |
---|
330 | Body(Cluster* p) : m_soft(p),m_rigid(0) {} |
---|
331 | Body(btRigidBody* p) : m_soft(0),m_rigid(p) {} |
---|
332 | void activate() const |
---|
333 | { |
---|
334 | if(m_rigid) m_rigid->activate(); |
---|
335 | } |
---|
336 | const btMatrix3x3& invWorldInertia() const |
---|
337 | { |
---|
338 | static const btMatrix3x3 iwi(0,0,0,0,0,0,0,0,0); |
---|
339 | if(m_rigid) return(m_rigid->getInvInertiaTensorWorld()); |
---|
340 | if(m_soft) return(m_soft->m_invwi); |
---|
341 | return(iwi); |
---|
342 | } |
---|
343 | btScalar invMass() const |
---|
344 | { |
---|
345 | if(m_rigid) return(m_rigid->getInvMass()); |
---|
346 | if(m_soft) return(m_soft->m_imass); |
---|
347 | return(0); |
---|
348 | } |
---|
349 | const btTransform& xform() const |
---|
350 | { |
---|
351 | static const btTransform identity=btTransform::getIdentity(); |
---|
352 | if(m_rigid) return(m_rigid->getInterpolationWorldTransform()); |
---|
353 | if(m_soft) return(m_soft->m_framexform); |
---|
354 | return(identity); |
---|
355 | } |
---|
356 | btVector3 linearVelocity() const |
---|
357 | { |
---|
358 | if(m_rigid) return(m_rigid->getLinearVelocity()); |
---|
359 | if(m_soft) return(m_soft->m_lv); |
---|
360 | return(btVector3(0,0,0)); |
---|
361 | } |
---|
362 | btVector3 angularVelocity(const btVector3& rpos) const |
---|
363 | { |
---|
364 | if(m_rigid) return(cross(m_rigid->getAngularVelocity(),rpos)); |
---|
365 | if(m_soft) return(cross(m_soft->m_av,rpos)); |
---|
366 | return(btVector3(0,0,0)); |
---|
367 | } |
---|
368 | btVector3 angularVelocity() const |
---|
369 | { |
---|
370 | if(m_rigid) return(m_rigid->getAngularVelocity()); |
---|
371 | if(m_soft) return(m_soft->m_av); |
---|
372 | return(btVector3(0,0,0)); |
---|
373 | } |
---|
374 | btVector3 velocity(const btVector3& rpos) const |
---|
375 | { |
---|
376 | return(linearVelocity()+angularVelocity(rpos)); |
---|
377 | } |
---|
378 | void applyVImpulse(const btVector3& impulse,const btVector3& rpos) const |
---|
379 | { |
---|
380 | if(m_rigid) m_rigid->applyImpulse(impulse,rpos); |
---|
381 | if(m_soft) btSoftBody::clusterVImpulse(m_soft,rpos,impulse); |
---|
382 | } |
---|
383 | void applyDImpulse(const btVector3& impulse,const btVector3& rpos) const |
---|
384 | { |
---|
385 | if(m_rigid) m_rigid->applyImpulse(impulse,rpos); |
---|
386 | if(m_soft) btSoftBody::clusterDImpulse(m_soft,rpos,impulse); |
---|
387 | } |
---|
388 | void applyImpulse(const Impulse& impulse,const btVector3& rpos) const |
---|
389 | { |
---|
390 | if(impulse.m_asVelocity) applyVImpulse(impulse.m_velocity,rpos); |
---|
391 | if(impulse.m_asDrift) applyDImpulse(impulse.m_drift,rpos); |
---|
392 | } |
---|
393 | void applyVAImpulse(const btVector3& impulse) const |
---|
394 | { |
---|
395 | if(m_rigid) m_rigid->applyTorqueImpulse(impulse); |
---|
396 | if(m_soft) btSoftBody::clusterVAImpulse(m_soft,impulse); |
---|
397 | } |
---|
398 | void applyDAImpulse(const btVector3& impulse) const |
---|
399 | { |
---|
400 | if(m_rigid) m_rigid->applyTorqueImpulse(impulse); |
---|
401 | if(m_soft) btSoftBody::clusterDAImpulse(m_soft,impulse); |
---|
402 | } |
---|
403 | void applyAImpulse(const Impulse& impulse) const |
---|
404 | { |
---|
405 | if(impulse.m_asVelocity) applyVAImpulse(impulse.m_velocity); |
---|
406 | if(impulse.m_asDrift) applyDAImpulse(impulse.m_drift); |
---|
407 | } |
---|
408 | void applyDCImpulse(const btVector3& impulse) const |
---|
409 | { |
---|
410 | if(m_rigid) m_rigid->applyCentralImpulse(impulse); |
---|
411 | if(m_soft) btSoftBody::clusterDCImpulse(m_soft,impulse); |
---|
412 | } |
---|
413 | }; |
---|
414 | /* Joint */ |
---|
415 | struct Joint |
---|
416 | { |
---|
417 | struct eType { enum _ { |
---|
418 | Linear, |
---|
419 | Angular, |
---|
420 | Contact, |
---|
421 | };}; |
---|
422 | struct Specs |
---|
423 | { |
---|
424 | Specs() : erp(1),cfm(1),split(1) {} |
---|
425 | btScalar erp; |
---|
426 | btScalar cfm; |
---|
427 | btScalar split; |
---|
428 | }; |
---|
429 | Body m_bodies[2]; |
---|
430 | btVector3 m_refs[2]; |
---|
431 | btScalar m_cfm; |
---|
432 | btScalar m_erp; |
---|
433 | btScalar m_split; |
---|
434 | btVector3 m_drift; |
---|
435 | btVector3 m_sdrift; |
---|
436 | btMatrix3x3 m_massmatrix; |
---|
437 | bool m_delete; |
---|
438 | virtual ~Joint() {} |
---|
439 | Joint() : m_delete(false) {} |
---|
440 | virtual void Prepare(btScalar dt,int iterations); |
---|
441 | virtual void Solve(btScalar dt,btScalar sor)=0; |
---|
442 | virtual void Terminate(btScalar dt)=0; |
---|
443 | virtual eType::_ Type() const=0; |
---|
444 | }; |
---|
445 | /* LJoint */ |
---|
446 | struct LJoint : Joint |
---|
447 | { |
---|
448 | struct Specs : Joint::Specs |
---|
449 | { |
---|
450 | btVector3 position; |
---|
451 | }; |
---|
452 | btVector3 m_rpos[2]; |
---|
453 | void Prepare(btScalar dt,int iterations); |
---|
454 | void Solve(btScalar dt,btScalar sor); |
---|
455 | void Terminate(btScalar dt); |
---|
456 | eType::_ Type() const { return(eType::Linear); } |
---|
457 | }; |
---|
458 | /* AJoint */ |
---|
459 | struct AJoint : Joint |
---|
460 | { |
---|
461 | struct IControl |
---|
462 | { |
---|
463 | virtual void Prepare(AJoint*) {} |
---|
464 | virtual btScalar Speed(AJoint*,btScalar current) { return(current); } |
---|
465 | static IControl* Default() { static IControl def;return(&def); } |
---|
466 | }; |
---|
467 | struct Specs : Joint::Specs |
---|
468 | { |
---|
469 | Specs() : icontrol(IControl::Default()) {} |
---|
470 | btVector3 axis; |
---|
471 | IControl* icontrol; |
---|
472 | }; |
---|
473 | btVector3 m_axis[2]; |
---|
474 | IControl* m_icontrol; |
---|
475 | void Prepare(btScalar dt,int iterations); |
---|
476 | void Solve(btScalar dt,btScalar sor); |
---|
477 | void Terminate(btScalar dt); |
---|
478 | eType::_ Type() const { return(eType::Angular); } |
---|
479 | }; |
---|
480 | /* CJoint */ |
---|
481 | struct CJoint : Joint |
---|
482 | { |
---|
483 | int m_life; |
---|
484 | int m_maxlife; |
---|
485 | btVector3 m_rpos[2]; |
---|
486 | btVector3 m_normal; |
---|
487 | btScalar m_friction; |
---|
488 | void Prepare(btScalar dt,int iterations); |
---|
489 | void Solve(btScalar dt,btScalar sor); |
---|
490 | void Terminate(btScalar dt); |
---|
491 | eType::_ Type() const { return(eType::Contact); } |
---|
492 | }; |
---|
493 | /* Config */ |
---|
494 | struct Config |
---|
495 | { |
---|
496 | eAeroModel::_ aeromodel; // Aerodynamic model (default: V_Point) |
---|
497 | btScalar kVCF; // Velocities correction factor (Baumgarte) |
---|
498 | btScalar kDP; // Damping coefficient [0,1] |
---|
499 | btScalar kDG; // Drag coefficient [0,+inf] |
---|
500 | btScalar kLF; // Lift coefficient [0,+inf] |
---|
501 | btScalar kPR; // Pressure coefficient [-inf,+inf] |
---|
502 | btScalar kVC; // Volume conversation coefficient [0,+inf] |
---|
503 | btScalar kDF; // Dynamic friction coefficient [0,1] |
---|
504 | btScalar kMT; // Pose matching coefficient [0,1] |
---|
505 | btScalar kCHR; // Rigid contacts hardness [0,1] |
---|
506 | btScalar kKHR; // Kinetic contacts hardness [0,1] |
---|
507 | btScalar kSHR; // Soft contacts hardness [0,1] |
---|
508 | btScalar kAHR; // Anchors hardness [0,1] |
---|
509 | btScalar kSRHR_CL; // Soft vs rigid hardness [0,1] (cluster only) |
---|
510 | btScalar kSKHR_CL; // Soft vs kinetic hardness [0,1] (cluster only) |
---|
511 | btScalar kSSHR_CL; // Soft vs soft hardness [0,1] (cluster only) |
---|
512 | btScalar kSR_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only) |
---|
513 | btScalar kSK_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only) |
---|
514 | btScalar kSS_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only) |
---|
515 | btScalar maxvolume; // Maximum volume ratio for pose |
---|
516 | btScalar timescale; // Time scale |
---|
517 | int viterations; // Velocities solver iterations |
---|
518 | int piterations; // Positions solver iterations |
---|
519 | int diterations; // Drift solver iterations |
---|
520 | int citerations; // Cluster solver iterations |
---|
521 | int collisions; // Collisions flags |
---|
522 | tVSolverArray m_vsequence; // Velocity solvers sequence |
---|
523 | tPSolverArray m_psequence; // Position solvers sequence |
---|
524 | tPSolverArray m_dsequence; // Drift solvers sequence |
---|
525 | }; |
---|
526 | /* SolverState */ |
---|
527 | struct SolverState |
---|
528 | { |
---|
529 | btScalar sdt; // dt*timescale |
---|
530 | btScalar isdt; // 1/sdt |
---|
531 | btScalar velmrg; // velocity margin |
---|
532 | btScalar radmrg; // radial margin |
---|
533 | btScalar updmrg; // Update margin |
---|
534 | }; |
---|
535 | /* RayCaster */ |
---|
536 | struct RayCaster : btDbvt::ICollide |
---|
537 | { |
---|
538 | btVector3 o; |
---|
539 | btVector3 d; |
---|
540 | btScalar mint; |
---|
541 | Face* face; |
---|
542 | int tests; |
---|
543 | RayCaster(const btVector3& org,const btVector3& dir,btScalar mxt); |
---|
544 | void Process(const btDbvtNode* leaf); |
---|
545 | static inline btScalar rayTriangle(const btVector3& org, |
---|
546 | const btVector3& dir, |
---|
547 | const btVector3& a, |
---|
548 | const btVector3& b, |
---|
549 | const btVector3& c, |
---|
550 | btScalar maxt=SIMD_INFINITY); |
---|
551 | }; |
---|
552 | |
---|
553 | // |
---|
554 | // Typedef's |
---|
555 | // |
---|
556 | |
---|
557 | typedef void (*psolver_t)(btSoftBody*,btScalar,btScalar); |
---|
558 | typedef void (*vsolver_t)(btSoftBody*,btScalar); |
---|
559 | typedef btAlignedObjectArray<Cluster*> tClusterArray; |
---|
560 | typedef btAlignedObjectArray<Note> tNoteArray; |
---|
561 | typedef btAlignedObjectArray<Node> tNodeArray; |
---|
562 | typedef btAlignedObjectArray<btDbvtNode*> tLeafArray; |
---|
563 | typedef btAlignedObjectArray<Link> tLinkArray; |
---|
564 | typedef btAlignedObjectArray<Face> tFaceArray; |
---|
565 | typedef btAlignedObjectArray<Anchor> tAnchorArray; |
---|
566 | typedef btAlignedObjectArray<RContact> tRContactArray; |
---|
567 | typedef btAlignedObjectArray<SContact> tSContactArray; |
---|
568 | typedef btAlignedObjectArray<Material*> tMaterialArray; |
---|
569 | typedef btAlignedObjectArray<Joint*> tJointArray; |
---|
570 | typedef btAlignedObjectArray<btSoftBody*> tSoftBodyArray; |
---|
571 | |
---|
572 | // |
---|
573 | // Fields |
---|
574 | // |
---|
575 | |
---|
576 | Config m_cfg; // Configuration |
---|
577 | SolverState m_sst; // Solver state |
---|
578 | Pose m_pose; // Pose |
---|
579 | void* m_tag; // User data |
---|
580 | btSoftBodyWorldInfo* m_worldInfo; // World info |
---|
581 | tNoteArray m_notes; // Notes |
---|
582 | tNodeArray m_nodes; // Nodes |
---|
583 | tLinkArray m_links; // Links |
---|
584 | tFaceArray m_faces; // Faces |
---|
585 | tAnchorArray m_anchors; // Anchors |
---|
586 | tRContactArray m_rcontacts; // Rigid contacts |
---|
587 | tSContactArray m_scontacts; // Soft contacts |
---|
588 | tJointArray m_joints; // Joints |
---|
589 | tMaterialArray m_materials; // Materials |
---|
590 | btScalar m_timeacc; // Time accumulator |
---|
591 | btVector3 m_bounds[2]; // Spatial bounds |
---|
592 | bool m_bUpdateRtCst; // Update runtime constants |
---|
593 | btDbvt m_ndbvt; // Nodes tree |
---|
594 | btDbvt m_fdbvt; // Faces tree |
---|
595 | btDbvt m_cdbvt; // Clusters tree |
---|
596 | tClusterArray m_clusters; // Clusters |
---|
597 | |
---|
598 | // |
---|
599 | // Api |
---|
600 | // |
---|
601 | |
---|
602 | /* ctor */ |
---|
603 | btSoftBody( btSoftBodyWorldInfo* worldInfo,int node_count, |
---|
604 | const btVector3* x, |
---|
605 | const btScalar* m); |
---|
606 | /* dtor */ |
---|
607 | virtual ~btSoftBody(); |
---|
608 | /* Check for existing link */ |
---|
609 | |
---|
610 | btAlignedObjectArray<int> m_userIndexMapping; |
---|
611 | |
---|
612 | btSoftBodyWorldInfo* getWorldInfo() |
---|
613 | { |
---|
614 | return m_worldInfo; |
---|
615 | } |
---|
616 | |
---|
617 | virtual void setCollisionShape(btCollisionShape* collisionShape) |
---|
618 | { |
---|
619 | //don't do anything, due to the internal shape hack: todo: fix this |
---|
620 | } |
---|
621 | |
---|
622 | bool checkLink( int node0, |
---|
623 | int node1) const; |
---|
624 | bool checkLink( const Node* node0, |
---|
625 | const Node* node1) const; |
---|
626 | /* Check for existring face */ |
---|
627 | bool checkFace( int node0, |
---|
628 | int node1, |
---|
629 | int node2) const; |
---|
630 | /* Append material */ |
---|
631 | Material* appendMaterial(); |
---|
632 | /* Append note */ |
---|
633 | void appendNote( const char* text, |
---|
634 | const btVector3& o, |
---|
635 | const btVector4& c=btVector4(1,0,0,0), |
---|
636 | Node* n0=0, |
---|
637 | Node* n1=0, |
---|
638 | Node* n2=0, |
---|
639 | Node* n3=0); |
---|
640 | void appendNote( const char* text, |
---|
641 | const btVector3& o, |
---|
642 | Node* feature); |
---|
643 | void appendNote( const char* text, |
---|
644 | const btVector3& o, |
---|
645 | Link* feature); |
---|
646 | void appendNote( const char* text, |
---|
647 | const btVector3& o, |
---|
648 | Face* feature); |
---|
649 | /* Append node */ |
---|
650 | void appendNode( const btVector3& x,btScalar m); |
---|
651 | /* Append link */ |
---|
652 | void appendLink(int model=-1,Material* mat=0); |
---|
653 | void appendLink( int node0, |
---|
654 | int node1, |
---|
655 | Material* mat=0, |
---|
656 | bool bcheckexist=false); |
---|
657 | void appendLink( Node* node0, |
---|
658 | Node* node1, |
---|
659 | Material* mat=0, |
---|
660 | bool bcheckexist=false); |
---|
661 | /* Append face */ |
---|
662 | void appendFace(int model=-1,Material* mat=0); |
---|
663 | void appendFace( int node0, |
---|
664 | int node1, |
---|
665 | int node2, |
---|
666 | Material* mat=0); |
---|
667 | /* Append anchor */ |
---|
668 | void appendAnchor( int node, |
---|
669 | btRigidBody* body); |
---|
670 | /* Append linear joint */ |
---|
671 | void appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1); |
---|
672 | void appendLinearJoint(const LJoint::Specs& specs,Body body=Body()); |
---|
673 | void appendLinearJoint(const LJoint::Specs& specs,btSoftBody* body); |
---|
674 | /* Append linear joint */ |
---|
675 | void appendAngularJoint(const AJoint::Specs& specs,Cluster* body0,Body body1); |
---|
676 | void appendAngularJoint(const AJoint::Specs& specs,Body body=Body()); |
---|
677 | void appendAngularJoint(const AJoint::Specs& specs,btSoftBody* body); |
---|
678 | /* Add force (or gravity) to the entire body */ |
---|
679 | void addForce( const btVector3& force); |
---|
680 | /* Add force (or gravity) to a node of the body */ |
---|
681 | void addForce( const btVector3& force, |
---|
682 | int node); |
---|
683 | /* Add velocity to the entire body */ |
---|
684 | void addVelocity( const btVector3& velocity); |
---|
685 | |
---|
686 | /* Set velocity for the entire body */ |
---|
687 | void setVelocity( const btVector3& velocity); |
---|
688 | |
---|
689 | /* Add velocity to a node of the body */ |
---|
690 | void addVelocity( const btVector3& velocity, |
---|
691 | int node); |
---|
692 | /* Set mass */ |
---|
693 | void setMass( int node, |
---|
694 | btScalar mass); |
---|
695 | /* Get mass */ |
---|
696 | btScalar getMass( int node) const; |
---|
697 | /* Get total mass */ |
---|
698 | btScalar getTotalMass() const; |
---|
699 | /* Set total mass (weighted by previous masses) */ |
---|
700 | void setTotalMass( btScalar mass, |
---|
701 | bool fromfaces=false); |
---|
702 | /* Set total density */ |
---|
703 | void setTotalDensity(btScalar density); |
---|
704 | /* Transform */ |
---|
705 | void transform( const btTransform& trs); |
---|
706 | /* Translate */ |
---|
707 | void translate( const btVector3& trs); |
---|
708 | /* Rotate */ |
---|
709 | void rotate( const btQuaternion& rot); |
---|
710 | /* Scale */ |
---|
711 | void scale( const btVector3& scl); |
---|
712 | /* Set current state as pose */ |
---|
713 | void setPose( bool bvolume, |
---|
714 | bool bframe); |
---|
715 | /* Return the volume */ |
---|
716 | btScalar getVolume() const; |
---|
717 | /* Cluster count */ |
---|
718 | int clusterCount() const; |
---|
719 | /* Cluster center of mass */ |
---|
720 | static btVector3 clusterCom(const Cluster* cluster); |
---|
721 | btVector3 clusterCom(int cluster) const; |
---|
722 | /* Cluster velocity at rpos */ |
---|
723 | static btVector3 clusterVelocity(const Cluster* cluster,const btVector3& rpos); |
---|
724 | /* Cluster impulse */ |
---|
725 | static void clusterVImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse); |
---|
726 | static void clusterDImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse); |
---|
727 | static void clusterImpulse(Cluster* cluster,const btVector3& rpos,const Impulse& impulse); |
---|
728 | static void clusterVAImpulse(Cluster* cluster,const btVector3& impulse); |
---|
729 | static void clusterDAImpulse(Cluster* cluster,const btVector3& impulse); |
---|
730 | static void clusterAImpulse(Cluster* cluster,const Impulse& impulse); |
---|
731 | static void clusterDCImpulse(Cluster* cluster,const btVector3& impulse); |
---|
732 | /* Generate bending constraints based on distance in the adjency graph */ |
---|
733 | int generateBendingConstraints( int distance, |
---|
734 | Material* mat=0); |
---|
735 | /* Randomize constraints to reduce solver bias */ |
---|
736 | void randomizeConstraints(); |
---|
737 | /* Release clusters */ |
---|
738 | void releaseCluster(int index); |
---|
739 | void releaseClusters(); |
---|
740 | /* Generate clusters (K-mean) */ |
---|
741 | int generateClusters(int k,int maxiterations=8192); |
---|
742 | /* Refine */ |
---|
743 | void refine(ImplicitFn* ifn,btScalar accurary,bool cut); |
---|
744 | /* CutLink */ |
---|
745 | bool cutLink(int node0,int node1,btScalar position); |
---|
746 | bool cutLink(const Node* node0,const Node* node1,btScalar position); |
---|
747 | /* Ray casting */ |
---|
748 | bool rayCast(const btVector3& org, |
---|
749 | const btVector3& dir, |
---|
750 | sRayCast& results, |
---|
751 | btScalar maxtime=SIMD_INFINITY); |
---|
752 | /* Solver presets */ |
---|
753 | void setSolver(eSolverPresets::_ preset); |
---|
754 | /* predictMotion */ |
---|
755 | void predictMotion(btScalar dt); |
---|
756 | /* solveConstraints */ |
---|
757 | void solveConstraints(); |
---|
758 | /* staticSolve */ |
---|
759 | void staticSolve(int iterations); |
---|
760 | /* solveCommonConstraints */ |
---|
761 | static void solveCommonConstraints(btSoftBody** bodies,int count,int iterations); |
---|
762 | /* solveClusters */ |
---|
763 | static void solveClusters(const btAlignedObjectArray<btSoftBody*>& bodies); |
---|
764 | /* integrateMotion */ |
---|
765 | void integrateMotion(); |
---|
766 | /* defaultCollisionHandlers */ |
---|
767 | void defaultCollisionHandler(btCollisionObject* pco); |
---|
768 | void defaultCollisionHandler(btSoftBody* psb); |
---|
769 | |
---|
770 | // |
---|
771 | // Cast |
---|
772 | // |
---|
773 | |
---|
774 | static const btSoftBody* upcast(const btCollisionObject* colObj) |
---|
775 | { |
---|
776 | if (colObj->getInternalType()==CO_SOFT_BODY) |
---|
777 | return (const btSoftBody*)colObj; |
---|
778 | return 0; |
---|
779 | } |
---|
780 | static btSoftBody* upcast(btCollisionObject* colObj) |
---|
781 | { |
---|
782 | if (colObj->getInternalType()==CO_SOFT_BODY) |
---|
783 | return (btSoftBody*)colObj; |
---|
784 | return 0; |
---|
785 | } |
---|
786 | |
---|
787 | // |
---|
788 | // ::btCollisionObject |
---|
789 | // |
---|
790 | |
---|
791 | virtual void getAabb(btVector3& aabbMin,btVector3& aabbMax) const |
---|
792 | { |
---|
793 | aabbMin = m_bounds[0]; |
---|
794 | aabbMax = m_bounds[1]; |
---|
795 | } |
---|
796 | // |
---|
797 | // Private |
---|
798 | // |
---|
799 | void pointersToIndices(); |
---|
800 | void indicesToPointers(const int* map=0); |
---|
801 | int rayCast(const btVector3& org,const btVector3& dir, |
---|
802 | btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const; |
---|
803 | void initializeFaceTree(); |
---|
804 | btVector3 evaluateCom() const; |
---|
805 | bool checkContact(btRigidBody* prb,const btVector3& x,btScalar margin,btSoftBody::sCti& cti) const; |
---|
806 | void updateNormals(); |
---|
807 | void updateBounds(); |
---|
808 | void updatePose(); |
---|
809 | void updateConstants(); |
---|
810 | void initializeClusters(); |
---|
811 | void updateClusters(); |
---|
812 | void cleanupClusters(); |
---|
813 | void prepareClusters(int iterations); |
---|
814 | void solveClusters(btScalar sor); |
---|
815 | void applyClusters(bool drift); |
---|
816 | void dampClusters(); |
---|
817 | void applyForces(); |
---|
818 | static void PSolve_Anchors(btSoftBody* psb,btScalar kst,btScalar ti); |
---|
819 | static void PSolve_RContacts(btSoftBody* psb,btScalar kst,btScalar ti); |
---|
820 | static void PSolve_SContacts(btSoftBody* psb,btScalar,btScalar ti); |
---|
821 | static void PSolve_Links(btSoftBody* psb,btScalar kst,btScalar ti); |
---|
822 | static void VSolve_Links(btSoftBody* psb,btScalar kst); |
---|
823 | static psolver_t getSolver(ePSolver::_ solver); |
---|
824 | static vsolver_t getSolver(eVSolver::_ solver); |
---|
825 | |
---|
826 | }; |
---|
827 | |
---|
828 | |
---|
829 | |
---|
830 | #endif //_BT_SOFT_BODY_H |
---|