// 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.  

#ifndef PX_BROAD_PHASE_H
#define PX_BROAD_PHASE_H

#include "PxPhysXConfig.h"
#include "foundation/PxBounds3.h"

#if !PX_DOXYGEN
namespace physx
{
#endif

	class PxBaseTask;
	class PxCudaContextManager;
	class PxAllocatorCallback;

	/**
	\brief Broad phase algorithm used in the simulation

	eSAP is a good generic choice with great performance when many objects are sleeping. Performance
	can degrade significantly though, when all objects are moving, or when large numbers of objects
	are added to or removed from the broad phase. This algorithm does not need world bounds to be
	defined in order to work.

	eMBP is an alternative broad phase algorithm that does not suffer from the same performance
	issues as eSAP when all objects are moving or when inserting large numbers of objects. However
	its generic performance when many objects are sleeping might be inferior to eSAP, and it requires
	users to define world bounds in order to work.

	eABP is a revisited implementation of MBP, which automatically manages broad-phase regions.
	It offers the convenience of eSAP (no need to define world bounds or regions) and the performance
	of eMBP when a lot of objects are moving. While eSAP can remain faster when most objects are
	sleeping and eMBP can remain faster when it uses a large number of properly-defined regions,
	eABP often gives the best performance on average and the best memory usage.

	ePABP is a parallel implementation of ABP. It can often be the fastest (CPU) broadphase, but it
	can use more memory than ABP.

	eGPU is a GPU implementation of the incremental sweep and prune approach. Additionally, it uses a ABP-style
	initial pair generation approach to avoid large spikes when inserting shapes. It not only has the advantage 
	of traditional SAP approch which is good for when many objects are sleeping, but due to being fully parallel, 
	it also is great when lots of shapes are moving or for runtime pair insertion and removal. It can become a 
	performance bottleneck if there are a very large number of shapes roughly projecting to the same values
	on a given axis. If the scene has a very large number of shapes in an actor, e.g. a humanoid, it is recommended
	to use an aggregate to represent multi-shape or multi-body actors to minimize stress placed on the broad phase.
	*/
	struct PxBroadPhaseType
	{
		enum Enum
		{
			eSAP,	//!< 3-axes sweep-and-prune
			eMBP,	//!< Multi box pruning
			eABP,	//!< Automatic box pruning
			ePABP,	//!< Parallel automatic box pruning
			eGPU,	//!< GPU broad phase
			eLAST
		};
	};

	/**
	\brief "Region of interest" for the broad-phase.

	This is currently only used for the PxBroadPhaseType::eMBP broad-phase, which requires zones or regions to be defined
	when the simulation starts in order to work. Regions can overlap and be added or removed at runtime, but at least one
	region needs to be defined when the scene is created.

	If objects that do no overlap any region are inserted into the scene, they will not be added to the broad-phase and
	thus collisions will be disabled for them. A PxBroadPhaseCallback out-of-bounds notification will be sent for each one
	of those objects.

	The total number of regions is limited by PxBroadPhaseCaps::mMaxNbRegions.

	The number of regions has a direct impact on performance and memory usage, so it is recommended to experiment with
	various settings to find the best combination for your game. A good default setup is to start with global bounds
	around the whole world, and subdivide these bounds into 4*4 regions. The PxBroadPhaseExt::createRegionsFromWorldBounds
	function can do that for you.

	\see PxBroadPhaseCallback PxBroadPhaseExt.createRegionsFromWorldBounds
	*/
	struct PxBroadPhaseRegion
	{
		PxBounds3	mBounds;	//!< Region's bounds
		void*		mUserData;	//!< Region's user-provided data
	};

	/**
	\brief Information & stats structure for a region
	*/
	struct PxBroadPhaseRegionInfo
	{
		PxBroadPhaseRegion	mRegion;			//!< User-provided region data
		PxU32				mNbStaticObjects;	//!< Number of static objects in the region
		PxU32				mNbDynamicObjects;	//!< Number of dynamic objects in the region
		bool				mActive;			//!< True if region is currently used, i.e. it has not been removed
		bool				mOverlap;			//!< True if region overlaps other regions (regions that are just touching are not considering overlapping)
	};

	/**
	\brief Caps class for broad phase.
	*/
	struct PxBroadPhaseCaps
	{
		PxU32	mMaxNbRegions;	//!< Max number of regions supported by the broad-phase (0 = explicit regions not needed)
	};

