forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			1006 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1006 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
| Bullet Continuous Collision Detection and Physics Library
 | |
| Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
 | |
| 
 | |
| This software is provided 'as-is', without any express or implied warranty.
 | |
| In no event will the authors be held liable for any damages arising from the use of this software.
 | |
| Permission is granted to anyone to use this software for any purpose,
 | |
| including commercial applications, and to alter it and redistribute it freely,
 | |
| subject to the following restrictions:
 | |
| 
 | |
| 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.
 | |
| 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
 | |
| 3. This notice may not be removed or altered from any source distribution.
 | |
| */
 | |
| ///btSoftBody implementation by Nathanael Presson
 | |
| 
 | |
| #ifndef _BT_SOFT_BODY_H
 | |
| #define _BT_SOFT_BODY_H
 | |
| 
 | |
| #include "LinearMath/btAlignedObjectArray.h"
 | |
| #include "LinearMath/btTransform.h"
 | |
| #include "LinearMath/btIDebugDraw.h"
 | |
| #include "BulletDynamics/Dynamics/btRigidBody.h"
 | |
| 
 | |
| #include "BulletCollision/CollisionShapes/btConcaveShape.h"
 | |
| #include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
 | |
| #include "btSparseSDF.h"
 | |
| #include "BulletCollision/BroadphaseCollision/btDbvt.h"
 | |
| 
 | |
| //#ifdef BT_USE_DOUBLE_PRECISION
 | |
| //#define btRigidBodyData	btRigidBodyDoubleData
 | |
| //#define btRigidBodyDataName	"btRigidBodyDoubleData"
 | |
| //#else
 | |
| #define btSoftBodyData	btSoftBodyFloatData
 | |
| #define btSoftBodyDataName	"btSoftBodyFloatData"
 | |
| //#endif //BT_USE_DOUBLE_PRECISION
 | |
| 
 | |
| class btBroadphaseInterface;
 | |
| class btDispatcher;
 | |
| class btSoftBodySolver;
 | |
| 
 | |
| /* btSoftBodyWorldInfo	*/ 
 | |
| struct	btSoftBodyWorldInfo
 | |
| {
 | |
| 	btScalar				air_density;
 | |
| 	btScalar				water_density;
 | |
| 	btScalar				water_offset;
 | |
| 	btScalar				m_maxDisplacement;
 | |
| 	btVector3				water_normal;
 | |
| 	btBroadphaseInterface*	m_broadphase;
 | |
| 	btDispatcher*	m_dispatcher;
 | |
| 	btVector3				m_gravity;
 | |
| 	btSparseSdf<3>			m_sparsesdf;
 | |
| 
 | |
| 	btSoftBodyWorldInfo()
 | |
| 		:air_density((btScalar)1.2),
 | |
| 		water_density(0),
 | |
| 		water_offset(0),
 | |
| 		m_maxDisplacement(1000.f),//avoid soft body from 'exploding' so use some upper threshold of maximum motion that a node can travel per frame
 | |
| 		water_normal(0,0,0),
 | |
| 		m_broadphase(0),
 | |
| 		m_dispatcher(0),
 | |
| 		m_gravity(0,-10,0)
 | |
| 	{
 | |
| 	}
 | |
| };	
 | |
| 
 | |
| 
 | |
| ///The btSoftBody is an class to simulate cloth and volumetric soft bodies. 
 | |
| ///There is two-way interaction between btSoftBody and btRigidBody/btCollisionObject.
 | |
| class	btSoftBody : public btCollisionObject
 | |
