640 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			640 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								Bullet Continuous Collision Detection and Physics Library
							 | 
						||
| 
								 | 
							
								Copyright (c) 2003-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.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								///original version written by Erwin Coumans, October 2013
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "btMLCPSolver.h"
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btMatrixX.h"
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btQuickprof.h"
							 | 
						||
| 
								 | 
							
								#include "btSolveProjectedGaussSeidel.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								btMLCPSolver::btMLCPSolver(	 btMLCPSolverInterface* solver)
							 | 
						||
| 
								 | 
							
								:m_solver(solver),
							 | 
						||
| 
								 | 
							
								m_fallback(0)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								btMLCPSolver::~btMLCPSolver()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								bool gUseMatrixMultiply = false;
							 | 
						||
| 
								 | 
							
								bool interleaveContactAndFriction = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								btScalar btMLCPSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies, int numBodiesUnUsed, btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup( bodies, numBodiesUnUsed, manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										BT_PROFILE("gather constraint data");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										int numFrictionPerContact = m_tmpSolverContactConstraintPool.size()==m_tmpSolverContactFrictionConstraintPool.size()? 1 : 2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//	int numBodies = m_tmpSolverBodyPool.size();
							 | 
						||
| 
								 | 
							
										m_allConstraintPtrArray.resize(0);
							 | 
						||
| 
								 | 
							
										m_limitDependencies.resize(m_tmpSolverNonContactConstraintPool.size()+m_tmpSolverContactConstraintPool.size()+m_tmpSolverContactFrictionConstraintPool.size());
							 | 
						||
| 
								 | 
							
										btAssert(m_limitDependencies.size() == m_tmpSolverNonContactConstraintPool.size()+m_tmpSolverContactConstraintPool.size()+m_tmpSolverContactFrictionConstraintPool.size());
							 | 
						||
| 
								 | 
							
									//	printf("m_limitDependencies.size() = %d\n",m_limitDependencies.size());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										int dindex = 0;
							 | 
						||
| 
								 | 
							
										for (int i=0;i<m_tmpSolverNonContactConstraintPool.size();i++)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											m_allConstraintPtrArray.push_back(&m_tmpSolverNonContactConstraintPool[i]);
							 | 
						||
| 
								 | 
							
											m_limitDependencies[dindex++] = -1;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
										///The btSequentialImpulseConstraintSolver moves all friction constraints at the very end, we can also interleave them instead
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										int firstContactConstraintOffset=dindex;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (interleaveContactAndFriction)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for (int i=0;i<m_tmpSolverContactConstraintPool.size();i++)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												m_allConstraintPtrArray.push_back(&m_tmpSolverContactConstraintPool[i]);
							 | 
						||
| 
								 | 
							
												m_limitDependencies[dindex++] = -1;
							 | 
						||
| 
								 | 
							
												m_allConstraintPtrArray.push_back(&m_tmpSolverContactFrictionConstraintPool[i*numFrictionPerContact]);
							 | 
						||
| 
								 | 
							
												int findex = (m_tmpSolverContactFrictionConstraintPool[i*numFrictionPerContact].m_frictionIndex*(1+numFrictionPerContact));
							 | 
						||
| 
								 | 
							
												m_limitDependencies[dindex++] = findex +firstContactConstraintOffset;
							 | 
						||
| 
								 | 
							
												if (numFrictionPerContact==2)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													m_allConstraintPtrArray.push_back(&m_tmpSolverContactFrictionConstraintPool[i*numFrictionPerContact+1]);
							 | 
						||
| 
								 | 
							
													m_limitDependencies[dindex++] = findex+firstContactConstraintOffset;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										} else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for (int i=0;i<m_tmpSolverContactConstraintPool.size();i++)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												m_allConstraintPtrArray.push_back(&m_tmpSolverContactConstraintPool[i]);
							 | 
						||
| 
								 | 
							
												m_limitDependencies[dindex++] = -1;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											for (int i=0;i<m_tmpSolverContactFrictionConstraintPool.size();i++)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												m_allConstraintPtrArray.push_back(&m_tmpSolverContactFrictionConstraintPool[i]);
							 | 
						||
