~ubuntu-branches/ubuntu/maverick/blender/maverick

« back to all changes in this revision

Viewing changes to extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Khashayar Naderehvandi, Khashayar Naderehvandi, Alessio Treglia
  • Date: 2009-01-22 16:53:59 UTC
  • mfrom: (14.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20090122165359-v0996tn7fbit64ni
Tags: 2.48a+dfsg-1ubuntu1
[ Khashayar Naderehvandi ]
* Merge from debian experimental (LP: #320045), Ubuntu remaining changes:
  - Add patch correcting header file locations.
  - Add libvorbis-dev and libgsm1-dev to Build-Depends.
  - Use avcodec_decode_audio2() in source/blender/src/hddaudio.c

[ Alessio Treglia ]
* Add missing previous changelog entries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
3. This notice may not be removed or altered from any source distribution.
14
14
*/
15
15
 
 
16
//#define COMPUTE_IMPULSE_DENOM 1
 
17
//It is not necessary (redundant) to refresh contact manifolds, this refresh has been moved to the collision algorithms.
 
18
//#define FORCE_REFESH_CONTACT_MANIFOLDS 1
16
19
 
17
20
#include "btSequentialImpulseConstraintSolver.h"
18
21
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
30
33
#include "btSolverBody.h"
31
34
#include "btSolverConstraint.h"
32
35
 
 
36
 
33
37
#include "LinearMath/btAlignedObjectArray.h"
34
38
 
35
 
#ifdef USE_PROFILE
36
 
#include "LinearMath/btQuickprof.h"
37
 
#endif //USE_PROFILE
38
39
 
39
40
int totalCpd = 0;
40
41
 
64
65
int btSequentialImpulseConstraintSolver::btRandInt2 (int n)
65
66
{
66
67
  // seems good; xor-fold and modulus
67
 
  const unsigned long un = n;
 
68
  const unsigned long un = static_cast<unsigned long>(n);
68
69
  unsigned long r = btRand2();
69
70
 
70
71
  // note: probably more aggressive than it needs to be -- might be
91
92
 
92
93
 
93
94
 
94
 
 
 
95
bool  MyContactDestroyedCallback(void* userPersistentData);
95
96
bool  MyContactDestroyedCallback(void* userPersistentData)
96
97
{
97
98
        assert (userPersistentData);
98
99
        btConstraintPersistentData* cpd = (btConstraintPersistentData*)userPersistentData;
99
 
        delete cpd;
 
100
        btAlignedFree(cpd);
100
101
        totalCpd--;
101
102
        //printf("totalCpd = %i. DELETED Ptr %x\n",totalCpd,userPersistentData);
102
103
        return true;
105
106
 
106
107
 
107
108
btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver()
108
 
:m_solverMode(SOLVER_RANDMIZE_ORDER | SOLVER_CACHE_FRIENDLY), //not using SOLVER_USE_WARMSTARTING,
109
 
m_btSeed2(0)
 
109
:m_btSeed2(0)
110
110
{
111
111
        gContactDestroyedCallback = &MyContactDestroyedCallback;
112
112
 
121
121
                }
122
122
}
123
123
 
124
 
 
125
 
void    initSolverBody(btSolverBody* solverBody, btRigidBody* rigidbody)
126
 
{
127
 
/*      int size = sizeof(btSolverBody);
128
 
        int sizeofrb = sizeof(btRigidBody);
129
 
        int sizemanifold = sizeof(btPersistentManifold);
130
 
        int sizeofmp = sizeof(btManifoldPoint);
131
 
        int sizeofPersistData = sizeof (btConstraintPersistentData);
132
 
*/
133
 
 
134
 
        solverBody->m_angularVelocity = rigidbody->getAngularVelocity();
135
 
        solverBody->m_centerOfMassPosition = rigidbody->getCenterOfMassPosition();
136
 
        solverBody->m_friction = rigidbody->getFriction();
137
 
//      solverBody->m_invInertiaWorld = rigidbody->getInvInertiaTensorWorld();
138
 
        solverBody->m_invMass = rigidbody->getInvMass();
139
 
        solverBody->m_linearVelocity = rigidbody->getLinearVelocity();
140
 
        solverBody->m_originalBody = rigidbody;
141
 
        solverBody->m_angularFactor = rigidbody->getAngularFactor();
142
 
}
143
 
 
144
 
btScalar penetrationResolveFactor = btScalar(0.9);
 
124
btSequentialImpulseConstraintSolver::~btSequentialImpulseConstraintSolver()
 
125
{
 
126
 
 
127
}
 
128
 
 
129
void    initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject);
 
130
void    initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject)
 
131
{
 
132
        btRigidBody* rb = btRigidBody::upcast(collisionObject);
 
133
        if (rb)
 
134
        {
 
135
                solverBody->m_angularVelocity = rb->getAngularVelocity() ;
 
136
                solverBody->m_centerOfMassPosition = collisionObject->getWorldTransform().getOrigin();
 
137
                solverBody->m_friction = collisionObject->getFriction();
 
138
                solverBody->m_invMass = rb->getInvMass();
 
139
                solverBody->m_linearVelocity = rb->getLinearVelocity();
 
140
                solverBody->m_originalBody = rb;
 
141
                solverBody->m_angularFactor = rb->getAngularFactor();
 
142
        } else
 
143
        {
 
144
                solverBody->m_angularVelocity.setValue(0,0,0);
 
145
                solverBody->m_centerOfMassPosition = collisionObject->getWorldTransform().getOrigin();
 
146
                solverBody->m_friction = collisionObject->getFriction();
 
147
                solverBody->m_invMass = 0.f;
 
148
                solverBody->m_linearVelocity.setValue(0,0,0);
 
149
                solverBody->m_originalBody = 0;
 
150
                solverBody->m_angularFactor = 1.f;
 
151
        }
 
152
        
 
153
        solverBody->m_pushVelocity.setValue(0.f,0.f,0.f);
 
154
        solverBody->m_turnVelocity.setValue(0.f,0.f,0.f);
 
155
}
 
156
 
 
157
 
 
158
int             gNumSplitImpulseRecoveries = 0;
 
159
 
 
160
btScalar restitutionCurve(btScalar rel_vel, btScalar restitution);
145
161
btScalar restitutionCurve(btScalar rel_vel, btScalar restitution)
146
162
{
147
163
        btScalar rest = restitution * -rel_vel;
149
165
}
150
166
 
151
167
 
152
 
 
153
 
 
 
168
void    resolveSplitPenetrationImpulseCacheFriendly(
 
169
        btSolverBody& body1,
 
170
        btSolverBody& body2,
 
171
        const btSolverConstraint& contactConstraint,
 
172
        const btContactSolverInfo& solverInfo);
 
173
 
 
174
//SIMD_FORCE_INLINE
 
175
void    resolveSplitPenetrationImpulseCacheFriendly(
 
176
        btSolverBody& body1,
 
177
        btSolverBody& body2,
 
178
        const btSolverConstraint& contactConstraint,
 
179
        const btContactSolverInfo& solverInfo)
 
180
{
 
181
        (void)solverInfo;
 
182
 
 
183
                if (contactConstraint.m_penetration < solverInfo.m_splitImpulsePenetrationThreshold)
 
184
        {
 
185
 
 
186
                                gNumSplitImpulseRecoveries++;
 
187
                btScalar normalImpulse;
 
188
 
 
189
                //  Optimized version of projected relative velocity, use precomputed cross products with normal
 
190
                //      body1.getVelocityInLocalPoint(contactConstraint.m_rel_posA,vel1);
 
191
                //      body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2);
 
192
                //      btVector3 vel = vel1 - vel2;
 
193
                //      btScalar  rel_vel = contactConstraint.m_contactNormal.dot(vel);
 
194
 
 
195
                btScalar rel_vel;
 
196
                btScalar vel1Dotn = contactConstraint.m_contactNormal.dot(body1.m_pushVelocity)
 
197
                + contactConstraint.m_relpos1CrossNormal.dot(body1.m_turnVelocity);
 
198
                btScalar vel2Dotn = contactConstraint.m_contactNormal.dot(body2.m_pushVelocity)
 
199
                + contactConstraint.m_relpos2CrossNormal.dot(body2.m_turnVelocity);
 
200
 
 
201
                rel_vel = vel1Dotn-vel2Dotn;
 
202
 
 
203
 
 
204
                                btScalar positionalError = -contactConstraint.m_penetration * solverInfo.m_erp2/solverInfo.m_timeStep;
 
205
                //      btScalar positionalError = contactConstraint.m_penetration;
 
206
 
 
207
                btScalar velocityError = contactConstraint.m_restitution - rel_vel;// * damping;
 
208
 
 
209
                btScalar penetrationImpulse = positionalError * contactConstraint.m_jacDiagABInv;
 
210
                btScalar        velocityImpulse = velocityError * contactConstraint.m_jacDiagABInv;
 
211
                normalImpulse = penetrationImpulse+velocityImpulse;
 
212
 
 
213
                // See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse
 
214
                btScalar oldNormalImpulse = contactConstraint.m_appliedPushImpulse;
 
215
                btScalar sum = oldNormalImpulse + normalImpulse;
 
216
                contactConstraint.m_appliedPushImpulse = btScalar(0.) > sum ? btScalar(0.): sum;
 
217
 
 
218
                normalImpulse = contactConstraint.m_appliedPushImpulse - oldNormalImpulse;
 
219
 
 
220
                                body1.internalApplyPushImpulse(contactConstraint.m_contactNormal*body1.m_invMass, contactConstraint.m_angularComponentA,normalImpulse);
 
221
               
 
222
                                body2.internalApplyPushImpulse(contactConstraint.m_contactNormal*body2.m_invMass, contactConstraint.m_angularComponentB,-normalImpulse);
 
223
               
 
224
        }
 
225
 
 
226
}
154
227
 
155
228
 
156
229
//velocity + friction
157
230
//response  between two dynamic objects with friction
158
 
SIMD_FORCE_INLINE btScalar resolveSingleCollisionCombinedCacheFriendly(
159
 
        btSolverBody& body1,
160
 
        btSolverBody& body2,
161
 
        btSolverConstraint& contactConstraint,
 
231
 
 
232
btScalar resolveSingleCollisionCombinedCacheFriendly(
 
233
        btSolverBody& body1,
 
234
        btSolverBody& body2,
 
235
        const btSolverConstraint& contactConstraint,
 
236
        const btContactSolverInfo& solverInfo);
 
237
 
 
238
//SIMD_FORCE_INLINE 
 
239
btScalar resolveSingleCollisionCombinedCacheFriendly(
 
240
        btSolverBody& body1,
 
241
        btSolverBody& body2,
 
242
        const btSolverConstraint& contactConstraint,
162
243
        const btContactSolverInfo& solverInfo)
163
244
{
164
245
        (void)solverInfo;
165
246
 
166
 
        btScalar normalImpulse(0.f);
 
247
        btScalar normalImpulse;
 
248
 
167
249
        {
168
 
                if (contactConstraint.m_penetration < 0.f)
169
 
                        return 0.f;
170
250
 
171
 
        //  Optimized version of projected relative velocity, use precomputed cross products with normal
172
 
        //      body1.getVelocityInLocalPoint(contactConstraint.m_rel_posA,vel1);
173
 
        //      body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2);
174
 
        //      btVector3 vel = vel1 - vel2;
175
 
        //      btScalar  rel_vel = contactConstraint.m_contactNormal.dot(vel);
 
251
                
 
252
                //  Optimized version of projected relative velocity, use precomputed cross products with normal
 
253
                //      body1.getVelocityInLocalPoint(contactConstraint.m_rel_posA,vel1);
 
254
                //      body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2);
 
255
                //      btVector3 vel = vel1 - vel2;
 
256
                //      btScalar  rel_vel = contactConstraint.m_contactNormal.dot(vel);
176
257
 
177
258
                btScalar rel_vel;
178
259
                btScalar vel1Dotn = contactConstraint.m_contactNormal.dot(body1.m_linearVelocity) 
182
263
 
183
264
                rel_vel = vel1Dotn-vel2Dotn;
184
265
 
 
266
                btScalar positionalError = 0.f;
 
267
                if (!solverInfo.m_splitImpulse || (contactConstraint.m_penetration > solverInfo.m_splitImpulsePenetrationThreshold))
 
268
                {
 
269
                        positionalError = -contactConstraint.m_penetration * solverInfo.m_erp/solverInfo.m_timeStep;
 
270
                }
185
271
 
186
 
                btScalar positionalError = contactConstraint.m_penetration;
187
272
                btScalar velocityError = contactConstraint.m_restitution - rel_vel;// * damping;
188
273
 
189
274
                btScalar penetrationImpulse = positionalError * contactConstraint.m_jacDiagABInv;
190
275
                btScalar        velocityImpulse = velocityError * contactConstraint.m_jacDiagABInv;
191
 
                btScalar normalImpulse = penetrationImpulse+velocityImpulse;
 
276
                normalImpulse = penetrationImpulse+velocityImpulse;
 
277
                
192
278
                
193
279
                // See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse
194
280
                btScalar oldNormalImpulse = contactConstraint.m_appliedImpulse;
195
281
                btScalar sum = oldNormalImpulse + normalImpulse;
196
282
                contactConstraint.m_appliedImpulse = btScalar(0.) > sum ? btScalar(0.): sum;
197
283
 
198
 
                btScalar oldVelocityImpulse = contactConstraint.m_appliedVelocityImpulse;
199
 
                btScalar velocitySum = oldVelocityImpulse + velocityImpulse;
200
 
                contactConstraint.m_appliedVelocityImpulse = btScalar(0.) > velocitySum ? btScalar(0.): velocitySum;
201
 
 
202
284
                normalImpulse = contactConstraint.m_appliedImpulse - oldNormalImpulse;
203
285
 
204
 
                if (body1.m_invMass)
205
 
                {
206
 
                        body1.internalApplyImpulse(contactConstraint.m_contactNormal*body1.m_invMass,
 
286
                body1.internalApplyImpulse(contactConstraint.m_contactNormal*body1.m_invMass,
207
287
                                contactConstraint.m_angularComponentA,normalImpulse);
208
 
                }
209
 
                if (body2.m_invMass)
210
 
                {
211
 
                        body2.internalApplyImpulse(contactConstraint.m_contactNormal*body2.m_invMass,
 
288
                
 
289
                body2.internalApplyImpulse(contactConstraint.m_contactNormal*body2.m_invMass,
212
290
                                contactConstraint.m_angularComponentB,-normalImpulse);
213
 
                }
214
 
 
215
291
        }
216
292
 
217
 
        
218
 
 
219
293
        return normalImpulse;
220
294
}
221
295
 
222
 
 
 
296
//#define NO_FRICTION_TANGENTIALS 1
223
297
#ifndef NO_FRICTION_TANGENTIALS
224
298
 
225
 
SIMD_FORCE_INLINE btScalar resolveSingleFrictionCacheFriendly(
226
 
        btSolverBody& body1,
227
 
        btSolverBody& body2,
228
 
        btSolverConstraint& contactConstraint,
 
299
btScalar resolveSingleFrictionCacheFriendly(
 
300
        btSolverBody& body1,
 
301
        btSolverBody& body2,
 
302
        const btSolverConstraint& contactConstraint,
 
303
        const btContactSolverInfo& solverInfo,
 
304
        btScalar appliedNormalImpulse);
 
305
 
 
306
//SIMD_FORCE_INLINE 
 
307
btScalar resolveSingleFrictionCacheFriendly(
 
308
        btSolverBody& body1,
 
309
        btSolverBody& body2,
 
310
        const btSolverConstraint& contactConstraint,
229
311
        const btContactSolverInfo& solverInfo,
230
312
        btScalar appliedNormalImpulse)
231
313
{
252
334
 
253
335
                        // calculate j that moves us to zero relative velocity
254
336
                        j1 = -rel_vel * contactConstraint.m_jacDiagABInv;
 
337
#define CLAMP_ACCUMULATED_FRICTION_IMPULSE 1
 
338
#ifdef CLAMP_ACCUMULATED_FRICTION_IMPULSE
255
339
                        btScalar oldTangentImpulse = contactConstraint.m_appliedImpulse;
256
340
                        contactConstraint.m_appliedImpulse = oldTangentImpulse + j1;
257
 
                        GEN_set_min(contactConstraint.m_appliedImpulse, limit);
258
 
                        GEN_set_max(contactConstraint.m_appliedImpulse, -limit);
 
341
                        
 
342
                        if (limit < contactConstraint.m_appliedImpulse)
 
343
                        {
 
344
                                contactConstraint.m_appliedImpulse = limit;
 
345
                        } else
 
346
                        {
 
347
                                if (contactConstraint.m_appliedImpulse < -limit)
 
348
                                        contactConstraint.m_appliedImpulse = -limit;
 
349
                        }
259
350
                        j1 = contactConstraint.m_appliedImpulse - oldTangentImpulse;
 
351
#else
 
352
                        if (limit < j1)
 
353
                        {
 
354
                                j1 = limit;
 
355
                        } else
 
356
                        {
 
357
                                if (j1 < -limit)
 
358
                                        j1 = -limit;
 
359
                        }
 
360
 
 
361
#endif //CLAMP_ACCUMULATED_FRICTION_IMPULSE
 
362
 
 
363
                        //GEN_set_min(contactConstraint.m_appliedImpulse, limit);
 
364
                        //GEN_set_max(contactConstraint.m_appliedImpulse, -limit);
 
365
 
 
366
                        
260
367
 
261
368
                }
262
369
        
263
 
                if (body1.m_invMass)
264
 
                {
265
 
                        body1.internalApplyImpulse(contactConstraint.m_contactNormal*body1.m_invMass,contactConstraint.m_angularComponentA,j1);
266
 
                }
267
 
                if (body2.m_invMass)
268
 
                {
269
 
                        body2.internalApplyImpulse(contactConstraint.m_contactNormal*body2.m_invMass,contactConstraint.m_angularComponentB,-j1);
270
 
                }
 
370
                body1.internalApplyImpulse(contactConstraint.m_contactNormal*body1.m_invMass,contactConstraint.m_angularComponentA,j1);
 
371
                
 
372
                body2.internalApplyImpulse(contactConstraint.m_contactNormal*body2.m_invMass,contactConstraint.m_angularComponentB,-j1);
271
373
 
272
374
        } 
273
375
        return 0.f;
295
397
                        return 0.f;
296
398
 
297
399
 
298
 
                body1.getVelocityInLocalPoint(contactConstraint.m_rel_posA,vel1);
 
400
                body1.getVelocityInLocalPoint(contactConstraint.m_relpos1CrossNormal,vel1);
299
401
                body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2);
300
402
                btVector3 vel = vel1 - vel2;
301
403
                btScalar rel_vel;
309
411
                const btVector3& rel_pos2 = contactConstraint.m_rel_posB;
310
412
 
311
413
 
312
 
                //if (contactConstraint.m_appliedVelocityImpulse > 0.f)
313
414
                if (lat_rel_vel > SIMD_EPSILON*SIMD_EPSILON)
314
415
                {
315
416
                        lat_rel_vel = btSqrt(lat_rel_vel);
319
420
                        btVector3 temp2 = body2.m_invInertiaWorld * rel_pos2.cross(lat_vel);
320
421
                        btScalar friction_impulse = lat_rel_vel /
321
422
                                (body1.m_invMass + body2.m_invMass + lat_vel.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2)));
322
 
                        btScalar normal_impulse = contactConstraint.m_appliedVelocityImpulse * combinedFriction;
 
423
                        btScalar normal_impulse = contactConstraint.m_appliedImpulse * combinedFriction;
323
424
 
324
 
                        GEN_set_min(friction_impulse, normal_impulse);
325
 
                        GEN_set_max(friction_impulse, -normal_impulse);
326
 
                        body1.applyImpulse(lat_vel * -friction_impulse, rel_pos1);
 
425
                        btSetMin(friction_impulse, normal_impulse);
 
426
                        btSetMin(friction_impulse, -normal_impulse);
 
427
                        body1.internalApplyImpulse(lat_vel * -friction_impulse, rel_pos1);
327
428
                        body2.applyImpulse(lat_vel * friction_impulse, rel_pos2);
328
429
                }
329
430
        }