| {
 | |
| public:
 | |
| 	btAlignedObjectArray<const class btCollisionObject*> m_collisionDisabledObjects;
 | |
| 
 | |
| 	// The solver object that handles this soft body
 | |
| 	btSoftBodySolver *m_softBodySolver;
 | |
| 
 | |
| 	//
 | |
| 	// Enumerations
 | |
| 	//
 | |
| 
 | |
| 	///eAeroModel 
 | |
| 	struct eAeroModel { enum _ {
 | |
| 		V_Point,			///Vertex normals are oriented toward velocity
 | |
| 		V_TwoSided,			///Vertex normals are flipped to match velocity	
 | |
| 		V_TwoSidedLiftDrag, ///Vertex normals are flipped to match velocity and lift and drag forces are applied
 | |
| 		V_OneSided,			///Vertex normals are taken as it is	
 | |
| 		F_TwoSided,			///Face normals are flipped to match velocity
 | |
| 		F_TwoSidedLiftDrag,	///Face normals are flipped to match velocity and lift and drag forces are applied 
 | |
| 		F_OneSided,			///Face normals are taken as it is		
 | |
| 		END
 | |
| 	};};
 | |
| 
 | |
| 	///eVSolver : velocities solvers
 | |
| 	struct	eVSolver { enum _ {
 | |
| 		Linear,		///Linear solver
 | |
| 		END
 | |
| 	};};
 | |
| 
 | |
| 	///ePSolver : positions solvers
 | |
| 	struct	ePSolver { enum _ {
 | |
| 		Linear,		///Linear solver
 | |
| 		Anchors,	///Anchor solver
 | |
| 		RContacts,	///Rigid contacts solver
 | |
| 		SContacts,	///Soft contacts solver
 | |
| 		END
 | |
| 	};};
 | |
| 
 | |
| 	///eSolverPresets
 | |
| 	struct	eSolverPresets { enum _ {
 | |
| 		Positions,
 | |
| 		Velocities,
 | |
| 		Default	=	Positions,
 | |
| 		END
 | |
| 	};};
 | |
| 
 | |
| 	///eFeature
 | |
| 	struct	eFeature { enum _ {
 | |
| 		None,
 | |
| 		Node,
 | |
| 		Link,
 | |
| 		Face,
 | |
| 		Tetra,
 | |
| 		END
 | |
| 	};};
 | |
| 
 | |
| 	typedef btAlignedObjectArray<eVSolver::_>	tVSolverArray;
 | |
| 	typedef btAlignedObjectArray<ePSolver::_>	tPSolverArray;
 | |
| 
 | |
| 	//
 | |
| 	// Flags
 | |
| 	//
 | |
| 
 | |
| 	///fCollision
 | |
| 	struct fCollision { enum _ {
 | |
| 		RVSmask	=	0x000f,	///Rigid versus soft mask
 | |
| 		SDF_RS	=	0x0001,	///SDF based rigid vs soft
 | |
| 		CL_RS	=	0x0002, ///Cluster vs convex rigid vs soft
 | |
| 
 | |
| 		SVSmask	=	0x0030,	///Rigid versus soft mask		
 | |
| 		VF_SS	=	0x0010,	///Vertex vs face soft vs soft handling
 | |
| 		CL_SS	=	0x0020, ///Cluster vs cluster soft vs soft handling
 | |
| 		CL_SELF =	0x0040, ///Cluster soft body self collision
 | |
| 		/* presets	*/ 
 | |
| 		Default	=	SDF_RS,
 | |
| 		END
 | |
| 	};};
 | |
| 
 | |
| 	///fMaterial
 | |
| 	struct fMaterial { enum _ {
 | |
| 		DebugDraw	=	0x0001,	/// Enable debug draw
 | |
| 		/* presets	*/ 
 | |
| 		Default		=	DebugDraw,
 | |
| 		END
 | |
| 	};};
 | |
| 
 | |
| 	//
 | |
| 	// API Types
 | |
| 	//
 | |
| 
 | |
| 	/* sRayCast		*/ 
 | |
| 	struct sRayCast
 | |
| 	{
 | |
| 		btSoftBody*	body;		/// soft body
 | |
| 		eFeature::_	feature;	/// feature type
 | |
| 		int			index;		/// feature index
 | |
| 		btScalar	fraction;		/// time of impact fraction (rayorg+(rayto-rayfrom)*fraction)
 | |
| 	};
 | |
| 
 | |
| 	/* ImplicitFn	*/ 
 | |
| 	struct	ImplicitFn
 | |
| 	{
 | |
| 		virtual ~ImplicitFn() {}
 | |
| 		virtual btScalar	Eval(const btVector3& x)=0;
 | |
| 	};
 | |
| 
 | |
| 	//
 | |
| 	// Internal types
 | |
| 	//
 | |
| 
 | |
| 	typedef btAlignedObjectArray<btScalar>	tScalarArray;
 | |
| 	typedef btAlignedObjectArray<btVector3>	tVector3Array;
 | |
| 
 | |
| 	/* sCti is Softbody contact info	*/ 
 | |
| 	struct	sCti
 | |
| 	{
 | |
| 		const btCollisionObject*	m_colObj;		/* Rigid body			*/ 
 | |
| 		btVector3		m_normal;	/* Outward normal		*/ 
 | |
| 		btScalar		m_offset;	/* Offset from origin	*/ 
 | |
| 	};	
 | |
| 
 | |
| 	/* sMedium		*/ 
 | |
| 	struct	sMedium
 | |
| 	{
 | |
| 		btVector3		m_velocity;	/* Velocity				*/ 
 | |
| 		btScalar		m_pressure;	/* Pressure				*/ 
 | |
| 		btScalar		m_density;	/* Density				*/ 
 | |
| 	};
 | |
| 
 | |
| 	/* Base type	*/ 
 | |
| 	struct	Element
 | |
| 	{
 | |
| 		void*			m_tag;			// User data
 | |
| 		Element() : m_tag(0) {}
 | |
| 	};
 | |
| 	/* Material		*/ 
 | |
| 	struct	Material : Element
 | |
| 	{
 | |
| 		btScalar				m_kLST;			// Linear stiffness coefficient [0,1]
 | |
| 		btScalar				m_kAST;			// Area/Angular stiffness coefficient [0,1]
 | |
| 		btScalar				m_kVST;			// Volume stiffness coefficient [0,1]
 | |
| 		int						m_flags;		// Flags
 | |
| 	};
 | |
| 
 | |
| 	/* Feature		*/ 
 | |
| 	struct	Feature : Element
 | |
| 	{
 | |
| 		Material*				m_material;		// Material
 | |
| 	};
 | |
| 	/* Node			*/ 
 | |
| 	struct	Node : Feature
 | |
| 	{
 | |
| 		btVector3				m_x;			// Position
 | |
| 		btVector3				m_q;			// Previous step position
 | |
| 		btVector3				m_v;			// Velocity
 | |
| 		btVector3				m_f;			// Force accumulator
 | |
| 		btVector3				m_n;			// Normal
 | |
| 		btScalar				m_im;			// 1/mass
 | |
| 		btScalar				m_area;			// Area
 | |
| 		btDbvtNode*				m_leaf;			// Leaf data
 | |
| 		int						m_battach:1;	// Attached
 | |
| 	};
 | |
| 	/* Link			*/ 
 | |
| 	ATTRIBUTE_ALIGNED16(struct)	Link : Feature
 | |
| 	{
 | |
| 		btVector3				m_c3;			// gradient
 | |
| 		Node*					m_n[2];			// Node pointers
 | |
| 		btScalar				m_rl;			// Rest length		
 | |
| 		int						m_bbending:1;	// Bending link
 | |
| 		btScalar				m_c0;			// (ima+imb)*kLST
 | |
| 		btScalar				m_c1;			// rl^2
 | |
| 		btScalar				m_c2;			// |gradient|^2/c0
 | |
| 	
 | |
| 		BT_DECLARE_ALIGNED_ALLOCATOR();
 | |
| 
 | |
| 	};
 | |
| 	/* Face			*/ 
 | |
| 	struct	Face : Feature
 | |
| 	{
 | |
| 		Node*					m_n[3];			// Node pointers
 | |
| 		btVector3				m_normal;		// Normal
 | |
| 		btScalar				m_ra;			// Rest area
 | |
| 		btDbvtNode*				m_leaf;			// Leaf data
 | |
| 	};
 | |
| 	/* Tetra		*/ 
 | |
| 	struct	Tetra : Feature
 | |
| 	{
 | |
| 		Node*					m_n[4];			// Node pointers		
 | |
| 		btScalar				m_rv;			// Rest volume
 | |
| 		btDbvtNode*				m_leaf;			// Leaf data
 | |
| 		btVector3				m_c0[4];		// gradients
 | |
| 		btScalar				m_c1;			// (4*kVST)/(im0+im1+im2+im3)
 | |
| 		btScalar				m_c2;			// m_c1/sum(|g0..3|^2)
 | |
| 	};
 | |
| 	/* RContact		*/ 
 | |
| 	struct	RContact
 | |
| 	{
 | |
| 		sCti		m_cti;			// Contact infos
 | |
| 		Node*					m_node;			// Owner node
 | |
| 		btMatrix3x3				m_c0;			// Impulse matrix
 | |
| 		btVector3				m_c1;			// Relative anchor
 | |
| 		btScalar				m_c2;			// ima*dt
 | |
| 		btScalar				m_c3;			// Friction
 | |
| 		btScalar				m_c4;			// Hardness
 | |
| 	};
 | |
| 	/* SContact		*/ 
 | |
| 	struct	SContact
 | |
| 	{
 | |
| 		Node*					m_node;			// Node
 | |
| 		Face*					m_face;			// Face
 | |
| 		btVector3				m_weights;		// Weigths
 | |
| 		btVector3				m_normal;		// Normal
 | |
| 		btScalar				m_margin;		// Margin
 | |
| 		btScalar				m_friction;		// Friction
 | |
| 		btScalar				m_cfm[2];		// Constraint force mixing
 | |
| 	};
 | |
| 	/* Anchor		*/ 
 | |
| 	struct	Anchor
 | |
| 	{
 | |
| 		Node*					m_node;			// Node pointer
 | |
| 		btVector3				m_local;		// Anchor position in body space
 | |
| 		btRigidBody*			m_body;			// Body
 | |
| 		btScalar				m_influence;
 | |
| 		btMatrix3x3				m_c0;			// Impulse matrix
 | |
| 		btVector3				m_c1;			// Relative anchor
 | |
| 		btScalar				m_c2;			// ima*dt
 | |
| 	};
 | |
| 	/* Note			*/ 
 | |
| 	struct	Note : Element
 | |
| 	{
 | |
| 		const char*				m_text;			// Text
 | |
| 		btVector3				m_offset;		// Offset
 | |
| 		int						m_rank;			// Rank
 | |
| 		Node*					m_nodes[4];		// Nodes
 | |
| 		btScalar				m_coords[4];	// Coordinates
 | |
| 	};	
 | |
| 	/* Pose			*/ 
 | |
| 	struct	Pose
 | |
| 	{
 | |
| 		bool					m_bvolume;		// Is valid
 | |
| 		bool					m_bframe;		// Is frame
 | |
| 		btScalar				m_volume;		// Rest volume
 | |
| 		tVector3Array			m_pos;			// Reference positions
 | |
| 		tScalarArray			m_wgh;			// Weights
 | |
| 		btVector3				m_com;			// COM
 | |
| 		btMatrix3x3				m_rot;			// Rotation
 | |
| 		btMatrix3x3				m_scl;			// Scale
 | |
| 		btMatrix3x3				m_aqq;			// Base scaling
 | |
| 	};
 | |
| 	/* Cluster		*/ 
 | |
| 	struct	Cluster
 | |
| 	{
 | |
| 		tScalarArray				m_masses;
 | |
| 		btAlignedObjectArray<Node*>	m_nodes;		
 | |
| 		tVector3Array				m_framerefs;
 | |
| 		btTransform					m_framexform;
 | |
| 		btScalar					m_idmass;
 | |
| 		btScalar					m_imass;
 | |
| 		btMatrix3x3					m_locii;
 | |
| 		btMatrix3x3					m_invwi;
 | |
| 		btVector3					m_com;
 | |
| 		btVector3					m_vimpulses[2];
 | |
| 		btVector3					m_dimpulses[2];
 | |
| 		int							m_nvimpulses;
 | |
| 		int							m_ndimpulses;
 | |
| 		btVector3					m_lv;
 | |
| 		btVector3					m_av;
 | |
| 		btDbvtNode*					m_leaf;
 | |
| 		btScalar					m_ndamping;	/* Node damping		*/ 
 | |
| 		btScalar					m_ldamping;	/* Linear damping	*/ 
 | |
| 		btScalar					m_adamping;	/* Angular damping	*/ 
 | |
| 		btScalar					m_matching;
 | |
| 		btScalar					m_maxSelfCollisionImpulse;
 | |
| 		btScalar					m_selfCollisionImpulseFactor;
 | |
| 		bool						m_containsAnchor;
 | |
| 		bool						m_collide;
 | |
| 		int							m_clusterIndex;
 | |
| 		Cluster() : m_leaf(0),m_ndamping(0),m_ldamping(0),m_adamping(0),m_matching(0) 
 | |
| 		,m_maxSelfCollisionImpulse(100.f),
 | |
| 		m_selfCollisionImpulseFactor(0.01f),
 | |
| 		m_containsAnchor(false)
 | |
| 		{}
 | |
| 	};
 | |
| 	/* Impulse		*/ 
 | |
| 	struct	Impulse
 | |
| 	{
 | |
| 		btVector3					m_velocity;
 | |
| 		btVector3					m_drift;
 | |
| 		int							m_asVelocity:1;
 | |
| 		int							m_asDrift:1;
 | |
| 		Impulse() : m_velocity(0,0,0),m_drift(0,0,0),m_asVelocity(0),m_asDrift(0)	{}
 | |
| 		Impulse						operator -() const
 | |
| 		{
 | |
| 			Impulse i=*this;
 | |
| 			i.m_velocity=-i.m_velocity;
 | |
| 			i.m_drift=-i.m_drift;
 | |
| 			return(i);
 | |
| 		}
 | |
| 		Impulse						operator*(btScalar x) const
 | |
| 		{
 | |
| 			Impulse i=*this;
 | |
| 			i.m_velocity*=x;
 | |
| 			i.m_drift*=x;
 | |
| 			return(i);
 | |
| 		}
 | |
| 	};
 | |
| 	/* Body			*/ 
 | |
| 	struct	Body
 | |
| 	{
 | |
| 		Cluster*			m_soft;
 | |
| 		btRigidBody*		m_rigid;
 | |
| 		const btCollisionObject*	m_collisionObject;
 | |
| 
 | |
| 		Body() : m_soft(0),m_rigid(0),m_collisionObject(0)				{}
 | |
| 		Body(Cluster* p) : m_soft(p),m_rigid(0),m_collisionObject(0)	{}
 | |
| 		Body(const btCollisionObject* colObj) : m_soft(0),m_collisionObject(colObj)
 | |
| 		{
 | |
| 			m_rigid = (btRigidBody*)btRigidBody::upcast(m_collisionObject);
 | |
| 		}
 | |
| 
 | |
| 		void						activate() const
 | |
| 		{
 | |
| 			if(m_rigid) 
 | |
| 				m_rigid->activate();
 | |
| 			if (m_collisionObject)
 | |
| 				m_collisionObject->activate();
 | |
| 
 | |
| 		}
 | |
| 		const btMatrix3x3&			invWorldInertia() const
 | |
| 		{
 | |
| 			static const btMatrix3x3	iwi(0,0,0,0,0,0,0,0,0);
 | |
| 			if(m_rigid) return(m_rigid->getInvInertiaTensorWorld());
 | |
| 			if(m_soft)	return(m_soft->m_invwi);
 | |
| 			return(iwi);
 | |
| 		}
 | |
| 		btScalar					invMass() const
 | |
| 		{
 | |
| 			if(m_rigid) return(m_rigid->getInvMass());
 | |
| 			if(m_soft)	return(m_soft->m_imass);
 | |
| 			return(0);
 | |
| 		}
 | |
| 		const btTransform&			xform() const
 | |
| 		{
 | |
| 			static const btTransform	identity=btTransform::getIdentity();		
 | |
| 			if(m_collisionObject) return(m_collisionObject->getWorldTransform());
 | |
| 			if(m_soft)	return(m_soft->m_framexform);
 | |
| 			return(identity);
 | |
| 		}
 | |
| 		btVector3					linearVelocity() const
 | |
| 		{
 | |
| 			if(m_rigid) return(m_rigid->getLinearVelocity());
 | |
| 			if(m_soft)	return(m_soft->m_lv);
 | |
| 			return(btVector3(0,0,0));
 | |
| 		}
 | |
| 		btVector3					angularVelocity(const btVector3& rpos) const
 | |
| 		{			
 | |
| 			if(m_rigid) return(btCross(m_rigid->getAngularVelocity(),rpos));
 | |
| 			if(m_soft)	return(btCross(m_soft->m_av,rpos));
 | |
| 			return(btVector3(0,0,0));
 | |
| 		}
 | |
| 		btVector3					angularVelocity() const
 | |
| 		{			
 | |
| 			if(m_rigid) return(m_rigid->getAngularVelocity());
 | |
| 			if(m_soft)	return(m_soft->m_av);
 | |
| 			return(btVector3(0,0,0));
 | |
| 		}
 | |
| 		btVector3					velocity(const btVector3& rpos) const
 | |
| 		{
 | |
| 			return(linearVelocity()+angularVelocity(rpos));
 | |
| 		}
 | |
| 		void						applyVImpulse(const btVector3& impulse,const btVector3& rpos) const
 | |
| 		{
 | |
| 			if(m_rigid)	m_rigid->applyImpulse(impulse,rpos);
 | |
| 			if(m_soft)	btSoftBody::clusterVImpulse(m_soft,rpos,impulse);
 | |
| 		}
 | |
| 		void						applyDImpulse(const btVector3& impulse,const btVector3& rpos) const
 | |
| 		{
 | |
| 			if(m_rigid)	m_rigid->applyImpulse(impulse,rpos);
 | |
| 			if(m_soft)	btSoftBody::clusterDImpulse(m_soft,rpos,impulse);
 | |
| 		}		
 | |
| 		void						applyImpulse(const Impulse& impulse,const btVector3& rpos) const
 | |
| 		{
 | |
| 			if(impulse.m_asVelocity)	
 | |
| 			{
 | |
| //				printf("impulse.m_velocity = %f,%f,%f\n",impulse.m_velocity.getX(),impulse.m_velocity.getY(),impulse.m_velocity.getZ());
 | |
| 				applyVImpulse(impulse.m_velocity,rpos);
 | |
| 			}
 | |
| 			if(impulse.m_asDrift)		
 | |
| 			{
 | |
| //				printf("impulse.m_drift = %f,%f,%f\n",impulse.m_drift.getX(),impulse.m_drift.getY(),impulse.m_drift.getZ());
 | |
| 				applyDImpulse(impulse.m_drift,rpos);
 | |
| 			}
 | |
| 		}
 | |
| 		void						applyVAImpulse(const btVector3& impulse) const
 | |
| 		{
 | |
| 			if(m_rigid)	m_rigid->applyTorqueImpulse(impulse);
 | |
| 			if(m_soft)	btSoftBody::clusterVAImpulse(m_soft,impulse);
 | |
| 		}
 | |
| 		void						applyDAImpulse(const btVector3& impulse) const
 | |
| 		{
 | |
| 			if(m_rigid)	m_rigid->applyTorqueImpulse(impulse);
 | |
| 			if(m_soft)	btSoftBody::clusterDAImpulse(m_soft,impulse);
 | |
| 		}
 | |
| 		void						applyAImpulse(const Impulse& impulse) const
 | |
| 		{
 | |
| 			if(impulse.m_asVelocity)	applyVAImpulse(impulse.m_velocity);
 | |
| 			if(impulse.m_asDrift)		applyDAImpulse(impulse.m_drift);
 | |
| 		}
 | |
| 		void						applyDCImpulse(const btVector3& impulse) const
 | |
| 		{
 | |
| 			if(m_rigid)	m_rigid->applyCentralImpulse(impulse);
 | |
| 			if(m_soft)	btSoftBody::clusterDCImpulse(m_soft,impulse);
 | |
| 		}
 | |
| 	};
 | |
| 	/* Joint		*/ 
 | |
| 	struct	Joint
 | |
| 	{
 | |
| 		struct eType { enum _ {
 | |
| 			Linear=0,
 | |
| 			Angular,
 | |
| 			Contact
 | |
| 		};};
 | |
| 		struct Specs
 | |
| 		{
 | |
| 			Specs() : erp(1),cfm(1),split(1) {}
 | |
| 			btScalar	erp;
 | |
| 			btScalar	cfm;
 | |
| 			btScalar	split;
 | |
| 		};
 | |
| 		Body						m_bodies[2];
 | |
| 		btVector3					m_refs[2];
 | |
| 		btScalar					m_cfm;
 | |
| 		btScalar					m_erp;
 | |
| 		btScalar					m_split;
 | |
| 		btVector3					m_drift;
 | |
| 		btVector3					m_sdrift;
 | |
| 		btMatrix3x3					m_massmatrix;
 | |
| 		bool						m_delete;
 | |
| 		virtual						~Joint() {}
 | |
| 		Joint() : m_delete(false) {}
 | |
| 		virtual void				Prepare(btScalar dt,int iterations);
 | |
| 		virtual void				Solve(btScalar dt,btScalar sor)=0;
 | |
| 		virtual void				Terminate(btScalar dt)=0;
 | |
| 		virtual eType::_			Type() const=0;
 | |
| 	};
 | |
| 	/* LJoint		*/ 
 | |
| 	struct	LJoint : Joint
 | |
| 	{
 | |
| 		struct Specs : Joint::Specs
 | |
| 		{
 | |
| 			btVector3	position;
 | |
| 		};		
 | |
| 		btVector3					m_rpos[2];
 | |
| 		void						Prepare(btScalar dt,int iterations);
 | |
| 		void						Solve(btScalar dt,btScalar sor);
 | |
| 		void						Terminate(btScalar dt);
 | |
| 		eType::_					Type() const { return(eType::Linear); }
 | |
| 	};
 | |
| 	/* AJoint		*/ 
 | |
| 	struct	AJoint : Joint
 | |
| 	{
 | |
| 		struct IControl
 | |
| 		{
 | |
| 			virtual ~IControl() {}
 | |
| 			virtual void			Prepare(AJoint*)				{}
 | |
| 			virtual btScalar		Speed(AJoint*,btScalar current) { return(current); }
 | |
| 			static IControl*		Default()						{ static IControl def;return(&def); }
 | |
| 		};
 | |
| 		struct Specs : Joint::Specs
 | |
| 		{
 | |
| 			Specs() : icontrol(IControl::Default()) {}
 | |
| 			btVector3	axis;
 | |
| 			IControl*	icontrol;
 | |
| 		};		
 | |
| 		btVector3					m_axis[2];
 | |
| 		IControl*					m_icontrol;
 | |
| 		void						Prepare(btScalar dt,int iterations);
 | |
| 		void						Solve(btScalar dt,btScalar sor);
 | |
| 		void						Terminate(btScalar dt);
 | |
| 		eType::_					Type() const { return(eType::Angular); }
 | |
| 	};
 | |
| 	/* CJoint		*/ 
 | |
| 	struct	CJoint : Joint
 | |
| 	{		
 | |
| 		int							m_life;
 | |
| 		int							m_maxlife;
 | |
| 		btVector3					m_rpos[2];
 | |
| 		btVector3					m_normal;
 | |
| 		btScalar					m_friction;
 | |
| 		void						Prepare(btScalar dt,int iterations);
 | |
| 		void						Solve(btScalar dt,btScalar sor);
 | |
| 		void						Terminate(btScalar dt);
 | |
| 		eType::_					Type() const { return(eType::Contact); }
 | |
| 	};
 | |
| 	/* Config		*/ 
 | |
| 	struct	Config
 | |
| 	{
 | |
| 		eAeroModel::_			aeromodel;		// Aerodynamic model (default: V_Point)
 | |
| 		btScalar				kVCF;			// Velocities correction factor (Baumgarte)
 | |
| 		btScalar				kDP;			// Damping coefficient [0,1]
 | |
| 		btScalar				kDG;			// Drag coefficient [0,+inf]
 | |
| 		btScalar				kLF;			// Lift coefficient [0,+inf]
 | |
| 		btScalar				kPR;			// Pressure coefficient [-inf,+inf]
 | |
| 		btScalar				kVC;			// Volume conversation coefficient [0,+inf]
 | |
| 		btScalar				kDF;			// Dynamic friction coefficient [0,1]
 | |
| 		btScalar				kMT;			// Pose matching coefficient [0,1]		
 | |
| 		btScalar				kCHR;			// Rigid contacts hardness [0,1]
 | |
| 		btScalar				kKHR;			// Kinetic contacts hardness [0,1]
 | |
| 		btScalar				kSHR;			// Soft contacts hardness [0,1]
 | |
| 		btScalar				kAHR;			// Anchors hardness [0,1]
 | |
| 		btScalar				kSRHR_CL;		// Soft vs rigid hardness [0,1] (cluster only)
 | |
| 		btScalar				kSKHR_CL;		// Soft vs kinetic hardness [0,1] (cluster only)
 | |
| 		btScalar				kSSHR_CL;		// Soft vs soft hardness [0,1] (cluster only)
 | |
| 		btScalar				kSR_SPLT_CL;	// Soft vs rigid impulse split [0,1] (cluster only)
 | |
| 		btScalar				kSK_SPLT_CL;	// Soft vs rigid impulse split [0,1] (cluster only)
 | |
| 		btScalar				kSS_SPLT_CL;	// Soft vs rigid impulse split [0,1] (cluster only)
 | |
| 		btScalar				maxvolume;		// Maximum volume ratio for pose
 | |
| 		btScalar				timescale;		// Time scale
 | |
| 		int						viterations;	// Velocities solver iterations
 | |
| 		int						piterations;	// Positions solver iterations
 | |
| 		int						diterations;	// Drift solver iterations
 | |
| 		int						citerations;	// Cluster solver iterations
 | |
| 		int						collisions;		// Collisions flags
 | |
| 		tVSolverArray			m_vsequence;	// Velocity solvers sequence
 | |
| 		tPSolverArray			m_psequence;	// Position solvers sequence
 | |
| 		tPSolverArray			m_dsequence;	// Drift solvers sequence
 | |
| 	};
 | |
| 	/* SolverState	*/ 
 | |
| 	struct	SolverState
 | |
| 	{
 | |
| 		btScalar				sdt;			// dt*timescale
 | |
| 		btScalar				isdt;			// 1/sdt
 | |
| 		btScalar				velmrg;			// velocity margin
 | |
| 		btScalar				radmrg;			// radial margin
 | |
| 		btScalar				updmrg;			// Update margin
 | |
| 	};	
 | |
| 	/// RayFromToCaster takes a ray from, ray to (instead of direction!)
 | |
| 	struct	RayFromToCaster : btDbvt::ICollide
 | |
| 	{
 | |
| 		btVector3			m_rayFrom;
 | |
| 		btVector3			m_rayTo;
 | |
| 		btVector3			m_rayNormalizedDirection;
 | |
| 		btScalar			m_mint;
 | |
| 		Face*				m_face;
 | |
| 		int					m_tests;
 | |
| 		RayFromToCaster(const btVector3& rayFrom,const btVector3& rayTo,btScalar mxt);
 | |
| 		void					Process(const btDbvtNode* leaf);
 | |
| 
 | |
| 		static /*inline*/ btScalar	rayFromToTriangle(const btVector3& rayFrom,
 | |
| 			const btVector3& rayTo,
 | |
| 			const btVector3& rayNormalizedDirection,
 | |
| 			const btVector3& a,
 | |
| 			const btVector3& b,
 | |
| 			const btVector3& c,
 | |
| 			btScalar maxt=SIMD_INFINITY);
 | |
| 	};
 | |
| 
 | |
| 	//
 | |
| 	// Typedefs
 | |
| 	//
 | |
| 
 | |
| 	typedef void								(*psolver_t)(btSoftBody*,btScalar,btScalar);
 | |
| 	typedef void								(*vsolver_t)(btSoftBody*,btScalar);
 | |
| 	typedef btAlignedObjectArray<Cluster*>		tClusterArray;
 | |
| 	typedef btAlignedObjectArray<Note>			tNoteArray;
 | |
| 	typedef btAlignedObjectArray<Node>			tNodeArray;
 | |
| 	typedef btAlignedObjectArray<btDbvtNode*>	tLeafArray;
 | |
| 	typedef btAlignedObjectArray<Link>			tLinkArray;
 | |
| 	typedef btAlignedObjectArray<Face>			tFaceArray;
 | |
| 	typedef btAlignedObjectArray<Tetra>			tTetraArray;
 | |
| 	typedef btAlignedObjectArray<Anchor>		tAnchorArray;
 | |
| 	typedef btAlignedObjectArray<RContact>		tRContactArray;
 | |
| 	typedef btAlignedObjectArray<SContact>		tSContactArray;
 | |
| 	typedef btAlignedObjectArray<Material*>		tMaterialArray;
 | |
| 	typedef btAlignedObjectArray<Joint*>		tJointArray;
 | |
| 	typedef btAlignedObjectArray<btSoftBody*>	tSoftBodyArray;	
 | |
| 
 | |
| 	//
 | |
| 	// Fields
 | |
| 	//
 | |
| 
 | |
| 	Config					m_cfg;			// Configuration
 | |
| 	SolverState				m_sst;			// Solver state
 | |
| 	Pose					m_pose;			// Pose
 | |
| 	void*					m_tag;			// User data
 | |
| 	btSoftBodyWorldInfo*	m_worldInfo;	// World info
 | |
| 	tNoteArray				m_notes;		// Notes
 | |
| 	tNodeArray				m_nodes;		// Nodes
 | |
| 	tLinkArray				m_links;		// Links
 | |
| 	tFaceArray				m_faces;		// Faces
 | |
| 	tTetraArray				m_tetras;		// Tetras
 | |
| 	tAnchorArray			m_anchors;		// Anchors
 | |
| 	tRContactArray			m_rcontacts;	// Rigid contacts
 | |
| 	tSContactArray			m_scontacts;	// Soft contacts
 | |
| 	tJointArray				m_joints;		// Joints
 | |
| 	tMaterialArray			m_materials;	// Materials
 | |
| 	btScalar				m_timeacc;		// Time accumulator
 | |
| 	btVector3				m_bounds[2];	// Spatial bounds	
 | |
| 	bool					m_bUpdateRtCst;	// Update runtime constants
 | |
| 	btDbvt					m_ndbvt;		// Nodes tree
 | |
| 	btDbvt					m_fdbvt;		// Faces tree
 | |
| 	btDbvt					m_cdbvt;		// Clusters tree
 | |
| 	tClusterArray			m_clusters;		// Clusters
 | |
| 
 | |
| 	btAlignedObjectArray<bool>m_clusterConnectivity;//cluster connectivity, for self-collision
 | |
| 
 | |
| 	btTransform			m_initialWorldTransform;
 | |
| 
 | |
| 	btVector3			m_windVelocity;
 | |
| 	
 | |
| 	btScalar        m_restLengthScale;
 | |
| 	
 | |
| 	//
 | |
| 	// Api
 | |
| 	//
 | |
| 
 | |
| 	/* ctor																	*/ 
 | |
| 	btSoftBody(	btSoftBodyWorldInfo* worldInfo,int node_count,		const btVector3* x,		const btScalar* m);
 | |
| 
 | |
| 	/* ctor																	*/ 
 | |
| 	btSoftBody(	btSoftBodyWorldInfo* worldInfo);
 | |
| 
 | |
| 	void	initDefaults();
 | |
| 
 | |
| 	/* dtor																	*/ 
 | |
| 	virtual ~btSoftBody();
 | |
| 	/* Check for existing link												*/ 
 | |
| 
 | |
| 	btAlignedObjectArray<int>	m_userIndexMapping;
 | |
| 
 | |
| 	btSoftBodyWorldInfo*	getWorldInfo()
 | |
| 	{
 | |
| 		return m_worldInfo;
 | |
| 	}
 | |
| 
 | |
| 	///@todo: avoid internal softbody shape hack and move collision code to collision library
 | |
| 	virtual void	setCollisionShape(btCollisionShape* collisionShape)
 | |
| 	{
 | |
| 		
 | |
| 	}
 | |
| 
 | |
| 	bool				checkLink(	int node0,
 | |
| 		int node1) const;
 | |
| 	bool				checkLink(	const Node* node0,
 | |
| 		const Node* node1) const;
 | |
| 	/* Check for existring face												*/ 
 | |
| 	bool				checkFace(	int node0,
 | |
| 		int node1,
 | |
| 		int node2) const;
 | |
| 	/* Append material														*/ 
 | |
| 	Material*			appendMaterial();
 | |
| 	/* Append note															*/ 
 | |
| 	void				appendNote(	const char* text,
 | |
| 		const btVector3& o,
 | |
| 		const btVector4& c=btVector4(1,0,0,0),
 | |
| 		Node* n0=0,
 | |
| 		Node* n1=0,
 | |
| 		Node* n2=0,
 | |
| 		Node* n3=0);
 | |
| 	void				appendNote(	const char* text,
 | |
| 		const btVector3& o,
 | |
| 		Node* feature);
 | |
| 	void				appendNote(	const char* text,
 | |
| 		const btVector3& o,
 | |
| 		Link* feature);
 | |
| 	void				appendNote(	const char* text,
 | |
| 		const btVector3& o,
 | |
| 		Face* feature);
 | |
| 	/* Append node															*/ 
 | |
| 	void				appendNode(	const btVector3& x,btScalar m);
 | |
| 	/* Append link															*/ 
 | |
| 	void				appendLink(int model=-1,Material* mat=0);
 | |
| 	void				appendLink(	int node0,
 | |
| 		int node1,
 | |
| 		Material* mat=0,
 | |
| 		bool bcheckexist=false);
 | |
| 	void				appendLink(	Node* node0,
 | |
| 		Node* node1,
 | |
| 		Material* mat=0,
 | |
| 		bool bcheckexist=false);
 | |
| 	/* Append face															*/ 
 | |
| 	void				appendFace(int model=-1,Material* mat=0);
 | |
| 	void				appendFace(	int node0,
 | |
| 		int node1,
 | |
| 		int node2,
 | |
| 		Material* mat=0);
 | |
| 	void			appendTetra(int model,Material* mat);
 | |
| 	//
 | |
| 	void			appendTetra(int node0,
 | |
| 										int node1,
 | |
| 										int node2,
 | |
| 										int node3,
 | |
| 										Material* mat=0);
 | |
| 
 | |
| 
 | |
| 	/* Append anchor														*/ 
 | |
| 	void				appendAnchor(	int node,
 | |
| 		btRigidBody* body, bool disableCollisionBetweenLinkedBodies=false,btScalar influence = 1);
 | |
| 	void			appendAnchor(int node,btRigidBody* body, const btVector3& localPivot,bool disableCollisionBetweenLinkedBodies=false,btScalar influence = 1);
 | |
| 	/* Append linear joint													*/ 
 | |
| 	void				appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1);
 | |