| 
								 | 
							
												m_limitDependencies[dindex++] = m_tmpSolverContactFrictionConstraintPool[i].m_frictionIndex+firstContactConstraintOffset;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (!m_allConstraintPtrArray.size())
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											m_A.resize(0,0);
							 | 
						||
| 
								 | 
							
											m_b.resize(0);
							 | 
						||
| 
								 | 
							
											m_x.resize(0);
							 | 
						||
| 
								 | 
							
											m_lo.resize(0);
							 | 
						||
| 
								 | 
							
											m_hi.resize(0);
							 | 
						||
| 
								 | 
							
											return 0.f;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									if (gUseMatrixMultiply)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										BT_PROFILE("createMLCP");
							 | 
						||
| 
								 | 
							
										createMLCP(infoGlobal);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										BT_PROFILE("createMLCPFast");
							 | 
						||
| 
								 | 
							
										createMLCPFast(infoGlobal);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return 0.f;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								bool btMLCPSolver::solveMLCP(const btContactSolverInfo& infoGlobal)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									bool result = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (m_A.rows()==0)
							 | 
						||
| 
								 | 
							
										return true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//if using split impulse, we solve 2 separate (M)LCPs
							 | 
						||
| 
								 | 
							
									if (infoGlobal.m_splitImpulse)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										btMatrixXu Acopy = m_A;
							 | 
						||
| 
								 | 
							
										btAlignedObjectArray<int> limitDependenciesCopy = m_limitDependencies;
							 | 
						||
| 
								 | 
							
								//		printf("solve first LCP\n");
							 | 
						||
| 
								 | 
							
										result = m_solver->solveMLCP(m_A, m_b, m_x, m_lo,m_hi, m_limitDependencies,infoGlobal.m_numIterations );
							 | 
						||
| 
								 | 
							
										if (result)
							 | 
						||
| 
								 | 
							
											result = m_solver->solveMLCP(Acopy, m_bSplit, m_xSplit, m_lo,m_hi, limitDependenciesCopy,infoGlobal.m_numIterations );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									} else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										result = m_solver->solveMLCP(m_A, m_b, m_x, m_lo,m_hi, m_limitDependencies,infoGlobal.m_numIterations );
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return result;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct btJointNode
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int jointIndex;     // pointer to enclosing dxJoint object
							 | 
						||
| 
								 | 
							
									int otherBodyIndex;       // *other* body this joint is connected to
							 | 
						||
| 
								 | 
							
									int nextJointNodeIndex;//-1 for null
							 | 
						||
| 
								 | 
							
									int constraintRowIndex;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btMLCPSolver::createMLCPFast(const btContactSolverInfo& infoGlobal)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int numContactRows = interleaveContactAndFriction ? 3 : 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int numConstraintRows = m_allConstraintPtrArray.size();
							 | 
						||
| 
								 | 
							
									int n = numConstraintRows;
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										BT_PROFILE("init b (rhs)");
							 | 
						||
| 
								 | 
							
										m_b.resize(numConstraintRows);
							 | 
						||
| 
								 | 
							
										m_bSplit.resize(numConstraintRows);
							 | 
						||
| 
								 | 
							
										m_b.setZero();
							 | 
						||
| 
								 | 
							
										m_bSplit.setZero();
							 | 
						||
| 
								 | 
							
										for (int i=0;i<numConstraintRows ;i++)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btScalar jacDiag = m_allConstraintPtrArray[i]->m_jacDiagABInv;
							 | 
						||
| 
								 | 
							
											if (!btFuzzyZero(jacDiag))
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												btScalar rhs = m_allConstraintPtrArray[i]->m_rhs;
							 | 
						||
| 
								 | 
							
												btScalar rhsPenetration = m_allConstraintPtrArray[i]->m_rhsPenetration;
							 | 
						||
| 
								 | 
							
												m_b[i]=rhs/jacDiag;
							 | 
						||
| 
								 | 
							
												m_bSplit[i] = rhsPenetration/jacDiag;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//	btScalar* w = 0;
							 | 
						||
| 
								 | 
							
								//	int nub = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									m_lo.resize(numConstraintRows);
							 | 
						||
