You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1392 regels
45 KiB

  1. /*
  2. Copyright (C) 2010 Sony Computer Entertainment Inc.
  3. All rights reserved.
  4. This software is provided 'as-is', without any express or implied warranty.
  5. In no event will the authors be held liable for any damages arising from the use of this software.
  6. Permission is granted to anyone to use this software for any purpose,
  7. including commercial applications, and to alter it and redistribute it freely,
  8. subject to the following restrictions:
  9. 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.
  10. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  11. 3. This notice may not be removed or altered from any source distribution.
  12. */
  13. #include "btParallelConstraintSolver.h"
  14. #include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
  15. #include "BulletCollision/BroadphaseCollision/btDispatcher.h"
  16. #include "LinearMath/btPoolAllocator.h"
  17. #include "BulletMultiThreaded/vectormath2bullet.h"
  18. #include "LinearMath/btQuickprof.h"
  19. #include "BulletMultiThreaded/btThreadSupportInterface.h"
  20. #ifdef PFX_USE_FREE_VECTORMATH
  21. #include "vecmath/vmInclude.h"
  22. #else
  23. #include "vectormath/vmInclude.h"
  24. #endif //PFX_USE_FREE_VECTORMATH
  25. #include "HeapManager.h"
  26. #include "PlatformDefinitions.h"
  27. //#include "PfxSimdUtils.h"
  28. #include "LinearMath/btScalar.h"
  29. #include "TrbStateVec.h"
  30. /////////////////
  31. #define TMP_BUFF_BYTES (15*1024*1024)
  32. unsigned char ATTRIBUTE_ALIGNED128(tmp_buff[TMP_BUFF_BYTES]);
  33. // Project Gauss Seidel or the equivalent Sequential Impulse
  34. inline void resolveSingleConstraintRowGeneric(PfxSolverBody& body1,PfxSolverBody& body2,const btSolverConstraint& c)
  35. {
  36. btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm;
  37. const btScalar deltaVel1Dotn = c.m_contactNormal.dot(getBtVector3(body1.mDeltaLinearVelocity)) + c.m_relpos1CrossNormal.dot(getBtVector3(body1.mDeltaAngularVelocity));
  38. const btScalar deltaVel2Dotn = -c.m_contactNormal.dot(getBtVector3(body2.mDeltaLinearVelocity)) + c.m_relpos2CrossNormal.dot(getBtVector3(body2.mDeltaAngularVelocity));
  39. // const btScalar delta_rel_vel = deltaVel1Dotn-deltaVel2Dotn;
  40. deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv;
  41. deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv;
  42. const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse;
  43. if (sum < c.m_lowerLimit)
  44. {
  45. deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse;
  46. c.m_appliedImpulse = c.m_lowerLimit;
  47. }
  48. else if (sum > c.m_upperLimit)
  49. {
  50. deltaImpulse = c.m_upperLimit-c.m_appliedImpulse;
  51. c.m_appliedImpulse = c.m_upperLimit;
  52. }
  53. else
  54. {
  55. c.m_appliedImpulse = sum;
  56. }
  57. if (body1.mMassInv)
  58. {
  59. btVector3 linearComponent = c.m_contactNormal*body1.mMassInv;
  60. body1.mDeltaLinearVelocity += vmVector3(linearComponent.getX()*deltaImpulse,linearComponent.getY()*deltaImpulse,linearComponent.getZ()*deltaImpulse);
  61. btVector3 tmp=c.m_angularComponentA*(btVector3(deltaImpulse,deltaImpulse,deltaImpulse));
  62. body1.mDeltaAngularVelocity += vmVector3(tmp.getX(),tmp.getY(),tmp.getZ());
  63. }
  64. if (body2.mMassInv)
  65. {
  66. btVector3 linearComponent = -c.m_contactNormal*body2.mMassInv;
  67. body2.mDeltaLinearVelocity += vmVector3(linearComponent.getX()*deltaImpulse,linearComponent.getY()*deltaImpulse,linearComponent.getZ()*deltaImpulse);
  68. btVector3 tmp = c.m_angularComponentB*((btVector3(deltaImpulse,deltaImpulse,deltaImpulse)));//*m_angularFactor);
  69. body2.mDeltaAngularVelocity += vmVector3(tmp.getX(),tmp.getY(),tmp.getZ());
  70. }
  71. //body1.internalApplyImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
  72. //body2.internalApplyImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
  73. }
  74. static SIMD_FORCE_INLINE
  75. void pfxSolveLinearConstraintRow(btConstraintRow &constraint,
  76. vmVector3 &deltaLinearVelocityA,vmVector3 &deltaAngularVelocityA,
  77. float massInvA,const vmMatrix3 &inertiaInvA,const vmVector3 &rA,
  78. vmVector3 &deltaLinearVelocityB,vmVector3 &deltaAngularVelocityB,
  79. float massInvB,const vmMatrix3 &inertiaInvB,const vmVector3 &rB)
  80. {
  81. const vmVector3 normal(btReadVector3(constraint.m_normal));
  82. btScalar deltaImpulse = constraint.m_rhs;
  83. vmVector3 dVA = deltaLinearVelocityA + cross(deltaAngularVelocityA,rA);
  84. vmVector3 dVB = deltaLinearVelocityB + cross(deltaAngularVelocityB,rB);
  85. deltaImpulse -= constraint.m_jacDiagInv * dot(normal,dVA-dVB);
  86. btScalar oldImpulse = constraint.m_accumImpulse;
  87. constraint.m_accumImpulse = btClamped(oldImpulse + deltaImpulse,constraint.m_lowerLimit,constraint.m_upperLimit);
  88. deltaImpulse = constraint.m_accumImpulse - oldImpulse;
  89. deltaLinearVelocityA += deltaImpulse * massInvA * normal;
  90. deltaAngularVelocityA += deltaImpulse * inertiaInvA * cross(rA,normal);
  91. deltaLinearVelocityB -= deltaImpulse * massInvB * normal;
  92. deltaAngularVelocityB -= deltaImpulse * inertiaInvB * cross(rB,normal);
  93. }
  94. void btSolveContactConstraint(
  95. btConstraintRow &constraintResponse,
  96. btConstraintRow &constraintFriction1,
  97. btConstraintRow &constraintFriction2,
  98. const vmVector3 &contactPointA,
  99. const vmVector3 &contactPointB,
  100. PfxSolverBody &solverBodyA,
  101. PfxSolverBody &solverBodyB,
  102. float friction
  103. )
  104. {
  105. vmVector3 rA = rotate(solverBodyA.mOrientation,contactPointA);
  106. vmVector3 rB = rotate(solverBodyB.mOrientation,contactPointB);
  107. pfxSolveLinearConstraintRow(constraintResponse,
  108. solverBodyA.mDeltaLinearVelocity,solverBodyA.mDeltaAngularVelocity,solverBodyA.mMassInv,solverBodyA.mInertiaInv,rA,
  109. solverBodyB.mDeltaLinearVelocity,solverBodyB.mDeltaAngularVelocity,solverBodyB.mMassInv,solverBodyB.mInertiaInv,rB);
  110. float mf = friction*fabsf(constraintResponse.m_accumImpulse);
  111. constraintFriction1.m_lowerLimit = -mf;
  112. constraintFriction1.m_upperLimit = mf;
  113. constraintFriction2.m_lowerLimit = -mf;
  114. constraintFriction2.m_upperLimit = mf;
  115. pfxSolveLinearConstraintRow(constraintFriction1,
  116. solverBodyA.mDeltaLinearVelocity,solverBodyA.mDeltaAngularVelocity,solverBodyA.mMassInv,solverBodyA.mInertiaInv,rA,
  117. solverBodyB.mDeltaLinearVelocity,solverBodyB.mDeltaAngularVelocity,solverBodyB.mMassInv,solverBodyB.mInertiaInv,rB);
  118. pfxSolveLinearConstraintRow(constraintFriction2,
  119. solverBodyA.mDeltaLinearVelocity,solverBodyA.mDeltaAngularVelocity,solverBodyA.mMassInv,solverBodyA.mInertiaInv,rA,
  120. solverBodyB.mDeltaLinearVelocity,solverBodyB.mDeltaAngularVelocity,solverBodyB.mMassInv,solverBodyB.mInertiaInv,rB);
  121. }
  122. void CustomSolveConstraintsTaskParallel(
  123. const PfxParallelGroup *contactParallelGroup,const PfxParallelBatch *contactParallelBatches,
  124. PfxConstraintPair *contactPairs,uint32_t numContactPairs,
  125. btPersistentManifold* offsetContactManifolds,
  126. const PfxParallelGroup *jointParallelGroup,const PfxParallelBatch *jointParallelBatches,
  127. PfxConstraintPair *jointPairs,uint32_t numJointPairs,
  128. btSolverConstraint* offsetSolverConstraints,
  129. TrbState *offsetRigStates,
  130. PfxSolverBody *offsetSolverBodies,
  131. uint32_t numRigidBodies,
  132. int iteration,unsigned int taskId,unsigned int numTasks,btBarrier *barrier)
  133. {
  134. PfxSolverBody staticBody;
  135. staticBody.mMassInv = 0.f;
  136. staticBody.mDeltaAngularVelocity=vmVector3(0,0,0);
  137. staticBody.mDeltaLinearVelocity =vmVector3(0,0,0);
  138. for(int k=0;k<iteration+1;k++) {
  139. // Joint
  140. for(uint32_t phaseId=0;phaseId<jointParallelGroup->numPhases;phaseId++) {
  141. for(uint32_t batchId=0;batchId<jointParallelGroup->numBatches[phaseId];batchId++) {
  142. uint32_t numPairs = jointParallelGroup->numPairs[phaseId*PFX_MAX_SOLVER_BATCHES+batchId];
  143. if(batchId%numTasks == taskId && numPairs > 0) {
  144. const PfxParallelBatch &batch = jointParallelBatches[phaseId*PFX_MAX_SOLVER_BATCHES+batchId];
  145. for(uint32_t i=0;i<numPairs;i++) {
  146. PfxConstraintPair &pair = jointPairs[batch.pairIndices[i]];
  147. uint16_t iA = pfxGetRigidBodyIdA(pair);
  148. uint16_t iB = pfxGetRigidBodyIdB(pair);
  149. PfxSolverBody &solverBodyA = iA != 65535 ? offsetSolverBodies[iA] : staticBody;
  150. PfxSolverBody &solverBodyB = iB != 65535 ? offsetSolverBodies[iB] : staticBody;
  151. if(k==0) {
  152. }
  153. else {
  154. btSolverConstraint* constraintRow = &offsetSolverConstraints[pfxGetContactId1(pair)];
  155. int numRows = pfxGetNumConstraints(pair);
  156. int i;
  157. for (i=0;i<numRows;i++)
  158. {
  159. resolveSingleConstraintRowGeneric(solverBodyA,solverBodyB,constraintRow[i]);
  160. }
  161. }
  162. }
  163. }
  164. }
  165. barrier->sync();
  166. }
  167. // Contact
  168. for(uint32_t phaseId=0;phaseId<contactParallelGroup->numPhases;phaseId++) {
  169. for(uint32_t batchId=0;batchId<contactParallelGroup->numBatches[phaseId];batchId++) {
  170. uint32_t numPairs = contactParallelGroup->numPairs[phaseId*PFX_MAX_SOLVER_BATCHES+batchId];
  171. if(batchId%numTasks == taskId && numPairs > 0) {
  172. const PfxParallelBatch &batch = contactParallelBatches[phaseId*PFX_MAX_SOLVER_BATCHES+batchId];
  173. for(uint32_t i=0;i<numPairs;i++) {
  174. PfxConstraintPair &pair = contactPairs[batch.pairIndices[i]];
  175. uint16_t iA = pfxGetRigidBodyIdA(pair);
  176. uint16_t iB = pfxGetRigidBodyIdB(pair);
  177. btPersistentManifold& contact = offsetContactManifolds[pfxGetConstraintId1(pair)];
  178. PfxSolverBody &solverBodyA = offsetSolverBodies[iA];
  179. PfxSolverBody &solverBodyB = offsetSolverBodies[iB];
  180. for(int j=0;j<contact.getNumContacts();j++) {
  181. btManifoldPoint& cp = contact.getContactPoint(j);
  182. if(k==0) {
  183. vmVector3 rA = rotate(solverBodyA.mOrientation,btReadVector3(cp.m_localPointA));
  184. vmVector3 rB = rotate(solverBodyB.mOrientation,btReadVector3(cp.m_localPointB));
  185. for(int k=0;k<3;k++) {
  186. vmVector3 normal = btReadVector3(cp.mConstraintRow[k].m_normal);
  187. float deltaImpulse = cp.mConstraintRow[k].m_accumImpulse;
  188. solverBodyA.mDeltaLinearVelocity += deltaImpulse * solverBodyA.mMassInv * normal;
  189. solverBodyA.mDeltaAngularVelocity += deltaImpulse * solverBodyA.mInertiaInv * cross(rA,normal);
  190. solverBodyB.mDeltaLinearVelocity -= deltaImpulse * solverBodyB.mMassInv * normal;
  191. solverBodyB.mDeltaAngularVelocity -= deltaImpulse * solverBodyB.mInertiaInv * cross(rB,normal);
  192. }
  193. }
  194. else {
  195. btSolveContactConstraint(
  196. cp.mConstraintRow[0],
  197. cp.mConstraintRow[1],
  198. cp.mConstraintRow[2],
  199. btReadVector3(cp.m_localPointA),
  200. btReadVector3(cp.m_localPointB),
  201. solverBodyA,
  202. solverBodyB,
  203. cp.m_combinedFriction
  204. );
  205. }
  206. }
  207. }
  208. }
  209. }
  210. if (barrier)
  211. barrier->sync();
  212. }
  213. }
  214. }
  215. void CustomPostSolverTask(
  216. TrbState *states,
  217. PfxSolverBody *solverBodies,
  218. uint32_t numRigidBodies)
  219. {
  220. for(uint32_t i=0;i<numRigidBodies;i++) {
  221. TrbState &state = states[i];
  222. PfxSolverBody &solverBody = solverBodies[i];
  223. state.setLinearVelocity(state.getLinearVelocity()+solverBody.mDeltaLinearVelocity);
  224. state.setAngularVelocity(state.getAngularVelocity()+solverBody.mDeltaAngularVelocity);
  225. }
  226. }
  227. void* SolverlsMemoryFunc()
  228. {
  229. //don't create local store memory, just return 0
  230. return 0;
  231. }
  232. static SIMD_FORCE_INLINE
  233. void pfxGetPlaneSpace(const vmVector3& n, vmVector3& p, vmVector3& q)
  234. {
  235. if(fabsf(n[2]) > 0.707f) {
  236. // choose p in y-z plane
  237. float a = n[1]*n[1] + n[2]*n[2];
  238. float k = 1.0f/sqrtf(a);
  239. p[0] = 0;
  240. p[1] = -n[2]*k;
  241. p[2] = n[1]*k;
  242. // set q = n x p
  243. q[0] = a*k;
  244. q[1] = -n[0]*p[2];
  245. q[2] = n[0]*p[1];
  246. }
  247. else {
  248. // choose p in x-y plane
  249. float a = n[0]*n[0] + n[1]*n[1];
  250. float k = 1.0f/sqrtf(a);
  251. p[0] = -n[1]*k;
  252. p[1] = n[0]*k;
  253. p[2] = 0;
  254. // set q = n x p
  255. q[0] = -n[2]*p[1];
  256. q[1] = n[2]*p[0];
  257. q[2] = a*k;
  258. }
  259. }
  260. #define PFX_CONTACT_SLOP 0.001f
  261. void btSetupContactConstraint(
  262. btConstraintRow &constraintResponse,
  263. btConstraintRow &constraintFriction1,
  264. btConstraintRow &constraintFriction2,
  265. float penetrationDepth,
  266. float restitution,
  267. float friction,
  268. const vmVector3 &contactNormal,
  269. const vmVector3 &contactPointA,
  270. const vmVector3 &contactPointB,
  271. const TrbState &stateA,
  272. const TrbState &stateB,
  273. PfxSolverBody &solverBodyA,
  274. PfxSolverBody &solverBodyB,
  275. float separateBias,
  276. float timeStep
  277. )
  278. {
  279. vmVector3 rA = rotate(solverBodyA.mOrientation,contactPointA);
  280. vmVector3 rB = rotate(solverBodyB.mOrientation,contactPointB);
  281. vmMatrix3 K = vmMatrix3::scale(vmVector3(solverBodyA.mMassInv + solverBodyB.mMassInv)) -
  282. crossMatrix(rA) * solverBodyA.mInertiaInv * crossMatrix(rA) -
  283. crossMatrix(rB) * solverBodyB.mInertiaInv * crossMatrix(rB);
  284. vmVector3 vA = stateA.getLinearVelocity() + cross(stateA.getAngularVelocity(),rA);
  285. vmVector3 vB = stateB.getLinearVelocity() + cross(stateB.getAngularVelocity(),rB);
  286. vmVector3 vAB = vA-vB;
  287. vmVector3 tangent1,tangent2;
  288. btPlaneSpace1(contactNormal,tangent1,tangent2);
  289. // constraintResponse.m_accumImpulse = 0.f;
  290. // constraintFriction1.m_accumImpulse = 0.f;
  291. // constraintFriction2.m_accumImpulse = 0.f;
  292. // Contact Constraint
  293. {
  294. vmVector3 normal = contactNormal;
  295. float denom = dot(K*normal,normal);
  296. constraintResponse.m_rhs = -(1.0f+restitution)*dot(vAB,normal); // velocity error
  297. constraintResponse.m_rhs -= (separateBias * btMin(0.0f,penetrationDepth+PFX_CONTACT_SLOP)) / timeStep; // position error
  298. constraintResponse.m_rhs /= denom;
  299. constraintResponse.m_jacDiagInv = 1.0f/denom;
  300. constraintResponse.m_lowerLimit = 0.0f;
  301. constraintResponse.m_upperLimit = SIMD_INFINITY;
  302. btStoreVector3(normal,constraintResponse.m_normal);
  303. }
  304. // Friction Constraint 1
  305. {
  306. vmVector3 normal = tangent1;
  307. float denom = dot(K*normal,normal);
  308. constraintFriction1.m_jacDiagInv = 1.0f/denom;
  309. constraintFriction1.m_rhs = -dot(vAB,normal);
  310. constraintFriction1.m_rhs *= constraintFriction1.m_jacDiagInv;
  311. constraintFriction1.m_lowerLimit = 0.0f;
  312. constraintFriction1.m_upperLimit = SIMD_INFINITY;
  313. btStoreVector3(normal,constraintFriction1.m_normal);
  314. }
  315. // Friction Constraint 2
  316. {
  317. vmVector3 normal = tangent2;
  318. float denom = dot(K*normal,normal);
  319. constraintFriction2.m_jacDiagInv = 1.0f/denom;
  320. constraintFriction2.m_rhs = -dot(vAB,normal);
  321. constraintFriction2.m_rhs *= constraintFriction2.m_jacDiagInv;
  322. constraintFriction2.m_lowerLimit = 0.0f;
  323. constraintFriction2.m_upperLimit = SIMD_INFINITY;
  324. btStoreVector3(normal,constraintFriction2.m_normal);
  325. }
  326. }
  327. void CustomSetupContactConstraintsTask(
  328. PfxConstraintPair *contactPairs,uint32_t numContactPairs,
  329. btPersistentManifold* offsetContactManifolds,
  330. TrbState *offsetRigStates,
  331. PfxSolverBody *offsetSolverBodies,
  332. uint32_t numRigidBodies,
  333. float separateBias,
  334. float timeStep)
  335. {
  336. for(uint32_t i=0;i<numContactPairs;i++) {
  337. PfxConstraintPair &pair = contactPairs[i];
  338. if(!pfxGetActive(pair) || pfxGetNumConstraints(pair) == 0 ||
  339. ((pfxGetMotionMaskA(pair)&PFX_MOTION_MASK_STATIC) && (pfxGetMotionMaskB(pair)&PFX_MOTION_MASK_STATIC)) ) {
  340. continue;
  341. }
  342. uint16_t iA = pfxGetRigidBodyIdA(pair);
  343. uint16_t iB = pfxGetRigidBodyIdB(pair);
  344. int id = pfxGetConstraintId1(pair);
  345. btPersistentManifold& contact = offsetContactManifolds[id];
  346. TrbState &stateA = offsetRigStates[iA];
  347. // PfxRigBody &bodyA = offsetRigBodies[iA];
  348. PfxSolverBody &solverBodyA = offsetSolverBodies[iA];
  349. TrbState &stateB = offsetRigStates[iB];
  350. // PfxRigBody &bodyB = offsetRigBodies[iB];
  351. PfxSolverBody &solverBodyB = offsetSolverBodies[iB];
  352. float restitution = 0.5f * (solverBodyA.restitution + solverBodyB.restitution);
  353. //if(contact.getDuration() > 1) restitution = 0.0f;
  354. float friction = sqrtf(solverBodyA.friction * solverBodyB.friction);
  355. for(int j=0;j<contact.getNumContacts();j++) {
  356. btManifoldPoint& cp = contact.getContactPoint(j);
  357. btSetupContactConstraint(
  358. cp.mConstraintRow[0],
  359. cp.mConstraintRow[1],
  360. cp.mConstraintRow[2],
  361. cp.getDistance(),
  362. restitution,
  363. friction,
  364. btReadVector3(cp.m_normalWorldOnB),//.mConstraintRow[0].m_normal),
  365. btReadVector3(cp.m_localPointA),
  366. btReadVector3(cp.m_localPointB),
  367. stateA,
  368. stateB,
  369. solverBodyA,
  370. solverBodyB,
  371. separateBias,
  372. timeStep
  373. );
  374. }
  375. //contact.setCompositeFriction(friction);
  376. }
  377. }
  378. void SolverThreadFunc(void* userPtr,void* lsMemory)
  379. {
  380. btConstraintSolverIO* io = (btConstraintSolverIO*)(userPtr);//arg->io);
  381. btCriticalSection* criticalsection = io->setupContactConstraints.criticalSection;
  382. //CustomCriticalSection *criticalsection = &io->m_cs;
  383. switch(io->cmd) {
  384. case PFX_CONSTRAINT_SOLVER_CMD_SOLVE_CONSTRAINTS:
  385. CustomSolveConstraintsTaskParallel(
  386. io->solveConstraints.contactParallelGroup,
  387. io->solveConstraints.contactParallelBatches,
  388. io->solveConstraints.contactPairs,
  389. io->solveConstraints.numContactPairs,
  390. io->solveConstraints.offsetContactManifolds,
  391. io->solveConstraints.jointParallelGroup,
  392. io->solveConstraints.jointParallelBatches,
  393. io->solveConstraints.jointPairs,
  394. io->solveConstraints.numJointPairs,
  395. io->solveConstraints.offsetSolverConstraints,
  396. io->solveConstraints.offsetRigStates1,
  397. io->solveConstraints.offsetSolverBodies,
  398. io->solveConstraints.numRigidBodies,
  399. io->solveConstraints.iteration,
  400. io->solveConstraints.taskId,
  401. io->maxTasks1,
  402. io->solveConstraints.barrier
  403. );
  404. break;
  405. case PFX_CONSTRAINT_SOLVER_CMD_POST_SOLVER:
  406. CustomPostSolverTask( io->postSolver.states,io->postSolver.solverBodies, io->postSolver.numRigidBodies);
  407. break;
  408. case PFX_CONSTRAINT_SOLVER_CMD_SETUP_CONTACT_CONSTRAINTS:
  409. {
  410. bool empty = false;
  411. while(!empty) {
  412. int start,batch;
  413. criticalsection->lock();
  414. start = (int)criticalsection->getSharedParam(0);
  415. batch = (int)criticalsection->getSharedParam(1);
  416. //PFX_PRINTF("taskId %d start %d num %d\n",arg->taskId,start,batch);
  417. // 次のバッファをセット
  418. int nextStart = start + batch;
  419. int rest = btMax((int)io->setupContactConstraints.numContactPairs1 - nextStart,0);
  420. int nextBatch = (rest > batch)?batch:rest;
  421. criticalsection->setSharedParam(0,nextStart);
  422. criticalsection->setSharedParam(1,nextBatch);
  423. criticalsection->unlock();
  424. if(batch > 0) {
  425. CustomSetupContactConstraintsTask(
  426. io->setupContactConstraints.offsetContactPairs+start,batch,
  427. io->setupContactConstraints.offsetContactManifolds,
  428. io->setupContactConstraints.offsetRigStates,
  429. // io->setupContactConstraints.offsetRigBodies,
  430. io->setupContactConstraints.offsetSolverBodies,
  431. io->setupContactConstraints.numRigidBodies,
  432. io->setupContactConstraints.separateBias,
  433. io->setupContactConstraints.timeStep);
  434. }
  435. else {
  436. empty = true;
  437. }
  438. }
  439. }
  440. break;
  441. default:
  442. {
  443. btAssert(0);
  444. }
  445. }
  446. }
  447. void CustomSetupContactConstraintsNew(
  448. PfxConstraintPair *contactPairs1,uint32_t numContactPairs,
  449. btPersistentManifold *offsetContactManifolds,
  450. TrbState *offsetRigStates,
  451. PfxSolverBody *offsetSolverBodies,
  452. uint32_t numRigidBodies,
  453. float separationBias,
  454. float timeStep,
  455. class btThreadSupportInterface* threadSupport,
  456. btCriticalSection* criticalSection,
  457. btConstraintSolverIO *io
  458. )
  459. {
  460. int maxTasks = threadSupport->getNumTasks();
  461. int div = (int)maxTasks * 4;
  462. int batch = ((int)numContactPairs + div - 1) / div;
  463. #ifdef __PPU__
  464. BulletPE2ConstraintSolverSpursSupport* spursThread = (BulletPE2ConstraintSolverSpursSupport*) threadSupport;
  465. #endif
  466. if (criticalSection)
  467. {
  468. criticalSection->setSharedParam(0,0);
  469. criticalSection->setSharedParam(1,btMin(batch,64)); // batched number
  470. } else
  471. {
  472. #ifdef __PPU__
  473. spursThread->setSharedParam(0,0);
  474. spursThread->setSharedParam(1,btMin(batch,64)); // batched number
  475. #endif //__PPU__
  476. }
  477. for(int t=0;t<maxTasks;t++) {
  478. io[t].cmd = PFX_CONSTRAINT_SOLVER_CMD_SETUP_CONTACT_CONSTRAINTS;
  479. io[t].setupContactConstraints.offsetContactPairs = contactPairs1;
  480. io[t].setupContactConstraints.numContactPairs1 = numContactPairs;
  481. io[t].setupContactConstraints.offsetRigStates = offsetRigStates;
  482. io[t].setupContactConstraints.offsetContactManifolds = offsetContactManifolds;
  483. io[t].setupContactConstraints.offsetSolverBodies = offsetSolverBodies;
  484. io[t].setupContactConstraints.numRigidBodies = numRigidBodies;
  485. io[t].setupContactConstraints.separateBias = separationBias;
  486. io[t].setupContactConstraints.timeStep = timeStep;
  487. io[t].setupContactConstraints.criticalSection = criticalSection;
  488. io[t].maxTasks1 = maxTasks;
  489. #ifdef __PPU__
  490. io[t].barrierAddr2 = (unsigned int)spursThread->getBarrierAddress();
  491. io[t].criticalsectionAddr2 = (unsigned int)spursThread->getCriticalSectionAddress();
  492. #endif
  493. //#define SEQUENTIAL_SETUP
  494. #ifdef SEQUENTIAL_SETUP
  495. CustomSetupContactConstraintsTask(contactPairs1,numContactPairs,offsetContactManifolds,offsetRigStates,offsetSolverBodies,numRigidBodies,separationBias,timeStep);
  496. #else
  497. threadSupport->sendRequest(1,(ppu_address_t)&io[t],t);
  498. #endif
  499. }
  500. #ifndef SEQUENTIAL_SETUP
  501. unsigned int arg0,arg1;
  502. for(int t=0;t<maxTasks;t++) {
  503. arg0 = t;
  504. threadSupport->waitForResponse(&arg0,&arg1);
  505. }
  506. #endif //SEQUENTIAL_SETUP
  507. }
  508. void CustomSplitConstraints(
  509. PfxConstraintPair *pairs,uint32_t numPairs,
  510. PfxParallelGroup &group,PfxParallelBatch *batches,
  511. uint32_t numTasks,
  512. uint32_t numRigidBodies,
  513. void *poolBuff,
  514. uint32_t poolBytes
  515. )
  516. {
  517. HeapManager pool((unsigned char*)poolBuff,poolBytes);
  518. // ステートチェック用ビットフラグテーブル
  519. int bufSize = sizeof(uint8_t)*numRigidBodies;
  520. bufSize = ((bufSize+127)>>7)<<7; // 128 bytes alignment
  521. uint8_t *bodyTable = (uint8_t*)pool.allocate(bufSize,HeapManager::ALIGN128);
  522. // ペアチェック用ビットフラグテーブル
  523. uint32_t *pairTable;
  524. size_t allocSize = sizeof(uint32_t)*((numPairs+31)/32);
  525. pairTable = (uint32_t*)pool.allocate(allocSize);
  526. memset(pairTable,0,allocSize);
  527. // 目標とする分割数
  528. uint32_t targetCount = btMax(uint32_t(PFX_MIN_SOLVER_PAIRS),btMin(numPairs / (numTasks*2),uint32_t(PFX_MAX_SOLVER_PAIRS)));
  529. uint32_t startIndex = 0;
  530. uint32_t phaseId;
  531. uint32_t batchId;
  532. uint32_t totalCount=0;
  533. uint32_t maxBatches = btMin(numTasks,uint32_t(PFX_MAX_SOLVER_BATCHES));
  534. for(phaseId=0;phaseId<PFX_MAX_SOLVER_PHASES&&totalCount<numPairs;phaseId++) {
  535. bool startIndexCheck = true;
  536. group.numBatches[phaseId] = 0;
  537. uint32_t i = startIndex;
  538. // チェック用ビットフラグテーブルをクリア
  539. memset(bodyTable,0xff,bufSize);
  540. for(batchId=0;i<numPairs&&totalCount<numPairs&&batchId<maxBatches;batchId++) {
  541. uint32_t pairCount=0;
  542. PfxParallelBatch &batch = batches[phaseId*PFX_MAX_SOLVER_BATCHES+batchId];
  543. uint32_t pairId = 0;
  544. for(;i<numPairs&&pairCount<targetCount;i++) {
  545. uint32_t idxP = i>>5;
  546. uint32_t maskP = 1L << (i & 31);
  547. //pair is already assigned to a phase/batch
  548. if(pairTable[idxP] & maskP) {
  549. continue;
  550. }
  551. uint32_t idxA = pfxGetRigidBodyIdA(pairs[i]);
  552. uint32_t idxB = pfxGetRigidBodyIdB(pairs[i]);
  553. // 両方ともアクティブでない、または衝突点が0のペアは登録対象からはずす
  554. if(!pfxGetActive(pairs[i]) || pfxGetNumConstraints(pairs[i]) == 0 ||
  555. ((pfxGetMotionMaskA(pairs[i])&PFX_MOTION_MASK_STATIC) && (pfxGetMotionMaskB(pairs[i])&PFX_MOTION_MASK_STATIC)) ) {
  556. if(startIndexCheck)
  557. startIndex++;
  558. //assign pair -> skip it because it has no constraints
  559. pairTable[idxP] |= maskP;
  560. totalCount++;
  561. continue;
  562. }
  563. // 依存性のチェック
  564. if( (bodyTable[idxA] != batchId && bodyTable[idxA] != 0xff) ||
  565. (bodyTable[idxB] != batchId && bodyTable[idxB] != 0xff) ) {
  566. startIndexCheck = false;
  567. //bodies of the pair are already assigned to another batch within this phase
  568. continue;
  569. }
  570. // 依存性判定テーブルに登録
  571. if(pfxGetMotionMaskA(pairs[i])&PFX_MOTION_MASK_DYNAMIC)
  572. bodyTable[idxA] = batchId;
  573. if(pfxGetMotionMaskB(pairs[i])&PFX_MOTION_MASK_DYNAMIC)
  574. bodyTable[idxB] = batchId;
  575. if(startIndexCheck)
  576. startIndex++;
  577. pairTable[idxP] |= maskP;
  578. //add the pair 'i' to the current batch
  579. batch.pairIndices[pairId++] = i;
  580. pairCount++;
  581. }
  582. group.numPairs[phaseId*PFX_MAX_SOLVER_BATCHES+batchId] = (uint16_t)pairId;
  583. totalCount += pairCount;
  584. }
  585. group.numBatches[phaseId] = batchId;
  586. }
  587. group.numPhases = phaseId;
  588. pool.clear();
  589. }
  590. void CustomSolveConstraintsParallel(
  591. PfxConstraintPair *contactPairs,uint32_t numContactPairs,
  592. PfxConstraintPair *jointPairs,uint32_t numJointPairs,
  593. btPersistentManifold* offsetContactManifolds,
  594. btSolverConstraint* offsetSolverConstraints,
  595. TrbState *offsetRigStates,
  596. PfxSolverBody *offsetSolverBodies,
  597. uint32_t numRigidBodies,
  598. struct btConstraintSolverIO* io,
  599. class btThreadSupportInterface* threadSupport,
  600. int iteration,
  601. void* poolBuf,
  602. int poolBytes,
  603. class btBarrier* barrier)
  604. {
  605. int maxTasks = threadSupport->getNumTasks();
  606. // config.taskManager->setTaskEntry(PFX_SOLVER_ENTRY);
  607. HeapManager pool((unsigned char*)poolBuf,poolBytes);
  608. {
  609. PfxParallelGroup *cgroup = (PfxParallelGroup*)pool.allocate(sizeof(PfxParallelGroup));
  610. PfxParallelBatch *cbatches = (PfxParallelBatch*)pool.allocate(sizeof(PfxParallelBatch)*(PFX_MAX_SOLVER_PHASES*PFX_MAX_SOLVER_BATCHES),128);
  611. PfxParallelGroup *jgroup = (PfxParallelGroup*)pool.allocate(sizeof(PfxParallelGroup));
  612. PfxParallelBatch *jbatches = (PfxParallelBatch*)pool.allocate(sizeof(PfxParallelBatch)*(PFX_MAX_SOLVER_PHASES*PFX_MAX_SOLVER_BATCHES),128);
  613. uint32_t tmpBytes = poolBytes - 2 * (sizeof(PfxParallelGroup) + sizeof(PfxParallelBatch)*(PFX_MAX_SOLVER_PHASES*PFX_MAX_SOLVER_BATCHES) + 128);
  614. void *tmpBuff = pool.allocate(tmpBytes);
  615. {
  616. BT_PROFILE("CustomSplitConstraints");
  617. CustomSplitConstraints(contactPairs,numContactPairs,*cgroup,cbatches,maxTasks,numRigidBodies,tmpBuff,tmpBytes);
  618. CustomSplitConstraints(jointPairs,numJointPairs,*jgroup,jbatches,maxTasks,numRigidBodies,tmpBuff,tmpBytes);
  619. }
  620. {
  621. BT_PROFILE("PFX_CONSTRAINT_SOLVER_CMD_SOLVE_CONSTRAINTS");
  622. //#define SOLVE_SEQUENTIAL
  623. #ifdef SOLVE_SEQUENTIAL
  624. CustomSolveConstraintsTask(
  625. io->solveConstraints.contactParallelGroup,
  626. io->solveConstraints.contactParallelBatches,
  627. io->solveConstraints.contactPairs,
  628. io->solveConstraints.numContactPairs,
  629. io->solveConstraints.offsetContactManifolds,
  630. io->solveConstraints.jointParallelGroup,
  631. io->solveConstraints.jointParallelBatches,
  632. io->solveConstraints.jointPairs,
  633. io->solveConstraints.numJointPairs,
  634. io->solveConstraints.offsetJoints,
  635. io->solveConstraints.offsetRigStates,
  636. io->solveConstraints.offsetSolverBodies,
  637. io->solveConstraints.numRigidBodies,
  638. io->solveConstraints.iteration,0,1,0);//arg->taskId,1,0);//,arg->maxTasks,arg->barrier);
  639. #else
  640. for(int t=0;t<maxTasks;t++) {
  641. io[t].cmd = PFX_CONSTRAINT_SOLVER_CMD_SOLVE_CONSTRAINTS;
  642. io[t].solveConstraints.contactParallelGroup = cgroup;
  643. io[t].solveConstraints.contactParallelBatches = cbatches;
  644. io[t].solveConstraints.contactPairs = contactPairs;
  645. io[t].solveConstraints.numContactPairs = numContactPairs;
  646. io[t].solveConstraints.offsetContactManifolds = offsetContactManifolds;
  647. io[t].solveConstraints.jointParallelGroup = jgroup;
  648. io[t].solveConstraints.jointParallelBatches = jbatches;
  649. io[t].solveConstraints.jointPairs = jointPairs;
  650. io[t].solveConstraints.numJointPairs = numJointPairs;
  651. io[t].solveConstraints.offsetSolverConstraints = offsetSolverConstraints;
  652. io[t].solveConstraints.offsetRigStates1 = offsetRigStates;
  653. io[t].solveConstraints.offsetSolverBodies = offsetSolverBodies;
  654. io[t].solveConstraints.numRigidBodies = numRigidBodies;
  655. io[t].solveConstraints.iteration = iteration;
  656. io[t].solveConstraints.taskId = t;
  657. io[t].solveConstraints.barrier = barrier;
  658. io[t].maxTasks1 = maxTasks;
  659. #ifdef __PPU__
  660. BulletPE2ConstraintSolverSpursSupport* spursThread = (BulletPE2ConstraintSolverSpursSupport*) threadSupport;
  661. io[t].barrierAddr2 = (unsigned int) spursThread->getBarrierAddress();
  662. io[t].criticalsectionAddr2 = (unsigned int)spursThread->getCriticalSectionAddress();
  663. #endif
  664. threadSupport->sendRequest(1,(ppu_address_t)&io[t],t);
  665. }
  666. unsigned int arg0,arg1;
  667. for(int t=0;t<maxTasks;t++) {
  668. arg0 = t;
  669. threadSupport->waitForResponse(&arg0,&arg1);
  670. }
  671. #endif
  672. }
  673. pool.clear();
  674. }
  675. {
  676. BT_PROFILE("PFX_CONSTRAINT_SOLVER_CMD_POST_SOLVER");
  677. int batch = ((int)numRigidBodies + maxTasks - 1) / maxTasks;
  678. int rest = (int)numRigidBodies;
  679. int start = 0;
  680. for(int t=0;t<maxTasks;t++) {
  681. int num = (rest - batch ) > 0 ? batch : rest;
  682. io[t].cmd = PFX_CONSTRAINT_SOLVER_CMD_POST_SOLVER;
  683. io[t].postSolver.states = offsetRigStates + start;
  684. io[t].postSolver.solverBodies = offsetSolverBodies + start;
  685. io[t].postSolver.numRigidBodies = (uint32_t)num;
  686. io[t].maxTasks1 = maxTasks;
  687. #ifdef __PPU__
  688. BulletPE2ConstraintSolverSpursSupport* spursThread = (BulletPE2ConstraintSolverSpursSupport*) threadSupport;
  689. io[t].barrierAddr2 = (unsigned int)spursThread->getBarrierAddress();
  690. io[t].criticalsectionAddr2 = (unsigned int)spursThread->getCriticalSectionAddress();
  691. #endif
  692. #ifdef SOLVE_SEQUENTIAL
  693. CustomPostSolverTask( io[t].postSolver.states,io[t].postSolver.solverBodies, io[t].postSolver.numRigidBodies);
  694. #else
  695. threadSupport->sendRequest(1,(ppu_address_t)&io[t],t);
  696. #endif
  697. rest -= num;
  698. start += num;
  699. }
  700. unsigned int arg0,arg1;
  701. for(int t=0;t<maxTasks;t++) {
  702. #ifndef SOLVE_SEQUENTIAL
  703. arg0 = t;
  704. threadSupport->waitForResponse(&arg0,&arg1);
  705. #endif
  706. }
  707. }
  708. }
  709. void BPE_customConstraintSolverSequentialNew(unsigned int new_num, PfxBroadphasePair *new_pairs1 ,
  710. btPersistentManifold* offsetContactManifolds,
  711. TrbState* states,int numRigidBodies,
  712. struct PfxSolverBody* solverBodies,
  713. PfxConstraintPair* jointPairs, unsigned int numJoints,
  714. btSolverConstraint* offsetSolverConstraints,
  715. float separateBias,
  716. float timeStep,
  717. int iteration,
  718. btThreadSupportInterface* solverThreadSupport,
  719. btCriticalSection* criticalSection,
  720. struct btConstraintSolverIO* solverIO,
  721. btBarrier* barrier
  722. )
  723. {
  724. {
  725. BT_PROFILE("pfxSetupConstraints");
  726. for(uint32_t i=0;i<numJoints;i++) {
  727. // 情報の更新
  728. PfxConstraintPair &pair = jointPairs[i];
  729. int idA = pfxGetRigidBodyIdA(pair);
  730. if (idA != 65535)
  731. {
  732. pfxSetMotionMaskA(pair,states[pfxGetRigidBodyIdA(pair)].getMotionMask());
  733. }
  734. else
  735. {
  736. pfxSetMotionMaskA(pair,PFX_MOTION_MASK_STATIC);
  737. }
  738. int idB = pfxGetRigidBodyIdB(pair);
  739. if (idB!= 65535)
  740. {
  741. pfxSetMotionMaskB(pair,states[pfxGetRigidBodyIdB(pair)].getMotionMask());
  742. } else
  743. {
  744. pfxSetMotionMaskB(pair,PFX_MOTION_MASK_STATIC);
  745. }
  746. }
  747. // CustomSetupJointConstraintsSeq( jointPairs,numJoints,joints, states, solverBodies, numRigidBodies, timeStep);
  748. #ifdef SEQUENTIAL_SETUP
  749. CustomSetupContactConstraintsSeqNew(
  750. (PfxConstraintPair*)new_pairs1,new_num,contacts,
  751. states,
  752. solverBodies,
  753. numRigidBodies,
  754. separateBias,
  755. timeStep);
  756. #else
  757. CustomSetupContactConstraintsNew(
  758. (PfxConstraintPair*)new_pairs1,new_num,
  759. offsetContactManifolds,
  760. states,
  761. solverBodies,
  762. numRigidBodies,
  763. separateBias,
  764. timeStep,
  765. solverThreadSupport,
  766. criticalSection,solverIO
  767. );
  768. #endif //SEQUENTIAL_SETUP
  769. }
  770. {
  771. BT_PROFILE("pfxSolveConstraints");
  772. //#define SEQUENTIAL
  773. #ifdef SEQUENTIAL
  774. CustomSolveConstraintsSeq(
  775. (PfxConstraintPair*)new_pairs1,new_num,contacts,
  776. jointPairs,numJoints,
  777. states,
  778. solverBodies,
  779. numRigidBodies,
  780. separateBias,
  781. timeStep,
  782. iteration);
  783. #else //SEQUENTIAL
  784. CustomSolveConstraintsParallel(
  785. (PfxConstraintPair*)new_pairs1,new_num,
  786. jointPairs,numJoints,
  787. offsetContactManifolds,
  788. offsetSolverConstraints,
  789. states,
  790. solverBodies,
  791. numRigidBodies,
  792. solverIO, solverThreadSupport,
  793. iteration,
  794. tmp_buff,
  795. TMP_BUFF_BYTES,
  796. barrier
  797. );
  798. #endif //SEQUENTIAL
  799. }
  800. }
  801. struct btParallelSolverMemoryCache
  802. {
  803. btAlignedObjectArray<TrbState> m_mystates;
  804. btAlignedObjectArray<PfxSolverBody> m_mysolverbodies;
  805. btAlignedObjectArray<PfxBroadphasePair> m_mypairs;
  806. btAlignedObjectArray<PfxConstraintPair> m_jointPairs;
  807. };
  808. btConstraintSolverIO* createSolverIO(int numThreads)
  809. {
  810. return new btConstraintSolverIO[numThreads];
  811. }
  812. btParallelConstraintSolver::btParallelConstraintSolver(btThreadSupportInterface* solverThreadSupport)
  813. {
  814. m_solverThreadSupport = solverThreadSupport;//createSolverThreadSupport(maxNumThreads);
  815. m_solverIO = createSolverIO(m_solverThreadSupport->getNumTasks());
  816. m_barrier = m_solverThreadSupport->createBarrier();
  817. m_criticalSection = m_solverThreadSupport->createCriticalSection();
  818. m_memoryCache = new btParallelSolverMemoryCache();
  819. }
  820. btParallelConstraintSolver::~btParallelConstraintSolver()
  821. {
  822. delete m_memoryCache;
  823. delete m_solverIO;
  824. }
  825. btScalar btParallelConstraintSolver::solveGroup(btCollisionObject** bodies1,int numRigidBodies,btPersistentManifold** manifoldPtr,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher)
  826. {
  827. /* int sz = sizeof(PfxSolverBody);
  828. int sz2 = sizeof(vmVector3);
  829. int sz3 = sizeof(vmMatrix3);
  830. int sz4 = sizeof(vmQuat);
  831. int sz5 = sizeof(btConstraintRow);
  832. int sz6 = sizeof(btSolverConstraint);
  833. int sz7 = sizeof(TrbState);
  834. */
  835. btPersistentManifold* offsetContactManifolds= (btPersistentManifold*) dispatcher->getInternalManifoldPool()->getPoolAddress();
  836. m_memoryCache->m_mysolverbodies.resize(numRigidBodies);
  837. m_memoryCache->m_mystates.resize(numRigidBodies);
  838. {
  839. BT_PROFILE("create states and solver bodies");
  840. for (int i=0;i<numRigidBodies;i++)
  841. {
  842. btCollisionObject* obj = bodies1[i];
  843. obj->setCompanionId(i);
  844. PfxSolverBody& solverBody = m_memoryCache->m_mysolverbodies[i];
  845. btRigidBody* rb = btRigidBody::upcast(obj);
  846. TrbState& state = m_memoryCache->m_mystates[i];
  847. state.reset();
  848. const btQuaternion& orgOri = obj->getWorldTransform().getRotation();
  849. vmQuat orn(orgOri.getX(),orgOri.getY(),orgOri.getZ(),orgOri.getW());
  850. state.setPosition(getVmVector3(obj->getWorldTransform().getOrigin()));
  851. state.setOrientation(orn);
  852. state.setPosition(state.getPosition());
  853. state.setRigidBodyId(i);
  854. state.setAngularDamping(0);
  855. state.setLinearDamping(0);
  856. solverBody.mOrientation = state.getOrientation();
  857. solverBody.mDeltaLinearVelocity = vmVector3(0.0f);
  858. solverBody.mDeltaAngularVelocity = vmVector3(0.0f);
  859. solverBody.friction = obj->getFriction();
  860. solverBody.restitution = obj->getRestitution();
  861. state.resetSleepCount();
  862. //if(state.getMotionMask()&PFX_MOTION_MASK_DYNAMIC) {
  863. if (rb && (rb->getInvMass()>0.f))
  864. {
  865. state.setAngularVelocity(vmVector3(rb->getAngularVelocity().getX(),rb->getAngularVelocity().getY(),rb->getAngularVelocity().getZ()));
  866. state.setLinearVelocity(vmVector3(rb->getLinearVelocity().getX(),rb->getLinearVelocity().getY(),rb->getLinearVelocity().getZ()));
  867. state.setMotionType(PfxMotionTypeActive);
  868. vmMatrix3 ori(solverBody.mOrientation);
  869. vmMatrix3 localInvInertia = vmMatrix3::identity();
  870. localInvInertia.setCol(0,vmVector3(rb->getInvInertiaDiagLocal().getX(),0,0));
  871. localInvInertia.setCol(1,vmVector3(0, rb->getInvInertiaDiagLocal().getY(),0));
  872. localInvInertia.setCol(2,vmVector3(0,0, rb->getInvInertiaDiagLocal().getZ()));
  873. solverBody.mMassInv = rb->getInvMass();
  874. solverBody.mInertiaInv = ori * localInvInertia * transpose(ori);
  875. } else
  876. {
  877. state.setAngularVelocity(vmVector3(0));
  878. state.setLinearVelocity(vmVector3(0));
  879. state.setMotionType(PfxMotionTypeFixed);
  880. m_memoryCache->m_mysolverbodies[i].mMassInv = 0.f;
  881. m_memoryCache->m_mysolverbodies[i].mInertiaInv = vmMatrix3(0.0f);
  882. }
  883. }
  884. }
  885. int totalPoints = 0;
  886. #ifndef USE_C_ARRAYS
  887. m_memoryCache->m_mypairs.resize(numManifolds);
  888. m_memoryCache->m_jointPairs.resize(numConstraints);
  889. #endif//USE_C_ARRAYS
  890. int actualNumManifolds= 0;
  891. {
  892. BT_PROFILE("convert manifolds");
  893. for (int i1=0;i1<numManifolds;i1++)
  894. {
  895. if (manifoldPtr[i1]->getNumContacts()>0)
  896. {
  897. btPersistentManifold* m = manifoldPtr[i1];
  898. btCollisionObject* obA = (btCollisionObject*)m->getBody0();
  899. btCollisionObject* obB = (btCollisionObject*)m->getBody1();
  900. bool obAisActive = !obA->isStaticOrKinematicObject() && obA->isActive();
  901. bool obBisActive = !obB->isStaticOrKinematicObject() && obB->isActive();
  902. if (!obAisActive && !obBisActive)
  903. continue;
  904. //int contactId = i1;//actualNumManifolds;
  905. PfxBroadphasePair& pair = m_memoryCache->m_mypairs[actualNumManifolds];
  906. //init those
  907. float compFric = obA->getFriction()*obB->getFriction();//@todo
  908. int idA = obA->getCompanionId();
  909. int idB = obB->getCompanionId();
  910. m->m_companionIdA = idA;
  911. m->m_companionIdB = idB;
  912. // if ((mysolverbodies[idA].mMassInv!=0)&&(mysolverbodies[idB].mMassInv!=0))
  913. // continue;
  914. int numPosPoints=0;
  915. for (int p=0;p<m->getNumContacts();p++)
  916. {
  917. //btManifoldPoint& pt = m->getContactPoint(p);
  918. //float dist = pt.getDistance();
  919. //if (dist<0.001)
  920. numPosPoints++;
  921. }
  922. numPosPoints = numPosPoints;
  923. totalPoints+=numPosPoints;
  924. pfxSetRigidBodyIdA(pair,idA);
  925. pfxSetRigidBodyIdB(pair,idB);
  926. pfxSetMotionMaskA(pair,m_memoryCache->m_mystates[idA].getMotionMask());
  927. pfxSetMotionMaskB(pair,m_memoryCache->m_mystates[idB].getMotionMask());
  928. pfxSetActive(pair,numPosPoints>0);
  929. pfxSetBroadphaseFlag(pair,0);
  930. int contactId = m-offsetContactManifolds;
  931. //likely the contact pool is not contiguous, make sure to allocate large enough contact pool
  932. btAssert(contactId>=0);
  933. btAssert(contactId<dispatcher->getInternalManifoldPool()->getMaxCount());
  934. pfxSetContactId(pair,contactId);
  935. pfxSetNumConstraints(pair,numPosPoints);//manifoldPtr[i]->getNumContacts());
  936. actualNumManifolds++;
  937. }
  938. }
  939. }
  940. PfxConstraintPair* jointPairs=0;
  941. jointPairs = numConstraints? &m_memoryCache->m_jointPairs[0]:0;
  942. int actualNumJoints=0;
  943. btSolverConstraint* offsetSolverConstraints = 0;
  944. //if (1)
  945. {
  946. {
  947. BT_PROFILE("convert constraints");
  948. int totalNumRows = 0;
  949. int i;
  950. m_tmpConstraintSizesPool.resize(numConstraints);
  951. //calculate the total number of contraint rows
  952. for (i=0;i<numConstraints;i++)
  953. {
  954. btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
  955. constraints[i]->getInfo1(&info1);
  956. totalNumRows += info1.m_numConstraintRows;
  957. }
  958. m_tmpSolverNonContactConstraintPool.resize(totalNumRows);
  959. offsetSolverConstraints =totalNumRows? &m_tmpSolverNonContactConstraintPool[0]:0;
  960. ///setup the btSolverConstraints
  961. int currentRow = 0;
  962. for (i=0;i<numConstraints;i++)
  963. {
  964. const btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
  965. if (info1.m_numConstraintRows)
  966. {
  967. btAssert(currentRow<totalNumRows);
  968. btTypedConstraint* constraint = constraints[i];
  969. btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[currentRow];
  970. btRigidBody& rbA = constraint->getRigidBodyA();
  971. btRigidBody& rbB = constraint->getRigidBodyB();
  972. int j;
  973. for ( j=0;j<info1.m_numConstraintRows;j++)
  974. {
  975. memset(&currentConstraintRow[j],0,sizeof(btSolverConstraint));
  976. currentConstraintRow[j].m_lowerLimit = -FLT_MAX;
  977. currentConstraintRow[j].m_upperLimit = FLT_MAX;
  978. currentConstraintRow[j].m_appliedImpulse = 0.f;
  979. currentConstraintRow[j].m_appliedPushImpulse = 0.f;
  980. currentConstraintRow[j].m_solverBodyA = &rbA;
  981. currentConstraintRow[j].m_solverBodyB = &rbB;
  982. }
  983. rbA.internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
  984. rbA.internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
  985. rbB.internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
  986. rbB.internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
  987. btTypedConstraint::btConstraintInfo2 info2;
  988. info2.fps = 1.f/infoGlobal.m_timeStep;
  989. info2.erp = infoGlobal.m_erp;
  990. info2.m_J1linearAxis = currentConstraintRow->m_contactNormal;
  991. info2.m_J1angularAxis = currentConstraintRow->m_relpos1CrossNormal;
  992. info2.m_J2linearAxis = 0;
  993. info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal;
  994. info2.rowskip = sizeof(btSolverConstraint)/sizeof(btScalar);//check this
  995. ///the size of btSolverConstraint needs be a multiple of btScalar
  996. btAssert(info2.rowskip*sizeof(btScalar)== sizeof(btSolverConstraint));
  997. info2.m_constraintError = &currentConstraintRow->m_rhs;
  998. currentConstraintRow->m_cfm = infoGlobal.m_globalCfm;
  999. info2.cfm = &currentConstraintRow->m_cfm;
  1000. info2.m_lowerLimit = &currentConstraintRow->m_lowerLimit;
  1001. info2.m_upperLimit = &currentConstraintRow->m_upperLimit;
  1002. info2.m_numIterations = infoGlobal.m_numIterations;
  1003. constraints[i]->getInfo2(&info2);
  1004. int idA = constraint->getRigidBodyA().getCompanionId();
  1005. int idB = constraint->getRigidBodyB().getCompanionId();
  1006. ///finalize the constraint setup
  1007. for ( j=0;j<info1.m_numConstraintRows;j++)
  1008. {
  1009. btSolverConstraint& solverConstraint = currentConstraintRow[j];
  1010. solverConstraint.m_originalContactPoint = constraint;
  1011. solverConstraint.m_companionIdA = idA;
  1012. solverConstraint.m_companionIdB = idB;
  1013. {
  1014. const btVector3& ftorqueAxis1 = solverConstraint.m_relpos1CrossNormal;
  1015. solverConstraint.m_angularComponentA = constraint->getRigidBodyA().getInvInertiaTensorWorld()*ftorqueAxis1*constraint->getRigidBodyA().getAngularFactor();
  1016. }
  1017. {
  1018. const btVector3& ftorqueAxis2 = solverConstraint.m_relpos2CrossNormal;
  1019. solverConstraint.m_angularComponentB = constraint->getRigidBodyB().getInvInertiaTensorWorld()*ftorqueAxis2*constraint->getRigidBodyB().getAngularFactor();
  1020. }
  1021. {
  1022. btVector3 iMJlA = solverConstraint.m_contactNormal*rbA.getInvMass();
  1023. btVector3 iMJaA = rbA.getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal;
  1024. btVector3 iMJlB = solverConstraint.m_contactNormal*rbB.getInvMass();//sign of normal?
  1025. btVector3 iMJaB = rbB.getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal;
  1026. btScalar sum = iMJlA.dot(solverConstraint.m_contactNormal);
  1027. sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal);
  1028. sum += iMJlB.dot(solverConstraint.m_contactNormal);
  1029. sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal);
  1030. solverConstraint.m_jacDiagABInv = btScalar(1.)/sum;
  1031. }
  1032. ///fix rhs
  1033. ///todo: add force/torque accelerators
  1034. {
  1035. btScalar rel_vel;
  1036. btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(rbA.getLinearVelocity()) + solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity());
  1037. btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rbB.getLinearVelocity()) + solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity());
  1038. rel_vel = vel1Dotn+vel2Dotn;
  1039. btScalar restitution = 0.f;
  1040. btScalar positionalError = solverConstraint.m_rhs;//already filled in by getConstraintInfo2
  1041. btScalar velocityError = restitution - rel_vel;// * damping;
  1042. btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
  1043. btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
  1044. solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;
  1045. solverConstraint.m_appliedImpulse = 0.f;
  1046. }
  1047. }
  1048. PfxConstraintPair& pair = jointPairs[actualNumJoints];
  1049. int numConstraintRows= info1.m_numConstraintRows;
  1050. pfxSetNumConstraints(pair,numConstraintRows);
  1051. pfxSetRigidBodyIdA(pair,idA);
  1052. pfxSetRigidBodyIdB(pair,idB);
  1053. //is this needed?
  1054. if (idA>=0)
  1055. pfxSetMotionMaskA(pair,m_memoryCache->m_mystates[idA].getMotionMask());
  1056. if (idB>=0)
  1057. pfxSetMotionMaskB(pair,m_memoryCache->m_mystates[idB].getMotionMask());
  1058. pfxSetActive(pair,true);
  1059. int id = currentConstraintRow-offsetSolverConstraints;
  1060. pfxSetContactId(pair,id);
  1061. actualNumJoints++;
  1062. }
  1063. currentRow+=m_tmpConstraintSizesPool[i].m_numConstraintRows;
  1064. }
  1065. }
  1066. }
  1067. float separateBias=0.1;//info.m_erp;//or m_erp2?
  1068. float timeStep=infoGlobal.m_timeStep;
  1069. int iteration=infoGlobal.m_numIterations;
  1070. //create a pair for each constraints, copy over info etc
  1071. {
  1072. BT_PROFILE("compute num contacts");
  1073. int totalContacts =0;
  1074. for (int i=0;i<actualNumManifolds;i++)
  1075. {
  1076. PfxConstraintPair* pair = &m_memoryCache->m_mypairs[i];
  1077. totalContacts += pfxGetNumConstraints(*pair);
  1078. }
  1079. //printf("numManifolds = %d\n",numManifolds);
  1080. //printf("totalContacts=%d\n",totalContacts);
  1081. }
  1082. // printf("actualNumManifolds=%d\n",actualNumManifolds);
  1083. {
  1084. BT_PROFILE("BPE_customConstraintSolverSequentialNew");
  1085. if (numRigidBodies>0 && (actualNumManifolds+actualNumJoints)>0)
  1086. {
  1087. // PFX_PRINTF("num points = %d\n",totalPoints);
  1088. // PFX_PRINTF("num points PFX = %d\n",total);
  1089. BPE_customConstraintSolverSequentialNew(
  1090. actualNumManifolds,
  1091. &m_memoryCache->m_mypairs[0],
  1092. offsetContactManifolds,
  1093. &m_memoryCache->m_mystates[0],numRigidBodies,
  1094. &m_memoryCache->m_mysolverbodies[0],
  1095. jointPairs,actualNumJoints,
  1096. offsetSolverConstraints,
  1097. separateBias,timeStep,iteration,
  1098. m_solverThreadSupport,m_criticalSection,m_solverIO,m_barrier);
  1099. }
  1100. }
  1101. //copy results back to bodies
  1102. {
  1103. BT_PROFILE("copy back");
  1104. for (int i=0;i<numRigidBodies;i++)
  1105. {
  1106. btCollisionObject* obj = bodies1[i];
  1107. btRigidBody* rb = btRigidBody::upcast(obj);
  1108. TrbState& state = m_memoryCache->m_mystates[i];
  1109. if (rb && (rb->getInvMass()>0.f))
  1110. {
  1111. rb->setLinearVelocity(btVector3(state.getLinearVelocity().getX(),state.getLinearVelocity().getY(),state.getLinearVelocity().getZ()));
  1112. rb->setAngularVelocity(btVector3(state.getAngularVelocity().getX(),state.getAngularVelocity().getY(),state.getAngularVelocity().getZ()));
  1113. }
  1114. }
  1115. }
  1116. return 0.f;
  1117. }