333
434
 
334
435
#endif //NO_FRICTION_TANGENTIALS
335
436
 
336
 
btAlignedObjectArray<btSolverBody>      tmpSolverBodyPool;
337
 
btAlignedObjectArray<btSolverConstraint>        tmpSolverConstraintPool;
338
 
btAlignedObjectArray<btSolverConstraint>        tmpSolverFrictionConstraintPool;
339
 
 
340
 
 
341
 
btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
342
 
{
 
437
 
 
438
 
 
439
 
 
440
 
 
441
void    btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation)
 
442
{
 
443
 
 
444
        btRigidBody* body0=btRigidBody::upcast(colObj0);
 
445
        btRigidBody* body1=btRigidBody::upcast(colObj1);
 
446
 
 
447
        btSolverConstraint& solverConstraint = m_tmpSolverFrictionConstraintPool.expand();
 
448
        solverConstraint.m_contactNormal = normalAxis;
 
449
 
 
450
        solverConstraint.m_solverBodyIdA = solverBodyIdA;
 
451
        solverConstraint.m_solverBodyIdB = solverBodyIdB;
 
452
        solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_FRICTION_1D;
 
453
        solverConstraint.m_frictionIndex = frictionIndex;
 
454
 
 
455
        solverConstraint.m_friction = cp.m_combinedFriction;
 
456
        solverConstraint.m_originalContactPoint = 0;
 
457
 
 
458
        solverConstraint.m_appliedImpulse = btScalar(0.);
 
459
        solverConstraint.m_appliedPushImpulse = 0.f;
 
460
        solverConstraint.m_penetration = 0.f;
 
461
        {
 
462
                btVector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal);
 
463
                solverConstraint.m_relpos1CrossNormal = ftorqueAxis1;
 
464
                solverConstraint.m_angularComponentA = body0 ? body0->getInvInertiaTensorWorld()*ftorqueAxis1 : btVector3(0,0,0);
 
465
        }
 