| 
								 | 
							
									m_hi.resize(numConstraintRows);
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										BT_PROFILE("init lo/ho");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for (int i=0;i<numConstraintRows;i++)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if (0)//m_limitDependencies[i]>=0)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												m_lo[i] = -BT_INFINITY;
							 | 
						||
| 
								 | 
							
												m_hi[i] = BT_INFINITY;
							 | 
						||
| 
								 | 
							
											} else
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												m_lo[i] = m_allConstraintPtrArray[i]->m_lowerLimit;
							 | 
						||
| 
								 | 
							
												m_hi[i] = m_allConstraintPtrArray[i]->m_upperLimit;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//
							 | 
						||
| 
								 | 
							
									int m=m_allConstraintPtrArray.size();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int numBodies = m_tmpSolverBodyPool.size();
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<int> bodyJointNodeArray;
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										BT_PROFILE("bodyJointNodeArray.resize");
							 | 
						||
| 
								 | 
							
										bodyJointNodeArray.resize(numBodies,-1);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									btAlignedObjectArray<btJointNode> jointNodeArray;
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										BT_PROFILE("jointNodeArray.reserve");
							 | 
						||
| 
								 | 
							
										jointNodeArray.reserve(2*m_allConstraintPtrArray.size());
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    btMatrixXu& J3 = m_scratchJ3;
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										BT_PROFILE("J3.resize");
							 | 
						||
| 
								 | 
							
										J3.resize(2*m,8);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								    btMatrixXu& JinvM3 = m_scratchJInvM3;
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										BT_PROFILE("JinvM3.resize/setZero");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										JinvM3.resize(2*m,8);
							 | 
						||
| 
								 | 
							
										JinvM3.setZero();
							 | 
						||
| 
								 | 
							
										J3.setZero();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									int cur=0;
							 | 
						||
| 
								 | 
							
									int rowOffset = 0;
							 | 
						||
| 
								 | 
							
								    btAlignedObjectArray<int>& ofs = m_scratchOfs;
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										BT_PROFILE("ofs resize");
							 | 
						||
| 
								 | 
							
										ofs.resize(0);
							 | 
						||
| 
								 | 
							
										ofs.resizeNoInitialize(m_allConstraintPtrArray.size());
							 | 
						||
| 
								 | 
							
									}				
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										BT_PROFILE("Compute J and JinvM");
							 | 
						||
| 
								 | 
							
										int c=0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										int numRows = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for (int i=0;i<m_allConstraintPtrArray.size();i+=numRows,c++)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											ofs[c] = rowOffset;
							 | 
						||
| 
								 | 
							
											int sbA = m_allConstraintPtrArray[i]->m_solverBodyIdA;
							 | 
						||
| 
								 | 
							
											int sbB = m_allConstraintPtrArray[i]->m_solverBodyIdB;
							 | 
						||
| 
								 | 
							
											btRigidBody* orgBodyA = m_tmpSolverBodyPool[sbA].m_originalBody;
							 | 
						||
| 
								 | 
							
											btRigidBody* orgBodyB = m_tmpSolverBodyPool[sbB].m_originalBody;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											numRows = i<m_tmpSolverNonContactConstraintPool.size() ? m_tmpConstraintSizesPool[c].m_numConstraintRows : numContactRows ;
							 | 
						||
| 
								 | 
							
											if (orgBodyA)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													int slotA=-1;
							 | 
						||
| 
								 | 
							
													//find free jointNode slot for sbA
							 | 
						||
| 
								 | 
							
													slotA =jointNodeArray.size();
							 | 
						||
| 
								 | 
							
													jointNodeArray.expand();//NonInitializing();
							 | 
						||
| 
								 | 
							
													int prevSlot = bodyJointNodeArray[sbA];
							 | 
						||
| 
								 | 
							
													bodyJointNodeArray[sbA] = slotA;
							 | 
						||
| 
								 | 
							
													jointNodeArray[slotA].nextJointNodeIndex = prevSlot;
							 | 
						||
| 
								 | 
							
													jointNodeArray[slotA].jointIndex = c;
							 | 
						||
| 
								 | 
							
													jointNodeArray[slotA].constraintRowIndex = i;
							 | 
						||
