RavEngine
Loading...
Searching...
No Matches
GuEPAFacet.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_EPA_FACET_H
30#define GU_EPA_FACET_H
31
32#include "foundation/PxVecMath.h"
33#include "foundation/PxFPU.h"
34#include "foundation/PxUtilities.h"
35#include "CmIDPool.h"
36
37#if (defined __GNUC__ && defined _DEBUG)
38#define PX_EPA_FORCE_INLINE
39#else
40#define PX_EPA_FORCE_INLINE PX_FORCE_INLINE
41#endif
42
43#define EPA_DEBUG 0
44
45namespace physx
46{
47#define MaxEdges 32
48#define MaxFacets 64
49#define MaxSupportPoints 64
50
51namespace Gu
52{
53 const PxU32 lookUp[3] = {1, 2, 0};
54
55 PX_FORCE_INLINE PxU32 incMod3(PxU32 i) { return lookUp[i]; }
56
57 class EdgeBuffer;
58 class Edge;
59 typedef Cm::InlineDeferredIDPool<MaxFacets> EPAFacetManager;
60
61 class Facet
62 {
63 public:
64
65 Facet()
66 {
67 }
68
69 PX_FORCE_INLINE Facet(const PxU32 _i0, const PxU32 _i1, const PxU32 _i2)
70 : m_obsolete(false), m_inHeap(false)
71 {
72 m_indices[0]= PxToI8(_i0);
73 m_indices[1]= PxToI8(_i1);
74 m_indices[2]= PxToI8(_i2);
75
76 m_adjFacets[0] = m_adjFacets[1] = m_adjFacets[2] = NULL;
77 m_adjEdges[0] = m_adjEdges[1] = m_adjEdges[2] = -1;
78 }
79
80
81 PX_FORCE_INLINE void invalidate()
82 {
83 m_adjFacets[0] = m_adjFacets[1] = m_adjFacets[2] = NULL;
84 m_adjEdges[0] = m_adjEdges[1] = m_adjEdges[2] = -1;
85 }
86
87 PX_FORCE_INLINE bool Valid()
88 {
89 return (m_adjFacets[0] != NULL) & (m_adjFacets[1] != NULL) & (m_adjFacets[2] != NULL);
90 }
91
92 PX_FORCE_INLINE PxU32 operator[](const PxU32 i) const
93 {
94 return PxU32(m_indices[i]);
95 }
96
97 //create ajacency information
98 bool link(const PxU32 edge0, Facet* PX_RESTRICT facet, const PxU32 edge1);
99
100 PX_FORCE_INLINE bool isObsolete() const { return m_obsolete; }
101
102 //calculate the signed distance from a point to a plane
103 PX_FORCE_INLINE aos::FloatV getPlaneDist(const aos::Vec3VArg p, const aos::Vec3V* PX_RESTRICT aBuf, const aos::Vec3V* PX_RESTRICT bBuf) const;
104
105 //check to see whether the triangle is a valid triangle, calculate plane normal and plane distance at the same time
106 aos::BoolV isValid2(const PxU32 i0, const PxU32 i1, const PxU32 i2, const aos::Vec3V* PX_RESTRICT aBuf, const aos::Vec3V* PX_RESTRICT bBuf,
107 const aos::FloatVArg upper);
108
109 //return the absolute value for the plane distance from origin
110 PX_FORCE_INLINE aos::FloatV getPlaneDist() const
111 {
112 return aos::FLoad(m_planeDist);
113 }
114
115 //return the plane normal
116 PX_FORCE_INLINE aos::Vec3V getPlaneNormal()const
117 {
118 return m_planeNormal;
119 }
120
121 //calculate the closest points for a shape pair
122 void getClosestPoint(const aos::Vec3V* PX_RESTRICT aBuf, const aos::Vec3V* PX_RESTRICT bBuf, aos::Vec3V& closestA,
123 aos::Vec3V& closestB);
124
125 //calculate the closest points for a shape pair
126 //void getClosestPoint(const aos::Vec3V* PX_RESTRICT aBuf, const aos::Vec3V* PX_RESTRICT bBuf, aos::FloatV& v, aos::FloatV& w);
127
128 //performs a flood fill over the boundary of the current polytope.
129 void silhouette(const aos::Vec3VArg w, const aos::Vec3V* PX_RESTRICT aBuf, const aos::Vec3V* PX_RESTRICT bBuf, EdgeBuffer& edgeBuffer, EPAFacetManager& manager);
130
131
132 //m_planeDist is positive
133 bool operator <(const Facet& b) const
134 {
135 return m_planeDist < b.m_planeDist;
136 }
137
138 //store all the boundary facets for the new polytope in the edgeBuffer and free indices when an old facet isn't part of the boundary anymore
139 PX_FORCE_INLINE void silhouette(const PxU32 index, const aos::Vec3VArg w, const aos::Vec3V* PX_RESTRICT aBuf, const aos::Vec3V* PX_RESTRICT bBuf, EdgeBuffer& edgeBuffer,
140 EPAFacetManager& manager);
141
142 aos::Vec3V m_planeNormal; //16
143 PxF32 m_planeDist;
144#if EPA_DEBUG
145 PxF32 m_lambda1;
146 PxF32 m_lambda2;
147#endif
148
149 Facet* PX_RESTRICT m_adjFacets[3]; //the triangle adjacent to edge i in this triangle //32
150 PxI8 m_adjEdges[3]; //the edge connected with the corresponding triangle //35
151 PxI8 m_indices[3]; //the index of vertices of the triangle //38
152 bool m_obsolete; //a flag to denote whether the triangle are still part of the bundeary of the new polytope //39
153 bool m_inHeap; //a flag to indicate whether the triangle is in the heap //40
154 PxU8 m_FacetId; //41 //73
155
156 };
157
158
159 class Edge
160 {
161 public:
163 PX_FORCE_INLINE Edge(Facet * PX_RESTRICT facet, const PxU32 index) : m_facet(facet), m_index(index) {}
164 PX_FORCE_INLINE Edge(const Edge& other) : m_facet(other.m_facet), m_index(other.m_index){}
165
166 PX_FORCE_INLINE Edge& operator = (const Edge& other)
167 {
168 m_facet = other.m_facet;
169 m_index = other.m_index;
170 return *this;
171 }
172
173 PX_FORCE_INLINE Facet *getFacet() const { return m_facet; }
174 PX_FORCE_INLINE PxU32 getIndex() const { return m_index; }
175
176 //get out the associated start vertex index in this edge from the facet
177 PX_FORCE_INLINE PxU32 getSource() const
178 {
179 PX_ASSERT(m_index < 3);
180 return (*m_facet)[m_index];
181 }
182
183 //get out the associated end vertex index in this edge from the facet
184 PX_FORCE_INLINE PxU32 getTarget() const
185 {
186 PX_ASSERT(m_index < 3);
187 return (*m_facet)[incMod3(m_index)];
188 }
189
190 Facet* PX_RESTRICT m_facet;
191 PxU32 m_index;
192 };
193
194
196 {
197 public:
198 EdgeBuffer() : m_Size(0), m_OverFlow(false)
199 {
200 }
201
202 Edge* Insert(Facet* PX_RESTRICT facet, const PxU32 index)
203 {
204 if (m_Size < MaxEdges)
205 {
206 Edge* pEdge = &m_pEdges[m_Size++];
207 pEdge->m_facet = facet;
208 pEdge->m_index = index;
209 return pEdge;
210 }
211 m_OverFlow = true;
212 return NULL;
213 }
214
215 Edge* Get(const PxU32 index)
216 {
217 PX_ASSERT(index < m_Size);
218 return &m_pEdges[index];
219 }
220
221 PxU32 Size()
222 {
223 return m_Size;
224 }
225
226 bool IsValid()
227 {
228 return m_Size > 0 && !m_OverFlow;
229 }
230
231 void MakeEmpty()
232 {
233 m_Size = 0;
234 m_OverFlow = false;
235 }
236
237 Edge m_pEdges[MaxEdges];
238 PxU32 m_Size;
239 bool m_OverFlow;
240 };
241
242 //ML: calculate MTD points for a shape pair
243 PX_FORCE_INLINE void Facet::getClosestPoint(const aos::Vec3V* PX_RESTRICT aBuf, const aos::Vec3V* PX_RESTRICT bBuf, aos::Vec3V& closestA,
244 aos::Vec3V& closestB)
245 {
246 using namespace aos;
247
248 const Vec3V pa0(aBuf[m_indices[0]]);
249 const Vec3V pa1(aBuf[m_indices[1]]);
250 const Vec3V pa2(aBuf[m_indices[2]]);
251
252 const Vec3V pb0(bBuf[m_indices[0]]);
253 const Vec3V pb1(bBuf[m_indices[1]]);
254 const Vec3V pb2(bBuf[m_indices[2]]);
255
256 const Vec3V p0 = V3Sub(pa0, pb0);
257 const Vec3V p1 = V3Sub(pa1, pb1);
258 const Vec3V p2 = V3Sub(pa2, pb2);
259
260 const Vec3V v0 = V3Sub(p1, p0);
261 const Vec3V v1 = V3Sub(p2, p0);
262
263 const Vec3V closestP = V3Scale(m_planeNormal, FLoad(m_planeDist));
264 const Vec3V v2 = V3Sub(closestP, p0);
265 //calculate barycentric coordinates
266 const FloatV d00 = V3Dot(v0, v0);
267 const FloatV d01 = V3Dot(v0, v1);
268 const FloatV d11 = V3Dot(v1, v1);
269
270 const FloatV d20 = V3Dot(v2, v0);
271 const FloatV d21 = V3Dot(v2, v1);
272
273 const FloatV det = FNegScaleSub(d01, d01, FMul(d00, d11));//FSub( FMul(v1dv1, v2dv2), FMul(v1dv2, v1dv2) ); // non-negative
274 const FloatV recip = FSel(FIsGrtr(det, FEps()), FRecip(det), FZero());
275
276 const FloatV lambda1 = FMul(FNegScaleSub(d01, d21, FMul(d11, d20)), recip);
277 const FloatV lambda2 = FMul(FNegScaleSub(d01, d20, FMul(d00, d21)), recip);
278
279#if EPA_DEBUG
280 FStore(lambda1, &m_lambda1);
281 FStore(lambda2, &m_lambda2);
282#endif
283
284 const FloatV u = FSub(FOne(), FAdd(lambda1, lambda2));
285 closestA = V3ScaleAdd(pa0, u, V3ScaleAdd(pa1, lambda1, V3Scale(pa2, lambda2)));
286 closestB = V3ScaleAdd(pb0, u, V3ScaleAdd(pb1, lambda1, V3Scale(pb2, lambda2)));
287 }
288
289 //ML: create adjacency informations for both facets
290 PX_FORCE_INLINE bool Facet::link(const PxU32 edge0, Facet * PX_RESTRICT facet, const PxU32 edge1)
291 {
292 m_adjFacets[edge0] = facet;
293 m_adjEdges[edge0] = PxToI8(edge1);
294 facet->m_adjFacets[edge1] = this;
295 facet->m_adjEdges[edge1] = PxToI8(edge0);
296
297 return (m_indices[edge0] == facet->m_indices[incMod3(edge1)]) && (m_indices[incMod3(edge0)] == facet->m_indices[edge1]);
298 }
299
300}
301
302}
303
304#endif
Definition GuEPAFacet.h:196
Definition GuEPAFacet.h:160
Definition GuEPAFacet.h:62
#define PX_RESTRICT
Definition PxPreprocessor.h:355
#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 PxVecMathAoSScalar.h:90
Definition PxVecMathAoSScalar.h:52
Definition PxVecMathAoSScalar.h:77