	/**
	\brief Descriptor for the GPU broad-phase.

	This struct contains parameters that are only relevant for the GPU broad-phase.

	\see PxBroadPhaseType::eGPU
	*/
	struct PxGpuBroadPhaseDesc
	{
		PxGpuBroadPhaseDesc() :
			gpuBroadPhaseNbBitsShiftX	(4),
			gpuBroadPhaseNbBitsShiftY	(4),
			gpuBroadPhaseNbBitsShiftZ	(4),
			gpuBroadPhaseNbBitsEnvIDX	(0),
			gpuBroadPhaseNbBitsEnvIDY	(0),
			gpuBroadPhaseNbBitsEnvIDZ	(0)
		{
		}

		// The GPU broadphase encodes bounds as integers, and then right-shifts the data by this amount of bits.
		// This makes the bounds a bit larger, which avoids losing and recreating overlaps over and over when
		// two objects are just touching. This effect is similar to what can be achieved with the contact distance
		// parameter, and the amount by which the bounds are inflated depends on the distance from the bounds to
		// the origin (as the bounds encoding does not use a regular float-to-integer conversion, but instead a
		// reinterpretation of the float's bits). The default value in the GPU broadphase has always been 4 bits
		// but it is safe to use 0 here for more accurate bounds.
		PxU8	gpuBroadPhaseNbBitsShiftX;	//!< number of bits used for "snap to grid" on the X axis
		PxU8	gpuBroadPhaseNbBitsShiftY;	//!< number of bits used for "snap to grid" on the Y axis
		PxU8	gpuBroadPhaseNbBitsShiftZ;	//!< number of bits used for "snap to grid" on the Z axis

		// The bits lost by the previous shifts (gpuBroadPhaseNbBitsShiftXYZ) can be replaced with bits of the
		// environment IDs. This only makes sense when these parameters are used (see PxActor::setEnvironmentID
		// and PxAggregate::setEnvironmentID). In this case a number of bits from the environment IDs are stored
		// in the MSBs of encoded bounds. This has the effect of virtually spreading the bounds over 3D space,
		// which reduces the number of internal overlaps inside the broad-phase. This is mainly useful in RL
		// scenarios with "co-located" environments, but it can also provide performance gains with regular grid
		// configurations, that also generate a lot of internal overlaps on all coordinate axes.
		//
		// Beware: when using this feature, each object of each environment should be assigned a proper environment
		// ID. Objects shared between all environments (i.e. objects whose environment ID is PX_INVALID_U32) will
		// otherwise be internally assigned bounds that cover the entire 3D space, creating a lot of overlaps and
		// potential performance issues. This is only a concern when gpuBroadPhaseNbBitsEnvIDX/Y/Z are non zero,
		// shared objects are fine otherwise.
		PxU8	gpuBroadPhaseNbBitsEnvIDX;	//!< number of environment ID bits merged with the bounds on the X axis
		PxU8	gpuBroadPhaseNbBitsEnvIDY;	//!< number of environment ID bits merged with the bounds on the Y axis
		PxU8	gpuBroadPhaseNbBitsEnvIDZ;	//!< number of environment ID bits merged with the bounds on the Z axis

		PX_INLINE	bool		isValid()	const
		{
			// This is used on 32bit data so it makes no sense to shift more than 32 bits.
			// It also makes no sense to shift all the bits of source data.
			if(	gpuBroadPhaseNbBitsShiftX > 31
			||	gpuBroadPhaseNbBitsShiftY > 31
			||	gpuBroadPhaseNbBitsShiftZ > 31)
				return false;

			if(	gpuBroadPhaseNbBitsEnvIDX > 31
			||	gpuBroadPhaseNbBitsEnvIDY > 31
			||	gpuBroadPhaseNbBitsEnvIDZ > 31)
				return false;

			// We can only store bits from environment IDs in bits shifted away from the source data.
			// So we need to drop (shift) at least as many bits of the source data as we need for env IDs.
			if(	gpuBroadPhaseNbBitsEnvIDX > gpuBroadPhaseNbBitsShiftX
			||	gpuBroadPhaseNbBitsEnvIDY > gpuBroadPhaseNbBitsShiftY
			||	gpuBroadPhaseNbBitsEnvIDZ > gpuBroadPhaseNbBitsShiftZ)
				return false;
			return true;
		}
	};

