340 lines
12 KiB
C++
340 lines
12 KiB
C++
//
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions
|
|
// are met:
|
|
// * Redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer.
|
|
// * Redistributions in binary form must reproduce the above copyright
|
|
// notice, this list of conditions and the following disclaimer in the
|
|
// documentation and/or other materials provided with the distribution.
|
|
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
|
// contributors may be used to endorse or promote products derived
|
|
// from this software without specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
|
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
//
|
|
// Copyright (c) 2008-2019 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 "PxvNphaseImplementationContext.h"
|
|
#include "PxvSimStats.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;
|
|
struct PxvContactManagerTouchEvent;
|
|
|
|
namespace Cm
|
|
{
|
|
class FlushPool;
|
|
}
|
|
|
|
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 PxsContext : public Ps::UserAllocated, public PxcNpContext
|
|
{
|
|
PX_NOCOPY(PxsContext)
|
|
public:
|
|
PxsContext( const PxSceneDesc& desc, PxTaskManager*, Cm::FlushPool&, PxCudaContextManager*, 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 PxCudaContextManager* getCudaContextManager()
|
|
{
|
|
return mCudaContextManager;
|
|
}
|
|
|
|
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;
|
|
|
|
PxCudaContextManager* mCudaContextManager;
|
|
|
|
// 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
|