29#ifndef GU_AABBTREEQUERY_H
30#define GU_AABBTREEQUERY_H
32#include "GuBVHTestsSIMD.h"
33#include "GuAABBTreeBounds.h"
34#include "foundation/PxInlineArray.h"
35#include "GuAABBTreeNode.h"
41#define RAW_TRAVERSAL_STACK_SIZE 256
45 static PX_FORCE_INLINE void getBoundsTimesTwo(Vec4V& center, Vec4V& extents,
const PxBounds3* bounds, PxU32 poolIndex)
47 const PxBounds3* objectBounds = bounds + poolIndex;
50 const Vec4V minV = V4LoadU(&objectBounds->minimum.x);
51 const Vec4V maxV = V4LoadU(&objectBounds->maximum.x);
53 center = V4Add(maxV, minV);
54 extents = V4Sub(maxV, minV);
59 template<const
bool tHasIndices,
typename Test,
typename Node,
typename QueryCallback>
60 static PX_FORCE_INLINE bool doOverlapLeafTest(
const Test& test,
const Node* node,
const PxBounds3* bounds,
const PxU32* indices, QueryCallback& visitor)
62 PxU32 nbPrims = node->getNbPrimitives();
63 const bool doBoxTest = nbPrims > 1;
64 const PxU32* prims = tHasIndices ? node->getPrimitives(indices) : NULL;
67 const PxU32 primIndex = tHasIndices ? *prims++ : node->getPrimitiveIndex();
70 Vec4V center2, extents2;
71 getBoundsTimesTwo(center2, extents2, bounds, primIndex);
73 const float half = 0.5f;
74 const FloatV halfV = FLoad(half);
76 const Vec4V extents_ = V4Scale(extents2, halfV);
77 const Vec4V center_ = V4Scale(center2, halfV);
79 if(!test(Vec3V_From_Vec4V(center_), Vec3V_From_Vec4V(extents_)))
83 if(!visitor.invoke(primIndex))
89 template<const
bool tHasIndices,
typename Test,
typename Tree,
typename Node,
typename QueryCallback>
93 bool operator()(
const AABBTreeBounds& treeBounds,
const Tree& tree,
const Test& test, QueryCallback& visitor)
95 const PxBounds3* bounds = treeBounds.getBounds();
98 stack.forceSize_Unsafe(RAW_TRAVERSAL_STACK_SIZE);
99 const Node*
const nodeBase = tree.getNodes();
101 PxU32 stackIndex = 1;
103 while(stackIndex > 0)
105 const Node* node = stack[--stackIndex];
106 Vec3V center, extents;
107 node->getAABBCenterExtentsV(¢er, &extents);
108 while(test(center, extents))
112 if(!doOverlapLeafTest<tHasIndices, Test, Node>(test, node, bounds, tree.getIndices(), visitor))
117 const Node* children = node->getPos(nodeBase);
120 stack[stackIndex++] = children + 1;
121 if(stackIndex == stack.capacity())
122 stack.resizeUninitialized(stack.capacity() * 2);
123 node->getAABBCenterExtentsV(¢er, &extents);
132 template <const
bool tInflate, const
bool tHasIndices,
typename Node,
typename QueryCallback>
135 PxU32 nbPrims = node->getNbPrimitives();
136 const bool doBoxTest = nbPrims > 1;
137 const PxU32* prims = tHasIndices ? node->getPrimitives(indices) : NULL;
140 const PxU32 primIndex = tHasIndices ? *prims++ : node->getPrimitiveIndex();
143 Vec4V center_, extents_;
144 getBoundsTimesTwo(center_, extents_, bounds, primIndex);
146 if(!test.check<tInflate>(Vec3V_From_Vec4V(center_), Vec3V_From_Vec4V(extents_)))
175 PxReal oldMaxDist = maxDist;
177 if(!pcb.invoke(md, primIndex))
183 test.setDistance(md);
191 template <const
bool tInflate, const
bool tHasIndices,
typename Tree,
typename Node,
typename QueryCallback>
197 const PxVec3& origin,
const PxVec3& unitDir, PxReal& maxDist,
const PxVec3& inflation,
200 const PxBounds3* bounds = treeBounds.getBounds();
204 Gu::RayAABBTest test(origin*2.0f, unitDir*2.0f, maxDist, inflation*2.0f);
207 stack.forceSize_Unsafe(RAW_TRAVERSAL_STACK_SIZE);
208 const Node*
const nodeBase = tree.getNodes();
210 PxU32 stackIndex = 1;
214 const Node* node = stack[stackIndex];
215 Vec3V center, extents;
216 node->getAABBCenterExtentsV2(¢er, &extents);
217 if(test.check<tInflate>(center, extents))
219 while(!node->isLeaf())
221 const Node* children = node->getPos(nodeBase);
224 children[0].getAABBCenterExtentsV2(&c0, &e0);
225 const PxU32 b0 = test.check<tInflate>(c0, e0);
228 children[1].getAABBCenterExtentsV2(&c1, &e1);
229 const PxU32 b1 = test.check<tInflate>(c1, e1);
234 const PxU32 bit = FAllGrtr(V3Dot(V3Sub(c1, c0), test.mDir), FZero()) & 1;
235 stack[stackIndex++] = children + bit;
236 node = children + (1 - bit);
237 if(stackIndex == stack.capacity())
238 stack.resizeUninitialized(stack.capacity() * 2);
248 if(!doLeafTest<tInflate, tHasIndices, Node>(node, test, bounds, tree.getIndices(), maxDist, pcb))
269 void traverseBVH(
const Gu::BVHNode* nodes, T& traversalController, PxI32 rootNodeIndex = 0)
271 PxI32 index = rootNodeIndex;
279 TraversalControl::Enum control = traversalController.analyze(a, index);
280 if (control == TraversalControl::eAbort)
282 if (!a.isLeaf() && (control == TraversalControl::eGoDeeper || control == TraversalControl::eGoDeeperNegFirst))
284 if (control == TraversalControl::eGoDeeperNegFirst)
286 todoStack.
pushBack(a.getPosIndex());
287 index = a.getNegIndex();
291 todoStack.
pushBack(a.getNegIndex());
292 index = a.getPosIndex();
296 if (todoStack.
empty())
break;
Definition GuAABBTreeBounds.h:39
Definition GuAABBTreeQuery.h:91
Definition GuAABBTreeQuery.h:193
PX_FORCE_INLINE bool empty() const
Definition PxArray.h:261
PX_FORCE_INLINE T & pushBack(const T &a)
Definition PxArray.h:296
PX_INLINE T popBack()
Definition PxArray.h:311
Class representing 3D range or axis aligned bounding box.
Definition PxBounds3.h:58
Definition PxInlineArray.h:43
3 Element vector class.
Definition PxVec3.h:50
#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
Definition GuAABBTreeNode.h:44
Definition GuBVHTestsSIMD.h:46
Definition GuAABBTreeQuery.h:259
Definition PxVecMathAoSScalar.h:77
Definition PxVecMathAoSScalar.h:65