| 
								 | 
							
													jointNodeArray[slotA].otherBodyIndex = orgBodyB ? sbB : -1;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												for (int row=0;row<numRows;row++,cur++)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													btVector3 normalInvMass =				m_allConstraintPtrArray[i+row]->m_contactNormal1 *		orgBodyA->getInvMass();
							 | 
						||
| 
								 | 
							
													btVector3 relPosCrossNormalInvInertia = m_allConstraintPtrArray[i+row]->m_relpos1CrossNormal *	orgBodyA->getInvInertiaTensorWorld();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													for (int r=0;r<3;r++)
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														J3.setElem(cur,r,m_allConstraintPtrArray[i+row]->m_contactNormal1[r]);
							 | 
						||
| 
								 | 
							
														J3.setElem(cur,r+4,m_allConstraintPtrArray[i+row]->m_relpos1CrossNormal[r]);
							 | 
						||
| 
								 | 
							
														JinvM3.setElem(cur,r,normalInvMass[r]);
							 | 
						||
| 
								 | 
							
														JinvM3.setElem(cur,r+4,relPosCrossNormalInvInertia[r]);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													J3.setElem(cur,3,0);
							 | 
						||
| 
								 | 
							
													JinvM3.setElem(cur,3,0);
							 | 
						||
| 
								 | 
							
													J3.setElem(cur,7,0);
							 | 
						||
| 
								 | 
							
													JinvM3.setElem(cur,7,0);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											} else
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												cur += numRows;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if (orgBodyB)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													int slotB=-1;
							 | 
						||
| 
								 | 
							
													//find free jointNode slot for sbA
							 | 
						||
| 
								 | 
							
													slotB =jointNodeArray.size();
							 | 
						||
| 
								 | 
							
													jointNodeArray.expand();//NonInitializing();
							 | 
						||
| 
								 | 
							
													int prevSlot = bodyJointNodeArray[sbB];
							 | 
						||
| 
								 | 
							
													bodyJointNodeArray[sbB] = slotB;
							 | 
						||
| 
								 | 
							
													jointNodeArray[slotB].nextJointNodeIndex = prevSlot;
							 | 
						||
| 
								 | 
							
													jointNodeArray[slotB].jointIndex = c;
							 | 
						||
| 
								 | 
							
													jointNodeArray[slotB].otherBodyIndex = orgBodyA ? sbA : -1;
							 | 
						||
| 
								 | 
							
													jointNodeArray[slotB].constraintRowIndex = i;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												for (int row=0;row<numRows;row++,cur++)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													btVector3 normalInvMassB = m_allConstraintPtrArray[i+row]->m_contactNormal2*orgBodyB->getInvMass();
							 | 
						||
| 
								 | 
							
													btVector3 relPosInvInertiaB = m_allConstraintPtrArray[i+row]->m_relpos2CrossNormal * orgBodyB->getInvInertiaTensorWorld();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													for (int r=0;r<3;r++)
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														J3.setElem(cur,r,m_allConstraintPtrArray[i+row]->m_contactNormal2[r]);
							 | 
						||
| 
								 | 
							
														J3.setElem(cur,r+4,m_allConstraintPtrArray[i+row]->m_relpos2CrossNormal[r]);
							 | 
						||
| 
								 | 
							
														JinvM3.setElem(cur,r,normalInvMassB[r]);
							 | 
						||
| 
								 | 
							
														JinvM3.setElem(cur,r+4,relPosInvInertiaB[r]);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													J3.setElem(cur,3,0);
							 | 
						||
| 
								 | 
							
													JinvM3.setElem(cur,3,0);
							 | 
						||
| 
								 | 
							
													J3.setElem(cur,7,0);
							 | 
						||
| 
								 | 
							
													JinvM3.setElem(cur,7,0);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											else
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												cur += numRows;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											rowOffset+=numRows;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//compute JinvM = J*invM.
							 | 
						||
| 
								 | 
							
									const btScalar* JinvM = JinvM3.getBufferPointer();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									const btScalar* Jptr = J3.getBufferPointer();
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										BT_PROFILE("m_A.resize");
							 | 
						||
| 
								 | 
							
										m_A.resize(n,n);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										BT_PROFILE("m_A.setZero");
							 | 
						||
| 
								 | 
							
										m_A.setZero();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									int c=0;
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										int numRows = 0;
							 | 
						||
