Space-Project/dependencies/physx-4.1/source/scenequery/include/SqSceneQueryManager.h
2021-01-16 17:11:39 +01:00

222 lines
8.6 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 PX_PHYSICS_SCENEQUERYMANAGER
#define PX_PHYSICS_SCENEQUERYMANAGER
/** \addtogroup physics
@{ */
#include "PxSceneDesc.h"
#include "CmBitMap.h"
#include "PsArray.h"
#include "SqPruner.h"
#include "PsMutex.h"
#include "PxActor.h" // needed for offset table
#include "ScScene.h"
// threading
#include "PsSync.h"
namespace physx
{
namespace Scb
{
class Scene;
class Shape;
class Actor;
}
namespace Gu
{
class BVHStructure;
}
namespace Sq
{
typedef size_t PrunerData;
#define SQ_INVALID_PRUNER_DATA 0xffffffff
struct PrunerPayload;
class Pruner;
class CompoundPruner;
// PT: extended pruner structure. We might want to move the additional data to the pruner itself later.
struct PrunerExt
{
PrunerExt();
~PrunerExt();
void init(PxPruningStructureType::Enum type, PxU64 contextID, PxU32 sceneLimit);
void flushMemory();
void preallocate(PxU32 nbShapes);
void flushShapes(PxU32 index);
void addToDirtyList(PrunerHandle handle);
Ps::IntBool isDirty(PrunerHandle handle) const;
void removeFromDirtyList(PrunerHandle handle);
void growDirtyList(PrunerHandle handle);
PX_FORCE_INLINE PxPruningStructureType::Enum type() const { return mPrunerType; }
PX_FORCE_INLINE const Pruner* pruner() const { return mPruner; }
PX_FORCE_INLINE Pruner* pruner() { return mPruner; }
PX_FORCE_INLINE PxU32 timestamp() const { return mTimestamp; }
PX_FORCE_INLINE void invalidateTimestamp() { mTimestamp++; }
private:
Pruner* mPruner;
Cm::BitMap mDirtyMap;
Ps::Array<PrunerHandle> mDirtyList;
PxPruningStructureType::Enum mPrunerType;
PxU32 mTimestamp;
PX_NOCOPY(PrunerExt)
friend class SceneQueryManager;
};
typedef Ps::Pair<PrunerCompoundId, PrunerHandle> CompoundPair;
typedef Ps::CoalescedHashSet<CompoundPair > CompoundPrunerSet;
// AB: extended compoud pruner structure, buffers compound shape changes and flushes them.
struct CompoundPrunerExt
{
CompoundPrunerExt();
~CompoundPrunerExt();
void flushMemory();
void preallocate(PxU32 nbShapes);
void flushShapes();
void addToDirtyList(PrunerCompoundId compoundId, PrunerHandle handle);
Ps::IntBool isDirty(PrunerCompoundId compoundId, PrunerHandle handle) const;
void removeFromDirtyList(PrunerCompoundId compoundId, PrunerHandle handle);
PX_FORCE_INLINE const CompoundPruner* pruner() const { return mPruner; }
PX_FORCE_INLINE CompoundPruner* pruner() { return mPruner; }
private:
CompoundPruner* mPruner;
CompoundPrunerSet mDirtyList;
PX_NOCOPY(CompoundPrunerExt)
friend class SceneQueryManager;
};
struct DynamicBoundsSync : public Sc::SqBoundsSync
{
virtual void sync(const PrunerHandle* handles, const PxU32* indices, const PxBounds3* bounds, PxU32 count, const Cm::BitMap& dirtyShapeSimMap);
Pruner* mPruner;
PxU32* mTimestamp;
};
class SceneQueryManager : public Ps::UserAllocated
{
PX_NOCOPY(SceneQueryManager)
public:
SceneQueryManager(Scb::Scene& scene, PxPruningStructureType::Enum staticStructure,
PxPruningStructureType::Enum dynamicStructure, PxU32 dynamicTreeRebuildRateHint,
const PxSceneLimits& limits);
~SceneQueryManager();
PrunerData addPrunerShape(const Scb::Shape& scbShape, const Scb::Actor& scbActor, bool dynamic, PrunerCompoundId compoundId, const PxBounds3* bounds=NULL, bool hasPrunerStructure = false);
void removePrunerShape(PrunerCompoundId compoundId, PrunerData shapeData);
const PrunerPayload& getPayload(PrunerCompoundId compoundId, PrunerData shapeData) const;
void addPruningStructure(const Sq::PruningStructure& ps);
void addCompoundShape(const Gu::BVHStructure& bvhStructure, PrunerCompoundId compoundId, const PxTransform& compoundTransform, PrunerData* prunerData, const Scb::Shape** scbShapes, const Scb::Actor& scbActor);
public:
PX_FORCE_INLINE Scb::Scene& getScene() const { return mScene; }
PX_FORCE_INLINE PxU32 getDynamicTreeRebuildRateHint() const { return mRebuildRateHint; }
PX_FORCE_INLINE const PrunerExt& get(PruningIndex::Enum index) const { return mPrunerExt[index]; }
PX_FORCE_INLINE PrunerExt& get(PruningIndex::Enum index) { return mPrunerExt[index]; }
PX_FORCE_INLINE const CompoundPrunerExt& getCompoundPruner() const { return mCompoundPrunerExt; }
void preallocate(PxU32 staticShapes, PxU32 dynamicShapes);
void markForUpdate(PrunerCompoundId compoundId, PrunerData s);
void setDynamicTreeRebuildRateHint(PxU32 dynTreeRebuildRateHint);
void flushUpdates();
void forceDynamicTreeRebuild(bool rebuildStaticStructure, bool rebuildDynamicStructure);
void sceneQueryBuildStep(PruningIndex::Enum index);
void updateCompoundActors(Sc::BodyCore*const* bodies, PxU32 numBodies);
void updateCompoundActor(PrunerCompoundId compoundId, const PxTransform& compoundTransform, bool dynamic);
void removeCompoundActor(PrunerCompoundId compoundId, bool dynamic);
DynamicBoundsSync& getDynamicBoundsSync() { return mDynamicBoundsSync; }
bool prepareSceneQueriesUpdate(PruningIndex::Enum index);
// Force a rebuild of the aabb/loose octree etc to allow raycasting on multiple threads.
void afterSync(PxSceneQueryUpdateMode::Enum updateMode);
void shiftOrigin(const PxVec3& shift);
void flushMemory();
private:
PrunerExt mPrunerExt[PruningIndex::eCOUNT];
CompoundPrunerExt mCompoundPrunerExt;
PxU32 mRebuildRateHint;
Scb::Scene& mScene;
// threading
shdfnd::Mutex mSceneQueryLock; // to make sure only one query updates the dirty pruner structure if multiple queries run in parallel
DynamicBoundsSync mDynamicBoundsSync;
volatile bool mPrunerNeedsUpdating;
void flushShapes();
};
///////////////////////////////////////////////////////////////////////////////
// PT: TODO: replace PrunerData with just PxU32 to save memory on Win64. Breaks binary compatibility though.
// PT: was previously called 'ActorShape' but does not contain an actor or shape pointer, contrary to the Np-level struct with the same name.
// PT: it only contains a pruner index (0 or 1) and a pruner handle. Hence the new name.
PX_FORCE_INLINE PrunerData createPrunerData(PxU32 index, PrunerHandle h) { return PrunerData((h << 1) | index); }
PX_FORCE_INLINE PxU32 getPrunerIndex(PrunerData data) { return PxU32(data & 1); }
PX_FORCE_INLINE PrunerHandle getPrunerHandle(PrunerData data) { return PrunerHandle(data >> 1); }
///////////////////////////////////////////////////////////////////////////////
} // namespace Sq
}
/** @} */
#endif