| 	void				appendLinearJoint(const LJoint::Specs& specs,Body body=Body());
 | |
| 	void				appendLinearJoint(const LJoint::Specs& specs,btSoftBody* body);
 | |
| 	/* Append linear joint													*/ 
 | |
| 	void				appendAngularJoint(const AJoint::Specs& specs,Cluster* body0,Body body1);
 | |
| 	void				appendAngularJoint(const AJoint::Specs& specs,Body body=Body());
 | |
| 	void				appendAngularJoint(const AJoint::Specs& specs,btSoftBody* body);
 | |
| 	/* Add force (or gravity) to the entire body							*/ 
 | |
| 	void				addForce(		const btVector3& force);
 | |
| 	/* Add force (or gravity) to a node of the body							*/ 
 | |
| 	void				addForce(		const btVector3& force,
 | |
| 		int node);
 | |
| 	/* Add aero force to a node of the body */
 | |
| 	void			    addAeroForceToNode(const btVector3& windVelocity,int nodeIndex);
 | |
| 
 | |
| 	/* Add aero force to a face of the body */
 | |
| 	void			    addAeroForceToFace(const btVector3& windVelocity,int faceIndex);
 | |
| 
 | |
| 	/* Add velocity to the entire body										*/ 
 | |
| 	void				addVelocity(	const btVector3& velocity);
 | |
