aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/GeomUtils/src/mesh/GuMidphaseInterface.h
blob: de3620193b0d6cb2ede8482ead2bdd6bd5f2c182 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
//
// 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-2018 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 GU_MIDPHASE_INTERFACE_H
#define GU_MIDPHASE_INTERFACE_H

#include "GuOverlapTests.h"
#include "GuRaycastTests.h"
#include "GuTriangleMesh.h"
#include "PsVecMath.h"

// PT: this file contains the common interface for all midphase implementations. Specifically the Midphase namespace contains the
// midphase-related entry points, dispatching calls to the proper implementations depending on the triangle mesh's type. The rest of it
// is simply classes & structs shared by all implementations.

namespace physx
{
	class PxMeshScale;
	class PxTriangleMeshGeometry;
namespace Cm
{
	class Matrix34;
	class FastVertex2ShapeScaling;
}

namespace Gu
{
	struct ConvexHullData;

	struct CallbackMode { enum Enum { eANY, eCLOSEST, eMULTIPLE }; };

	template<typename HitType>
	struct MeshHitCallback
	{
		CallbackMode::Enum mode;

		MeshHitCallback(CallbackMode::Enum aMode) : mode(aMode) {}

		PX_FORCE_INLINE	bool inAnyMode()		const { return mode == CallbackMode::eANY;		}
		PX_FORCE_INLINE	bool inClosestMode()	const { return mode == CallbackMode::eCLOSEST;	}
		PX_FORCE_INLINE	bool inMultipleMode()	const { return mode == CallbackMode::eMULTIPLE;	}

		virtual PxAgain processHit( // all reported coords are in mesh local space including hit.position
			const HitType& hit, const PxVec3& v0, const PxVec3& v1, const PxVec3& v2, PxReal& shrunkMaxT, const PxU32* vIndices) = 0;

		virtual ~MeshHitCallback() {}
	};

	struct SweepConvexMeshHitCallback;

	struct LimitedResults
	{
		PxU32*	mResults;
		PxU32	mNbResults;
		PxU32	mMaxResults;
		PxU32	mStartIndex;
		PxU32	mNbSkipped;
		bool	mOverflow;

		PX_FORCE_INLINE LimitedResults(PxU32* results, PxU32 maxResults, PxU32 startIndex)
			: mResults(results), mMaxResults(maxResults), mStartIndex(startIndex)
		{
			reset();
		}

		PX_FORCE_INLINE	void reset()
		{
			mNbResults	= 0;
			mNbSkipped	= 0;
			mOverflow	= false;
		}

		PX_FORCE_INLINE	bool add(PxU32 index)
		{
			if(mNbResults>=mMaxResults)
			{
				mOverflow = true;
				return false;
			}

			if(mNbSkipped>=mStartIndex)
				mResults[mNbResults++] = index;
			else
				mNbSkipped++;

			return true;
		}
	};

	// Exposing wrapper for Midphase::intersectOBB just for particles in order to avoid DelayLoad performance problem. This should be removed with particles in PhysX 3.5 (US16993)
	PX_PHYSX_COMMON_API void intersectOBB_Particles(const TriangleMesh* mesh, const Box& obb, MeshHitCallback<PxRaycastHit>& callback, bool bothTriangleSidesCollide, bool checkObbIsAligned = true);