466
        {
 
467
                btVector3 ftorqueAxis1 = rel_pos2.cross(solverConstraint.m_contactNormal);
 
468
                solverConstraint.m_relpos2CrossNormal = ftorqueAxis1;
 
469
                solverConstraint.m_angularComponentB = body1 ? body1->getInvInertiaTensorWorld()*ftorqueAxis1 : btVector3(0,0,0);
 
470
        }
 
471
 
 
472
#ifdef COMPUTE_IMPULSE_DENOM
 
473
        btScalar denom0 = rb0->computeImpulseDenominator(pos1,solverConstraint.m_contactNormal);
 
474
        btScalar denom1 = rb1->computeImpulseDenominator(pos2,solverConstraint.m_contactNormal);
 
475
#else
 
476
        btVector3 vec;
 
477
        btScalar denom0 = 0.f;
 
478
        btScalar denom1 = 0.f;
 
479
        if (body0)
 
480
        {
 
481
                vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1);
 
482
                denom0 = body0->getInvMass() + normalAxis.dot(vec);
 
483
        }
 
484
        if (body1)
 
485
        {
 
486
                vec = ( solverConstraint.m_angularComponentB).cross(rel_pos2);
 
487
                denom1 = body1->getInvMass() + normalAxis.dot(vec);
 
488
        }
 
489
 
 
490
 
 
491
#endif //COMPUTE_IMPULSE_DENOM
 
492
        btScalar denom = relaxation/(denom0+denom1);
 
493
        solverConstraint.m_jacDiagABInv = denom;
 
494
 
 
495
 
 
496
}
 
497
 
 
498
 
 
499
void    applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection);
 
500
void    applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection)
 
501
{
 
502
        if (colObj && colObj->hasAnisotropicFriction())
 
503
        {
 
504
                // transform to local coordinates
 
505
                btVector3 loc_lateral = frictionDirection * colObj->getWorldTransform().getBasis();
 
506
                const btVector3& friction_scaling = colObj->getAnisotropicFriction();
 
507
                //apply anisotropic friction
 
508
                loc_lateral *= friction_scaling;
 
509
                // ... and transform it back to global coordinates
 
510
                frictionDirection = colObj->getWorldTransform().getBasis() * loc_lateral;
 
511
        }
 
512
}
 
513
 
 
514
 
 
515
 
 
516
 
 
517
btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** /*bodies */,int /*numBodies */,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
 
