RavEngine
Loading...
Searching...
No Matches
GuPCMContactMeshCallback.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_PCM_CONTACT_MESH_CALLBACK_H
30#define GU_PCM_CONTACT_MESH_CALLBACK_H
31
32#include "GuMidphaseInterface.h"
33#include "GuEntityReport.h"
34#include "GuHeightFieldUtil.h"
35#include "GuTriangleCache.h"
36#include "GuConvexEdgeFlags.h"
37
38namespace physx
39{
40namespace Gu
41{
42
43template <typename Derived>
45{
46public:
47 const Cm::FastVertex2ShapeScaling& mMeshScaling;
48 const PxU8* PX_RESTRICT mExtraTrigData;
49 bool mIdtMeshScale;
50 static const PxU32 CacheSize = 16;
52
53 PCMMeshContactGenerationCallback(const Cm::FastVertex2ShapeScaling& meshScaling, const PxU8* extraTrigData, bool idtMeshScale)
54 : MeshHitCallback<PxGeomRaycastHit>(CallbackMode::eMULTIPLE),
55 mMeshScaling(meshScaling), mExtraTrigData(extraTrigData), mIdtMeshScale(idtMeshScale)
56 {
57 }
58
59 void flushCache()
60 {
61 if (!mCache.isEmpty())
62 {
63 (static_cast<Derived*>(this))->template processTriangleCache< CacheSize >(mCache);
64 mCache.reset();
65 }
66 }
67
68 virtual PxAgain processHit(
69 const PxGeomRaycastHit& hit, const PxVec3& v0, const PxVec3& v1, const PxVec3& v2, PxReal&, const PxU32* vinds)
70 {
71 if (!(static_cast<Derived*>(this))->doTest(v0, v1, v2))
72 return true;
73
74 const PxU32 triangleIndex = hit.faceIndex;
75 PxU8 extraData = getConvexEdgeFlags(mExtraTrigData, triangleIndex);
76
77 const PxU32* vertexIndices = vinds;
78 PxVec3 v[3];
79 PxU32 localStorage[3];
80 if(mIdtMeshScale)
81 {
82 v[0] = v0;
83 v[1] = v1;
84 v[2] = v2;
85 }
86 else
87 {
88 const PxI32 winding = mMeshScaling.flipsNormal() ? 1 : 0;
89 v[0] = mMeshScaling * v0;
90 v[1 + winding] = mMeshScaling * v1;
91 v[2 - winding] = mMeshScaling * v2;
92
93 if(winding)
94 {
95 flipConvexEdgeFlags(extraData);
96 localStorage[0] = vinds[0];
97 localStorage[1] = vinds[2];
98 localStorage[2] = vinds[1];
99 vertexIndices = localStorage;
100 }
101 }
102
103 if (mCache.isFull())
104 {
105 (static_cast<Derived*>(this))->template processTriangleCache< CacheSize >(mCache);
106 mCache.reset();
107 }
108 mCache.addTriangle(v, vertexIndices, triangleIndex, extraData);
109
110 return true;
111 }
112
113protected:
115};
116
117template <typename Derived>
119{
120public:
121 const Gu::HeightFieldUtil& mHfUtil;
122 const PxTransform& mHeightfieldTransform;
123 bool mBoundaryCollisions;
124
125 PCMHeightfieldContactGenerationCallback(const Gu::HeightFieldUtil& hfUtil, const PxTransform& heightfieldTransform) :
126 mHfUtil(hfUtil), mHeightfieldTransform(heightfieldTransform)
127 {
128 mBoundaryCollisions = !(hfUtil.getHeightField().getFlags() & PxHeightFieldFlag::eNO_BOUNDARY_EDGES);
129 }
130
131 // PT: TODO: refactor/unify with similar code in other places
132 virtual bool reportTouchedTris(PxU32 nb, const PxU32* indices)
133 {
134 const PxU32 CacheSize = 16;
136
137 const PxU32 nbPasses = (nb+(CacheSize-1))/CacheSize;
138 PxU32 nbTrigs = nb;
139 const PxU32* inds0 = indices;
140
141 const PxU8 nextInd[] = {2,0,1};
142
143 for(PxU32 i = 0; i < nbPasses; ++i)
144 {
145 cache.mNumTriangles = 0;
146 PxU32 trigCount = PxMin(nbTrigs, CacheSize);
147 nbTrigs -= trigCount;
148 while(trigCount--)
149 {
150 PxU32 triangleIndex = *(inds0++);
151 PxU32 vertIndices[3];
152
153 PxTriangle currentTriangle; // in world space
154
155 PxU32 adjInds[3];
156 mHfUtil.getTriangle(mHeightfieldTransform, currentTriangle, vertIndices, adjInds, triangleIndex, false, false);
157
158 PxVec3 normal;
159 currentTriangle.normal(normal);
160
161 PxU8 triFlags = 0; //KS - temporary until we can calculate triFlags for HF
162
163 for(PxU32 a = 0; a < 3; ++a)
164 {
165 if (adjInds[a] != 0xFFFFFFFF)
166 {
167 PxTriangle adjTri;
168 PxU32 inds[3];
169 mHfUtil.getTriangle(mHeightfieldTransform, adjTri, inds, NULL, adjInds[a], false, false);
170 //We now compare the triangles to see if this edge is active
171
172 PX_ASSERT(inds[0] == vertIndices[a] || inds[1] == vertIndices[a] || inds[2] == vertIndices[a]);
173 PX_ASSERT(inds[0] == vertIndices[(a + 1) % 3] || inds[1] == vertIndices[(a + 1) % 3] || inds[2] == vertIndices[(a + 1) % 3]);
174
175 PxVec3 adjNormal;
176 adjTri.denormalizedNormal(adjNormal);
177 PxU32 otherIndex = nextInd[a];
178 PxF32 projD = adjNormal.dot(currentTriangle.verts[otherIndex] - adjTri.verts[0]);
179
180 if (projD < 0.f)
181 {
182 adjNormal.normalize();
183
184 PxF32 proj = adjNormal.dot(normal);
185
186 if (proj < 0.997f)
187 {
188 triFlags |= (1 << (a + 3));
189 }
190 }
191 }
192 else if (mBoundaryCollisions)
193 {
194 triFlags |= (1 << (a + 3)); //Mark boundary edge active
195 }
196 else
197 triFlags |= (1 << a); //Mark as silhouette edge
198 }
199
200 cache.addTriangle(currentTriangle.verts, vertIndices, triangleIndex, triFlags);
201 }
202 PX_ASSERT(cache.mNumTriangles <= 16);
203
204 (static_cast<Derived*>(this))->template processTriangleCache< CacheSize >(cache);
205 }
206 return true;
207 }
208protected:
210};
211
212template <typename Derived>
214{
215public:
216
217 static const PxU32 CacheSize = 16;
219
221 {
222 }
223
224 void flushCache()
225 {
226 if (!mCache.isEmpty())
227 {
228 (static_cast<Derived*>(this))->template processTetrahedronCache< CacheSize >(mCache);
229 mCache.reset();
230 }
231 }
232
233 virtual PxAgain processHit(
234 const PxGeomRaycastHit& hit, const PxVec3& v0, const PxVec3& v1, const PxVec3& v2, const PxVec3& v3, PxReal&, const PxU32* vinds)
235 {
236 if (!(static_cast<Derived*>(this))->doTest(v0, v1, v2, v3))
237 return true;
238
239 PxVec3 v[4] = { v0, v1, v2, v3 };
240
241 const PxU32 tetIndex = hit.faceIndex;
242
243 if (mCache.isFull())
244 {
245 (static_cast<Derived*>(this))->template processTetrahedronCache< CacheSize >(mCache);
246 mCache.reset();
247 }
248 mCache.addTetrahedrons(v, vinds, tetIndex);
249
250 return true;
251 }
252
253protected:
255};
256
257}//Gu
258}//physx
259
260#endif
Definition CmScaling.h:61
Definition GuHeightFieldUtil.h:69
virtual PxHeightFieldFlags getFlags() const
Retrieves the flags bits, combined from values of the enum ::PxHeightFieldFlag.
Definition GuHeightField.h:86
Definition GuEntityReport.h:48
class representing a rigid euclidean transform as a quaternion and a vector
Definition PxTransform.h:49
Triangle class.
Definition PxTriangle.h:47
PxVec3 verts[3]
Array of Vertices.
Definition PxTriangle.h:140
PX_FORCE_INLINE void denormalizedNormal(PxVec3 &_normal) const
Compute the unnormalized normal of the triangle.
Definition PxTriangle.h:111
PX_FORCE_INLINE void normal(PxVec3 &_normal) const
Compute the normal of the Triangle.
Definition PxTriangle.h:100
3 Element vector class.
Definition PxVec3.h:50
PX_CUDA_CALLABLE PX_FORCE_INLINE float dot(const PxVec3 &v) const
returns the scalar product of this and other.
Definition PxVec3.h:276
PX_CUDA_CALLABLE PX_FORCE_INLINE float normalize()
normalizes the vector in place
Definition PxVec3.h:300
#define PX_RESTRICT
Definition PxPreprocessor.h:355
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
bool PxAgain
Describes query behavior after returning a partial query result via a callback.
Definition PxQueryReport.h:78
PX_CUDA_CALLABLE PX_FORCE_INLINE T PxMin(T a, T b)
The return value is the lesser of the two specified values.
Definition PxMath.h:88
Definition GuMidphaseInterface.h:61
Definition GuPCMContactMeshCallback.h:119
Definition GuPCMContactMeshCallback.h:45
Definition GuPCMContactMeshCallback.h:214
Definition GuMidphaseInterface.h:78
Definition GuTriangleCache.h:205
Definition GuTriangleCache.h:172
Stores results of raycast queries.
Definition PxGeometryHit.h:151
@ eNO_BOUNDARY_EDGES
Disable collisions with height field with boundary edges.
Definition PxHeightFieldFlag.h:143
PxU32 faceIndex
Definition PxGeometryHit.h:106