RavEngine
Loading...
Searching...
No Matches
GuAABBTree.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2008-2022 NVIDIA Corporation. All rights reserved.
26// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
27// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
28
29#ifndef GU_AABBTREE_H
30#define GU_AABBTREE_H
31
32#include "foundation/PxMemory.h"
33#include "foundation/PxArray.h"
34#include "foundation/PxBounds3.h"
35#include "foundation/PxUserAllocated.h"
36#include "common/PxPhysXCommonConfig.h"
37#include "GuPrunerTypedef.h"
38
39namespace physx
40{
41namespace Gu
42{
43 struct BVHNode;
44 struct SAH_Buffers;
45 class NodeAllocator;
46 struct BuildStats;
47 class AABBTreeBounds;
48
49 // PT: TODO: sometimes we export member functions, sometimes we export the whole class. What's the story here?
50
51#if PX_VC
52#pragma warning(push)
53#pragma warning( disable : 4251 ) // class needs to have dll-interface to be used by clients of class
54#endif
56 class PX_PHYSX_COMMON_API AABBTreeBuildParams : public PxUserAllocated
57 {
58 public:
59 AABBTreeBuildParams(PxU32 limit = 1, PxU32 nb_prims = 0, const AABBTreeBounds* bounds = NULL, BVHBuildStrategy bs = BVH_SPLATTER_POINTS) :
60 mLimit (limit),
61 mNbPrimitives (nb_prims),
62 mBounds (bounds),
63 mCache (NULL),
64 mBuildStrategy (bs)
65 {
66 }
68 {
69 reset();
70 }
71
72 PX_FORCE_INLINE void reset()
73 {
74 mLimit = mNbPrimitives = 0;
75 mBounds = NULL;
76 PX_FREE(mCache);
77 }
78
79 PxU32 mLimit;
82 mutable PxVec3* mCache;
83 BVHBuildStrategy mBuildStrategy;
84 };
85
87 class PX_PHYSX_COMMON_API AABBTreeBuildNode : public PxUserAllocated
88 {
89 public:
92
93 PX_FORCE_INLINE const PxBounds3& getAABB() const { return mBV; }
94 PX_FORCE_INLINE const AABBTreeBuildNode* getPos() const { return mPos; }
95 PX_FORCE_INLINE const AABBTreeBuildNode* getNeg() const { const AABBTreeBuildNode* P = mPos; return P ? P + 1 : NULL; }
96
97 PX_FORCE_INLINE bool isLeaf() const { return !getPos(); }
98
101
104
105 PX_FORCE_INLINE PxU32 getNbPrimitives() const { return mNbPrimitives; }
106
107 PX_FORCE_INLINE PxU32 getNbRuntimePrimitives() const { return mNbPrimitives; }
108 PX_FORCE_INLINE void setNbRunTimePrimitives(PxU32 val) { mNbPrimitives = val; }
109 PX_FORCE_INLINE const PxU32* getPrimitives(const PxU32* base) const { return base + mNodeIndex; }
110 PX_FORCE_INLINE PxU32* getPrimitives(PxU32* base) { return base + mNodeIndex; }
111
112 void subdivide(const AABBTreeBuildParams& params, BuildStats& stats, NodeAllocator& allocator, PxU32* const indices);
113 void subdivideSAH(const AABBTreeBuildParams& params, SAH_Buffers& sah, BuildStats& stats, NodeAllocator& allocator, PxU32* const indices);
114 void _buildHierarchy(const AABBTreeBuildParams& params, BuildStats& stats, NodeAllocator& allocator, PxU32* const indices);
115 void _buildHierarchySAH(const AABBTreeBuildParams& params, SAH_Buffers& sah, BuildStats& stats, NodeAllocator& allocator, PxU32* const indices);
116 };
117
124 class PX_PHYSX_COMMON_API NodeAllocator : public PxUserAllocated
125 {
126 public:
129
130 void release();
131 void init(PxU32 nbPrimitives, PxU32 limit);
132 AABBTreeBuildNode* getBiNode();
133
134 AABBTreeBuildNode* mPool;
135
136 struct Slab
137 {
139 PX_FORCE_INLINE Slab(AABBTreeBuildNode* pool, PxU32 nbUsedNodes, PxU32 maxNbNodes) : mPool(pool), mNbUsedNodes(nbUsedNodes), mMaxNbNodes(maxNbNodes) {}
140 AABBTreeBuildNode* mPool;
141 PxU32 mNbUsedNodes;
142 PxU32 mMaxNbNodes;
143 };
144 PxArray<Slab> mSlabs;
145 PxU32 mCurrentSlabIndex;
146 PxU32 mTotalNbNodes;
147 };
148#if PX_VC
149#pragma warning(pop)
150#endif
151
152 /*
153 * \brief Builds AABBtree from given parameters.
154 * \param params [in/out] AABBTree build params
155 * \param nodeAllocator [in/out] Node allocator
156 * \param stats [out] Statistics
157 * \return Indices buffer allocated during build, or NULL if failed
158 */
159 PX_PHYSX_COMMON_API PxU32* buildAABBTree(const AABBTreeBuildParams& params, NodeAllocator& nodeAllocator, BuildStats& stats);
160
161 // PT: TODO: explain how users should call these functions and maybe revisit this
162 PX_PHYSX_COMMON_API void flattenTree(const NodeAllocator& nodeAllocator, BVHNode* dest, const PxU32* remap = NULL);
163
164 PX_PHYSX_COMMON_API void buildAABBTree(PxU32 nbBounds, const AABBTreeBounds& bounds, PxArray<BVHNode>& tree);
165
166 PxU32 reshuffle(PxU32 nb, PxU32* const PX_RESTRICT prims, const PxVec3* PX_RESTRICT centers, float splitValue, PxU32 axis);
167
169 {
170 public:
171 BitArray() : mBits(NULL), mSize(0) {}
172 BitArray(PxU32 nb_bits) { init(nb_bits); }
173 ~BitArray() { PX_FREE(mBits); }
174
175 bool init(PxU32 nb_bits);
176
177 // Data management
178 PX_FORCE_INLINE void setBit(PxU32 bit_number)
179 {
180 mBits[bit_number>>5] |= 1<<(bit_number&31);
181 }
182 PX_FORCE_INLINE void clearBit(PxU32 bit_number)
183 {
184 mBits[bit_number>>5] &= ~(1<<(bit_number&31));
185 }
186 PX_FORCE_INLINE void toggleBit(PxU32 bit_number)
187 {
188 mBits[bit_number>>5] ^= 1<<(bit_number&31);
189 }
190
191 PX_FORCE_INLINE void clearAll() { PxMemZero(mBits, mSize*4); }
192 PX_FORCE_INLINE void setAll() { PxMemSet(mBits, 0xff, mSize*4); }
193
194 void resize(PxU32 maxBitNumber);
195
196 // Data access
197 PX_FORCE_INLINE PxIntBool isSet(PxU32 bit_number) const
198 {
199 return PxIntBool(mBits[bit_number>>5] & (1<<(bit_number&31)));
200 }
201
202 PX_FORCE_INLINE const PxU32* getBits() const { return mBits; }
203 PX_FORCE_INLINE PxU32 getSize() const { return mSize; }
204
205 protected:
206 PxU32* mBits;
207 PxU32 mSize;
208 };
209
212 {
213 public:
214 AABBTreeMergeData(PxU32 nbNodes, const BVHNode* nodes, PxU32 nbIndices, const PxU32* indices, PxU32 indicesOffset) :
215 mNbNodes(nbNodes), mNodes(nodes), mNbIndices(nbIndices), mIndices(indices), mIndicesOffset(indicesOffset)
216 {
217 }
218
220
221 PX_FORCE_INLINE const BVHNode& getRootNode() const { return *mNodes; }
222
223 public:
224 PxU32 mNbNodes;
226
228 const PxU32* mIndices;
229
231 };
232
233 // Progressive building
234 class FIFOStack;
235 //~Progressive building
236
237 // PT: base class used to share some data and code between Gu::AABBtree and Gu::BVH. This is WIP and subject to change.
238 // Design dictated by refactoring necessities rather than a grand vision of something.
240 {
241 public:
242 BVHCoreData() : mNbIndices(0), mNbNodes(0), mNodes(NULL), mIndices(NULL) {}
243
244 PX_FORCE_INLINE PxU32 getNbIndices() const { return mNbIndices; }
245 PX_FORCE_INLINE const PxU32* getIndices() const { return mIndices; }
246 PX_FORCE_INLINE PxU32* getIndices() { return mIndices; }
247 PX_FORCE_INLINE void setIndices(PxU32* indices) { mIndices = indices; }
248
249 PX_FORCE_INLINE PxU32 getNbNodes() const { return mNbNodes; }
250 PX_FORCE_INLINE const BVHNode* getNodes() const { return mNodes; }
251 PX_FORCE_INLINE BVHNode* getNodes() { return mNodes; }
252
253 PX_PHYSX_COMMON_API void fullRefit(const PxBounds3* boxes);
254
255 // PT: I'm leaving the above accessors here to avoid refactoring the SQ code using them, but members became public.
257 PxU32 mNbNodes;
259 PxU32* mIndices;
260 };
261
263 {
264 public:
265 PX_PHYSX_COMMON_API BVHPartialRefitData();
266 PX_PHYSX_COMMON_API ~BVHPartialRefitData();
267
268 PX_PHYSX_COMMON_API void releasePartialRefitData(bool clearRefitMap);
269 // adds node[index] to a list of nodes to refit when refitMarkedNodes is called
270 // Note that this includes updating the hierarchy up the chain
271 PX_PHYSX_COMMON_API void markNodeForRefit(TreeNodeIndex nodeIndex);
272 PX_PHYSX_COMMON_API void refitMarkedNodes(const PxBounds3* boxes);
273
274 PX_FORCE_INLINE PxU32* getUpdateMap() { return mUpdateMap; }
275
276 protected:
278 PxU32* mUpdateMap;
280 PxU32 mRefitHighestSetWord;
281
282 PxU32* getParentIndices();
283 public:
284 void createUpdateMap(PxU32 nbObjects);
285 };
286
288 // PT: TODO: each PX_PHYSX_COMMON_API is a cross-DLL call, should we split that class in Gu/Sq parts to minimize this?
290 {
291 public:
292 PX_PHYSX_COMMON_API AABBTree();
293 PX_PHYSX_COMMON_API ~AABBTree();
294 // Build
295 PX_PHYSX_COMMON_API bool build(const AABBTreeBuildParams& params, NodeAllocator& nodeAllocator);
296 // Progressive building
297 PX_PHYSX_COMMON_API PxU32 progressiveBuild(const AABBTreeBuildParams& params, NodeAllocator& nodeAllocator, BuildStats& stats, PxU32 progress, PxU32 limit);
298 //~Progressive building
299 PX_PHYSX_COMMON_API void release(bool clearRefitMap=true);
300
301 // Merge tree with another one
302 PX_PHYSX_COMMON_API void mergeTree(const AABBTreeMergeData& tree);
303 // Initialize tree from given merge data
304 PX_PHYSX_COMMON_API void initTree(const AABBTreeMergeData& tree);
305
306 // Data access
307 PX_FORCE_INLINE PxU32 getTotalPrims() const { return mTotalPrims; }
308
309 PX_PHYSX_COMMON_API void shiftOrigin(const PxVec3& shift);
310
311 // Shift indices of the tree by offset. Used for merged trees, when initial indices needs to be shifted to match indices in current pruning pool
312 PX_PHYSX_COMMON_API void shiftIndices(PxU32 offset);
313
314#if PX_DEBUG
315 void validate() {}
316#endif
317 private:
318 PxU32 mTotalPrims;
319 // Progressive building
320 FIFOStack* mStack;
321 //~Progressive building
322 bool buildInit(const AABBTreeBuildParams& params, NodeAllocator& nodeAllocator, BuildStats& stats);
323 void buildEnd(const AABBTreeBuildParams& params, NodeAllocator& nodeAllocator, const BuildStats& stats);
324 // tree merge
325 void mergeRuntimeNode(BVHNode& targetNode, const AABBTreeMergeData& tree, PxU32 targetNodeIndex);
326 void mergeRuntimeLeaf(BVHNode& targetNode, const AABBTreeMergeData& tree, PxU32 targetNodeIndex);
327 void addRuntimeChilds(PxU32& nodeIndex, const AABBTreeMergeData& tree);
328 void traverseRuntimeNode(BVHNode& targetNode, const AABBTreeMergeData& tree, PxU32 nodeIndex);
329 };
330} // namespace Gu
331}
332
333#endif // GU_AABBTREE_H
Definition GuAABBTree.cpp:491
Definition GuAABBTreeBounds.h:39
AABB tree node used for building.
Definition GuAABBTree.h:88
PxU32 mNodeIndex
Index of node-related primitives (in the tree's mIndices array)
Definition GuAABBTree.h:102
PxBounds3 mBV
Global bounding-volume enclosing all the node-related primitives.
Definition GuAABBTree.h:99
const AABBTreeBuildNode * mPos
"Positive" & "Negative" children
Definition GuAABBTree.h:100
PxU32 mNbPrimitives
Number of primitives for this node.
Definition GuAABBTree.h:103
Contains AABB-tree build parameters.
Definition GuAABBTree.h:57
PxVec3 * mCache
Cache for AABB centers - managed by build code.
Definition GuAABBTree.h:82
PxU32 mLimit
Limit number of primitives / node. If limit is 1, build a complete tree (2*N-1 nodes)
Definition GuAABBTree.h:79
PxU32 mNbPrimitives
Number of (source) primitives.
Definition GuAABBTree.h:80
const AABBTreeBounds * mBounds
Shortcut to an app-controlled array of AABBs.
Definition GuAABBTree.h:81
Contains AABB-tree merge parameters.
Definition GuAABBTree.h:212
PxU32 mNbNodes
Number of nodes of AABB tree merge.
Definition GuAABBTree.h:224
const PxU32 * mIndices
Indices of AABB tree merge.
Definition GuAABBTree.h:228
const BVHNode * mNodes
Nodes of AABB tree merge.
Definition GuAABBTree.h:225
PxU32 mNbIndices
Number of indices of AABB tree merge.
Definition GuAABBTree.h:227
PxU32 mIndicesOffset
Indices offset from pruning pool.
Definition GuAABBTree.h:230
AABB-tree, N primitives/leaf.
Definition GuAABBTree.h:290
Definition GuAABBTree.h:240
PxU32 mNbNodes
Number of nodes in the tree.
Definition GuAABBTree.h:257
PxU32 mNbIndices
Nb indices.
Definition GuAABBTree.h:256
BVHNode * mNodes
Linear pool of nodes.
Definition GuAABBTree.h:258
PxU32 * mIndices
Indices in the app list. Indices are reorganized during build (permutation).
Definition GuAABBTree.h:259
Definition GuAABBTree.h:263
BitArray mRefitBitmask
bit is set for each node index in markForRefit
Definition GuAABBTree.h:279
PxU32 * mParentIndices
PT: hot/cold split, keep parent data in separate array.
Definition GuAABBTree.h:277
PxU32 * mUpdateMap
PT: Local index to tree node index.
Definition GuAABBTree.h:278
Definition GuAABBTree.h:169
PxU32 * mBits
Array of bits.
Definition GuAABBTree.h:206
PxU32 mSize
Size of the array in dwords.
Definition GuAABBTree.h:207
Definition GuAABBTree.h:125
Definition PxArray.h:53
Class representing 3D range or axis aligned bounding box.
Definition PxBounds3.h:58
Definition PxUserAllocated.h:43
3 Element vector class.
Definition PxVec3.h:50
#define PX_RESTRICT
Definition PxPreprocessor.h:355
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
PX_FORCE_INLINE void * PxMemSet(void *dest, PxI32 c, PxU32 count)
Sets the bytes of the provided buffer to the specified value.
Definition PxMemory.h:67
PX_FORCE_INLINE void * PxMemZero(void *dest, PxU32 count)
Sets the bytes of the provided buffer to zero.
Definition PxMemory.h:53
Definition GuAABBTreeNode.h:44
Contains AABB-tree build statistics.
Definition GuAABBTreeBuildStats.h:40
Definition GuAABBTree.h:137