518
{
 
519
        BT_PROFILE("solveGroupCacheFriendlySetup");
343
520
        (void)stackAlloc;
344
521
        (void)debugDrawer;
345
522
 
 
523
 
346
524
        if (!(numConstraints + numManifolds))
347
525
        {
348
526
//              printf("empty\n");
349
527
                return 0.f;
350
528
        }
 
529
        btPersistentManifold* manifold = 0;
 
530
        btCollisionObject* colObj0=0,*colObj1=0;
 
531
 
 
532
        //btRigidBody* rb0=0,*rb1=0;
 
533
 
 
534
 
 
535
#ifdef FORCE_REFESH_CONTACT_MANIFOLDS
351
536
 
352
537
        BEGIN_PROFILE("refreshManifolds");
353
538
 
354
539
        int i;
 
540
        
 
541
        
 
542
 
355
543
        for (i=0;i<numManifolds;i++)
356
544
        {
357
 
                btPersistentManifold* manifold = manifoldPtr[i];
358
 
                btRigidBody* rb0 = (btRigidBody*)manifold->getBody0();
359
 
                btRigidBody* rb1 = (btRigidBody*)manifold->getBody1();
360
 
 
 
545
                manifold = manifoldPtr[i];
 
546
                rb1 = (btRigidBody*)manifold->getBody1();
 
547
                rb0 = (btRigidBody*)manifold->getBody0();
 
548
                
361
549
                manifold->refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform());
362
550
 
363
551
        }
364
 
        
 
552
 
365
553
        END_PROFILE("refreshManifolds");
366
 
 
367
 
 
368
 
        BEGIN_PROFILE("gatherSolverData");
 
554
#endif //FORCE_REFESH_CONTACT_MANIFOLDS
 
555
 
 
556
        
 
557
 
 
558
 
369
559
 
370
560
        //int sizeofSB = sizeof(btSolverBody);
371
561
        //int sizeofSC = sizeof(btSolverConstraint);
382
572
 
383
573
                
384
574
                //todo: use stack allocator for this temp memory
385
 
                int minReservation = numManifolds*2;
386
 
 
387
 
                tmpSolverBodyPool.reserve(minReservation);
388
 
 
 
575
//              int minReservation = numManifolds*2;
 
576
 
 
577
                //m_tmpSolverBodyPool.reserve(minReservation);
 
578
 
 
579
                //don't convert all bodies, only the one we need so solver the constraints
 
580
/*
389
581
                {
390
582
                        for (int i=0;i<numBodies;i++)
391
583
                        {
393
585
                                if (rb &&       (rb->getIslandTag() >= 0))
394
586
                                {
395
587
                                        btAssert(rb->getCompanionId() < 0);
396
 
                                        int solverBodyId = tmpSolverBodyPool.size();
397
 
                                        btSolverBody& solverBody = tmpSolverBodyPool.expand();
 
588
                                        int solverBodyId = m_tmpSolverBodyPool.size();
 
589
                                        btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
398
590
                                        initSolverBody(&solverBody,rb);
399
591
                                        rb->setCompanionId(solverBodyId);
400
592
                                } 
401
593
                        }
402
594
                }
 
595
*/
 
596
                
 
597
                //m_tmpSolverConstraintPool.reserve(minReservation);
 
598
                //m_tmpSolverFrictionConstraintPool.reserve(minReservation);
403
599
 
404
 
                
405
 
                tmpSolverConstraintPool.reserve(minReservation);
406
 
                tmpSolverFrictionConstraintPool.reserve(minReservation);
407
600
                {
408
601
                        int i;
409
602
 
410
603
                        for (i=0;i<numManifolds;i++)
411
604
                        {
412
 
                                btPersistentManifold* manifold = manifoldPtr[i];
413
 
                                btRigidBody* rb0 = (btRigidBody*)manifold->getBody0();
414
 
                                btRigidBody* rb1 = (btRigidBody*)manifold->getBody1();
415
 
 
 
605
                                manifold = manifoldPtr[i];
 
606
                                colObj0 = (btCollisionObject*)manifold->getBody0();
 
607
                                colObj1 = (btCollisionObject*)manifold->getBody1();
416
608
                        
417
609
                                int solverBodyIdA=-1;
418
610
                                int solverBodyIdB=-1;
422
614
 
423
615
                                        
424
616
 
425
 
                                        if (rb0->getIslandTag() >= 0)
 
617
                                        if (colObj0->getIslandTag() >= 0)
426
618
                                        {
427
 
                                                solverBodyIdA = rb0->getCompanionId();
 
619
                                                if (colObj0->getCompanionId() >= 0)
 
620
                                                {
 
621
                                                        //body has already been converted
 
622
                                                        solverBodyIdA = colObj0->getCompanionId();
 
623
                                                } else
 
624
                                                {
 
625
                                                        solverBodyIdA = m_tmpSolverBodyPool.size();
 
626
                                                        btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
 
627
                                                        initSolverBody(&solverBody,colObj0);
 
628
                                                        colObj0->setCompanionId(solverBodyIdA);
 
629
                                                }
428
630
                                        } else
429
631
                                        {
430
632
                                                //create a static body
431
 
                                                solverBodyIdA = tmpSolverBodyPool.size();
432
 
                                                btSolverBody& solverBody = tmpSolverBodyPool.expand();
433
 
                                                initSolverBody(&solverBody,rb0);
 
633
                                                solverBodyIdA = m_tmpSolverBodyPool.size();
 
634
                                                btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
 
635
                                                initSolverBody(&solverBody,colObj0);
434
636
                                        }
435
637
 
436
 
                                        if (rb1->getIslandTag() >= 0)
 
638
                                        if (colObj1->getIslandTag() >= 0)
437
639
                                        {
438
 
                                                solverBodyIdB = rb1->getCompanionId();
 
640
                                                if (colObj1->getCompanionId() >= 0)
 
641
                                                {
 
642
                                                        solverBodyIdB = colObj1->getCompanionId();
 
643
                                                } else
 
644
                                                {
 
645
                                                        solverBodyIdB = m_tmpSolverBodyPool.size();
 
646
                                                        btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
 
647
                                                        initSolverBody(&solverBody,colObj1);
 
648
                                                        colObj1->setCompanionId(solverBodyIdB);
 
649
                                                }
439
650
                                        } else
440
651
                                        {
441
652
                                                //create a static body
442
 
                                                solverBodyIdB = tmpSolverBodyPool.size();
443
 
                                                btSolverBody& solverBody = tmpSolverBodyPool.expand();
444
 
                                                initSolverBody(&solverBody,rb1);
 
653
                                                solverBodyIdB = m_tmpSolverBodyPool.size();
 
654
                                                btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
 
655
                                                initSolverBody(&solverBody,colObj1);
445
656
                                        }
446
657
                                }
447
658
 
 
659
                                btVector3 rel_pos1;
 
660
                                btVector3 rel_pos2;
 
661
                                btScalar relaxation;
 
662
 
448
663
                                for (int j=0;j<manifold->getNumContacts();j++)
449
664
                                {
450
665
                                        
451
666
                                        btManifoldPoint& cp = manifold->getContactPoint(j);
452
 
 
453
 
                                        int frictionIndex = tmpSolverConstraintPool.size();
454
 
 
 
667
                                        
455
668
                                        if (cp.getDistance() <= btScalar(0.))
456
669
                                        {
457
670
                                                
458
671
                                                const btVector3& pos1 = cp.getPositionWorldOnA();
459
672
                                                const btVector3& pos2 = cp.getPositionWorldOnB();
460
673
 
461
 
                                                btVector3 rel_pos1 = pos1 - rb0->getCenterOfMassPosition(); 
462
 
                                                btVector3 rel_pos2 = pos2 - rb1->getCenterOfMassPosition();
 
674
                                                 rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin(); 
 
675
                                                 rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin();
463
676
 
464
677
                                                
465
 
                                                        btScalar relaxation = 1.f;
 
678
                                                relaxation = 1.f;
 
679
                                                btScalar rel_vel;
 
680
                                                btVector3 vel;
 
681
 
 
682
                                                int frictionIndex = m_tmpSolverConstraintPool.size();
466
683
 
467
684
                                                {
468
 
                                                        btSolverConstraint& solverConstraint = tmpSolverConstraintPool.expand();
 
685
                                                        btSolverConstraint& solverConstraint = m_tmpSolverConstraintPool.expand();
 
686
                                                        btRigidBody* rb0 = btRigidBody::upcast(colObj0);
 
687
                                                        btRigidBody* rb1 = btRigidBody::upcast(colObj1);
469
688
 
470
689
                                                        solverConstraint.m_solverBodyIdA = solverBodyIdA;
471
690
                                                        solverConstraint.m_solverBodyIdB = solverBodyIdB;
472
691
                                                        solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_CONTACT_1D;
473
692
 
474
 
                                        
 
693
                                                        solverConstraint.m_originalContactPoint = &cp;
475
694
 
 
695
                                                        btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB);
 
696
                                                        solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld()*torqueAxis0 : btVector3(0,0,0);
 
697
                                                        btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB);            
 
698
                                                        solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld()*torqueAxis1 : btVector3(0,0,0);
476
699
                                                        {
477
 
                                                                //can be optimized, the cross products are already calculated
 
700
#ifdef COMPUTE_IMPULSE_DENOM
478
701
                                                                btScalar denom0 = rb0->computeImpulseDenominator(pos1,cp.m_normalWorldOnB);
479
702
                                                                btScalar denom1 = rb1->computeImpulseDenominator(pos2,cp.m_normalWorldOnB);
 
703
#else                                                   
 
704
                                                                btVector3 vec;
 
705
                                                                btScalar denom0 = 0.f;
 
706
                                                                btScalar denom1 = 0.f;
 
707
                                                                if (rb0)
 
708
                                                                {
 
709
                                                                        vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1);
 
710
                                                                        denom0 = rb0->getInvMass() + cp.m_normalWorldOnB.dot(vec);
 
711
                                                                }
 
712
                                                                if (rb1)
 
713
                                                                {
 
714
                                                                        vec = ( solverConstraint.m_angularComponentB).cross(rel_pos2);
 
715
                                                                        denom1 = rb1->getInvMass() + cp.m_normalWorldOnB.dot(vec);
 
716
                                                                }
 
717
#endif //COMPUTE_IMPULSE_DENOM          
 
718
                                                                
480
719
                                                                btScalar denom = relaxation/(denom0+denom1);
481
720
                                                                solverConstraint.m_jacDiagABInv = denom;
482
721
                                                        }
486
725
                                                        solverConstraint.m_relpos2CrossNormal = rel_pos2.cross(cp.m_normalWorldOnB);
487
726
 
488
727
 
489
 
                                                        btVector3 vel1 = rb0->getVelocityInLocalPoint(rel_pos1);
490
 
                                                        btVector3 vel2 = rb1->getVelocityInLocalPoint(rel_pos2);
 
728
                                                        btVector3 vel1 = rb0 ? rb0->getVelocityInLocalPoint(rel_pos1) : btVector3(0,0,0);
 
729
                                                        btVector3 vel2 = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0);
