PxSimulationEventCallback.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_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-2018 NVIDIA Corporation, 2701 San Tomas Expressway, Santa Clara, CA 95050 U.S.A. All rights reserved. www.nvidia.com