| 
								 | 
							
										BT_PROFILE("Compute A");
							 | 
						||
| 
								 | 
							
										for (int i=0;i<m_allConstraintPtrArray.size();i+= numRows,c++)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											int row__ = ofs[c];
							 | 
						||
| 
								 | 
							
											int sbA = m_allConstraintPtrArray[i]->m_solverBodyIdA;
							 | 
						||
| 
								 | 
							
											int sbB = m_allConstraintPtrArray[i]->m_solverBodyIdB;
							 | 
						||
| 
								 | 
							
										//	btRigidBody* orgBodyA = m_tmpSolverBodyPool[sbA].m_originalBody;
							 | 
						||
| 
								 | 
							
										//	btRigidBody* orgBodyB = m_tmpSolverBodyPool[sbB].m_originalBody;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											numRows = i<m_tmpSolverNonContactConstraintPool.size() ? m_tmpConstraintSizesPool[c].m_numConstraintRows : numContactRows ;
							 | 
						||
| 
								 | 
							
													
							 | 
						||
| 
								 | 
							
											const btScalar *JinvMrow = JinvM + 2*8*(size_t)row__;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												int startJointNodeA = bodyJointNodeArray[sbA];
							 | 
						||
| 
								 | 
							
												while (startJointNodeA>=0)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													int j0 = jointNodeArray[startJointNodeA].jointIndex;
							 | 
						||
| 
								 | 
							
													int cr0 = jointNodeArray[startJointNodeA].constraintRowIndex;
							 | 
						||
| 
								 | 
							
													if (j0<c)
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
																 
							 | 
						||
| 
								 | 
							
														int numRowsOther = cr0 < m_tmpSolverNonContactConstraintPool.size() ? m_tmpConstraintSizesPool[j0].m_numConstraintRows : numContactRows;
							 | 
						||
| 
								 | 
							
														size_t ofsother = (m_allConstraintPtrArray[cr0]->m_solverBodyIdB == sbA) ? 8*numRowsOther  : 0;
							 | 
						||
| 
								 | 
							
														//printf("%d joint i %d and j0: %d: ",count++,i,j0);
							 | 
						||
| 
								 | 
							
														m_A.multiplyAdd2_p8r ( JinvMrow, 
							 | 
						||
| 
								 | 
							
														Jptr + 2*8*(size_t)ofs[j0] + ofsother, numRows, numRowsOther,  row__,ofs[j0]);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													startJointNodeA = jointNodeArray[startJointNodeA].nextJointNodeIndex;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												int startJointNodeB = bodyJointNodeArray[sbB];
							 | 
						||
| 
								 | 
							
												while (startJointNodeB>=0)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													int j1 = jointNodeArray[startJointNodeB].jointIndex;
							 | 
						||
| 
								 | 
							
													int cj1 = jointNodeArray[startJointNodeB].constraintRowIndex;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													if (j1<c)
							 | 
						||