	// RTree forward declarations
	PX_PHYSX_COMMON_API PxU32 raycast_triangleMesh_RTREE(const TriangleMesh* mesh, const PxTriangleMeshGeometry& meshGeom, const PxTransform& pose,
									const PxVec3& rayOrigin, const PxVec3& rayDir, PxReal maxDist,
									PxHitFlags hitFlags, PxU32 maxHits, PxRaycastHit* PX_RESTRICT hits);
	PX_PHYSX_COMMON_API bool intersectSphereVsMesh_RTREE(const Sphere& sphere,		const TriangleMesh& triMesh, const PxTransform& meshTransform, const PxMeshScale& meshScale, LimitedResults* results);
	PX_PHYSX_COMMON_API bool intersectBoxVsMesh_RTREE	(const Box& box,			const TriangleMesh& triMesh, const PxTransform& meshTransform, const PxMeshScale& meshScale, LimitedResults* results);
	PX_PHYSX_COMMON_API bool intersectCapsuleVsMesh_RTREE(const Capsule& capsule,	const TriangleMesh& triMesh, const PxTransform& meshTransform, const PxMeshScale& meshScale, LimitedResults* results);
	PX_PHYSX_COMMON_API void intersectOBB_RTREE(const TriangleMesh* mesh, const Box& obb, MeshHitCallback<PxRaycastHit>& callback, bool bothTriangleSidesCollide, bool checkObbIsAligned);
	PX_PHYSX_COMMON_API bool sweepCapsule_MeshGeom_RTREE(	const TriangleMesh* mesh, const PxTriangleMeshGeometry& triMeshGeom, const PxTransform& pose,
										const Gu::Capsule& lss, const PxVec3& unitDir, const PxReal distance,
										PxSweepHit& sweepHit, PxHitFlags hitFlags, const PxReal inflation);
	PX_PHYSX_COMMON_API bool sweepBox_MeshGeom_RTREE(	const TriangleMesh* mesh, const PxTriangleMeshGeometry& triMeshGeom, const PxTransform& pose,
									const Gu::Box& box, const PxVec3& unitDir, const PxReal distance,
									PxSweepHit& sweepHit, PxHitFlags hitFlags, const PxReal inflation);
	PX_PHYSX_COMMON_API void sweepConvex_MeshGeom_RTREE(const TriangleMesh* mesh, const Gu::Box& hullBox, const PxVec3& localDir, const PxReal distance, SweepConvexMeshHitCallback& callback, bool anyHit);

#if PX_INTEL_FAMILY
	// BV4 forward declarations
	PX_PHYSX_COMMON_API PxU32 raycast_triangleMesh_BV4(	const TriangleMesh* mesh, const PxTriangleMeshGeometry& meshGeom, const PxTransform& pose,
									const PxVec3& rayOrigin, const PxVec3& rayDir, PxReal maxDist,
									PxHitFlags hitFlags, PxU32 maxHits, PxRaycastHit* PX_RESTRICT hits);
	PX_PHYSX_COMMON_API bool intersectSphereVsMesh_BV4	(const Sphere& sphere,		const TriangleMesh& triMesh, const PxTransform& meshTransform, const PxMeshScale& meshScale, LimitedResults* results);
	PX_PHYSX_COMMON_API bool intersectBoxVsMesh_BV4		(const Box& box,			const TriangleMesh& triMesh, const PxTransform& meshTransform, const PxMeshScale& meshScale, LimitedResults* results);
	PX_PHYSX_COMMON_API bool intersectCapsuleVsMesh_BV4	(const Capsule& capsule,	const TriangleMesh& triMesh, const PxTransform& meshTransform, const PxMeshScale& meshScale, LimitedResults* results);
	PX_PHYSX_COMMON_API void intersectOBB_BV4(const TriangleMesh* mesh, const Box& obb, MeshHitCallback<PxRaycastHit>& callback, bool bothTriangleSidesCollide, bool checkObbIsAligned);
	PX_PHYSX_COMMON_API bool sweepCapsule_MeshGeom_BV4(	const TriangleMesh* mesh, const PxTriangleMeshGeometry& triMeshGeom, const PxTransform& pose,
									const Gu::Capsule& lss, const PxVec3& unitDir, const PxReal distance,
									PxSweepHit& sweepHit, PxHitFlags hitFlags, const PxReal inflation);
	PX_PHYSX_COMMON_API bool sweepBox_MeshGeom_BV4(	const TriangleMesh* mesh, const PxTriangleMeshGeometry& triMeshGeom, const PxTransform& pose,
								const Gu::Box& box, const PxVec3& unitDir, const PxReal distance,
								PxSweepHit& sweepHit, PxHitFlags hitFlags, const PxReal inflation);
	PX_PHYSX_COMMON_API void sweepConvex_MeshGeom_BV4(const TriangleMesh* mesh, const Gu::Box& hullBox, const PxVec3& localDir, const PxReal distance, SweepConvexMeshHitCallback& callback, bool anyHit);
#endif