	/**
	\brief Broadphase descriptor.

	This structure is used to create a standalone broadphase. It captures all the parameters needed to
	initialize a broadphase.

	For the GPU broadphase (PxBroadPhaseType::eGPU) it is necessary to provide a CUDA context manager.

	The kinematic filtering flags are currently not supported by the GPU broadphase. They are used to
	dismiss pairs that involve kinematic objects directly within the broadphase.

	\see	PxCreateBroadPhase
	*/
	class PxBroadPhaseDesc
	{
		public:
		PxBroadPhaseDesc(PxBroadPhaseType::Enum type = PxBroadPhaseType::eLAST) :
			mType						(type),
			mContextID					(0),
			mContextManager				(NULL),
			mFoundLostPairsCapacity		(256 * 1024),
			mDiscardStaticVsKinematic	(false),
			mDiscardKinematicVsKinematic(false)
		{}
	
		PxBroadPhaseType::Enum	mType;							//!< Desired broadphase implementation
		PxU64					mContextID;						//!< Context ID for profiler. See PxProfilerCallback.

		PxCudaContextManager*	mContextManager;				//!< (GPU) CUDA context manager, must be provided for PxBroadPhaseType::eGPU.
		PxU32					mFoundLostPairsCapacity;		//!< (GPU) Capacity of found and lost buffers allocated in GPU global memory. This is used for the found/lost pair reports in the BP.

		bool					mDiscardStaticVsKinematic;		//!< Static-vs-kinematic filtering flag. Not supported by PxBroadPhaseType::eGPU.
		bool					mDiscardKinematicVsKinematic;	//!< kinematic-vs-kinematic filtering flag. Not supported by PxBroadPhaseType::eGPU.

		PX_INLINE	bool		isValid()	const
		{
			if(PxU32(mType)>=PxBroadPhaseType::eLAST)
				return false;

			if(mType==PxBroadPhaseType::eGPU && !mContextManager)
				return false;

			return true;
		}
	};

	typedef PxU32 PxBpIndex;						//!< Broadphase index. Indexes bounds, groups and distance arrays.
	typedef PxU32 PxBpFilterGroup;					//!< Broadphase filter group.
	#define PX_INVALID_BP_FILTER_GROUP	0xffffffff	//!< Invalid broadphase filter group

	/**
	\brief Retrieves the filter group for static objects.

	Mark static objects with this group when adding them to the broadphase.
	Overlaps between static objects will not be detected. All static objects
	should have the same group.

	\return		Filter group for static objects.
	\see		PxBpFilterGroup
	*/
	PX_C_EXPORT PX_PHYSX_CORE_API	PxBpFilterGroup	PxGetBroadPhaseStaticFilterGroup();

	/**
	\brief Retrieves a filter group for dynamic objects.

	Mark dynamic objects with this group when adding them to the broadphase.
	Each dynamic object must have an ID, and overlaps between dynamic objects that have
	the same ID will not be detected. This is useful to dismiss overlaps between shapes
	of the same (compound) actor directly within the broadphase.

	\param		id [in]		ID/Index of dynamic object
	\return		Filter group for the object.
	\see		PxBpFilterGroup
	*/
	PX_C_EXPORT PX_PHYSX_CORE_API	PxBpFilterGroup	PxGetBroadPhaseDynamicFilterGroup(PxU32 id);

	/**
	\brief Retrieves a filter group for kinematic objects.

	Mark kinematic objects with this group when adding them to the broadphase.
	Each kinematic object must have an ID, and overlaps between kinematic objects that have
	the same ID will not be detected.

	\param		id [in]		ID/Index of kinematic object
	\return		Filter group for the object.
	\see		PxBpFilterGroup
	*/
	PX_C_EXPORT PX_PHYSX_CORE_API	PxBpFilterGroup	PxGetBroadPhaseKinematicFilterGroup(PxU32 id);

	/**
	\brief Broadphase data update structure.

	This structure is used to update the low-level broadphase (PxBroadPhase). All added, updated and removed objects
	must be batched and submitted at once to the broadphase.

	Broadphase objects have bounds, a filtering group, and a distance. With the low-level broadphase the data must be
	externally managed by the clients of the broadphase API, and passed to the update function.

	The provided bounds are non-inflated "base" bounds that can be further extended by the broadphase using the passed
	distance value. These can be contact offsets, or dynamically updated distance values for e.g. speculative contacts.
	Either way they are optional and can be left to zero. The broadphase implementations efficiently combine the base
	bounds with the per-object distance values at runtime.

	The per-object filtering groups are used to discard some pairs directly within the broadphase, which is more
	efficient than reporting the pairs and culling them in a second pass.

	\see	PxBpFilterGroup PxBpIndex PxBounds3 PxBroadPhase::update
	*/
	class PxBroadPhaseUpdateData
	{
		public:

