|
Bullet Collision Detection & Physics Library
|
00001 /* 00002 Copyright (C) 2010 Sony Computer Entertainment Inc. 00003 All rights reserved. 00004 00005 This software is provided 'as-is', without any express or implied warranty. 00006 In no event will the authors be held liable for any damages arising from the use of this software. 00007 Permission is granted to anyone to use this software for any purpose, 00008 including commercial applications, and to alter it and redistribute it freely, 00009 subject to the following restrictions: 00010 00011 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. 00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 00013 3. This notice may not be removed or altered from any source distribution. 00014 00015 */ 00016 00017 00018 #include "btParallelConstraintSolver.h" 00019 #include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" 00020 #include "BulletCollision/BroadphaseCollision/btDispatcher.h" 00021 #include "LinearMath/btPoolAllocator.h" 00022 00023 #include "BulletMultiThreaded/vectormath2bullet.h" 00024 00025 #include "LinearMath/btQuickprof.h" 00026 #include "BulletMultiThreaded/btThreadSupportInterface.h" 00027 #ifdef PFX_USE_FREE_VECTORMATH 00028 #include "vecmath/vmInclude.h" 00029 #else 00030 #include "vectormath/vmInclude.h" 00031 #endif //PFX_USE_FREE_VECTORMATH 00032 00033 #include "HeapManager.h" 00034 00035 #include "PlatformDefinitions.h" 00036 00037 //#include "PfxSimdUtils.h" 00038 #include "LinearMath/btScalar.h" 00039 00040 #include "TrbStateVec.h" 00041 00042 00043 00045 00046 00047 #define TMP_BUFF_BYTES (15*1024*1024) 00048 unsigned char ATTRIBUTE_ALIGNED128(tmp_buff[TMP_BUFF_BYTES]); 00049 00050 00051 00052 // Project Gauss Seidel or the equivalent Sequential Impulse 00053 inline void resolveSingleConstraintRowGeneric(PfxSolverBody& body1,PfxSolverBody& body2,const btSolverConstraint& c) 00054 { 00055 00056 btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm; 00057 const btScalar deltaVel1Dotn = c.m_contactNormal.dot(getBtVector3(body1.mDeltaLinearVelocity)) + c.m_relpos1CrossNormal.dot(getBtVector3(body1.mDeltaAngularVelocity)); 00058 const btScalar deltaVel2Dotn = -c.m_contactNormal.dot(getBtVector3(body2.mDeltaLinearVelocity)) + c.m_relpos2CrossNormal.dot(getBtVector3(body2.mDeltaAngularVelocity)); 00059 00060 // const btScalar delta_rel_vel = deltaVel1Dotn-deltaVel2Dotn; 00061 deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv; 00062 deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv; 00063 00064 const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse; 00065 if (sum < c.m_lowerLimit) 00066 { 00067 deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse; 00068 c.m_appliedImpulse = c.m_lowerLimit; 00069 } 00070 else if (sum > c.m_upperLimit) 00071 { 00072 deltaImpulse = c.m_upperLimit-c.m_appliedImpulse; 00073 c.m_appliedImpulse = c.m_upperLimit; 00074 } 00075 else 00076 { 00077 c.m_appliedImpulse = sum; 00078 } 00079 00080 00081 if (body1.mMassInv) 00082 { 00083 btVector3 linearComponent = c.m_contactNormal*body1.mMassInv; 00084 body1.mDeltaLinearVelocity += vmVector3(linearComponent.getX()*deltaImpulse,linearComponent.getY()*deltaImpulse,linearComponent.getZ()*deltaImpulse); 00085 btVector3 tmp=c.m_angularComponentA*(btVector3(deltaImpulse,deltaImpulse,deltaImpulse)); 00086 body1.mDeltaAngularVelocity += vmVector3(tmp.getX(),tmp.getY(),tmp.getZ()); 00087 } 00088 00089 if (body2.mMassInv) 00090 { 00091 btVector3 linearComponent = -c.m_contactNormal*body2.mMassInv; 00092 body2.mDeltaLinearVelocity += vmVector3(linearComponent.getX()*deltaImpulse,linearComponent.getY()*deltaImpulse,linearComponent.getZ()*deltaImpulse); 00093 btVector3 tmp = c.m_angularComponentB*((btVector3(deltaImpulse,deltaImpulse,deltaImpulse)));//*m_angularFactor); 00094 body2.mDeltaAngularVelocity += vmVector3(tmp.getX(),tmp.getY(),tmp.getZ()); 00095 } 00096 00097 //body1.internalApplyImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse); 00098 //body2.internalApplyImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse); 00099 00100 } 00101 00102 00103 static SIMD_FORCE_INLINE 00104 void pfxSolveLinearConstraintRow(btConstraintRow &constraint, 00105 vmVector3 &deltaLinearVelocityA,vmVector3 &deltaAngularVelocityA, 00106 float massInvA,const vmMatrix3 &inertiaInvA,const vmVector3 &rA, 00107 vmVector3 &deltaLinearVelocityB,vmVector3 &deltaAngularVelocityB, 00108 float massInvB,const vmMatrix3 &inertiaInvB,const vmVector3 &rB) 00109 { 00110 const vmVector3 normal(btReadVector3(constraint.m_normal)); 00111 btScalar deltaImpulse = constraint.m_rhs; 00112 vmVector3 dVA = deltaLinearVelocityA + cross(deltaAngularVelocityA,rA); 00113 vmVector3 dVB = deltaLinearVelocityB + cross(deltaAngularVelocityB,rB); 00114 deltaImpulse -= constraint.m_jacDiagInv * dot(normal,dVA-dVB); 00115 btScalar oldImpulse = constraint.m_accumImpulse; 00116 constraint.m_accumImpulse = btClamped(oldImpulse + deltaImpulse,constraint.m_lowerLimit,constraint.m_upperLimit); 00117 deltaImpulse = constraint.m_accumImpulse - oldImpulse; 00118 deltaLinearVelocityA += deltaImpulse * massInvA * normal; 00119 deltaAngularVelocityA += deltaImpulse * inertiaInvA * cross(rA,normal); 00120 deltaLinearVelocityB -= deltaImpulse * massInvB * normal; 00121 deltaAngularVelocityB -= deltaImpulse * inertiaInvB * cross(rB,normal); 00122 00123 } 00124 00125 void btSolveContactConstraint( 00126 btConstraintRow &constraintResponse, 00127 btConstraintRow &constraintFriction1, 00128 btConstraintRow &constraintFriction2, 00129 const vmVector3 &contactPointA, 00130 const vmVector3 &contactPointB, 00131 PfxSolverBody &solverBodyA, 00132 PfxSolverBody &solverBodyB, 00133 float friction 00134 ) 00135 { 00136 vmVector3 rA = rotate(solverBodyA.mOrientation,contactPointA); 00137 vmVector3 rB = rotate(solverBodyB.mOrientation,contactPointB); 00138 00139 pfxSolveLinearConstraintRow(constraintResponse, 00140 solverBodyA.mDeltaLinearVelocity,solverBodyA.mDeltaAngularVelocity,solverBodyA.mMassInv,solverBodyA.mInertiaInv,rA, 00141 solverBodyB.mDeltaLinearVelocity,solverBodyB.mDeltaAngularVelocity,solverBodyB.mMassInv,solverBodyB.mInertiaInv,rB); 00142 00143 float mf = friction*fabsf(constraintResponse.m_accumImpulse); 00144 constraintFriction1.m_lowerLimit = -mf; 00145 constraintFriction1.m_upperLimit = mf; 00146 constraintFriction2.m_lowerLimit = -mf; 00147 constraintFriction2.m_upperLimit = mf; 00148 00149 pfxSolveLinearConstraintRow(constraintFriction1, 00150 solverBodyA.mDeltaLinearVelocity,solverBodyA.mDeltaAngularVelocity,solverBodyA.mMassInv,solverBodyA.mInertiaInv,rA, 00151 solverBodyB.mDeltaLinearVelocity,solverBodyB.mDeltaAngularVelocity,solverBodyB.mMassInv,solverBodyB.mInertiaInv,rB); 00152 00153 pfxSolveLinearConstraintRow(constraintFriction2, 00154 solverBodyA.mDeltaLinearVelocity,solverBodyA.mDeltaAngularVelocity,solverBodyA.mMassInv,solverBodyA.mInertiaInv,rA, 00155 solverBodyB.mDeltaLinearVelocity,solverBodyB.mDeltaAngularVelocity,solverBodyB.mMassInv,solverBodyB.mInertiaInv,rB); 00156 } 00157 00158 00159 void CustomSolveConstraintsTaskParallel( 00160 const PfxParallelGroup *contactParallelGroup,const PfxParallelBatch *contactParallelBatches, 00161 PfxConstraintPair *contactPairs,uint32_t numContactPairs, 00162 btPersistentManifold* offsetContactManifolds, 00163 const PfxParallelGroup *jointParallelGroup,const PfxParallelBatch *jointParallelBatches, 00164 PfxConstraintPair *jointPairs,uint32_t numJointPairs, 00165 btSolverConstraint* offsetSolverConstraints, 00166 TrbState *offsetRigStates, 00167 PfxSolverBody *offsetSolverBodies, 00168 uint32_t numRigidBodies, 00169 int iteration,unsigned int taskId,unsigned int numTasks,btBarrier *barrier) 00170 { 00171 00172 PfxSolverBody staticBody; 00173 staticBody.mMassInv = 0.f; 00174 staticBody.mDeltaAngularVelocity=vmVector3(0,0,0); 00175 staticBody.mDeltaLinearVelocity =vmVector3(0,0,0); 00176 00177 00178 for(int k=0;k<iteration+1;k++) { 00179 // Joint 00180 for(uint32_t phaseId=0;phaseId<jointParallelGroup->numPhases;phaseId++) { 00181 for(uint32_t batchId=0;batchId<jointParallelGroup->numBatches[phaseId];batchId++) { 00182 uint32_t numPairs = jointParallelGroup->numPairs[phaseId*PFX_MAX_SOLVER_BATCHES+batchId]; 00183 if(batchId%numTasks == taskId && numPairs > 0) { 00184 const PfxParallelBatch &batch = jointParallelBatches[phaseId*PFX_MAX_SOLVER_BATCHES+batchId]; 00185 for(uint32_t i=0;i<numPairs;i++) { 00186 PfxConstraintPair &pair = jointPairs[batch.pairIndices[i]]; 00187 uint16_t iA = pfxGetRigidBodyIdA(pair); 00188 uint16_t iB = pfxGetRigidBodyIdB(pair); 00189 00190 00191 PfxSolverBody &solverBodyA = iA != 65535 ? offsetSolverBodies[iA] : staticBody; 00192 PfxSolverBody &solverBodyB = iB != 65535 ? offsetSolverBodies[iB] : staticBody; 00193 00194 if(k==0) { 00195 00196 } 00197 else { 00198 btSolverConstraint* constraintRow = &offsetSolverConstraints[pfxGetContactId1(pair)]; 00199 int numRows = pfxGetNumConstraints(pair); 00200 int i; 00201 for (i=0;i<numRows;i++) 00202 { 00203 resolveSingleConstraintRowGeneric(solverBodyA,solverBodyB,constraintRow[i]); 00204 } 00205 00206 } 00207 } 00208 } 00209 } 00210 00211 barrier->sync(); 00212 } 00213 00214 // Contact 00215 for(uint32_t phaseId=0;phaseId<contactParallelGroup->numPhases;phaseId++) { 00216 for(uint32_t batchId=0;batchId<contactParallelGroup->numBatches[phaseId];batchId++) { 00217 uint32_t numPairs = contactParallelGroup->numPairs[phaseId*PFX_MAX_SOLVER_BATCHES+batchId]; 00218 if(batchId%numTasks == taskId && numPairs > 0) { 00219 const PfxParallelBatch &batch = contactParallelBatches[phaseId*PFX_MAX_SOLVER_BATCHES+batchId]; 00220 for(uint32_t i=0;i<numPairs;i++) { 00221 PfxConstraintPair &pair = contactPairs[batch.pairIndices[i]]; 00222 uint16_t iA = pfxGetRigidBodyIdA(pair); 00223 uint16_t iB = pfxGetRigidBodyIdB(pair); 00224 00225 btPersistentManifold& contact = offsetContactManifolds[pfxGetConstraintId1(pair)]; 00226 00227 00228 PfxSolverBody &solverBodyA = offsetSolverBodies[iA]; 00229 PfxSolverBody &solverBodyB = offsetSolverBodies[iB]; 00230 00231 for(int j=0;j<contact.getNumContacts();j++) { 00232 btManifoldPoint& cp = contact.getContactPoint(j); 00233 00234 if(k==0) { 00235 vmVector3 rA = rotate(solverBodyA.mOrientation,btReadVector3(cp.m_localPointA)); 00236 vmVector3 rB = rotate(solverBodyB.mOrientation,btReadVector3(cp.m_localPointB)); 00237 00238 for(int k=0;k<3;k++) { 00239 vmVector3 normal = btReadVector3(cp.mConstraintRow[k].m_normal); 00240 float deltaImpulse = cp.mConstraintRow[k].m_accumImpulse; 00241 solverBodyA.mDeltaLinearVelocity += deltaImpulse * solverBodyA.mMassInv * normal; 00242 solverBodyA.mDeltaAngularVelocity += deltaImpulse * solverBodyA.mInertiaInv * cross(rA,normal); 00243 solverBodyB.mDeltaLinearVelocity -= deltaImpulse * solverBodyB.mMassInv * normal; 00244 solverBodyB.mDeltaAngularVelocity -= deltaImpulse * solverBodyB.mInertiaInv * cross(rB,normal); 00245 } 00246 } 00247 else { 00248 btSolveContactConstraint( 00249 cp.mConstraintRow[0], 00250 cp.mConstraintRow[1], 00251 cp.mConstraintRow[2], 00252 btReadVector3(cp.m_localPointA), 00253 btReadVector3(cp.m_localPointB), 00254 solverBodyA, 00255 solverBodyB, 00256 cp.m_combinedFriction 00257 ); 00258 } 00259 } 00260 } 00261 } 00262 } 00263 00264 if (barrier) 00265 barrier->sync(); 00266 } 00267 } 00268 } 00269 00270 void CustomPostSolverTask( 00271 TrbState *states, 00272 PfxSolverBody *solverBodies, 00273 uint32_t numRigidBodies) 00274 { 00275 for(uint32_t i=0;i<numRigidBodies;i++) { 00276 TrbState &state = states[i]; 00277 PfxSolverBody &solverBody = solverBodies[i]; 00278 state.setLinearVelocity(state.getLinearVelocity()+solverBody.mDeltaLinearVelocity); 00279 state.setAngularVelocity(state.getAngularVelocity()+solverBody.mDeltaAngularVelocity); 00280 } 00281 } 00282 00283 void* SolverlsMemoryFunc() 00284 { 00285 //don't create local store memory, just return 0 00286 return 0; 00287 } 00288 00289 00290 static SIMD_FORCE_INLINE 00291 void pfxGetPlaneSpace(const vmVector3& n, vmVector3& p, vmVector3& q) 00292 { 00293 if(fabsf(n[2]) > 0.707f) { 00294 // choose p in y-z plane 00295 float a = n[1]*n[1] + n[2]*n[2]; 00296 float k = 1.0f/sqrtf(a); 00297 p[0] = 0; 00298 p[1] = -n[2]*k; 00299 p[2] = n[1]*k; 00300 // set q = n x p 00301 q[0] = a*k; 00302 q[1] = -n[0]*p[2]; 00303 q[2] = n[0]*p[1]; 00304 } 00305 else { 00306 // choose p in x-y plane 00307 float a = n[0]*n[0] + n[1]*n[1]; 00308 float k = 1.0f/sqrtf(a); 00309 p[0] = -n[1]*k; 00310 p[1] = n[0]*k; 00311 p[2] = 0; 00312 // set q = n x p 00313 q[0] = -n[2]*p[1]; 00314 q[1] = n[2]*p[0]; 00315 q[2] = a*k; 00316 } 00317 } 00318 00319 00320 00321 #define PFX_CONTACT_SLOP 0.001f 00322 00323 void btSetupContactConstraint( 00324 btConstraintRow &constraintResponse, 00325 btConstraintRow &constraintFriction1, 00326 btConstraintRow &constraintFriction2, 00327 float penetrationDepth, 00328 float restitution, 00329 float friction, 00330 const vmVector3 &contactNormal, 00331 const vmVector3 &contactPointA, 00332 const vmVector3 &contactPointB, 00333 const TrbState &stateA, 00334 const TrbState &stateB, 00335 PfxSolverBody &solverBodyA, 00336 PfxSolverBody &solverBodyB, 00337 float separateBias, 00338 float timeStep 00339 ) 00340 { 00341 vmVector3 rA = rotate(solverBodyA.mOrientation,contactPointA); 00342 vmVector3 rB = rotate(solverBodyB.mOrientation,contactPointB); 00343 00344 vmMatrix3 K = vmMatrix3::scale(vmVector3(solverBodyA.mMassInv + solverBodyB.mMassInv)) - 00345 crossMatrix(rA) * solverBodyA.mInertiaInv * crossMatrix(rA) - 00346 crossMatrix(rB) * solverBodyB.mInertiaInv * crossMatrix(rB); 00347 00348 vmVector3 vA = stateA.getLinearVelocity() + cross(stateA.getAngularVelocity(),rA); 00349 vmVector3 vB = stateB.getLinearVelocity() + cross(stateB.getAngularVelocity(),rB); 00350 vmVector3 vAB = vA-vB; 00351 00352 vmVector3 tangent1,tangent2; 00353 btPlaneSpace1(contactNormal,tangent1,tangent2); 00354 00355 // constraintResponse.m_accumImpulse = 0.f; 00356 // constraintFriction1.m_accumImpulse = 0.f; 00357 // constraintFriction2.m_accumImpulse = 0.f; 00358 00359 // Contact Constraint 00360 { 00361 vmVector3 normal = contactNormal; 00362 00363 float denom = dot(K*normal,normal); 00364 00365 constraintResponse.m_rhs = -(1.0f+restitution)*dot(vAB,normal); // velocity error 00366 constraintResponse.m_rhs -= (separateBias * btMin(0.0f,penetrationDepth+PFX_CONTACT_SLOP)) / timeStep; // position error 00367 constraintResponse.m_rhs /= denom; 00368 constraintResponse.m_jacDiagInv = 1.0f/denom; 00369 constraintResponse.m_lowerLimit = 0.0f; 00370 constraintResponse.m_upperLimit = SIMD_INFINITY; 00371 btStoreVector3(normal,constraintResponse.m_normal); 00372 } 00373 00374 // Friction Constraint 1 00375 { 00376 vmVector3 normal = tangent1; 00377 00378 float denom = dot(K*normal,normal); 00379 00380 constraintFriction1.m_jacDiagInv = 1.0f/denom; 00381 constraintFriction1.m_rhs = -dot(vAB,normal); 00382 constraintFriction1.m_rhs *= constraintFriction1.m_jacDiagInv; 00383 constraintFriction1.m_lowerLimit = 0.0f; 00384 constraintFriction1.m_upperLimit = SIMD_INFINITY; 00385 btStoreVector3(normal,constraintFriction1.m_normal); 00386 } 00387 00388 // Friction Constraint 2 00389 { 00390 vmVector3 normal = tangent2; 00391 00392 float denom = dot(K*normal,normal); 00393 00394 constraintFriction2.m_jacDiagInv = 1.0f/denom; 00395 constraintFriction2.m_rhs = -dot(vAB,normal); 00396 constraintFriction2.m_rhs *= constraintFriction2.m_jacDiagInv; 00397 constraintFriction2.m_lowerLimit = 0.0f; 00398 constraintFriction2.m_upperLimit = SIMD_INFINITY; 00399 btStoreVector3(normal,constraintFriction2.m_normal); 00400 } 00401 } 00402 00403 00404 void CustomSetupContactConstraintsTask( 00405 PfxConstraintPair *contactPairs,uint32_t numContactPairs, 00406 btPersistentManifold* offsetContactManifolds, 00407 TrbState *offsetRigStates, 00408 PfxSolverBody *offsetSolverBodies, 00409 uint32_t numRigidBodies, 00410 float separateBias, 00411 float timeStep) 00412 { 00413 for(uint32_t i=0;i<numContactPairs;i++) { 00414 PfxConstraintPair &pair = contactPairs[i]; 00415 if(!pfxGetActive(pair) || pfxGetNumConstraints(pair) == 0 || 00416 ((pfxGetMotionMaskA(pair)&PFX_MOTION_MASK_STATIC) && (pfxGetMotionMaskB(pair)&PFX_MOTION_MASK_STATIC)) ) { 00417 continue; 00418 } 00419 00420 uint16_t iA = pfxGetRigidBodyIdA(pair); 00421 uint16_t iB = pfxGetRigidBodyIdB(pair); 00422 00423 int id = pfxGetConstraintId1(pair); 00424 btPersistentManifold& contact = offsetContactManifolds[id]; 00425 00426 00427 TrbState &stateA = offsetRigStates[iA]; 00428 // PfxRigBody &bodyA = offsetRigBodies[iA]; 00429 PfxSolverBody &solverBodyA = offsetSolverBodies[iA]; 00430 00431 TrbState &stateB = offsetRigStates[iB]; 00432 // PfxRigBody &bodyB = offsetRigBodies[iB]; 00433 PfxSolverBody &solverBodyB = offsetSolverBodies[iB]; 00434 00435 float restitution = 0.5f * (solverBodyA.restitution + solverBodyB.restitution); 00436 //if(contact.getDuration() > 1) restitution = 0.0f; 00437 00438 float friction = sqrtf(solverBodyA.friction * solverBodyB.friction); 00439 00440 for(int j=0;j<contact.getNumContacts();j++) { 00441 btManifoldPoint& cp = contact.getContactPoint(j); 00442 00443 btSetupContactConstraint( 00444 cp.mConstraintRow[0], 00445 cp.mConstraintRow[1], 00446 cp.mConstraintRow[2], 00447 cp.getDistance(), 00448 restitution, 00449 friction, 00450 btReadVector3(cp.m_normalWorldOnB),//.mConstraintRow[0].m_normal), 00451 btReadVector3(cp.m_localPointA), 00452 btReadVector3(cp.m_localPointB), 00453 stateA, 00454 stateB, 00455 solverBodyA, 00456 solverBodyB, 00457 separateBias, 00458 timeStep 00459 ); 00460 } 00461 00462 //contact.setCompositeFriction(friction); 00463 } 00464 } 00465 00466 void SolverThreadFunc(void* userPtr,void* lsMemory) 00467 { 00468 btConstraintSolverIO* io = (btConstraintSolverIO*)(userPtr);//arg->io); 00469 btCriticalSection* criticalsection = io->setupContactConstraints.criticalSection; 00470 00471 00472 //CustomCriticalSection *criticalsection = &io->m_cs; 00473 switch(io->cmd) { 00474 00475 case PFX_CONSTRAINT_SOLVER_CMD_SOLVE_CONSTRAINTS: 00476 CustomSolveConstraintsTaskParallel( 00477 io->solveConstraints.contactParallelGroup, 00478 io->solveConstraints.contactParallelBatches, 00479 io->solveConstraints.contactPairs, 00480 io->solveConstraints.numContactPairs, 00481 io->solveConstraints.offsetContactManifolds, 00482 00483 io->solveConstraints.jointParallelGroup, 00484 io->solveConstraints.jointParallelBatches, 00485 io->solveConstraints.jointPairs, 00486 io->solveConstraints.numJointPairs, 00487 io->solveConstraints.offsetSolverConstraints, 00488 io->solveConstraints.offsetRigStates1, 00489 io->solveConstraints.offsetSolverBodies, 00490 io->solveConstraints.numRigidBodies, 00491 io->solveConstraints.iteration, 00492 00493 io->solveConstraints.taskId, 00494 io->maxTasks1, 00495 io->solveConstraints.barrier 00496 ); 00497 break; 00498 00499 case PFX_CONSTRAINT_SOLVER_CMD_POST_SOLVER: 00500 CustomPostSolverTask( io->postSolver.states,io->postSolver.solverBodies, io->postSolver.numRigidBodies); 00501 break; 00502 00503 00504 case PFX_CONSTRAINT_SOLVER_CMD_SETUP_CONTACT_CONSTRAINTS: 00505 { 00506 bool empty = false; 00507 while(!empty) { 00508 int start,batch; 00509 00510 criticalsection->lock(); 00511 00512 start = (int)criticalsection->getSharedParam(0); 00513 batch = (int)criticalsection->getSharedParam(1); 00514 00515 //PFX_PRINTF("taskId %d start %d num %d\n",arg->taskId,start,batch); 00516 00517 // ŽŸ‚̃oƒbƒtƒ@‚ðƒZƒbƒg 00518 int nextStart = start + batch; 00519 int rest = btMax((int)io->setupContactConstraints.numContactPairs1 - nextStart,0); 00520 int nextBatch = (rest > batch)?batch:rest; 00521 00522 criticalsection->setSharedParam(0,nextStart); 00523 criticalsection->setSharedParam(1,nextBatch); 00524 00525 criticalsection->unlock(); 00526 00527 if(batch > 0) { 00528 CustomSetupContactConstraintsTask( 00529 io->setupContactConstraints.offsetContactPairs+start,batch, 00530 io->setupContactConstraints.offsetContactManifolds, 00531 io->setupContactConstraints.offsetRigStates, 00532 // io->setupContactConstraints.offsetRigBodies, 00533 io->setupContactConstraints.offsetSolverBodies, 00534 io->setupContactConstraints.numRigidBodies, 00535 io->setupContactConstraints.separateBias, 00536 io->setupContactConstraints.timeStep); 00537 } 00538 else { 00539 empty = true; 00540 } 00541 } 00542 } 00543 break; 00544 00545 default: 00546 { 00547 btAssert(0); 00548 } 00549 } 00550 00551 } 00552 00553 00554 void CustomSetupContactConstraintsNew( 00555 PfxConstraintPair *contactPairs1,uint32_t numContactPairs, 00556 btPersistentManifold *offsetContactManifolds, 00557 TrbState *offsetRigStates, 00558 PfxSolverBody *offsetSolverBodies, 00559 uint32_t numRigidBodies, 00560 float separationBias, 00561 float timeStep, 00562 class btThreadSupportInterface* threadSupport, 00563 btCriticalSection* criticalSection, 00564 btConstraintSolverIO *io 00565 ) 00566 { 00567 int maxTasks = threadSupport->getNumTasks(); 00568 00569 int div = (int)maxTasks * 4; 00570 int batch = ((int)numContactPairs + div - 1) / div; 00571 #ifdef __PPU__ 00572 BulletPE2ConstraintSolverSpursSupport* spursThread = (BulletPE2ConstraintSolverSpursSupport*) threadSupport; 00573 #endif 00574 if (criticalSection) 00575 { 00576 criticalSection->setSharedParam(0,0); 00577 criticalSection->setSharedParam(1,btMin(batch,64)); // batched number 00578 } else 00579 { 00580 #ifdef __PPU__ 00581 spursThread->setSharedParam(0,0); 00582 spursThread->setSharedParam(1,btMin(batch,64)); // batched number 00583 #endif //__PPU__ 00584 } 00585 00586 for(int t=0;t<maxTasks;t++) { 00587 io[t].cmd = PFX_CONSTRAINT_SOLVER_CMD_SETUP_CONTACT_CONSTRAINTS; 00588 io[t].setupContactConstraints.offsetContactPairs = contactPairs1; 00589 io[t].setupContactConstraints.numContactPairs1 = numContactPairs; 00590 io[t].setupContactConstraints.offsetRigStates = offsetRigStates; 00591 io[t].setupContactConstraints.offsetContactManifolds = offsetContactManifolds; 00592 io[t].setupContactConstraints.offsetSolverBodies = offsetSolverBodies; 00593 io[t].setupContactConstraints.numRigidBodies = numRigidBodies; 00594 io[t].setupContactConstraints.separateBias = separationBias; 00595 io[t].setupContactConstraints.timeStep = timeStep; 00596 io[t].setupContactConstraints.criticalSection = criticalSection; 00597 io[t].maxTasks1 = maxTasks; 00598 #ifdef __PPU__ 00599 io[t].barrierAddr2 = (unsigned int)spursThread->getBarrierAddress(); 00600 io[t].criticalsectionAddr2 = (unsigned int)spursThread->getCriticalSectionAddress(); 00601 #endif 00602 00603 00604 //#define SEQUENTIAL_SETUP 00605 #ifdef SEQUENTIAL_SETUP 00606 CustomSetupContactConstraintsTask(contactPairs1,numContactPairs,offsetContactManifolds,offsetRigStates,offsetSolverBodies,numRigidBodies,separationBias,timeStep); 00607 #else 00608 threadSupport->sendRequest(1,(ppu_address_t)&io[t],t); 00609 #endif 00610 00611 } 00612 #ifndef SEQUENTIAL_SETUP 00613 unsigned int arg0,arg1; 00614 for(int t=0;t<maxTasks;t++) { 00615 arg0 = t; 00616 threadSupport->waitForResponse(&arg0,&arg1); 00617 } 00618 #endif //SEQUENTIAL_SETUP 00619 00620 } 00621 00622 00623 void CustomSplitConstraints( 00624 PfxConstraintPair *pairs,uint32_t numPairs, 00625 PfxParallelGroup &group,PfxParallelBatch *batches, 00626 uint32_t numTasks, 00627 uint32_t numRigidBodies, 00628 void *poolBuff, 00629 uint32_t poolBytes 00630 ) 00631 { 00632 HeapManager pool((unsigned char*)poolBuff,poolBytes); 00633 00634 // ƒXƒe[ƒgƒ`ƒFƒbƒN—pƒrƒbƒgƒtƒ‰ƒOƒe[ƒuƒ‹ 00635 int bufSize = sizeof(uint8_t)*numRigidBodies; 00636 bufSize = ((bufSize+127)>>7)<<7; // 128 bytes alignment 00637 uint8_t *bodyTable = (uint8_t*)pool.allocate(bufSize,HeapManager::ALIGN128); 00638 00639 // ƒyƒAƒ`ƒFƒbƒN—pƒrƒbƒgƒtƒ‰ƒOƒe[ƒuƒ‹ 00640 uint32_t *pairTable; 00641 size_t allocSize = sizeof(uint32_t)*((numPairs+31)/32); 00642 pairTable = (uint32_t*)pool.allocate(allocSize); 00643 memset(pairTable,0,allocSize); 00644 00645 // –Ú•W‚Æ‚·‚é•ªŠ„” 00646 uint32_t targetCount = btMax(uint32_t(PFX_MIN_SOLVER_PAIRS),btMin(numPairs / (numTasks*2),uint32_t(PFX_MAX_SOLVER_PAIRS))); 00647 uint32_t startIndex = 0; 00648 00649 uint32_t phaseId; 00650 uint32_t batchId; 00651 uint32_t totalCount=0; 00652 00653 uint32_t maxBatches = btMin(numTasks,uint32_t(PFX_MAX_SOLVER_BATCHES)); 00654 00655 for(phaseId=0;phaseId<PFX_MAX_SOLVER_PHASES&&totalCount<numPairs;phaseId++) { 00656 bool startIndexCheck = true; 00657 00658 group.numBatches[phaseId] = 0; 00659 00660 uint32_t i = startIndex; 00661 00662 // ƒ`ƒFƒbƒN—pƒrƒbƒgƒtƒ‰ƒOƒe[ƒuƒ‹‚ðƒNƒŠƒA 00663 memset(bodyTable,0xff,bufSize); 00664 00665 for(batchId=0;i<numPairs&&totalCount<numPairs&&batchId<maxBatches;batchId++) { 00666 uint32_t pairCount=0; 00667 00668 PfxParallelBatch &batch = batches[phaseId*PFX_MAX_SOLVER_BATCHES+batchId]; 00669 uint32_t pairId = 0; 00670 00671 for(;i<numPairs&&pairCount<targetCount;i++) { 00672 uint32_t idxP = i>>5; 00673 uint32_t maskP = 1L << (i & 31); 00674 00675 //pair is already assigned to a phase/batch 00676 if(pairTable[idxP] & maskP) { 00677 continue; 00678 } 00679 00680 uint32_t idxA = pfxGetRigidBodyIdA(pairs[i]); 00681 uint32_t idxB = pfxGetRigidBodyIdB(pairs[i]); 00682 00683 // —¼•û‚Æ‚àƒAƒNƒeƒBƒu‚łȂ¢A‚Ü‚½‚ÍÕ“Ë“_‚ª‚O‚̃yƒA‚Í“o˜^‘ÎÛ‚©‚ç‚Í‚¸‚· 00684 if(!pfxGetActive(pairs[i]) || pfxGetNumConstraints(pairs[i]) == 0 || 00685 ((pfxGetMotionMaskA(pairs[i])&PFX_MOTION_MASK_STATIC) && (pfxGetMotionMaskB(pairs[i])&PFX_MOTION_MASK_STATIC)) ) { 00686 if(startIndexCheck) 00687 startIndex++; 00688 //assign pair -> skip it because it has no constraints 00689 pairTable[idxP] |= maskP; 00690 totalCount++; 00691 continue; 00692 } 00693 00694 // ˆË‘¶«‚̃`ƒFƒbƒN 00695 if( (bodyTable[idxA] != batchId && bodyTable[idxA] != 0xff) || 00696 (bodyTable[idxB] != batchId && bodyTable[idxB] != 0xff) ) { 00697 startIndexCheck = false; 00698 //bodies of the pair are already assigned to another batch within this phase 00699 continue; 00700 } 00701 00702 // ˆË‘¶«”»’èƒe[ƒuƒ‹‚É“o˜^ 00703 if(pfxGetMotionMaskA(pairs[i])&PFX_MOTION_MASK_DYNAMIC) 00704 bodyTable[idxA] = batchId; 00705 if(pfxGetMotionMaskB(pairs[i])&PFX_MOTION_MASK_DYNAMIC) 00706 bodyTable[idxB] = batchId; 00707 00708 if(startIndexCheck) 00709 startIndex++; 00710 00711 pairTable[idxP] |= maskP; 00712 //add the pair 'i' to the current batch 00713 batch.pairIndices[pairId++] = i; 00714 pairCount++; 00715 } 00716 00717 group.numPairs[phaseId*PFX_MAX_SOLVER_BATCHES+batchId] = (uint16_t)pairId; 00718 totalCount += pairCount; 00719 } 00720 00721 group.numBatches[phaseId] = batchId; 00722 } 00723 00724 group.numPhases = phaseId; 00725 00726 pool.clear(); 00727 } 00728 00729 00730 00731 void CustomSolveConstraintsParallel( 00732 PfxConstraintPair *contactPairs,uint32_t numContactPairs, 00733 00734 PfxConstraintPair *jointPairs,uint32_t numJointPairs, 00735 btPersistentManifold* offsetContactManifolds, 00736 btSolverConstraint* offsetSolverConstraints, 00737 TrbState *offsetRigStates, 00738 PfxSolverBody *offsetSolverBodies, 00739 uint32_t numRigidBodies, 00740 struct btConstraintSolverIO* io, 00741 class btThreadSupportInterface* threadSupport, 00742 int iteration, 00743 void* poolBuf, 00744 int poolBytes, 00745 class btBarrier* barrier) 00746 { 00747 00748 int maxTasks = threadSupport->getNumTasks(); 00749 // config.taskManager->setTaskEntry(PFX_SOLVER_ENTRY); 00750 00751 HeapManager pool((unsigned char*)poolBuf,poolBytes); 00752 00753 { 00754 PfxParallelGroup *cgroup = (PfxParallelGroup*)pool.allocate(sizeof(PfxParallelGroup)); 00755 PfxParallelBatch *cbatches = (PfxParallelBatch*)pool.allocate(sizeof(PfxParallelBatch)*(PFX_MAX_SOLVER_PHASES*PFX_MAX_SOLVER_BATCHES),128); 00756 PfxParallelGroup *jgroup = (PfxParallelGroup*)pool.allocate(sizeof(PfxParallelGroup)); 00757 PfxParallelBatch *jbatches = (PfxParallelBatch*)pool.allocate(sizeof(PfxParallelBatch)*(PFX_MAX_SOLVER_PHASES*PFX_MAX_SOLVER_BATCHES),128); 00758 00759 uint32_t tmpBytes = poolBytes - 2 * (sizeof(PfxParallelGroup) + sizeof(PfxParallelBatch)*(PFX_MAX_SOLVER_PHASES*PFX_MAX_SOLVER_BATCHES) + 128); 00760 void *tmpBuff = pool.allocate(tmpBytes); 00761 00762 { 00763 BT_PROFILE("CustomSplitConstraints"); 00764 CustomSplitConstraints(contactPairs,numContactPairs,*cgroup,cbatches,maxTasks,numRigidBodies,tmpBuff,tmpBytes); 00765 CustomSplitConstraints(jointPairs,numJointPairs,*jgroup,jbatches,maxTasks,numRigidBodies,tmpBuff,tmpBytes); 00766 } 00767 00768 { 00769 BT_PROFILE("PFX_CONSTRAINT_SOLVER_CMD_SOLVE_CONSTRAINTS"); 00770 //#define SOLVE_SEQUENTIAL 00771 #ifdef SOLVE_SEQUENTIAL 00772 CustomSolveConstraintsTask( 00773 io->solveConstraints.contactParallelGroup, 00774 io->solveConstraints.contactParallelBatches, 00775 io->solveConstraints.contactPairs, 00776 io->solveConstraints.numContactPairs, 00777 io->solveConstraints.offsetContactManifolds, 00778 00779 io->solveConstraints.jointParallelGroup, 00780 io->solveConstraints.jointParallelBatches, 00781 io->solveConstraints.jointPairs, 00782 io->solveConstraints.numJointPairs, 00783 io->solveConstraints.offsetJoints, 00784 00785 io->solveConstraints.offsetRigStates, 00786 io->solveConstraints.offsetSolverBodies, 00787 io->solveConstraints.numRigidBodies, 00788 io->solveConstraints.iteration,0,1,0);//arg->taskId,1,0);//,arg->maxTasks,arg->barrier); 00789 #else 00790 for(int t=0;t<maxTasks;t++) { 00791 io[t].cmd = PFX_CONSTRAINT_SOLVER_CMD_SOLVE_CONSTRAINTS; 00792 io[t].solveConstraints.contactParallelGroup = cgroup; 00793 io[t].solveConstraints.contactParallelBatches = cbatches; 00794 io[t].solveConstraints.contactPairs = contactPairs; 00795 io[t].solveConstraints.numContactPairs = numContactPairs; 00796 io[t].solveConstraints.offsetContactManifolds = offsetContactManifolds; 00797 io[t].solveConstraints.jointParallelGroup = jgroup; 00798 io[t].solveConstraints.jointParallelBatches = jbatches; 00799 io[t].solveConstraints.jointPairs = jointPairs; 00800 io[t].solveConstraints.numJointPairs = numJointPairs; 00801 io[t].solveConstraints.offsetSolverConstraints = offsetSolverConstraints; 00802 io[t].solveConstraints.offsetRigStates1 = offsetRigStates; 00803 io[t].solveConstraints.offsetSolverBodies = offsetSolverBodies; 00804 io[t].solveConstraints.numRigidBodies = numRigidBodies; 00805 io[t].solveConstraints.iteration = iteration; 00806 io[t].solveConstraints.taskId = t; 00807 io[t].solveConstraints.barrier = barrier; 00808 00809 io[t].maxTasks1 = maxTasks; 00810 #ifdef __PPU__ 00811 BulletPE2ConstraintSolverSpursSupport* spursThread = (BulletPE2ConstraintSolverSpursSupport*) threadSupport; 00812 io[t].barrierAddr2 = (unsigned int) spursThread->getBarrierAddress(); 00813 io[t].criticalsectionAddr2 = (unsigned int)spursThread->getCriticalSectionAddress(); 00814 #endif 00815 00816 threadSupport->sendRequest(1,(ppu_address_t)&io[t],t); 00817 } 00818 00819 unsigned int arg0,arg1; 00820 for(int t=0;t<maxTasks;t++) { 00821 arg0 = t; 00822 threadSupport->waitForResponse(&arg0,&arg1); 00823 } 00824 #endif 00825 } 00826 pool.clear(); 00827 } 00828 00829 { 00830 BT_PROFILE("PFX_CONSTRAINT_SOLVER_CMD_POST_SOLVER"); 00831 int batch = ((int)numRigidBodies + maxTasks - 1) / maxTasks; 00832 int rest = (int)numRigidBodies; 00833 int start = 0; 00834 00835 for(int t=0;t<maxTasks;t++) { 00836 int num = (rest - batch ) > 0 ? batch : rest; 00837 io[t].cmd = PFX_CONSTRAINT_SOLVER_CMD_POST_SOLVER; 00838 io[t].postSolver.states = offsetRigStates + start; 00839 io[t].postSolver.solverBodies = offsetSolverBodies + start; 00840 io[t].postSolver.numRigidBodies = (uint32_t)num; 00841 io[t].maxTasks1 = maxTasks; 00842 #ifdef __PPU__ 00843 BulletPE2ConstraintSolverSpursSupport* spursThread = (BulletPE2ConstraintSolverSpursSupport*) threadSupport; 00844 io[t].barrierAddr2 = (unsigned int)spursThread->getBarrierAddress(); 00845 io[t].criticalsectionAddr2 = (unsigned int)spursThread->getCriticalSectionAddress(); 00846 #endif 00847 00848 #ifdef SOLVE_SEQUENTIAL 00849 CustomPostSolverTask( io[t].postSolver.states,io[t].postSolver.solverBodies, io[t].postSolver.numRigidBodies); 00850 #else 00851 threadSupport->sendRequest(1,(ppu_address_t)&io[t],t); 00852 #endif 00853 rest -= num; 00854 start += num; 00855 } 00856 00857 unsigned int arg0,arg1; 00858 for(int t=0;t<maxTasks;t++) { 00859 #ifndef SOLVE_SEQUENTIAL 00860 arg0 = t; 00861 threadSupport->waitForResponse(&arg0,&arg1); 00862 #endif 00863 } 00864 } 00865 00866 } 00867 00868 00869 00870 void BPE_customConstraintSolverSequentialNew(unsigned int new_num, PfxBroadphasePair *new_pairs1 , 00871 btPersistentManifold* offsetContactManifolds, 00872 TrbState* states,int numRigidBodies, 00873 struct PfxSolverBody* solverBodies, 00874 PfxConstraintPair* jointPairs, unsigned int numJoints, 00875 btSolverConstraint* offsetSolverConstraints, 00876 float separateBias, 00877 float timeStep, 00878 int iteration, 00879 btThreadSupportInterface* solverThreadSupport, 00880 btCriticalSection* criticalSection, 00881 struct btConstraintSolverIO* solverIO, 00882 btBarrier* barrier 00883 ) 00884 { 00885 00886 { 00887 BT_PROFILE("pfxSetupConstraints"); 00888 00889 for(uint32_t i=0;i<numJoints;i++) { 00890 // î•ñ‚ÌXV 00891 PfxConstraintPair &pair = jointPairs[i]; 00892 int idA = pfxGetRigidBodyIdA(pair); 00893 00894 if (idA != 65535) 00895 { 00896 pfxSetMotionMaskA(pair,states[pfxGetRigidBodyIdA(pair)].getMotionMask()); 00897 } 00898 else 00899 { 00900 pfxSetMotionMaskA(pair,PFX_MOTION_MASK_STATIC); 00901 } 00902 int idB = pfxGetRigidBodyIdB(pair); 00903 if (idB!= 65535) 00904 { 00905 pfxSetMotionMaskB(pair,states[pfxGetRigidBodyIdB(pair)].getMotionMask()); 00906 } else 00907 { 00908 pfxSetMotionMaskB(pair,PFX_MOTION_MASK_STATIC); 00909 } 00910 } 00911 00912 // CustomSetupJointConstraintsSeq( jointPairs,numJoints,joints, states, solverBodies, numRigidBodies, timeStep); 00913 00914 #ifdef SEQUENTIAL_SETUP 00915 CustomSetupContactConstraintsSeqNew( 00916 (PfxConstraintPair*)new_pairs1,new_num,contacts, 00917 states, 00918 solverBodies, 00919 numRigidBodies, 00920 separateBias, 00921 timeStep); 00922 #else 00923 CustomSetupContactConstraintsNew( 00924 (PfxConstraintPair*)new_pairs1,new_num, 00925 offsetContactManifolds, 00926 states, 00927 solverBodies, 00928 numRigidBodies, 00929 separateBias, 00930 timeStep, 00931 solverThreadSupport, 00932 criticalSection,solverIO 00933 ); 00934 00935 #endif //SEQUENTIAL_SETUP 00936 00937 } 00938 { 00939 BT_PROFILE("pfxSolveConstraints"); 00940 00941 //#define SEQUENTIAL 00942 #ifdef SEQUENTIAL 00943 CustomSolveConstraintsSeq( 00944 (PfxConstraintPair*)new_pairs1,new_num,contacts, 00945 jointPairs,numJoints, 00946 states, 00947 solverBodies, 00948 numRigidBodies, 00949 separateBias, 00950 timeStep, 00951 iteration); 00952 #else //SEQUENTIAL 00953 CustomSolveConstraintsParallel( 00954 (PfxConstraintPair*)new_pairs1,new_num, 00955 jointPairs,numJoints, 00956 offsetContactManifolds, 00957 offsetSolverConstraints, 00958 states, 00959 solverBodies, 00960 numRigidBodies, 00961 solverIO, solverThreadSupport, 00962 iteration, 00963 tmp_buff, 00964 TMP_BUFF_BYTES, 00965 barrier 00966 ); 00967 00968 #endif //SEQUENTIAL 00969 } 00970 00971 } 00972 00973 00974 struct btParallelSolverMemoryCache 00975 { 00976 btAlignedObjectArray<TrbState> m_mystates; 00977 btAlignedObjectArray<PfxSolverBody> m_mysolverbodies; 00978 btAlignedObjectArray<PfxBroadphasePair> m_mypairs; 00979 btAlignedObjectArray<PfxConstraintPair> m_jointPairs; 00980 00981 }; 00982 00983 00984 btConstraintSolverIO* createSolverIO(int numThreads) 00985 { 00986 return new btConstraintSolverIO[numThreads]; 00987 } 00988 00989 btParallelConstraintSolver::btParallelConstraintSolver(btThreadSupportInterface* solverThreadSupport) 00990 { 00991 00992 m_solverThreadSupport = solverThreadSupport;//createSolverThreadSupport(maxNumThreads); 00993 m_solverIO = createSolverIO(m_solverThreadSupport->getNumTasks()); 00994 00995 m_barrier = m_solverThreadSupport->createBarrier(); 00996 m_criticalSection = m_solverThreadSupport->createCriticalSection(); 00997 00998 m_memoryCache = new btParallelSolverMemoryCache(); 00999 } 01000 01001 btParallelConstraintSolver::~btParallelConstraintSolver() 01002 { 01003 delete m_memoryCache; 01004 delete m_solverIO; 01005 } 01006 01007 01008 01009 btScalar btParallelConstraintSolver::solveGroup(btCollisionObject** bodies1,int numRigidBodies,btPersistentManifold** manifoldPtr,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher) 01010 { 01011 01012 /* int sz = sizeof(PfxSolverBody); 01013 int sz2 = sizeof(vmVector3); 01014 int sz3 = sizeof(vmMatrix3); 01015 int sz4 = sizeof(vmQuat); 01016 int sz5 = sizeof(btConstraintRow); 01017 int sz6 = sizeof(btSolverConstraint); 01018 int sz7 = sizeof(TrbState); 01019 */ 01020 01021 btPersistentManifold* offsetContactManifolds= (btPersistentManifold*) dispatcher->getInternalManifoldPool()->getPoolAddress(); 01022 01023 01024 m_memoryCache->m_mysolverbodies.resize(numRigidBodies); 01025 m_memoryCache->m_mystates.resize(numRigidBodies); 01026 01027 { 01028 BT_PROFILE("create states and solver bodies"); 01029 for (int i=0;i<numRigidBodies;i++) 01030 { 01031 btCollisionObject* obj = bodies1[i]; 01032 obj->setCompanionId(i); 01033 01034 PfxSolverBody& solverBody = m_memoryCache->m_mysolverbodies[i]; 01035 btRigidBody* rb = btRigidBody::upcast(obj); 01036 TrbState& state = m_memoryCache->m_mystates[i]; 01037 01038 state.reset(); 01039 const btQuaternion& orgOri = obj->getWorldTransform().getRotation(); 01040 vmQuat orn(orgOri.getX(),orgOri.getY(),orgOri.getZ(),orgOri.getW()); 01041 state.setPosition(getVmVector3(obj->getWorldTransform().getOrigin())); 01042 state.setOrientation(orn); 01043 state.setPosition(state.getPosition()); 01044 state.setRigidBodyId(i); 01045 state.setAngularDamping(0); 01046 state.setLinearDamping(0); 01047 01048 01049 solverBody.mOrientation = state.getOrientation(); 01050 solverBody.mDeltaLinearVelocity = vmVector3(0.0f); 01051 solverBody.mDeltaAngularVelocity = vmVector3(0.0f); 01052 solverBody.friction = obj->getFriction(); 01053 solverBody.restitution = obj->getRestitution(); 01054 01055 state.resetSleepCount(); 01056 01057 //if(state.getMotionMask()&PFX_MOTION_MASK_DYNAMIC) { 01058 if (rb && (rb->getInvMass()>0.f)) 01059 { 01060 state.setAngularVelocity(vmVector3(rb->getAngularVelocity().getX(),rb->getAngularVelocity().getY(),rb->getAngularVelocity().getZ())); 01061 state.setLinearVelocity(vmVector3(rb->getLinearVelocity().getX(),rb->getLinearVelocity().getY(),rb->getLinearVelocity().getZ())); 01062 01063 state.setMotionType(PfxMotionTypeActive); 01064 vmMatrix3 ori(solverBody.mOrientation); 01065 vmMatrix3 localInvInertia = vmMatrix3::identity(); 01066 localInvInertia.setCol(0,vmVector3(rb->getInvInertiaDiagLocal().getX(),0,0)); 01067 localInvInertia.setCol(1,vmVector3(0, rb->getInvInertiaDiagLocal().getY(),0)); 01068 localInvInertia.setCol(2,vmVector3(0,0, rb->getInvInertiaDiagLocal().getZ())); 01069 01070 solverBody.mMassInv = rb->getInvMass(); 01071 solverBody.mInertiaInv = ori * localInvInertia * transpose(ori); 01072 } else 01073 { 01074 state.setAngularVelocity(vmVector3(0)); 01075 state.setLinearVelocity(vmVector3(0)); 01076 01077 state.setMotionType(PfxMotionTypeFixed); 01078 m_memoryCache->m_mysolverbodies[i].mMassInv = 0.f; 01079 m_memoryCache->m_mysolverbodies[i].mInertiaInv = vmMatrix3(0.0f); 01080 } 01081 01082 } 01083 } 01084 01085 01086 01087 int totalPoints = 0; 01088 #ifndef USE_C_ARRAYS 01089 m_memoryCache->m_mypairs.resize(numManifolds); 01090 m_memoryCache->m_jointPairs.resize(numConstraints); 01091 #endif//USE_C_ARRAYS 01092 01093 int actualNumManifolds= 0; 01094 { 01095 BT_PROFILE("convert manifolds"); 01096 for (int i1=0;i1<numManifolds;i1++) 01097 { 01098 if (manifoldPtr[i1]->getNumContacts()>0) 01099 { 01100 btPersistentManifold* m = manifoldPtr[i1]; 01101 btCollisionObject* obA = (btCollisionObject*)m->getBody0(); 01102 btCollisionObject* obB = (btCollisionObject*)m->getBody1(); 01103 bool obAisActive = !obA->isStaticOrKinematicObject() && obA->isActive(); 01104 bool obBisActive = !obB->isStaticOrKinematicObject() && obB->isActive(); 01105 01106 if (!obAisActive && !obBisActive) 01107 continue; 01108 01109 01110 //int contactId = i1;//actualNumManifolds; 01111 01112 PfxBroadphasePair& pair = m_memoryCache->m_mypairs[actualNumManifolds]; 01113 //init those 01114 float compFric = obA->getFriction()*obB->getFriction();//@todo 01115 int idA = obA->getCompanionId(); 01116 int idB = obB->getCompanionId(); 01117 01118 m->m_companionIdA = idA; 01119 m->m_companionIdB = idB; 01120 01121 01122 // if ((mysolverbodies[idA].mMassInv!=0)&&(mysolverbodies[idB].mMassInv!=0)) 01123 // continue; 01124 int numPosPoints=0; 01125 for (int p=0;p<m->getNumContacts();p++) 01126 { 01127 //btManifoldPoint& pt = m->getContactPoint(p); 01128 //float dist = pt.getDistance(); 01129 //if (dist<0.001) 01130 numPosPoints++; 01131 } 01132 01133 01134 numPosPoints = numPosPoints; 01135 totalPoints+=numPosPoints; 01136 pfxSetRigidBodyIdA(pair,idA); 01137 pfxSetRigidBodyIdB(pair,idB); 01138 pfxSetMotionMaskA(pair,m_memoryCache->m_mystates[idA].getMotionMask()); 01139 pfxSetMotionMaskB(pair,m_memoryCache->m_mystates[idB].getMotionMask()); 01140 pfxSetActive(pair,numPosPoints>0); 01141 01142 pfxSetBroadphaseFlag(pair,0); 01143 int contactId = m-offsetContactManifolds; 01144 //likely the contact pool is not contiguous, make sure to allocate large enough contact pool 01145 btAssert(contactId>=0); 01146 btAssert(contactId<dispatcher->getInternalManifoldPool()->getMaxCount()); 01147 01148 pfxSetContactId(pair,contactId); 01149 pfxSetNumConstraints(pair,numPosPoints);//manifoldPtr[i]->getNumContacts()); 01150 actualNumManifolds++; 01151 } 01152 01153 } 01154 } 01155 01156 PfxConstraintPair* jointPairs=0; 01157 jointPairs = numConstraints? &m_memoryCache->m_jointPairs[0]:0; 01158 int actualNumJoints=0; 01159 01160 01161 btSolverConstraint* offsetSolverConstraints = 0; 01162 01163 //if (1) 01164 { 01165 01166 { 01167 BT_PROFILE("convert constraints"); 01168 01169 int totalNumRows = 0; 01170 int i; 01171 01172 m_tmpConstraintSizesPool.resize(numConstraints); 01173 //calculate the total number of contraint rows 01174 for (i=0;i<numConstraints;i++) 01175 { 01176 btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i]; 01177 constraints[i]->getInfo1(&info1); 01178 totalNumRows += info1.m_numConstraintRows; 01179 } 01180 m_tmpSolverNonContactConstraintPool.resize(totalNumRows); 01181 offsetSolverConstraints =totalNumRows? &m_tmpSolverNonContactConstraintPool[0]:0; 01182 01183 01185 int currentRow = 0; 01186 01187 for (i=0;i<numConstraints;i++) 01188 { 01189 const btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i]; 01190 01191 if (info1.m_numConstraintRows) 01192 { 01193 btAssert(currentRow<totalNumRows); 01194 btTypedConstraint* constraint = constraints[i]; 01195 btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[currentRow]; 01196 01197 btRigidBody& rbA = constraint->getRigidBodyA(); 01198 btRigidBody& rbB = constraint->getRigidBodyB(); 01199 01200 01201 int j; 01202 for ( j=0;j<info1.m_numConstraintRows;j++) 01203 { 01204 memset(¤tConstraintRow[j],0,sizeof(btSolverConstraint)); 01205 currentConstraintRow[j].m_lowerLimit = -FLT_MAX; 01206 currentConstraintRow[j].m_upperLimit = FLT_MAX; 01207 currentConstraintRow[j].m_appliedImpulse = 0.f; 01208 currentConstraintRow[j].m_appliedPushImpulse = 0.f; 01209 currentConstraintRow[j].m_solverBodyA = &rbA; 01210 currentConstraintRow[j].m_solverBodyB = &rbB; 01211 } 01212 01213 rbA.internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f); 01214 rbA.internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f); 01215 rbB.internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f); 01216 rbB.internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f); 01217 01218 01219 01220 btTypedConstraint::btConstraintInfo2 info2; 01221 info2.fps = 1.f/infoGlobal.m_timeStep; 01222 info2.erp = infoGlobal.m_erp; 01223 info2.m_J1linearAxis = currentConstraintRow->m_contactNormal; 01224 info2.m_J1angularAxis = currentConstraintRow->m_relpos1CrossNormal; 01225 info2.m_J2linearAxis = 0; 01226 info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal; 01227 info2.rowskip = sizeof(btSolverConstraint)/sizeof(btScalar);//check this 01229 btAssert(info2.rowskip*sizeof(btScalar)== sizeof(btSolverConstraint)); 01230 info2.m_constraintError = ¤tConstraintRow->m_rhs; 01231 currentConstraintRow->m_cfm = infoGlobal.m_globalCfm; 01232 info2.cfm = ¤tConstraintRow->m_cfm; 01233 info2.m_lowerLimit = ¤tConstraintRow->m_lowerLimit; 01234 info2.m_upperLimit = ¤tConstraintRow->m_upperLimit; 01235 info2.m_numIterations = infoGlobal.m_numIterations; 01236 constraints[i]->getInfo2(&info2); 01237 01238 01239 int idA = constraint->getRigidBodyA().getCompanionId(); 01240 int idB = constraint->getRigidBodyB().getCompanionId(); 01241 01242 01244 for ( j=0;j<info1.m_numConstraintRows;j++) 01245 { 01246 btSolverConstraint& solverConstraint = currentConstraintRow[j]; 01247 solverConstraint.m_originalContactPoint = constraint; 01248 01249 solverConstraint.m_companionIdA = idA; 01250 solverConstraint.m_companionIdB = idB; 01251 01252 { 01253 const btVector3& ftorqueAxis1 = solverConstraint.m_relpos1CrossNormal; 01254 solverConstraint.m_angularComponentA = constraint->getRigidBodyA().getInvInertiaTensorWorld()*ftorqueAxis1*constraint->getRigidBodyA().getAngularFactor(); 01255 } 01256 { 01257 const btVector3& ftorqueAxis2 = solverConstraint.m_relpos2CrossNormal; 01258 solverConstraint.m_angularComponentB = constraint->getRigidBodyB().getInvInertiaTensorWorld()*ftorqueAxis2*constraint->getRigidBodyB().getAngularFactor(); 01259 } 01260 01261 { 01262 btVector3 iMJlA = solverConstraint.m_contactNormal*rbA.getInvMass(); 01263 btVector3 iMJaA = rbA.getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal; 01264 btVector3 iMJlB = solverConstraint.m_contactNormal*rbB.getInvMass();//sign of normal? 01265 btVector3 iMJaB = rbB.getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal; 01266 01267 btScalar sum = iMJlA.dot(solverConstraint.m_contactNormal); 01268 sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal); 01269 sum += iMJlB.dot(solverConstraint.m_contactNormal); 01270 sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal); 01271 01272 solverConstraint.m_jacDiagABInv = btScalar(1.)/sum; 01273 } 01274 01275 01278 { 01279 btScalar rel_vel; 01280 btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(rbA.getLinearVelocity()) + solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity()); 01281 btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rbB.getLinearVelocity()) + solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity()); 01282 01283 rel_vel = vel1Dotn+vel2Dotn; 01284 01285 btScalar restitution = 0.f; 01286 btScalar positionalError = solverConstraint.m_rhs;//already filled in by getConstraintInfo2 01287 btScalar velocityError = restitution - rel_vel;// * damping; 01288 btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv; 01289 btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv; 01290 solverConstraint.m_rhs = penetrationImpulse+velocityImpulse; 01291 solverConstraint.m_appliedImpulse = 0.f; 01292 01293 } 01294 } 01295 01296 PfxConstraintPair& pair = jointPairs[actualNumJoints]; 01297 01298 int numConstraintRows= info1.m_numConstraintRows; 01299 pfxSetNumConstraints(pair,numConstraintRows); 01300 01301 01302 01303 pfxSetRigidBodyIdA(pair,idA); 01304 pfxSetRigidBodyIdB(pair,idB); 01305 //is this needed? 01306 if (idA>=0) 01307 pfxSetMotionMaskA(pair,m_memoryCache->m_mystates[idA].getMotionMask()); 01308 if (idB>=0) 01309 pfxSetMotionMaskB(pair,m_memoryCache->m_mystates[idB].getMotionMask()); 01310 01311 pfxSetActive(pair,true); 01312 int id = currentConstraintRow-offsetSolverConstraints; 01313 pfxSetContactId(pair,id); 01314 actualNumJoints++; 01315 01316 01317 } 01318 currentRow+=m_tmpConstraintSizesPool[i].m_numConstraintRows; 01319 } 01320 } 01321 } 01322 01323 01324 01325 float separateBias=0.1;//info.m_erp;//or m_erp2? 01326 float timeStep=infoGlobal.m_timeStep; 01327 int iteration=infoGlobal.m_numIterations; 01328 01329 //create a pair for each constraints, copy over info etc 01330 01331 01332 01333 01334 01335 { 01336 BT_PROFILE("compute num contacts"); 01337 int totalContacts =0; 01338 01339 for (int i=0;i<actualNumManifolds;i++) 01340 { 01341 PfxConstraintPair* pair = &m_memoryCache->m_mypairs[i]; 01342 totalContacts += pfxGetNumConstraints(*pair); 01343 } 01344 //printf("numManifolds = %d\n",numManifolds); 01345 //printf("totalContacts=%d\n",totalContacts); 01346 } 01347 01348 01349 01350 // printf("actualNumManifolds=%d\n",actualNumManifolds); 01351 { 01352 BT_PROFILE("BPE_customConstraintSolverSequentialNew"); 01353 if (numRigidBodies>0 && (actualNumManifolds+actualNumJoints)>0) 01354 { 01355 // PFX_PRINTF("num points = %d\n",totalPoints); 01356 // PFX_PRINTF("num points PFX = %d\n",total); 01357 01358 01359 01360 BPE_customConstraintSolverSequentialNew( 01361 actualNumManifolds, 01362 &m_memoryCache->m_mypairs[0], 01363 offsetContactManifolds, 01364 &m_memoryCache->m_mystates[0],numRigidBodies, 01365 &m_memoryCache->m_mysolverbodies[0], 01366 jointPairs,actualNumJoints, 01367 offsetSolverConstraints, 01368 separateBias,timeStep,iteration, 01369 m_solverThreadSupport,m_criticalSection,m_solverIO,m_barrier); 01370 } 01371 } 01372 01373 //copy results back to bodies 01374 { 01375 BT_PROFILE("copy back"); 01376 for (int i=0;i<numRigidBodies;i++) 01377 { 01378 btCollisionObject* obj = bodies1[i]; 01379 btRigidBody* rb = btRigidBody::upcast(obj); 01380 TrbState& state = m_memoryCache->m_mystates[i]; 01381 if (rb && (rb->getInvMass()>0.f)) 01382 { 01383 rb->setLinearVelocity(btVector3(state.getLinearVelocity().getX(),state.getLinearVelocity().getY(),state.getLinearVelocity().getZ())); 01384 rb->setAngularVelocity(btVector3(state.getAngularVelocity().getX(),state.getAngularVelocity().getY(),state.getAngularVelocity().getZ())); 01385 } 01386 } 01387 } 01388 01389 01390 return 0.f; 01391 }