| 
 | |
| 	/* Set velocity for the entire body										*/ 
 | |
| 	void				setVelocity(	const btVector3& velocity);
 | |
| 
 | |
| 	/* Add velocity to a node of the body									*/ 
 | |
| 	void				addVelocity(	const btVector3& velocity,
 | |
| 		int node);
 | |
| 	/* Set mass																*/ 
 | |
| 	void				setMass(		int node,
 | |
| 		btScalar mass);
 | |
| 	/* Get mass																*/ 
 | |
| 	btScalar			getMass(		int node) const;
 | |
| 	/* Get total mass														*/ 
 | |
| 	btScalar			getTotalMass() const;
 | |
| 	/* Set total mass (weighted by previous masses)							*/ 
 | |
| 	void				setTotalMass(	btScalar mass,
 | |
| 		bool fromfaces=false);
 | |
| 	/* Set total density													*/ 
 | |
| 	void				setTotalDensity(btScalar density);
 | |
| 	/* Set volume mass (using tetrahedrons)									*/
 | |
| 	void				setVolumeMass(		btScalar mass);
 | |
| 	/* Set volume density (using tetrahedrons)								*/
 | |
| 	void				setVolumeDensity(	btScalar density);
 | |
| 	/* Transform															*/ 
 | |
| 	void				transform(		const btTransform& trs);
 | |
