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