		PxBroadPhaseUpdateData(	const PxBpIndex* created, PxU32 nbCreated,
								const PxBpIndex* updated, PxU32 nbUpdated,
								const PxBpIndex* removed, PxU32 nbRemoved,
								const PxBounds3* bounds, const PxBpFilterGroup* groups, const float* distances,
								PxU32 capacity) :
			mCreated	(created),	mNbCreated	(nbCreated),
			mUpdated	(updated),	mNbUpdated	(nbUpdated),
			mRemoved	(removed),	mNbRemoved	(nbRemoved),
			mBounds		(bounds),	mGroups		(groups),	mDistances	(distances),
			mCapacity	(capacity)
		{
		}

		PxBroadPhaseUpdateData(const PxBroadPhaseUpdateData& other) :
			mCreated	(other.mCreated),	mNbCreated	(other.mNbCreated),
			mUpdated	(other.mUpdated),	mNbUpdated	(other.mNbUpdated),
			mRemoved	(other.mRemoved),	mNbRemoved	(other.mNbRemoved),
			mBounds		(other.mBounds),	mGroups		(other.mGroups),	mDistances	(other.mDistances),
			mCapacity	(other.mCapacity)
		{
		}

		PxBroadPhaseUpdateData& operator=(const PxBroadPhaseUpdateData& other);

		const PxBpIndex*		mCreated;	//!< Indices of created objects.
		const PxU32				mNbCreated;	//!< Number of created objects.

		const PxBpIndex*		mUpdated;	//!< Indices of updated objects.
		const PxU32				mNbUpdated;	//!< Number of updated objects.

		const PxBpIndex*		mRemoved;	//!< Indices of removed objects.
		const PxU32				mNbRemoved;	//!< Number of removed objects.

		const PxBounds3*		mBounds;	//!< (Persistent) array of bounds.
		const PxBpFilterGroup*	mGroups;	//!< (Persistent) array of groups.
		const float*			mDistances;	//!< (Persistent) array of distances.
		const PxU32				mCapacity;	//!< Capacity of bounds / groups / distance buffers.
	};

	/**
	\brief Broadphase pair.

	A pair of indices returned by the broadphase for found or lost pairs.

	\see	PxBroadPhaseResults
	*/
	struct PxBroadPhasePair
	{
		PxBpIndex	mID0;	//!< Index of first object
		PxBpIndex	mID1;	//!< Index of second object
	};

	/**
	\brief Broadphase results.

	Set of found and lost pairs after a broadphase update.

	\see	PxBroadPhasePair PxBroadPhase::fetchResults PxAABBManager::fetchResults
	*/
	struct PxBroadPhaseResults
	{
		PxBroadPhaseResults() : mNbCreatedPairs(0), mCreatedPairs(NULL), mNbDeletedPairs(0), mDeletedPairs(NULL)	{}

		PxU32					mNbCreatedPairs;	//!< Number of new/found/created pairs.
		const PxBroadPhasePair*	mCreatedPairs;		//!< Array of new/found/created pairs.

		PxU32					mNbDeletedPairs;	//!< Number of lost/deleted pairs.
		const PxBroadPhasePair*	mDeletedPairs;		//!< Array of lost/deleted pairs.
	};

	/**
	\brief Broadphase regions.

	An API to manage broadphase regions. Only needed for the MBP broadphase (PxBroadPhaseType::eMBP).

	\see	PxBroadPhase::getRegions()
	*/
	class PxBroadPhaseRegions
	{
		protected:
				PxBroadPhaseRegions()	{}
		virtual	~PxBroadPhaseRegions()	{}
		public:

		/**
		\brief Returns number of regions currently registered in the broad-phase.

		\return Number of regions
		*/
		virtual	PxU32	getNbRegions()	const	= 0;