	typedef PxU32 (*MidphaseRaycastFunction)(	const TriangleMesh* mesh, const PxTriangleMeshGeometry& meshGeom, const PxTransform& pose,
												const PxVec3& rayOrigin, const PxVec3& rayDir, PxReal maxDist,
												PxHitFlags hitFlags, PxU32 maxHits, PxRaycastHit* PX_RESTRICT hits);

	typedef bool (*MidphaseSphereOverlapFunction)	(const Sphere& sphere,		const TriangleMesh& triMesh, const PxTransform& meshTransform, const PxMeshScale& meshScale, LimitedResults* results);
	typedef bool (*MidphaseBoxOverlapFunction)		(const Box& box,			const TriangleMesh& triMesh, const PxTransform& meshTransform, const PxMeshScale& meshScale, LimitedResults* results);
	typedef bool (*MidphaseCapsuleOverlapFunction)	(const Capsule& capsule,	const TriangleMesh& triMesh, const PxTransform& meshTransform, const PxMeshScale& meshScale, LimitedResults* results);
	typedef void (*MidphaseBoxCBOverlapFunction)	(const TriangleMesh* mesh, const Box& obb, MeshHitCallback<PxRaycastHit>& callback, bool bothTriangleSidesCollide, bool checkObbIsAligned);

	typedef bool (*MidphaseCapsuleSweepFunction)(	const TriangleMesh* mesh, const PxTriangleMeshGeometry& triMeshGeom, const PxTransform& pose,
													const Gu::Capsule& lss, const PxVec3& unitDir, const PxReal distance,
													PxSweepHit& sweepHit, PxHitFlags hitFlags, const PxReal inflation);
	typedef bool (*MidphaseBoxSweepFunction)(		const TriangleMesh* mesh, const PxTriangleMeshGeometry& triMeshGeom, const PxTransform& pose,
													const Gu::Box& box, const PxVec3& unitDir, const PxReal distance,
													PxSweepHit& sweepHit, PxHitFlags hitFlags, const PxReal inflation);
	typedef void (*MidphaseConvexSweepFunction)(	const TriangleMesh* mesh, const Gu::Box& hullBox, const PxVec3& localDir, const PxReal distance, SweepConvexMeshHitCallback& callback, bool anyHit);

namespace Midphase
{
	PX_FORCE_INLINE bool outputError()
	{
		static bool reportOnlyOnce = false;
		if(!reportOnlyOnce)
		{
			reportOnlyOnce = true;
			Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "BV4 midphase only supported on Intel platforms.");
		}
		return false;
	}
}

	#if PX_INTEL_FAMILY && !defined(PX_SIMD_DISABLED)
	#else
	static PxU32 unsupportedMidphase(	const TriangleMesh*, const PxTriangleMeshGeometry&, const PxTransform&,
										const PxVec3&, const PxVec3&, PxReal,
										PxHitFlags, PxU32, PxRaycastHit* PX_RESTRICT)
	{
		return PxU32(Midphase::outputError());
	}
	static bool unsupportedSphereOverlapMidphase(const Sphere&, const TriangleMesh&, const PxTransform&, const PxMeshScale&, LimitedResults*)
	{
		return Midphase::outputError();
	}
	static bool unsupportedBoxOverlapMidphase(const Box&, const TriangleMesh&, const PxTransform&, const PxMeshScale&, LimitedResults*)
	{
		return Midphase::outputError();
	}
	static bool unsupportedCapsuleOverlapMidphase(const Capsule&, const TriangleMesh&, const PxTransform&, const PxMeshScale&, LimitedResults*)
	{
		return Midphase::outputError();
	}
	static void unsupportedBoxCBOverlapMidphase(const TriangleMesh*, const Box&, MeshHitCallback<PxRaycastHit>&, bool, bool)
	{
		Midphase::outputError();
	}
	static bool unsupportedBoxSweepMidphase(const TriangleMesh*, const PxTriangleMeshGeometry&, const PxTransform&, const Gu::Box&, const PxVec3&, const PxReal, PxSweepHit&, PxHitFlags, const PxReal)
	{
		return Midphase::outputError();
	}
	static bool unsupportedCapsuleSweepMidphase(const TriangleMesh*, const PxTriangleMeshGeometry&, const PxTransform&, const Gu::Capsule&, const PxVec3&, const PxReal, PxSweepHit&, PxHitFlags, const PxReal)
	{
		return Midphase::outputError();
	}
	static void unsupportedConvexSweepMidphase(const TriangleMesh*, const Gu::Box&, const PxVec3&, const PxReal, SweepConvexMeshHitCallback&, bool)
	{
		Midphase::outputError();
	}
	#endif

