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
 |