Projekt_Grafika/dependencies/physx-4.1/source/lowlevelaabb/include/BpBroadPhase.h
Jakub Adamski f5087ee7b6 new repo
2021-01-29 17:02:11 +01:00

328 lines
13 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 BP_BROADPHASE_H
#define BP_BROADPHASE_H
#include "foundation/PxUnionCast.h"
#include "PxBroadPhase.h"
#include "BpAABBManager.h"
namespace physx
{
class PxcScratchAllocator;
namespace Bp
{
class BroadPhaseUpdateData;
/**
\brief Base broad phase class. Functions only relevant to MBP.
*/
class BroadPhaseBase
{
public:
BroadPhaseBase() {}
virtual ~BroadPhaseBase() {}
/**
\brief Gets broad-phase caps.
\param[out] caps Broad-phase caps
\return True if success
*/
virtual bool getCaps(PxBroadPhaseCaps& caps) const
{
caps.maxNbRegions = 0;
caps.maxNbObjects = 0;
caps.needsPredefinedBounds = false;
return true;
}
/**
\brief Returns number of regions currently registered in the broad-phase.
\return Number of regions
*/
virtual PxU32 getNbRegions() const
{
return 0;
}
/**
\brief Gets broad-phase regions.
\param[out] userBuffer Returned broad-phase regions
\param[in] bufferSize Size of userBuffer
\param[in] startIndex Index of first desired region, in [0 ; getNbRegions()[
\return Number of written out regions
*/
virtual PxU32 getRegions(PxBroadPhaseRegionInfo* userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const
{
PX_UNUSED(userBuffer);
PX_UNUSED(bufferSize);
PX_UNUSED(startIndex);
return 0;
}
/**
\brief Adds a new broad-phase region.
The bounds for the new region must be non-empty, otherwise an error occurs and the call is ignored.
The total number of regions is limited to 256. If that number is exceeded, the call is ignored.
The newly added region will be automatically populated with already existing SDK 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
- if a PxBroadPhaseCallback object is provided, an "out-of-bounds" event is generated via that callback
- if a PxBroadPhaseCallback object is not provided, a warning/error message is sent to the error stream
If an object goes out-of-bounds and user deletes it during the same frame, neither the out-of-bounds event nor the
error message is generated.
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[in] region User-provided region data
\param[in] populateRegion True to automatically populate the newly added region with existing objects touching it
\return Handle for newly created region, or 0xffffffff in case of failure.
*/
virtual PxU32 addRegion(const PxBroadPhaseRegion& region, bool populateRegion, const PxBounds3* boundsArray, const PxReal* contactDistance)
{
PX_UNUSED(region);
PX_UNUSED(populateRegion);
PX_UNUSED(boundsArray);
PX_UNUSED(contactDistance);
return 0xffffffff;
}
/**
\brief Removes a new 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[in] handle Region's handle, as returned by PxScene::addBroadPhaseRegion.
\return True if success
*/
virtual bool removeRegion(PxU32 handle)
{
PX_UNUSED(handle);
return false;
}
/*
\brief Return the number of objects that are not in any region.
*/
virtual PxU32 getNbOutOfBoundsObjects() const
{
return 0;
}
/*
\brief Return an array of objects that are not in any region.
*/
virtual const PxU32* getOutOfBoundsObjects() const
{
return NULL;
}
};
/*
\brief Structure used to report created and deleted broadphase pairs
\note The indices mVolA and mVolB correspond to the bounds indices
BroadPhaseUpdateData::mCreated used by BroadPhase::update
@see BroadPhase::getCreatedPairs, BroadPhase::getDeletedPairs
*/
struct BroadPhasePair
{
BroadPhasePair(ShapeHandle volA, ShapeHandle volB) :
mVolA (PxMin(volA, volB)),
mVolB (PxMax(volA, volB))
{
}
BroadPhasePair() :
mVolA (BP_INVALID_BP_HANDLE),
mVolB (BP_INVALID_BP_HANDLE)
{
}
ShapeHandle mVolA; // NB: mVolA < mVolB
ShapeHandle mVolB;
};
class BroadPhase : public BroadPhaseBase
{
public:
virtual PxBroadPhaseType::Enum getType() const = 0;
/**
\brief Instantiate a BroadPhase instance.
\param[in] bpType - the bp type (either mbp or sap). This is typically specified in PxSceneDesc.
\param[in] maxNbRegions is the expected maximum number of broad-phase regions.
\param[in] maxNbBroadPhaseOverlaps is the expected maximum number of broad-phase overlaps.
\param[in] maxNbStaticShapes is the expected maximum number of static shapes.
\param[in] maxNbDynamicShapes is the expected maximum number of dynamic shapes.
\param[in] contextID is the context ID parameter sent to the profiler
\return The instantiated BroadPhase.
\note maxNbRegions is only used if mbp is the chosen broadphase (PxBroadPhaseType::eMBP)
\note maxNbRegions, maxNbBroadPhaseOverlaps, maxNbStaticShapes and maxNbDynamicShapes are typically specified in PxSceneLimits
*/
static BroadPhase* create(
const PxBroadPhaseType::Enum bpType,
const PxU32 maxNbRegions,
const PxU32 maxNbBroadPhaseOverlaps,
const PxU32 maxNbStaticShapes,
const PxU32 maxNbDynamicShapes,
PxU64 contextID);
/**
\brief Shutdown of the broadphase.
*/
virtual void destroy() = 0;
/**
\brief Update the broadphase and compute the lists of created/deleted pairs.
\param[in] numCpuTasks the number of cpu tasks that can be used for the broadphase update.
\param[in] scratchAllocator - a PxcScratchAllocator instance used for temporary memory allocations.
This must be non-null.
\param[in] updateData a description of changes to the collection of aabbs since the last broadphase update.
The changes detail the indices of the bounds that have been added/updated/removed as well as an array of all
bound coordinates and an array of group ids used to filter pairs with the same id.
@see BroadPhaseUpdateData
\param[in] continuation the task that is in the queue to be executed immediately after the broadphase has completed its update. NULL is not supported.
\param[in] nPhaseUnlockTask this task will have its ref count decremented when it is safe to permit NP to run in parallel with BP. NULL is supported.
\note In PX_CHECKED and PX_DEBUG build configurations illegal input data (that does not conform to the BroadPhaseUpdateData specifications) triggers
a special code-path that entirely bypasses the broadphase and issues a warning message to the error stream. No guarantees can be made about the
correctness/consistency of broadphase behavior with illegal input data in PX_RELEASE and PX_PROFILE configs because validity checks are not active
in these builds.
*/
virtual void update(const PxU32 numCpuTasks, PxcScratchAllocator* scratchAllocator, const BroadPhaseUpdateData& updateData, physx::PxBaseTask* continuation, physx::PxBaseTask* nPhaseUnlockTask) = 0;
/**
\brief Fetch the results of any asynchronous broad phase work.
*/
virtual void fetchBroadPhaseResults(physx::PxBaseTask* nPhaseUnlockTask) = 0;
/*
\brief Return the number of created aabb overlap pairs computed in the execution of update() that has just completed.
*/
virtual PxU32 getNbCreatedPairs() const = 0;
/*
\brief Return the array of created aabb overlap pairs computed in the execution of update() that has just completed.
Note that each overlap pair is reported only on the frame when the overlap first occurs. The overlap persists
until the pair appears in the list of deleted pairs or either of the bounds in the pair is removed from the broadphase.
A created overlap must involve at least one of the bounds of the overlap pair appearing in either the created or updated list.
It is impossible for the same pair to appear simultaneously in the list of created and deleted overlap pairs.
An overlap is defined as a pair of bounds that overlap on all three axes; that is when maxA > minB and maxB > minA for all three axes.
The rule that minima(maxima) are even(odd) (see BroadPhaseUpdateData) removes the ambiguity of touching bounds.
*/
virtual BroadPhasePair* getCreatedPairs() = 0;
/**
\brief Return the number of deleted overlap pairs computed in the execution of update() that has just completed.
*/
virtual PxU32 getNbDeletedPairs() const = 0;
/**
\brief Return the number of deleted overlap pairs computed in the execution of update() that has just completed.
Note that a deleted pair can only be reported if that pair has already appeared in the list of created pairs in an earlier update.
A lost overlap occurs when a pair of bounds previously overlapped on all three axes but have now separated on at least one axis.
A lost overlap must involve at least one of the bounds of the lost overlap pair appearing in the updated list.
Lost overlaps arising from removal of bounds from the broadphase do not appear in the list of deleted pairs.
It is impossible for the same pair to appear simultaneously in the list of created and deleted pairs.
The test for overlap is conservative throughout, meaning that deleted pairs do not include touching pairs.
*/
virtual BroadPhasePair* getDeletedPairs() = 0;
/**
\brief After the broadphase has completed its update() function and the created/deleted pairs have been queried
with getCreatedPairs/getDeletedPairs it is desirable to free any memory that was temporarily acquired for the update but is
is no longer required post-update. This can be achieved with the function freeBuffers().
*/
virtual void freeBuffers() = 0;
/**
\brief Adjust internal structures after all bounds have been adjusted due to a scene origin shift.
*/
virtual void shiftOrigin(const PxVec3& shift, const PxBounds3* boundsArray, const PxReal* contactDistances) = 0;
/**
\brief Test that the created/updated/removed lists obey the rules that
1. object ids can only feature in the created list if they have never been previously added or if they were previously removed.
2. object ids can only be added to the updated list if they have been previously added without being removed.
3. objects ids can only be added to the removed list if they have been previously added without being removed.
*/
#if PX_CHECKED
virtual bool isValid(const BroadPhaseUpdateData& updateData) const = 0;
#endif
virtual BroadPhasePair* getBroadPhasePairs() const = 0;
virtual void deletePairs() = 0;
// PT: for unit-testing the non-GPU versions
virtual void singleThreadedUpdate(PxcScratchAllocator* /*scratchAllocator*/, const BroadPhaseUpdateData& /*updateData*/){}
};
} //namespace Bp
} //namespace physx
#endif //BP_BROADPHASE_H