196 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			196 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								Bullet Continuous Collision Detection and Physics Library
							 | 
						||
| 
								 | 
							
								Copyright (c) 2013 Erwin Coumans  http://bulletphysics.org
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef BT_MULTIBODY_CONSTRAINT_H
							 | 
						||
| 
								 | 
							
								#define BT_MULTIBODY_CONSTRAINT_H
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btScalar.h"
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btAlignedObjectArray.h"
							 | 
						||
| 
								 | 
							
								#include "btMultiBody.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class btMultiBody;
							 | 
						||
| 
								 | 
							
								struct btSolverInfo;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "btMultiBodySolverConstraint.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct btMultiBodyJacobianData
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<btScalar>		m_jacobians;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<btScalar>		m_deltaVelocitiesUnitImpulse;	//holds the joint-space response of the corresp. tree to the test impulse in each constraint space dimension
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<btScalar>		m_deltaVelocities;				//holds joint-space vectors of all the constrained trees accumulating the effect of corrective impulses applied in SI
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<btScalar>		scratch_r;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<btVector3>		scratch_v;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<btMatrix3x3>	scratch_m;
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<btSolverBody>*	m_solverBodyPool;
							 | 
						||
| 
								 | 
							
									int									m_fixedBodyId;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ATTRIBUTE_ALIGNED16(class) btMultiBodyConstraint
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								protected:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btMultiBody*	m_bodyA;
							 | 
						||
| 
								 | 
							
								    btMultiBody*	m_bodyB;
							 | 
						||
| 
								 | 
							
								    int				m_linkA;
							 | 
						||
| 
								 | 
							
								    int				m_linkB;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    int				m_numRows;
							 | 
						||
| 
								 | 
							
								    int				m_jacSizeA;
							 | 
						||
| 
								 | 
							
								    int				m_jacSizeBoth;
							 | 
						||
| 
								 | 
							
								    int				m_posOffset;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									bool			m_isUnilateral;
							 | 
						||
| 
								 | 
							
									int				m_numDofsFinalized;
							 | 
						||
| 
								 | 
							
									btScalar		m_maxAppliedImpulse;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // warning: the data block lay out is not consistent for all constraints
							 | 
						||
| 
								 | 
							
								    // data block laid out as follows:
							 | 
						||
| 
								 | 
							
								    // cached impulses. (one per row.)
							 | 
						||
| 
								 | 
							
								    // jacobians. (interleaved, row1 body1 then row1 body2 then row2 body 1 etc)
							 | 
						||
| 
								 | 
							
								    // positions. (one per row.)
							 | 
						||