		/**
		\brief Gets broad-phase regions.

		\param	userBuffer	[out]	Returned broad-phase regions
		\param	bufferSize	[in]	Size of provided userBuffer.
		\param	startIndex	[in]	Index of first desired region, in [0 ; getNbRegions()[
		\return Number of written out regions.
		\see	PxBroadPhaseRegionInfo
		*/
		virtual	PxU32	getRegions(PxBroadPhaseRegionInfo* userBuffer, PxU32 bufferSize, PxU32 startIndex=0)	const	= 0;

		/**
		\brief Adds a new broad-phase region.

		The total number of regions is limited to PxBroadPhaseCaps::mMaxNbRegions. If that number is exceeded, the call is ignored.

		The newly added region will be automatically populated with already existing objects that touch it, if the
		'populateRegion' parameter is set to true. Otherwise the newly added region will be empty, and it will only be
		populated with objects when those objects are added to the simulation, or updated if they already exist.

		Using 'populateRegion=true' has a cost, so it is best to avoid it if possible. In particular it is more efficient
		to create the empty regions first (with populateRegion=false) and then add the objects afterwards (rather than
		the opposite).

		Objects automatically move from one region to another during their lifetime. The system keeps tracks of what
		regions a given object is in. It is legal for an object to be in an arbitrary number of regions. However if an
		object leaves all regions, or is created outside of all regions, several things happen:
			- collisions get disabled for this object
			- the object appears in the getOutOfBoundsObjects() array

		If an out-of-bounds object, whose collisions are disabled, re-enters a valid broadphase region, then collisions
		are re-enabled for that object.

		\param	region			[in] User-provided region data
		\param	populateRegion	[in] True to automatically populate the newly added region with existing objects touching it
		\param	bounds			[in] User-managed array of bounds
		\param	distances		[in] User-managed array of distances

		\return Handle for newly created region, or 0xffffffff in case of failure.
		\see	PxBroadPhaseRegion getOutOfBoundsObjects()
		*/
		virtual	PxU32	addRegion(const PxBroadPhaseRegion& region, bool populateRegion, const PxBounds3* bounds, const float* distances)	= 0;

		/**
		\brief Removes a broad-phase region.

		If the region still contains objects, and if those objects do not overlap any region any more, they are not
		automatically removed from the simulation. Instead, the PxBroadPhaseCallback::onObjectOutOfBounds notification
		is used for each object. Users are responsible for removing the objects from the simulation if this is the
		desired behavior.

		If the handle is invalid, or if a valid handle is removed twice, an error message is sent to the error stream.

		\param	handle	[in] Region's handle, as returned by addRegion
		\return True if success
		*/
		virtual	bool	removeRegion(PxU32 handle)	= 0;

		/*
		\brief Return the number of objects that are not in any region.
		*/
		virtual	PxU32	getNbOutOfBoundsObjects()	const	= 0;

		/*
		\brief Return an array of objects that are not in any region.
		*/
		virtual	const PxU32*	getOutOfBoundsObjects()	const	= 0;
	};

	/**
	\brief Low-level broadphase API.

	This low-level API only supports batched updates and leaves most of the data management to its clients.

	This is useful if you want to use the broadphase with your own memory buffers. Note however that the GPU broadphase
	works best with buffers allocated in CUDA memory. The getAllocator() function returns an allocator that is compatible
	with the selected broadphase. It is recommended to allocate and deallocate the broadphase data (bounds, groups, distances)
	using this allocator.

	Important note: it must be safe to load 4 bytes past the end of the provided bounds array.
	
	The high-level broadphase API (PxAABBManager) is an easier-to-use interface that automatically deals with these requirements.

	\see	PxCreateBroadPhase
	*/
	class PxBroadPhase
	{
		protected:
				PxBroadPhase()	{}
		virtual	~PxBroadPhase()	{}
		public:

		/*
		\brief Releases the broadphase.
		*/
		virtual	void	release()	= 0;

		/**
		\brief Gets the broadphase type.

		\return	Broadphase type.
		\see	PxBroadPhaseType::Enum
		*/
		virtual	PxBroadPhaseType::Enum	getType()	const	= 0;

		/**
		\brief Gets broad-phase caps.

		\param	caps	[out] Broad-phase caps
		\see	PxBroadPhaseCaps
		*/
		virtual	void	getCaps(PxBroadPhaseCaps& caps)	const	= 0;

		/**
		\brief Retrieves the regions API if applicable.

		For broadphases that do not use explicit user-defined regions, this call returns NULL.

		\return	Region API, or NULL.
		\see	PxBroadPhaseRegions
		*/
		virtual	PxBroadPhaseRegions*	getRegions()	= 0;