491
730
                                
492
 
                                                        btVector3 vel = vel1 - vel2;
493
 
                                                        btScalar rel_vel;
 
731
                                                        vel  = vel1 - vel2;
 
732
                                                        
494
733
                                                        rel_vel = cp.m_normalWorldOnB.dot(vel);
495
734
                                                        
 
735
                                                        solverConstraint.m_penetration = btMin(cp.getDistance()+infoGlobal.m_linearSlop,btScalar(0.));
 
736
                                                        //solverConstraint.m_penetration = cp.getDistance();
496
737
 
497
 
                                                        solverConstraint.m_penetration = cp.getDistance();///btScalar(infoGlobal.m_numIterations);
498
738
                                                        solverConstraint.m_friction = cp.m_combinedFriction;
499
 
                                                        btScalar rest =  restitutionCurve(rel_vel, cp.m_combinedRestitution);
500
 
                                                        if (rest <= btScalar(0.))
 
739
                                                        solverConstraint.m_restitution =  restitutionCurve(rel_vel, cp.m_combinedRestitution);
 
740
                                                        if (solverConstraint.m_restitution <= btScalar(0.))
501
741
                                                        {
502
 
                                                                rest = 0.f;
 
742
                                                                solverConstraint.m_restitution = 0.f;
503
743
                                                        };
 
744
 
504
745
                                                        
505
746
                                                        btScalar penVel = -solverConstraint.m_penetration/infoGlobal.m_timeStep;
506
 
                                                        if (rest > penVel)
507
 
                                                        {
508
 
                                                                rest = btScalar(0.);
509
 
                                                        }
510
 
                                                        solverConstraint.m_restitution = rest;
511
 
 
512
 
                                                        solverConstraint.m_penetration *= -(infoGlobal.m_erp/infoGlobal.m_timeStep);
513
 
 
514
 
                                                        solverConstraint.m_appliedImpulse = 0.f;
515
 
                                                        solverConstraint.m_appliedVelocityImpulse = 0.f;
516
 
                                                        
517
 
                                        
518
 
                                                        btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB);
519
 
                                                        solverConstraint.m_angularComponentA = rb0->getInvInertiaTensorWorld()*torqueAxis0;
520
 
                                                        btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB);            
521
 
                                                        solverConstraint.m_angularComponentB = rb1->getInvInertiaTensorWorld()*torqueAxis1;
522
 
                                                }
523
 
 
524
 
                                                //create 2 '1d axis' constraints for 2 tangential friction directions
525
 
                        
526
 
                                                //re-calculate friction direction every frame, todo: check if this is really needed
527
 
                                                btVector3 frictionTangential0a, frictionTangential1b;
528
 
 
529
 
                                                btPlaneSpace1(cp.m_normalWorldOnB,frictionTangential0a,frictionTangential1b);
530
 
 
531
 
                                                {
532
 
                                                        btSolverConstraint& solverConstraint = tmpSolverFrictionConstraintPool.expand();
533
 
                                                        solverConstraint.m_contactNormal = frictionTangential0a;
534
 
 
535
 
                                                        solverConstraint.m_solverBodyIdA = solverBodyIdA;
536
 
                                                        solverConstraint.m_solverBodyIdB = solverBodyIdB;
537
 
                                                        solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_FRICTION_1D;
538
 
                                                        solverConstraint.m_frictionIndex = frictionIndex;
539
 
 
540
 
                                                        solverConstraint.m_friction = cp.m_combinedFriction;
541
 
 
542
 
                                                        solverConstraint.m_appliedImpulse = btScalar(0.);
543
 
                                                        solverConstraint.m_appliedVelocityImpulse = 0.f;
544
 
 
545
 
                                                        btScalar denom0 = rb0->computeImpulseDenominator(pos1,solverConstraint.m_contactNormal);
546
 
                                                        btScalar denom1 = rb1->computeImpulseDenominator(pos2,solverConstraint.m_contactNormal);
547
 
                                                        btScalar denom = relaxation/(denom0+denom1);
548
 
                                                        solverConstraint.m_jacDiagABInv = denom;
549
 
 
550
 
                                                        {
551
 
                                                        btVector3 ftorqueAxis0 = rel_pos1.cross(solverConstraint.m_contactNormal);
552
 
                                                        solverConstraint.m_relpos1CrossNormal = ftorqueAxis0;
553
 
                                                        solverConstraint.m_angularComponentA = rb0->getInvInertiaTensorWorld()*ftorqueAxis0;
554
 
                                                        }
555
 
                                                        {
556
 
                                                        btVector3 ftorqueAxis0 = rel_pos2.cross(solverConstraint.m_contactNormal);
557
 
                                                        solverConstraint.m_relpos2CrossNormal = ftorqueAxis0;
558
 
                                                        solverConstraint.m_angularComponentB = rb1->getInvInertiaTensorWorld()*ftorqueAxis0;
559
 
                                                        }
560
 
 
561
 
                                                }
562
 
 
563
 
 
564
 
                                                {
565
 
 
566
 
                                                        btSolverConstraint& solverConstraint = tmpSolverFrictionConstraintPool.expand();
567
 
                                                        solverConstraint.m_contactNormal = frictionTangential1b;
568
 
 
569
 
                                                        solverConstraint.m_solverBodyIdA = solverBodyIdA;
570
 
                                                        solverConstraint.m_solverBodyIdB = solverBodyIdB;
571
 
                                                        solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_FRICTION_1D;
572
 
                                                        solverConstraint.m_frictionIndex = frictionIndex;
573
 
 
574
 
                                                        solverConstraint.m_friction = cp.m_combinedFriction;
575
 
 
576
 
                                                        solverConstraint.m_appliedImpulse = btScalar(0.);
577
 
                                                        solverConstraint.m_appliedVelocityImpulse = 0.f;
578
 
                                                
579
 
                                                        btScalar denom0 = rb0->computeImpulseDenominator(pos1,solverConstraint.m_contactNormal);
580
 
                                                        btScalar denom1 = rb1->computeImpulseDenominator(pos2,solverConstraint.m_contactNormal);
581
 
                                                        btScalar denom = relaxation/(denom0+denom1);
582
 
                                                        solverConstraint.m_jacDiagABInv = denom;
583
 
                                                        {
584
 
                                                                btVector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal);
585
 
                                                                solverConstraint.m_relpos1CrossNormal = ftorqueAxis1;
586
 
                                                                solverConstraint.m_angularComponentA = rb0->getInvInertiaTensorWorld()*ftorqueAxis1;
587
 
                                                                }
