RavEngine
Loading...
Searching...
No Matches
GuBVHTestsSIMD.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_BVH_TESTS_SIMD_H
30#define GU_BVH_TESTS_SIMD_H
31
32#include "foundation/PxTransform.h"
33#include "foundation/PxBounds3.h"
34#include "geometry/PxBoxGeometry.h"
35#include "geometry/PxSphereGeometry.h"
36#include "geometry/PxCapsuleGeometry.h"
37#include "foundation/PxVecMath.h"
38
39namespace physx
40{
41 using namespace aos;
42namespace Gu
43{
44
46{
47 PX_FORCE_INLINE RayAABBTest(const PxVec3& origin_, const PxVec3& unitDir_, const PxReal maxDist, const PxVec3& inflation_)
48 : mOrigin(V3LoadU(origin_))
49 , mDir(V3LoadU(unitDir_))
50 , mDirYZX(V3PermYZX(mDir))
51 , mInflation(V3LoadU(inflation_))
52 , mAbsDir(V3Abs(mDir))
53 , mAbsDirYZX(V3PermYZX(mAbsDir))
54 {
55 const PxVec3 ext = maxDist >= PX_MAX_F32 ? PxVec3( unitDir_.x == 0 ? origin_.x : PxSign(unitDir_.x)*PX_MAX_F32,
56 unitDir_.y == 0 ? origin_.y : PxSign(unitDir_.y)*PX_MAX_F32,
57 unitDir_.z == 0 ? origin_.z : PxSign(unitDir_.z)*PX_MAX_F32)
58 : origin_ + unitDir_ * maxDist;
59 mRayMin = V3Min(mOrigin, V3LoadU(ext));
60 mRayMax = V3Max(mOrigin, V3LoadU(ext));
61 }
62
63 PX_FORCE_INLINE void setDistance(PxReal distance)
64 {
65 const Vec3V ext = V3ScaleAdd(mDir, FLoad(distance), mOrigin);
66 mRayMin = V3Min(mOrigin, ext);
67 mRayMax = V3Max(mOrigin, ext);
68 }
69
70 template<bool TInflate>
71 PX_FORCE_INLINE PxU32 check(const Vec3V center, const Vec3V extents) const
72 {
73 const Vec3V iExt = TInflate ? V3Add(extents, mInflation) : extents;
74
75 // coordinate axes
76 const Vec3V nodeMax = V3Add(center, iExt);
77 const Vec3V nodeMin = V3Sub(center, iExt);
78
79 // cross axes
80 const Vec3V offset = V3Sub(mOrigin, center);
81 const Vec3V offsetYZX = V3PermYZX(offset);
82 const Vec3V iExtYZX = V3PermYZX(iExt);
83
84 const Vec3V f = V3NegMulSub(mDirYZX, offset, V3Mul(mDir, offsetYZX));
85 const Vec3V g = V3MulAdd(iExt, mAbsDirYZX, V3Mul(iExtYZX, mAbsDir));
86
87 const BoolV
88 maskA = V3IsGrtrOrEq(nodeMax, mRayMin),
89 maskB = V3IsGrtrOrEq(mRayMax, nodeMin),
90 maskC = V3IsGrtrOrEq(g, V3Abs(f));
91 const BoolV andABCMasks = BAnd(BAnd(maskA, maskB), maskC);
92
93 return BAllEqTTTT(andABCMasks);
94 }
95
96 const Vec3V mOrigin, mDir, mDirYZX, mInflation, mAbsDir, mAbsDirYZX;
97 Vec3V mRayMin, mRayMax;
98protected:
99 RayAABBTest& operator=(const RayAABBTest&);
100};
101
102// probably not worth having a SIMD version of this unless the traversal passes Vec3Vs
104{
106 : mCenter(V3LoadU(t.p))
107 , mExtents(V3LoadU(b.halfExtents))
108 { }
109
111 : mCenter(V3LoadU(b.getCenter()))
112 , mExtents(V3LoadU(b.getExtents()))
113 { }
114
115 PX_FORCE_INLINE PxIntBool operator()(const Vec3V center, const Vec3V extents) const
116 {
117 //PxVec3 c; PxVec3_From_Vec3V(center, c);
118 //PxVec3 e; PxVec3_From_Vec3V(extents, e);
119 //if(PxAbs(c.x - mCenter.x) > mExtents.x + e.x) return IntFalse;
120 //if(PxAbs(c.y - mCenter.y) > mExtents.y + e.y) return IntFalse;
121 //if(PxAbs(c.z - mCenter.z) > mExtents.z + e.z) return IntFalse;
122 //return IntTrue;
123 return PxIntBool(V3AllGrtrOrEq(V3Add(mExtents, extents), V3Abs(V3Sub(center, mCenter))));
124 }
125
126private:
127 AABBAABBTest& operator=(const AABBAABBTest&);
128 const Vec3V mCenter, mExtents;
129};
130
132{
134 : mCenter(V3LoadU(t.p))
135 , mRadius2(FLoad(s.radius * s.radius))
136 {}
137
138 PX_FORCE_INLINE SphereAABBTest(const PxVec3& center, PxF32 radius)
139 : mCenter(V3LoadU(center))
140 , mRadius2(FLoad(radius * radius))
141 {}
142
143 PX_FORCE_INLINE PxIntBool operator()(const Vec3V boxCenter, const Vec3V boxExtents) const
144 {
145 const Vec3V offset = V3Sub(mCenter, boxCenter);
146 const Vec3V closest = V3Clamp(offset, V3Neg(boxExtents), boxExtents);
147 const Vec3V d = V3Sub(offset, closest);
148 return PxIntBool(BAllEqTTTT(FIsGrtrOrEq(mRadius2, V3Dot(d, d))));
149 }
150
151private:
152 SphereAABBTest& operator=(const SphereAABBTest&);
153 const Vec3V mCenter;
154 const FloatV mRadius2;
155};
156
157// The Opcode capsule-AABB traversal test seems to be *exactly* the same as the ray-box test inflated by the capsule radius (so not a true capsule/box test)
158// and the code for the ray-box test is better. TODO: check the zero length case and use the sphere traversal if this one fails.
159// (OTOH it's not that hard to adapt the Ray-AABB test to a capsule test)
160
162{
163 PX_FORCE_INLINE CapsuleAABBTest(const PxVec3& origin, const PxVec3& unitDir, const PxReal length, const PxVec3& inflation)
164 : RayAABBTest(origin, unitDir, length, inflation)
165 {}
166
167 PX_FORCE_INLINE PxIntBool operator()(const Vec3VArg center, const Vec3VArg extents) const
168 {
169 return PxIntBool(RayAABBTest::check<true>(center, extents));
170 }
171};
172
173template<bool fullTest>
175{
176 OBBAABBTests(const PxVec3& pos, const PxMat33& rot, const PxVec3& halfExtentsInflated)
177 {
178 const Vec3V eps = V3Load(1e-6f);
179
180 mT = V3LoadU(pos);
181 mExtents = V3LoadU(halfExtentsInflated);
182
183 // storing the transpose matrices yields a simpler SIMD test
184 mRT = Mat33V_From_PxMat33(rot.getTranspose());
185 mART = Mat33V(V3Add(V3Abs(mRT.col0), eps), V3Add(V3Abs(mRT.col1), eps), V3Add(V3Abs(mRT.col2), eps));
186 mBB_xyz = M33TrnspsMulV3(mART, mExtents);
187
188 if(fullTest)
189 {
190 const Vec3V eYZX = V3PermYZX(mExtents), eZXY = V3PermZXY(mExtents);
191
192 mBB_123 = V3MulAdd(eYZX, V3PermZXY(mART.col0), V3Mul(eZXY, V3PermYZX(mART.col0)));
193 mBB_456 = V3MulAdd(eYZX, V3PermZXY(mART.col1), V3Mul(eZXY, V3PermYZX(mART.col1)));
194 mBB_789 = V3MulAdd(eYZX, V3PermZXY(mART.col2), V3Mul(eZXY, V3PermYZX(mART.col2)));
195 }
196 }
197
198 // TODO: force inline it?
199 PxIntBool operator()(const Vec3V center, const Vec3V extents) const
200 {
201 const Vec3V t = V3Sub(mT, center);
202
203 // class I - axes of AABB
204 if(V3OutOfBounds(t, V3Add(extents, mBB_xyz)))
205 return PxIntFalse;
206
207 const Vec3V rX = mRT.col0, rY = mRT.col1, rZ = mRT.col2;
208 const Vec3V arX = mART.col0, arY = mART.col1, arZ = mART.col2;
209
210 const FloatV eX = V3GetX(extents), eY = V3GetY(extents), eZ = V3GetZ(extents);
211 const FloatV tX = V3GetX(t), tY = V3GetY(t), tZ = V3GetZ(t);
212
213 // class II - axes of OBB
214 {
215 const Vec3V v = V3ScaleAdd(rZ, tZ, V3ScaleAdd(rY, tY, V3Scale(rX, tX)));
216 const Vec3V v2 = V3ScaleAdd(arZ, eZ, V3ScaleAdd(arY, eY, V3ScaleAdd(arX, eX, mExtents)));
217 if(V3OutOfBounds(v, v2))
218 return PxIntFalse;
219 }
220
221 if(!fullTest)
222 return PxIntTrue;
223
224 // class III - edge cross products. Almost all OBB tests early-out with type I or type II,
225 // so early-outs here probably aren't useful (TODO: profile)
226
227 const Vec3V va = V3NegScaleSub(rZ, tY, V3Scale(rY, tZ));
228 const Vec3V va2 = V3ScaleAdd(arY, eZ, V3ScaleAdd(arZ, eY, mBB_123));
229 const BoolV ba = BOr(V3IsGrtr(va, va2), V3IsGrtr(V3Neg(va2), va));
230
231 const Vec3V vb = V3NegScaleSub(rX, tZ, V3Scale(rZ, tX));
232 const Vec3V vb2 = V3ScaleAdd(arX, eZ, V3ScaleAdd(arZ, eX, mBB_456));
233 const BoolV bb = BOr(V3IsGrtr(vb, vb2), V3IsGrtr(V3Neg(vb2), vb));
234
235 const Vec3V vc = V3NegScaleSub(rY, tX, V3Scale(rX, tY));
236 const Vec3V vc2 = V3ScaleAdd(arX, eY, V3ScaleAdd(arY, eX, mBB_789));
237 const BoolV bc = BOr(V3IsGrtr(vc, vc2), V3IsGrtr(V3Neg(vc2), vc));
238
239 return PxIntBool(BAllEqFFFF(BOr(ba, BOr(bb,bc))));
240 }
241
242 Vec3V mExtents; // extents of OBB
243 Vec3V mT; // translation of OBB
244 Mat33V mRT; // transpose of rotation matrix of OBB
245 Mat33V mART; // transpose of mRT, padded by epsilon
246
247 Vec3V mBB_xyz; // extents of OBB along coordinate axes
248 Vec3V mBB_123; // projections of extents onto edge-cross axes
249 Vec3V mBB_456;
250 Vec3V mBB_789;
251};
252
254
255}
256}
257#endif
Class representing 3D range or axis aligned bounding box.
Definition PxBounds3.h:58
Class representing the geometry of a box.
Definition PxBoxGeometry.h:49
3x3 matrix class
Definition PxMat33.h:91
A class representing the geometry of a sphere.
Definition PxSphereGeometry.h:48
class representing a rigid euclidean transform as a quaternion and a vector
Definition PxTransform.h:49
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 GuBVHTestsSIMD.h:104
Definition GuBVHTestsSIMD.h:162
Definition GuBVHTestsSIMD.h:175
Definition GuBVHTestsSIMD.h:46
Definition GuBVHTestsSIMD.h:132
Definition PxVecMathAoSScalar.h:90
Definition PxVecMathAoSScalar.h:52
Definition PxVecMathAoSScalar.h:101
Definition PxVecMathAoSScalar.h:77