| 	/* Translate															*/ 
 | |
| 	void				translate(		const btVector3& trs);
 | |
| 	/* Rotate															*/ 
 | |
| 	void				rotate(	const btQuaternion& rot);
 | |
| 	/* Scale																*/ 
 | |
| 	void				scale(	const btVector3& scl);
 | |
| 	/* Get link resting lengths scale										*/
 | |
| 	btScalar			getRestLengthScale();
 | |
| 	/* Scale resting length of all springs									*/
 | |
| 	void				setRestLengthScale(btScalar restLength);
 | |
| 	/* Set current state as pose											*/ 
 | |
| 	void				setPose(		bool bvolume,
 | |
| 		bool bframe);
 | |
| 	/* Set current link lengths as resting lengths							*/ 
 | |
| 	void				resetLinkRestLengths();
 | |
| 	/* Return the volume													*/ 
 | |
| 	btScalar			getVolume() const;
 | |
| 	/* Cluster count														*/ 
 | |
| 	int					clusterCount() const;
 | |
| 	/* Cluster center of mass												*/ 
 | |
| 	static btVector3	clusterCom(const Cluster* cluster);
 | |
| 	btVector3			clusterCom(int cluster) const;
 | |
| 	/* Cluster velocity at rpos												*/ 
 | |