588
 
                                                        {
589
 
                                                                btVector3 ftorqueAxis1 = rel_pos2.cross(solverConstraint.m_contactNormal);
590
 
                                                                solverConstraint.m_relpos2CrossNormal = ftorqueAxis1;
591
 
                                                                solverConstraint.m_angularComponentB = rb1->getInvInertiaTensorWorld()*ftorqueAxis1;
592
 
                                                                }
593
 
                                                        }
 
747
 
 
748
                                                        
 
749
 
 
750
                                                        if (solverConstraint.m_restitution > penVel)
 
751
                                                        {
 
752
                                                                solverConstraint.m_penetration = btScalar(0.);
 
753
                                                        }
 
754
                                                         
 
755
                                                        
 
756
                                                        
 
757
                                                        ///warm starting (or zero if disabled)
 
758
                                                        if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
 
759
                                                        {
 
760
                                                                solverConstraint.m_appliedImpulse = cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor;
 
761
                                                                if (rb0)
 
762
                                                                        m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(solverConstraint.m_contactNormal*rb0->getInvMass(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse);
 
763
                                                                if (rb1)
 
764
                                                                        m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(solverConstraint.m_contactNormal*rb1->getInvMass(),solverConstraint.m_angularComponentB,-solverConstraint.m_appliedImpulse);
 
765
                                                        } else
 
766
                                                        {
 
767
                                                                solverConstraint.m_appliedImpulse = 0.f;
 
768
                                                        }
 
769
 
 
770
                                                        solverConstraint.m_appliedPushImpulse = 0.f;
 
771
                                                        
 
772
                                                        solverConstraint.m_frictionIndex = m_tmpSolverFrictionConstraintPool.size();
 
773
                                                        if (!cp.m_lateralFrictionInitialized)
 
774
                                                        {
 
775
                                                                cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel;
 
776
                                                                
 
777
                                                                //scale anisotropic friction
 
778
                                                                
 
779
                                                                applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1);
 
780
                                                                applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1);
 
781
 
 
782
                                                                btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2();
 
783
 
 
784
 
 
785
                                                                if (lat_rel_vel > SIMD_EPSILON)//0.0f)
 
786
                                                                {
 
787
                                                                        cp.m_lateralFrictionDir1 /= btSqrt(lat_rel_vel);
 
788
                                                                        addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
 
789
                                                                        cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB);
 
790
                                                                        cp.m_lateralFrictionDir2.normalize();
 
791
                                                                        applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2);
 
792
                                                                        applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2);
 
793
 
 
794
                                                                        addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
 
795
                                                                } else
 
796
                                                                {
 
797
                                                                        //re-calculate friction direction every frame, todo: check if this is really needed
 
798
                                                                        btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2);
 
799
                                                                        applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2);
 
800
                                                                        applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2);
 
801
                                                                        addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
 
802
                                                                        addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
 
803
                                                                }
 
804
                                                                cp.m_lateralFrictionInitialized = true;
 
805
                                                                
 
806
                                                        } else
 
807
                                                        {
 
808
                                                                addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
 
809
                                                                addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
 
810
                                                        }
 
811
 
 
812
                                                        {
 
813
                                                                btSolverConstraint& frictionConstraint1 = m_tmpSolverFrictionConstraintPool[solverConstraint.m_frictionIndex];
 
814
                                                                if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
 
815
                                                                {
 
816
                                                                        frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor;
 
817
                                                                        if (rb0)
 
818
                                                                                m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(frictionConstraint1.m_contactNormal*rb0->getInvMass(),frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse);
 
819
                                                                        if (rb1)
 
820
                                                                                m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(frictionConstraint1.m_contactNormal*rb1->getInvMass(),frictionConstraint1.m_angularComponentB,-frictionConstraint1.m_appliedImpulse);
 
821
                                                                } else
 
822
                                                                {
 
823
                                                                        frictionConstraint1.m_appliedImpulse = 0.f;
 
824
                                                                }
 
825
                                                        }
 
826
                                                        {
 
827
                                                                btSolverConstraint& frictionConstraint2 = m_tmpSolverFrictionConstraintPool[solverConstraint.m_frictionIndex+1];
 
828
                                                                if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
 
829
                                                                {
 
830
                                                                        frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor;
 
831
                                                                        if (rb0)
 
832
                                                                                m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(frictionConstraint2.m_contactNormal*rb0->getInvMass(),frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse);
 
833
                                                                        if (rb1)
 
834
                                                                                m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(frictionConstraint2.m_contactNormal*rb1->getInvMass(),frictionConstraint2.m_angularComponentB,-frictionConstraint2.m_appliedImpulse);
 
835
                                                                } else
 
836
                                                                {
 
837
                                                                        frictionConstraint2.m_appliedImpulse = 0.f;
 
838
                                                                }
 
839
                                                        }
 
840
                                                }
 
841
 
594
842
 
595
843
                                        }
596
844
                                }
597
845
                        }
598
846
                }
599
847
        }
600
 
        END_PROFILE("gatherSolverData");
601
 
 
602
 
        BEGIN_PROFILE("prepareConstraints");
603
 
 
 
848
        
604
849
        btContactSolverInfo info = infoGlobal;
605
850
 
606
851
        {
612
857
                }
613
858
        }
614
859
        
615
 
        btAlignedObjectArray<int>       gOrderTmpConstraintPool;
616
 
        btAlignedObjectArray<int>       gOrderFrictionConstraintPool;
 
860
        
617
861
 
618
 
        int numConstraintPool = tmpSolverConstraintPool.size();
619
 
        int numFrictionPool = tmpSolverFrictionConstraintPool.size();
 
862
        int numConstraintPool = m_tmpSolverConstraintPool.size();
 
863
        int numFrictionPool = m_tmpSolverFrictionConstraintPool.size();
620
864
 
621
865
        ///todo: use stack allocator for such temporarily memory, same for solver bodies/constraints
622
 
        gOrderTmpConstraintPool.resize(numConstraintPool);
623
 
        gOrderFrictionConstraintPool.resize(numFrictionPool);
 
866
        m_orderTmpConstraintPool.resize(numConstraintPool);
 
867
        m_orderFrictionConstraintPool.resize(numFrictionPool);
624
868
        {
625
869
                int i;
626
870
                for (i=0;i<numConstraintPool;i++)
627
871
                {
628
 
                        gOrderTmpConstraintPool[i] = i;
 
872
                        m_orderTmpConstraintPool[i] = i;
629
873
                }
630
874
                for (i=0;i<numFrictionPool;i++)
631
875
                {
632
 
                        gOrderFrictionConstraintPool[i] = i;
 
876
                        m_orderFrictionConstraintPool[i] = i;
633
877
                }
634
878
        }
635
879
 
636
880
 
637
881
 
638
 
 
639
 
        END_PROFILE("prepareConstraints");
640
 
 
641
 
 
642
 
        BEGIN_PROFILE("solveConstraints");
 
882
        return 0.f;
 
883
 
 
884
}
 
885
 
 
886
btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(btCollisionObject** /*bodies */,int /*numBodies*/,btPersistentManifold** /*manifoldPtr*/, int /*numManifolds*/,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* /*debugDrawer*/,btStackAlloc* /*stackAlloc*/)
 
