84 ContactPatch mIntermediatePatches[CONTACT_REDUCTION_MAX_PATCHES];
85 ContactPatch* mIntermediatePatchesPtrs[CONTACT_REDUCTION_MAX_PATCHES];
86 PxU32 mNumIntermediatePatches;
89 PxU32 mNumOriginalContacts;
92 mNumPatches(0), mNumIntermediatePatches(0), mOriginalContacts(originalContacts), mMaterialInfo(materialInfo), mNumOriginalContacts(numContacts)
100 mIntermediatePatches[0].rootNormal = mOriginalContacts[0].normal;
101 mIntermediatePatches[0].mNextPatch = NULL;
102 mIntermediatePatches[0].startIndex = 0;
103 mIntermediatePatches[0].rootIndex = 0;
104 mIntermediatePatches[0].maxPenetration = mOriginalContacts[0].separation;
105 mIntermediatePatches[0].index = 0;
106 PxU16 numPatches = 1;
108 PxU32 numUniquePatches = 1;
110 for(; m < mNumOriginalContacts; ++m)
113 for(PxU32 b = numPatches; b > 0; --b)
116 if(mMaterialInfo[patch.startIndex].mMaterialIndex0 == mMaterialInfo[m].mMaterialIndex0 && mMaterialInfo[patch.startIndex].mMaterialIndex1 == mMaterialInfo[m].mMaterialIndex1 &&
117 patch.rootNormal.dot(mOriginalContacts[m].normal) >= PXS_NORMAL_TOLERANCE)
124 if(index != numPatches - 1)
126 mIntermediatePatches[numPatches-1].stride = PxU16(m - mIntermediatePatches[numPatches - 1].startIndex);
128 if(numPatches == CONTACT_REDUCTION_MAX_PATCHES)
132 mIntermediatePatches[numPatches].startIndex = m;
133 mIntermediatePatches[numPatches].mNextPatch = NULL;
136 mIntermediatePatches[numPatches].rootIndex = numPatches;
137 mIntermediatePatches[numPatches].rootNormal = mOriginalContacts[m].normal;
138 mIntermediatePatches[numPatches].maxPenetration = mOriginalContacts[m].separation;
139 mIntermediatePatches[numPatches].index = numPatches;
145 PxU16 rootIndex = mIntermediatePatches[index].rootIndex;
146 mIntermediatePatches[index].mNextPatch = &mIntermediatePatches[numPatches];
147 mIntermediatePatches[numPatches].rootNormal = mIntermediatePatches[index].rootNormal;
148 mIntermediatePatches[rootIndex].maxPenetration = mIntermediatePatches[numPatches].maxPenetration =
PxMin(mIntermediatePatches[rootIndex].maxPenetration, mOriginalContacts[m].separation);
149 mIntermediatePatches[numPatches].rootIndex = rootIndex;
150 mIntermediatePatches[numPatches].index = numPatches;
155 mIntermediatePatches[numPatches-1].stride = PxU16(m - mIntermediatePatches[numPatches-1].startIndex);
161 for(PxU32 a = 0; a < numPatches; ++a)
163 mIntermediatePatchesPtrs[a] = &mIntermediatePatches[a];
168 PxSort(mIntermediatePatchesPtrs, numPatches, predicate);
170 PxU32 numReducedPatches = 0;
171 for(PxU32 a = 0; a < numPatches; ++a)
173 if(mIntermediatePatchesPtrs[a]->rootIndex == mIntermediatePatchesPtrs[a]->index)
176 if(numReducedPatches == MaxPatches)
181 PxU32 contactCount = 0;
187 contactCount += tmpPatch->stride;
188 tmpPatch = tmpPatch->mNextPatch;
192 if(contactCount <= CONTACT_REDUCTION_MAX_CONTACTS)
200 for(PxU32 b = 0; b < tmpPatch->stride; ++b)
202 reducedPatch.contactPoints[ind++] = tmpPatch->startIndex + b;
204 tmpPatch = tmpPatch->mNextPatch;
206 reducedPatch.numContactPoints = contactCount;
220 for(PxU32 b = 0; b < tmpPatch->stride; ++b)
222 PxReal magSq = mOriginalContacts[tmpPatch->startIndex + b].point.magnitudeSquared();
225 ind = tmpPatch->startIndex + b;
229 tmpPatch = tmpPatch->mNextPatch;
232 reducedPatch.contactPoints[0] = ind;
233 const PxVec3 p0 = mOriginalContacts[ind].point;
237 PxReal maxDist = 0.f;
241 for(PxU32 b = 0; b < tmpPatch->stride; ++b)
243 PxReal magSq = (p0 - mOriginalContacts[tmpPatch->startIndex + b].point).magnitudeSquared();
246 ind = tmpPatch->startIndex + b;
250 tmpPatch = tmpPatch->mNextPatch;
253 reducedPatch.contactPoints[1] = ind;
254 const PxVec3 p1 = mOriginalContacts[ind].point;
258 PxVec3 n = (p0 - p1).cross(mIntermediatePatchesPtrs[a]->rootNormal);
262 PxReal maxDist = 0.f;
268 for(PxU32 b = 0; b < tmpPatch->stride; ++b)
272 PxReal magSq = (mOriginalContacts[tmpPatch->startIndex + b].point - p0).dot(n);
275 ind = tmpPatch->startIndex + b;
280 tmpPatch = tmpPatch->mNextPatch;
283 reducedPatch.contactPoints[2] = ind;
290 PxReal maxDist = 0.f;
295 for(PxU32 b = 0; b < tmpPatch->stride; ++b)
297 PxReal magSq = (mOriginalContacts[tmpPatch->startIndex + b].point - p0).dot(dir);
300 ind = tmpPatch->startIndex + b;
304 tmpPatch = tmpPatch->mNextPatch;
307 reducedPatch.contactPoints[3] = ind;
312 PxReal separation[CONTACT_REDUCTION_MAX_CONTACTS];
313 PxU32 deepestInd[CONTACT_REDUCTION_MAX_CONTACTS];
314 for(PxU32 i = 0; i < 4; ++i)
316 PxU32 index = reducedPatch.contactPoints[i];
317 separation[i] = mOriginalContacts[index].separation - PXS_SEPARATION_TOLERANCE;
318 deepestInd[i] = index;
324 for(PxU32 b = 0; b < tmpPatch->stride; ++b)
326 PxContactPoint& point = mOriginalContacts[tmpPatch->startIndex + b];
328 PxReal distance = PX_MAX_REAL;
330 for(PxU32 c = 0; c < 4; ++c)
332 PxVec3 dif = mOriginalContacts[reducedPatch.contactPoints[c]].point - point.point;
342 deepestInd[index] = tmpPatch->startIndex+b;
347 tmpPatch = tmpPatch->mNextPatch;
352 for(PxU32 i = 0; i < 4; ++i)
354 reducedPatch.contactPoints[i] = deepestInd[i];
355 chosen[deepestInd[i]] =
true;
358 for(PxU32 i = 4; i < CONTACT_REDUCTION_MAX_CONTACTS; ++i)
360 separation[i] = PX_MAX_REAL;
363 tmpPatch = mIntermediatePatchesPtrs[a];
366 for(PxU32 b = 0; b < tmpPatch->stride; ++b)
368 if(!chosen[tmpPatch->startIndex+b])
370 PxContactPoint& point = mOriginalContacts[tmpPatch->startIndex + b];
371 for(PxU32 j = 4; j < CONTACT_REDUCTION_MAX_CONTACTS; ++j)
375 for(PxU32 k = CONTACT_REDUCTION_MAX_CONTACTS-1; k > j; --k)
377 separation[k] = separation[k-1];
378 deepestInd[k] = deepestInd[k-1];
381 deepestInd[j] = tmpPatch->startIndex+b;
387 tmpPatch = tmpPatch->mNextPatch;
390 for(PxU32 i = 4; i < CONTACT_REDUCTION_MAX_CONTACTS; ++i)
392 reducedPatch.contactPoints[i] = deepestInd[i];
395 reducedPatch.numContactPoints = CONTACT_REDUCTION_MAX_CONTACTS;
399 mNumPatches = numReducedPatches;