| 	static btVector3	clusterVelocity(const Cluster* cluster,const btVector3& rpos);
 | |
| 	/* Cluster impulse														*/ 
 | |
| 	static void			clusterVImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse);
 | |
| 	static void			clusterDImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse);
 | |
| 	static void			clusterImpulse(Cluster* cluster,const btVector3& rpos,const Impulse& impulse);
 | |
| 	static void			clusterVAImpulse(Cluster* cluster,const btVector3& impulse);
 | |
| 	static void			clusterDAImpulse(Cluster* cluster,const btVector3& impulse);
 | |
| 	static void			clusterAImpulse(Cluster* cluster,const Impulse& impulse);
 | |
| 	static void			clusterDCImpulse(Cluster* cluster,const btVector3& impulse);
 | |
| 	/* Generate bending constraints based on distance in the adjency graph	*/ 
 | |
| 	int					generateBendingConstraints(	int distance,
 | |
| 		Material* mat=0);
 | |
| 	/* Randomize constraints to reduce solver bias							*/ 
 | |
| 	void				randomizeConstraints();
 | |
| 	/* Release clusters														*/ 
 | |
| 	void				releaseCluster(int index);
 | |
| 	void				releaseClusters();
 | |
| 	/* Generate clusters (K-mean)											*/ 
 | |
