// // 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_BROAD_PHASE_H #define PX_PHYSICS_BROAD_PHASE_H /** \addtogroup physics @{ */ #include "PxPhysXConfig.h" #include "foundation/PxBounds3.h" #if !PX_DOXYGEN namespace physx { #endif class PxActor; /** \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. */ struct PxBroadPhaseType { enum Enum { eSAP, //!< 3-axes sweep-and-prune eMBP, //!< Multi box pruning eABP, //!< Automatic box pruning eGPU, eLAST }; }; /** \brief Broad-phase callback to receive broad-phase related events. Each broadphase callback object is associated with a PxClientID. It is possible to register different callbacks for different clients. The callback functions are called this way: - for shapes/actors, the callback assigned to the actors' clients are used - for aggregates, the callbacks assigned to clients from aggregated actors are used \note SDK state should not be modified from within the callbacks. In particular objects should not be created or destroyed. If state modification is needed then the changes should be stored to a buffer and performed after the simulation step. Threading: It is not necessary to make this class thread safe as it will only be called in the context of the user thread. @see PxSceneDesc PxScene.setBroadPhaseCallback() PxScene.getBroadPhaseCallback() */ class PxBroadPhaseCallback { public: virtual ~PxBroadPhaseCallback() {} /** \brief Out-of-bounds notification. This function is called when an object leaves the broad-phase. \param[in] shape Shape that left the broad-phase bounds \param[in] actor Owner actor */ virtual void onObjectOutOfBounds(PxShape& shape, PxActor& actor) = 0; /** \brief Out-of-bounds notification. This function is called when an aggregate leaves the broad-phase. \param[in] aggregate Aggregate that left the broad-phase bounds */ virtual void onObjectOutOfBounds(PxAggregate& aggregate) = 0; }; /** \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::maxNbRegions. 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 bounds; //!< Region's bounds void* userData; //!< Region's user-provided data }; /** \brief Information & stats structure for a region */ struct PxBroadPhaseRegionInfo { PxBroadPhaseRegion region; //!< User-provided region data PxU32 nbStaticObjects; //!< Number of static objects in the region PxU32 nbDynamicObjects; //!< Number of dynamic objects in the region bool active; //!< True if region is currently used, i.e. it has not been removed bool overlap; //!< True if region overlaps other regions (regions that are just touching are not considering overlapping) }; /** \brief Caps class for broad phase. */ struct PxBroadPhaseCaps { PxU32 maxNbRegions; //!< Max number of regions supported by the broad-phase PxU32 maxNbObjects; //!< Max number of objects supported by the broad-phase bool needsPredefinedBounds; //!< If true, broad-phase needs 'regions' to work }; #if !PX_DOXYGEN } // namespace physx #endif /** @} */ #endif