00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef PX_CONTACT_H
00032 #define PX_CONTACT_H
00033
00034 #include "foundation/PxVec3.h"
00035 #include "foundation/PxAssert.h"
00036
00037 #if !PX_DOXYGEN
00038 namespace physx
00039 {
00040 #endif
00041
00042 #if PX_VC
00043 #pragma warning(push)
00044 #pragma warning(disable: 4324) // Padding was added at the end of a structure because of a __declspec(align) value.
00045 #endif
00046
00047 #define PXC_CONTACT_NO_FACE_INDEX 0xffffffff
00048
00049 PX_ALIGN_PREFIX(16)
00050 struct PxMassModificationProps
00051 {
00052 PxReal mInvMassScale0;
00053 PxReal mInvInertiaScale0;
00054 PxReal mInvMassScale1;
00055 PxReal mInvInertiaScale1;
00056 }
00057 PX_ALIGN_SUFFIX(16);
00058
00063 PX_ALIGN_PREFIX(16)
00064 struct PxContactPatch
00065 {
00066 enum PxContactPatchFlags
00067 {
00068 eHAS_FACE_INDICES = 1,
00069 eMODIFIABLE = 2,
00070 eFORCE_NO_RESPONSE = 4,
00071 eHAS_MODIFIED_MASS_RATIOS = 8,
00072 eHAS_TARGET_VELOCITY = 16,
00073 eHAS_MAX_IMPULSE = 32,
00074 eREGENERATE_PATCHES = 64,
00075
00076 eCOMPRESSED_MODIFIED_CONTACT = 128
00077 };
00078
00079 PX_ALIGN(16, PxMassModificationProps mMassModification);
00083 PX_ALIGN(16, PxVec3 normal);
00087 PxReal restitution;
00088
00089 PxReal dynamicFriction;
00090 PxReal staticFriction;
00091 PxU8 startContactIndex;
00092 PxU8 nbContacts;
00093
00094 PxU8 materialFlags;
00095 PxU8 internalFlags;
00096 PxU16 materialIndex0;
00097 PxU16 materialIndex1;
00098
00099
00100 }
00101 PX_ALIGN_SUFFIX(16);
00102
00107 PX_ALIGN_PREFIX(16)
00108 struct PxContact
00109 {
00113 PxVec3 contact;
00117 PxReal separation;
00118 }
00119 PX_ALIGN_SUFFIX(16);
00120
00121 PX_ALIGN_PREFIX(16)
00122 struct PxExtendedContact : public PxContact
00123 {
00127 PX_ALIGN(16, PxVec3 targetVelocity);
00131 PxReal maxImpulse;
00132 }
00133 PX_ALIGN_SUFFIX(16);
00134
00139 PX_ALIGN_PREFIX(16)
00140 struct PxModifiableContact : public PxExtendedContact
00141 {
00145 PX_ALIGN(16, PxVec3 normal);
00149 PxReal restitution;
00150
00154 PxU32 materialFlags;
00155
00159 PxU16 materialIndex0;
00163 PxU16 materialIndex1;
00167 PxReal staticFriction;
00171 PxReal dynamicFriction;
00172 }
00173 PX_ALIGN_SUFFIX(16);
00174
00178 struct PxContactStreamIterator
00179 {
00180 enum StreamFormat
00181 {
00182 eSIMPLE_STREAM,
00183 eMODIFIABLE_STREAM,
00184 eCOMPRESSED_MODIFIABLE_STREAM
00185 };
00191 PxVec3 zero;
00195 const PxContactPatch* patch;
00196
00200 const PxContact* contact;
00201
00205 const PxU32* faceIndice;
00206
00207
00211 PxU32 totalPatches;
00212
00216 PxU32 totalContacts;
00217
00221 PxU32 nextContactIndex;
00222
00226 PxU32 nextPatchIndex;
00227
00228
00229
00230
00231
00232 PxU32 contactPatchHeaderSize;
00237 PxU32 contactPointSize;
00241 StreamFormat mStreamFormat;
00245 PxU32 forceNoResponse;
00246
00247 bool pointStepped;
00248
00249 PxU32 hasFaceIndices;
00250
00254 PX_CUDA_CALLABLE PX_FORCE_INLINE PxContactStreamIterator(const PxU8* contactPatches, const PxU8* contactPoints, const PxU32* contactFaceIndices, PxU32 nbPatches, PxU32 nbContacts)
00255 : zero(0.f)
00256 {
00257 bool modify = false;
00258 bool compressedModify = false;
00259 bool response = false;
00260 bool indices = false;
00261
00262 PxU32 pointSize = 0;
00263 PxU32 patchHeaderSize = sizeof(PxContactPatch);
00264
00265 const PxContactPatch* patches = reinterpret_cast<const PxContactPatch*>(contactPatches);
00266
00267 if(patches)
00268 {
00269 modify = (patches->internalFlags & PxContactPatch::eMODIFIABLE) != 0;
00270 compressedModify = (patches->internalFlags & PxContactPatch::eCOMPRESSED_MODIFIED_CONTACT) != 0;
00271 indices = (patches->internalFlags & PxContactPatch::eHAS_FACE_INDICES) != 0;
00272
00273 patch = patches;
00274
00275 contact = reinterpret_cast<const PxContact*>(contactPoints);
00276
00277 faceIndice = contactFaceIndices;
00278
00279 pointSize = compressedModify ? sizeof(PxExtendedContact) : modify ? sizeof(PxModifiableContact) : sizeof(PxContact);
00280
00281 response = (patch->internalFlags & PxContactPatch::eFORCE_NO_RESPONSE) == 0;
00282 }
00283
00284
00285 mStreamFormat = compressedModify ? eCOMPRESSED_MODIFIABLE_STREAM : modify ? eMODIFIABLE_STREAM : eSIMPLE_STREAM;
00286 hasFaceIndices = PxU32(indices);
00287 forceNoResponse = PxU32(!response);
00288
00289 contactPatchHeaderSize = patchHeaderSize;
00290 contactPointSize = pointSize;
00291 nextPatchIndex = 0;
00292 nextContactIndex = 0;
00293 totalContacts = nbContacts;
00294 totalPatches = nbPatches;
00295
00296 pointStepped = false;
00297 }
00298
00303 PX_CUDA_CALLABLE PX_FORCE_INLINE bool hasNextPatch() const
00304 {
00305 return nextPatchIndex < totalPatches;
00306 }
00307
00312 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getTotalContactCount() const
00313 {
00314 return totalContacts;
00315 }
00316
00317 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getTotalPatchCount() const
00318 {
00319 return totalPatches;
00320 }
00321
00325 PX_CUDA_CALLABLE PX_INLINE void nextPatch()
00326 {
00327 PX_ASSERT(nextPatchIndex < totalPatches);
00328 if(nextPatchIndex)
00329 {
00330 if(nextContactIndex < patch->nbContacts)
00331 {
00332 PxU32 nbToStep = patch->nbContacts - this->nextContactIndex;
00333 contact = reinterpret_cast<const PxContact*>(reinterpret_cast<const PxU8*>(contact) + contactPointSize * nbToStep);
00334 }
00335 patch = reinterpret_cast<const PxContactPatch*>(reinterpret_cast<const PxU8*>(patch) + contactPatchHeaderSize);
00336 }
00337 nextPatchIndex++;
00338 nextContactIndex = 0;
00339 }
00340
00345 PX_CUDA_CALLABLE PX_FORCE_INLINE bool hasNextContact() const
00346 {
00347 return nextContactIndex < (patch->nbContacts);
00348 }
00349
00353 PX_CUDA_CALLABLE PX_FORCE_INLINE void nextContact()
00354 {
00355 PX_ASSERT(nextContactIndex < patch->nbContacts);
00356 if(pointStepped)
00357 {
00358 contact = reinterpret_cast<const PxContact*>(reinterpret_cast<const PxU8*>(contact) + contactPointSize);
00359 faceIndice++;
00360 }
00361 nextContactIndex++;
00362 pointStepped = true;
00363 }
00364
00365
00370 PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3& getContactNormal() const
00371 {
00372 return getContactPatch().normal;
00373 }
00374
00379 PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getInvMassScale0() const
00380 {
00381 return patch->mMassModification.mInvMassScale0;
00382 }
00383
00388 PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getInvMassScale1() const
00389 {
00390 return patch->mMassModification.mInvMassScale1;
00391 }
00392
00397 PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getInvInertiaScale0() const
00398 {
00399 return patch->mMassModification.mInvInertiaScale0;
00400 }
00401
00406 PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getInvInertiaScale1() const
00407 {
00408 return patch->mMassModification.mInvInertiaScale1;
00409 }
00410
00415 PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getMaxImpulse() const
00416 {
00417 return mStreamFormat != eSIMPLE_STREAM ? getExtendedContact().maxImpulse : PX_MAX_REAL;
00418 }
00419
00424 PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3& getTargetVel() const
00425 {
00426 return mStreamFormat != eSIMPLE_STREAM ? getExtendedContact().targetVelocity : zero;
00427 }
00428
00433 PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3& getContactPoint() const
00434 {
00435 return contact->contact;
00436 }
00437
00442 PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getSeparation() const
00443 {
00444 return contact->separation;
00445 }
00446
00451 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getFaceIndex0() const
00452 {
00453 return PXC_CONTACT_NO_FACE_INDEX;
00454 }
00455
00460 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getFaceIndex1() const
00461 {
00462 return hasFaceIndices ? *faceIndice : PXC_CONTACT_NO_FACE_INDEX;
00463 }
00464
00469 PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getStaticFriction() const
00470 {
00471 return getContactPatch().staticFriction;
00472 }
00473
00478 PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getDynamicFriction() const
00479 {
00480 return getContactPatch().dynamicFriction;
00481 }
00482
00487 PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getRestitution() const
00488 {
00489 return getContactPatch().restitution;
00490 }
00491
00496 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getMaterialFlags() const
00497 {
00498 return getContactPatch().materialFlags;
00499 }
00500
00505 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU16 getMaterialIndex0() const
00506 {
00507 return PxU16(getContactPatch().materialIndex0);
00508 }
00509
00514 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU16 getMaterialIndex1() const
00515 {
00516 return PxU16(getContactPatch().materialIndex1);
00517 }
00518
00522 bool advanceToIndex(const PxU32 initialIndex)
00523 {
00524 PX_ASSERT(this->nextPatchIndex == 0 && this->nextContactIndex == 0);
00525
00526 PxU32 numToAdvance = initialIndex;
00527
00528 if(numToAdvance == 0)
00529 {
00530 PX_ASSERT(hasNextPatch());
00531 nextPatch();
00532 return true;
00533 }
00534
00535 while(numToAdvance)
00536 {
00537 while(hasNextPatch())
00538 {
00539 nextPatch();
00540 PxU32 patchSize = patch->nbContacts;
00541 if(numToAdvance <= patchSize)
00542 {
00543 contact = reinterpret_cast<const PxContact*>(reinterpret_cast<const PxU8*>(contact) + contactPointSize * numToAdvance);
00544 nextContactIndex += numToAdvance;
00545 return true;
00546 }
00547 else
00548 {
00549 numToAdvance -= patchSize;
00550 }
00551 }
00552 }
00553 return false;
00554 }
00555
00556 private:
00557
00561 PX_CUDA_CALLABLE PX_FORCE_INLINE const PxContactPatch& getContactPatch() const
00562 {
00563 return *static_cast<const PxContactPatch*>(patch);
00564 }
00565
00566 PX_CUDA_CALLABLE PX_FORCE_INLINE const PxExtendedContact& getExtendedContact() const
00567 {
00568 PX_ASSERT(mStreamFormat == eMODIFIABLE_STREAM || mStreamFormat == eCOMPRESSED_MODIFIABLE_STREAM);
00569 return *static_cast<const PxExtendedContact*>(contact);
00570 }
00571
00572 };
00573
00574
00575 #if PX_VC
00576 #pragma warning(pop)
00577 #endif
00578
00579 #if !PX_DOXYGEN
00580 }
00581 #endif
00582
00583 #endif