		/**
		\brief Retrieves the broadphase allocator.

		User-provided buffers should ideally be allocated with this allocator, for best performance.
		This is especially true for the GPU broadphases, whose buffers need to be allocated in CUDA
		host memory.

		\return	The broadphase allocator.
		\see	PxAllocatorCallback
		*/
		virtual	PxAllocatorCallback*	getAllocator()	= 0;

		/**
		\brief Retrieves the profiler's context ID.

		\return	The context ID.
		\see	PxBroadPhaseDesc
		*/
		virtual	PxU64	getContextID()	const	= 0;

		/**
		\brief Sets a scratch buffer

		Some broadphases might take advantage of a scratch buffer to limit runtime allocations.

		All broadphases still work without providing a scratch buffer, this is an optional function
		that can potentially reduce runtime allocations.

		\param	scratchBlock	[in] The scratch buffer
		\param	size			[in] Size of the scratch buffer in bytes
		*/
		virtual	void	setScratchBlock(void* scratchBlock, PxU32 size)	= 0;

		/**
		\brief Updates the broadphase and computes the lists of created/deleted pairs.

		The provided update data describes changes to objects since the last broadphase update.

		To benefit from potentially multithreaded implementations, it is necessary to provide a continuation
		task to the function. It is legal to pass NULL there, but the underlying (CPU) implementations will
		then run single-threaded.

		\param	updateData		[in] The update data
		\param	continuation	[in] Continuation task to enable multi-threaded implementations, or NULL.
		\see	PxBroadPhaseUpdateData PxBaseTask
		*/
		virtual	void	update(const PxBroadPhaseUpdateData& updateData, PxBaseTask* continuation=NULL)	= 0;

		/**
		\brief Retrieves the broadphase results after an update.

		This should be called once after each update call to retrieve the results of the broadphase. The
		results are incremental, i.e. the system only returns new and lost pairs, not all current pairs.

		\param	results		[out] The broadphase results
		\see	PxBroadPhaseResults
		*/
		virtual	void	fetchResults(PxBroadPhaseResults& results)	= 0;

		/**
		\brief Helper for single-threaded updates.

		This short helper function performs a single-theaded update and reports the results in a single call.

		\param	results		[out] The broadphase results
		\param	updateData	[in] The update data
		\see	PxBroadPhaseUpdateData PxBroadPhaseResults
		*/
		PX_FORCE_INLINE	void	updateAndFetchResults(PxBroadPhaseResults& results, const PxBroadPhaseUpdateData& updateData)
		{
			update(updateData);
			fetchResults(results);
		}

		/**
		\brief Helper for single-threaded updates.

		This short helper function performs a single-theaded update and reports the results in a single call.

		\param	results		[out] The broadphase results
		\param	updateData	[in] The update data
		\see	PxBroadPhaseUpdateData PxBroadPhaseResults
		*/
		PX_DEPRECATED	PX_FORCE_INLINE	void	update(PxBroadPhaseResults& results, const PxBroadPhaseUpdateData& updateData)
		{
			update(updateData);
			fetchResults(results);
		}
	};

	/**
	\brief Broadphase factory function.

	Use this function to create a new standalone broadphase.

	\param	desc	[in] Broadphase descriptor
	\return	Newly created broadphase, or NULL
	\see	PxBroadPhase PxBroadPhaseDesc
	*/
	PX_C_EXPORT PX_PHYSX_CORE_API	PxBroadPhase*	PxCreateBroadPhase(const PxBroadPhaseDesc& desc);

	/**
	\brief High-level broadphase API.

	The low-level broadphase API (PxBroadPhase) only supports batched updates and has a few non-trivial
	requirements for managing the bounds data.

	The high-level broadphase API (PxAABBManager) is an easier-to-use one-object-at-a-time API that
	automatically deals with the quirks of the PxBroadPhase data management.

	\see	PxCreateAABBManager
	*/
	class PxAABBManager
	{
		protected:
				PxAABBManager()		{}
		virtual	~PxAABBManager()	{}
		public:

		/*
		\brief Releases the AABB manager.
		*/
		virtual	void	release()	= 0;

		/**
		\brief Retrieves the underlying broadphase.

		\return	The managed broadphase.
		\see	PxBroadPhase
		*/
		virtual	PxBroadPhase&	getBroadPhase()	= 0;

