PxSimulationEventCallback.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_SIMULATION_EVENT_CALLBACK 00032 #define PX_SIMULATION_EVENT_CALLBACK 00033 00037 #include "foundation/PxVec3.h" 00038 #include "foundation/PxTransform.h" 00039 #include "foundation/PxMemory.h" 00040 #include "PxPhysXConfig.h" 00041 #include "PxFiltering.h" 00042 #include "PxContact.h" 00043 00044 #if !PX_DOXYGEN 00045 namespace physx 00046 { 00047 #endif 00048 00049 class PxShape; 00050 class PxActor; 00051 class PxRigidActor; 00052 class PxRigidBody; 00053 class PxConstraint; 00054 00055 00061 struct PxContactPairExtraDataType 00062 { 00063 enum Enum 00064 { 00065 ePRE_SOLVER_VELOCITY, 00066 ePOST_SOLVER_VELOCITY, 00067 eCONTACT_EVENT_POSE, 00068 eCONTACT_PAIR_INDEX 00069 }; 00070 }; 00071 00072 00078 struct PxContactPairExtraDataItem 00079 { 00080 public: 00081 PX_FORCE_INLINE PxContactPairExtraDataItem() {} 00082 00086 PxU8 type; 00087 }; 00088 00089 00101 struct PxContactPairVelocity : public PxContactPairExtraDataItem 00102 { 00103 public: 00104 PX_FORCE_INLINE PxContactPairVelocity() {} 00105 00109 PxVec3 linearVelocity[2]; 00110 00114 PxVec3 angularVelocity[2]; 00115 }; 00116 00117 00123 struct PxContactPairPose : public PxContactPairExtraDataItem 00124 { 00125 public: 00126 PX_FORCE_INLINE PxContactPairPose() {} 00127 00131 PxTransform globalPose[2]; 00132 }; 00133 00134 00160 struct PxContactPairIndex : public PxContactPairExtraDataItem 00161 { 00162 public: 00163 PX_FORCE_INLINE PxContactPairIndex() {} 00164 00168 PxU16 index; 00169 }; 00170 00171 00177 struct PxContactPairExtraDataIterator 00178 { 00184 PX_FORCE_INLINE PxContactPairExtraDataIterator(const PxU8* stream, PxU32 size) 00185 : currPtr(stream), endPtr(stream + size), contactPairIndex(0) 00186 { 00187 clearDataPtrs(); 00188 } 00189 00208 PX_INLINE bool nextItemSet() 00209 { 00210 clearDataPtrs(); 00211 00212 bool foundEntry = false; 00213 bool endOfItemSet = false; 00214 while ((currPtr < endPtr) && (!endOfItemSet)) 00215 { 00216 const PxContactPairExtraDataItem* edItem = reinterpret_cast<const PxContactPairExtraDataItem*>(currPtr); 00217 PxU8 type = edItem->type; 00218 00219 switch(type) 00220 { 00221 case PxContactPairExtraDataType::ePRE_SOLVER_VELOCITY: 00222 { 00223 PX_ASSERT(!preSolverVelocity); 00224 preSolverVelocity = static_cast<const PxContactPairVelocity*>(edItem); 00225 currPtr += sizeof(PxContactPairVelocity); 00226 foundEntry = true; 00227 } 00228 break; 00229 00230 case PxContactPairExtraDataType::ePOST_SOLVER_VELOCITY: 00231 { 00232 postSolverVelocity = static_cast<const PxContactPairVelocity*>(edItem); 00233 currPtr += sizeof(PxContactPairVelocity); 00234 foundEntry = true; 00235 } 00236 break; 00237 00238 case PxContactPairExtraDataType::eCONTACT_EVENT_POSE: 00239 { 00240 eventPose = static_cast<const PxContactPairPose*>(edItem); 00241 currPtr += sizeof(PxContactPairPose); 00242 foundEntry = true; 00243 } 00244 break; 00245 00246 case PxContactPairExtraDataType::eCONTACT_PAIR_INDEX: 00247 { 00248 if (!foundEntry) 00249 { 00250 contactPairIndex = static_cast<const PxContactPairIndex*>(edItem)->index; 00251 currPtr += sizeof(PxContactPairIndex); 00252 foundEntry = true; 00253 } 00254 else 00255 endOfItemSet = true; 00256 } 00257 break; 00258 00259 default: 00260 return foundEntry; 00261 } 00262 } 00263 00264 return foundEntry; 00265 } 00266 00267 private: 00271 PX_FORCE_INLINE void clearDataPtrs() 00272 { 00273 preSolverVelocity = NULL; 00274 postSolverVelocity = NULL; 00275 eventPose = NULL; 00276 } 00277 00278 public: 00282 const PxU8* currPtr; 00283 00287 const PxU8* endPtr; 00288 00294 const PxContactPairVelocity* preSolverVelocity; 00295 00301 const PxContactPairVelocity* postSolverVelocity; 00302 00308 const PxContactPairPose* eventPose; 00309 00315 PxU32 contactPairIndex; 00316 }; 00317 00318 00324 struct PxContactPairHeaderFlag 00325 { 00326 enum Enum 00327 { 00328 eREMOVED_ACTOR_0 = (1<<0), 00329 eREMOVED_ACTOR_1 = (1<<1) 00330 }; 00331 }; 00332 00338 typedef PxFlags<PxContactPairHeaderFlag::Enum, PxU16> PxContactPairHeaderFlags; 00339 PX_FLAGS_OPERATORS(PxContactPairHeaderFlag::Enum, PxU16) 00340 00341 00342 00347 struct PxContactPairHeader 00348 { 00349 public: 00350 PX_INLINE PxContactPairHeader() {} 00351 00363 PxRigidActor* actors[2]; 00364 00373 const PxU8* extraDataStream; 00374 00378 PxU16 extraDataStreamSize; 00379 00385 PxContactPairHeaderFlags flags; 00386 00390 const struct PxContactPair* pairs; 00391 00395 PxU32 nbPairs; 00396 }; 00397 00398 00404 struct PxContactPairFlag 00405 { 00406 enum Enum 00407 { 00411 eREMOVED_SHAPE_0 = (1<<0), 00412 00416 eREMOVED_SHAPE_1 = (1<<1), 00417 00425 eACTOR_PAIR_HAS_FIRST_TOUCH = (1<<2), 00426 00432 eACTOR_PAIR_LOST_TOUCH = (1<<3), 00433 00440 eINTERNAL_HAS_IMPULSES = (1<<4), 00441 00447 eINTERNAL_CONTACTS_ARE_FLIPPED = (1<<5) 00448 }; 00449 }; 00450 00456 typedef PxFlags<PxContactPairFlag::Enum, PxU16> PxContactPairFlags; 00457 PX_FLAGS_OPERATORS(PxContactPairFlag::Enum, PxU16) 00458 00459 00460 00463 struct PxContactPairPoint 00464 { 00468 PxVec3 position; 00469 00473 PxReal separation; 00474 00478 PxVec3 normal; 00479 00483 PxU32 internalFaceIndex0; 00484 00488 PxVec3 impulse; 00489 00493 PxU32 internalFaceIndex1; 00494 }; 00495 00496 00505 struct PxContactPair 00506 { 00507 public: 00508 PX_INLINE PxContactPair() {} 00509 00521 PxShape* shapes[2]; 00522 00529 const PxU8* contactPatches; 00530 00537 const PxU8* contactPoints; 00538 00545 const PxReal* contactImpulses; 00546 00550 PxU32 requiredBufferSize; 00551 00555 PxU8 contactCount; 00556 00561 PxU8 patchCount; 00562 00567 PxU16 contactStreamSize; 00568 00574 PxContactPairFlags flags; 00575 00598 PxPairFlags events; 00599 00600 PxU32 internalData[2]; // For internal use only 00601 00611 PX_INLINE PxU32 extractContacts(PxContactPairPoint* userBuffer, PxU32 bufferSize) const; 00612 00622 PX_INLINE void bufferContacts(PxContactPair* newPair, PxU8* bufferMemory) const; 00623 00624 PX_INLINE const PxU32* getInternalFaceIndices() const; 00625 }; 00626 00627 00628 PX_INLINE PxU32 PxContactPair::extractContacts(PxContactPairPoint* userBuffer, PxU32 bufferSize) const 00629 { 00630 PxU32 nbContacts = 0; 00631 00632 if(contactCount && bufferSize) 00633 { 00634 PxContactStreamIterator iter(contactPatches, contactPoints, getInternalFaceIndices(), patchCount, contactCount); 00635 00636 const PxReal* impulses = contactImpulses; 00637 00638 const PxU32 flippedContacts = (flags & PxContactPairFlag::eINTERNAL_CONTACTS_ARE_FLIPPED); 00639 const PxU32 hasImpulses = (flags & PxContactPairFlag::eINTERNAL_HAS_IMPULSES); 00640 00641 while(iter.hasNextPatch()) 00642 { 00643 iter.nextPatch(); 00644 while(iter.hasNextContact()) 00645 { 00646 iter.nextContact(); 00647 PxContactPairPoint& dst = userBuffer[nbContacts]; 00648 dst.position = iter.getContactPoint(); 00649 dst.separation = iter.getSeparation(); 00650 dst.normal = iter.getContactNormal(); 00651 if(!flippedContacts) 00652 { 00653 dst.internalFaceIndex0 = iter.getFaceIndex0(); 00654 dst.internalFaceIndex1 = iter.getFaceIndex1(); 00655 } 00656 else 00657 { 00658 dst.internalFaceIndex0 = iter.getFaceIndex1(); 00659 dst.internalFaceIndex1 = iter.getFaceIndex0(); 00660 } 00661 00662 if(hasImpulses) 00663 { 00664 const PxReal impulse = impulses[nbContacts]; 00665 dst.impulse = dst.normal * impulse; 00666 } 00667 else 00668 dst.impulse = PxVec3(0.0f); 00669 ++nbContacts; 00670 if(nbContacts == bufferSize) 00671 return nbContacts; 00672 } 00673 } 00674 } 00675 00676 return nbContacts; 00677 } 00678 00679 00680 PX_INLINE void PxContactPair::bufferContacts(PxContactPair* newPair, PxU8* bufferMemory) const 00681 { 00682 PxU8* patches = bufferMemory; 00683 PxU8* contacts = NULL; 00684 if(patches) 00685 { 00686 contacts = bufferMemory + patchCount * sizeof(PxContactPatch); 00687 PxMemCopy(patches, contactPatches, sizeof(PxContactPatch)*patchCount); 00688 PxMemCopy(contacts, contactPoints, contactStreamSize - (sizeof(PxContactPatch)*patchCount)); 00689 } 00690 00691 if(contactImpulses) 00692 { 00693 PxMemCopy(bufferMemory + ((contactStreamSize + 15) & (~15)), contactImpulses, sizeof(PxReal) * contactCount); 00694 } 00695 00696 if (newPair) 00697 { 00698 *newPair = *this; 00699 newPair->contactPatches = patches; 00700 newPair->contactPoints = contacts; 00701 } 00702 } 00703 00704 00705 PX_INLINE const PxU32* PxContactPair::getInternalFaceIndices() const 00706 { 00707 return reinterpret_cast<const PxU32*>(contactImpulses + contactCount); 00708 } 00709 00715 struct PxTriggerPairFlag 00716 { 00717 enum Enum 00718 { 00719 eREMOVED_SHAPE_TRIGGER = (1<<0), 00720 eREMOVED_SHAPE_OTHER = (1<<1), 00721 eNEXT_FREE = (1<<2) 00722 }; 00723 }; 00724 00730 typedef PxFlags<PxTriggerPairFlag::Enum, PxU8> PxTriggerPairFlags; 00731 PX_FLAGS_OPERATORS(PxTriggerPairFlag::Enum, PxU8) 00732 00733 00734 00746 struct PxTriggerPair 00747 { 00748 PX_INLINE PxTriggerPair() {} 00749 00750 PxShape* triggerShape; 00751 PxRigidActor* triggerActor; 00752 PxShape* otherShape; 00753 PxRigidActor* otherActor; 00754 PxPairFlag::Enum status; 00755 PxTriggerPairFlags flags; 00756 }; 00757 00758 00766 struct PxConstraintInfo 00767 { 00768 PX_INLINE PxConstraintInfo() {} 00769 PX_INLINE PxConstraintInfo(PxConstraint* c, void* extRef, PxU32 t) : constraint(c), externalReference(extRef), type(t) {} 00770 00771 PxConstraint* constraint; 00772 void* externalReference; 00773 PxU32 type; 00774 }; 00775 00776 00793 class PxSimulationEventCallback 00794 { 00795 public: 00808 virtual void onConstraintBreak(PxConstraintInfo* constraints, PxU32 count) = 0; 00809 00826 virtual void onWake(PxActor** actors, PxU32 count) = 0; 00827 00845 virtual void onSleep(PxActor** actors, PxU32 count) = 0; 00846 00863 virtual void onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 nbPairs) = 0; 00864 00880 virtual void onTrigger(PxTriggerPair* pairs, PxU32 count) = 0; 00881 00907 virtual void onAdvance(const PxRigidBody*const* bodyBuffer, const PxTransform* poseBuffer, const PxU32 count) = 0; 00908 00909 virtual ~PxSimulationEventCallback() {} 00910 }; 00911 00912 #if !PX_DOXYGEN 00913 } // namespace physx 00914 #endif 00915 00917 #endif
Copyright © 2008-2017 NVIDIA Corporation, 2701 San Tomas Expressway, Santa Clara, CA 95050 U.S.A. All rights reserved. www.nvidia.com