feat(physics): wire physx sdk into build
This commit is contained in:
469
engine/third_party/physx/source/physxextensions/src/ExtSceneQuerySystem.cpp
vendored
Normal file
469
engine/third_party/physx/source/physxextensions/src/ExtSceneQuerySystem.cpp
vendored
Normal file
@@ -0,0 +1,469 @@
|
||||
// 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-2025 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 "extensions/PxSceneQuerySystemExt.h"
|
||||
#include "extensions/PxShapeExt.h"
|
||||
#include "foundation/PxAlloca.h"
|
||||
#include "foundation/PxHashMap.h"
|
||||
#include "foundation/PxUserAllocated.h"
|
||||
#include "geometry/PxBVH.h"
|
||||
#include "GuActorShapeMap.h"
|
||||
#include "SqQuery.h"
|
||||
#include "SqFactory.h"
|
||||
#include "PxRigidActor.h"
|
||||
#include "PxPruningStructure.h"
|
||||
#include "PxSceneDesc.h" // PT: for PxSceneLimits TODO: remove
|
||||
|
||||
// PT: this file re-implements a scene-queries system for PxScene inside PxExtensions. All SQ-related calls from the PxScene API
|
||||
// will be re-routed to this class. This version re-uses the same internal code as PhysX (most notably from SqQuery.h) so there is
|
||||
// little differences between the internal PhysX version and this one except minor implementation details like what we store in the
|
||||
// PrunerPayload. The whole API is available, it uses the same number of "pruners" for the queries, etc. This is a good working
|
||||
// starting point for users who want to start tinkering with the system without starting from scratch.
|
||||
|
||||
using namespace physx;
|
||||
using namespace Sq;
|
||||
using namespace Gu;
|
||||
|
||||
#define EXT_PRUNER_EPSILON 0.005f
|
||||
|
||||
// PT: in this external implementation we'll use Px pointers instead of Np pointers in the payload.
|
||||
static PX_FORCE_INLINE void setPayload(PrunerPayload& pp, const PxShape* shape, const PxRigidActor* actor)
|
||||
{
|
||||
pp.data[0] = size_t(shape);
|
||||
pp.data[1] = size_t(actor);
|
||||
}
|
||||
|
||||
static PX_FORCE_INLINE PxShape* getShapeFromPayload(const PrunerPayload& payload)
|
||||
{
|
||||
return reinterpret_cast<PxShape*>(payload.data[0]);
|
||||
}
|
||||
|
||||
static PX_FORCE_INLINE PxRigidActor* getActorFromPayload(const PrunerPayload& payload)
|
||||
{
|
||||
return reinterpret_cast<PxRigidActor*>(payload.data[1]);
|
||||
}
|
||||
|
||||
static PX_FORCE_INLINE bool isDynamicActor(const PxRigidActor& actor)
|
||||
{
|
||||
const PxType actorType = actor.getConcreteType();
|
||||
return actorType != PxConcreteType::eRIGID_STATIC;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static PX_FORCE_INLINE ActorShapeData createActorShapeData(PrunerData data, PrunerCompoundId id) { return (ActorShapeData(id) << 32) | ActorShapeData(data); }
|
||||
static PX_FORCE_INLINE PrunerData getPrunerData(ActorShapeData data) { return PrunerData(data); }
|
||||
static PX_FORCE_INLINE PrunerCompoundId getCompoundID(ActorShapeData data) { return PrunerCompoundId(data >> 32); }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace
|
||||
{
|
||||
class ExtSqAdapter : public QueryAdapter
|
||||
{
|
||||
public:
|
||||
ExtSqAdapter() {}
|
||||
virtual ~ExtSqAdapter() {}
|
||||
|
||||
// Adapter
|
||||
virtual const PxGeometry& getGeometry(const PrunerPayload& payload) const;
|
||||
//~Adapter
|
||||
|
||||
// QueryAdapter
|
||||
virtual PrunerHandle findPrunerHandle(const PxQueryCache& cache, PrunerCompoundId& compoundId, PxU32& prunerIndex) const;
|
||||
virtual void getFilterData(const PrunerPayload& payload, PxFilterData& filterData) const;
|
||||
virtual void getActorShape(const PrunerPayload& payload, PxActorShape& actorShape) const;
|
||||
//~QueryAdapter
|
||||
|
||||
ActorShapeMap mDatabase;
|
||||
};
|
||||
}
|
||||
|
||||
const PxGeometry& ExtSqAdapter::getGeometry(const PrunerPayload& payload) const
|
||||
{
|
||||
PxShape* shape = getShapeFromPayload(payload);
|
||||
return shape->getGeometry();
|
||||
}
|
||||
|
||||
PrunerHandle ExtSqAdapter::findPrunerHandle(const PxQueryCache& cache, PrunerCompoundId& compoundId, PxU32& prunerIndex) const
|
||||
{
|
||||
const PxU32 actorIndex = cache.actor->getInternalActorIndex();
|
||||
PX_ASSERT(actorIndex!=0xffffffff);
|
||||
|
||||
const ActorShapeData actorShapeData = mDatabase.find(actorIndex, cache.actor, cache.shape);
|
||||
|
||||
const PrunerData prunerData = getPrunerData(actorShapeData);
|
||||
compoundId = getCompoundID(actorShapeData);
|
||||
|
||||
prunerIndex = getPrunerIndex(prunerData);
|
||||
return getPrunerHandle(prunerData);
|
||||
}
|
||||
|
||||
void ExtSqAdapter::getFilterData(const PrunerPayload& payload, PxFilterData& filterData) const
|
||||
{
|
||||
PxShape* shape = getShapeFromPayload(payload);
|
||||
filterData = shape->getQueryFilterData();
|
||||
}
|
||||
|
||||
void ExtSqAdapter::getActorShape(const PrunerPayload& payload, PxActorShape& actorShape) const
|
||||
{
|
||||
actorShape.actor = getActorFromPayload(payload);
|
||||
actorShape.shape = getShapeFromPayload(payload);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace
|
||||
{
|
||||
class ExternalPxSQ : public PxSceneQuerySystem, public PxUserAllocated
|
||||
{
|
||||
public:
|
||||
ExternalPxSQ(PVDCapture* pvd, PxU64 contextID, Pruner* staticPruner, Pruner* dynamicPruner,
|
||||
PxU32 dynamicTreeRebuildRateHint, PxSceneQueryUpdateMode::Enum mode, const PxSceneLimits& limits) :
|
||||
mQueries (pvd, contextID, staticPruner, dynamicPruner, dynamicTreeRebuildRateHint, EXT_PRUNER_EPSILON, limits, mExtAdapter),
|
||||
mUpdateMode (mode),
|
||||
mRefCount (1)
|
||||
{}
|
||||
virtual ~ExternalPxSQ() {}
|
||||
|
||||
virtual void release();
|
||||
virtual void acquireReference();
|
||||
virtual void preallocate(PxU32 prunerIndex, PxU32 nbShapes) { SQ().preallocate(prunerIndex, nbShapes); }
|
||||
virtual void addSQShape( const PxRigidActor& actor, const PxShape& shape, const PxBounds3& bounds,
|
||||
const PxTransform& transform, const PxSQCompoundHandle* compoundHandle, bool hasPruningStructure);
|
||||
virtual void removeSQShape(const PxRigidActor& actor, const PxShape& shape);
|
||||
virtual void updateSQShape(const PxRigidActor& actor, const PxShape& shape, const PxTransform& transform);
|
||||
virtual PxSQCompoundHandle addSQCompound(const PxRigidActor& actor, const PxShape** shapes, const PxBVH& pxbvh, const PxTransform* transforms);
|
||||
virtual void removeSQCompound(PxSQCompoundHandle compoundHandle);
|
||||
virtual void updateSQCompound(PxSQCompoundHandle compoundHandle, const PxTransform& compoundTransform);
|
||||
virtual void flushUpdates() { SQ().flushUpdates(); }
|
||||
virtual void flushMemory() { SQ().flushMemory(); }
|
||||
virtual void visualize(PxU32 prunerIndex, PxRenderOutput& out) const { SQ().visualize(prunerIndex, out); }
|
||||
virtual void shiftOrigin(const PxVec3& shift) { SQ().shiftOrigin(shift); }
|
||||
virtual PxSQBuildStepHandle prepareSceneQueryBuildStep(PxU32 prunerIndex);
|
||||
virtual void sceneQueryBuildStep(PxSQBuildStepHandle handle);
|
||||
virtual void finalizeUpdates();
|
||||
virtual void setDynamicTreeRebuildRateHint(PxU32 dynTreeRebuildRateHint) { SQ().setDynamicTreeRebuildRateHint(dynTreeRebuildRateHint); }
|
||||
virtual PxU32 getDynamicTreeRebuildRateHint() const { return SQ().getDynamicTreeRebuildRateHint(); }
|
||||
virtual void forceRebuildDynamicTree(PxU32 prunerIndex) { SQ().forceRebuildDynamicTree(prunerIndex); }
|
||||
virtual PxSceneQueryUpdateMode::Enum getUpdateMode() const { return mUpdateMode; }
|
||||
virtual void setUpdateMode(PxSceneQueryUpdateMode::Enum mode) { mUpdateMode = mode; }
|
||||
virtual PxU32 getStaticTimestamp() const { return SQ().getStaticTimestamp(); }
|
||||
virtual void merge(const PxPruningStructure& pxps);
|
||||
virtual bool raycast(const PxVec3& origin, const PxVec3& unitDir, const PxReal distance,
|
||||
PxRaycastCallback& hitCall, PxHitFlags hitFlags,
|
||||
const PxQueryFilterData& filterData, PxQueryFilterCallback* filterCall,
|
||||
const PxQueryCache* cache, PxGeometryQueryFlags flags) const;
|
||||
virtual bool sweep( const PxGeometry& geometry, const PxTransform& pose,
|
||||
const PxVec3& unitDir, const PxReal distance,
|
||||
PxSweepCallback& hitCall, PxHitFlags hitFlags,
|
||||
const PxQueryFilterData& filterData, PxQueryFilterCallback* filterCall,
|
||||
const PxQueryCache* cache, const PxReal inflation, PxGeometryQueryFlags flags) const;
|
||||
virtual bool overlap(const PxGeometry& geometry, const PxTransform& transform,
|
||||
PxOverlapCallback& hitCall,
|
||||
const PxQueryFilterData& filterData, PxQueryFilterCallback* filterCall,
|
||||
const PxQueryCache* cache, PxGeometryQueryFlags flags) const;
|
||||
virtual PxSQPrunerHandle getHandle(const PxRigidActor& actor, const PxShape& shape, PxU32& prunerIndex) const;
|
||||
virtual void sync(PxU32 prunerIndex, const PxSQPrunerHandle* handles, const PxU32* indices, const PxBounds3* bounds,
|
||||
const PxTransform32* transforms, PxU32 count, const PxBitMap& ignoredIndices);
|
||||
|
||||
PX_FORCE_INLINE PrunerManager& SQ() { return mQueries.mSQManager; }
|
||||
PX_FORCE_INLINE const PrunerManager& SQ() const { return mQueries.mSQManager; }
|
||||
|
||||
ExtSqAdapter mExtAdapter;
|
||||
SceneQueries mQueries;
|
||||
PxSceneQueryUpdateMode::Enum mUpdateMode;
|
||||
PxU32 mRefCount;
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void addExternalSQ(PxSceneQuerySystem* added);
|
||||
void removeExternalSQ(PxSceneQuerySystem* removed);
|
||||
|
||||
void ExternalPxSQ::release()
|
||||
{
|
||||
mRefCount--;
|
||||
if(!mRefCount)
|
||||
{
|
||||
removeExternalSQ(this);
|
||||
PX_DELETE_THIS;
|
||||
}
|
||||
}
|
||||
|
||||
void ExternalPxSQ::acquireReference()
|
||||
{
|
||||
mRefCount++;
|
||||
}
|
||||
|
||||
void ExternalPxSQ::addSQShape(const PxRigidActor& actor, const PxShape& shape, const PxBounds3& bounds, const PxTransform& transform, const PxSQCompoundHandle* compoundHandle, bool hasPruningStructure)
|
||||
{
|
||||
PrunerPayload payload;
|
||||
setPayload(payload, &shape, &actor);
|
||||
|
||||
const PrunerCompoundId cid = compoundHandle ? PrunerCompoundId(*compoundHandle) : INVALID_COMPOUND_ID;
|
||||
const PrunerData prunerData = SQ().addPrunerShape(payload, isDynamicActor(actor), cid, bounds, transform, hasPruningStructure);
|
||||
|
||||
const PxU32 actorIndex = actor.getInternalActorIndex();
|
||||
PX_ASSERT(actorIndex!=0xffffffff);
|
||||
mExtAdapter.mDatabase.add(actorIndex, &actor, &shape, createActorShapeData(prunerData, cid));
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct DatabaseCleaner : PrunerPayloadRemovalCallback
|
||||
{
|
||||
DatabaseCleaner(ExtSqAdapter& adapter) : mAdapter(adapter){}
|
||||
|
||||
virtual void invoke(PxU32 nbRemoved, const PrunerPayload* removed) PX_OVERRIDE PX_FINAL
|
||||
{
|
||||
PxU32 actorIndex = 0xffffffff;
|
||||
const PxRigidActor* cachedActor = NULL;
|
||||
|
||||
while(nbRemoved--)
|
||||
{
|
||||
const PrunerPayload& payload = *removed++;
|
||||
|
||||
const PxRigidActor* actor = getActorFromPayload(payload);
|
||||
|
||||
if(actor!=cachedActor)
|
||||
{
|
||||
actorIndex = actor->getInternalActorIndex();
|
||||
cachedActor = actor;
|
||||
}
|
||||
PX_ASSERT(actorIndex!=0xffffffff);
|
||||
|
||||
bool status = mAdapter.mDatabase.remove(actorIndex, actor, getShapeFromPayload(payload), NULL);
|
||||
PX_ASSERT(status);
|
||||
PX_UNUSED(status);
|
||||
}
|
||||
}
|
||||
ExtSqAdapter& mAdapter;
|
||||
|
||||
PX_NOCOPY(DatabaseCleaner)
|
||||
};
|
||||
}
|
||||
|
||||
void ExternalPxSQ::removeSQShape(const PxRigidActor& actor, const PxShape& shape)
|
||||
{
|
||||
const PxU32 actorIndex = actor.getInternalActorIndex();
|
||||
PX_ASSERT(actorIndex!=0xffffffff);
|
||||
|
||||
ActorShapeData actorShapeData;
|
||||
mExtAdapter.mDatabase.remove(actorIndex, &actor, &shape, &actorShapeData);
|
||||
|
||||
const PrunerData data = getPrunerData(actorShapeData);
|
||||
const PrunerCompoundId compoundId = getCompoundID(actorShapeData);
|
||||
|
||||
SQ().removePrunerShape(compoundId, data, NULL);
|
||||
}
|
||||
|
||||
void ExternalPxSQ::updateSQShape(const PxRigidActor& actor, const PxShape& shape, const PxTransform& transform)
|
||||
{
|
||||
const PxU32 actorIndex = actor.getInternalActorIndex();
|
||||
PX_ASSERT(actorIndex!=0xffffffff);
|
||||
|
||||
const ActorShapeData actorShapeData = mExtAdapter.mDatabase.find(actorIndex, &actor, &shape);
|
||||
|
||||
const PrunerData shapeHandle = getPrunerData(actorShapeData);
|
||||
const PrunerCompoundId cid = getCompoundID(actorShapeData);
|
||||
|
||||
SQ().markForUpdate(cid, shapeHandle, transform);
|
||||
}
|
||||
|
||||
PxSQCompoundHandle ExternalPxSQ::addSQCompound(const PxRigidActor& actor, const PxShape** shapes, const PxBVH& bvh, const PxTransform* transforms)
|
||||
{
|
||||
const PxU32 numSqShapes = bvh.getNbBounds();
|
||||
|
||||
PX_ALLOCA(payloads, PrunerPayload, numSqShapes);
|
||||
for(PxU32 i=0; i<numSqShapes; i++)
|
||||
setPayload(payloads[i], shapes[i], &actor);
|
||||
|
||||
const PxU32 actorIndex = actor.getInternalActorIndex();
|
||||
PX_ASSERT(actorIndex!=0xffffffff);
|
||||
|
||||
PX_ALLOCA(shapeHandles, PrunerData, numSqShapes);
|
||||
SQ().addCompoundShape(bvh, actorIndex, actor.getGlobalPose(), shapeHandles, payloads, transforms, isDynamicActor(actor));
|
||||
|
||||
for(PxU32 i=0; i<numSqShapes; i++)
|
||||
{
|
||||
// PT: TODO: actorIndex is now redundant!
|
||||
mExtAdapter.mDatabase.add(actorIndex, &actor, shapes[i], createActorShapeData(shapeHandles[i], actorIndex));
|
||||
}
|
||||
|
||||
return PxSQCompoundHandle(actorIndex);
|
||||
}
|
||||
|
||||
void ExternalPxSQ::removeSQCompound(PxSQCompoundHandle compoundHandle)
|
||||
{
|
||||
DatabaseCleaner cleaner(mExtAdapter);
|
||||
SQ().removeCompoundActor(PrunerCompoundId(compoundHandle), &cleaner);
|
||||
}
|
||||
|
||||
void ExternalPxSQ::updateSQCompound(PxSQCompoundHandle compoundHandle, const PxTransform& compoundTransform)
|
||||
{
|
||||
SQ().updateCompoundActor(PrunerCompoundId(compoundHandle), compoundTransform);
|
||||
}
|
||||
|
||||
PxSQBuildStepHandle ExternalPxSQ::prepareSceneQueryBuildStep(PxU32 prunerIndex)
|
||||
{
|
||||
return SQ().prepareSceneQueriesUpdate(PruningIndex::Enum(prunerIndex));
|
||||
}
|
||||
|
||||
void ExternalPxSQ::sceneQueryBuildStep(PxSQBuildStepHandle handle)
|
||||
{
|
||||
SQ().sceneQueryBuildStep(handle);
|
||||
}
|
||||
|
||||
void ExternalPxSQ::finalizeUpdates()
|
||||
{
|
||||
switch(mUpdateMode)
|
||||
{
|
||||
case PxSceneQueryUpdateMode::eBUILD_ENABLED_COMMIT_ENABLED: SQ().afterSync(true, true); break;
|
||||
case PxSceneQueryUpdateMode::eBUILD_ENABLED_COMMIT_DISABLED: SQ().afterSync(true, false); break;
|
||||
case PxSceneQueryUpdateMode::eBUILD_DISABLED_COMMIT_DISABLED: SQ().afterSync(false, false); break;
|
||||
}
|
||||
}
|
||||
|
||||
void ExternalPxSQ::merge(const PxPruningStructure& pxps)
|
||||
{
|
||||
Pruner* staticPruner = SQ().getPruner(PruningIndex::eSTATIC);
|
||||
if(staticPruner)
|
||||
staticPruner->merge(pxps.getStaticMergeData());
|
||||
|
||||
Pruner* dynamicPruner = SQ().getPruner(PruningIndex::eDYNAMIC);
|
||||
if(dynamicPruner)
|
||||
dynamicPruner->merge(pxps.getDynamicMergeData());
|
||||
}
|
||||
|
||||
bool ExternalPxSQ::raycast( const PxVec3& origin, const PxVec3& unitDir, const PxReal distance,
|
||||
PxRaycastCallback& hitCall, PxHitFlags hitFlags,
|
||||
const PxQueryFilterData& filterData, PxQueryFilterCallback* filterCall,
|
||||
const PxQueryCache* cache, PxGeometryQueryFlags flags) const
|
||||
{
|
||||
return mQueries._raycast(origin, unitDir, distance, hitCall, hitFlags, filterData, filterCall, cache, flags);
|
||||
}
|
||||
|
||||
bool ExternalPxSQ::sweep( const PxGeometry& geometry, const PxTransform& pose,
|
||||
const PxVec3& unitDir, const PxReal distance,
|
||||
PxSweepCallback& hitCall, PxHitFlags hitFlags,
|
||||
const PxQueryFilterData& filterData, PxQueryFilterCallback* filterCall,
|
||||
const PxQueryCache* cache, const PxReal inflation, PxGeometryQueryFlags flags) const
|
||||
{
|
||||
return mQueries._sweep(geometry, pose, unitDir, distance, hitCall, hitFlags, filterData, filterCall, cache, inflation, flags);
|
||||
}
|
||||
|
||||
bool ExternalPxSQ::overlap( const PxGeometry& geometry, const PxTransform& transform,
|
||||
PxOverlapCallback& hitCall,
|
||||
const PxQueryFilterData& filterData, PxQueryFilterCallback* filterCall,
|
||||
const PxQueryCache* cache, PxGeometryQueryFlags flags) const
|
||||
{
|
||||
return mQueries._overlap( geometry, transform, hitCall, filterData, filterCall, cache, flags);
|
||||
}
|
||||
|
||||
PxSQPrunerHandle ExternalPxSQ::getHandle(const PxRigidActor& actor, const PxShape& shape, PxU32& prunerIndex) const
|
||||
{
|
||||
const PxU32 actorIndex = actor.getInternalActorIndex();
|
||||
PX_ASSERT(actorIndex!=0xffffffff);
|
||||
|
||||
const ActorShapeData actorShapeData = mExtAdapter.mDatabase.find(actorIndex, &actor, &shape);
|
||||
|
||||
const PrunerData prunerData = getPrunerData(actorShapeData);
|
||||
|
||||
prunerIndex = getPrunerIndex(prunerData);
|
||||
|
||||
return PxSQPrunerHandle(getPrunerHandle(prunerData));
|
||||
}
|
||||
|
||||
void ExternalPxSQ::sync(PxU32 prunerIndex, const PxSQPrunerHandle* handles, const PxU32* indices, const PxBounds3* bounds,
|
||||
const PxTransform32* transforms, PxU32 count, const PxBitMap& ignoredIndices)
|
||||
{
|
||||
PX_ASSERT(prunerIndex==PruningIndex::eDYNAMIC);
|
||||
if(prunerIndex==PruningIndex::eDYNAMIC)
|
||||
SQ().sync(handles, indices, bounds, transforms, count, ignoredIndices);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static CompanionPrunerType getCompanionType(PxDynamicTreeSecondaryPruner::Enum type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case PxDynamicTreeSecondaryPruner::eNONE: return COMPANION_PRUNER_NONE;
|
||||
case PxDynamicTreeSecondaryPruner::eBUCKET: return COMPANION_PRUNER_BUCKET;
|
||||
case PxDynamicTreeSecondaryPruner::eINCREMENTAL: return COMPANION_PRUNER_INCREMENTAL;
|
||||
case PxDynamicTreeSecondaryPruner::eBVH: return COMPANION_PRUNER_AABB_TREE;
|
||||
case PxDynamicTreeSecondaryPruner::eLAST: return COMPANION_PRUNER_NONE;
|
||||
}
|
||||
return COMPANION_PRUNER_NONE;
|
||||
}
|
||||
|
||||
static BVHBuildStrategy getBuildStrategy(PxBVHBuildStrategy::Enum bs)
|
||||
{
|
||||
switch(bs)
|
||||
{
|
||||
case PxBVHBuildStrategy::eFAST: return BVH_SPLATTER_POINTS;
|
||||
case PxBVHBuildStrategy::eDEFAULT: return BVH_SPLATTER_POINTS_SPLIT_GEOM_CENTER;
|
||||
case PxBVHBuildStrategy::eSAH: return BVH_SAH;
|
||||
case PxBVHBuildStrategy::eLAST: return BVH_SPLATTER_POINTS;
|
||||
}
|
||||
return BVH_SPLATTER_POINTS;
|
||||
}
|
||||
|
||||
static Pruner* create(PxPruningStructureType::Enum type, PxU64 contextID, PxDynamicTreeSecondaryPruner::Enum secondaryType, PxBVHBuildStrategy::Enum buildStrategy, PxU32 nbObjectsPerNode)
|
||||
{
|
||||
// if(0)
|
||||
// return createIncrementalPruner(contextID);
|
||||
|
||||
const CompanionPrunerType cpType = getCompanionType(secondaryType);
|
||||
const BVHBuildStrategy bs = getBuildStrategy(buildStrategy);
|
||||
|
||||
Pruner* pruner = NULL;
|
||||
switch(type)
|
||||
{
|
||||
case PxPruningStructureType::eNONE: { pruner = createBucketPruner(contextID); break; }
|
||||
case PxPruningStructureType::eDYNAMIC_AABB_TREE: { pruner = createAABBPruner(contextID, true, cpType, bs, nbObjectsPerNode); break; }
|
||||
case PxPruningStructureType::eSTATIC_AABB_TREE: { pruner = createAABBPruner(contextID, false, cpType, bs, nbObjectsPerNode); break; }
|
||||
case PxPruningStructureType::eLAST: break;
|
||||
}
|
||||
return pruner;
|
||||
}
|
||||
|
||||
PxSceneQuerySystem* physx::PxCreateExternalSceneQuerySystem(const PxSceneQueryDesc& desc, PxU64 contextID)
|
||||
{
|
||||
PVDCapture* pvd = NULL;
|
||||
Pruner* staticPruner = create(desc.staticStructure, contextID, desc.dynamicTreeSecondaryPruner, desc.staticBVHBuildStrategy, desc.staticNbObjectsPerNode);
|
||||
Pruner* dynamicPruner = create(desc.dynamicStructure, contextID, desc.dynamicTreeSecondaryPruner, desc.dynamicBVHBuildStrategy, desc.dynamicNbObjectsPerNode);
|
||||
|
||||
ExternalPxSQ* pxsq = PX_NEW(ExternalPxSQ)(pvd, contextID, staticPruner, dynamicPruner, desc.dynamicTreeRebuildRateHint, desc.sceneQueryUpdateMode, PxSceneLimits());
|
||||
|
||||
addExternalSQ(pxsq);
|
||||
|
||||
return pxsq;
|
||||
}
|
||||
Reference in New Issue
Block a user