887
{
 
888
        BT_PROFILE("solveGroupCacheFriendlyIterations");
 
889
        int numConstraintPool = m_tmpSolverConstraintPool.size();
 
890
        int numFrictionPool = m_tmpSolverFrictionConstraintPool.size();
643
891
 
644
892
        //should traverse the contacts random order...
645
893
        int iteration;
646
894
        {
647
 
                for ( iteration = 0;iteration<info.m_numIterations;iteration++)
 
895
                for ( iteration = 0;iteration<infoGlobal.m_numIterations;iteration++)
648
896
                {                       
649
897
 
650
898
                        int j;
651
 
                        if (m_solverMode & SOLVER_RANDMIZE_ORDER)
 
899
                        if (infoGlobal.m_solverMode & SOLVER_RANDMIZE_ORDER)
652
900
                        {
653
901
                                if ((iteration & 7) == 0) {
654
902
                                        for (j=0; j<numConstraintPool; ++j) {
655
 
                                                int tmp = gOrderTmpConstraintPool[j];
 
903
                                                int tmp = m_orderTmpConstraintPool[j];
656
904
                                                int swapi = btRandInt2(j+1);
657
 
                                                gOrderTmpConstraintPool[j] = gOrderTmpConstraintPool[swapi];
658
 
                                                gOrderTmpConstraintPool[swapi] = tmp;
 
905
                                                m_orderTmpConstraintPool[j] = m_orderTmpConstraintPool[swapi];
 
906
                                                m_orderTmpConstraintPool[swapi] = tmp;
659
907
                                        }
660
908
 
661
909
                                        for (j=0; j<numFrictionPool; ++j) {
662
 
                                                int tmp = gOrderFrictionConstraintPool[j];
 
910
                                                int tmp = m_orderFrictionConstraintPool[j];
663
911
                                                int swapi = btRandInt2(j+1);
664
 
                                                gOrderFrictionConstraintPool[j] = gOrderFrictionConstraintPool[swapi];
665
 
                                                gOrderFrictionConstraintPool[swapi] = tmp;
 
912
                                                m_orderFrictionConstraintPool[j] = m_orderFrictionConstraintPool[swapi];
 
913
                                                m_orderFrictionConstraintPool[swapi] = tmp;
666
914
                                        }
667
915
                                }
668
916
                        }
674
922
 
675
923
                                if ((constraint->getRigidBodyA().getIslandTag() >= 0) && (constraint->getRigidBodyA().getCompanionId() >= 0))
676
924
                                {
677
 
                                        tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].writebackVelocity();
 
925
                                        m_tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].writebackVelocity();
678
926
                                }
679
927
                                if ((constraint->getRigidBodyB().getIslandTag() >= 0) && (constraint->getRigidBodyB().getCompanionId() >= 0))
680
928
                                {
681
 
                                        tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].writebackVelocity();
 
929
                                        m_tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].writebackVelocity();
682
930
                                }
683
931
 
684
 
                                constraint->solveConstraint(info.m_timeStep);
 
932
                                constraint->solveConstraint(infoGlobal.m_timeStep);
685
933
 
686
934
                                if ((constraint->getRigidBodyA().getIslandTag() >= 0) && (constraint->getRigidBodyA().getCompanionId() >= 0))
687
935
                                {
688
 
                                        tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].readVelocity();
 
936
                                        m_tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].readVelocity();
689
937
                                }
690
938
                                if ((constraint->getRigidBodyB().getIslandTag() >= 0) && (constraint->getRigidBodyB().getCompanionId() >= 0))
691
939
                                {
692
 
                                        tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].readVelocity();
 
940
                                        m_tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].readVelocity();
693
941
                                }
694
942
 
695
943
                        }
696
944
 
697
945
                        {
698
 
                                int numPoolConstraints = tmpSolverConstraintPool.size();
 
946
                                int numPoolConstraints = m_tmpSolverConstraintPool.size();
699
947
                                for (j=0;j<numPoolConstraints;j++)
700
948
                                {
701
 
                                        btSolverConstraint& solveManifold = tmpSolverConstraintPool[gOrderTmpConstraintPool[j]];
702
 
                                        resolveSingleCollisionCombinedCacheFriendly(tmpSolverBodyPool[solveManifold.m_solverBodyIdA],
703
 
                                                tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold,info);
704
 
                                }
705
 
                        }
706
 
 
707
 
                        {
708
 
                                 int numFrictionPoolConstraints = tmpSolverFrictionConstraintPool.size();
709
 
                                for (j=0;j<numFrictionPoolConstraints;j++)
710
 
                                {
711
 
                                        btSolverConstraint& solveManifold = tmpSolverFrictionConstraintPool[gOrderFrictionConstraintPool[j]];
712
 
                                                btScalar appliedNormalImpulse = tmpSolverConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
713
 
 
714
 
                                                resolveSingleFrictionCacheFriendly(tmpSolverBodyPool[solveManifold.m_solverBodyIdA],
715
 
                                                        tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold,info,appliedNormalImpulse);
716
 
                                }
717
 
                        }
718
 
                        
719
 
 
720
 
 
721
 
                }
 
949
                                        
 
950
                                        const btSolverConstraint& solveManifold = m_tmpSolverConstraintPool[m_orderTmpConstraintPool[j]];
 
951
                                        resolveSingleCollisionCombinedCacheFriendly(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],
 
952
                                                m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold,infoGlobal);
 
953
                                }
 
954
                        }
 
955
 
 
956
                        {
 
957
                                 int numFrictionPoolConstraints = m_tmpSolverFrictionConstraintPool.size();
 
958
                                
 
959
                                 for (j=0;j<numFrictionPoolConstraints;j++)
 
960
                                {
 
961
                                        const btSolverConstraint& solveManifold = m_tmpSolverFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
 
962
                                        btScalar totalImpulse = m_tmpSolverConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse+
 
963
                                                                m_tmpSolverConstraintPool[solveManifold.m_frictionIndex].m_appliedPushImpulse;                  
 
964
 
 
965
                                                resolveSingleFrictionCacheFriendly(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],
 
966
                                                        m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold,infoGlobal,
 
967
                                                        totalImpulse);
 
968
                                }
 
969
                        }
 
970
                        
 
971
 
 
972
 
 
973
                }
 
974
        
 
975
                if (infoGlobal.m_splitImpulse)
 
976
                {
 
977
                        
 
978
                        for ( iteration = 0;iteration<infoGlobal.m_numIterations;iteration++)
 
979
                        {
 
980
                                {
 
981
                                        int numPoolConstraints = m_tmpSolverConstraintPool.size();
 
982
                                        int j;
 
983
                                        for (j=0;j<numPoolConstraints;j++)
 
984
                                        {
 
985
                                                const btSolverConstraint& solveManifold = m_tmpSolverConstraintPool[m_orderTmpConstraintPool[j]];
 
986
 
 
987
                                                resolveSplitPenetrationImpulseCacheFriendly(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],
 
988
                                                        m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold,infoGlobal);
 
989
                                        }
 
990
                                }
 
991
                        }
 
992
 
 
993
                }
 
994
 
722
995
        }
 
996
 
 
997
        return 0.f;
 
998
}
 
999
 
 
1000
 
 
1001
btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
 