| 
								 | 
							
													{
							 | 
						||
| 
								 | 
							
														int numRowsOther =  cj1 < m_tmpSolverNonContactConstraintPool.size() ? m_tmpConstraintSizesPool[j1].m_numConstraintRows : numContactRows;
							 | 
						||
| 
								 | 
							
														size_t ofsother = (m_allConstraintPtrArray[cj1]->m_solverBodyIdB == sbB) ? 8*numRowsOther  : 0;
							 | 
						||
| 
								 | 
							
														m_A.multiplyAdd2_p8r ( JinvMrow + 8*(size_t)numRows, 
							 | 
						||
| 
								 | 
							
														Jptr + 2*8*(size_t)ofs[j1] + ofsother, numRows, numRowsOther, row__,ofs[j1]);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													startJointNodeB = jointNodeArray[startJointNodeB].nextJointNodeIndex;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											BT_PROFILE("compute diagonal");
							 | 
						||
| 
								 | 
							
											// compute diagonal blocks of m_A
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											int  row__ = 0;
							 | 
						||
| 
								 | 
							
											int numJointRows = m_allConstraintPtrArray.size();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											int jj=0;
							 | 
						||
| 
								 | 
							
											for (;row__<numJointRows;)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												//int sbA = m_allConstraintPtrArray[row__]->m_solverBodyIdA;
							 | 
						||
| 
								 | 
							
												int sbB = m_allConstraintPtrArray[row__]->m_solverBodyIdB;
							 | 
						||
| 
								 | 
							
											//	btRigidBody* orgBodyA = m_tmpSolverBodyPool[sbA].m_originalBody;
							 | 
						||
| 
								 | 
							
												btRigidBody* orgBodyB = m_tmpSolverBodyPool[sbB].m_originalBody;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												const unsigned int infom =  row__ < m_tmpSolverNonContactConstraintPool.size() ? m_tmpConstraintSizesPool[jj].m_numConstraintRows : numContactRows;
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
												const btScalar *JinvMrow = JinvM + 2*8*(size_t)row__;
							 | 
						||
| 
								 | 
							
												const btScalar *Jrow = Jptr + 2*8*(size_t)row__;
							 | 
						||
| 
								 | 
							
												m_A.multiply2_p8r (JinvMrow, Jrow, infom, infom, row__,row__);
							 | 
						||
| 
								 | 
							
												if (orgBodyB) 
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													m_A.multiplyAdd2_p8r (JinvMrow + 8*(size_t)infom, Jrow + 8*(size_t)infom, infom, infom,  row__,row__);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												row__ += infom;
							 | 
						||
| 
								 | 
							
												jj++;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (1)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										// add cfm to the diagonal of m_A
							 | 
						||
| 
								 | 
							
										for ( int i=0; i<m_A.rows(); ++i) 
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											m_A.setElem(i,i,m_A(i,i)+ infoGlobal.m_globalCfm/ infoGlobal.m_timeStep);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
												   
							 | 
						||
| 
								 | 
							
									///fill the upper triangle of the matrix, to make it symmetric
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										BT_PROFILE("fill the upper triangle ");
							 | 
						||
| 
								 | 
							
										m_A.copyLowerToUpperTriangle();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										BT_PROFILE("resize/init x");
							 | 
						||
| 
								 | 
							
										m_x.resize(numConstraintRows);
							 | 
						||
| 
								 | 
							
										m_xSplit.resize(numConstraintRows);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if (infoGlobal.m_solverMode&SOLVER_USE_WARMSTARTING)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											for (int i=0;i<m_allConstraintPtrArray.size();i++)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												const btSolverConstraint& c = *m_allConstraintPtrArray[i];
							 | 
						||
| 
								 | 
							
												m_x[i]=c.m_appliedImpulse;
							 | 
						||
| 
								 | 
							
												m_xSplit[i] = c.m_appliedPushImpulse;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										} else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											m_x.setZero();
							 | 
						||
| 
								 | 
							
											m_xSplit.setZero();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btMLCPSolver::createMLCP(const btContactSolverInfo& infoGlobal)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int numBodies = this->m_tmpSolverBodyPool.size();
							 | 
						||
| 
								 | 
							
									int numConstraintRows = m_allConstraintPtrArray.size();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									m_b.resize(numConstraintRows);
							 | 
						||
| 
								 | 
							
									if (infoGlobal.m_splitImpulse)
							 | 
						||
| 
								 | 
							
										m_bSplit.resize(numConstraintRows);
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
									m_bSplit.setZero();
							 | 
						||