	static const MidphaseRaycastFunction	gMidphaseRaycastTable[PxMeshMidPhase::eLAST] =
	{
		raycast_triangleMesh_RTREE,
	#if PX_INTEL_FAMILY && !defined(PX_SIMD_DISABLED)
		raycast_triangleMesh_BV4,
	#else
		unsupportedMidphase,
	#endif
	};

	static const MidphaseSphereOverlapFunction gMidphaseSphereOverlapTable[PxMeshMidPhase::eLAST] =
	{
		intersectSphereVsMesh_RTREE,
	#if PX_INTEL_FAMILY && !defined(PX_SIMD_DISABLED)
		intersectSphereVsMesh_BV4,
	#else
		unsupportedSphereOverlapMidphase,
	#endif
	};

	static const MidphaseBoxOverlapFunction gMidphaseBoxOverlapTable[PxMeshMidPhase::eLAST] =
	{
		intersectBoxVsMesh_RTREE,
	#if PX_INTEL_FAMILY && !defined(PX_SIMD_DISABLED)
		intersectBoxVsMesh_BV4,
	#else
		unsupportedBoxOverlapMidphase,
	#endif
	};

	static const MidphaseCapsuleOverlapFunction gMidphaseCapsuleOverlapTable[PxMeshMidPhase::eLAST] =
	{
		intersectCapsuleVsMesh_RTREE,
	#if PX_INTEL_FAMILY && !defined(PX_SIMD_DISABLED)
		intersectCapsuleVsMesh_BV4,
	#else
		unsupportedCapsuleOverlapMidphase,
	#endif
	};

	static const MidphaseBoxCBOverlapFunction gMidphaseBoxCBOverlapTable[PxMeshMidPhase::eLAST] =
	{
		intersectOBB_RTREE,
	#if PX_INTEL_FAMILY && !defined(PX_SIMD_DISABLED)
		intersectOBB_BV4,
	#else
		unsupportedBoxCBOverlapMidphase,
	#endif
	};

	static const MidphaseBoxSweepFunction gMidphaseBoxSweepTable[PxMeshMidPhase::eLAST] =
	{
		sweepBox_MeshGeom_RTREE,
	#if PX_INTEL_FAMILY && !defined(PX_SIMD_DISABLED)
		sweepBox_MeshGeom_BV4,
	#else
		unsupportedBoxSweepMidphase,
	#endif
	};

	static const MidphaseCapsuleSweepFunction gMidphaseCapsuleSweepTable[PxMeshMidPhase::eLAST] =
	{
		sweepCapsule_MeshGeom_RTREE,
	#if PX_INTEL_FAMILY && !defined(PX_SIMD_DISABLED)
		sweepCapsule_MeshGeom_BV4,
	#else
		unsupportedCapsuleSweepMidphase,
	#endif
	};