1002
{
 
1003
        int i;
 
1004
 
 
1005
        solveGroupCacheFriendlySetup( bodies, numBodies, manifoldPtr,  numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc);
 
1006
        solveGroupCacheFriendlyIterations(bodies, numBodies, manifoldPtr,  numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc);
 
1007
 
 
1008
        int numPoolConstraints = m_tmpSolverConstraintPool.size();
 
1009
        int j;
 
1010
        for (j=0;j<numPoolConstraints;j++)
 
1011
        {
723
1012
                
724
 
        for ( i=0;i<tmpSolverBodyPool.size();i++)
 
1013
                const btSolverConstraint& solveManifold = m_tmpSolverConstraintPool[j];
 
1014
                btManifoldPoint* pt = (btManifoldPoint*) solveManifold.m_originalContactPoint;
 
1015
                btAssert(pt);
 
1016
                pt->m_appliedImpulse = solveManifold.m_appliedImpulse;
 
1017
                pt->m_appliedImpulseLateral1 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
 
1018
                pt->m_appliedImpulseLateral2 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse;
 
1019
 
 
1020
                //do a callback here?
 
1021
 
 
1022
        }
 
1023
 
 
1024
        if (infoGlobal.m_splitImpulse)
 
1025
        {               
 
1026
                for ( i=0;i<m_tmpSolverBodyPool.size();i++)
 
1027
                {
 
1028
                        m_tmpSolverBodyPool[i].writebackVelocity(infoGlobal.m_timeStep);
 
1029
                }
 
1030
        } else
725
1031
        {
726
 
                tmpSolverBodyPool[i].writebackVelocity();
 
1032
                for ( i=0;i<m_tmpSolverBodyPool.size();i++)
 
1033
        {
 
1034
                m_tmpSolverBodyPool[i].writebackVelocity();
 
1035
        }
727
1036
        }
728
1037
 
729
 
        END_PROFILE("solveConstraints");
730
 
 
731
 
//      printf("tmpSolverConstraintPool.size() = %i\n",tmpSolverConstraintPool.size());
 
1038
//      printf("m_tmpSolverConstraintPool.size() = %i\n",m_tmpSolverConstraintPool.size());
732
1039
 
733
1040
/*
734
 
        printf("tmpSolverBodyPool.size() = %i\n",tmpSolverBodyPool.size());
735
 
        printf("tmpSolverConstraintPool.size() = %i\n",tmpSolverConstraintPool.size());
736
 
        printf("tmpSolverFrictionConstraintPool.size() = %i\n",tmpSolverFrictionConstraintPool.size());
 
1041
        printf("m_tmpSolverBodyPool.size() = %i\n",m_tmpSolverBodyPool.size());
 
1042
        printf("m_tmpSolverConstraintPool.size() = %i\n",m_tmpSolverConstraintPool.size());
 
1043
        printf("m_tmpSolverFrictionConstraintPool.size() = %i\n",m_tmpSolverFrictionConstraintPool.size());
737
1044
 
738
1045
        
739
 
        printf("tmpSolverBodyPool.capacity() = %i\n",tmpSolverBodyPool.capacity());
740
 
        printf("tmpSolverConstraintPool.capacity() = %i\n",tmpSolverConstraintPool.capacity());
741
 
        printf("tmpSolverFrictionConstraintPool.capacity() = %i\n",tmpSolverFrictionConstraintPool.capacity());
 
1046
        printf("m_tmpSolverBodyPool.capacity() = %i\n",m_tmpSolverBodyPool.capacity());
 
1047
        printf("m_tmpSolverConstraintPool.capacity() = %i\n",m_tmpSolverConstraintPool.capacity());
 
1048
        printf("m_tmpSolverFrictionConstraintPool.capacity() = %i\n",m_tmpSolverFrictionConstraintPool.capacity());
742
1049
*/
743
1050
 
744
 
        tmpSolverBodyPool.resize(0);
745
 
        tmpSolverConstraintPool.resize(0);
746
 
        tmpSolverFrictionConstraintPool.resize(0);
 
1051
        m_tmpSolverBodyPool.resize(0);
 
1052
        m_tmpSolverConstraintPool.resize(0);
 
1053
        m_tmpSolverFrictionConstraintPool.resize(0);
747
1054
 
748
1055
 
749
1056
        return 0.f;
750
1057
}
751
1058
 
752
1059
/// btSequentialImpulseConstraintSolver Sequentially applies impulses
753
 
btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
 
1060
btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc,btDispatcher* /*dispatcher*/)
754
1061
{
755
 
 
756
 
        if (getSolverMode() & SOLVER_CACHE_FRIENDLY)
 
1062
        BT_PROFILE("solveGroup");
 
1063
        if (infoGlobal.m_solverMode & SOLVER_CACHE_FRIENDLY)
757
1064
        {
758
1065
                //you need to provide at least some bodies
759
1066
                //btSimpleDynamicsWorld needs to switch off SOLVER_CACHE_FRIENDLY
762
1069
                return solveGroupCacheFriendly(bodies,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer,stackAlloc);
763
1070
        }
764
1071
 
765
 
 
766
 
        BEGIN_PROFILE("prepareConstraints");
767
1072
        
768
1073
 
769
1074
        btContactSolverInfo info = infoGlobal;
770
1075
 
771
1076
        int numiter = infoGlobal.m_numIterations;
772
 
#ifdef USE_PROFILE
773
 
        btProfiler::beginBlock("solve");
774
 
#endif //USE_PROFILE
775
1077
 
776
1078
        int totalPoints = 0;
777
1079
 
801
1103
                }
802
1104
        }
803
1105
        
804
 
        END_PROFILE("prepareConstraints");
805
 
 
806
 
 
807
 
        BEGIN_PROFILE("solveConstraints");
808
1106
 
809
1107
        //should traverse the contacts random order...
810
1108
        int iteration;
813
1111
                for ( iteration = 0;iteration<numiter;iteration++)
814
1112
                {
815
1113
                        int j;
816
 
                        if (m_solverMode & SOLVER_RANDMIZE_ORDER)
 
1114
                        if (infoGlobal.m_solverMode & SOLVER_RANDMIZE_ORDER)
817
1115
                        {
818
1116
                                if ((iteration & 7) == 0) {
819
1117
                                        for (j=0; j<totalPoints; ++j) {
845
1143
                                solveFriction((btRigidBody*)manifold->getBody0(),
846
1144
                                        (btRigidBody*)manifold->getBody1(),manifold->getContactPoint(gOrder[j].m_pointIndex),info,iteration,debugDrawer);
847
1145
                        }
 
1146
                        
848
1147
                }
849
1148
        }
850
1149
                
851
 
        END_PROFILE("solveConstraints");
852
 
 
853
 
 
854
 
#ifdef USE_PROFILE
855
 
        btProfiler::endBlock("solve");
856
 
#endif //USE_PROFILE
857
 
 
858
1150
 
859
1151
 
860
1152
 
878
1170
 
879
1171
        //only necessary to refresh the manifold once (first iteration). The integration is done outside the loop
880
1172
        {
 
1173
#ifdef FORCE_REFESH_CONTACT_MANIFOLDS
881
1174
                manifoldPtr->refreshContactPoints(body0->getCenterOfMassTransform(),body1->getCenterOfMassTransform());
882
 
                
 
1175
#endif //FORCE_REFESH_CONTACT_MANIFOLDS         
883
1176
                int numpoints = manifoldPtr->getNumContacts();
884
1177
 
885
1178
                gTotalContactPoints += numpoints;
886
1179
 
887
 
                btVector3 color(0,1,0);
 
1180
                
888
1181
                for (int i=0;i<numpoints ;i++)
889
1182
                {
890
1183
                        btManifoldPoint& cp = manifoldPtr->getContactPoint(i);
925
1218
                                } else
926
1219
                                {
927
1220
                                                
928
 
                                        cpd = new btConstraintPersistentData;
 
1221
                                        //todo: should this be in a pool?
 
1222
                                        void* mem = btAlignedAlloc(sizeof(btConstraintPersistentData),16);
 
1223
                                        cpd = new (mem)btConstraintPersistentData;
929
1224
                                        assert(cpd);
930
1225
 
931
1226
                                        totalCpd ++;
972
1267
                                        cpd->m_penetration = btScalar(0.);
973
1268
                                }                               
974
1269
                                
975
 
                                
976
1270
 
977
1271
                                btScalar relaxation = info.m_damping;
978
 
                                if (m_solverMode & SOLVER_USE_WARMSTARTING)
 
1272
                                if (info.m_solverMode & SOLVER_USE_WARMSTARTING)
979
1273
                                {
980
1274
                                        cpd->m_appliedImpulse *= relaxation;
981
1275
                                } else
1060
1354
 
1061
1355
        {
1062
1356
 
1063
 
                btVector3 color(0,1,0);
 
1357
                
1064
1358
                {
1065
1359
                        if (cp.getDistance() <= btScalar(0.))
1066
1360
                        {
1067
1361
 
1068
 
                                if (iter == 0)
1069
 
                                {
1070
 
                                        if (debugDrawer)
1071
 
                                                debugDrawer->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color);
1072
 
                                }
 
1362
                                
1073
1363
 
1074
1364
                                {
1075
1365
 
1098
1388
 
1099
1389
        {
1100
1390
 
1101
 
                btVector3 color(0,1,0);
 
1391
                
1102
1392
                {
1103
1393
                        if (cp.getDistance() <= btScalar(0.))
1104
1394
                        {
1105
1395
 
1106
 
                                if (iter == 0)
1107
 
                                {
1108
 
                                        if (debugDrawer)
1109
 
                                                debugDrawer->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color);
1110
 
                                }
 
1396
                                
1111
1397
 
1112
1398
                                {
1113
1399
 
1136
1422
 
1137
1423
        {
1138
1424
 
1139
 
                btVector3 color(0,1,0);
 
1425
                
1140
1426
                {
1141
1427
                        
1142
1428
                        if (cp.getDistance() <= btScalar(0.))
1156
1442
        }
1157
1443
        return btScalar(0.);
1158
1444
}
 
1445
 
 
1446
 
 
1447
void    btSequentialImpulseConstraintSolver::reset()
 
1448
{
 
1449
        m_btSeed2 = 0;
 
1450
}
 
1451
 
 
1452