| 	///generateClusters with k=0 will create a convex cluster for each tetrahedron or triangle
 | |
| 	///otherwise an approximation will be used (better performance)
 | |
| 	int					generateClusters(int k,int maxiterations=8192);
 | |
| 	/* Refine																*/ 
 | |
| 	void				refine(ImplicitFn* ifn,btScalar accurary,bool cut);
 | |
| 	/* CutLink																*/ 
 | |
| 	bool				cutLink(int node0,int node1,btScalar position);
 | |
| 	bool				cutLink(const Node* node0,const Node* node1,btScalar position);
 | |
| 
 | |
| 	///Ray casting using rayFrom and rayTo in worldspace, (not direction!)
 | |
| 	bool				rayTest(const btVector3& rayFrom,
 | |
| 		const btVector3& rayTo,
 | |
| 		sRayCast& results);
 | |
| 	/* Solver presets														*/ 
 | |
| 	void				setSolver(eSolverPresets::_ preset);
 | |
| 	/* predictMotion														*/ 
 | |
| 	void				predictMotion(btScalar dt);
 | |
| 	/* solveConstraints														*/ 
 | |
| 	void				solveConstraints();
 | |
| 	/* staticSolve															*/ 
 | |
| 	void				staticSolve(int iterations);
 | |
| 	/* solveCommonConstraints												*/ 
 | |
