diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Include/PxContact.h | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'PhysX_3.4/Include/PxContact.h')
| -rw-r--r-- | PhysX_3.4/Include/PxContact.h | 583 |
1 files changed, 583 insertions, 0 deletions
diff --git a/PhysX_3.4/Include/PxContact.h b/PhysX_3.4/Include/PxContact.h new file mode 100644 index 00000000..c98e84a3 --- /dev/null +++ b/PhysX_3.4/Include/PxContact.h @@ -0,0 +1,583 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + + +#ifndef PX_CONTACT_H +#define PX_CONTACT_H + +#include "foundation/PxVec3.h" +#include "foundation/PxAssert.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +#if PX_VC +#pragma warning(push) +#pragma warning(disable: 4324) // Padding was added at the end of a structure because of a __declspec(align) value. +#endif + +#define PXC_CONTACT_NO_FACE_INDEX 0xffffffff + +PX_ALIGN_PREFIX(16) +struct PxMassModificationProps +{ + PxReal mInvMassScale0; + PxReal mInvInertiaScale0; + PxReal mInvMassScale1; + PxReal mInvInertiaScale1; +} +PX_ALIGN_SUFFIX(16); + +/** +\brief Header for contact patch where all points share same material and normal +*/ + +PX_ALIGN_PREFIX(16) +struct PxContactPatch +{ + enum PxContactPatchFlags + { + eHAS_FACE_INDICES = 1, //!< Indicates this contact stream has face indices. + eMODIFIABLE = 2, //!< Indicates this contact stream is modifiable. + eFORCE_NO_RESPONSE = 4, //!< Indicates this contact stream is notify-only (no contact response). + eHAS_MODIFIED_MASS_RATIOS = 8, //!< Indicates this contact stream has modified mass ratios + eHAS_TARGET_VELOCITY = 16, //!< Indicates this contact stream has target velocities set + eHAS_MAX_IMPULSE = 32, //!< Indicates this contact stream has max impulses set + eREGENERATE_PATCHES = 64, //!< Indicates this contact stream needs patches re-generated. + //!< This is required if the application modified either the contact normal or the material properties + eCOMPRESSED_MODIFIED_CONTACT = 128 + }; + + PX_ALIGN(16, PxMassModificationProps mMassModification); //16 + /** + \brief Contact normal + */ + PX_ALIGN(16, PxVec3 normal); //28 + /** + \brief Restitution coefficient + */ + PxReal restitution; //32 + + PxReal dynamicFriction; //36 + PxReal staticFriction; //40 + PxU8 startContactIndex; //41 + PxU8 nbContacts; //42 //Can be a U8 + + PxU8 materialFlags; //43 //Can be a U16 + PxU8 internalFlags; //44 //Can be a U16 + PxU16 materialIndex0; //46 //Can be a U16 + PxU16 materialIndex1; //48 //Can be a U16 + + +} +PX_ALIGN_SUFFIX(16); + +/** +\brief Contact point data including face (feature) indices +*/ + +PX_ALIGN_PREFIX(16) +struct PxContact +{ + /** + \brief Contact point in world space + */ + PxVec3 contact; //12 + /** + \brief Separation value (negative implies penetration). + */ + PxReal separation; //16 +} +PX_ALIGN_SUFFIX(16); + +PX_ALIGN_PREFIX(16) +struct PxExtendedContact : public PxContact +{ + /** + \brief Target velocity + */ + PX_ALIGN(16, PxVec3 targetVelocity); //28 + /** + \brief Maximum impulse + */ + PxReal maxImpulse; //32 +} +PX_ALIGN_SUFFIX(16); + +/** +\brief A modifiable contact point. This has additional fields per-contact to permit modification by user. +\note Not all fields are currently exposed to the user. +*/ +PX_ALIGN_PREFIX(16) +struct PxModifiableContact : public PxExtendedContact +{ + /** + \brief Contact normal + */ + PX_ALIGN(16, PxVec3 normal); //44 + /** + \brief Restitution coefficient + */ + PxReal restitution; //48 + + /** + \brief Material Flags + */ + PxU32 materialFlags; //52 + + /** + \brief Shape A's material index + */ + PxU16 materialIndex0; //54 + /** + \brief Shape B's material index + */ + PxU16 materialIndex1; //56 + /** + \brief static friction coefficient + */ + PxReal staticFriction; //60 + /** + \brief dynamic friction coefficient + */ + PxReal dynamicFriction; //64 +} +PX_ALIGN_SUFFIX(16); + +/** +\brief A class to iterate over a compressed contact stream. This supports read-only access to the various contact formats. +*/ +struct PxContactStreamIterator +{ + enum StreamFormat + { + eSIMPLE_STREAM, + eMODIFIABLE_STREAM, + eCOMPRESSED_MODIFIABLE_STREAM + }; + /** + \brief Utility zero vector to optimize functions returning zero vectors when a certain flag isn't set. + \note This allows us to return by reference instead of having to return by value. Returning by value will go via memory (registers -> stack -> registers), which can + cause performance issues on certain platforms. + */ + PxVec3 zero; + /** + \brief The patch headers. + */ + const PxContactPatch* patch; + + /** + \brief The contacts + */ + const PxContact* contact; + + /** + \brief The contact triangle face index + */ + const PxU32* faceIndice; + + + /** + \brief The total number of patches in this contact stream + */ + PxU32 totalPatches; + + /** + \brief The total number of contact points in this stream + */ + PxU32 totalContacts; + + /** + \brief The current contact index + */ + PxU32 nextContactIndex; + + /** + \brief The current patch Index + */ + PxU32 nextPatchIndex; + + /* + \brief Size of contact patch header + \note This varies whether the patch is modifiable or not. + */ + PxU32 contactPatchHeaderSize; + /** + \brief Contact point size + \note This varies whether the patch has feature indices or is modifiable. + */ + PxU32 contactPointSize; + /** + \brief The stream format + */ + StreamFormat mStreamFormat; + /** + \brief Indicates whether this stream is notify-only or not. + */ + PxU32 forceNoResponse; + + bool pointStepped; + + PxU32 hasFaceIndices; + + /** + \brief Constructor + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxContactStreamIterator(const PxU8* contactPatches, const PxU8* contactPoints, const PxU32* contactFaceIndices, PxU32 nbPatches, PxU32 nbContacts) + : zero(0.f) + { + bool modify = false; + bool compressedModify = false; + bool response = false; + bool indices = false; + + PxU32 pointSize = 0; + PxU32 patchHeaderSize = sizeof(PxContactPatch); + + const PxContactPatch* patches = reinterpret_cast<const PxContactPatch*>(contactPatches); + + if(patches) + { + modify = (patches->internalFlags & PxContactPatch::eMODIFIABLE) != 0; + compressedModify = (patches->internalFlags & PxContactPatch::eCOMPRESSED_MODIFIED_CONTACT) != 0; + indices = (patches->internalFlags & PxContactPatch::eHAS_FACE_INDICES) != 0; + + patch = patches; + + contact = reinterpret_cast<const PxContact*>(contactPoints); + + faceIndice = contactFaceIndices; + + pointSize = compressedModify ? sizeof(PxExtendedContact) : modify ? sizeof(PxModifiableContact) : sizeof(PxContact); + + response = (patch->internalFlags & PxContactPatch::eFORCE_NO_RESPONSE) == 0; + } + + + mStreamFormat = compressedModify ? eCOMPRESSED_MODIFIABLE_STREAM : modify ? eMODIFIABLE_STREAM : eSIMPLE_STREAM; + hasFaceIndices = PxU32(indices); + forceNoResponse = PxU32(!response); + + contactPatchHeaderSize = patchHeaderSize; + contactPointSize = pointSize; + nextPatchIndex = 0; + nextContactIndex = 0; + totalContacts = nbContacts; + totalPatches = nbPatches; + + pointStepped = false; + } + + /** + \brief Returns whether there are more patches in this stream. + \return Whether there are more patches in this stream. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE bool hasNextPatch() const + { + return nextPatchIndex < totalPatches; + } + + /** + \brief Returns the total contact count. + \return Total contact count. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getTotalContactCount() const + { + return totalContacts; + } + + PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getTotalPatchCount() const + { + return totalPatches; + } + + /** + \brief Advances iterator to next contact patch. + */ + PX_CUDA_CALLABLE PX_INLINE void nextPatch() + { + PX_ASSERT(nextPatchIndex < totalPatches); + if(nextPatchIndex) + { + if(nextContactIndex < patch->nbContacts) + { + PxU32 nbToStep = patch->nbContacts - this->nextContactIndex; + contact = reinterpret_cast<const PxContact*>(reinterpret_cast<const PxU8*>(contact) + contactPointSize * nbToStep); + } + patch = reinterpret_cast<const PxContactPatch*>(reinterpret_cast<const PxU8*>(patch) + contactPatchHeaderSize); + } + nextPatchIndex++; + nextContactIndex = 0; + } + + /** + \brief Returns if the current patch has more contacts. + \return If there are more contacts in the current patch. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE bool hasNextContact() const + { + return nextContactIndex < (patch->nbContacts); + } + + /** + \brief Advances to the next contact in the patch. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE void nextContact() + { + PX_ASSERT(nextContactIndex < patch->nbContacts); + if(pointStepped) + { + contact = reinterpret_cast<const PxContact*>(reinterpret_cast<const PxU8*>(contact) + contactPointSize); + faceIndice++; + } + nextContactIndex++; + pointStepped = true; + } + + + /** + \brief Gets the current contact's normal + \return The current contact's normal. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3& getContactNormal() const + { + return getContactPatch().normal; + } + + /** + \brief Gets the inverse mass scale for body 0. + \return The inverse mass scale for body 0. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getInvMassScale0() const + { + return patch->mMassModification.mInvMassScale0; + } + + /** + \brief Gets the inverse mass scale for body 1. + \return The inverse mass scale for body 1. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getInvMassScale1() const + { + return patch->mMassModification.mInvMassScale1; + } + + /** + \brief Gets the inverse inertia scale for body 0. + \return The inverse inertia scale for body 0. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getInvInertiaScale0() const + { + return patch->mMassModification.mInvInertiaScale0; + } + + /** + \brief Gets the inverse inertia scale for body 1. + \return The inverse inertia scale for body 1. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getInvInertiaScale1() const + { + return patch->mMassModification.mInvInertiaScale1; + } + + /** + \brief Gets the contact's max impulse. + \return The contact's max impulse. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getMaxImpulse() const + { + return mStreamFormat != eSIMPLE_STREAM ? getExtendedContact().maxImpulse : PX_MAX_REAL; + } + + /** + \brief Gets the contact's target velocity. + \return The contact's target velocity. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3& getTargetVel() const + { + return mStreamFormat != eSIMPLE_STREAM ? getExtendedContact().targetVelocity : zero; + } + + /** + \brief Gets the contact's contact point. + \return The contact's contact point. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3& getContactPoint() const + { + return contact->contact; + } + + /** + \brief Gets the contact's separation. + \return The contact's separation. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getSeparation() const + { + return contact->separation; + } + + /** + \brief Gets the contact's face index for shape 0. + \return The contact's face index for shape 0. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getFaceIndex0() const + { + return PXC_CONTACT_NO_FACE_INDEX; + } + + /** + \brief Gets the contact's face index for shape 1. + \return The contact's face index for shape 1. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getFaceIndex1() const + { + return hasFaceIndices ? *faceIndice : PXC_CONTACT_NO_FACE_INDEX; + } + + /** + \brief Gets the contact's static friction coefficient. + \return The contact's static friction coefficient. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getStaticFriction() const + { + return getContactPatch().staticFriction; + } + + /** + \brief Gets the contact's static dynamic coefficient. + \return The contact's static dynamic coefficient. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getDynamicFriction() const + { + return getContactPatch().dynamicFriction; + } + + /** + \brief Gets the contact's restitution coefficient. + \return The contact's restitution coefficient. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getRestitution() const + { + return getContactPatch().restitution; + } + + /** + \brief Gets the contact's material flags. + \return The contact's material flags. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getMaterialFlags() const + { + return getContactPatch().materialFlags; + } + + /** + \brief Gets the contact's material index for shape 0. + \return The contact's material index for shape 0. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxU16 getMaterialIndex0() const + { + return PxU16(getContactPatch().materialIndex0); + } + + /** + \brief Gets the contact's material index for shape 1. + \return The contact's material index for shape 1. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxU16 getMaterialIndex1() const + { + return PxU16(getContactPatch().materialIndex1); + } + + /** + \brief Advances the contact stream iterator to a specific contact index. + */ + bool advanceToIndex(const PxU32 initialIndex) + { + PX_ASSERT(this->nextPatchIndex == 0 && this->nextContactIndex == 0); + + PxU32 numToAdvance = initialIndex; + + if(numToAdvance == 0) + { + PX_ASSERT(hasNextPatch()); + nextPatch(); + return true; + } + + while(numToAdvance) + { + while(hasNextPatch()) + { + nextPatch(); + PxU32 patchSize = patch->nbContacts; + if(numToAdvance <= patchSize) + { + contact = reinterpret_cast<const PxContact*>(reinterpret_cast<const PxU8*>(contact) + contactPointSize * numToAdvance); + nextContactIndex += numToAdvance; + return true; + } + else + { + numToAdvance -= patchSize; + } + } + } + return false; + } + +private: + + /** + \brief Internal helper + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE const PxContactPatch& getContactPatch() const + { + return *static_cast<const PxContactPatch*>(patch); + } + + PX_CUDA_CALLABLE PX_FORCE_INLINE const PxExtendedContact& getExtendedContact() const + { + PX_ASSERT(mStreamFormat == eMODIFIABLE_STREAM || mStreamFormat == eCOMPRESSED_MODIFIABLE_STREAM); + return *static_cast<const PxExtendedContact*>(contact); + } + +}; + + +#if PX_VC +#pragma warning(pop) +#endif + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif |