aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/LowLevel/software/include
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Source/LowLevel/software/include
downloadphysx-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/Source/LowLevel/software/include')
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsBodySim.h52
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsCCD.h617
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsContactManager.h178
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsContactManagerState.h95
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsContext.h369
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsDefaultMemoryManager.h98
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsHeapMemoryAllocator.h68
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsIncrementalConstraintPartitioning.h40
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsIslandManagerTypes.h372
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsIslandSim.h965
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsKernelWrangler.h50
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsMaterialCombiner.h143
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsMemoryManager.h62
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsNphaseImplementationContext.h142
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsRigidBody.h168
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsShapeSim.h52
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsSimpleIslandManager.h207
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsSimulationController.h135
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxsTransformCache.h144
-rw-r--r--PhysX_3.4/Source/LowLevel/software/include/PxvNphaseImplementationContext.h220
20 files changed, 4177 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsBodySim.h b/PhysX_3.4/Source/LowLevel/software/include/PxsBodySim.h
new file mode 100644
index 00000000..93aafc41
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsBodySim.h
@@ -0,0 +1,52 @@
+// 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 PXS_BODYSIM_H
+#define PXS_BODYSIM_H
+
+#include "PxsRigidBody.h"
+
+namespace physx
+{
+
+struct PxsBodySim
+{
+public:
+ PxsBodySim() : mRigidBody(NULL), mBodySimIndex(0xffffffff), mUpdated(0)
+ {
+ }
+
+ PxsRigidBody* mRigidBody; //4 or 8
+ PxU32 mBodySimIndex; //8 or 12
+ PxU32 mUpdated; //12 or 16
+};
+
+}//physx
+
+#endif
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsCCD.h b/PhysX_3.4/Source/LowLevel/software/include/PxsCCD.h
new file mode 100644
index 00000000..32ec53d3
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsCCD.h
@@ -0,0 +1,617 @@
+// 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.
+
+#include "Ps.h"
+#include "PxGeometry.h"
+#include "GuCCDSweepConvexMesh.h"
+#include "PsHashMap.h"
+
+#ifndef PXS_CCD_H
+#define PXS_CCD_H
+
+#define CCD_DEBUG_PRINTS 0
+#define CCD_POST_DEPENETRATE_DIST 0.001f
+#define CCD_ROTATION_LOCKING 0
+#define CCD_MIN_TIME_LEFT 0.01f
+#define CCD_ANGULAR_IMPULSE 0
+
+#define DEBUG_RENDER_CCD 0
+
+#if CCD_DEBUG_PRINTS
+namespace physx {
+ extern void printCCDDebug(const char* msg, const PxsRigidBody* atom0, PxGeometryType::Enum g0, bool printPtr = true);
+ extern void printShape(PxsRigidBody* atom0, PxGeometryType::Enum g0, const char* annotation, PxReal dt, PxU32 pass, bool printPtr = true);
+}
+#define PRINTCCDSHAPE(x) printShape x
+#define PRINTCCDDEBUG(x) printCCDDebug x
+#else
+#define PRINTCCDSHAPE(x)
+#define PRINTCCDDEBUG(x)
+#endif
+
+namespace physx
+{
+
+// ------------------------------------------------------------------------------------------------------------
+// a fraction of objects will be CCD active so this is dynamic, not a member of PsxRigidBody
+// CCD code builds a temporary array of PxsCCDPair objects (allocated in blocks)
+// this is done to gather scattered data from memory and also to reduce PxsRidigBody permanent memory footprint
+// we have to do it every pass since new CMs can become fast moving after each pass (and sometimes cease to be)
+//
+struct PxsCCDBody;
+class PxsRigidBody;
+struct PxsShapeCore;
+struct PxsRigidCore;
+class PxsContactManager;
+class PxsContext;
+class PxCCDContactModifyCallback;
+class PxcNpThreadContext;
+
+class PxvNphaseImplementationContext;
+
+namespace Dy
+{
+ class ThresholdStream;
+}
+
+
+/**
+\brief structure to represent interactions between a given body and another body.
+*/
+struct PxsCCDOverlap
+{
+ //The body the interaction relates to
+ PxsCCDBody* mBody;
+ //The next interaction in the list
+ PxsCCDOverlap* mNext;
+};
+
+/**
+\brief Temporary CCD representation for a shape.
+
+Stores data about a shape that may be frequently used in CCD. It also stores update counters per-shape that can be compared with the body's update
+counter to determine if the shape needs its transforms re-calculated. This avoids us needing to store a list of shapes in a CCD body.
+*/
+struct PxsCCDShape : Gu::CCDShape
+{
+public:
+ const PxsShapeCore* mShapeCore; //Shape core (can be shared)
+ const PxsRigidCore* mRigidCore; //Rigid body core
+
+ /**
+ \brief Returns the world-space pose for this shape
+ \param[in] atom The rigid body that this CCD shape is associated with
+ */
+ PxTransform getAbsPose(const PxsRigidBody* atom) const;
+ /**
+ \brief Returns the world-space previous pose for this shape
+ \param[in] atom The rigid body that this CCD shape is associated with
+ */
+ PxTransform getLastCCDAbsPose(const PxsRigidBody* atom) const;
+};
+
+/**
+\brief Structure to represent a body in the CCD system.
+*/
+struct PxsCCDBody
+{
+ Cm::SpatialVector mPreSolverVelocity;
+ PxU16 mIndex; //The CCD body's index
+ bool mPassDone; //Whether it has been processed in the current CCD pass
+ bool mHasAnyPassDone; //Whether this body was influenced by any passes
+ PxReal mTimeLeft; //CCD time left to elapse (normalized in range 0-1)
+ PxsRigidBody* mBody; //The rigid body
+ PxsCCDOverlap* mOverlappingObjects; //A list of overlapping bodies for island update
+ PxU32 mUpdateCount; //How many times this body has eben updated in the CCD. This is correlated with CCD shapes' update counts.
+
+
+
+ /**
+ \brief Returns the CCD body's index.
+ \return The CCD body's index.
+ */
+ PX_FORCE_INLINE PxU32 getIndex() const { return mIndex; }
+
+ /**
+ \brief Tests whether this body has already registered an overlap with a given body.
+ \param[in] body The body to test against.
+ \return Whether this body has already registered an overlap with a given body.
+ */
+ bool overlaps(PxsCCDBody* body) const
+ {
+ PxsCCDOverlap* overlaps = mOverlappingObjects;
+
+ while(overlaps)
+ {
+ if(overlaps->mBody == body)
+ return true;
+ overlaps = overlaps->mNext;
+ }
+ return false;
+ }
+
+ /**
+ \brief Registers an overlap with a given body
+ \param[in] overlap The CCD overlap to register.
+ */
+ void addOverlap(PxsCCDOverlap* overlap)
+ {
+ overlap->mNext = mOverlappingObjects;
+ mOverlappingObjects = overlap;
+ }
+
+};
+
+/**
+\brief a container class used in the CCD that minimizes frequency of hitting the allocator.
+
+This class stores a set of blocks of memory. It is effectively an array that resizes more efficiently because it doesn't need to
+reallocate an entire buffer and copy data.
+*/
+template<typename T, int BLOCK_SIZE>
+struct PxsCCDBlockArray
+{
+ /**
+ \brief A block of data
+ */
+ struct Block : Ps::UserAllocated { T items[BLOCK_SIZE]; };
+ /**
+ \brief A header for a block of data.
+ */
+ struct BlockInfo
+ {
+ Block* block;
+ PxU32 count; // number of elements in this block
+ BlockInfo(Block* aBlock, PxU32 aCount) : block(aBlock), count(aCount) {}
+ };
+ /*
+ \brief An array of block headers
+ */
+ Ps::Array<BlockInfo> blocks;
+ /**
+ \brief The current block.
+ */
+ PxU32 currentBlock;
+
+ /**
+ \brief Constructor
+ */
+ PxsCCDBlockArray() : currentBlock(0)
+ {
+ blocks.pushBack(BlockInfo(PX_NEW(Block), 0));
+ }
+
+ /**
+ \brief Destructor
+ */
+ ~PxsCCDBlockArray()
+ {
+ for (PxU32 i = 0; i < blocks.size(); i++)
+ {
+ PX_DELETE(blocks[i].block);
+ }
+ currentBlock = 0;
+ }
+
+ /**
+ \brief Clears this block array.
+ \note This clear function also deletes all additional blocks
+ */
+ void clear()
+ {
+ for (PxU32 i = 0; i < blocks.size(); i++)
+ {
+ PX_DELETE(blocks[i].block);
+ }
+ blocks.clear();
+ blocks.pushBack(BlockInfo(PX_NEW(Block), 0)); // at least one block is expected to always be present in the array
+ currentBlock = 0;
+ }
+
+ /**
+ \brief Clears this block array but does not release the memory.
+ */
+ void clear_NoDelete()
+ {
+ currentBlock = 0;
+ blocks[0].count = 0;
+ }
+
+ /**
+ \brief Push a new element onto the back of the block array
+ \return The new element
+ */
+ T& pushBack()
+ {
+ PxU32 numBlocks = blocks.size();
+ if (blocks[currentBlock].count == BLOCK_SIZE)
+ {
+ if((currentBlock + 1) == numBlocks)
+ {
+ blocks.pushBack(BlockInfo(PX_NEW(Block), 0));
+ numBlocks ++;
+ }
+ currentBlock++;
+ blocks[currentBlock].count = 0;
+ }
+ const PxU32 count = blocks[currentBlock].count ++;
+
+ return blocks[currentBlock].block->items[count];
+ }
+
+ /**
+ \brief Pushes a new element onto the back of this array, intitializing it to match the data
+ \param data The data to initialize the new element to
+ \return The new element
+ */
+ T& pushBack(T& data)
+ {
+ PxU32 numBlocks = blocks.size();
+ if (blocks[currentBlock].count == BLOCK_SIZE)
+ {
+ if((currentBlock + 1) == numBlocks)
+ {
+ blocks.pushBack(BlockInfo(PX_NEW(Block), 0));
+ numBlocks ++;
+ }
+ currentBlock++;
+ blocks[currentBlock].count = 0;
+ }
+ const PxU32 count = blocks[currentBlock].count ++;
+ blocks[currentBlock].block->items[count] = data;
+ return blocks[currentBlock].block->items[count];
+ }
+
+ /**
+ \brief Pops the last element from the list.
+ */
+ void popBack()
+ {
+ PX_ASSERT(blocks[currentBlock].count > 0);
+ if (blocks[currentBlock].count > 1)
+ blocks[currentBlock].count --;
+ else
+ {
+ PX_DELETE(blocks[currentBlock].block);
+ blocks.popBack();
+ currentBlock--;
+ }
+ }
+
+ /**
+ \brief Returns the current size of the array.
+ \return The current size of the array.
+ */
+ PxU32 size() const
+ {
+ return (currentBlock)*BLOCK_SIZE + blocks[currentBlock].count;
+ }
+
+ /**
+ \brief Returns the element at a given index in the array
+ \param[in] index The index of the element in the array
+ \return The element at a given index in the array.
+ */
+ T& operator[] (PxU32 index) const
+ {
+ PX_ASSERT(index/BLOCK_SIZE < blocks.size());
+ PX_ASSERT(index%BLOCK_SIZE < blocks[index/BLOCK_SIZE].count);
+ return blocks[index/BLOCK_SIZE].block->items[index%BLOCK_SIZE];
+ }
+};
+
+/**
+\brief A structure to represent a potential CCD interaction between a pair of shapes
+*/
+struct PxsCCDPair
+{
+ /**
+ \brief Defines whether this is an estimated TOI or an accurate TOI.
+
+ We store pairs in a priority queue based on the TOIs. We use cheap estimates to cull away work and lazily evaluate TOIs. This means that an element in the
+ priority queue may either be an estimate or a precise result.
+ */
+ enum E_TOIType
+ {
+ eEstimate,
+ ePrecise
+ };
+ PxsRigidBody* mBa0; // Body A. Can be NULL for statics
+ PxsRigidBody* mBa1; // Body B. Can be NULL for statics
+ PxsCCDShape* mCCDShape0; // Shape A
+ PxsCCDShape* mCCDShape1; // Shape B
+ PxVec3 mMinToiNormal; // The contact normal. Only valid for precise results. On the surface of body/shape A
+ PxReal mMinToi; // Min TOI. Valid for both precise and estimated results but estimates may be too early (i.e. conservative).
+ PxReal mPenetrationPostStep; // Valid only for precise sweeps. Only used for initial intersections (i.e. at TOI = 0).
+ PxVec3 mMinToiPoint; // The contact point. Only valid for precise sweep results.
+ PxReal mPenetration; // The penetration. Only valid for precise sweep results.
+ PxsContactManager* mCm; // The contact manager.
+ PxU32 mIslandId; // The index of the island this pair is in
+ PxGeometryType::Enum mG0, mG1; // The geometry types for shapes 0 and 1
+ bool mIsEarliestToiHit; // Indicates this was the earliest hit for one of the bodies in the pair
+ bool mIsModifiable; // Indicates whether this contact is modifiable
+ PxU32 mFaceIndex; // The face index. Only valid for precise sweeps involving meshes or heightfields.
+ PxU16 mMaterialIndex0; // The material index for shape 0
+ PxU16 mMaterialIndex1; // The material index for shape 1
+ PxReal mDynamicFriction; // The dynamic friction coefficient
+ PxReal mStaticFriction; // The static friction coefficient
+ PxReal mRestitution; // The restitution coefficient
+ PxU32 mEstimatePass; // The current estimation pass. Used after a sweep hit was found to determine if the pair needs re-estimating.
+ PxReal mAppliedForce; // The applied force for this pair. Only valid if the pair has been responded to.
+
+ E_TOIType mToiType; // The TOI type (estimate, precise).
+ bool mHasFriction; // Whether we want to simulate CCD friction for this pair
+
+ /**
+ \brief Perform a precise sweep for this pair
+ \param[in] threadContext The per-thread context
+ \param[in] dt The time-step
+ \param[in] pass The current CCD pass
+ \return The normalized TOI. <=1.0 indicates a hit. Otherwise PX_MAX_REAL.
+ */
+ PxReal sweepFindToi(PxcNpThreadContext& threadContext, PxReal dt, PxU32 pass);
+ /**
+ \brief Performs a sweep estimation for this pair
+ \return The normalized TOI. <= 1.0 indicates a potential hit, otherwise PX_MAX_REAL.
+ */
+ PxReal sweepEstimateToi();
+ /**
+ \brief Advances this pair to the TOI
+ \param[in] dt The time-step
+ \param[in] clipTrajectoryToToi Indicates whether we clip the body's trajectory to the end pose. Only done in the final pass
+ \return Whether the advance was successful. An advance will be unsuccessful if body bodies were already updated.
+ */
+ bool sweepAdvanceToToi(PxReal dt, bool clipTrajectoryToToi);
+ /**
+ \brief Updates the transforms of the shapes involved in this pair.
+ */
+ void updateShapes();
+
+};
+
+/**
+\brief Block array of CCD bodies
+*/
+typedef PxsCCDBlockArray<PxsCCDBody, 128> PxsCCDBodyArray;
+/**
+\brief Block array of CCD pairs
+*/
+typedef PxsCCDBlockArray<PxsCCDPair, 128> PxsCCDPairArray;
+/**
+\brief Block array of CCD overlaps
+*/
+typedef PxsCCDBlockArray<PxsCCDOverlap, 128> PxsCCDOverlapArray;
+/**
+\brief Block array of CCD shapes
+*/
+typedef PxsCCDBlockArray<PxsCCDShape, 128> PxsCCDShapeArray;
+
+/**
+\brief Pair structure to be able to look-up a rigid body-shape pair in a map
+*/
+typedef Ps::Pair<const PxsRigidCore*, const PxsShapeCore*> PxsRigidShapePair;
+
+
+/**
+\brief CCD context object.
+*/
+class PxsCCDContext
+{
+public:
+
+ /**
+ \brief Creates this PxsCCDContext
+ */
+ static PxsCCDContext* create(PxsContext* context, Dy::ThresholdStream& dynamicsContext, PxvNphaseImplementationContext& nPhaseContext);
+
+ /**
+ \brief Destroys this PxsCCDContext
+ */
+ void destroy();
+
+ /**
+ \brief Returns the CCD contact modification callback
+ \return The CCD contact modification callback
+ */
+ PX_FORCE_INLINE PxCCDContactModifyCallback* getCCDContactModifyCallback() const { return mCCDContactModifyCallback; }
+ /**
+ \brief Sets the CCD contact modification callback
+ \param[in] c The CCD contact modification callback
+ */
+ PX_FORCE_INLINE void setCCDContactModifyCallback(PxCCDContactModifyCallback* c) { mCCDContactModifyCallback = c; }
+ /**
+ \brief Returns the maximum number of CCD passes
+ \return The maximum number of CCD passes
+ */
+ PX_FORCE_INLINE PxU32 getCCDMaxPasses() const { return mCCDMaxPasses; }
+ /**
+ \brief Sets the maximum number of CCD passes
+ \param[in] ccdMaxPasses The maximum number of CCD passes
+ */
+ PX_FORCE_INLINE void setCCDMaxPasses(PxU32 ccdMaxPasses) { mCCDMaxPasses = ccdMaxPasses; }
+ /**
+ \brief Returns the current CCD pass
+ \return The current CCD pass
+ */
+ PX_FORCE_INLINE PxU32 getCurrentCCDPass() const { return miCCDPass; }
+ /**
+ \brief Returns The number of swept hits reported
+ \return The number of swept hits reported
+ */
+ PX_FORCE_INLINE PxI32 getNumSweepHits() const { return mSweepTotalHits; }
+ /**
+ \brief Returns The number of updated bodies
+ \return The number of updated bodies in this CCD pass
+ */
+ PX_FORCE_INLINE PxU32 getNumUpdatedBodies() const { return mUpdatedCCDBodies.size(); }
+ /**
+ \brief Returns The update bodies array
+ \return The updated bodies array from this CCD pass
+ */
+ PX_FORCE_INLINE PxsRigidBody*const* getUpdatedBodies() const { return mUpdatedCCDBodies.begin(); }
+
+ /**
+ \brief Returns Clears the updated bodies array
+ */
+ PX_FORCE_INLINE void clearUpdatedBodies() { mUpdatedCCDBodies.forceSize_Unsafe(0); }
+
+ /**
+ \brief Runs the CCD contact modification.
+ \param[in] contacts The list of modifiable contacts
+ \param[in] contactCount The number of contacts
+ \param[in] shapeCore0 The first shape core
+ \param[in] shapeCore1 The second shape core
+ \param[in] rigidCore0 The first rigid core
+ \param[in] rigidCore1 The second rigid core
+ \param[in] rigid0 The first rigid body
+ \param[in] rigid1 The second rigid body
+ */
+ void runCCDModifiableContact(PxModifiableContact* PX_RESTRICT contacts, PxU32 contactCount, const PxsShapeCore* PX_RESTRICT shapeCore0,
+ const PxsShapeCore* PX_RESTRICT shapeCore1, const PxsRigidCore* PX_RESTRICT rigidCore0, const PxsRigidCore* PX_RESTRICT rigidCore1,
+ const PxsRigidBody* PX_RESTRICT rigid0, const PxsRigidBody* PX_RESTRICT rigid1);
+
+ /**
+ \brief Performs a single CCD update
+ This occurs after broad phase and is responsible for creating islands, finding the TOI of collisions, filtering contacts, issuing modification callbacks and responding to
+ collisions. At the end of this phase all bodies will have stepper to their first TOI if they were involved in a CCD collision this frame.
+ \param[in] dt The timestep to simulate
+ \param[in] continuation The continuation task
+ \param[in] disableResweep If this is true, we perform a reduced-fidelity CCD approach
+ */
+ void updateCCD(PxReal dt, PxBaseTask* continuation, bool disableResweep, PxI32 numFastMovingShapes);
+
+ /**
+ \brief Signals the beginning of a CCD multi-pass update
+ */
+ void updateCCDBegin();
+
+ /**
+ \brief Resets the CCD contact state in any contact managers that previously had a reported CCD touch. This must be called if CCD update is bypassed for a frame
+ */
+ void resetContactManagers();
+
+
+
+
+protected:
+
+ /**
+ \brief Constructor for PxsCCDContext
+ \param[in] context The PxsContext that is associated with this PxsCCDContext.
+ */
+ PxsCCDContext(PxsContext* context, Dy::ThresholdStream& thresholdStream, PxvNphaseImplementationContext& nPhaseContext);
+ /**
+ \brief Destructor for PxsCCDContext
+ */
+ ~PxsCCDContext();
+
+private:
+
+
+ /**
+ \brief Verifies the consistency of the CCD context at the beginning
+ */
+ void verifyCCDBegin();
+
+ /**
+ \brief Cleans up after the CCD update has completed
+ */
+ void updateCCDEnd();
+
+ /**
+ \brief Spawns the update island tasks after the initial sweep estimates have been performed
+ \param[in] continuation The continuation task
+ */
+ void postCCDSweep(PxBaseTask* continuation);
+ /**
+ \brief Creates contact buffers for CCD contacts. These will be sent to the user in the contact notification.
+ \param[in] continuation The continuation task
+ */
+ void postCCDAdvance(PxBaseTask* continuation);
+ /**
+ \brief The final phase of the CCD task chain. Cleans up after the parallel update/postCCDAdvance stages.
+ \param[in] continuation The continuation task
+ */
+ void postCCDDepenetrate(PxBaseTask* continuation);
+
+ typedef Cm::DelegateTask<PxsCCDContext, &PxsCCDContext::postCCDSweep> PostCCDSweepTask;
+ typedef Cm::DelegateTask<PxsCCDContext, &PxsCCDContext::postCCDAdvance> PostCCDAdvanceTask;
+ typedef Cm::DelegateTask<PxsCCDContext, &PxsCCDContext::postCCDDepenetrate> PostCCDDepenetrateTask;
+
+ PostCCDSweepTask mPostCCDSweepTask;
+ PostCCDAdvanceTask mPostCCDAdvanceTask;
+ PostCCDDepenetrateTask mPostCCDDepenetrateTask;
+
+ PxCCDContactModifyCallback* mCCDContactModifyCallback;
+
+ // CCD global data
+ bool mDisableCCDResweep;
+ PxU32 miCCDPass;
+ PxI32 mSweepTotalHits;
+
+ // a fraction of objects will be CCD active so PxsCCDBody is dynamic, not a member of PxsRigidBody
+ PxsCCDBodyArray mCCDBodies;
+ PxsCCDOverlapArray mCCDOverlaps;
+ PxsCCDShapeArray mCCDShapes;
+ Ps::Array<PxsCCDBody*> mIslandBodies;
+ Ps::Array<PxU16> mIslandSizes;
+ Ps::Array<PxsRigidBody*> mUpdatedCCDBodies;
+ Ps::HashMap<PxsRigidShapePair, PxsCCDShape*> mMap;
+
+ // temporary array updated during CCD update
+ //Array<PxsCCDPair> mCCDPairs;
+ PxsCCDPairArray mCCDPairs;
+ Ps::Array<PxsCCDPair*> mCCDPtrPairs;
+ // number of pairs per island
+ Ps::Array<PxU32> mCCDIslandHistogram;
+ // thread context valid during CCD update
+ PxcNpThreadContext* mCCDThreadContext;
+ // number of pairs to process per thread
+ PxU32 mCCDPairsPerBatch;
+ PxU32 mCCDMaxPasses;
+
+ PxsContext* mContext;
+ Dy::ThresholdStream& mThresholdStream;
+
+ PxvNphaseImplementationContext& mNphaseContext;
+
+ Ps::Mutex mMutex;
+
+private:
+
+ PX_NOCOPY(PxsCCDContext)
+};
+
+
+}
+
+
+
+#endif
+
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsContactManager.h b/PhysX_3.4/Source/LowLevel/software/include/PxsContactManager.h
new file mode 100644
index 00000000..197b4afa
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsContactManager.h
@@ -0,0 +1,178 @@
+// 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 PXS_CONTACTMANAGER_H
+#define PXS_CONTACTMANAGER_H
+
+#include "PxvConfig.h"
+#include "PxcNpWorkUnit.h"
+
+namespace physx
+{
+
+class PxsContext;
+class PxsRigidBody;
+struct PxsCCDBody;
+class PxsMaterialManager;
+struct PxsCCDShape;
+
+namespace Dy
+{
+ class DynamicsContext;
+}
+
+namespace Sc
+{
+ class ShapeInteraction;
+}
+
+enum PxsPairVisColor
+{
+
+ eVIS_COLOR_SWEPTINTEGRATE_OFF = 0x000000,
+ eVIS_COLOR_SWEPTINTEGRATE_SLOW = 0x404040,
+ eVIS_COLOR_SWEPTINTEGRATE_CLEAR = 0x007f00,
+ eVIS_COLOR_SWEPTINTEGRATE_IMPACT = 0x1680ff,
+ eVIS_COLOR_SWEPTINTEGRATE_FAIL = 0x0000ff
+
+};
+
+
+/**
+\brief Additional header structure for CCD contact data stream.
+*/
+struct PxsCCDContactHeader
+{
+ /**
+ \brief Stream for next collision. The same pair can collide multiple times during multiple CCD passes.
+ */
+ PxsCCDContactHeader* nextStream; //4 //8
+ /**
+ \brief Size (in bytes) of the CCD contact stream (not including force buffer)
+ */
+ PxU16 contactStreamSize; //6 //10
+ /**
+ \brief Defines whether the stream is from a previous pass.
+
+ It could happen that the stream can not get allocated because we run out of memory. In that case the current event should not use the stream
+ from an event of the previous pass.
+ */
+ PxU16 isFromPreviousPass; //8 //12
+
+ PxU8 pad[12 - sizeof(PxsCCDContactHeader*)]; //16
+};
+
+PX_COMPILE_TIME_ASSERT((sizeof(PxsCCDContactHeader) & 0xF) == 0);
+
+
+class PxsContactManager
+{
+public:
+ PxsContactManager(PxsContext* context, PxU32 index);
+ ~PxsContactManager();
+
+
+ PX_FORCE_INLINE void setDisableStrongFriction(PxU32 d) { (!d) ? mNpUnit.flags &= ~PxcNpWorkUnitFlag::eDISABLE_STRONG_FRICTION
+ : mNpUnit.flags |= PxcNpWorkUnitFlag::eDISABLE_STRONG_FRICTION; }
+
+ PX_FORCE_INLINE PxReal getRestDistance() const { return mNpUnit.restDistance; }
+ PX_FORCE_INLINE void setRestDistance(PxReal v) { mNpUnit.restDistance = v; }
+
+ void destroy();
+
+ PX_FORCE_INLINE PxU8 getDominance0() const { return mNpUnit.dominance0; }
+ PX_FORCE_INLINE void setDominance0(PxU8 v) { mNpUnit.dominance0 = v; }
+
+ PX_FORCE_INLINE PxU8 getDominance1() const { return mNpUnit.dominance1; }
+ PX_FORCE_INLINE void setDominance1(PxU8 v) { mNpUnit.dominance1 = v; }
+
+ PX_FORCE_INLINE PxU16 getTouchStatus() const { return PxU16(mNpUnit.statusFlags & PxcNpWorkUnitStatusFlag::eHAS_TOUCH); }
+ PX_FORCE_INLINE PxU16 touchStatusKnown() const { return PxU16(mNpUnit.statusFlags & PxcNpWorkUnitStatusFlag::eTOUCH_KNOWN); }
+ PX_FORCE_INLINE PxI32 getTouchIdx() const { return (mNpUnit.statusFlags& PxcNpWorkUnitStatusFlag::eHAS_TOUCH) ? 1 : (mNpUnit.statusFlags& PxcNpWorkUnitStatusFlag::eHAS_NO_TOUCH ? -1 : 0); }
+
+ PX_FORCE_INLINE PxU32 getIndex() const { return mNpUnit.index; }
+
+ PX_FORCE_INLINE PxU16 getHasCCDRetouch() const { return PxU16(mNpUnit.statusFlags & PxcNpWorkUnitStatusFlag::eHAS_CCD_RETOUCH); }
+ PX_FORCE_INLINE void clearCCDRetouch() { mNpUnit.statusFlags &= ~PxcNpWorkUnitStatusFlag::eHAS_CCD_RETOUCH; }
+ PX_FORCE_INLINE void raiseCCDRetouch() { mNpUnit.statusFlags |= PxcNpWorkUnitStatusFlag::eHAS_CCD_RETOUCH; }
+
+
+
+ // flags stuff - needs to be refactored
+
+ PX_FORCE_INLINE Ps::IntBool isChangeable() const { return Ps::IntBool(mFlags & PXS_CM_CHANGEABLE); }
+ PX_FORCE_INLINE Ps::IntBool getCCD() const { return Ps::IntBool((mFlags & PXS_CM_CCD_LINEAR) && (mNpUnit.flags & PxcNpWorkUnitFlag::eDETECT_CCD_CONTACTS)); }
+ PX_FORCE_INLINE Ps::IntBool getHadCCDContact() const { return Ps::IntBool(mFlags & PXS_CM_CCD_CONTACT); }
+ PX_FORCE_INLINE void setHadCCDContact() { mFlags |= PXS_CM_CCD_CONTACT; }
+ void setCCD(bool enable);
+ PX_FORCE_INLINE void clearCCDContactInfo() { mFlags &= ~PXS_CM_CCD_CONTACT; mNpUnit.ccdContacts = NULL; }
+
+ PX_FORCE_INLINE PxcNpWorkUnit& getWorkUnit() { return mNpUnit; }
+ PX_FORCE_INLINE const PxcNpWorkUnit& getWorkUnit() const { return mNpUnit; }
+
+ PX_FORCE_INLINE void* getUserData() const { return mShapeInteraction; }
+
+ // Setup solver-constraints
+ void resetCachedState();
+ void resetFrictionCachedState();
+
+ Sc::ShapeInteraction* getShapeInteraction() const { return mShapeInteraction; }
+
+private:
+ //KS - moving this up - we want to get at flags
+
+ PxsRigidBody* mRigidBody0; //4 //8
+ PxsRigidBody* mRigidBody1; //8 //16
+ PxU32 mFlags; //20 //36
+ Sc::ShapeInteraction* mShapeInteraction; //16 //32
+
+
+
+ friend class PxsContext;
+ // everything required for narrow phase to run
+ PxcNpWorkUnit mNpUnit;
+
+ enum
+ {
+ PXS_CM_CHANGEABLE = (1<<0),
+ PXS_CM_CCD_LINEAR = (1<<1),
+ PXS_CM_CCD_CONTACT = (1 << 2)
+ };
+
+ friend class Dy::DynamicsContext;
+ friend struct PxsCCDPair;
+ friend class PxsIslandManager;
+ friend class PxsCCDContext;
+ friend class Sc::ShapeInteraction;
+};
+
+}
+
+#endif
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsContactManagerState.h b/PhysX_3.4/Source/LowLevel/software/include/PxsContactManagerState.h
new file mode 100644
index 00000000..a06a2063
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsContactManagerState.h
@@ -0,0 +1,95 @@
+// 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 PXS_CONTACT_MANAGER_STATE_H
+#define PXS_CONTACT_MANAGER_STATE_H
+
+#include "foundation/PxSimpleTypes.h"
+
+namespace physx
+{
+
+ struct PxsShapeCore;
+
+ /**
+ There is an implicit 1:1 mapping between PxgContactManagerInput and PxsContactManagerOutput. The structures are split because PxgNpContactManagerInput contains constant
+ data that is produced by the CPU code and PxgNpContactManagerOutput contains per-frame contact information produced by the NP.
+
+ There is also a 1:1 mapping between the PxgNpContactManager and PxsContactManager. This mapping is handled within the PxgNPhaseCore.
+
+ The previous contact states are implicitly cached in PxsContactManager and will be propagated to the solver. Friction correlation is also done implicitly using cached
+ information in PxsContactManager.
+ The NP will produce a list of pairs that found/lost patches for the solver along with updating the PxgNpContactManagerOutput for all pairs.
+ */
+
+ struct PxsContactManagerStatusFlag
+ {
+ enum Enum
+ {
+ eHAS_NO_TOUCH = (1 << 0),
+ eHAS_TOUCH = (1 << 1),
+ //eHAS_SOLVER_CONSTRAINTS = (1 << 2),
+ eREQUEST_CONSTRAINTS = (1 << 3),
+ eHAS_CCD_RETOUCH = (1 << 4), // Marks pairs that are touching at a CCD pass and were touching at discrete collision or at a previous CCD pass already
+ // but we can not tell whether they lost contact in a pass before. We send them as pure eNOTIFY_TOUCH_CCD events to the
+ // contact report callback if requested.
+ eDIRTY_MANAGER = (1 << 5),
+ eTOUCH_KNOWN = eHAS_NO_TOUCH | eHAS_TOUCH // The touch status is known (if narrowphase never ran for a pair then no flag will be set)
+ };
+ };
+
+
+ struct PX_ALIGN_PREFIX(16) PxsContactManagerOutput
+ {
+ PxU8* contactPatches; //Start index/ptr for contact patches
+ PxU8* contactPoints; //Start index/ptr for contact points
+ PxReal* contactForces; //Start index/ptr for contact forces
+ PxU8 nbContacts; //Num contacts
+ PxU8 nbPatches; //Num patches
+ PxU8 statusFlag; //Status flag (has touch etc.)
+ PxU8 prevPatches; //Previous number of patches
+
+ PX_FORCE_INLINE PxU32* getInternalFaceIndice()
+ {
+ return reinterpret_cast<PxU32*>(contactForces + nbContacts);
+ }
+ }
+ PX_ALIGN_SUFFIX(16);
+
+ struct /*PX_ALIGN_PREFIX(16)*/ PxsContactManagerPersistency
+ {
+ PxU8 mPrevPatches;
+ PxU8 mNbFrictionPatches;
+ PxU8 mNbPrevFrictionPatches;
+ }
+ /*PX_ALIGN_SUFFIX(16)*/;
+
+}
+
+#endif //PXG_CONTACT_MANAGER_H
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsContext.h b/PhysX_3.4/Source/LowLevel/software/include/PxsContext.h
new file mode 100644
index 00000000..d50cff15
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsContext.h
@@ -0,0 +1,369 @@
+// 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 PXS_CONTEXT_H
+#define PXS_CONTEXT_H
+
+#include "PxVisualizationParameter.h"
+#include "PxSceneDesc.h"
+
+#include "CmPool.h"
+
+#include "PxvContext.h"
+#include "PxvNphaseImplementationContext.h"
+#include "PxsContactManager.h"
+#include "PxcNpBatch.h"
+#include "PxcConstraintBlockStream.h"
+#include "PxcNpCacheStreamPair.h"
+#include "PxcNpMemBlockPool.h"
+#include "CmRenderOutput.h"
+#include "CmUtils.h"
+#include "CmTask.h"
+
+#include "PxContactModifyCallback.h"
+
+#include "PxsTransformCache.h"
+#include "GuPersistentContactManifold.h"
+#include "DyArticulation.h"
+
+#if PX_SUPPORT_GPU_PHYSX
+namespace physx
+{
+ class PxCudaContextManager;
+}
+#endif
+
+namespace physx
+{
+
+class PxsRigidBody;
+struct PxcConstraintBlock;
+class PxsMaterialManager;
+class PxsCCDContext;
+struct PxsContactManagerOutput;
+
+namespace Cm
+{
+ class FlushPool;
+}
+
+namespace Bp
+{
+ class AABBManagerImpl;
+}
+
+namespace IG
+{
+ class SimpleIslandManager;
+ typedef PxU32 EdgeIndex;
+}
+
+enum PxsTouchEventCount
+{
+ PXS_LOST_TOUCH_COUNT = 0,
+ PXS_NEW_TOUCH_COUNT = 1,
+ PXS_CCD_RETOUCH_COUNT = 2, // pairs that are touching at a CCD pass and were touching at discrete collision or at a previous CCD pass already
+ // (but they could have lost touch in between)
+ PXS_PATCH_FOUND_COUNT = 3,
+ PXS_PATCH_LOST_COUNT = 4,
+ PXS_TOUCH_EVENT_COUNT = 5
+};
+
+
+
+class PxsCMUpdateTask : public Cm::Task
+{
+public:
+
+ static const PxU32 BATCH_SIZE = 128;
+
+ PxsCMUpdateTask(PxsContext* context, PxReal dt, PxsContactManager** cmArray, PxsContactManagerOutput* cmOutputs, Gu::Cache* caches, PxU32 cmCount,
+ PxContactModifyCallback* callback):
+ mCmArray(cmArray), mCmOutputs(cmOutputs), mCaches(caches), mCmCount(cmCount), mDt(dt), mContext(context), mCallback(callback)
+ {
+ }
+
+ virtual void release();
+
+ /*PX_FORCE_INLINE void insert(PxsContactManager* cm)
+ {
+ PX_ASSERT(mCmCount < BATCH_SIZE);
+ mCmArray[mCmCount++]=cm;
+ }*/
+
+protected:
+ //PxsContactManager* mCmArray[BATCH_SIZE];
+ PxsContactManager** mCmArray;
+ PxsContactManagerOutput* mCmOutputs;
+ Gu::Cache* mCaches;
+ PxU32 mCmCount;
+ PxReal mDt; //we could probably retrieve from context to save space?
+ PxsContext* mContext;
+ PxContactModifyCallback* mCallback;
+};
+
+class PxsContext : public Ps::UserAllocated, public PxcNpContext
+{
+ PX_NOCOPY(PxsContext)
+public:
+ PxsContext( const PxSceneDesc& desc, PxTaskManager*, Cm::FlushPool&, PxU64 contextID);
+ ~PxsContext();
+
+ void removeRigidBody(PxsRigidBody&);
+
+ Dy::Articulation* createArticulation();
+ void destroyArticulation(Dy::Articulation&);
+
+ void createTransformCache(Ps::VirtualAllocatorCallback& allocatorCallback);
+
+ PxsContactManager* createContactManager(PxsContactManager* contactManager, const bool useCCD);
+ void createCache(Gu::Cache& cache, PxsContactManager* cm, PxU8 geomType0, PxU8 geomType1);
+ void destroyCache(Gu::Cache& cache);
+ void destroyContactManager(PxsContactManager* cm);
+
+
+ PX_FORCE_INLINE PxU64 getContextId() const { return mContextID; }
+
+ // Collision properties
+ PX_FORCE_INLINE PxContactModifyCallback* getContactModifyCallback() const { return mContactModifyCallback; }
+ PX_FORCE_INLINE void setContactModifyCallback(PxContactModifyCallback* c) { mContactModifyCallback = c; mNpImplementationContext->setContactModifyCallback(c);}
+
+
+ // resource-related
+ void setScratchBlock(void* addr, PxU32 size);
+
+ void setContactDistance(Ps::Array<PxReal, Ps::VirtualAllocator>* contactDistance);
+
+ // Task-related
+ void updateContactManager(PxReal dt, bool hasBoundsArrayChanged, bool hasContactDistanceChanged, PxBaseTask* continuation, PxBaseTask* firstPassContinuation);
+ void secondPassUpdateContactManager(PxReal dt, PxBaseTask* continuation);
+ void fetchUpdateContactManager();
+ void swapStreams();
+
+ void resetThreadContexts();
+
+ // Manager status change
+ bool getManagerTouchEventCount(int* newTouch, int* lostTouch, int* ccdTouch) const;
+ bool fillManagerTouchEvents(
+ PxvContactManagerTouchEvent* newTouch, PxI32& newTouchCount,
+ PxvContactManagerTouchEvent* lostTouch, PxI32& lostTouchCount,
+ PxvContactManagerTouchEvent* ccdTouch, PxI32& ccdTouchCount);
+
+ PX_FORCE_INLINE void getManagerPatchEventCount(PxU32& foundPatch, PxU32& lostPatch) const { foundPatch = mCMTouchEventCount[PXS_PATCH_FOUND_COUNT]; lostPatch = mCMTouchEventCount[PXS_PATCH_LOST_COUNT]; }
+ bool fillManagerPatchChangedEvents(
+ PxsContactManager** foundPatch, PxU32& foundPatchCount,
+ PxsContactManager** lostPatch, PxU32& lostPatchCount);
+
+ void beginUpdate();
+
+ // PX_ENABLE_SIM_STATS
+ PX_FORCE_INLINE PxvSimStats& getSimStats() { return mSimStats; }
+ PX_FORCE_INLINE const PxvSimStats& getSimStats() const { return mSimStats; }
+
+ PX_FORCE_INLINE Cm::FlushPool& getTaskPool() const { return mTaskPool; }
+ PX_FORCE_INLINE Cm::RenderBuffer& getRenderBuffer() { return mRenderBuffer; }
+
+ PxReal getVisualizationParameter(PxVisualizationParameter::Enum param) const;
+ void setVisualizationParameter(PxVisualizationParameter::Enum param, PxReal value);
+
+ PX_FORCE_INLINE void setVisualizationCullingBox(const PxBounds3& box) { mVisualizationCullingBox = box; }
+ PX_FORCE_INLINE const PxBounds3& getVisualizationCullingBox()const { return mVisualizationCullingBox; }
+
+ PX_FORCE_INLINE PxReal getRenderScale() const { return mVisualizationParams[PxVisualizationParameter::eSCALE]; }
+ Cm::RenderOutput getRenderOutput() { return Cm::RenderOutput(mRenderBuffer); }
+ PX_FORCE_INLINE bool getPCM() const { return mPCM; }
+ PX_FORCE_INLINE bool getContactCacheFlag() const { return mContactCache; }
+ PX_FORCE_INLINE bool getCreateAveragePoint() const { return mCreateAveragePoint; }
+
+ // general stuff
+ void shiftOrigin(const PxVec3& shift);
+
+ void setCreateContactStream(bool to);
+ PX_FORCE_INLINE void setPCM(bool enabled) { mPCM = enabled; }
+ PX_FORCE_INLINE void setContactCache(bool enabled) { mContactCache = enabled; }
+
+ PX_FORCE_INLINE PxcScratchAllocator& getScratchAllocator() { return mScratchAllocator; }
+ PX_FORCE_INLINE PxsTransformCache& getTransformCache() { return *mTransformCache; }
+ PX_FORCE_INLINE PxReal* getContactDistance() { return mContactDistance->begin(); }
+
+ PX_FORCE_INLINE PxvNphaseImplementationContext* getNphaseImplementationContext() const
+ {
+ return mNpImplementationContext;
+ }
+
+ PX_FORCE_INLINE void setNphaseImplementationContext(PxvNphaseImplementationContext* ctx)
+ {
+ mNpImplementationContext = ctx;
+ }
+
+ PX_FORCE_INLINE PxvNphaseImplementationContext* getNphaseFallbackImplementationContext() const
+ {
+ return mNpFallbackImplementationContext;
+ }
+
+ PX_FORCE_INLINE void setNphaseFallbackImplementationContext(PxvNphaseImplementationContext* ctx)
+ {
+ mNpFallbackImplementationContext = ctx;
+ }
+
+ PxU32 getTotalCompressedContactSize() const { return mTotalCompressedCacheSize; }
+ PxU32 getMaxPatchCount() const { return mMaxPatches; }
+
+ PX_FORCE_INLINE PxcThreadCoherentCache<PxcNpThreadContext, PxcNpContext>& getNpThreadContextPool()
+ {
+ return mNpThreadContextPool;
+ }
+
+ PX_FORCE_INLINE PxcNpThreadContext* getNpThreadContext()
+ {
+ // We may want to conditional compile to exclude this on single threaded implementations
+ // if it is determined to be a performance hit.
+ return mNpThreadContextPool.get();
+ }
+
+ PX_FORCE_INLINE void putNpThreadContext(PxcNpThreadContext* threadContext)
+ { mNpThreadContextPool.put(threadContext); }
+ PX_FORCE_INLINE Ps::Mutex& getLock() { return mLock; }
+
+ PX_FORCE_INLINE PxTaskManager& getTaskManager()
+ {
+ PX_ASSERT(mTaskManager);
+ return *mTaskManager;
+ }
+
+ PX_FORCE_INLINE void clearManagerTouchEvents();
+
+ PX_FORCE_INLINE Cm::PoolList<PxsContactManager, PxsContext>& getContactManagerPool()
+ {
+ return this->mContactManagerPool;
+ }
+
+ PX_FORCE_INLINE void setActiveContactManager(const PxsContactManager* manager)
+ {
+ const PxU32 index = manager->getIndex();
+ if (index >= mActiveContactManager.size())
+ {
+ PxU32 newSize = (2 * index + 256)&~255;
+ mActiveContactManager.resize(newSize);
+ }
+ mActiveContactManager.set(index);
+
+ //Record any pairs that have CCD enabled!
+ if (manager->getCCD())
+ {
+ if (index >= mActiveContactManagersWithCCD.size())
+ {
+ PxU32 newSize = (2 * index + 256)&~255;
+ mActiveContactManagersWithCCD.resize(newSize);
+ }
+ mActiveContactManagersWithCCD.set(index);
+ }
+ }
+
+
+private:
+ void mergeCMDiscreteUpdateResults(PxBaseTask* continuation);
+
+ PxU32 mIndex;
+
+ // Threading
+ PxcThreadCoherentCache<PxcNpThreadContext, PxcNpContext>
+ mNpThreadContextPool;
+
+ // Contact managers
+ Cm::PoolList<PxsContactManager, PxsContext> mContactManagerPool;
+ Ps::Pool<Gu::LargePersistentContactManifold> mManifoldPool;
+ Ps::Pool<Gu::SpherePersistentContactManifold> mSphereManifoldPool;
+
+ Cm::BitMap mActiveContactManager;
+ Cm::BitMap mActiveContactManagersWithCCD; //KS - adding to filter any pairs that had a touch
+ Cm::BitMap mContactManagersWithCCDTouch; //KS - adding to filter any pairs that had a touch
+ Cm::BitMap mContactManagerTouchEvent;
+ Cm::BitMap mContactManagerPatchChangeEvent;
+ PxU32 mCMTouchEventCount[PXS_TOUCH_EVENT_COUNT];
+
+ Ps::Mutex mLock;
+
+
+
+ PxContactModifyCallback* mContactModifyCallback;
+
+ // narrowphase platform-dependent implementations support
+ PxvNphaseImplementationContext* mNpImplementationContext;
+ PxvNphaseImplementationContext* mNpFallbackImplementationContext;
+
+
+ // debug rendering (CS TODO: MS would like to have these wrapped into a class)
+ PxReal mVisualizationParams[PxVisualizationParameter::eNUM_VALUES];
+
+ PxBounds3 mVisualizationCullingBox;
+
+ PxTaskManager* mTaskManager;
+ Cm::FlushPool& mTaskPool;
+
+
+ // PxU32 mTouchesLost;
+ // PxU32 mTouchesFound;
+
+ // PX_ENABLE_SIM_STATS
+ PxvSimStats mSimStats;
+ bool mPCM;
+ bool mContactCache;
+ bool mCreateAveragePoint;
+
+ PxsTransformCache* mTransformCache;
+ Ps::Array<PxReal, Ps::VirtualAllocator>* mContactDistance;
+
+
+ PxU32 mMaxPatches;
+ PxU32 mTotalCompressedCacheSize;
+
+ PxU64 mContextID;
+
+ friend class PxsCCDContext;
+ friend class PxsNphaseImplementationContext;
+ friend class PxgNphaseImplementationContext; //FDTODO ideally it shouldn't be here..
+};
+
+
+PX_FORCE_INLINE void PxsContext::clearManagerTouchEvents()
+{
+ mContactManagerTouchEvent.clear();
+ mContactManagerPatchChangeEvent.clear();
+ for(PxU32 i = 0; i < PXS_TOUCH_EVENT_COUNT; ++i)
+ {
+ mCMTouchEventCount[i] = 0;
+ }
+}
+
+
+}
+
+#endif
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsDefaultMemoryManager.h b/PhysX_3.4/Source/LowLevel/software/include/PxsDefaultMemoryManager.h
new file mode 100644
index 00000000..baabbd86
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsDefaultMemoryManager.h
@@ -0,0 +1,98 @@
+// 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 PXS_DEFAULT_MEMORY_MANAGER_H
+#define PXS_DEFAULT_MEMORY_MANAGER_H
+
+#include "PxsMemoryManager.h"
+#include "PsAllocator.h"
+#include "PsArray.h"
+
+namespace physx
+{
+
+ class PxsDefaultMemoryAllocator : public Ps::VirtualAllocatorCallback
+ {
+ public:
+
+ PxsDefaultMemoryAllocator(const char* name = NULL)
+ {
+ PX_UNUSED(name);
+#if 0 //PX_USE_NAMED_ALLOCATOR
+ if (name)
+ strcpy(mName, name);
+ else
+ strcpy(mName, "");
+#endif
+ }
+
+ virtual ~PxsDefaultMemoryAllocator()
+ {
+ }
+
+ virtual void* allocate(const size_t newByteSize, const char* filename, const int line)
+ {
+ PX_UNUSED(line);
+ PX_UNUSED(filename);
+#if 0 //PX_USE_NAMED_ALLOCATOR
+ return PX_ALLOC(newByteSize, mName);
+#else
+ return PX_ALLOC(newByteSize, filename);
+#endif
+ }
+
+ virtual void deallocate(void* ptr)
+ {
+ if (ptr)
+ PX_FREE(ptr);
+ }
+
+#if 0 //PX_USE_NAMED_ALLOCATOR
+ char mName[32];
+#endif
+ };
+
+
+ class PxsDefaultMemoryManager : public PxsMemoryManager
+ {
+ public:
+ virtual ~PxsDefaultMemoryManager();
+ virtual Ps::VirtualAllocatorCallback* createHostMemoryAllocator(const PxU32 gpuComputeVersion = 0);
+ virtual Ps::VirtualAllocatorCallback* createDeviceMemoryAllocator(const PxU32 gpuComputeVersion = 0);
+
+ virtual void destroyMemoryAllocator();
+
+ Ps::Array<Ps::VirtualAllocatorCallback*> mAllocators;
+
+ };
+
+}
+
+#endif
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsHeapMemoryAllocator.h b/PhysX_3.4/Source/LowLevel/software/include/PxsHeapMemoryAllocator.h
new file mode 100644
index 00000000..61d600dc
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsHeapMemoryAllocator.h
@@ -0,0 +1,68 @@
+// 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 PXS_HEAP_MEMORY_ALLOCATOR_H
+#define PXS_HEAP_MEMORY_ALLOCATOR_H
+
+
+#include "DyGpuAPI.h"
+#include "foundation/PxSimpleTypes.h"
+
+namespace physx
+{
+ namespace shdfnd
+ {
+ class VirtualAllocatorCallback;
+ }
+
+ class PxErrorCallback;
+ class PxsHostMemoryAllocator;
+
+ class PxsHeapMemoryAllocator : public Ps::VirtualAllocatorCallback
+ {
+ public:
+ virtual ~PxsHeapMemoryAllocator(){}
+ virtual void* allocate(const size_t size, const char* file, const int line) = 0;
+ virtual void deallocate(void* ptr) = 0;
+
+ };
+
+ class PxsHeapMemoryAllocatorManager
+ {
+ public:
+ virtual ~PxsHeapMemoryAllocatorManager()
+ {
+
+ }
+ PxsHeapMemoryAllocator* mMappedMemoryAllocators;
+ };
+}
+
+#endif \ No newline at end of file
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsIncrementalConstraintPartitioning.h b/PhysX_3.4/Source/LowLevel/software/include/PxsIncrementalConstraintPartitioning.h
new file mode 100644
index 00000000..279e3666
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsIncrementalConstraintPartitioning.h
@@ -0,0 +1,40 @@
+// 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 PXS_INCREMENTAL_CONSTRAINT_PARTITIONING_H
+#define PXS_INCREMENTAL_CONSTRAINT_PARTITIONING_H
+
+#include "PxsSimpleIslandManager.h"
+
+namespace physx
+{
+
+}
+
+#endif \ No newline at end of file
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsIslandManagerTypes.h b/PhysX_3.4/Source/LowLevel/software/include/PxsIslandManagerTypes.h
new file mode 100644
index 00000000..01f7b4ee
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsIslandManagerTypes.h
@@ -0,0 +1,372 @@
+// 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 PXS_ISLAND_MANAGER_TYPES_H
+#define PXS_ISLAND_MANAGER_TYPES_H
+
+#include "CmPhysXCommon.h"
+
+namespace physx
+{
+
+class PxsContactManager;
+class PxsRigidBody;
+namespace Dy
+{
+ struct Constraint;
+ class Articulation;
+}
+
+#if PX_USE_16_BIT_HANDLES
+typedef PxU16 NodeType;
+typedef PxU16 EdgeType;
+typedef PxU16 IslandType;
+#define INVALID_NODE 0xffff
+#define INVALID_EDGE 0xffff
+#define INVALID_ISLAND 0xffff
+#else
+typedef PxU32 NodeType;
+typedef PxU32 EdgeType;
+typedef PxU32 IslandType;
+#define INVALID_NODE 0xffffffff
+#define INVALID_EDGE 0xffffffff
+#define INVALID_ISLAND 0xffffffff
+#endif
+
+namespace Dy
+{
+ typedef size_t ArticulationLinkHandle;
+}
+
+//----------------------------------------------------------------------------//
+
+template <class T, T INVLD> class PxsIslandManagerHook
+{
+ friend class PxsIslandManager;
+ T index;
+
+public:
+
+ static const T INVALID = INVLD;
+
+ PX_FORCE_INLINE PxsIslandManagerHook(): index(INVLD) {}
+ PX_FORCE_INLINE PxsIslandManagerHook(const T id): index(id) {}
+ PX_FORCE_INLINE PxsIslandManagerHook(const PxsIslandManagerHook<T,INVLD>& src) : index(src.index) {}
+ PX_FORCE_INLINE ~PxsIslandManagerHook(){}
+
+ PX_FORCE_INLINE bool isManaged() const { return index!=INVLD; }
+
+private:
+};
+
+typedef PxsIslandManagerHook<NodeType,INVALID_NODE> PxsIslandManagerNodeHook;
+typedef PxsIslandManagerHook<EdgeType,INVALID_EDGE> PxsIslandManagerEdgeHook;
+typedef PxsIslandManagerHook<IslandType,INVALID_ISLAND> PxsIslandManagerIslandHook;
+
+//----------------------------------------------------------------------------//
+
+/**
+\brief PxsIslandObjects contains arrays of all rigid bodies, articulations, contact managers, and constraints that
+belong to all awake islands. The per array indices denoting the ownership per island are stored in PxsIslandIndices.
+
+@see PxsIslandManager::getIslandObjects
+*/
+struct PxsIslandObjects
+{
+ /**
+ \brief Array of all rigid bodies in all awake islands.
+
+ \note Each rigid body corresponds to the void* passed to PxsIslandManager::addBody. The PxsRigidBody ptr is computed
+ by adding the rigid body offset value (passed to PxsIslandManager::create) to the void* pointer
+ ie [(PxsRigidBody*)((PxU8*)owner + rigidBodyOffset)]
+
+ @see PxsIslandManager::addBody, PxsIslandManager::create
+ */
+ PxsRigidBody*const* bodies;
+
+ /**
+ \brief Array of all articulation roots in all awake islands.
+
+ \note Each Articulation* corresponds to Dy::getArticulation(articLinkHandle) where
+ articLinkHandle is the handle passed to PxsIslandManager::setArticulationRootLinkHandle.
+
+ @see PxsIslandManager::setArticulationRootLinkHandle, Dy::getArticulation
+ */
+ Dy::Articulation*const* articulations;
+
+ /**
+ \brief Array of all articulation roots in all awake islands.
+
+ \note Each void* corresponds to the void* passed to PxsIslandManager::setArticulationRootLinkHandle
+
+ @see PxsIslandManager::setArticulationRootLinkHandle
+ */
+ void*const* articulationOwners;
+
+ /**
+ \brief Array of all contact managers in all awake islands.
+
+ @see PxsIslandManager::setEdgeRigidCM
+ */
+ struct PxsIndexedContactManager* contactManagers;
+
+ /**
+ \brief Array of all constraints in all awake islands.
+
+ @see PxsIslandManager::setEdgeConstraint
+ */
+ struct PxsIndexedConstraint* constraints;
+
+
+ PxsIslandObjects() : bodies(NULL), articulations(NULL), articulationOwners(NULL), contactManagers(NULL), constraints(NULL)
+ {
+ }
+};
+
+
+//----------------------------------------------------------------------------//
+
+/**
+\brief An array of PxsIslandIndices describes the rigid bodies, articulations, contacts and constraints that
+belong to each island.
+
+\note Given an array of PxsIslandIndices, the rigid bodies of the ith island span the inclusive range:
+ (PxsIslandObjects::bodies[PxsIslandIndices[i]], PxsIslandObjects::bodies[PxsIslandIndices[i+1]-1])
+
+\note Given an array of PxsIslandIndices, the constraints of the ith island span the inclusive range:
+ (PxsIslandObjects::constraints[PxsIslandIndices[i]], PxsIslandObjects::constraints[PxsIslandIndices[i+1]-1])
+
+@see PxsIslandObjects::getIslandIndices, PxsIslandObjects::getIslandCount
+*/
+class PxsIslandIndices
+{
+public:
+
+ PxsIslandIndices(){}
+ ~PxsIslandIndices(){}
+
+ /**
+ \brief Return true if the corresponding island has a contact with a static rigid body.
+ */
+ PX_FORCE_INLINE bool getHasStaticContact() const
+ {
+ return (1 & hasStaticContact) ? true : false;
+ }
+
+ /**
+ \brief The starting index of island rigid bodies in the array PxsIslandObjects::bodies
+ */
+ NodeType bodies;
+
+ /**
+ \brief The starting index of island articulations in the arrays PxsIslandObjects::articulations and PxsIslandObjects::articulationOwners
+
+ \note The total number of articulations is clamped at 32767 on any platform that uses 16-bit handles.
+ */
+ NodeType articulations : 8*sizeof(NodeType)-1;
+
+private:
+
+ NodeType hasStaticContact : 1;
+
+public:
+
+ /**
+ \brief The starting index of island contact managers in the array PxsIslandObjects::contactManagers.
+ */
+ EdgeType contactManagers;
+
+ /**
+ \brief The starting index of island constraints in the array PxsIslandObjects::constraints.
+
+ \note islandId is for internal use only and is used for tracking islands that need a second pass.
+ */
+ union
+ {
+ EdgeType constraints;
+ IslandType islandId;
+ };
+
+//private:
+
+ /**
+ \brief Internal use only.
+ */
+ PX_FORCE_INLINE void setHasStaticContact(const bool b)
+ {
+ hasStaticContact = NodeType(b ? 1 : 0);
+ }
+};
+PX_COMPILE_TIME_ASSERT(0==(0x07 & sizeof(PxsIslandIndices)));
+
+
+//----------------------------------------------------------------------------//
+
+typedef Dy::ArticulationLinkHandle PxsNodeType;
+
+
+/**
+\brief Each contact manager or constraint references two separate bodies, where
+a body can be a dynamic rigid body, a kinematic rigid body, an articulation or a static.
+The struct PxsIndexedInteraction describes the bodies that make up the pair.
+*/
+struct PxsIndexedInteraction
+{
+ /**
+ \brief An enumerated list of all possible body types.
+ A body type is stored for each body in the pair.
+ */
+ enum Enum
+ {
+ eBODY = 0,
+ eKINEMATIC = 1,
+ eARTICULATION = 2,
+ eWORLD = 3
+ };
+
+ /**
+ \brief An index describing how to access body0
+
+ \note If body0 is a dynamic (eBODY) rigid body then solverBody0 is an index into PxsIslandObjects::bodies.
+ \note If body0 is a kinematic (eKINEMATIC) rigid body then solverBody0 is an index into PxsIslandManager::getActiveKinematics.
+
+ \note If body0 is a static (eWORLD) then solverBody0 is PX_MAX_U32 or PX_MAX_U64, depending on the platform being 32- or 64-bit.
+
+ \note If body0 is an articulation then the articulation is found directly from Dy::getArticulation(articulation0)
+ */
+ union
+ {
+ PxsNodeType solverBody0;
+ Dy::ArticulationLinkHandle articulation0;
+ };
+
+ /**
+ \brief An index describing how to access body1
+
+ \note If body1 is a dynamic (eBODY) rigid body then solverBody1 is an index into PxsIslandObjects::bodies.
+ \note If body1 is a kinematic (eKINEMATIC) rigid body then solverBody1 is an index into PxsIslandManager::getActiveKinematics.
+
+ \note If body1 is a static (eWORLD) then solverBody1 is PX_MAX_U32 or PX_MAX_U64, depending on the platform being 32- or 64-bit.
+
+ \note If body1 is an articulation then the articulation is found directly from Dy::getArticulation(articulation1)
+ */
+ union
+ {
+ PxsNodeType solverBody1;
+ Dy::ArticulationLinkHandle articulation1;
+ };
+
+ /**
+ \brief The type (eBODY, eKINEMATIC etc) of body0
+ */
+ PxU8 indexType0;
+
+ /**
+ \brief The type (eBODY, eKINEMATIC etc) of body1
+ */
+ PxU8 indexType1;
+
+ PxU8 pad[2];
+};
+
+/**
+@see PxsIslandObjects, PxsIndexedInteraction
+*/
+struct PxsIndexedContactManager : public PxsIndexedInteraction
+{
+ /**
+ \brief The contact manager corresponds to the value set in PxsIslandManager::setEdgeRigidCM
+ */
+ PxsContactManager* contactManager;
+
+ PxsIndexedContactManager(PxsContactManager* cm) : contactManager(cm) {}
+};
+#if !PX_X64
+PX_COMPILE_TIME_ASSERT(0==(sizeof(PxsIndexedContactManager) & 0x0f));
+#endif
+
+/**
+@see PxsIslandObjects, PxsIndexedInteraction
+*/
+struct PxsIndexedConstraint : public PxsIndexedInteraction
+{
+ /**
+ \brief The constraint corresponds to the value set in PxsIslandManager::setEdgeConstraint
+ */
+ Dy::Constraint* constraint;
+
+ PxsIndexedConstraint(Dy::Constraint* c) : constraint(c) {}
+};
+#if !PX_P64_FAMILY
+PX_COMPILE_TIME_ASSERT(0==(sizeof(PxsIndexedConstraint) & 0x0f));
+#endif
+
+//----------------------------------------------------------------------------//
+
+/**
+\brief Any sleeping contact pair that finds itself in an awake island after 1st pass island gen
+must participate in 2nd pass narrowphase so that contacts can be generated.
+
+\note Contact managers in sleeping pairs are NULL until PxsIslandManager::setWokenPairContactManagers is complete.
+
+@see PxsIslandManager::getNarrowPhaseSecondPassContactManagers, PxsIslandManager::getNumNarrowPhaseSecondPassContactManagers,
+PxsIslandManager::setWokenPairContactManagers
+*/
+struct PxsNarrowPhaseSecondPassContactManager
+{
+ /**
+ \brief The contact manager that is to participate in 2nd pass narrowphase.
+
+ \note This pointer is NULL after 1st pass island gen and remains NULL until PxsIslandManager::setWokenPairContactManagers
+ completes.
+ */
+ PxsContactManager* mCM;
+
+ /**
+ \brief The corresponding entry in PxsIslandObjects::contactManagers.
+
+ \note All sleeping pairs have a null contact manager during 1st pass island gen. After 1st pass island gen completes,
+ the bodies to be woken are externally processed. Waking up bodies generates contact managers and passes the pointer to the
+ corresponding edge. So that the contact manager can be efficiently passed to PxsIslandObjects we store mEdgeId and mSolverCMId.
+ The contact manager pointers are set in PxsIslandManager::setWokenPairContactManagers
+ */
+ EdgeType mSolverCMId; //Keeps a track of which entries in the solver islands temporarily have a null contact manager
+
+ /**
+ \brief The internal id of the corresponding edge.
+ */
+ EdgeType mEdgeId;
+};
+
+
+} //namespace physx
+
+
+#endif //PXS_ISLAND_MANAGER_TYPES_H
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsIslandSim.h b/PhysX_3.4/Source/LowLevel/software/include/PxsIslandSim.h
new file mode 100644
index 00000000..48cfc7d2
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsIslandSim.h
@@ -0,0 +1,965 @@
+// 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 PXS_ISLAND_SIM_H
+#define PXS_ISLAND_SIM_H
+
+#include "CmPhysXCommon.h"
+#include "foundation/PxAssert.h"
+#include "PsArray.h"
+#include "CmBitMap.h"
+#include "CmPriorityQueue.h"
+
+namespace physx
+{
+
+namespace Dy
+{
+ struct Constraint;
+ class Articulation;
+}
+
+namespace Sc
+{
+ class ArticulationSim;
+}
+
+class PxsContactManager;
+class PxsRigidBody;
+
+struct PartitionEdge;
+
+namespace IG
+{
+
+//This index is
+#define IG_INVALID_ISLAND 0xFFFFFFFFu
+#define IG_INVALID_EDGE 0xFFFFFFFFu
+#define IG_INVALID_NODE 0x3FFFFFFu
+#define IG_INVALID_LINK 0xFFu
+
+typedef PxU32 IslandId;
+typedef PxU32 EdgeIndex;
+typedef PxU32 EdgeInstanceIndex;
+
+class IslandSim;
+
+
+
+class NodeIndex
+{
+private:
+ PxU32 ind;
+
+public:
+
+ explicit PX_FORCE_INLINE NodeIndex(PxU32 id = IG_INVALID_NODE, PxU32 articId = 0) : ind((id<<6) | articId)
+ {
+ }
+
+ PxU32 index() const { return ind>>6; }
+ PxU32 articulationLinkId() const { return (ind & 63); }
+
+ bool isStaticBody() const { return (ind>>6) == IG_INVALID_NODE; }
+
+ bool isValid() const { return (ind>>6) != IG_INVALID_NODE; }
+
+ void setIndices(PxU32 index, PxU32 articId) { ind = ((index<<6) | articId); }
+};
+
+union ConstraintOrContactManager
+{
+ PxsContactManager* mCm;
+ Dy::Constraint* mConstraint;
+};
+
+
+struct Edge
+{
+ //Edge instances can be implicitly calculated based on this edge index, which is an offset into the array of edges.
+ //From that, the child edge index is simply the
+ //The constraint or contact referenced by this edge
+
+ enum EdgeType
+ {
+ eCONTACT_MANAGER,
+ eCONSTRAINT,
+ eEDGE_TYPE_COUNT
+ };
+
+
+ enum EdgeState
+ {
+ eINSERTED =1<<0,
+ ePENDING_DESTROYED =1<<1,
+ eACTIVE =1<<2,
+ eIN_DIRTY_LIST =1<<3,
+ eDESTROYED =1<<4,
+ eREPORT_ONLY_DESTROY=1<<5,
+ eACTIVATING =1<<6
+ };
+
+
+ //NodeIndex mNode1, mNode2;
+ EdgeType mEdgeType;
+ PxU16 mEdgeState;
+
+ EdgeIndex mNextIslandEdge, mPrevIslandEdge;
+
+
+
+ PX_FORCE_INLINE void setInserted() { mEdgeState |= (eINSERTED); }
+
+ PX_FORCE_INLINE void clearInserted() { mEdgeState &= (~eINSERTED); }
+
+ PX_FORCE_INLINE void clearDestroyed() { mEdgeState &=(~eDESTROYED);}
+ PX_FORCE_INLINE void setPendingDestroyed() { mEdgeState |= ePENDING_DESTROYED; }
+ PX_FORCE_INLINE void clearPendingDestroyed() { mEdgeState &= (~ePENDING_DESTROYED); }
+ PX_FORCE_INLINE void activateEdge() { mEdgeState |= eACTIVE; }
+ PX_FORCE_INLINE void deactivateEdge() { mEdgeState &= (~eACTIVE); }
+ PX_FORCE_INLINE void markInDirtyList() { mEdgeState |= (eIN_DIRTY_LIST); }
+ PX_FORCE_INLINE void clearInDirtyList() { mEdgeState &= (~eIN_DIRTY_LIST); }
+ PX_FORCE_INLINE void setReportOnlyDestroy() { mEdgeState |= (eREPORT_ONLY_DESTROY); }
+ PX_FORCE_INLINE void clearReportOnlyDestroy() { mEdgeState &= (~eREPORT_ONLY_DESTROY); }
+public:
+ Edge() : mEdgeType(Edge::eCONTACT_MANAGER), mEdgeState(eDESTROYED),
+ mNextIslandEdge(IG_INVALID_EDGE), mPrevIslandEdge(IG_INVALID_EDGE)
+ {
+ }
+ PX_FORCE_INLINE bool isInserted() const { return !!(mEdgeState & eINSERTED);}
+ PX_FORCE_INLINE bool isDestroyed() const { return !!(mEdgeState & eDESTROYED); }
+ PX_FORCE_INLINE bool isPendingDestroyed() const { return !!(mEdgeState & ePENDING_DESTROYED); }
+ PX_FORCE_INLINE bool isActive() const { return !!(mEdgeState & eACTIVE); }
+ PX_FORCE_INLINE bool isInDirtyList() const { return !!(mEdgeState & eIN_DIRTY_LIST); }
+ PX_FORCE_INLINE EdgeType getEdgeType() const { return mEdgeType; }
+ //PX_FORCE_INLINE const NodeIndex getIndex1() const { return mNode1; }
+ //PX_FORCE_INLINE const NodeIndex getIndex2() const { return mNode2; }
+ PX_FORCE_INLINE bool isReportOnlyDestroy() { return !!(mEdgeState & eREPORT_ONLY_DESTROY); }
+};
+
+struct EdgeInstance
+{
+ EdgeInstanceIndex mNextEdge, mPrevEdge; //The next edge instance in this node's list of edge instances
+
+ EdgeInstance() : mNextEdge(IG_INVALID_EDGE), mPrevEdge(IG_INVALID_EDGE)
+ {
+ }
+};
+
+template<typename Handle>
+class HandleManager
+{
+ Ps::Array<Handle> mFreeHandles;
+ Handle mCurrentHandle;
+
+public:
+
+ HandleManager() : mFreeHandles(PX_DEBUG_EXP("FreeHandles")), mCurrentHandle(0)
+ {
+ }
+
+ ~HandleManager(){}
+
+ Handle getHandle()
+ {
+ if(mFreeHandles.size())
+ {
+ Handle handle = mFreeHandles.popBack();
+ PX_ASSERT(isValidHandle(handle));
+ return handle;
+ }
+ return mCurrentHandle++;
+ }
+
+ bool isNotFreeHandle(Handle handle)
+ {
+ for(PxU32 a = 0; a < mFreeHandles.size(); ++a)
+ {
+ if(mFreeHandles[a] == handle)
+ return false;
+ }
+ return true;
+ }
+
+ void freeHandle(Handle handle)
+ {
+ PX_ASSERT(isValidHandle(handle));
+ PX_ASSERT(isNotFreeHandle(handle));
+ if(handle == mCurrentHandle)
+ mCurrentHandle--;
+ else
+ mFreeHandles.pushBack(handle);
+ }
+
+ bool isValidHandle(Handle handle)
+ {
+ return handle < mCurrentHandle;
+ }
+
+ PX_FORCE_INLINE PxU32 getTotalHandles() const { return mCurrentHandle; }
+};
+
+class Node
+{
+
+public:
+ enum NodeType
+ {
+ eRIGID_BODY_TYPE,
+ eARTICULATION_TYPE,
+ eTYPE_COUNT
+ };
+ enum State
+ {
+ eREADY_FOR_SLEEPING = 1u << 0, //! Ready to go to sleep
+ eACTIVE = 1u << 1, //! Active
+ eKINEMATIC = 1u << 2, //! Kinematic
+ eDELETED = 1u << 3, //! Is pending deletion
+ eDIRTY = 1u << 4, //! Is dirty (i.e. lost a connection)
+ eACTIVATING = 1u << 5, //! Is in the activating list
+ eDEACTIVATING = 1u << 6 //! It is being forced to deactivate this frame
+ };
+ EdgeInstanceIndex mFirstEdgeIndex;
+
+ PxU8 mFlags;
+ PxU8 mType;
+ PxU16 mStaticTouchCount;
+ //PxU32 mActiveNodeIndex; //! Look-up for this node in the active nodes list, activating list or deactivating list...
+
+ NodeIndex mNextNode, mPrevNode;
+
+ //A counter for the number of active references to this body. Whenever an edge is activated, this is incremented.
+ //Whenver an edge is deactivated, this is decremented. This is used for kinematic bodies to determine if they need
+ //to be in the active kinematics list
+ PxU32 mActiveRefCount;
+
+
+ //A node can correspond with either a rigid body or an articulation.
+ union
+ {
+ PxsRigidBody* mRigidBody;
+ Dy::Articulation* mLLArticulation;
+ };
+
+
+
+ PX_FORCE_INLINE Node() : mFirstEdgeIndex(IG_INVALID_EDGE), mFlags(eDELETED), mType(eRIGID_BODY_TYPE),
+ mStaticTouchCount(0), mActiveRefCount(0), mRigidBody(NULL)
+ {
+ }
+
+ PX_FORCE_INLINE ~Node() {}
+
+ PX_FORCE_INLINE void reset()
+ {
+ mFirstEdgeIndex = IG_INVALID_EDGE;
+ mFlags = eDELETED;
+ mRigidBody = NULL;
+ mActiveRefCount = 0;
+ mStaticTouchCount = 0;
+ }
+
+ PX_FORCE_INLINE void setRigidBody(PxsRigidBody* body) { mRigidBody = body; }
+
+ PX_FORCE_INLINE PxsRigidBody* getRigidBody() const { return mRigidBody; }
+
+ PX_FORCE_INLINE Dy::Articulation* getArticulation() const { return mLLArticulation; }
+
+
+ PX_FORCE_INLINE void setActive() { mFlags |= eACTIVE; }
+ PX_FORCE_INLINE void clearActive() { mFlags &= ~eACTIVE; }
+
+ PX_FORCE_INLINE void setActivating() { mFlags |= eACTIVATING; }
+ PX_FORCE_INLINE void clearActivating() { mFlags &= ~eACTIVATING; }
+
+ PX_FORCE_INLINE void setDeactivating() { mFlags |= eDEACTIVATING; }
+ PX_FORCE_INLINE void clearDeactivating() { mFlags &= (~eDEACTIVATING); }
+
+
+ //Activates a body/node.
+ PX_FORCE_INLINE void setIsReadyForSleeping() { mFlags |= eREADY_FOR_SLEEPING; }
+
+ PX_FORCE_INLINE void clearIsReadyForSleeping(){ mFlags &= (~eREADY_FOR_SLEEPING);}
+
+ PX_FORCE_INLINE void setIsDeleted(){mFlags |= eDELETED; }
+
+ PX_FORCE_INLINE void setKinematicFlag() {PX_ASSERT(!isKinematic()); mFlags |= eKINEMATIC;}
+
+ PX_FORCE_INLINE void clearKinematicFlag(){ PX_ASSERT(isKinematic()); mFlags &= (~eKINEMATIC);}
+
+ PX_FORCE_INLINE void markDirty(){mFlags |= eDIRTY;}
+
+ PX_FORCE_INLINE void clearDirty(){mFlags &= (~eDIRTY);}
+
+public:
+
+ PX_FORCE_INLINE bool isActive() const { return !!(mFlags & eACTIVE); }
+
+ PX_FORCE_INLINE bool isActivating() const { return !!(mFlags & eACTIVATING); }
+
+ PX_FORCE_INLINE bool isDeactivating() const { return !!(mFlags & eDEACTIVATING); }
+
+ PX_FORCE_INLINE bool isKinematic() const { return !!(mFlags & eKINEMATIC); }
+
+ PX_FORCE_INLINE bool isDeleted() const { return !!(mFlags & eDELETED); }
+
+ PX_FORCE_INLINE bool isDirty() const { return !!(mFlags & eDIRTY); }
+
+ PX_FORCE_INLINE bool isReadyForSleeping() const { return !!(mFlags & eREADY_FOR_SLEEPING); }
+
+ PX_FORCE_INLINE NodeType getNodeType() const { return NodeType(mType); }
+
+ friend class SimpleIslandManager;
+
+};
+
+struct Island
+{
+ NodeIndex mRootNode;
+ NodeIndex mLastNode;
+ PxU32 mSize[Node::eTYPE_COUNT];
+ PxU32 mActiveIndex;
+
+ EdgeIndex mFirstEdge[Edge::eEDGE_TYPE_COUNT], mLastEdge[Edge::eEDGE_TYPE_COUNT];
+ PxU32 mEdgeCount[Edge::eEDGE_TYPE_COUNT];
+
+ Island() : mActiveIndex(IG_INVALID_ISLAND)
+ {
+ for(PxU32 a = 0; a < Edge::eEDGE_TYPE_COUNT; ++a)
+ {
+ mFirstEdge[a] = IG_INVALID_EDGE;
+ mLastEdge[a] = IG_INVALID_EDGE;
+ mEdgeCount[a] = 0;
+ }
+
+ for(PxU32 a = 0; a < Node::eTYPE_COUNT; ++a)
+ {
+ mSize[a] = 0;
+ }
+ }
+};
+
+struct TraversalState
+{
+ NodeIndex mNodeIndex;
+ PxU32 mCurrentIndex;
+ PxU32 mPrevIndex;
+ PxU32 mDepth;
+
+ TraversalState()
+ {
+ }
+
+ TraversalState(NodeIndex nodeIndex, PxU32 currentIndex, PxU32 prevIndex, PxU32 depth) :
+ mNodeIndex(nodeIndex), mCurrentIndex(currentIndex), mPrevIndex(prevIndex), mDepth(depth)
+ {
+ }
+};
+
+struct QueueElement
+{
+ TraversalState* mState;
+ PxU32 mHopCount;
+
+ QueueElement()
+ {
+ }
+
+ QueueElement(TraversalState* state, PxU32 hopCount) : mState(state), mHopCount(hopCount)
+ {
+ }
+};
+
+struct NodeComparator
+{
+ NodeComparator()
+ {
+ }
+
+ bool operator() (const QueueElement& node0, const QueueElement& node1) const
+ {
+ return node0.mHopCount < node1.mHopCount;
+ }
+private:
+ NodeComparator& operator = (const NodeComparator&);
+};
+
+
+class IslandSim
+{
+ HandleManager<IslandId> mIslandHandles; //! Handle manager for islands
+
+ Ps::Array<Node> mNodes; //! The nodes used in the constraint graph
+ Ps::Array<PxU32> mActiveNodeIndex; //! The active node index for each node
+ Ps::Array<Edge> mEdges; //! Edges used to represent contacts or constraints
+ //Ps::Array<ConstraintOrContactManager> mConstraintOrCm; //! Pointers to either the constraint or Cm for this pair
+ Ps::Array<EdgeInstance> mEdgeInstances; //! Edges used to connect nodes in the constraint graph
+ Ps::Array<Island> mIslands; //! The array of islands
+ Ps::Array<PxU32> mIslandStaticTouchCount; //! Array of static touch counts per-island
+
+
+ Ps::Array<NodeIndex> mActiveNodes[Node::eTYPE_COUNT]; //! An array of active nodes
+ Ps::Array<NodeIndex> mActiveKinematicNodes; //! An array of active or referenced kinematic nodes
+ //Ps::Array<EdgeIndex> mActiveEdges[Edge::eEDGE_TYPE_COUNT]; //! An array of active edges
+ Ps::Array<EdgeIndex> mActivatedEdges[Edge::eEDGE_TYPE_COUNT]; //! An array of active edges
+
+ PxU32 mActiveEdgeCount[Edge::eEDGE_TYPE_COUNT];
+
+ Ps::Array<PxU32> mHopCounts; //! The observed number of "hops" from a given node to its root node. May be inaccurate but used to accelerate searches.
+ Ps::Array<NodeIndex> mFastRoute; //! The observed last route from a given node to the root node. We try the fast route (unless its broken) before trying others.
+
+ Ps::Array<IslandId> mIslandIds; //! The array of per-node island ids
+
+ Cm::BitMap mIslandAwake; //! Indicates whether an island is awake or not
+
+ Cm::BitMap mActiveContactEdges;
+
+ //An array of active islands
+ Ps::Array<IslandId> mActiveIslands;
+
+ //PxU32 mInitialActiveEdgeCount[Edge::eEDGE_TYPE_COUNT];
+ PxU32 mInitialActiveNodeCount[Edge::eEDGE_TYPE_COUNT];
+
+ Ps::Array<NodeIndex> mNodesToPutToSleep[Node::eTYPE_COUNT];
+
+ //Input to this frame's island management (changed nodes/edges)
+
+ //Input list of changes observed this frame. If there no changes, no work to be done.
+ Ps::Array<EdgeIndex> mDirtyEdges[Edge::eEDGE_TYPE_COUNT];
+ //Dirty nodes. These nodes lost at least one connection so we need to recompute islands from these nodes
+ //Ps::Array<NodeIndex> mDirtyNodes;
+ Cm::BitMap mDirtyMap;
+ PxU32 mLastMapIndex;
+
+ //An array of nodes to activate
+ Ps::Array<NodeIndex> mActivatingNodes;
+ Ps::Array<EdgeIndex> mDestroyedEdges;
+ Ps::Array<IslandId> mTempIslandIds;
+
+
+ //Temporary, transient data used for traversals. TODO - move to PxsSimpleIslandManager. Or if we keep it here, we can
+ //process multiple island simulations in parallel
+ Cm::PriorityQueue<QueueElement, NodeComparator>
+ mPriorityQueue; //! Priority queue used for graph traversal
+ Ps::Array<TraversalState> mVisitedNodes; //! The list of nodes visited in the current traversal
+ Cm::BitMap mVisitedState; //! Indicates whether a node has been visited
+ Ps::Array<EdgeIndex> mIslandSplitEdges[Edge::eEDGE_TYPE_COUNT];
+
+ Ps::Array<EdgeIndex> mDeactivatingEdges[Edge::eEDGE_TYPE_COUNT];
+
+ Ps::Array<PartitionEdge*>* mFirstPartitionEdges;
+ Ps::Array<NodeIndex>& mEdgeNodeIndices;
+ Ps::Array<physx::PartitionEdge*>* mDestroyedPartitionEdges;
+
+ PxU32* mNpIndexPtr;
+
+ PxU64 mContextId;
+
+public:
+
+ IslandSim(Ps::Array<PartitionEdge*>* firstPartitionEdges, Ps::Array<NodeIndex>& edgeNodeIndices, Ps::Array<PartitionEdge*>* destroyedPartitionEdges, PxU64 contextID);
+ ~IslandSim() {}
+
+ void resize(const PxU32 nbNodes, const PxU32 nbContactManagers, const PxU32 nbConstraints);
+
+ void addRigidBody(PxsRigidBody* body, bool isKinematic, bool isActive, NodeIndex nodeIndex);
+
+ void addArticulation(Sc::ArticulationSim* articulation, Dy::Articulation* llArtic, bool isActive, NodeIndex nodeIndex);
+
+ void addContactManager(PxsContactManager* manager, NodeIndex nodeHandle1, NodeIndex nodeHandle2, EdgeIndex handle);
+
+ void addConstraint(Dy::Constraint* constraint, NodeIndex nodeHandle1, NodeIndex nodeHandle2, EdgeIndex handle);
+
+ void activateNode(NodeIndex index);
+ void deactivateNode(NodeIndex index);
+ void putNodeToSleep(NodeIndex index);
+
+ void removeConnection(EdgeIndex edgeIndex);
+
+ PX_FORCE_INLINE PxU32 getNbNodes() const { return mNodes.size(); }
+
+ PX_FORCE_INLINE PxU32 getNbActiveNodes(Node::NodeType type) const { return mActiveNodes[type].size(); }
+
+ PX_FORCE_INLINE const NodeIndex* getActiveNodes(Node::NodeType type) const { return mActiveNodes[type].begin(); }
+
+ PX_FORCE_INLINE PxU32 getNbActiveKinematics() const { return mActiveKinematicNodes.size(); }
+
+ PX_FORCE_INLINE const NodeIndex* getActiveKinematics() const { return mActiveKinematicNodes.begin(); }
+
+ PX_FORCE_INLINE PxU32 getNbNodesToActivate(Node::NodeType type) const { return mActiveNodes[type].size() - mInitialActiveNodeCount[type]; }
+
+ PX_FORCE_INLINE const NodeIndex* getNodesToActivate(Node::NodeType type) const { return mActiveNodes[type].begin() + mInitialActiveNodeCount[type]; }
+
+ PX_FORCE_INLINE PxU32 getNbNodesToDeactivate(Node::NodeType type) const { return mNodesToPutToSleep[type].size(); }
+
+ PX_FORCE_INLINE const NodeIndex* getNodesToDeactivate(Node::NodeType type) const { return mNodesToPutToSleep[type].begin(); }
+
+ PX_FORCE_INLINE PxU32 getNbActivatedEdges(Edge::EdgeType type) const { return mActivatedEdges[type].size(); }
+
+ PX_FORCE_INLINE const EdgeIndex* getActivatedEdges(Edge::EdgeType type) const { return mActivatedEdges[type].begin(); }
+
+ PX_FORCE_INLINE PxU32 getNbActiveEdges(Edge::EdgeType type) const { return mActiveEdgeCount[type]; }
+
+ PX_FORCE_INLINE PartitionEdge* getFirstPartitionEdge(IG::EdgeIndex edgeIndex) const { return (*mFirstPartitionEdges)[edgeIndex]; }
+ PX_FORCE_INLINE void setFirstPartitionEdge(IG::EdgeIndex edgeIndex, PartitionEdge* partitionEdge) { (*mFirstPartitionEdges)[edgeIndex] = partitionEdge; }
+
+ //PX_FORCE_INLINE const EdgeIndex* getActiveEdges(Edge::EdgeType type) const { return mActiveEdges[type].begin(); }
+
+ PX_FORCE_INLINE PxsRigidBody* getRigidBody(NodeIndex nodeIndex) const
+ {
+ const Node& node = mNodes[nodeIndex.index()];
+ PX_ASSERT(node.mType == Node::eRIGID_BODY_TYPE);
+ return node.mRigidBody;
+ }
+
+ PX_FORCE_INLINE Dy::Articulation* getLLArticulation(NodeIndex nodeIndex) const
+ {
+ const Node& node = mNodes[nodeIndex.index()];
+ PX_ASSERT(node.mType == Node::eARTICULATION_TYPE);
+ return node.mLLArticulation;
+ }
+
+ PX_FORCE_INLINE void clearDeactivations()
+ {
+ mNodesToPutToSleep[0].forceSize_Unsafe(0);
+ mNodesToPutToSleep[1].forceSize_Unsafe(0);
+
+ mDeactivatingEdges[0].forceSize_Unsafe(0);
+ mDeactivatingEdges[1].forceSize_Unsafe(0);
+ }
+
+ PX_FORCE_INLINE const Island& getIsland(IG::IslandId islandIndex) const { return mIslands[islandIndex]; }
+
+ PX_FORCE_INLINE PxU32 getNbActiveIslands() const { return mActiveIslands.size(); }
+ PX_FORCE_INLINE const IslandId* getActiveIslands() const { return mActiveIslands.begin(); }
+
+ PX_FORCE_INLINE PxU32 getNbDeactivatingEdges(const IG::Edge::EdgeType edgeType) const { return mDeactivatingEdges[edgeType].size(); }
+ PX_FORCE_INLINE const EdgeIndex* getDeactivatingEdges(const IG::Edge::EdgeType edgeType) const { return mDeactivatingEdges[edgeType].begin(); }
+
+ PX_FORCE_INLINE PxU32 getNbDestroyedEdges() const { return mDestroyedEdges.size(); }
+ PX_FORCE_INLINE const EdgeIndex* getDestroyedEdges() const { return mDestroyedEdges.begin(); }
+
+ PX_FORCE_INLINE PxU32 getNbDestroyedPartitionEdges() const { return mDestroyedPartitionEdges->size(); }
+ PX_FORCE_INLINE const PartitionEdge*const * getDestroyedPartitionEdges() const { return mDestroyedPartitionEdges->begin(); }
+ PX_FORCE_INLINE PartitionEdge** getDestroyedPartitionEdges() { return mDestroyedPartitionEdges->begin(); }
+
+ PX_FORCE_INLINE PxU32 getNbDirtyEdges(IG::Edge::EdgeType type) const { return mDirtyEdges[type].size(); }
+ PX_FORCE_INLINE const EdgeIndex* getDirtyEdges(IG::Edge::EdgeType type) const { return mDirtyEdges[type].begin(); }
+
+ PX_FORCE_INLINE const Edge& getEdge(const EdgeIndex edgeIndex) const { return mEdges[edgeIndex]; }
+
+ PX_FORCE_INLINE Edge& getEdge(const EdgeIndex edgeIndex) { return mEdges[edgeIndex]; }
+
+ PX_FORCE_INLINE const Node& getNode(const NodeIndex& nodeIndex) const { return mNodes[nodeIndex.index()]; }
+
+ PX_FORCE_INLINE const Island& getIsland(const NodeIndex& nodeIndex) const { PX_ASSERT(mIslandIds[nodeIndex.index()] != IG_INVALID_ISLAND); return mIslands[mIslandIds[nodeIndex.index()]]; }
+
+ PX_FORCE_INLINE PxU32 getIslandStaticTouchCount(const NodeIndex& nodeIndex) const { PX_ASSERT(mIslandIds[nodeIndex.index()] != IG_INVALID_ISLAND); return mIslandStaticTouchCount[mIslandIds[nodeIndex.index()]]; }
+
+ PX_FORCE_INLINE const Cm::BitMap& getActiveContactManagerBitmap() const { return mActiveContactEdges; }
+
+ PX_FORCE_INLINE PxU32 getActiveNodeIndex(const NodeIndex& nodeIndex) const { PxU32 activeNodeIndex = mActiveNodeIndex[nodeIndex.index()]; return activeNodeIndex;}
+
+ PX_FORCE_INLINE const PxU32* getActiveNodeIndex() const { return mActiveNodeIndex.begin(); }
+
+ PX_FORCE_INLINE PxU32 getNbActiveNodeIndex() const { return mActiveNodeIndex.size(); }
+
+ void setKinematic(IG::NodeIndex nodeIndex);
+
+ void setDynamic(IG::NodeIndex nodeIndex);
+
+ PX_FORCE_INLINE void setEdgeNodeIndexPtr(PxU32* ptr) { mNpIndexPtr = ptr; }
+
+ PX_FORCE_INLINE NodeIndex getNodeIndex1(IG::EdgeIndex index) const { return mEdgeNodeIndices[2 * index]; }
+ PX_FORCE_INLINE NodeIndex getNodeIndex2(IG::EdgeIndex index) const { return mEdgeNodeIndices[2 * index + 1]; }
+
+ PX_FORCE_INLINE PxU32* getEdgeNodeIndexPtr() const { return mNpIndexPtr; }
+ PX_FORCE_INLINE PxU64 getContextId() const { return mContextId; }
+
+ PxU32 getNbIslands() const { return mIslandStaticTouchCount.size(); }
+
+ const PxU32* getIslandStaticTouchCount() const { return mIslandStaticTouchCount.begin(); }
+
+ const PxU32* getIslandIds() const { return mIslandIds.begin(); }
+
+ bool checkInternalConsistency();
+
+private:
+
+ void insertNewEdges();
+ void removeDestroyedEdges();
+ void wakeIslands();
+ void wakeIslands2();
+ void processNewEdges();
+ void processLostEdges(Ps::Array<NodeIndex>& destroyedNodes, bool allowDeactivation, bool permitKinematicDeactivation, PxU32 dirtyNodeLimit);
+
+ void removeConnectionInternal(EdgeIndex edgeIndex);
+
+ void addConnection(NodeIndex nodeHandle1, NodeIndex nodeHandle2, Edge::EdgeType edgeType, EdgeIndex handle);
+
+ void addConnectionToGraph(EdgeIndex index);
+ void removeConnectionFromGraph(EdgeIndex edgeIndex);
+ void connectEdge(EdgeInstance& instance, EdgeInstanceIndex edgeIndex, Node& source, NodeIndex destination);
+ void disconnectEdge(EdgeInstance& instance, EdgeInstanceIndex edgeIndex, Node& node);
+
+ //Merges 2 islands together. The returned id is the id of the merged island
+ IslandId mergeIslands(IslandId island0, IslandId island1, NodeIndex node0, NodeIndex node1);
+
+ void mergeIslandsInternal(Island& island0, Island& island1, IslandId islandId0, IslandId islandId1, NodeIndex node0, NodeIndex node1);
+
+
+ IslandSim& operator = (const IslandSim&);
+ IslandSim(const IslandSim&);
+
+ void unwindRoute(PxU32 traversalIndex, NodeIndex lastNode, PxU32 hopCount, IslandId id);
+
+ void activateIsland(IslandId island);
+
+ void deactivateIsland(IslandId island);
+
+ bool canFindRoot(NodeIndex startNode, NodeIndex targetNode, Ps::Array<NodeIndex>* visitedNodes);
+
+ bool tryFastPath(NodeIndex startNode, NodeIndex targetNode, IslandId islandId);
+
+ bool findRoute(NodeIndex startNode, NodeIndex targetNode, IslandId islandId);
+
+ bool isPathTo(NodeIndex startNode, NodeIndex targetNode);
+
+ void addNode(bool isActive, bool isKinematic, Node::NodeType type, NodeIndex nodeIndex);
+
+ void activateNodeInternal(NodeIndex index);
+ void deactivateNodeInternal(NodeIndex index);
+
+ PX_FORCE_INLINE void notifyReadyForSleeping(const NodeIndex nodeIndex)
+ {
+ Node& node = mNodes[nodeIndex.index()];
+ //PX_ASSERT(node.isActive());
+ node.setIsReadyForSleeping();
+ }
+
+ PX_FORCE_INLINE void notifyNotReadyForSleeping(const NodeIndex nodeIndex)
+ {
+ Node& node = mNodes[nodeIndex.index()];
+ PX_ASSERT(node.isActive() || node.isActivating());
+ node.clearIsReadyForSleeping();
+ }
+
+ PX_FORCE_INLINE void markIslandActive(IslandId islandId)
+ {
+ Island& island = mIslands[islandId];
+ PX_ASSERT(!mIslandAwake.test(islandId));
+ PX_ASSERT(island.mActiveIndex == IG_INVALID_ISLAND);
+
+ mIslandAwake.set(islandId);
+ island.mActiveIndex = mActiveIslands.size();
+ mActiveIslands.pushBack(islandId);
+ }
+
+ PX_FORCE_INLINE void markIslandInactive(IslandId islandId)
+ {
+ Island& island = mIslands[islandId];
+ PX_ASSERT(mIslandAwake.test(islandId));
+ PX_ASSERT(island.mActiveIndex != IG_INVALID_ISLAND);
+ PX_ASSERT(mActiveIslands[island.mActiveIndex] == islandId);
+ IslandId replaceId = mActiveIslands[mActiveIslands.size()-1];
+ PX_ASSERT(mIslandAwake.test(replaceId));
+ Island& replaceIsland = mIslands[replaceId];
+ replaceIsland.mActiveIndex = island.mActiveIndex;
+ mActiveIslands[island.mActiveIndex] = replaceId;
+ mActiveIslands.forceSize_Unsafe(mActiveIslands.size()-1);
+ island.mActiveIndex = IG_INVALID_ISLAND;
+ mIslandAwake.reset(islandId);
+ }
+
+ PX_FORCE_INLINE void markKinematicActive(NodeIndex index)
+ {
+ Node& node = mNodes[index.index()];
+ PX_ASSERT(node.isKinematic());
+ if(node.mActiveRefCount == 0 && mActiveNodeIndex[index.index()] == IG_INVALID_NODE)
+ {
+ //PX_ASSERT(mActiveNodeIndex[index.index()] == IG_INVALID_NODE);
+ //node.mActiveNodeIndex = mActiveKinematicNodes.size();
+ mActiveNodeIndex[index.index()] = mActiveKinematicNodes.size();
+ mActiveKinematicNodes.pushBack(index);
+ }
+ }
+
+ PX_FORCE_INLINE void markKinematicInactive(NodeIndex index)
+ {
+ Node& node = mNodes[index.index()];
+ PX_ASSERT(node.isKinematic());
+ PX_ASSERT(mActiveNodeIndex[index.index()] != IG_INVALID_NODE);
+ PX_ASSERT(mActiveKinematicNodes[mActiveNodeIndex[index.index()]].index() == index.index());
+
+ if(node.mActiveRefCount == 0)
+ {
+ //Only remove from active kinematic list if it has no active contacts referencing it *and* it is asleep
+ if(mActiveNodeIndex[index.index()] != IG_INVALID_NODE)
+ {
+ //Need to verify active node index because there is an edge case where a node could be woken, then put to
+ //sleep in the same frame. This would mean that it would not have an active index at this stage.
+ NodeIndex replaceIndex = mActiveKinematicNodes.back();
+ PX_ASSERT(mActiveNodeIndex[replaceIndex.index()] == mActiveKinematicNodes.size()-1);
+ mActiveNodeIndex[replaceIndex.index()] = mActiveNodeIndex[index.index()];
+ mActiveKinematicNodes[mActiveNodeIndex[index.index()]] = replaceIndex;
+ mActiveKinematicNodes.forceSize_Unsafe(mActiveKinematicNodes.size()-1);
+ mActiveNodeIndex[index.index()] = IG_INVALID_NODE;
+ }
+ }
+ }
+
+ PX_FORCE_INLINE void markActive(NodeIndex index)
+ {
+ Node& node = mNodes[index.index()];
+ PX_ASSERT(!node.isKinematic());
+ PX_ASSERT(mActiveNodeIndex[index.index()] == IG_INVALID_NODE);
+ mActiveNodeIndex[index.index()] = mActiveNodes[node.mType].size();
+ mActiveNodes[node.mType].pushBack(index);
+ }
+
+ PX_FORCE_INLINE void markInactive(NodeIndex index)
+ {
+ Node& node = mNodes[index.index()];
+
+ PX_ASSERT(!node.isKinematic());
+ PX_ASSERT(mActiveNodeIndex[index.index()] != IG_INVALID_NODE);
+
+ Ps::Array<NodeIndex>& activeNodes = mActiveNodes[node.mType];
+
+ PX_ASSERT(activeNodes[mActiveNodeIndex[index.index()]].index() == index.index());
+ const PxU32 initialActiveNodeCount = mInitialActiveNodeCount[node.mType];
+
+ if(mActiveNodeIndex[index.index()] < initialActiveNodeCount)
+ {
+ //It's in the initial active node set. We retain a list of active nodes, where the existing active nodes
+ //are at the beginning of the array and the newly activated nodes are at the end of the array...
+ //The solution is to move the node to the end of the initial active node list in this case
+ PxU32 activeNodeIndex = mActiveNodeIndex[index.index()];
+ NodeIndex replaceIndex = activeNodes[initialActiveNodeCount-1];
+ PX_ASSERT(mActiveNodeIndex[replaceIndex.index()] == initialActiveNodeCount-1);
+ mActiveNodeIndex[index.index()] = mActiveNodeIndex[replaceIndex.index()];
+ mActiveNodeIndex[replaceIndex.index()] = activeNodeIndex;
+ activeNodes[activeNodeIndex] = replaceIndex;
+ activeNodes[mActiveNodeIndex[index.index()]] = index;
+ mInitialActiveNodeCount[node.mType]--;
+ }
+
+ PX_ASSERT(!node.isKinematic());
+ PX_ASSERT(mActiveNodeIndex[index.index()] != IG_INVALID_NODE);
+ PX_ASSERT(activeNodes[mActiveNodeIndex[index.index()]].index() == index.index());
+
+ NodeIndex replaceIndex = activeNodes.back();
+ PX_ASSERT(mActiveNodeIndex[replaceIndex.index()] == activeNodes.size()-1);
+ mActiveNodeIndex[replaceIndex.index()] = mActiveNodeIndex[index.index()];
+ activeNodes[mActiveNodeIndex[index.index()]] = replaceIndex;
+ activeNodes.forceSize_Unsafe(activeNodes.size()-1);
+ mActiveNodeIndex[index.index()] = IG_INVALID_NODE;
+ }
+
+ PX_FORCE_INLINE void markEdgeActive(EdgeIndex index)
+ {
+ Edge& edge = mEdges[index];
+
+ PX_ASSERT((edge.mEdgeState & Edge::eACTIVATING) == 0);
+
+ edge.mEdgeState |= Edge::eACTIVATING;
+
+ mActivatedEdges[edge.mEdgeType].pushBack(index);
+
+ mActiveEdgeCount[edge.mEdgeType]++;
+
+ //Set the active bit...
+ if(edge.mEdgeType == Edge::eCONTACT_MANAGER)
+ mActiveContactEdges.set(index);
+
+ NodeIndex nodeIndex1 = mEdgeNodeIndices[2 * index];
+ NodeIndex nodeIndex2 = mEdgeNodeIndices[2 * index + 1];
+
+ if (nodeIndex1.index() != IG_INVALID_NODE && nodeIndex2.index() != IG_INVALID_NODE)
+ {
+ PX_ASSERT((!mNodes[nodeIndex1.index()].isKinematic()) || (!mNodes[nodeIndex2.index()].isKinematic()) || edge.getEdgeType() == IG::Edge::eCONTACT_MANAGER);
+ {
+ Node& node = mNodes[nodeIndex1.index()];
+
+ if(node.mActiveRefCount == 0 && node.isKinematic() && !(node.isActive() || node.isActivating()))
+ {
+ //Add to active kinematic list
+ markKinematicActive(nodeIndex1);
+ }
+ node.mActiveRefCount++;
+ }
+
+ {
+ Node& node = mNodes[nodeIndex2.index()];
+ if(node.mActiveRefCount == 0 && node.isKinematic() && !(node.isActive() || node.isActivating()))
+ {
+ //Add to active kinematic list
+ markKinematicActive(nodeIndex2);
+ }
+ node.mActiveRefCount++;
+ }
+ }
+
+ }
+
+ void removeEdgeFromActivatingList(EdgeIndex index);
+
+ PX_FORCE_INLINE void removeEdgeFromIsland(Island& island, EdgeIndex edgeIndex)
+ {
+ Edge& edge = mEdges[edgeIndex];
+ if(edge.mNextIslandEdge != IG_INVALID_EDGE)
+ {
+ PX_ASSERT(mEdges[edge.mNextIslandEdge].mPrevIslandEdge == edgeIndex);
+ mEdges[edge.mNextIslandEdge].mPrevIslandEdge = edge.mPrevIslandEdge;
+ }
+ else
+ {
+ PX_ASSERT(island.mLastEdge[edge.mEdgeType] == edgeIndex);
+ island.mLastEdge[edge.mEdgeType] = edge.mPrevIslandEdge;
+ }
+
+ if(edge.mPrevIslandEdge != IG_INVALID_EDGE)
+ {
+ PX_ASSERT(mEdges[edge.mPrevIslandEdge].mNextIslandEdge == edgeIndex);
+ mEdges[edge.mPrevIslandEdge].mNextIslandEdge = edge.mNextIslandEdge;
+ }
+ else
+ {
+ PX_ASSERT(island.mFirstEdge[edge.mEdgeType] == edgeIndex);
+ island.mFirstEdge[edge.mEdgeType] = edge.mNextIslandEdge;
+ }
+
+ island.mEdgeCount[edge.mEdgeType]--;
+ edge.mNextIslandEdge = edge.mPrevIslandEdge = IG_INVALID_EDGE;
+ }
+
+ PX_FORCE_INLINE void addEdgeToIsland(Island& island, EdgeIndex edgeIndex)
+ {
+ Edge& edge = mEdges[edgeIndex];
+ PX_ASSERT(edge.mNextIslandEdge == IG_INVALID_EDGE && edge.mPrevIslandEdge == IG_INVALID_EDGE);
+
+ if(island.mLastEdge[edge.mEdgeType] != IG_INVALID_EDGE)
+ {
+ PX_ASSERT(mEdges[island.mLastEdge[edge.mEdgeType]].mNextIslandEdge == IG_INVALID_EDGE);
+ mEdges[island.mLastEdge[edge.mEdgeType]].mNextIslandEdge = edgeIndex;
+ }
+ else
+ {
+ PX_ASSERT(island.mFirstEdge[edge.mEdgeType] == IG_INVALID_EDGE);
+ island.mFirstEdge[edge.mEdgeType] = edgeIndex;
+ }
+
+ edge.mPrevIslandEdge = island.mLastEdge[edge.mEdgeType];
+ island.mLastEdge[edge.mEdgeType] = edgeIndex;
+ island.mEdgeCount[edge.mEdgeType]++;
+ }
+
+ PX_FORCE_INLINE void removeNodeFromIsland(Island& island, NodeIndex nodeIndex)
+ {
+ Node& node = mNodes[nodeIndex.index()];
+ if(node.mNextNode.isValid())
+ {
+ PX_ASSERT(mNodes[node.mNextNode.index()].mPrevNode.index() == nodeIndex.index());
+ mNodes[node.mNextNode.index()].mPrevNode = node.mPrevNode;
+ }
+ else
+ {
+ PX_ASSERT(island.mLastNode.index() == nodeIndex.index());
+ island.mLastNode = node.mPrevNode;
+ }
+
+ if(node.mPrevNode.isValid())
+ {
+ PX_ASSERT(mNodes[node.mPrevNode.index()].mNextNode.index() == nodeIndex.index());
+ mNodes[node.mPrevNode.index()].mNextNode = node.mNextNode;
+ }
+ else
+ {
+ PX_ASSERT(island.mRootNode.index() == nodeIndex.index());
+ island.mRootNode = node.mNextNode;
+ }
+
+ island.mSize[node.mType]--;
+
+ node.mNextNode = NodeIndex(); node.mPrevNode = NodeIndex();
+ }
+
+ //void setEdgeConnectedInternal(EdgeIndex edgeIndex);
+
+ //void setEdgeDisconnectedInternal(EdgeIndex edgeIndex);
+
+ friend class SimpleIslandManager;
+ friend class ThirdPassTask;
+
+};
+
+
+}
+
+
+struct PartitionIndexData
+{
+ PxU16 mPartitionIndex; //! The current partition this edge is in. Used to find the edge efficiently. PxU8 is probably too small (256 partitions max) but PxU16 should be more than enough
+ PxU8 mPatchIndex; //! The patch index for this partition edge. There may be multiple entries for a given edge if there are multiple patches.
+ PxU8 mType; //! The type of constraint this is
+ PxU32 mPartitionEntryIndex; //! index of partition edges for this partition
+};
+
+struct PartitionNodeData
+{
+ PxU32 mNodeIndex0;
+ PxU32 mNodeIndex1;
+ PxU32 mNextIndex0;
+ PxU32 mNextIndex1;
+};
+
+
+#define INVALID_PARTITION_INDEX 0xFFFF
+
+struct PartitionEdge
+{
+ IG::EdgeIndex mEdgeIndex; //! The edge index into the island manager. Used to identify the contact manager/constraint
+ IG::NodeIndex mNode0; //! The node index for node 0. Can be obtained from the edge index alternatively
+ IG::NodeIndex mNode1; //! The node idnex for node 1. Can be obtained from the edge index alternatively
+ bool mInfiniteMass0; //! Whether body 0 is kinematic
+ bool mInfiniteMass1; //! Whether body 1 is kinematic
+
+ PartitionEdge* mNextPatch; //! for the contact manager has more than 1 patch, we have next patch's edge and previous patch's edge to connect to this edge
+
+ PxU32 mUniqueIndex; //! a unique ID for this edge
+
+ PartitionEdge() : mEdgeIndex(IG_INVALID_EDGE), mInfiniteMass0(false),
+ mInfiniteMass1(false), mNextPatch(NULL)
+ {
+ }
+};
+
+}
+
+#endif
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsKernelWrangler.h b/PhysX_3.4/Source/LowLevel/software/include/PxsKernelWrangler.h
new file mode 100644
index 00000000..494ab4f7
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsKernelWrangler.h
@@ -0,0 +1,50 @@
+// 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 PXS_KERNEL_WRANGLER_H
+#define PXS_KERNEL_WRANGLER_H
+
+#include "DyGpuAPI.h"
+#include "foundation/PxSimpleTypes.h"
+
+namespace physx
+{
+ class KernelWrangler;
+ class PxGpuDispatcher;
+ class PxErrorCallback;
+
+ class PxsKernelWranglerManager
+ {
+ public:
+ virtual ~PxsKernelWranglerManager(){}
+ virtual KernelWrangler* getKernelWrangler() = 0;
+ };
+}
+#endif \ No newline at end of file
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsMaterialCombiner.h b/PhysX_3.4/Source/LowLevel/software/include/PxsMaterialCombiner.h
new file mode 100644
index 00000000..4f6a3dfc
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsMaterialCombiner.h
@@ -0,0 +1,143 @@
+// 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 PXS_MATERIALCOMBINER_H
+#define PXS_MATERIALCOMBINER_H
+
+#include "PxsMaterialCore.h"
+
+namespace physx
+{
+
+ class PxsMaterialCombiner
+ {
+ public:
+
+ class PxsCombinedMaterial
+ {
+ public:
+ PxReal staFriction;
+ PxReal dynFriction;
+ PxU32 flags; //PxMaterialFlag::eDISABLE_FRICTION, PxMaterialFlag::eDISABLE_STRONG_FRICTION.
+ };
+
+ static PxReal combineRestitution(const PxsMaterialData& material0, const PxsMaterialData& material1);
+
+ PxsMaterialCombiner(PxReal staticFrictionScaling, PxReal dynamicFrictionScaling);
+
+ PxsCombinedMaterial combineIsotropicFriction(const PxsMaterialData& material0, const PxsMaterialData& material1);
+
+ //ML:: move this function to header file to avoid LHS in Xbox
+ PX_FORCE_INLINE void combineIsotropicFriction(const PxsMaterialData& mat0, const PxsMaterialData& mat1, PxReal& dynamicFriction, PxReal& staticFriction, PxU32& flags)
+ {
+
+ const PxU32 combineFlags= (mat0.flags | mat1.flags); //& (PxMaterialFlag::eDISABLE_STRONG_FRICTION|PxMaterialFlag::eDISABLE_FRICTION); //eventually set DisStrongFric flag, lower all others.
+
+ if (!(combineFlags & PxMaterialFlag::eDISABLE_FRICTION))
+ {
+ const PxI32 fictionCombineMode = PxMax(mat0.getFrictionCombineMode(), mat1.getFrictionCombineMode());
+ PxReal dynFriction = 0.f;
+ PxReal staFriction = 0.f;
+
+
+ switch (fictionCombineMode)
+ {
+ case PxCombineMode::eAVERAGE:
+ dynFriction = 0.5f * (mat0.dynamicFriction + mat1.dynamicFriction);
+ staFriction = 0.5f * (mat0.staticFriction + mat1.staticFriction);
+ break;
+ case PxCombineMode::eMIN:
+ dynFriction = PxMin(mat0.dynamicFriction, mat1.dynamicFriction);
+ staFriction = PxMin(mat0.staticFriction, mat1.staticFriction);
+ break;
+ case PxCombineMode::eMULTIPLY:
+ dynFriction = (mat0.dynamicFriction * mat1.dynamicFriction);
+ staFriction = (mat0.staticFriction * mat1.staticFriction);
+ break;
+ case PxCombineMode::eMAX:
+ dynFriction = PxMax(mat0.dynamicFriction, mat1.dynamicFriction);
+ staFriction = PxMax(mat0.staticFriction, mat1.staticFriction);
+ break;
+ }
+
+ dynFriction*=mDynamicFrictionScaling;
+ staFriction*=mStaticFrictionScaling;
+ //isotropic case
+ const PxReal fDynFriction = PxMax(dynFriction, 0.f);
+
+ const PxReal fStaFriction = physx::intrinsics::fsel(staFriction - fDynFriction, staFriction*mStaticFrictionScaling, fDynFriction);
+ /*dest.dynFriction = fDynFriction;
+ dest.staFriction = fStaFriction;*/
+
+ dynamicFriction = fDynFriction;
+ staticFriction = fStaFriction;
+ flags = combineFlags;
+ }
+ else
+ {
+ /* dest.flags |= PxMaterialFlag::eDISABLE_STRONG_FRICTION;
+ dest.staFriction = 0.0f;
+ dest.dynFriction = 0.0f;*/
+ flags = (combineFlags | PxMaterialFlag::eDISABLE_STRONG_FRICTION);
+ dynamicFriction = 0.f;
+ staticFriction = 0.f;
+ }
+
+ }
+
+
+ //private:
+ protected:
+ static PX_FORCE_INLINE PxReal combineScalars(PxReal a, PxReal b, PxI32 nxCombineMode)
+ {
+ switch (nxCombineMode)
+ {
+ case PxCombineMode::eAVERAGE:
+ return 0.5f * (a + b);
+ case PxCombineMode::eMIN:
+ return PxMin(a,b);
+ case PxCombineMode::eMULTIPLY:
+ return a * b;
+ case PxCombineMode::eMAX:
+ return PxMax(a,b);
+ default:
+ /* Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__,
+ "Sc::MaterialCombiner::combineScalars(): unknown combine mode");*/
+ return PxReal(0);
+ }
+ }
+
+ PxReal mStaticFrictionScaling, mDynamicFrictionScaling;
+
+ };
+
+}
+
+#endif
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsMemoryManager.h b/PhysX_3.4/Source/LowLevel/software/include/PxsMemoryManager.h
new file mode 100644
index 00000000..1f5193dd
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsMemoryManager.h
@@ -0,0 +1,62 @@
+// 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 PXS_MEMORY_MANAGER_H
+#define PXS_MEMORY_MANAGER_H
+
+#include "foundation/PxPreprocessor.h"
+#include "foundation/PxSimpleTypes.h"
+#include "DyGpuAPI.h"
+#include "CmPhysXCommon.h"
+
+namespace physx
+{
+ namespace shdfnd
+ {
+ class VirtualAllocatorCallback;
+ }
+
+ class PxGpuDispatcher;
+
+ class PxsMemoryManager
+ {
+ public:
+ virtual ~PxsMemoryManager(){}
+ virtual Ps::VirtualAllocatorCallback* createHostMemoryAllocator(const PxU32 gpuComputeVersion = 0) = 0;
+ virtual Ps::VirtualAllocatorCallback* createDeviceMemoryAllocator(const PxU32 gpuComputeVersion = 0) = 0;
+
+ virtual void destroyMemoryAllocator() = 0;
+
+ };
+
+ PxsMemoryManager* createMemoryManager();
+}
+
+#endif
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsNphaseImplementationContext.h b/PhysX_3.4/Source/LowLevel/software/include/PxsNphaseImplementationContext.h
new file mode 100644
index 00000000..e6d9b8e9
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsNphaseImplementationContext.h
@@ -0,0 +1,142 @@
+// 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 PXS_NPHASE_IMPLEMENTATION_CONTEXT_H
+#define PXS_NPHASE_IMPLEMENTATION_CONTEXT_H
+
+#include "PxvNphaseImplementationContext.h"
+#include "PxsContactManagerState.h"
+#include "PxcNpCache.h"
+
+namespace physx
+{
+
+struct PxsContactManagers : PxsContactManagerBase
+{
+ Ps::Array<PxsContactManagerOutput> mOutputContactManagers;
+ Ps::Array<PxsContactManager*> mContactManagerMapping;
+ Ps::Array<Gu::Cache> mCaches;
+
+
+ PxsContactManagers(const PxU32 bucketId) : PxsContactManagerBase(bucketId),
+ mOutputContactManagers(PX_DEBUG_EXP("mOutputContactManagers")),
+ mContactManagerMapping(PX_DEBUG_EXP("mContactManagerMapping")),
+ mCaches(PX_DEBUG_EXP("mCaches"))
+ {
+ }
+
+ void clear()
+ {
+ mOutputContactManagers.forceSize_Unsafe(0);
+ mContactManagerMapping.forceSize_Unsafe(0);
+ mCaches.forceSize_Unsafe(0);
+
+ }
+private:
+ PX_NOCOPY(PxsContactManagers)
+};
+
+
+class PxsNphaseImplementationContext: public PxvNphaseImplementationContextUsableAsFallback
+{
+public:
+ static PxsNphaseImplementationContext* create(PxsContext& context, IG::IslandSim* islandSim);
+
+ PxsNphaseImplementationContext(PxsContext& context, IG::IslandSim* islandSim, PxU32 index = 0): PxvNphaseImplementationContextUsableAsFallback(context), mNarrowPhasePairs(index), mNewNarrowPhasePairs(index),
+ mModifyCallback(NULL), mIslandSim(islandSim) {}
+ virtual void destroy();
+ virtual void updateContactManager(PxReal dt, bool hasBoundsArrayChanged, bool hasContactDistanceChanged, PxBaseTask* continuation, PxBaseTask* firstPassContinuation);
+ virtual void secondPassUpdateContactManager(PxReal dt, PxBaseTask* continuation);
+
+ virtual void registerContactManager(PxsContactManager* cm, PxI32 touching, PxU32 numPatches);
+ virtual void registerContactManagers(PxsContactManager** cm, PxU32 nbContactManagers, PxU32 maxContactManagerId);
+ virtual void unregisterContactManager(PxsContactManager* cm);
+ virtual void unregisterContactManagerFallback(PxsContactManager* cm, PxsContactManagerOutput* cmOutputs);
+
+
+ virtual void refreshContactManager(PxsContactManager* cm);
+ virtual void refreshContactManagerFallback(PxsContactManager* cm, PxsContactManagerOutput* cmOutputs);
+
+ virtual void registerShape(const PxsShapeCore& shapeCore);
+
+ virtual void updateShapeMaterial(const PxsShapeCore& shapeCore);
+ virtual void updateShapeContactOffset(const PxsShapeCore& shapeCore);
+
+ virtual void unregisterShape(const PxsShapeCore& shapeCore);
+
+ virtual void registerMaterial(const PxsMaterialCore& materialCore);
+ virtual void updateMaterial(const PxsMaterialCore& materialCore);
+ virtual void unregisterMaterial(const PxsMaterialCore& materialCore);
+
+ virtual void appendContactManagers();
+ virtual void appendContactManagersFallback(PxsContactManagerOutput* cmOutputs);
+
+ virtual void removeContactManagersFallback(PxsContactManagerOutput* cmOutputs);
+
+ virtual void setContactModifyCallback(PxContactModifyCallback* callback) { mModifyCallback = callback; }
+
+ virtual PxsContactManagerOutputIterator getContactManagerOutputs();
+
+ virtual PxsContactManagerOutput& getNewContactManagerOutput(PxU32 npIndex);
+
+ virtual PxsContactManagerOutput* getGPUContactManagerOutputBase() { return NULL; }
+
+ virtual void acquireContext(){}
+ virtual void releaseContext(){}
+ virtual void preallocateNewBuffers(PxU32 /*nbNewPairs*/, PxU32 /*maxIndex*/) { /*TODO - implement if it's useful to do so*/}
+
+ void processContactManager(PxReal dt, PxsContactManagerOutput* cmOutputs, PxBaseTask* continuation);
+ void processContactManagerSecondPass(PxReal dt, PxBaseTask* continuation);
+ void fetchUpdateContactManager() {}
+
+
+
+ void startNarrowPhaseTasks() {}
+
+
+
+ Ps::Array<PxU32> mRemovedContactManagers;
+ PxsContactManagers mNarrowPhasePairs;
+ PxsContactManagers mNewNarrowPhasePairs;
+
+ PxContactModifyCallback* mModifyCallback;
+
+ IG::IslandSim* mIslandSim;
+
+private:
+
+ void unregisterContactManagerInternal(PxU32 npIndex, PxsContactManagers& managers, PxsContactManagerOutput* cmOutputs);
+
+ PX_NOCOPY(PxsNphaseImplementationContext)
+};
+
+}
+
+#endif
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsRigidBody.h b/PhysX_3.4/Source/LowLevel/software/include/PxsRigidBody.h
new file mode 100644
index 00000000..0bbfc8ec
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsRigidBody.h
@@ -0,0 +1,168 @@
+// 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 PXS_BODYATOM_H
+#define PXS_BODYATOM_H
+
+#include "PxcRigidBody.h"
+#include "PxvDynamics.h"
+
+namespace physx
+{
+
+class PxsRigidBody : public PxcRigidBody
+{
+ public:
+ PX_FORCE_INLINE PxsRigidBody(PxsBodyCore* core) : PxcRigidBody(core) { }
+ PX_FORCE_INLINE ~PxsRigidBody() {}
+
+ PX_FORCE_INLINE const PxTransform& getPose() const { PX_ASSERT(mCore->body2World.isSane()); return mCore->body2World; }
+
+ //PX_FORCE_INLINE const Cm::SpatialVector& getAccelerationV() const { return mAcceleration; }
+ //PX_FORCE_INLINE void setAccelerationV(const Cm::SpatialVector& v) { mAcceleration = v; }
+
+ PX_FORCE_INLINE const PxVec3& getLinearVelocity() const { PX_ASSERT(mCore->linearVelocity.isFinite()); return mCore->linearVelocity; }
+ PX_FORCE_INLINE const PxVec3& getAngularVelocity() const { PX_ASSERT(mCore->angularVelocity.isFinite()); return mCore->angularVelocity; }
+
+ PX_FORCE_INLINE void setVelocity(const PxVec3& linear,
+ const PxVec3& angular) { PX_ASSERT(linear.isFinite()); PX_ASSERT(angular.isFinite());
+ mCore->linearVelocity = linear;
+ mCore->angularVelocity = angular; }
+ PX_FORCE_INLINE void setLinearVelocity(const PxVec3& linear) { PX_ASSERT(linear.isFinite()); mCore->linearVelocity = linear; }
+ PX_FORCE_INLINE void setAngularVelocity(const PxVec3& angular) { PX_ASSERT(angular.isFinite()); mCore->angularVelocity = angular; }
+
+ PX_FORCE_INLINE void constrainLinearVelocity();
+ PX_FORCE_INLINE void constrainAngularVelocity();
+
+ PX_FORCE_INLINE PxU32 getIterationCounts() { return mCore->solverIterationCounts; }
+
+ PX_FORCE_INLINE PxReal getReportThreshold() const { return mCore->contactReportThreshold; }
+
+ // AP newccd todo: merge into get both velocities, compute inverse transform once, precompute mLastTransform.getInverse()
+ PX_FORCE_INLINE PxVec3 getLinearMotionVelocity(PxReal invDt) const {
+ // delta(t0(x))=t1(x)
+ // delta(t0(t0`(x)))=t1(t0`(x))
+ // delta(x)=t1(t0`(x))
+ PxVec3 deltaP = mCore->body2World.p - getLastCCDTransform().p;
+ return deltaP * invDt;
+ }
+ PX_FORCE_INLINE PxVec3 getAngularMotionVelocity(PxReal invDt) const {
+ PxQuat deltaQ = mCore->body2World.q * getLastCCDTransform().q.getConjugate();
+ PxVec3 axis;
+ PxReal angle;
+ deltaQ.toRadiansAndUnitAxis(angle, axis);
+ return axis * angle * invDt;
+ }
+ PX_FORCE_INLINE PxVec3 getLinearMotionVelocity(PxReal dt, const PxsBodyCore* PX_RESTRICT bodyCore) const {
+ // delta(t0(x))=t1(x)
+ // delta(t0(t0`(x)))=t1(t0`(x))
+ // delta(x)=t1(t0`(x))
+ PxVec3 deltaP = bodyCore->body2World.p - getLastCCDTransform().p;
+ return deltaP * 1.0f / dt;
+ }
+ PX_FORCE_INLINE PxVec3 getAngularMotionVelocity(PxReal dt, const PxsBodyCore* PX_RESTRICT bodyCore) const {
+ PxQuat deltaQ = bodyCore->body2World.q * getLastCCDTransform().q.getConjugate();
+ PxVec3 axis;
+ PxReal angle;
+ deltaQ.toRadiansAndUnitAxis(angle, axis);
+ return axis * angle * 1.0f/dt;
+ }
+
+ PX_FORCE_INLINE PxTransform getLastCCDTransform() const { return mLastTransform; }
+ PX_FORCE_INLINE void saveLastCCDTransform() { mLastTransform = mCore->body2World; }
+
+ PX_FORCE_INLINE bool isKinematic() const { return (mCore->inverseMass == 0.0f); }
+
+ PX_FORCE_INLINE void setPose(const PxTransform& pose) { mCore->body2World = pose; }
+ PX_FORCE_INLINE void setPosition(const PxVec3& position) { mCore->body2World.p = position; }
+ PX_FORCE_INLINE PxReal getInvMass() const { return mCore->inverseMass; }
+ PX_FORCE_INLINE PxVec3 getInvInertia() const { return mCore->inverseInertia; }
+ PX_FORCE_INLINE PxReal getMass() const { return 1.0f/mCore->inverseMass; }
+ PX_FORCE_INLINE PxVec3 getInertia() const { return PxVec3(1.0f/mCore->inverseInertia.x,
+ 1.0f/mCore->inverseInertia.y,
+ 1.0f/mCore->inverseInertia.z); }
+ PX_FORCE_INLINE PxsBodyCore& getCore() { return *mCore; }
+ PX_FORCE_INLINE const PxsBodyCore& getCore() const { return *mCore; }
+
+ PX_FORCE_INLINE PxU32 isActivateThisFrame() const { return PxU32(mInternalFlags & eACTIVATE_THIS_FRAME); }
+
+ PX_FORCE_INLINE PxU32 isDeactivateThisFrame() const { return PxU32(mInternalFlags & eDEACTIVATE_THIS_FRAME); }
+
+ PX_FORCE_INLINE PxU32 isFreezeThisFrame() const { return PxU32(mInternalFlags & eFREEZE_THIS_FRAME); }
+
+ PX_FORCE_INLINE PxU32 isUnfreezeThisFrame() const { return PxU32(mInternalFlags & eUNFREEZE_THIS_FRAME); }
+
+ PX_FORCE_INLINE void clearFreezeFlag() { mInternalFlags &= ~eFREEZE_THIS_FRAME; }
+
+ PX_FORCE_INLINE void clearUnfreezeFlag() { mInternalFlags &= ~eUNFREEZE_THIS_FRAME; }
+
+ PX_FORCE_INLINE void clearAllFrameFlags() { mInternalFlags &= (eFROZEN | eDISABLE_GRAVITY); }
+
+ void advanceToToi(PxReal toi, PxReal dt, bool clip);
+ void advancePrevPoseToToi(PxReal toi);
+ PxTransform getAdvancedTransform(PxReal toi) const;
+ Cm::SpatialVector getPreSolverVelocities() const;
+
+
+};
+
+void PxsRigidBody::constrainLinearVelocity()
+{
+ const PxU32 lockFlags = mCore->lockFlags;
+
+ if (lockFlags)
+ {
+ if (lockFlags & PxRigidDynamicLockFlag::eLOCK_LINEAR_X)
+ mCore->linearVelocity.x = 0.f;
+ if (lockFlags & PxRigidDynamicLockFlag::eLOCK_LINEAR_Y)
+ mCore->linearVelocity.y = 0.f;
+ if (lockFlags & PxRigidDynamicLockFlag::eLOCK_LINEAR_Z)
+ mCore->linearVelocity.z = 0.f;
+ }
+}
+
+void PxsRigidBody::constrainAngularVelocity()
+{
+ const PxU32 lockFlags = mCore->lockFlags;
+
+ if (lockFlags)
+ {
+ if (lockFlags & PxRigidDynamicLockFlag::eLOCK_ANGULAR_X)
+ mCore->angularVelocity.x = 0.f;
+ if (lockFlags & PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y)
+ mCore->angularVelocity.y = 0.f;
+ if (lockFlags & PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z)
+ mCore->angularVelocity.z = 0.f;
+ }
+}
+
+}
+
+#endif
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsShapeSim.h b/PhysX_3.4/Source/LowLevel/software/include/PxsShapeSim.h
new file mode 100644
index 00000000..0bf63f2e
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsShapeSim.h
@@ -0,0 +1,52 @@
+// 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 PXS_SHAPESIM_H
+#define PXS_SHAPESIM_H
+
+#include "PxsBodySim.h"
+
+namespace physx
+{
+
+//PxsBodySim is 12 or 16 bytes
+struct PxsShapeSim// : public PxsBodySim
+{
+ PxsShapeCore* mShapeCore; // 4 or 8
+ PxU32 mBodySimIndex; // 8 or 12
+ PxU32 mElementIndex; // 12 or 16 transform cache and bound index
+ PxU32 mShapeIndex; // 16 or 20
+#if PX_P64_FAMILY
+ PxU32 mPad[3];
+#endif
+};
+
+}//physx
+
+#endif
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsSimpleIslandManager.h b/PhysX_3.4/Source/LowLevel/software/include/PxsSimpleIslandManager.h
new file mode 100644
index 00000000..50291b8f
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsSimpleIslandManager.h
@@ -0,0 +1,207 @@
+// 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 PXS_SIMPLE_ISLAND_GEN_H
+#define PXS_SIMPLE_ISLAND_GEN_H
+
+#include "PxsIslandSim.h"
+#include "CmTask.h"
+
+namespace physx
+{
+
+namespace Sc
+{
+ class Interaction;
+}
+namespace IG
+{
+
+ class SimpleIslandManager;
+
+class ThirdPassTask : public Cm::Task
+{
+ SimpleIslandManager& mIslandManager;
+ IslandSim& mIslandSim;
+
+public:
+
+ ThirdPassTask(SimpleIslandManager& islandManager, IslandSim& islandSim) : mIslandManager(islandManager), mIslandSim(islandSim)
+ {
+ }
+
+ virtual void runInternal();
+
+ virtual const char* getName() const
+ {
+ return "ThirdPassIslandGenTask";
+ }
+
+private:
+ PX_NOCOPY(ThirdPassTask)
+};
+
+class PostThirdPassTask : public Cm::Task
+{
+ SimpleIslandManager& mIslandManager;
+
+public:
+
+ PostThirdPassTask(SimpleIslandManager& islandManager) : mIslandManager(islandManager)
+ {
+ }
+
+ virtual void runInternal();
+
+ virtual const char* getName() const
+ {
+ return "PostThirdPassTask";
+ }
+private:
+ PX_NOCOPY(PostThirdPassTask)
+};
+
+class SimpleIslandManager
+{
+
+ HandleManager<PxU32> mNodeHandles; //! Handle manager for nodes
+ HandleManager<EdgeIndex> mEdgeHandles; //! Handle manager for edges
+
+ //An array of destroyed nodes
+ Ps::Array<NodeIndex> mDestroyedNodes;
+ Ps::Array<Sc::Interaction*> mInteractions;
+
+
+ //Edges destroyed this frame
+ Ps::Array<EdgeIndex> mDestroyedEdges;
+ Ps::Array<PartitionEdge*> mFirstPartitionEdges;
+ Ps::Array<PartitionEdge*> mDestroyedPartitionEdges;
+ //KS - stores node indices for a given edge. Node index 0 is at 2* edgeId and NodeIndex1 is at 2*edgeId + 1
+ //can also be used for edgeInstance indexing so there's no need to figure out outboundNode ID either!
+ Ps::Array<NodeIndex> mEdgeNodeIndices;
+
+ Ps::Array<ConstraintOrContactManager> mConstraintOrCm; //! Pointers to either the constraint or Cm for this pair
+
+ Cm::BitMap mConnectedMap;
+
+ IslandSim mIslandManager;
+ IslandSim mSpeculativeIslandManager;
+
+ ThirdPassTask mSpeculativeThirdPassTask;
+ ThirdPassTask mAccurateThirdPassTask;
+
+ PostThirdPassTask mPostThirdPassTask;
+ PxU32 mMaxDirtyNodesPerFrame;
+
+ PxU64 mContextID;
+public:
+
+ SimpleIslandManager(bool useEnhancedDeterminism, PxU64 contextID);
+
+ ~SimpleIslandManager();
+
+ NodeIndex addRigidBody(PxsRigidBody* body, bool isKinematic, bool isActive);
+
+ void removeNode(const NodeIndex index);
+
+ NodeIndex addArticulation(Sc::ArticulationSim* articulation, Dy::Articulation* llArtic, bool isActive);
+
+ EdgeIndex addContactManager(PxsContactManager* manager, NodeIndex nodeHandle1, NodeIndex nodeHandle2, Sc::Interaction* interaction);
+
+ EdgeIndex addConstraint(Dy::Constraint* constraint, NodeIndex nodeHandle1, NodeIndex nodeHandle2, Sc::Interaction* interaction);
+
+ bool isConnected(EdgeIndex edgeIndex) const { return !!mConnectedMap.test(edgeIndex); }
+
+ PX_FORCE_INLINE NodeIndex getEdgeIndex(EdgeInstanceIndex edgeIndex) const { return mEdgeNodeIndices[edgeIndex]; }
+
+ void activateNode(NodeIndex index);
+ void deactivateNode(NodeIndex index);
+ void putNodeToSleep(NodeIndex index);
+
+ void removeConnection(EdgeIndex edgeIndex);
+
+ void firstPassIslandGen();
+ void additionalSpeculativeActivation();
+ void secondPassIslandGen();
+ void thirdPassIslandGen(PxBaseTask* continuation);
+
+ void clearDestroyedEdges();
+
+ void setEdgeConnected(EdgeIndex edgeIndex);
+ void setEdgeDisconnected(EdgeIndex edgeIndex);
+
+ bool getIsEdgeConnected(EdgeIndex edgeIndex);
+
+ void setEdgeRigidCM(const EdgeIndex edgeIndex, PxsContactManager* cm);
+
+ void clearEdgeRigidCM(const EdgeIndex edgeIndex);
+
+ void setKinematic(IG::NodeIndex nodeIndex);
+
+ void setDynamic(IG::NodeIndex nodeIndex);
+
+ const IslandSim& getSpeculativeIslandSim() const { return mSpeculativeIslandManager; }
+ const IslandSim& getAccurateIslandSim() const { return mIslandManager; }
+
+ IslandSim& getAccurateIslandSim() { return mIslandManager; }
+
+ PX_FORCE_INLINE PxU32 getNbEdgeHandles() const { return mEdgeHandles.getTotalHandles(); }
+
+ PX_FORCE_INLINE PxU32 getNbNodeHandles() const { return mNodeHandles.getTotalHandles(); }
+
+ void deactivateEdge(const EdgeIndex edge);
+
+ PX_FORCE_INLINE PxsContactManager* getContactManager(IG::EdgeIndex edgeId) const { return mConstraintOrCm[edgeId].mCm; }
+ PX_FORCE_INLINE PxsContactManager* getContactManagerUnsafe(IG::EdgeIndex edgeId) const { return mConstraintOrCm[edgeId].mCm; }
+ PX_FORCE_INLINE Dy::Constraint* getConstraint(IG::EdgeIndex edgeId) const { return mConstraintOrCm[edgeId].mConstraint; }
+ PX_FORCE_INLINE Dy::Constraint* getConstraintUnsafe(IG::EdgeIndex edgeId) const { return mConstraintOrCm[edgeId].mConstraint; }
+
+ PX_FORCE_INLINE Sc::Interaction* getInteraction(IG::EdgeIndex edgeId) const { return mInteractions[edgeId]; }
+
+ PX_FORCE_INLINE PxU64 getContextId() const { return mContextID; }
+
+ bool checkInternalConsistency();
+
+
+private:
+
+ friend class ThirdPassTask;
+ friend class PostThirdPassTask;
+
+ bool validateDeactivations() const;
+
+ PX_NOCOPY(SimpleIslandManager)
+};
+
+
+
+}
+}
+
+#endif
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsSimulationController.h b/PhysX_3.4/Source/LowLevel/software/include/PxsSimulationController.h
new file mode 100644
index 00000000..8d6c2612
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsSimulationController.h
@@ -0,0 +1,135 @@
+// 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 PXS_SIMULATION_CONTROLLER_H
+#define PXS_SIMULATION_CONTROLLER_H
+
+#include "foundation/PxSimpleTypes.h"
+#include "foundation/PxPreprocessor.h"
+#include "foundation/PxTransform.h"
+#include "DyGpuAPI.h"
+#include "CmBitMap.h"
+#include "PsArray.h"
+
+
+namespace physx
+{
+ namespace Dy
+ {
+ class Context;
+ struct Constraint;
+ }
+
+ namespace Cm
+ {
+ class EventProfiler;
+ }
+
+ namespace Bp
+ {
+ class BoundsArray;
+ class BroadPhase;
+ }
+
+ namespace IG
+ {
+ class SimpleIslandManager;
+ class IslandSim;
+ }
+
+ class PxGpuDispatcher;
+ class PxsTransformCache;
+ class PxvNphaseImplementationContext;
+ class PxBaseTask;
+
+ struct PxsBodySim;
+ struct PxsShapeSim;
+ class PxsRigidBody;
+ class PxsKernelWranglerManager;
+ class PxsHeapMemoryAllocatorManager;
+
+ template<typename T> class PxgIterator;
+ struct PxgSolverConstraintManagerConstants;
+
+
+ class PxsSimulationControllerCallback
+ {
+ public:
+ virtual void updateScBodyAndShapeSim(PxBaseTask* continuation) = 0;
+ virtual PxU32 getNbCcdBodies() = 0;
+
+ virtual ~PxsSimulationControllerCallback() {}
+ };
+
+
+ class PxsSimulationController
+ {
+ public:
+ PxsSimulationController(PxsSimulationControllerCallback* callback): mCallback(callback){}
+ virtual ~PxsSimulationController(){}
+
+ virtual void addJoint(const PxU32 edgeIndex, Dy::Constraint* constraint, IG::IslandSim& islandSim, Ps::Array<PxU32, Ps::VirtualAllocator>& jointIndices,
+ Ps::Array<PxgSolverConstraintManagerConstants, Ps::VirtualAllocator>& managerIter, PxU32 uniqueId) = 0;
+ virtual void removeJoint(const PxU32 edgeIndex, Dy::Constraint* constraint, Ps::Array<PxU32, Ps::VirtualAllocator>& jointIndices, IG::IslandSim& islandSim) = 0;
+ virtual void addShape(PxsShapeSim* shapeSim, const PxU32 index) = 0;
+ virtual void removeShape(const PxU32 index) = 0;
+ virtual void addDynamic(PxsRigidBody* rigidBody, const PxU32 nodeIndex) = 0;
+ virtual void addDynamics(PxsRigidBody** rigidBody, const PxU32* nodeIndex, PxU32 nbToProcess) = 0;
+ virtual void updateJoint(const PxU32 edgeIndex, Dy::Constraint* constraint) = 0;
+ virtual void updateBodies(PxsRigidBody** rigidBodies, PxU32* nodeIndices, const PxU32 nbBodies) = 0;
+ virtual void updateBody(PxsRigidBody* rigidBodies, const PxU32 nodeIndex) = 0;
+ virtual void updateBodiesAndShapes(PxBaseTask* continuation, bool extrudeHeightfields) = 0;
+ virtual void update(const PxU32 bitMapWordCounts) = 0;
+ virtual void gpuDmabackData(PxsTransformCache& cache, Bp::BoundsArray& boundArray, Cm::BitMapPinned& changedAABBMgrHandles) = 0;
+ virtual void udpateScBodyAndShapeSim(PxsTransformCache& cache, Bp::BoundsArray& boundArray, PxBaseTask* continuation) = 0;
+ virtual PxU32* getActiveBodies() = 0;
+ virtual PxU32* getDeactiveBodies() = 0;
+ virtual PxsBodySim* getBodySims() = 0;
+ virtual PxU32 getNbBodies() = 0;
+
+ virtual PxU32* getUnfrozenShapes() = 0;
+ virtual PxU32* getFrozenShapes() = 0;
+ virtual PxsShapeSim** getShapeSims() = 0;
+ virtual PxU32 getNbFrozenShapes() = 0;
+ virtual PxU32 getNbUnfrozenShapes() = 0;
+
+ virtual void clear() = 0;
+ virtual void setBounds(Bp::BoundsArray* boundArray) = 0;
+ virtual void reserve(const PxU32 nbBodies) = 0;
+
+ protected:
+ PxsSimulationControllerCallback* mCallback;
+
+ };
+
+ PxsSimulationController* createSimulationController(PxsSimulationControllerCallback* callback);
+}
+
+#endif
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxsTransformCache.h b/PhysX_3.4/Source/LowLevel/software/include/PxsTransformCache.h
new file mode 100644
index 00000000..b9d69022
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxsTransformCache.h
@@ -0,0 +1,144 @@
+// 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 PXS_TRANSFORM_CACHE_H
+#define PXS_TRANSFORM_CACHE_H
+
+#include "CmPhysXCommon.h"
+#include "CmIDPool.h"
+#include "CmBitMap.h"
+#include "PsUserAllocated.h"
+#include "PsAllocator.h"
+
+#define PX_DEFAULT_CACHE_SIZE 512
+
+namespace physx
+{
+ struct PxsTransformFlag
+ {
+ enum Flags
+ {
+ eFROZEN = (1 << 0)
+ };
+ };
+
+ struct PX_ALIGN_PREFIX(16) PxsCachedTransform
+ {
+ PxTransform transform;
+ PxU32 flags;
+
+ PX_FORCE_INLINE PxU32 isFrozen() const { return flags & PxsTransformFlag::eFROZEN; }
+ }
+ PX_ALIGN_SUFFIX(16);
+
+
+ class PxsTransformCache : public Ps::UserAllocated
+ {
+ typedef PxU32 RefCountType;
+
+ public:
+ PxsTransformCache(Ps::VirtualAllocatorCallback& allocatorCallback) : mTransformCache(Ps::VirtualAllocator(&allocatorCallback)), mHasAnythingChanged(true)
+ {
+ /*mTransformCache.reserve(PX_DEFAULT_CACHE_SIZE);
+ mTransformCache.forceSize_Unsafe(PX_DEFAULT_CACHE_SIZE);*/
+ mUsedSize = 0;
+ }
+
+ void initEntry(PxU32 index)
+ {
+ PxU32 oldCapacity = mTransformCache.capacity();
+ if (index >= oldCapacity)
+ {
+ PxU32 newCapacity = Ps::nextPowerOfTwo(index);
+ mTransformCache.reserve(newCapacity);
+ mTransformCache.forceSize_Unsafe(newCapacity);
+ }
+ mUsedSize = PxMax(mUsedSize, index + 1u);
+ }
+
+
+ PX_FORCE_INLINE void setTransformCache(const PxTransform& transform, const PxU32 flags, const PxU32 index)
+ {
+ mTransformCache[index].transform = transform;
+ mTransformCache[index].flags = flags;
+ mHasAnythingChanged = true;
+ }
+
+ PX_FORCE_INLINE const PxsCachedTransform& getTransformCache(const PxU32 index) const
+ {
+ return mTransformCache[index];
+ }
+
+
+ PX_FORCE_INLINE PxsCachedTransform& getTransformCache(const PxU32 index)
+ {
+ return mTransformCache[index];
+ }
+
+ PX_FORCE_INLINE void shiftTransforms(const PxVec3& shift)
+ {
+ for (PxU32 i = 0; i < mTransformCache.capacity(); i++)
+ {
+ mTransformCache[i].transform.p += shift;
+ }
+ mHasAnythingChanged = true;
+ }
+
+ PX_FORCE_INLINE PxU32 getTotalSize() const
+ {
+ return mUsedSize;
+ }
+
+ PX_FORCE_INLINE const PxsCachedTransform* getTransforms() const
+ {
+ return mTransformCache.begin();
+ }
+
+ PX_FORCE_INLINE PxsCachedTransform* getTransforms()
+ {
+ return mTransformCache.begin();
+ }
+
+ PX_FORCE_INLINE Ps::Array<PxsCachedTransform, Ps::VirtualAllocator>* getCachedTransformArray()
+ {
+ return &mTransformCache;
+ }
+
+ PX_FORCE_INLINE void resetChangedState() { mHasAnythingChanged = false; }
+ PX_FORCE_INLINE void setChangedState() { mHasAnythingChanged = true; }
+ PX_FORCE_INLINE bool hasChanged() const { return mHasAnythingChanged; }
+
+ private:
+ Ps::Array<PxsCachedTransform, Ps::VirtualAllocator> mTransformCache;
+ PxU32 mUsedSize;
+ bool mHasAnythingChanged;
+ };
+}
+
+#endif
diff --git a/PhysX_3.4/Source/LowLevel/software/include/PxvNphaseImplementationContext.h b/PhysX_3.4/Source/LowLevel/software/include/PxvNphaseImplementationContext.h
new file mode 100644
index 00000000..84eddbca
--- /dev/null
+++ b/PhysX_3.4/Source/LowLevel/software/include/PxvNphaseImplementationContext.h
@@ -0,0 +1,220 @@
+// 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 PXV_NPHASE_IMPLEMENTATION_CONTEXT_H
+#define PXV_NPHASE_IMPLEMENTATION_CONTEXT_H
+
+#include "PxSceneDesc.h"
+#include "PxsContactManagerState.h"
+#include "PsArray.h"
+
+#if PX_SUPPORT_GPU_PHYSX
+#include "Pxg.h"
+#endif
+
+namespace physx
+{
+
+namespace IG
+{
+ class SimpleIslandManager;
+ class IslandSim;
+ typedef PxU32 EdgeIndex;
+}
+
+namespace Dy
+{
+ class Context;
+}
+
+class PxBaseTask;
+class PxsContext;
+struct PxsShapeCore;
+class PxsMaterialCore;
+struct PxgDynamicsMemoryConfig;
+class PxsContactManager;
+struct PxsContactManagerOutput;
+class PxsKernelWranglerManager;
+class PxsHeapMemoryAllocatorManager;
+
+
+struct PxsContactManagerBase
+{
+ static const PxU32 NEW_CONTACT_MANAGER_MASK = 0x80000000;
+ static const PxU32 GPU_NP_OFFSET = 0x4;
+
+ static const PxU32 MaxBucketBits = 3;
+
+ const PxU32 mBucketId;
+
+ PxsContactManagerBase(const PxU32 bucketId) : mBucketId(bucketId)
+ {
+ PX_ASSERT(bucketId < (1<<MaxBucketBits));
+ }
+
+
+ PX_FORCE_INLINE PxU32 computeId(const PxU32 index) const { PX_ASSERT(index < PxU32(1 << (32 - (MaxBucketBits-1)))); return (index << MaxBucketBits) | (mBucketId); }
+ static PX_FORCE_INLINE PxU32 computeIndexFromId(const PxU32 id) { return id >> MaxBucketBits; }
+ static PX_FORCE_INLINE PxU32 computeBucketIndexFromId(const PxU32 id) { return id & ((1<<MaxBucketBits)-1); }
+
+private:
+ PX_NOCOPY(PxsContactManagerBase)
+};
+
+class PxsContactManagerOutputIterator
+{
+ PxU32 mOffsets[1<<PxsContactManagerBase::MaxBucketBits];
+ PxsContactManagerOutput* mOutputs;
+
+public:
+
+ PxsContactManagerOutputIterator() : mOutputs(NULL)
+ {
+ }
+
+ PxsContactManagerOutputIterator(PxU32* offsets, PxU32 nbOffsets, PxsContactManagerOutput* outputs) : mOutputs(outputs)
+ {
+ PX_ASSERT(nbOffsets <= (1<<PxsContactManagerBase::MaxBucketBits));
+
+ for(PxU32 a = 0; a < nbOffsets; ++a)
+ {
+ mOffsets[a] = offsets[a];
+ }
+ }
+
+ PX_FORCE_INLINE PxsContactManagerOutput& getContactManager(PxU32 id)
+ {
+ PX_ASSERT((id & PxsContactManagerBase::NEW_CONTACT_MANAGER_MASK) == 0);
+ PxU32 bucketId = PxsContactManagerBase::computeBucketIndexFromId(id);
+ PxU32 cmOutId = PxsContactManagerBase::computeIndexFromId(id);
+ return mOutputs[mOffsets[bucketId] + cmOutId];
+ }
+
+ PxU32 getIndex(PxU32 id)
+ {
+ PX_ASSERT((id & PxsContactManagerBase::NEW_CONTACT_MANAGER_MASK) == 0);
+ PxU32 bucketId = PxsContactManagerBase::computeBucketIndexFromId(id);
+ PxU32 cmOutId = PxsContactManagerBase::computeIndexFromId(id);
+ return mOffsets[bucketId] + cmOutId;
+ }
+};
+
+
+class PxvNphaseImplementationContext
+{
+ private:
+ PX_NOCOPY(PxvNphaseImplementationContext)
+public:
+
+ PxvNphaseImplementationContext(PxsContext& context): mContext(context) {}
+ virtual ~PxvNphaseImplementationContext() {}
+ virtual void destroy() = 0;
+ virtual void updateContactManager(PxReal dt, bool hasBoundsArrayChanged, bool hasContactDistanceChanged, PxBaseTask* continuation, PxBaseTask* firstPassContinuation) = 0;
+ virtual void secondPassUpdateContactManager(PxReal dt, PxBaseTask* continuation) = 0;
+ virtual void fetchUpdateContactManager() = 0;
+
+ virtual void registerContactManager(PxsContactManager* cm, PxI32 touching, PxU32 patchCount) = 0;
+ virtual void registerContactManagers(PxsContactManager** cm, PxU32 nbContactManagers, PxU32 maxContactManagerId) = 0;
+ virtual void unregisterContactManager(PxsContactManager* cm) = 0;
+ virtual void refreshContactManager(PxsContactManager* cm) = 0;
+
+ virtual void registerShape(const PxsShapeCore& shapeCore) = 0;
+ virtual void unregisterShape(const PxsShapeCore& shapeCore) = 0;
+
+ virtual void registerMaterial(const PxsMaterialCore& materialCore) = 0;
+ virtual void updateMaterial(const PxsMaterialCore& materialCore) = 0;
+ virtual void unregisterMaterial(const PxsMaterialCore& materialCore) = 0;
+
+ virtual void updateShapeMaterial(const PxsShapeCore& shapeCore) = 0;
+
+ virtual PxsContactManagerOutput* getGPUContactManagerOutputBase() = 0;
+
+ virtual void startNarrowPhaseTasks() = 0;
+
+ virtual void appendContactManagers() = 0;
+
+ virtual PxsContactManagerOutput& getNewContactManagerOutput(PxU32 index) = 0;
+
+ virtual PxsContactManagerOutputIterator getContactManagerOutputs() = 0;
+
+ virtual void setContactModifyCallback(PxContactModifyCallback* callback) = 0;
+
+ virtual void acquireContext() = 0;
+ virtual void releaseContext() = 0;
+ virtual void preallocateNewBuffers(PxU32 nbNewPairs, PxU32 maxIndex) = 0;
+
+
+
+
+protected:
+
+ PxsContext& mContext;
+};
+
+class PxvNphaseImplementationFallback
+{
+ private:
+ PX_NOCOPY(PxvNphaseImplementationFallback)
+public:
+
+ PxvNphaseImplementationFallback() {}
+ virtual ~PxvNphaseImplementationFallback() {}
+ virtual void processContactManager(PxReal dt, PxsContactManagerOutput* cmOutputs, PxBaseTask* continuation) = 0;
+ virtual void processContactManagerSecondPass(PxReal dt, PxBaseTask* continuation) = 0;
+
+ virtual void registerContactManager(PxsContactManager* cm, PxI32 touching, PxU32 numPatches) = 0;
+ virtual void unregisterContactManagerFallback(PxsContactManager* cm, PxsContactManagerOutput* cmOutputs) = 0;
+
+ virtual void refreshContactManagerFallback(PxsContactManager* cm, PxsContactManagerOutput* cmOutputs) = 0;
+
+ virtual PxsContactManagerOutput& getNewContactManagerOutput(PxU32 npId) = 0;
+
+ virtual void appendContactManagersFallback(PxsContactManagerOutput* outputs) = 0;
+
+ virtual void setContactModifyCallback(PxContactModifyCallback* callback) = 0;
+
+ virtual void removeContactManagersFallback(PxsContactManagerOutput* cmOutputs) = 0;
+
+};
+
+class PxvNphaseImplementationContextUsableAsFallback: public PxvNphaseImplementationContext, public PxvNphaseImplementationFallback
+{
+ private:
+ PX_NOCOPY(PxvNphaseImplementationContextUsableAsFallback)
+public:
+ PxvNphaseImplementationContextUsableAsFallback(PxsContext& context): PxvNphaseImplementationContext(context) {}
+ virtual ~PxvNphaseImplementationContextUsableAsFallback() {}
+};
+
+PxvNphaseImplementationContextUsableAsFallback* createNphaseImplementationContext(PxsContext& context, IG::IslandSim* islandSim);
+
+}
+
+#endif