| 
								 | 
							
								    btAlignedObjectArray<btScalar> m_data;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void	applyDeltaVee(btMultiBodyJacobianData& data, btScalar* delta_vee, btScalar impulse, int velocityIndex, int ndof);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
									btScalar fillMultiBodyConstraint(btMultiBodySolverConstraint& solverConstraint,
							 | 
						||
| 
								 | 
							
																								btMultiBodyJacobianData& data,
							 | 
						||
| 
								 | 
							
								                                     btScalar* jacOrgA, btScalar* jacOrgB,
							 | 
						||
| 
								 | 
							
								                                     const btVector3& constraintNormalAng,
							 | 
						||
| 
								 | 
							
								                                     
							 | 
						||
| 
								 | 
							
																								const btVector3& constraintNormalLin,
							 | 
						||
| 
								 | 
							
																								const btVector3& posAworld, const btVector3& posBworld,
							 | 
						||
| 
								 | 
							
																								btScalar posError,
							 | 
						||
| 
								 | 
							
																								const btContactSolverInfo& infoGlobal,
							 | 
						||
| 
								 | 
							
								                                     btScalar lowerLimit, btScalar upperLimit,
							 | 
						||
| 
								 | 
							
								                                     bool angConstraint = false,
							 | 
						||
| 
								 | 
							
								                                     
							 | 
						||
| 
								 | 
							
																								btScalar relaxation = 1.f,
							 | 
						||
| 
								 | 
							
																								bool isFriction = false, btScalar desiredVelocity=0, btScalar cfmSlip=0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									BT_DECLARE_ALIGNED_ALLOCATOR();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btMultiBodyConstraint(btMultiBody* bodyA,btMultiBody* bodyB,int linkA, int linkB, int numRows, bool isUnilateral);
							 | 
						||
| 
								 | 
							
									virtual ~btMultiBodyConstraint();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void updateJacobianSizes();
							 | 
						||
| 
								 | 
							
									void allocateJacobiansMultiDof();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//many constraints have setFrameInB/setPivotInB. Will use 'getConstraintType' later.
							 | 
						||
| 
								 | 
							
									virtual void setFrameInB(const btMatrix3x3& frameInB) {}
							 | 
						||
| 
								 | 
							
									virtual void setPivotInB(const btVector3& pivotInB){}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									virtual void finalizeMultiDof()=0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									virtual int getIslandIdA() const =0;
							 | 
						||
| 
								 | 
							
									virtual int getIslandIdB() const =0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									virtual void createConstraintRows(btMultiBodyConstraintArray& constraintRows,
							 | 
						||
| 
								 | 
							
										btMultiBodyJacobianData& data,
							 | 
						||
| 
								 | 
							
										const btContactSolverInfo& infoGlobal)=0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int	getNumRows() const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return m_numRows;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btMultiBody*	getMultiBodyA()
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return m_bodyA;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								    btMultiBody*	getMultiBodyB()
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return m_bodyB;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void	internalSetAppliedImpulse(int dof, btScalar appliedImpulse)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btAssert(dof>=0);
							 | 
						||
| 
								 | 
							
										btAssert(dof < getNumRows());
							 | 
						||
| 
								 | 
							
										m_data[dof] = appliedImpulse;
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									btScalar	getAppliedImpulse(int dof)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btAssert(dof>=0);
							 | 
						||
| 
								 | 
							
										btAssert(dof < getNumRows());
							 | 
						||
| 
								 | 
							
										return m_data[dof];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									// current constraint position
							 | 
						||
| 
								 | 
							
								    // constraint is pos >= 0 for unilateral, or pos = 0 for bilateral
							 | 
						||
| 
								 | 
							
								    // NOTE: ignored position for friction rows.
							 | 
						||
| 
								 | 
							
								    btScalar getPosition(int row) const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return m_data[m_posOffset + row];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void setPosition(int row, btScalar pos)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										m_data[m_posOffset + row] = pos;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									bool isUnilateral() const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return m_isUnilateral;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// jacobian blocks.
							 | 
						||
| 
								 | 
							
								    // each of size 6 + num_links. (jacobian2 is null if no body2.)
							 | 
						||
| 
								 | 
							
								    // format: 3 'omega' coefficients, 3 'v' coefficients, then the 'qdot' coefficients.
							 | 
						||
| 
								 | 
							
								    btScalar* jacobianA(int row)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return &m_data[m_numRows + row * m_jacSizeBoth];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								    const btScalar* jacobianA(int row) const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return &m_data[m_numRows + (row * m_jacSizeBoth)];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								    btScalar* jacobianB(int row)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return &m_data[m_numRows + (row * m_jacSizeBoth) + m_jacSizeA];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								    const btScalar* jacobianB(int row) const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return &m_data[m_numRows + (row * m_jacSizeBoth) + m_jacSizeA];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btScalar	getMaxAppliedImpulse() const
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return m_maxAppliedImpulse;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									void	setMaxAppliedImpulse(btScalar maxImp)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										m_maxAppliedImpulse = maxImp;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									virtual void debugDraw(class btIDebugDraw* drawer)=0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									virtual void setGearRatio(btScalar ratio) {}
							 | 
						||
| 
								 | 
							
									virtual void setGearAuxLink(int gearAuxLink) {}
							 | 
						||
| 
								 | 
							
									virtual void setRelativePositionTarget(btScalar relPosTarget){}
							 | 
						||
| 
								 | 
							
									virtual void setErp(btScalar erp){}
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif //BT_MULTIBODY_CONSTRAINT_H
							 | 
						||
| 
								 | 
							
								
							 |