1/*
2 * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
3 *
4 * NVIDIA CORPORATION and its licensors retain all intellectual property
5 * and proprietary rights in and to this software, related documentation
6 * and any modifications thereto. Any use, reproduction, disclosure or
7 * distribution of this software and related documentation without an express
8 * license agreement from NVIDIA CORPORATION is strictly prohibited.
9 */
10// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
11// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
12
13
14#ifndef PX_PHYSICS_NX_SCENEQUERYREPORT
15#define PX_PHYSICS_NX_SCENEQUERYREPORT
16/** \addtogroup scenequery
17@{
18*/
19#include "PxPhysXConfig.h"
20#include "foundation/PxVec3.h"
21#include "foundation/PxFlags.h"
22
23#ifndef PX_DOXYGEN
24namespace physx
25{
26#endif
27
28class PxShape;
29class PxRigidActor;
30
31/**
32\brief Scene query and geometry query behavior flags.
33
34PxHitFlags are used for 3 different purposes:
35
361) To request hit fields to be filled in by scene queries (such as hit position, normal, distance or UVs).
372) Once query is completed, to indicate which fields are valid (note that a query may produce more valid fields than requested).
383) To specify additional options for the narrow phase and mid-phase intersection routines.
39
40All these flags apply to both scene queries and geometry queries (PxGeometryQuery).
41
42@see PxRaycastHit PxSweepHit PxOverlapHit PxScene.raycast PxScene.sweep PxScene.overlap PxGeometryQuery
43*/
44struct PxHitFlag
45{
46 enum Enum
47 {
48 ePOSITION = (1<<0), //!< "position" member of #PxQueryHit is valid
49 eIMPACT = ePOSITION,//!< \deprecated Deprecated alias PX_DEPRECATED
50 eNORMAL = (1<<1), //!< "normal" member of #PxQueryHit is valid
51 eDISTANCE = (1<<2), //!< "distance" member of #PxQueryHit is valid
52 eUV = (1<<3), //!< "u" and "v" barycentric coordinates of #PxQueryHit are valid. Not applicable to sweep queries.
53 eASSUME_NO_INITIAL_OVERLAP = (1<<4), //!< Performance hint flag for sweeps when it is known upfront there's no initial overlap.
54 //!< NOTE: using this flag may cause undefined results if shapes are initially overlapping.
55 eMESH_MULTIPLE = (1<<5), //!< Report all hits for meshes rather than just the first. Not applicable to sweep queries.
56 //!< On SPU the number of reported hits per mesh is limited to 16 in no specific order.
57 eMESH_ANY = (1<<6), //!< Report any first hit for meshes. If neither eMESH_MULTIPLE nor eMESH_ANY is specified,
58 //!< a single closest hit will be reported for meshes.
59 eMESH_BOTH_SIDES = (1<<7), //!< Report hits with back faces of mesh triangles. Also report hits for raycast
60 //!< originating on mesh surface and facing away from the surface normal. Not applicable to sweep queries.
61 //!< Please refer to the user guide for heightfield-specific differences.
62 ePRECISE_SWEEP = (1<<8), //!< Use more accurate but slower narrow phase sweep tests.
63 //!< May provide better compatibility with PhysX 3.2 sweep behavior. Ignored on SPU.
64 eMTD = (1<<9), //!< Report the minimum translation depth, normal and contact point. Ignored on SPU.
65 eDIRECT_SWEEP = ePRECISE_SWEEP, //!< \deprecated Deprecated alias. PX_DEPRECATED
66
67 eDEFAULT = ePOSITION|eNORMAL|eDISTANCE,
68
69 /** \brief Only this subset of flags can be modified by pre-filter. Other modifications will be discarded. */
70 eMODIFIABLE_FLAGS = eMESH_MULTIPLE|eMESH_BOTH_SIDES|eASSUME_NO_INITIAL_OVERLAP|ePRECISE_SWEEP
71 };
72};
73
74
75/**
76\brief collection of set bits defined in PxHitFlag.
77
78@see PxHitFlag
79*/
80PX_FLAGS_TYPEDEF(PxHitFlag, PxU16)
81
82/** \deprecated Deprecated definition for backwards compatibility with PhysX 3.2 */
83#define PxSceneQueryFlag PxHitFlag // PX_DEPRECATED
84/** \deprecated Deprecated definition for backwards compatibility with PhysX 3.2 */
85#define PxSceneQueryFlags PxHitFlags // PX_DEPRECATED
86
87/**
88\brief Combines a shape pointer and the actor the shape belongs to into one memory location.
89
90Used with PxVolumeCache iterator and serves as a base class for PxQueryHit.
91
92@see PxVolumeCache PxQueryHit
93*/
94struct PxActorShape
95{
96 PX_INLINE PxActorShape() : actor(NULL), shape(NULL) {}
97 PX_INLINE PxActorShape(PxRigidActor* a, PxShape* s) : actor(a), shape(s) {}
98
99 PxRigidActor* actor;
100 PxShape* shape;
101};
102
103
104/**
105\brief Scene query hit information.
106*/
107struct PxQueryHit : PxActorShape
108{
109 PX_INLINE PxQueryHit() : faceIndex(0xFFFFffff) {}
110
111 /**
112 Face index of touched triangle, for triangle meshes, convex meshes and height fields.
113
114 \note This index will default to 0xFFFFffff value for overlap queries.
115 \note Please refer to the user guide for more details for sweep queries.
116 \note This index is remapped by mesh cooking. Use #PxTriangleMesh::getTrianglesRemap() to convert to original mesh index.
117 \note For convex meshes use #PxConvexMesh::getPolygonData() to retrieve touched polygon data.
118 */
119 PxU32 faceIndex;
120};
121
122/** \deprecated Deprecated definition for backwards compatibility with PhysX 3.2 */
123#define PxSceneQueryHit PxQueryHit
124
125/**
126\brief Scene query hit information for raycasts and sweeps returning hit position and normal information.
127
128::PxHitFlag flags can be passed to scene query functions, as an optimization, to cause the SDK to
129only generate specific members of this structure.
130*/
131struct PxLocationHit : public PxQueryHit
132{
133 PX_INLINE PxLocationHit() : flags(0), position(PxVec3(0)), normal(PxVec3(0)), distance(PX_MAX_REAL) {}
134
135 /**
136 \note For raycast hits: true for shapes overlapping with raycast origin.
137 \note For sweep hits: true for shapes overlapping at zero sweep distance.
138
139 @see PxRaycastHit PxSweepHit
140 */
141 PX_INLINE bool hadInitialOverlap() const { return (distance <= 0.0f); }
142
143 // the following fields are set in accordance with the #PxHitFlags
144 PxHitFlags flags; //!< Hit flags specifying which members contain valid values.
145 PxVec3 position; //!< World-space hit position (flag: #PxHitFlag::ePOSITION)
146 //!< Formerly known as .impact, renamed for clarity.
147 PxVec3 normal; //!< World-space hit normal (flag: #PxHitFlag::eNORMAL)
148
149 /**
150 \brief Distance to hit.
151 \note If the eMTD flag is used, distance will be a negative value if shapes are overlapping indicating the penetration depth.
152 \note Otherwise, this value will be >= 0 (flag: #PxHitFlag::eDISTANCE) */
153 PxF32 distance;
154};
155
156
157/**
158\brief Stores results of raycast queries.
159
160::PxHitFlag flags can be passed to raycast function, as an optimization, to cause the SDK to only compute specified members of this
161structure.
162
163Some members like barycentric coordinates are currently only computed for triangle meshes and height fields, but next versions
164might provide them in other cases. The client code should check #flags to make sure returned values are valid.
165
166@see PxScene.raycast PxBatchQuery.raycast PxVolumeCache.raycast
167*/
168struct PxRaycastHit : public PxLocationHit
169{
170 PX_INLINE PxRaycastHit() : u(0.0f), v(0.0f) {}
171
172 // the following fields are set in accordance with the #PxHitFlags
173
174 PxReal u, v; //!< barycentric coordinates of hit point, for triangle mesh and height field (flag: #PxHitFlag::eUV)
175#if !defined(PX_P64)
176 PxU32 padTo16Bytes[3];
177#endif
178};
179
180
181/**
182\brief Stores results of overlap queries.
183
184@see PxScene.overlap and PxBatchQuery.overlap PxVolumeCache.overlap
185*/
186struct PxOverlapHit: public PxQueryHit { PxU32 padTo16Bytes; };
187
188
189/**
190\brief Stores results of sweep queries.
191
192@see PxScene.sweep PxBatchQuery.sweep PxVolumeCache.sweep
193*/
194struct PxSweepHit : public PxLocationHit
195{
196 PX_INLINE PxSweepHit() {}
197
198 PxU32 padTo16Bytes;
199};
200
201
202/**
203\brief Describes query behavior after returning a partial query result via a callback.
204
205If callback returns true, traversal will continue and callback can be issued again.
206If callback returns false, traversal will stop, callback will not be issued again.
207
208@see PxHitCallback
209*/
210typedef bool PxAgain;
211
212
213/**
214\brief This callback class facilitates reporting scene query hits (intersections) to the user.
215
216User overrides the virtual processTouches function to receive hits in (possibly multiple) fixed size blocks.
217
218\note PxHitBuffer derives from this class and is used to receive touching hits in a fixed size buffer.
219\note Since the compiler doesn't look in template dependent base classes when looking for non-dependent names
220\note with some compilers it will be necessary to use "this->hasBlock" notation to access a parent variable
221\note in a child callback class.
222\note Pre-made typedef shorthands, such as ::PxRaycastCallback can be used for raycast, overlap and sweep queries.
223
224@see PxHitBuffer PxRaycastHit PxSweepHit PxOverlapHit PxRaycastCallback PxOverlapCallback PxSweepCallback
225*/
226template<typename HitType>
227struct PxHitCallback
228{
229 HitType block; //<! Holds the closest blocking hit result for the query. Invalid if hasBlock is false.
230 bool hasBlock; //<! Set to true if there was a blocking hit during query.
231
232 HitType* touches; //<! User specified buffer for touching hits.
233
234 /**
235 \brief Size of the user specified touching hits buffer.
236 \note If set to 0 all hits will default to PxQueryHitType::eBLOCK, otherwise to PxQueryHitType::eTOUCH
237 \note Hit type returned from pre-filter overrides this default */
238 PxU32 maxNbTouches;
239
240 /**
241 \brief Number of touching hits returned by the query. Used with PxHitBuffer.
242 \note If true (PxAgain) is returned from the callback, nbTouches will be reset to 0. */
243 PxU32 nbTouches;
244
245 /**
246 \brief Initializes the class with user provided buffer.
247
248 \param[in] aTouches Optional buffer for recording PxQueryHitType::eTOUCH type hits.
249 \param[in] aMaxNbTouches Size of touch buffer.
250
251 \note if aTouches is NULL and aMaxNbTouches is 0, only the closest blocking hit will be recorded by the query.
252 \note If PxQueryFlag::eANY_HIT flag is used as a query parameter, hasBlock will be set to true and blockingHit will be used to receive the result.
253 \note Both eTOUCH and eBLOCK hits will be registered as hasBlock=true and stored in PxHitCallback.block when eANY_HIT flag is used.
254
255 @see PxHitCallback.hasBlock PxHitCallback.block */
256 PxHitCallback(HitType* aTouches, PxU32 aMaxNbTouches)
257 : hasBlock(false), touches(aTouches), maxNbTouches(aMaxNbTouches), nbTouches(0)
258 {}
259
260 /**
261 \brief virtual callback function used to communicate query results to the user.
262
263 This callback will always be invoked with aTouches as a buffer if aTouches was specified as non-NULL.
264 All reported touch hits are guaranteed to be closer than the closest blocking hit.
265
266 \param[in] buffer Callback will report touch hits to the user in this buffer. This pointer will be the same as aTouches parameter.
267 \param[in] nbHits Number of touch hits reported in buffer. This number will not exceed aMaxNbTouches constructor parameter.
268
269 \note There is a significant performance penalty in case multiple touch callbacks are issued (up to 2x)
270 \note to avoid the penalty use a bigger buffer so that all touching hits can be reported in a single buffer.
271 \note If true (again) is returned from the callback, nbTouches will be reset to 0,
272 \note If false is returned, nbTouched will remain unchanged.
273 \note By the time processTouches is first called, the globally closest blocking hit is already determined,
274 \note values of hasBlock and block are final and all touch hits are guaranteed to be closer than the blocking hit.
275 \note touches and maxNbTouches can be modified inside of processTouches callback.
276
277 \return true to continue receiving callbacks in case there are more hits or false to stop.
278
279 @see PxAgain PxRaycastHit PxSweepHit PxOverlapHit */
280 virtual PxAgain processTouches(const HitType* buffer, PxU32 nbHits) = 0;
281
282 virtual void finalizeQuery() {} //<! Query finalization callback, called after the last processTouches callback.
283
284 virtual ~PxHitCallback() {}
285
286 /** \brief Returns true if any blocking or touching hits were encountered during a query. */
287 PX_FORCE_INLINE bool hasAnyHits() { return (hasBlock || (nbTouches > 0)); }
288};
289
290
291/**
292\brief Returns scene query hits (intersections) to the user in a preallocated buffer.
293
294Will clip touch hits to maximum buffer capacity. When clipped, an arbitrary subset of touching hits will be discarded.
295Overflow does not trigger warnings or errors. block and hasBlock will be valid in finalizeQuery callback and after query completion.
296Touching hits are guaranteed to have closer or same distance ( <= condition) as the globally nearest blocking hit at the time any processTouches()
297callback is issued.
298
299\note Pre-made typedef shorthands, such as ::PxRaycastBuffer can be used for raycast, overlap and sweep queries.
300
301@see PxHitCallback
302@see PxRaycastBuffer PxOverlapBuffer PxSweepBuffer PxRaycastBufferN PxOverlapBufferN PxSweepBufferN
303*/
304template<typename HitType>
305struct PxHitBuffer : public PxHitCallback<HitType>
306{
307 /**
308 \brief Initializes the buffer with user memory.
309
310 The buffer is initialized with 0 touch hits by default => query will only report a single closest blocking hit.
311 Use PxQueryFlag::eANY_HIT to tell the query to abort and return any first hit encoutered as blocking.
312
313 \param[in] aTouches Optional buffer for recording PxQueryHitType::eTOUCH type hits.
314 \param[in] aMaxNbTouches Size of touch buffer.
315
316 @see PxHitCallback */
317 PxHitBuffer(HitType* aTouches = NULL, PxU32 aMaxNbTouches = 0) : PxHitCallback<HitType>(aTouches, aMaxNbTouches) {}
318
319 /** \brief Computes the number of any hits in this result, blocking or touching. */
320 PX_INLINE PxU32 getNbAnyHits() const { return getNbTouches() + PxU32(this->hasBlock); }
321 /** \brief Convenience iterator used to access any hits in this result, blocking or touching. */
322 PX_INLINE const HitType& getAnyHit(const PxU32 index) const { PX_ASSERT(index < getNbTouches() + PxU32(this->hasBlock));
323 return index < getNbTouches() ? getTouches()[index] : this->block; }
324
325 PX_INLINE PxU32 getNbTouches() const { return this->nbTouches; }
326 PX_INLINE const HitType* getTouches() const { return this->touches; }
327 PX_INLINE const HitType& getTouch(const PxU32 index) const { PX_ASSERT(index < getNbTouches()); return getTouches()[index]; }
328 PX_INLINE PxU32 getMaxNbTouches() const { return this->maxNbTouches; }
329
330 virtual ~PxHitBuffer() {}
331
332protected:
333 // stops after the first callback
334 virtual PxAgain processTouches(const HitType* buffer, PxU32 nbHits) { PX_UNUSED(buffer); PX_UNUSED(nbHits); return false; }
335};
336
337
338/** \brief Raycast query callback. */
339typedef PxHitCallback<PxRaycastHit> PxRaycastCallback;
340
341/** \brief Overlap query callback. */
342typedef PxHitCallback<PxOverlapHit> PxOverlapCallback;
343
344/** \brief Sweep query callback. */
345typedef PxHitCallback<PxSweepHit> PxSweepCallback;
346
347/** \brief Raycast query buffer. */
348typedef PxHitBuffer<PxRaycastHit> PxRaycastBuffer;
349
350/** \brief Overlap query buffer. */
351typedef PxHitBuffer<PxOverlapHit> PxOverlapBuffer;
352
353/** \brief Sweep query buffer. */
354typedef PxHitBuffer<PxSweepHit> PxSweepBuffer;
355
356/** \brief Returns touching raycast hits to the user in a fixed size array embedded in the buffer class. **/
357template <int N>
358struct PxRaycastBufferN : PxHitBuffer<PxRaycastHit>
359{
360 PxRaycastHit hits[N];
361 PxRaycastBufferN() : PxHitBuffer<PxRaycastHit>(hits, N) {}
362};
363
364/** \brief Returns touching overlap hits to the user in a fixed size array embedded in the buffer class. **/
365template <int N>
366struct PxOverlapBufferN : PxHitBuffer<PxOverlapHit>
367{
368 PxOverlapHit hits[N];
369 PxOverlapBufferN() : PxHitBuffer<PxOverlapHit>(hits, N) {}
370};
371
372/** \brief Returns touching sweep hits to the user in a fixed size array embedded in the buffer class. **/
373template <int N>
374struct PxSweepBufferN : PxHitBuffer<PxSweepHit>
375{
376 PxSweepHit hits[N];
377 PxSweepBufferN() : PxHitBuffer<PxSweepHit>(hits, N) {}
378};
379
380#ifndef PX_DOXYGEN
381} // namespace physx
382#endif
383
384/** @} */
385#endif
386