| 
								 | 
							
									m_b.setZero();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for (int i=0;i<numConstraintRows ;i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if (m_allConstraintPtrArray[i]->m_jacDiagABInv)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											m_b[i]=m_allConstraintPtrArray[i]->m_rhs/m_allConstraintPtrArray[i]->m_jacDiagABInv;
							 | 
						||
| 
								 | 
							
											if (infoGlobal.m_splitImpulse)
							 | 
						||
| 
								 | 
							
												m_bSplit[i] = m_allConstraintPtrArray[i]->m_rhsPenetration/m_allConstraintPtrArray[i]->m_jacDiagABInv;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								    btMatrixXu& Minv = m_scratchMInv;
							 | 
						||
| 
								 | 
							
									Minv.resize(6*numBodies,6*numBodies);
							 | 
						||
| 
								 | 
							
									Minv.setZero();
							 | 
						||
| 
								 | 
							
									for (int i=0;i<numBodies;i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										const btSolverBody& rb = m_tmpSolverBodyPool[i];
							 | 
						||
| 
								 | 
							
										const btVector3& invMass = rb.m_invMass;
							 | 
						||
| 
								 | 
							
										setElem(Minv,i*6+0,i*6+0,invMass[0]);
							 | 
						||
| 
								 | 
							
										setElem(Minv,i*6+1,i*6+1,invMass[1]);
							 | 
						||
| 
								 | 
							
										setElem(Minv,i*6+2,i*6+2,invMass[2]);
							 | 
						||
| 
								 | 
							
										btRigidBody* orgBody = m_tmpSolverBodyPool[i].m_originalBody;
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
										for (int r=0;r<3;r++)
							 | 
						||
| 
								 | 
							
											for (int c=0;c<3;c++)
							 | 
						||
| 
								 | 
							
												setElem(Minv,i*6+3+r,i*6+3+c,orgBody? orgBody->getInvInertiaTensorWorld()[r][c] : 0);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								    btMatrixXu& J = m_scratchJ;
							 | 
						||
| 
								 | 
							
									J.resize(numConstraintRows,6*numBodies);
							 | 
						||
| 
								 | 
							
									J.setZero();
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
									m_lo.resize(numConstraintRows);
							 | 
						||
| 
								 | 
							
									m_hi.resize(numConstraintRows);
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
									for (int i=0;i<numConstraintRows;i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										m_lo[i] = m_allConstraintPtrArray[i]->m_lowerLimit;
							 | 
						||
| 
								 | 
							
										m_hi[i] = m_allConstraintPtrArray[i]->m_upperLimit;
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
										int bodyIndex0 = m_allConstraintPtrArray[i]->m_solverBodyIdA;
							 | 
						||
| 
								 | 
							
										int bodyIndex1 = m_allConstraintPtrArray[i]->m_solverBodyIdB;
							 | 
						||
| 
								 | 
							
										if (m_tmpSolverBodyPool[bodyIndex0].m_originalBody)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											setElem(J,i,6*bodyIndex0+0,m_allConstraintPtrArray[i]->m_contactNormal1[0]);
							 | 
						||
| 
								 | 
							
											setElem(J,i,6*bodyIndex0+1,m_allConstraintPtrArray[i]->m_contactNormal1[1]);
							 | 
						||
| 
								 | 
							
											setElem(J,i,6*bodyIndex0+2,m_allConstraintPtrArray[i]->m_contactNormal1[2]);
							 | 
						||
| 
								 | 
							
											setElem(J,i,6*bodyIndex0+3,m_allConstraintPtrArray[i]->m_relpos1CrossNormal[0]);
							 | 
						||
| 
								 | 
							
											setElem(J,i,6*bodyIndex0+4,m_allConstraintPtrArray[i]->m_relpos1CrossNormal[1]);
							 | 
						||
| 
								 | 
							
											setElem(J,i,6*bodyIndex0+5,m_allConstraintPtrArray[i]->m_relpos1CrossNormal[2]);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if (m_tmpSolverBodyPool[bodyIndex1].m_originalBody)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											setElem(J,i,6*bodyIndex1+0,m_allConstraintPtrArray[i]->m_contactNormal2[0]);
							 | 
						||
| 
								 | 
							
											setElem(J,i,6*bodyIndex1+1,m_allConstraintPtrArray[i]->m_contactNormal2[1]);
							 | 
						||
| 
								 | 
							
											setElem(J,i,6*bodyIndex1+2,m_allConstraintPtrArray[i]->m_contactNormal2[2]);
							 | 
						||
| 
								 | 
							
											setElem(J,i,6*bodyIndex1+3,m_allConstraintPtrArray[i]->m_relpos2CrossNormal[0]);
							 | 
						||
| 
								 | 
							
											setElem(J,i,6*bodyIndex1+4,m_allConstraintPtrArray[i]->m_relpos2CrossNormal[1]);
							 | 
						||
| 
								 | 
							
											setElem(J,i,6*bodyIndex1+5,m_allConstraintPtrArray[i]->m_relpos2CrossNormal[2]);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								    btMatrixXu& J_transpose = m_scratchJTranspose;
							 | 
						||
| 
								 | 
							
									J_transpose= J.transpose();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    btMatrixXu& tmp = m_scratchTmp;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											BT_PROFILE("J*Minv");
							 | 
						||
| 
								 | 
							
											tmp = J*Minv;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											BT_PROFILE("J*tmp");
							 | 
						||
| 
								 | 
							
											m_A = tmp*J_transpose;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (1)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										// add cfm to the diagonal of m_A
							 | 
						||
| 
								 | 
							
										for ( int i=0; i<m_A.rows(); ++i) 
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											m_A.setElem(i,i,m_A(i,i)+ infoGlobal.m_globalCfm / infoGlobal.m_timeStep);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									m_x.resize(numConstraintRows);
							 | 
						||
| 
								 | 
							
									if (infoGlobal.m_splitImpulse)
							 | 
						||
| 
								 | 
							
										m_xSplit.resize(numConstraintRows);
							 | 
						||
| 
								 | 
							
								//	m_x.setZero();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for (int i=0;i<m_allConstraintPtrArray.size();i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										const btSolverConstraint& c = *m_allConstraintPtrArray[i];
							 | 
						||
| 
								 | 
							
										m_x[i]=c.m_appliedImpulse;
							 | 
						||
| 
								 | 
							
										if (infoGlobal.m_splitImpulse)
							 | 
						||
| 
								 | 
							
											m_xSplit[i] = c.m_appliedPushImpulse;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								btScalar btMLCPSolver::solveGroupCacheFriendlyIterations(btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									bool result = true;
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										BT_PROFILE("solveMLCP");
							 | 
						||
| 
								 | 
							
								//		printf("m_A(%d,%d)\n", m_A.rows(),m_A.cols());
							 | 
						||
| 
								 | 
							
										result = solveMLCP(infoGlobal);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//check if solution is valid, and otherwise fallback to btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations
							 | 
						||
| 
								 | 
							
									if (result)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										BT_PROFILE("process MLCP results");
							 | 
						||
| 
								 | 
							
										for (int i=0;i<m_allConstraintPtrArray.size();i++)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												btSolverConstraint& c = *m_allConstraintPtrArray[i];
							 | 
						||
| 
								 | 
							
												int sbA = c.m_solverBodyIdA;
							 | 
						||
| 
								 | 
							
												int sbB = c.m_solverBodyIdB;
							 | 
						||
| 
								 | 
							
												//btRigidBody* orgBodyA = m_tmpSolverBodyPool[sbA].m_originalBody;
							 | 
						||
| 
								 | 
							
											//	btRigidBody* orgBodyB = m_tmpSolverBodyPool[sbB].m_originalBody;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												btSolverBody& solverBodyA = m_tmpSolverBodyPool[sbA];
							 | 
						||
| 
								 | 
							
												btSolverBody& solverBodyB = m_tmpSolverBodyPool[sbB];
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													btScalar deltaImpulse = m_x[i]-c.m_appliedImpulse;
							 | 
						||
| 
								 | 
							
													c.m_appliedImpulse = m_x[i];
							 | 
						||
| 
								 | 
							
													solverBodyA.internalApplyImpulse(c.m_contactNormal1*solverBodyA.internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
							 | 
						||
| 
								 | 
							
													solverBodyB.internalApplyImpulse(c.m_contactNormal2*solverBodyB.internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if (infoGlobal.m_splitImpulse)
							 | 
						||
| 
								 | 
							
												{
							 | 
						||
| 
								 | 
							
													btScalar deltaImpulse = m_xSplit[i] - c.m_appliedPushImpulse;
							 | 
						||
| 
								 | 
							
													solverBodyA.internalApplyPushImpulse(c.m_contactNormal1*solverBodyA.internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
							 | 
						||
| 
								 | 
							
													solverBodyB.internalApplyPushImpulse(c.m_contactNormal2*solverBodyB.internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
							 | 
						||
| 
								 | 
							
													c.m_appliedPushImpulse = m_xSplit[i];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									//	printf("m_fallback = %d\n",m_fallback);
							 | 
						||
| 
								 | 
							
										m_fallback++;
							 | 
						||
| 
								 | 
							
										btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return 0.f;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 |