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_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];
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 }
00914 #endif
00915
00917 #endif