PxContact.h
Go to the documentation of this file.00001 // This code contains NVIDIA Confidential Information and is disclosed to you 00002 // under a form of NVIDIA software license agreement provided separately to you. 00003 // 00004 // Notice 00005 // NVIDIA Corporation and its licensors retain all intellectual property and 00006 // proprietary rights in and to this software and related documentation and 00007 // any modifications thereto. Any use, reproduction, disclosure, or 00008 // distribution of this software and related documentation without an express 00009 // license agreement from NVIDIA Corporation is strictly prohibited. 00010 // 00011 // ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES 00012 // NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO 00013 // THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, 00014 // MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. 00015 // 00016 // Information and code furnished is believed to be accurate and reliable. 00017 // However, NVIDIA Corporation assumes no responsibility for the consequences of use of such 00018 // information or for any infringement of patents or other rights of third parties that may 00019 // result from its use. No license is granted by implication or otherwise under any patent 00020 // or patent rights of NVIDIA Corporation. Details are subject to change without notice. 00021 // This code supersedes and replaces all information previously supplied. 00022 // NVIDIA Corporation products are not authorized for use as critical 00023 // components in life support devices or systems without express written approval of 00024 // NVIDIA Corporation. 00025 // 00026 // Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. 00027 // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. 00028 // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. 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); //16 00083 PX_ALIGN(16, PxVec3 normal); //28 00087 PxReal restitution; //32 00088 00089 PxReal dynamicFriction; //36 00090 PxReal staticFriction; //40 00091 PxU8 startContactIndex; //41 00092 PxU8 nbContacts; //42 //Can be a U8 00093 00094 PxU8 materialFlags; //43 //Can be a U16 00095 PxU8 internalFlags; //44 //Can be a U16 00096 PxU16 materialIndex0; //46 //Can be a U16 00097 PxU16 materialIndex1; //48 //Can be a U16 00098 00099 00100 } 00101 PX_ALIGN_SUFFIX(16); 00102 00107 PX_ALIGN_PREFIX(16) 00108 struct PxContact 00109 { 00113 PxVec3 contact; //12 00117 PxReal separation; //16 00118 } 00119 PX_ALIGN_SUFFIX(16); 00120 00121 PX_ALIGN_PREFIX(16) 00122 struct PxExtendedContact : public PxContact 00123 { 00127 PX_ALIGN(16, PxVec3 targetVelocity); //28 00131 PxReal maxImpulse; //32 00132 } 00133 PX_ALIGN_SUFFIX(16); 00134 00139 PX_ALIGN_PREFIX(16) 00140 struct PxModifiableContact : public PxExtendedContact 00141 { 00145 PX_ALIGN(16, PxVec3 normal); //44 00149 PxReal restitution; //48 00150 00154 PxU32 materialFlags; //52 00155 00159 PxU16 materialIndex0; //54 00163 PxU16 materialIndex1; //56 00167 PxReal staticFriction; //60 00171 PxReal dynamicFriction; //64 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 \brief Size of contact patch header 00230 \note This varies whether the patch is modifiable or not. 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 } // namespace physx 00581 #endif 00582 00583 #endif
Copyright © 2008-2017 NVIDIA Corporation, 2701 San Tomas Expressway, Santa Clara, CA 95050 U.S.A. All rights reserved. www.nvidia.com