	static const MidphaseConvexSweepFunction gMidphaseConvexSweepTable[PxMeshMidPhase::eLAST] =
	{
		sweepConvex_MeshGeom_RTREE,
	#if PX_INTEL_FAMILY && !defined(PX_SIMD_DISABLED)
		sweepConvex_MeshGeom_BV4,
	#else
		unsupportedConvexSweepMidphase,
	#endif
	};

namespace Midphase
{
	// \param[in]	mesh			triangle mesh to raycast against
	// \param[in]	meshGeom		geometry object associated with the mesh
	// \param[in]	meshTransform	pose/transform of geometry object
	// \param[in]	rayOrigin		ray's origin
	// \param[in]	rayDir			ray's unit dir
	// \param[in]	maxDist			ray's length/max distance
	// \param[in]	hitFlags		query behavior flags
	// \param[in]	maxHits			max number of hits = size of 'hits' buffer
	// \param[out]	hits			result buffer where to write raycast hits
	// \return		number of hits written to 'hits' result buffer
	// \note		there's no mechanism to report overflow. Returned number of hits is just clamped to maxHits.
	PX_FORCE_INLINE PxU32 raycastTriangleMesh(	const TriangleMesh* mesh, const PxTriangleMeshGeometry& meshGeom, const PxTransform& meshTransform,
												const PxVec3& rayOrigin, const PxVec3& rayDir, PxReal maxDist,
												PxHitFlags hitFlags, PxU32 maxHits, PxRaycastHit* PX_RESTRICT hits)
	{
		const PxU32 index = PxU32(mesh->getConcreteType() - PxConcreteType::eTRIANGLE_MESH_BVH33);
		return gMidphaseRaycastTable[index](mesh, meshGeom, meshTransform, rayOrigin, rayDir, maxDist, hitFlags, maxHits, hits);
	}

	// \param[in]	sphere			sphere
	// \param[in]	mesh			triangle mesh
	// \param[in]	meshTransform	pose/transform of triangle mesh
	// \param[in]	meshScale		mesh scale
	// \param[out]	results			results object if multiple hits are needed, NULL if a simple boolean answer is enough
	// \return 		true if at least one overlap has been found
	PX_FORCE_INLINE bool intersectSphereVsMesh(const Sphere& sphere, const TriangleMesh& mesh, const PxTransform& meshTransform, const PxMeshScale& meshScale, LimitedResults* results)
	{
		const PxU32 index = PxU32(mesh.getConcreteType() - PxConcreteType::eTRIANGLE_MESH_BVH33);
		return gMidphaseSphereOverlapTable[index](sphere, mesh, meshTransform, meshScale, results);
	}

	// \param[in]	box				box
	// \param[in]	mesh			triangle mesh
	// \param[in]	meshTransform	pose/transform of triangle mesh
	// \param[in]	meshScale		mesh scale
	// \param[out]	results			results object if multiple hits are needed, NULL if a simple boolean answer is enough
	// \return 		true if at least one overlap has been found
	PX_FORCE_INLINE bool intersectBoxVsMesh(const Box& box, const TriangleMesh& mesh, const PxTransform& meshTransform, const PxMeshScale& meshScale, LimitedResults* results)
	{
		const PxU32 index = PxU32(mesh.getConcreteType() - PxConcreteType::eTRIANGLE_MESH_BVH33);
		return gMidphaseBoxOverlapTable[index](box, mesh, meshTransform, meshScale, results);
	}

	// \param[in]	capsule			capsule
	// \param[in]	mesh			triangle mesh
	// \param[in]	meshTransform	pose/transform of triangle mesh
	// \param[in]	meshScale		mesh scale
	// \param[out]	results			results object if multiple hits are needed, NULL if a simple boolean answer is enough
	// \return 		true if at least one overlap has been found
	PX_FORCE_INLINE bool intersectCapsuleVsMesh(const Capsule& capsule, const TriangleMesh& mesh, const PxTransform& meshTransform, const PxMeshScale& meshScale, LimitedResults* results)
	{
		const PxU32 index = PxU32(mesh.getConcreteType() - PxConcreteType::eTRIANGLE_MESH_BVH33);
		return gMidphaseCapsuleOverlapTable[index](capsule, mesh, meshTransform, meshScale, results);
	}