		/**
		\brief Retrieves the managed bounds.

		This is needed as input parameters to functions like PxBroadPhaseRegions::addRegion.

		\return	The managed object bounds.
		\see	PxBounds3
		*/
		virtual	const PxBounds3*	getBounds()	const	= 0;

		/**
		\brief Retrieves the managed distances.

		This is needed as input parameters to functions like PxBroadPhaseRegions::addRegion.

		\return	The managed object distances.
		*/
		virtual	const float*	getDistances()	const	= 0;

		/**
		\brief Retrieves the managed filter groups.

		\return	The managed object groups.
		*/
		virtual	const PxBpFilterGroup*	getGroups()	const	= 0;

		/**
		\brief Retrieves the managed buffers' capacity.

		Bounds, distances and groups buffers have the same capacity.

		\return	The managed buffers' capacity.
		*/
		virtual	PxU32	getCapacity()	const	= 0;

		/**
		\brief Adds an object to the manager.

		Objects' indices are externally managed, i.e. they must be provided by users (as opposed to handles
		that could be returned by this manager). The design allows users to identify an object by a single ID,
		and use the same ID in multiple sub-systems.

		\param	index		[in] The object's index
		\param	bounds		[in] The object's bounds
		\param	group		[in] The object's filter group
		\param	distance	[in] The object's distance (optional)
		\see	PxBpIndex PxBounds3 PxBpFilterGroup
		*/
		virtual	void	addObject(PxBpIndex index, const PxBounds3& bounds, PxBpFilterGroup group, float distance=0.0f)	= 0;

		/**
		\brief Removes an object from the manager.

		\param	index	[in] The object's index
		\see	PxBpIndex
		*/
		virtual	void	removeObject(PxBpIndex index)	= 0;

		/**
		\brief Updates an object in the manager.

		This call can update an object's bounds, distance, or both.
		It is not possible to update an object's filter group.

		\param	index		[in] The object's index
		\param	bounds		[in] The object's updated bounds, or NULL
		\param	distance	[in] The object's updated distance, or NULL
		\see	PxBpIndex PxBounds3
		*/
		virtual	void	updateObject(PxBpIndex index, const PxBounds3* bounds=NULL, const float* distance=NULL)	= 0;

		/**
		\brief Updates the broadphase and computes the lists of created/deleted pairs.

		The data necessary for updating the broadphase is internally computed by the AABB manager.

		To benefit from potentially multithreaded implementations, it is necessary to provide a continuation
		task to the function. It is legal to pass NULL there, but the underlying (CPU) implementations will
		then run single-threaded.

		\param	continuation	[in] Continuation task to enable multi-threaded implementations, or NULL.
		\see	PxBaseTask
		*/
		virtual	void	update(PxBaseTask* continuation=NULL)	= 0;

		/**
		\brief Retrieves the broadphase results after an update.

		This should be called once after each update call to retrieve the results of the broadphase. The
		results are incremental, i.e. the system only returns new and lost pairs, not all current pairs.

		\param	results		[out] The broadphase results
		\see	PxBroadPhaseResults
		*/
		virtual	void	fetchResults(PxBroadPhaseResults& results)	= 0;

		/**
		\brief Helper for single-threaded updates.

		This short helper function performs a single-theaded update and reports the results in a single call.

		\param	results		[out] The broadphase results
		\see	PxBroadPhaseResults
		*/
		PX_FORCE_INLINE	void	updateAndFetchResults(PxBroadPhaseResults& results)
		{
			update();
			fetchResults(results);
		}

		/**
		\brief Helper for single-threaded updates.

		This short helper function performs a single-theaded update and reports the results in a single call.

		\param	results		[out] The broadphase results
		\see	PxBroadPhaseResults
		*/
		PX_DEPRECATED	PX_FORCE_INLINE	void	update(PxBroadPhaseResults& results)
		{
			update();
			fetchResults(results);
		}
	};

	/**
	\brief AABB manager factory function.

	Use this function to create a new standalone high-level broadphase.

	\param	broadphase	[in] The broadphase that will be managed by the AABB manager
	\return	Newly created AABB manager, or NULL
	\see	PxAABBManager PxBroadPhase
	*/
	PX_C_EXPORT PX_PHYSX_CORE_API	PxAABBManager*	PxCreateAABBManager(PxBroadPhase& broadphase);

#if !PX_DOXYGEN
} // namespace physx
#endif

#endif