| 	static void			solveCommonConstraints(btSoftBody** bodies,int count,int iterations);
 | |
| 	/* solveClusters														*/ 
 | |
| 	static void			solveClusters(const btAlignedObjectArray<btSoftBody*>& bodies);
 | |
| 	/* integrateMotion														*/ 
 | |
| 	void				integrateMotion();
 | |
| 	/* defaultCollisionHandlers												*/ 
 | |
| 	void				defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap);
 | |
| 	void				defaultCollisionHandler(btSoftBody* psb);
 | |
| 
 | |
| 
 | |
| 
 | |
| 	//
 | |
| 	// Functionality to deal with new accelerated solvers.
 | |
| 	//
 | |
| 
 | |
| 	/**
 | |
| 	 * Set a wind velocity for interaction with the air.
 | |
| 	 */
 | |
| 	void setWindVelocity( const btVector3 &velocity );
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * Return the wind velocity for interaction with the air.
 | |
| 	 */
 | |
| 	const btVector3& getWindVelocity();
 | |
| 
 | |
| 	//
 | |
| 	// Set the solver that handles this soft body
 | |
| 	// Should not be allowed to get out of sync with reality
 | |
| 	// Currently called internally on addition to the world
 | |
| 	void setSoftBodySolver( btSoftBodySolver *softBodySolver )
 | |
| 	{
 | |
| 		m_softBodySolver = softBodySolver;
 | |
| 	}
 | |
| 
 | |
| 	//
 | |
| 	// Return the solver that handles this soft body
 | |
| 	// 
 | |
| 	btSoftBodySolver *getSoftBodySolver()
 | |
| 	{
 | |
| 		return m_softBodySolver;
 | |
| 	}
 | |
| 
 | |
| 	//
 | |
| 	// Return the solver that handles this soft body
 | |
| 	// 
 | |
| 	btSoftBodySolver *getSoftBodySolver() const
 | |
| 	{
 | |
| 		return m_softBodySolver;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	//
 | |
| 	// Cast
 | |
| 	//
 | |
| 
 | |
| 	static const btSoftBody*	upcast(const btCollisionObject* colObj)
 | |
| 	{
 | |
| 		if (colObj->getInternalType()==CO_SOFT_BODY)
 | |
| 			return (const btSoftBody*)colObj;
 | |
| 		return 0;
 | |
| 	}
 | |
| 	static btSoftBody*			upcast(btCollisionObject* colObj)
 | |
| 	{
 | |
| 		if (colObj->getInternalType()==CO_SOFT_BODY)
 | |
| 			return (btSoftBody*)colObj;
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	//
 | |
| 	// ::btCollisionObject
 | |
| 	//
 | |
| 
 | |
| 	virtual void getAabb(btVector3& aabbMin,btVector3& aabbMax) const
 | |
| 	{
 | |
| 		aabbMin = m_bounds[0];
 | |
| 		aabbMax = m_bounds[1];
 | |
| 	}
 | |
| 	//
 | |
| 	// Private
 | |
| 	//
 | |
| 	void				pointersToIndices();
 | |
| 	void				indicesToPointers(const int* map=0);
 | |
| 
 | |
| 	int					rayTest(const btVector3& rayFrom,const btVector3& rayTo,
 | |
| 		btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const;
 | |
| 	void				initializeFaceTree();
 | |
| 	btVector3			evaluateCom() const;
 | |
| 	bool				checkContact(const btCollisionObjectWrapper* colObjWrap,const btVector3& x,btScalar margin,btSoftBody::sCti& cti) const;
 | |
| 	void				updateNormals();
 | |
| 	void				updateBounds();
 | |
| 	void				updatePose();
 | |
| 	void				updateConstants();
 | |
| 	void				updateLinkConstants();
 | |
| 	void				updateArea(bool averageArea = true);
 | |
| 	void				initializeClusters();
 | |
| 	void				updateClusters();
 | |
| 	void				cleanupClusters();
 | |
| 	void				prepareClusters(int iterations);
 | |
| 	void				solveClusters(btScalar sor);
 | |
| 	void				applyClusters(bool drift);
 | |
| 	void				dampClusters();
 | |
| 	void				applyForces();	
 | |
| 	static void			PSolve_Anchors(btSoftBody* psb,btScalar kst,btScalar ti);
 | |
| 	static void			PSolve_RContacts(btSoftBody* psb,btScalar kst,btScalar ti);
 | |
| 	static void			PSolve_SContacts(btSoftBody* psb,btScalar,btScalar ti);
 | |
| 	static void			PSolve_Links(btSoftBody* psb,btScalar kst,btScalar ti);
 | |
| 	static void			VSolve_Links(btSoftBody* psb,btScalar kst);
 | |
| 	static psolver_t	getSolver(ePSolver::_ solver);
 | |
| 	static vsolver_t	getSolver(eVSolver::_ solver);
 | |
| 
 | |
| 
 | |
| 	virtual	int	calculateSerializeBufferSize()	const;
 | |
| 
 | |
| 	///fills the dataBuffer and returns the struct name (and 0 on failure)
 | |
| 	virtual	const char*	serialize(void* dataBuffer,  class btSerializer* serializer) const;
 | |
| 
 | |
| 	//virtual void serializeSingleObject(class btSerializer* serializer) const;
 | |
| 
 | |
| 
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| #endif //_BT_SOFT_BODY_H
 |