	// \param[in]	mesh						triangle mesh
	// \param[in]	box							box
	// \param[in]	callback					callback object, called each time a hit is found
	// \param[in]	bothTriangleSidesCollide	true for double-sided meshes
	// \param[in]	checkObbIsAligned			true to use a dedicated codepath for axis-aligned boxes
	PX_FORCE_INLINE void intersectOBB(const TriangleMesh* mesh, const Box& obb, MeshHitCallback<PxRaycastHit>& callback, bool bothTriangleSidesCollide, bool checkObbIsAligned = true)
	{
		const PxU32 index = PxU32(mesh->getConcreteType() - PxConcreteType::eTRIANGLE_MESH_BVH33);
		gMidphaseBoxCBOverlapTable[index](mesh, obb, callback, bothTriangleSidesCollide, checkObbIsAligned);
	}

	// \param[in]	mesh			triangle mesh
	// \param[in]	meshGeom		geometry object associated with the mesh
	// \param[in]	meshTransform	pose/transform of geometry object
	// \param[in]	capsule			swept capsule
	// \param[in]	unitDir			sweep's unit dir
	// \param[in]	distance		sweep's length/max distance
	// \param[out]	sweepHit		hit result
	// \param[in]	hitFlags		query behavior flags
	// \param[in]	inflation		optional inflation value for swept shape
	// \return		true if a hit was found, false otherwise
	PX_FORCE_INLINE bool sweepCapsuleVsMesh(const TriangleMesh* mesh, const PxTriangleMeshGeometry& meshGeom, const PxTransform& meshTransform,
											const Gu::Capsule& capsule, const PxVec3& unitDir, const PxReal distance,
											PxSweepHit& sweepHit, PxHitFlags hitFlags, const PxReal inflation)
	{
		const PxU32 index = PxU32(mesh->getConcreteType() - PxConcreteType::eTRIANGLE_MESH_BVH33);
		return gMidphaseCapsuleSweepTable[index](mesh, meshGeom, meshTransform, capsule, unitDir, distance, sweepHit, hitFlags, inflation);
	}

	// \param[in]	mesh			triangle mesh
	// \param[in]	meshGeom		geometry object associated with the mesh
	// \param[in]	meshTransform	pose/transform of geometry object
	// \param[in]	box				swept box
	// \param[in]	unitDir			sweep's unit dir
	// \param[in]	distance		sweep's length/max distance
	// \param[out]	sweepHit		hit result
	// \param[in]	hitFlags		query behavior flags
	// \param[in]	inflation		optional inflation value for swept shape
	// \return		true if a hit was found, false otherwise
	PX_FORCE_INLINE bool sweepBoxVsMesh(const TriangleMesh* mesh, const PxTriangleMeshGeometry& meshGeom, const PxTransform& meshTransform,
										const Gu::Box& box, const PxVec3& unitDir, const PxReal distance,
										PxSweepHit& sweepHit, PxHitFlags hitFlags, const PxReal inflation)
	{
		const PxU32 index = PxU32(mesh->getConcreteType() - PxConcreteType::eTRIANGLE_MESH_BVH33);
		return gMidphaseBoxSweepTable[index](mesh, meshGeom, meshTransform, box, unitDir, distance, sweepHit, hitFlags, inflation);
	}

	// \param[in]	mesh			triangle mesh
	// \param[in]	hullBox			hull's bounding box
	// \param[in]	localDir		sweep's unit dir, in local/mesh space
	// \param[in]	distance		sweep's length/max distance
	// \param[in]	callback		callback object, called each time a hit is found
	// \param[in]	anyHit			true for PxHitFlag::eMESH_ANY queries
	PX_FORCE_INLINE void sweepConvexVsMesh(const TriangleMesh* mesh, const Gu::Box& hullBox, const PxVec3& localDir, const PxReal distance, SweepConvexMeshHitCallback& callback, bool anyHit)
	{
		const PxU32 index = PxU32(mesh->getConcreteType() - PxConcreteType::eTRIANGLE_MESH_BVH33);
		gMidphaseConvexSweepTable[index](mesh, hullBox, localDir, distance, callback, anyHit);
	}
}
}
}
#endif	// GU_MIDPHASE_INTERFACE_H