aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/GeomUtils/src/mesh/GuBV4_OBBSweep.cpp
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Source/GeomUtils/src/mesh/GuBV4_OBBSweep.cpp
downloadphysx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz
physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip
Initial commit:
PhysX 3.4.0 Update @ 21294896 APEX 1.4.0 Update @ 21275617 [CL 21300167]
Diffstat (limited to 'PhysX_3.4/Source/GeomUtils/src/mesh/GuBV4_OBBSweep.cpp')
-rw-r--r--PhysX_3.4/Source/GeomUtils/src/mesh/GuBV4_OBBSweep.cpp170
1 files changed, 170 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/GeomUtils/src/mesh/GuBV4_OBBSweep.cpp b/PhysX_3.4/Source/GeomUtils/src/mesh/GuBV4_OBBSweep.cpp
new file mode 100644
index 00000000..c578b359
--- /dev/null
+++ b/PhysX_3.4/Source/GeomUtils/src/mesh/GuBV4_OBBSweep.cpp
@@ -0,0 +1,170 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include "GuBV4.h"
+using namespace physx;
+using namespace Gu;
+
+#if PX_INTEL_FAMILY
+#include "PsVecMath.h"
+using namespace physx::shdfnd::aos;
+#include "GuBV4_BoxSweep_Internal.h"
+
+Ps::IntBool Sweep_AABB_BV4(const Box& localBox, const PxVec3& localDir, float maxDist, const BV4Tree& tree, SweepHit* PX_RESTRICT hit, PxU32 flags);
+void GenericSweep_AABB_CB(const Box& localBox, const PxVec3& localDir, float maxDist, const BV4Tree& tree, MeshSweepCallback callback, void* userData, PxU32 flags);
+void Sweep_AABB_BV4_CB(const Box& localBox, const PxVec3& localDir, float maxDist, const BV4Tree& tree, const PxMat44* PX_RESTRICT worldm_Aligned, SweepUnlimitedCallback callback, void* userData, PxU32 flags, bool nodeSorting);
+
+// PT: TODO: optimize this (TA34704)
+static PX_FORCE_INLINE void computeLocalData(Box& localBox, PxVec3& localDir, const Box& box, const PxVec3& dir, const PxMat44* PX_RESTRICT worldm_Aligned)
+{
+ if(worldm_Aligned)
+ {
+ PxMat44 IWM;
+ invertPRMatrix(&IWM, worldm_Aligned);
+
+ localDir = IWM.rotate(dir);
+
+ rotateBox(localBox, IWM, box);
+ }
+ else
+ {
+ localDir = dir;
+ localBox = box; // PT: TODO: check asm for operator= (TA34704)
+ }
+}
+
+static PX_FORCE_INLINE bool isAxisAligned(const PxVec3& axis)
+{
+ const PxReal minLimit = 1e-3f;
+ const PxReal maxLimit = 1.0f - 1e-3f;
+
+ const PxReal absX = PxAbs(axis.x);
+ if(absX>minLimit && absX<maxLimit)
+ return false;
+
+ const PxReal absY = PxAbs(axis.y);
+ if(absY>minLimit && absY<maxLimit)
+ return false;
+
+ const PxReal absZ = PxAbs(axis.z);
+ if(absZ>minLimit && absZ<maxLimit)
+ return false;
+
+ return true;
+}
+
+static PX_FORCE_INLINE bool isAABB(const Box& box)
+{
+ if(!isAxisAligned(box.rot.column0))
+ return false;
+ if(!isAxisAligned(box.rot.column1))
+ return false;
+ if(!isAxisAligned(box.rot.column2))
+ return false;
+ return true;
+}
+
+Ps::IntBool BV4_BoxSweepSingle(const Box& box, const PxVec3& dir, float maxDist, const BV4Tree& tree, const PxMat44* PX_RESTRICT worldm_Aligned, SweepHit* PX_RESTRICT hit, PxU32 flags)
+{
+ Box localBox;
+ PxVec3 localDir;
+ computeLocalData(localBox, localDir, box, dir, worldm_Aligned);
+
+ Ps::IntBool Status;
+ if(isAABB(localBox))
+ Status = Sweep_AABB_BV4(localBox, localDir, maxDist, tree, hit, flags);
+ else
+ Status = Sweep_OBB_BV4(localBox, localDir, maxDist, tree, hit, flags);
+ if(Status && worldm_Aligned)
+ {
+ // Move to world space
+ // PT: TODO: optimize (TA34704)
+ hit->mPos = worldm_Aligned->transform(hit->mPos);
+ hit->mNormal = worldm_Aligned->rotate(hit->mNormal);
+ }
+ return Status;
+}
+
+// PT: for design decisions in this function, refer to the comments of BV4_GenericSweepCB().
+void BV4_BoxSweepCB(const Box& box, const PxVec3& dir, float maxDist, const BV4Tree& tree, const PxMat44* PX_RESTRICT worldm_Aligned, SweepUnlimitedCallback callback, void* userData, PxU32 flags, bool nodeSorting)
+{
+ Box localBox;
+ PxVec3 localDir;
+ computeLocalData(localBox, localDir, box, dir, worldm_Aligned);
+
+ if(isAABB(localBox))
+ Sweep_AABB_BV4_CB(localBox, localDir, maxDist, tree, worldm_Aligned, callback, userData, flags, nodeSorting);
+ else
+ Sweep_OBB_BV4_CB(localBox, localDir, maxDist, tree, worldm_Aligned, callback, userData, flags, nodeSorting);
+}
+
+
+// PT: this generic sweep uses an OBB because this is the most versatile volume, but it does not mean this function is
+// a "box sweep function" per-se. In fact it could be used all alone to implement all sweeps in the SDK (but that would
+// have an impact on performance).
+//
+// So the idea here is simply to provide and use a generic function for everything that the BV4 code does not support directly.
+// In particular this should be used:
+// - for convex sweeps (where the OBB is the box around the swept convex)
+// - for non-trivial sphere/capsule/box sweeps where mesh scaling or inflation
+//
+// By design we don't do leaf tests inside the BV4 traversal code here (because we don't support them, e.g. convex
+// sweeps. If we could do them inside the BV4 traversal code, like we do for regular sweeps, then this would not be a generic
+// sweep function, but instead a built-in, natively supported query). So the leaf tests are performed outside of BV4, in the
+// client code, through MeshSweepCallback. This has a direct impact on the design & parameters of MeshSweepCallback.
+//
+// On the other hand this is used for "regular sweeps with shapes we don't natively support", i.e. SweepSingle kind of queries.
+// This means that we need to support an early-exit codepath (without node-sorting) and a regular sweep single codepath (with
+// node sorting) for this generic function. The leaf tests are external, but everything traversal-related should be exactly the
+// same as the regular box-sweep function otherwise.
+//
+// As a consequence, this function is not well-suited to implement "unlimited results" kind of queries, a.k.a. "sweep all":
+//
+// - for regular sphere/capsule/box "sweep all" queries, the leaf tests should be internal (same as sweep single queries). This
+// means the existing MeshSweepCallback can't be reused.
+//
+// - there is no need to support "sweep any" (it is already supported by the other sweep functions).
+//
+// - there may be no need for ordered traversal/node sorting/ray shrinking, since we want to return all results anyway. But this
+// may not be true if the "sweep all" function is used to emulate the Epic Tweak. In that case we still want to shrink the ray
+// and use node sorting. Since both versions are useful, we should probably have a bool param to enable/disable node sorting.
+//
+// - we are interested in all hits so we can't delay the computation of impact data (computing it only once in the end, for the
+// closest hit). We actually need to compute the data for all hits, possibly within the traversal code.
+void BV4_GenericSweepCB(const Box& localBox, const PxVec3& localDir, float maxDist, const BV4Tree& tree, MeshSweepCallback callback, void* userData, bool anyHit)
+{
+ const PxU32 flags = anyHit ? PxU32(QUERY_MODIFIER_ANY_HIT) : 0;
+
+ if(isAABB(localBox))
+ GenericSweep_AABB_CB(localBox, localDir, maxDist, tree, callback, userData, flags);
+ else
+ GenericSweep_OBB_CB(localBox, localDir, maxDist, tree, callback, userData, flags);
+}
+
+#endif