PxContact.h

Go to the documentation of this file.
00001 //
00002 // Redistribution and use in source and binary forms, with or without
00003 // modification, are permitted provided that the following conditions
00004 // are met:
00005 //  * Redistributions of source code must retain the above copyright
00006 //    notice, this list of conditions and the following disclaimer.
00007 //  * Redistributions in binary form must reproduce the above copyright
00008 //    notice, this list of conditions and the following disclaimer in the
00009 //    documentation and/or other materials provided with the distribution.
00010 //  * Neither the name of NVIDIA CORPORATION nor the names of its
00011 //    contributors may be used to endorse or promote products derived
00012 //    from this software without specific prior written permission.
00013 //
00014 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
00015 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00016 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00017 // PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
00018 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00019 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00020 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00021 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00022 // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00023 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00024 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 //
00026 // Copyright (c) 2008-2018 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-2018 NVIDIA Corporation, 2701 San Tomas Expressway, Santa Clara, CA 95050 U.S.A. All rights reserved. www.nvidia.com