RavEngine
Loading...
Searching...
No Matches
GuHeightField.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_HEIGHTFIELD_H
30#define GU_HEIGHTFIELD_H
31
32#include "geometry/PxHeightFieldSample.h"
33#include "geometry/PxHeightFieldDesc.h"
34#include "geometry/PxHeightField.h"
35#include "geometry/PxHeightFieldGeometry.h"
36
37#include "foundation/PxUserAllocated.h"
38#include "CmRefCountable.h"
39#include "GuSphere.h"
40#include "GuHeightFieldData.h"
41
42//#define PX_HEIGHTFIELD_VERSION 0
43//#define PX_HEIGHTFIELD_VERSION 1 // tiled version that was needed for PS3 only has been removed
44#define PX_HEIGHTFIELD_VERSION 2 // some floats are now integers
45
46namespace physx
47{
48class PxHeightFieldDesc;
49
50namespace Gu
51{
52class MeshFactory;
54{
55//= ATTENTION! =====================================================================================
56// Changing the data layout of this class breaks the binary serialization format. See comments for
57// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
58// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
59// accordingly.
60//==================================================================================================
61public:
62// PX_SERIALIZATION
63 HeightField(PxBaseFlags baseFlags) : PxHeightField(baseFlags), mData(PxEmpty), mModifyCount(0) {}
64
65 void preExportDataReset() { Cm::RefCountable_preExportDataReset(*this); }
66 virtual void exportExtraData(PxSerializationContext& context);
67 void importExtraData(PxDeserializationContext& context);
68 PX_FORCE_INLINE void setMeshFactory(MeshFactory* f) { mMeshFactory = f; }
69 PX_PHYSX_COMMON_API static HeightField* createObject(PxU8*& address, PxDeserializationContext& context);
70 PX_PHYSX_COMMON_API static void getBinaryMetaData(PxOutputStream& stream);
71 void resolveReferences(PxDeserializationContext&) {}
72
73 virtual void requiresObjects(PxProcessPxBaseCallback&){}
74//~PX_SERIALIZATION
75 HeightField(MeshFactory* factory);
77 // PxHeightField
78 virtual void release();
79 virtual PxU32 saveCells(void* destBuffer, PxU32 destBufferSize) const;
80 virtual bool modifySamples(PxI32 startCol, PxI32 startRow, const PxHeightFieldDesc& subfieldDesc, bool shrinkBounds);
81 virtual PxU32 getNbRows() const { return mData.rows; }
82 virtual PxU32 getNbColumns() const { return mData.columns; }
83 virtual PxHeightFieldFormat::Enum getFormat() const { return mData.format; }
84 virtual PxU32 getSampleStride() const { return sizeof(PxHeightFieldSample); }
85 virtual PxReal getConvexEdgeThreshold() const { return mData.convexEdgeThreshold; }
86 virtual PxHeightFieldFlags getFlags() const { return mData.flags; }
87 virtual PxReal getHeight(PxReal x, PxReal z) const { return getHeightInternal(x, z); }
88 virtual PxMaterialTableIndex getTriangleMaterialIndex(PxTriangleID triangleIndex) const
89 {
90 return getTriangleMaterial(triangleIndex);
91 }
92
93 virtual PxVec3 getTriangleNormal(PxTriangleID triangleIndex) const
94 {
95 return getTriangleNormalInternal(triangleIndex);
96 }
97
98 virtual const PxHeightFieldSample& getSample(PxU32 row, PxU32 column) const
99 {
100 const PxU32 cell = row * getNbColumnsFast() + column;
101 return getSample(cell);
102 }
103 virtual PxU32 getTimestamp() const { return mModifyCount; }
104 //~PxHeightField
105
106 // PxRefCounted
107 virtual void acquireReference();
108 virtual PxU32 getReferenceCount() const;
109 //~PxRefCounted
110
111 // PxBase
112 virtual void onRefCountZero();
113 //~PxBase
114 bool loadFromDesc(const PxHeightFieldDesc&);
115 bool load(PxInputStream&);
116 bool save(PxOutputStream& stream, bool endianSwap);
117
118 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getNbRowsFast() const { return mData.rows; }
119 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getNbColumnsFast() const { return mData.columns; }
120 PX_FORCE_INLINE PxHeightFieldFormat::Enum getFormatFast() const { return mData.format; }
121 PX_FORCE_INLINE PxU32 getFlagsFast() const { return mData.flags; }
122
123 PX_CUDA_CALLABLE PX_FORCE_INLINE bool isZerothVertexShared(PxU32 vertexIndex) const
124 {
125 // return (getSample(vertexIndex).tessFlag & PxHeightFieldTessFlag::e0TH_VERTEX_SHARED);
126 return getSample(vertexIndex).tessFlag() != 0;
127 }
128
129 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU16 getMaterialIndex0(PxU32 vertexIndex) const { return getSample(vertexIndex).materialIndex0; }
130 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU16 getMaterialIndex1(PxU32 vertexIndex) const { return getSample(vertexIndex).materialIndex1; }
131 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getMaterialIndex01(PxU32 vertexIndex) const
132 {
133 const PxHeightFieldSample& sample = getSample(vertexIndex);
134 return PxU32(sample.materialIndex0 | (sample.materialIndex1 << 16));
135 }
136
137 PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getHeight(PxU32 vertexIndex) const
138 {
139 return PxReal(getSample(vertexIndex).height);
140 }
141
142 PX_INLINE PxReal getHeightInternal2(PxU32 vertexIndex, PxReal fracX, PxReal fracZ) const;
143 PX_FORCE_INLINE PxReal getHeightInternal(PxReal x, PxReal z) const
144 {
145 PxReal fracX, fracZ;
146 const PxU32 vertexIndex = computeCellCoordinates(x, z, fracX, fracZ);
147
148 return getHeightInternal2(vertexIndex, fracX, fracZ);
149 }
150
151 PX_FORCE_INLINE bool isValidVertex(PxU32 vertexIndex) const { return vertexIndex < mData.rows*mData.columns; }
152
153 PX_INLINE PxVec3 getVertex(PxU32 vertexIndex) const;
154 PX_INLINE bool isConvexVertex(PxU32 vertexIndex, PxU32 row, PxU32 column) const;
155
156 PX_INLINE bool isValidEdge(PxU32 edgeIndex) const;
157 PX_INLINE PxU32 getEdgeTriangleIndices(PxU32 edgeIndex, PxU32 triangleIndices[2]) const;
158 PX_INLINE PxU32 getEdgeTriangleIndices(PxU32 edgeIndex, PxU32 triangleIndices[2], PxU32 cell, PxU32 row, PxU32 column) const;
159 PX_INLINE void getEdgeVertexIndices(PxU32 edgeIndex, PxU32& vertexIndex0, PxU32& vertexIndex1) const;
160 // PX_INLINE bool isConvexEdge(PxU32 edgeIndex) const;
161 PX_INLINE bool isConvexEdge(PxU32 edgeIndex, PxU32 cell, PxU32 row, PxU32 column) const;
162 PX_FORCE_INLINE bool isConvexEdge(PxU32 edgeIndex) const
163 {
164 const PxU32 cell = edgeIndex / 3;
165 const PxU32 row = cell / mData.columns;
166 const PxU32 column = cell % mData.columns;
167 return isConvexEdge(edgeIndex, cell, row, column);
168 }
169
170 PxU32 computeCellCoordinates(PxReal x, PxReal z, PxReal& fracX, PxReal& fracZ) const;
171
172 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getMin(PxReal x, PxU32 nb) const
173 {
174 if(x<0.0f)
175 return 0;
176 if(x>PxReal(nb))
177 return nb;
178
179 const PxReal cx = PxFloor(x);
180 const PxU32 icx = PxU32(cx);
181 return icx;
182 }
183
184 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getMax(PxReal x, PxU32 nb) const
185 {
186 if(x<0.0f)
187 return 0;
188 if(x>PxReal(nb))
189 return nb;
190
191 const PxReal cx = PxCeil(x);
192 const PxU32 icx = PxU32(cx);
193 return icx;
194 }
195
196 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getMinRow(PxReal x) const { return getMin(x, mData.rows-2); }
197 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getMaxRow(PxReal x) const { return getMax(x, mData.rows-1); }
198 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getMinColumn(PxReal z) const { return getMin(z, mData.columns-2); }
199 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getMaxColumn(PxReal z) const { return getMax(z, mData.columns-1); }
200
201 PX_CUDA_CALLABLE PX_INLINE bool isValidTriangle(PxU32 triangleIndex) const;
202 PX_CUDA_CALLABLE PX_FORCE_INLINE bool isFirstTriangle(PxU32 triangleIndex) const { return ((triangleIndex & 0x1) == 0); }
203
204 PX_CUDA_CALLABLE PX_FORCE_INLINE PxU16 getTriangleMaterial(PxU32 triangleIndex) const
205 {
206 return isFirstTriangle(triangleIndex) ? getMaterialIndex0(triangleIndex >> 1) : getMaterialIndex1(triangleIndex >> 1);
207 }
208
209 PX_CUDA_CALLABLE PX_INLINE void getTriangleVertexIndices(PxU32 triangleIndex, PxU32& vertexIndex0, PxU32& vertexIndex1, PxU32& vertexIndex2) const;
210 PX_CUDA_CALLABLE PX_INLINE PxVec3 getTriangleNormalInternal(PxU32 triangleIndex) const;
211 PX_INLINE void getTriangleAdjacencyIndices(PxU32 triangleIndex,PxU32 vertexIndex0, PxU32 vertexIndex1, PxU32 vertexIndex2, PxU32& adjacencyIndex0, PxU32& adjacencyIndex1, PxU32& adjacencyIndex2) const;
212
213 PX_INLINE PxVec3 getNormal_2(PxU32 vertexIndex, PxReal fracX, PxReal fracZ, PxReal xcoeff, PxReal ycoeff, PxReal zcoeff) const;
214 PX_FORCE_INLINE PxVec3 getNormal_(PxReal x, PxReal z, PxReal xcoeff, PxReal ycoeff, PxReal zcoeff) const
215 {
216 PxReal fracX, fracZ;
217 const PxU32 vertexIndex = computeCellCoordinates(x, z, fracX, fracZ);
218
219 return getNormal_2(vertexIndex, fracX, fracZ, xcoeff, ycoeff, zcoeff);
220 }
221
222 PX_INLINE PxU32 getTriangleIndex(PxReal x, PxReal z) const;
223 PX_INLINE PxU32 getTriangleIndex2(PxU32 cell, PxReal fracX, PxReal fracZ) const;
224 PX_FORCE_INLINE PxU16 getMaterial(PxReal x, PxReal z) const
225 {
226 return getTriangleMaterial(getTriangleIndex(x, z));
227 }
228
229 PX_FORCE_INLINE PxReal getMinHeight() const { return mMinHeight; }
230 PX_FORCE_INLINE PxReal getMaxHeight() const { return mMaxHeight; }
231
232 PX_FORCE_INLINE const Gu::HeightFieldData& getData() const { return mData; }
233
234 PX_CUDA_CALLABLE PX_FORCE_INLINE void getTriangleVertices(PxU32 triangleIndex, PxU32 row, PxU32 column, PxVec3& v0, PxVec3& v1, PxVec3& v2) const;
235
236 // checks if current vertex is solid or not
237 bool isSolidVertex(PxU32 vertexIndex, PxU32 row, PxU32 coloumn, PxU16 holeMaterialIndex, bool& nbSolid) const;
238
239 // PT: TODO: I think we could drop that whole precomputation thing now
240 // if precomputed bitmap define is used, the collision vertex information
241 // is precomputed during create height field and stored as a bit in materialIndex1
242 PX_PHYSX_COMMON_API bool isCollisionVertexPreca(PxU32 vertexIndex, PxU32 row, PxU32 column, PxU16 holeMaterialIndex) const;
243 void parseTrianglesForCollisionVertices(PxU16 holeMaterialIndex);
244
245 PX_CUDA_CALLABLE PX_FORCE_INLINE const PxHeightFieldSample& getSample(PxU32 vertexIndex) const
246 {
247 PX_ASSERT(isValidVertex(vertexIndex));
248 return mData.samples[vertexIndex];
249 }
250#ifdef __CUDACC__
251 PX_CUDA_CALLABLE void setSamplePtr(PxHeightFieldSample* s) { mData.samples = s; }
252#endif
253 Gu::HeightFieldData mData;
254 PxU32 mSampleStride;
255 PxU32 mNbSamples; // PT: added for platform conversion. Try to remove later.
256 PxReal mMinHeight;
257 PxReal mMaxHeight;
258 PxU32 mModifyCount;
259
260 void releaseMemory();
261 virtual ~HeightField();
262
263private:
264 MeshFactory* mMeshFactory; // PT: changed to pointer for serialization
265};
266
267} // namespace Gu
268
269PX_INLINE PxVec3 Gu::HeightField::getVertex(PxU32 vertexIndex) const
270{
271 const PxU32 row = vertexIndex / mData.columns;
272 const PxU32 column = vertexIndex % mData.columns;
273// return PxVec3(PxReal(row), getHeight(row * mData.columns + column), PxReal(column));
274 return PxVec3(PxReal(row), getHeight(vertexIndex), PxReal(column));
275}
276
277// PT: only called from "isCollisionVertex", should move
278PX_INLINE bool Gu::HeightField::isConvexVertex(PxU32 vertexIndex, PxU32 row, PxU32 column) const
279{
280#ifdef PX_HEIGHTFIELD_DEBUG
281 PX_ASSERT(isValidVertex(vertexIndex));
282#endif
283 PX_ASSERT((vertexIndex / mData.columns)==row);
284 PX_ASSERT((vertexIndex % mData.columns)==column);
285
286// PxReal h0 = PxReal(2) * getHeight(vertexIndex);
287 PxI32 h0 = getSample(vertexIndex).height;
288 h0 += h0;
289
290 bool definedInX, definedInZ;
291 PxI32 convexityX, convexityZ;
292
293 if ((row > 0) && (row < mData.rows - 1))
294 {
295// convexityX = h0 - getHeight(vertexIndex + mData.columns) - getHeight(vertexIndex - mData.columns);
296 convexityX = h0 - getSample(vertexIndex + mData.columns).height - getSample(vertexIndex - mData.columns).height;
297 definedInX = true;
298 }
299 else
300 {
301 convexityX = 0;
302 definedInX = false;
303 }
304
305 if ((column > 0) && (column < mData.columns - 1))
306 {
307// convexityZ = h0 - getHeight(vertexIndex + 1) - getHeight(vertexIndex - 1);
308 convexityZ = h0 - getSample(vertexIndex + 1).height - getSample(vertexIndex - 1).height;
309 definedInZ = true;
310 }
311 else
312 {
313 convexityZ = 0;
314 definedInZ = false;
315 }
316
317 if(definedInX || definedInZ)
318 {
319 // PT: use XOR here
320 // saddle points
321/* if ((convexityX > 0) && (convexityZ < 0))
322 return false;
323 if ((convexityX < 0) && (convexityZ > 0))
324 return false;*/
325 if(((convexityX ^ convexityZ) & 0x80000000)==0)
326 return false;
327
328 const PxReal value = PxReal(convexityX + convexityZ);
329 return value > mData.convexEdgeThreshold;
330 }
331
332 // this has to be one of the two corner vertices
333 return true;
334}
335
336PX_INLINE bool Gu::HeightField::isValidEdge(PxU32 edgeIndex) const
337{
338 const PxU32 cell = (edgeIndex / 3);
339 const PxU32 row = cell / mData.columns;
340 const PxU32 column = cell % mData.columns;
341// switch (edgeIndex % 3)
342 switch (edgeIndex - cell*3)
343 {
344 case 0:
345 if (row > mData.rows - 1) return false;
346 if (column >= mData.columns - 1) return false;
347 break;
348 case 1:
349 if (row >= mData.rows - 1) return false;
350 if (column >= mData.columns - 1) return false;
351 break;
352 case 2:
353 if (row >= mData.rows - 1) return false;
354 if (column > mData.columns - 1) return false;
355 break;
356 }
357 return true;
358}
359
360PX_INLINE PxU32 Gu::HeightField::getEdgeTriangleIndices(PxU32 edgeIndex, PxU32 triangleIndices[2]) const
361{
362 const PxU32 cell = edgeIndex / 3;
363 const PxU32 row = cell / mData.columns;
364 const PxU32 column = cell % mData.columns;
365 PxU32 count = 0;
366// switch (edgeIndex % 3)
367 switch (edgeIndex - cell*3)
368 {
369 case 0:
370 if (column < mData.columns - 1)
371 {
372 if (row > 0)
373 {
374/* if (isZerothVertexShared(cell - mData.columns))
375 triangleIndices[count++] = ((cell - mData.columns) << 1);
376 else
377 triangleIndices[count++] = ((cell - mData.columns) << 1) + 1;*/
378 triangleIndices[count++] = ((cell - mData.columns) << 1) + 1 - isZerothVertexShared(cell - mData.columns);
379 }
380 if (row < mData.rows - 1)
381 {
382/* if (isZerothVertexShared(cell))
383 triangleIndices[count++] = (cell << 1) + 1;
384 else
385 triangleIndices[count++] = cell << 1;*/
386 triangleIndices[count++] = (cell << 1) + isZerothVertexShared(cell);
387 }
388 }
389 break;
390 case 1:
391 if ((row < mData.rows - 1) && (column < mData.columns - 1))
392 {
393 triangleIndices[count++] = cell << 1;
394 triangleIndices[count++] = (cell << 1) + 1;
395 }
396 break;
397 case 2:
398 if (row < mData.rows - 1)
399 {
400 if (column > 0)
401 triangleIndices[count++] = ((cell - 1) << 1) + 1;
402 if (column < mData.columns - 1)
403 triangleIndices[count++] = cell << 1;
404 }
405 break;
406 }
407 return count;
408}
409
410PX_INLINE PxU32 Gu::HeightField::getEdgeTriangleIndices(PxU32 edgeIndex, PxU32 triangleIndices[2], PxU32 cell, PxU32 row, PxU32 column) const
411{
412// const PxU32 cell = edgeIndex / 3;
413// const PxU32 row = cell / mData.columns;
414// const PxU32 column = cell % mData.columns;
415 PxU32 count = 0;
416// switch (edgeIndex % 3)
417 switch (edgeIndex - cell*3)
418 {
419 case 0:
420 if (column < mData.columns - 1)
421 {
422 if (row > 0)
423 {
424/* if (isZerothVertexShared(cell - mData.columns))
425 triangleIndices[count++] = ((cell - mData.columns) << 1);
426 else
427 triangleIndices[count++] = ((cell - mData.columns) << 1) + 1;*/
428 triangleIndices[count++] = ((cell - mData.columns) << 1) + 1 - isZerothVertexShared(cell - mData.columns);
429 }
430 if (row < mData.rows - 1)
431 {
432/* if (isZerothVertexShared(cell))
433 triangleIndices[count++] = (cell << 1) + 1;
434 else
435 triangleIndices[count++] = cell << 1;*/
436 triangleIndices[count++] = (cell << 1) + isZerothVertexShared(cell);
437 }
438 }
439 break;
440 case 1:
441 if ((row < mData.rows - 1) && (column < mData.columns - 1))
442 {
443 triangleIndices[count++] = cell << 1;
444 triangleIndices[count++] = (cell << 1) + 1;
445 }
446 break;
447 case 2:
448 if (row < mData.rows - 1)
449 {
450 if (column > 0)
451 triangleIndices[count++] = ((cell - 1) << 1) + 1;
452 if (column < mData.columns - 1)
453 triangleIndices[count++] = cell << 1;
454 }
455 break;
456 }
457 return count;
458}
459
460PX_INLINE void Gu::HeightField::getEdgeVertexIndices(PxU32 edgeIndex, PxU32& vertexIndex0, PxU32& vertexIndex1) const
461{
462 const PxU32 cell = edgeIndex / 3;
463// switch (edgeIndex % 3)
464 switch (edgeIndex - cell*3)
465 {
466 case 0:
467 vertexIndex0 = cell;
468 vertexIndex1 = cell + 1;
469 break;
470 case 1:
471 {
472/* if (isZerothVertexShared(cell))
473 {
474 vertexIndex0 = cell;
475 vertexIndex1 = cell + mData.columns + 1;
476 }
477 else
478 {
479 vertexIndex0 = cell + 1;
480 vertexIndex1 = cell + mData.columns;
481 }*/
482 const bool b = isZerothVertexShared(cell);
483 vertexIndex0 = cell + 1 - b;
484 vertexIndex1 = cell + mData.columns + b;
485 }
486 break;
487 case 2:
488 vertexIndex0 = cell;
489 vertexIndex1 = cell + mData.columns;
490 break;
491 }
492}
493
494PX_INLINE bool Gu::HeightField::isConvexEdge(PxU32 edgeIndex, PxU32 cell, PxU32 row, PxU32 column) const
495{
496// const PxU32 cell = edgeIndex / 3;
497 PX_ASSERT(cell == edgeIndex / 3);
498
499// const PxU32 row = cell / mData.columns;
500 PX_ASSERT(row == cell / mData.columns);
501 if (row > mData.rows-2) return false;
502
503// const PxU32 column = cell % mData.columns;
504 PX_ASSERT(column == cell % mData.columns);
505 if (column > mData.columns-2) return false;
506
507// PxReal h0 = 0, h1 = 0, h2 = 0, h3 = 0;
508// PxReal convexity = 0;
509 PxI32 h0 = 0, h1 = 0, h2 = 0, h3 = 0;
510 PxI32 convexity = 0;
511
512// switch (edgeIndex % 3)
513 switch (edgeIndex - cell*3)
514 {
515 case 0:
516 {
517 if (row < 1) return false;
518/* if(isZerothVertexShared(cell - mData.columns))
519 {
520 // <------ COL
521 // +----+ 0 R
522 // | / /# O
523 // | / / # W
524 // | / / # |
525 // |/ / # |
526 // + +====1 |
527 // |
528 // |
529 // |
530 // |
531 // |
532 // |
533 // V
534 //
535// h0 = getHeight(cell - mData.columns);
536// h1 = getHeight(cell);
537 h0 = getSample(cell - mData.columns).height;
538 h1 = getSample(cell).height;
539 }
540 else
541 {
542 // <------ COL
543 // 0 +----+ R
544 // #\ \ | O
545 // # \ \ | W
546 // # \ \ | |
547 // # \ \| |
548 // 1====+ + |
549 // |
550 // |
551 // |
552 // |
553 // |
554 // |
555 // V
556 //
557// h0 = getHeight(cell - mData.columns + 1);
558// h1 = getHeight(cell + 1);
559 h0 = getSample(cell - mData.columns + 1).height;
560 h1 = getSample(cell + 1).height;
561 }*/
562 const bool b0 = !isZerothVertexShared(cell - mData.columns);
563 h0 = getSample(cell - mData.columns + b0).height;
564 h1 = getSample(cell + b0).height;
565
566/* if(isZerothVertexShared(cell))
567 {
568 // <------ COL
569 // R
570 // O
571 // W
572 // |
573 // |
574 // |
575 // 2====+ 0 |
576 // # / /| |
577 // # / / | |
578 // # / / | |
579 // #/ / | |
580 // 3 +----+ |
581 // V
582 //
583// h2 = getHeight(cell + 1);
584// h3 = getHeight(cell + mData.columns + 1);
585 h2 = getSample(cell + 1).height;
586 h3 = getSample(cell + mData.columns + 1).height;
587 }
588 else
589 {
590 // <------ COL
591 // R
592 // O
593 // W
594 // |
595 // |
596 // |
597 // + +====2 |
598 // |\ \ # |
599 // | \ \ # |
600 // | \ \ # |
601 // | \ \# |
602 // +----+ 3 |
603 // V
604 //
605// h2 = getHeight(cell);
606// h3 = getHeight(cell + mData.columns);
607 h2 = getSample(cell).height;
608 h3 = getSample(cell + mData.columns).height;
609 }*/
610 const bool b1 = isZerothVertexShared(cell);
611 h2 = getSample(cell + b1).height;
612 h3 = getSample(cell + mData.columns + b1).height;
613
614 //convex = (h3-h2) < (h1-h0);
615 convexity = (h1-h0) - (h3-h2);
616 }
617 break;
618 case 1:
619// h0 = getHeight(cell);
620// h1 = getHeight(cell + 1);
621// h2 = getHeight(cell + mData.columns);
622// h3 = getHeight(cell + mData.columns + 1);
623 h0 = getSample(cell).height;
624 h1 = getSample(cell + 1).height;
625 h2 = getSample(cell + mData.columns).height;
626 h3 = getSample(cell + mData.columns + 1).height;
627 if (isZerothVertexShared(cell))
628 //convex = (h0 + h3) > (h1 + h2);
629 convexity = (h0 + h3) - (h1 + h2);
630 else
631 //convex = (h2 + h1) > (h0 + h3);
632 convexity = (h2 + h1) - (h0 + h3);
633 break;
634 case 2:
635 {
636 if (column < 1) return false;
637/* if(isZerothVertexShared(cell-1))
638 {
639 // <-------------- COL
640 // 1====0 + R
641 // + / /| O
642 // + / / | W
643 // + / / | |
644 // +/ / | |
645 // + +----+ V
646 //
647// h0 = getHeight(cell - 1);
648// h1 = getHeight(cell);
649 h0 = getSample(cell - 1).height;
650 h1 = getSample(cell).height;
651 }
652 else
653 {
654 // <-------------- COL
655 // + +----+ R
656 // +\ \ | O
657 // + \ \ | W
658 // + \ \ | |
659 // + \ \| |
660 // 1====0 + V
661 //
662// h0 = getHeight(cell - 1 + mData.columns);
663// h1 = getHeight(cell + mData.columns);
664 h0 = getSample(cell - 1 + mData.columns).height;
665 h1 = getSample(cell + mData.columns).height;
666 }*/
667 const PxU32 offset0 = isZerothVertexShared(cell-1) ? 0 : mData.columns;
668 h0 = getSample(cell - 1 + offset0).height;
669 h1 = getSample(cell + offset0).height;
670
671/* if(isZerothVertexShared(cell))
672 {
673 // <-------------- COL
674 // +----+ + R
675 // | / /+ O
676 // | / / + W
677 // | / / + |
678 // |/ / + |
679 // + 3====2 V
680 //
681// h2 = getHeight(cell + mData.columns);
682// h3 = getHeight(cell + mData.columns + 1);
683 h2 = getSample(cell + mData.columns).height;
684 h3 = getSample(cell + mData.columns + 1).height;
685 }
686 else
687 {
688 // <-------------- COL
689 // + 3====2 R
690 // |\ \ + O
691 // | \ \ + W
692 // | \ \ + |
693 // | \ \+ |
694 // +----+ + V
695 //
696// h2 = getHeight(cell);
697// h3 = getHeight(cell + 1);
698 h2 = getSample(cell).height;
699 h3 = getSample(cell + 1).height;
700 }*/
701 const PxU32 offset1 = isZerothVertexShared(cell) ? mData.columns : 0;
702 h2 = getSample(cell + offset1).height;
703 h3 = getSample(cell + offset1 + 1).height;
704
705 //convex = (h3-h2) < (h1-h0);
706 convexity = (h1-h0) - (h3-h2);
707 }
708 break;
709 }
710
711 const PxI32 threshold = PxI32(mData.convexEdgeThreshold);
712 return convexity > threshold;
713}
714
715PX_INLINE bool Gu::HeightField::isValidTriangle(PxU32 triangleIndex) const
716{
717 const PxU32 cell = triangleIndex >> 1;
718 const PxU32 row = cell / mData.columns;
719 if (row >= (mData.rows - 1)) return false;
720 const PxU32 column = cell % mData.columns;
721 if (column >= (mData.columns - 1)) return false;
722 return true;
723}
724
725PX_INLINE void Gu::HeightField::getTriangleVertexIndices(PxU32 triangleIndex, PxU32& vertexIndex0, PxU32& vertexIndex1, PxU32& vertexIndex2) const
726{
727 const PxU32 cell = triangleIndex >> 1;
728 if (isZerothVertexShared(cell))
729 {
730 // <---- COL
731 // 0----2 1 R
732 // | 1 / /| O
733 // | / / | W
734 // | / / | |
735 // |/ / 0 | |
736 // 1 2----0 V
737 //
738 if (isFirstTriangle(triangleIndex))
739 {
740 vertexIndex0 = cell + mData.columns;
741 vertexIndex1 = cell;
742 vertexIndex2 = cell + mData.columns + 1;
743 }
744 else
745 {
746 vertexIndex0 = cell + 1;
747 vertexIndex1 = cell + mData.columns + 1;
748 vertexIndex2 = cell;
749 }
750 }
751 else
752 {
753 // <---- COL
754 // 2 1----0 R
755 // |\ \ 0 | O
756 // | \ \ | W
757 // | \ \ | |
758 // | 1 \ \| |
759 // 0----1 2 V
760 //
761 if (isFirstTriangle(triangleIndex))
762 {
763 vertexIndex0 = cell;
764 vertexIndex1 = cell + 1;
765 vertexIndex2 = cell + mData.columns;
766 }
767 else
768 {
769 vertexIndex0 = cell + mData.columns + 1;
770 vertexIndex1 = cell + mData.columns;
771 vertexIndex2 = cell + 1;
772 }
773 }
774}
775
776PX_INLINE void Gu::HeightField::getTriangleAdjacencyIndices(PxU32 triangleIndex, PxU32 vertexIndex0, PxU32 vertexIndex1, PxU32 vertexIndex2, PxU32& adjacencyIndex0, PxU32& adjacencyIndex1, PxU32& adjacencyIndex2) const
777{
778 PX_UNUSED(vertexIndex0);
779 PX_UNUSED(vertexIndex1);
780 PX_UNUSED(vertexIndex2);
781
782 const PxU32 cell = triangleIndex >> 1;
783 if (isZerothVertexShared(cell))
784 {
785 // <---- COL
786 // 0----2 1 R
787 // | 1 / /| O
788 // | / / | W
789 // | / / | |
790 // |/ / 0 | |
791 // 1 2----0 V
792 //
793 if (isFirstTriangle(triangleIndex))
794 {
795 adjacencyIndex0 = 0xFFFFFFFF;
796 adjacencyIndex1 = triangleIndex + 1;
797 adjacencyIndex2 = 0xFFFFFFFF;
798
799 if((cell % (mData.columns) != 0))
800 {
801 adjacencyIndex0 = triangleIndex - 1;
802 }
803
804 if((cell / mData.columns != mData.rows - 2))
805 {
806 const PxU32 tMod = isZerothVertexShared(cell + mData.columns) ? 1u : 0u;
807 adjacencyIndex2 = ((cell + mData.columns) * 2) + tMod;
808 }
809 }
810 else
811 {
812 adjacencyIndex0 = 0xFFFFFFFF;
813 adjacencyIndex1 = triangleIndex - 1;
814 adjacencyIndex2 = 0xFFFFFFFF;
815
816 if(cell % (mData.columns) < (mData.columns - 2))
817 {
818 adjacencyIndex0 = triangleIndex + 1;
819 }
820
821 if(cell >= mData.columns - 1)
822 {
823 const PxU32 tMod = isZerothVertexShared(cell - mData.columns) ? 0u : 1u;
824 adjacencyIndex2 = ((cell - mData.columns) * 2) + tMod;
825 }
826 }
827 }
828 else
829 {
830 // <---- COL
831 // 2 1----0 R
832 // |\ \ 0 | O
833 // | \ \ | W
834 // | \ \ | |
835 // | 1 \ \| |
836 // 0----1 2 V
837 //
838 if (isFirstTriangle(triangleIndex))
839 {
840 adjacencyIndex0 = 0xFFFFFFFF;
841 adjacencyIndex1 = triangleIndex + 1;
842 adjacencyIndex2 = 0xFFFFFFFF;
843
844 if(cell >= mData.columns - 1)
845 {
846 const PxU32 tMod = isZerothVertexShared(cell - mData.columns) ? 0u : 1u;
847 adjacencyIndex0 = ((cell - (mData.columns)) * 2) + tMod;
848 }
849
850 if((cell % (mData.columns) != 0))
851 {
852 adjacencyIndex2 = triangleIndex - 1;
853 }
854 }
855 else
856 {
857 adjacencyIndex0 = 0xFFFFFFFF;
858 adjacencyIndex1 = triangleIndex - 1;
859 adjacencyIndex2 = 0xFFFFFFFF;
860
861 if((cell / mData.columns != mData.rows - 2))
862 {
863 const PxU32 tMod = isZerothVertexShared(cell + mData.columns) ? 1u : 0u;
864 adjacencyIndex0 = (cell + (mData.columns)) * 2 + tMod;
865 }
866
867 if(cell % (mData.columns) < (mData.columns - 2))
868 {
869 adjacencyIndex2 = triangleIndex + 1;
870 }
871 }
872 }
873}
874
875PX_INLINE PxVec3 Gu::HeightField::getTriangleNormalInternal(PxU32 triangleIndex) const
876{
877 PxU32 v0, v1, v2;
878 getTriangleVertexIndices(triangleIndex, v0, v1, v2);
879
880// const PxReal h0 = getHeight(v0);
881// const PxReal h1 = getHeight(v1);
882// const PxReal h2 = getHeight(v2);
883 const PxI32 h0 = getSample(v0).height;
884 const PxI32 h1 = getSample(v1).height;
885 const PxI32 h2 = getSample(v2).height;
886
887 const float thickness = 0.0f;
888 const PxReal coeff = physx::intrinsics::fsel(thickness, -1.0f, 1.0f);
889
890// PxVec3 n(0,1,0);
891 const PxU32 cell = triangleIndex >> 1;
892 if (isZerothVertexShared(cell))
893 {
894 // <---- COL
895 // 0----2 1 R
896 // | 1 / /| O
897 // | / / | W
898 // | / / | |
899 // |/ / 0 | |
900 // 1 2----0 V
901 //
902 if (isFirstTriangle(triangleIndex))
903 {
904// n.x = -(h0-h1);
905// n.z = -(h2-h0);
906 return PxVec3(coeff*PxReal(h1-h0), coeff, coeff*PxReal(h0-h2));
907 }
908 else
909 {
910// n.x = -(h1-h0);
911// n.z = -(h0-h2);
912 return PxVec3(coeff*PxReal(h0-h1), coeff, coeff*PxReal(h2-h0));
913 }
914 }
915 else
916 {
917 // <---- COL
918 // 2 1----0 R
919 // |\ \ 0 | O
920 // | \ \ | W
921 // | \ \ | |
922 // | 1 \ \| |
923 // 0----1 2 V
924 //
925 if (isFirstTriangle(triangleIndex))
926 {
927// n.x = -(h2-h0);
928// n.z = -(h1-h0);
929 return PxVec3(coeff*PxReal(h0-h2), coeff, coeff*PxReal(h0-h1));
930 }
931 else
932 {
933// n.x = -(h0-h2);
934// n.z = -(h0-h1);
935 return PxVec3(coeff*PxReal(h2-h0), coeff, coeff*PxReal(h1-h0));
936 }
937 }
938// return n;
939}
940
941PX_INLINE PxReal Gu::HeightField::getHeightInternal2(PxU32 vertexIndex, PxReal fracX, PxReal fracZ) const
942{
943 if (isZerothVertexShared(vertexIndex))
944 {
945 // <----Z---+
946 // +----+ |
947 // | /| |
948 // | / | X
949 // | / | |
950 // |/ | |
951 // +----+ |
952 // V
953 const PxReal h0 = getHeight(vertexIndex);
954 const PxReal h2 = getHeight(vertexIndex + mData.columns + 1);
955 if (fracZ > fracX)
956 {
957 // <----Z---+
958 // 1----0 |
959 // | / |
960 // | / X
961 // | / |
962 // |/ |
963 // 2 |
964 // V
965 const PxReal h1 = getHeight(vertexIndex + 1);
966 return h0 + fracZ*(h1-h0) + fracX*(h2-h1);
967 }
968 else
969 {
970 // <----Z---+
971 // 0 |
972 // /| |
973 // / | X
974 // / | |
975 // / | |
976 // 2----1 |
977 // V
978 const PxReal h1 = getHeight(vertexIndex + mData.columns);
979 return h0 + fracX*(h1-h0) + fracZ*(h2-h1);
980 }
981 }
982 else
983 {
984 // <----Z---+
985 // +----+ |
986 // |\ | |
987 // | \ | X
988 // | \ | |
989 // | \| |
990 // +----+ |
991 // V
992 const PxReal h2 = getHeight(vertexIndex + mData.columns);
993 const PxReal h1 = getHeight(vertexIndex + 1);
994 if (fracX + fracZ < 1.0f)
995 {
996 // <----Z---+
997 // 1----0 |
998 // \ | |
999 // \ | X
1000 // \ | |
1001 // \| |
1002 // 2 |
1003 // V
1004 const PxReal h0 = getHeight(vertexIndex);
1005 return h0 + fracZ*(h1-h0) + fracX*(h2-h0);
1006 }
1007 else
1008 {
1009 // <----Z---+
1010 // 1 |
1011 // |\ |
1012 // | \ X
1013 // | \ |
1014 // | \ |
1015 // 0----2 |
1016 // V
1017 //
1018 // Note that we need to flip fracX and fracZ since we are moving the origin
1019 const PxReal h0 = getHeight(vertexIndex + mData.columns + 1);
1020 return h0 + (1.0f - fracZ)*(h2-h0) + (1.0f - fracX)*(h1-h0);
1021 }
1022 }
1023}
1024
1025PX_INLINE PxVec3 Gu::HeightField::getNormal_2(PxU32 vertexIndex, PxReal fracX, PxReal fracZ, PxReal xcoeff, PxReal ycoeff, PxReal zcoeff) const
1026{
1027 PxVec3 normal;
1028 if (isZerothVertexShared(vertexIndex))
1029 {
1030 // <----Z---+
1031 // +----+ |
1032 // | /| |
1033 // | / | X
1034 // | / | |
1035 // |/ | |
1036 // +----+ |
1037 // V
1038// const PxReal h0 = getHeight(vertexIndex);
1039// const PxReal h2 = getHeight(vertexIndex + mData.columns + 1);
1040 const PxI32 ih0 = getSample(vertexIndex).height;
1041 const PxI32 ih2 = getSample(vertexIndex + mData.columns + 1).height;
1042 if (fracZ >= fracX)
1043 {
1044 // <----Z---+
1045 // 1----0 |
1046 // | / |
1047 // | / X
1048 // | / |
1049 // |/ |
1050 // 2 |
1051 // V
1052// const PxReal h0 = getHeight(vertexIndex);
1053// const PxReal h1 = getHeight(vertexIndex + 1);
1054// const PxReal h2 = getHeight(vertexIndex + mData.columns + 1);
1055// normal.set(-(h2-h1), 1.0f, -(h1-h0));
1056 const PxI32 ih1 = getSample(vertexIndex + 1).height;
1057 normal = PxVec3(PxReal(ih1 - ih2)*xcoeff, ycoeff, PxReal(ih0 - ih1)*zcoeff);
1058 }
1059 else
1060 {
1061 // <----Z---+
1062 // 0 |
1063 // /| |
1064 // / | X
1065 // / | |
1066 // / | |
1067 // 2----1 |
1068 // V
1069// const PxReal h0 = getHeight(vertexIndex);
1070// const PxReal h1 = getHeight(vertexIndex + mData.columns);
1071// const PxReal h2 = getHeight(vertexIndex + mData.columns + 1);
1072// normal.set(-(h1-h0), 1.0f, -(h2-h1));
1073 const PxI32 ih1 = getSample(vertexIndex + mData.columns).height;
1074 normal = PxVec3(PxReal(ih0 - ih1)*xcoeff, ycoeff, PxReal(ih1 - ih2)*zcoeff);
1075 }
1076 }
1077 else
1078 {
1079 // <----Z---+
1080 // +----+ |
1081 // |\ | |
1082 // | \ | X
1083 // | \ | |
1084 // | \| |
1085 // +----+ |
1086 // V
1087 const PxI32 ih1 = getSample(vertexIndex + 1).height;
1088 const PxI32 ih2 = getSample(vertexIndex + mData.columns).height;
1089 if (fracX + fracZ <= PxReal(1))
1090 {
1091 // <----Z---+
1092 // 1----0 |
1093 // \ | |
1094 // \ | X
1095 // \ | |
1096 // \| |
1097 // 2 |
1098 // V
1099// const PxReal h0 = getHeight(vertexIndex);
1100// const PxReal h1 = getHeight(vertexIndex + 1);
1101// const PxReal h2 = getHeight(vertexIndex + mData.columns);
1102// normal.set(-(h2-h0), 1.0f, -(h1-h0));
1103 const PxI32 ih0 = getSample(vertexIndex).height;
1104// const PxI32 ih1 = getSample(vertexIndex + 1).height;
1105// const PxI32 ih2 = getSample(vertexIndex + mData.columns).height;
1106 normal = PxVec3(PxReal(ih0 - ih2)*xcoeff, ycoeff, PxReal(ih0 - ih1)*zcoeff);
1107 }
1108 else
1109 {
1110 // <----Z---+
1111 // 2 |
1112 // |\ |
1113 // | \ X
1114 // | \ |
1115 // | \ |
1116 // 0----1 |
1117 // V
1118 //
1119 // Note that we need to flip fracX and fracZ since we are moving the origin
1120// const PxReal h2 = getHeight(vertexIndex + 1);
1121// const PxReal h1 = getHeight(vertexIndex + mData.columns);
1122// const PxReal h0 = getHeight(vertexIndex + mData.columns + 1);
1123// normal.set(-(h0-h2), 1.0f, -(h0-h1));
1124// const PxI32 ih2 = getSample(vertexIndex + 1).height;
1125// const PxI32 ih1 = getSample(vertexIndex + mData.columns).height;
1126 const PxI32 ih0 = getSample(vertexIndex + mData.columns + 1).height;
1127// normal.set(PxReal(ih2 - ih0), 1.0f, PxReal(ih1b - ih0));
1128 normal = PxVec3(PxReal(ih1 - ih0)*xcoeff, ycoeff, PxReal(ih2 - ih0)*zcoeff);
1129 }
1130 }
1131 return normal;
1132}
1133
1134PX_INLINE PxU32 Gu::HeightField::getTriangleIndex2(PxU32 cell, PxReal fracX, PxReal fracZ) const
1135{
1136 if (isZerothVertexShared(cell))
1137 return (fracZ > fracX) ? (cell << 1) + 1 : (cell << 1);
1138 else
1139 return (fracX + fracZ > 1) ? (cell << 1) + 1 : (cell << 1);
1140}
1141
1142PX_INLINE PxU32 Gu::HeightField::getTriangleIndex(PxReal x, PxReal z) const
1143{
1144 PxReal fracX, fracZ;
1145 const PxU32 cell = computeCellCoordinates(x, z, fracX, fracZ);
1146
1147 return getTriangleIndex2(cell, fracX, fracZ);
1148}
1149
1150PX_FORCE_INLINE void Gu::HeightField::getTriangleVertices(PxU32 triangleIndex, PxU32 row, PxU32 column, PxVec3& v0, PxVec3& v1, PxVec3& v2) const
1151{
1152 PxU32 cell = triangleIndex >> 1;
1153 PX_ASSERT(row * getNbColumnsFast() + column == cell);
1154
1155 PxReal h0 = getHeight(cell);
1156 PxReal h1 = getHeight(cell + 1);
1157 PxReal h2 = getHeight(cell + getNbColumnsFast());
1158 PxReal h3 = getHeight(cell + getNbColumnsFast() + 1);
1159
1160 if (isFirstTriangle(triangleIndex))
1161 {
1162 if (isZerothVertexShared(cell))
1163 {
1164 // <---- COL
1165 // 1 R
1166 // /| O
1167 // / | W
1168 // / | |
1169 // / 0 | |
1170 // 2----0 V
1171 //
1172 v0 = PxVec3(PxReal(row + 1), h2, PxReal(column ));
1173 v1 = PxVec3(PxReal(row ), h0, PxReal(column ));
1174 v2 = PxVec3(PxReal(row + 1), h3, PxReal(column + 1));
1175 }
1176 else
1177 {
1178 // <---- COL
1179 // 1----0 R
1180 // \ 0 | O
1181 // \ | W
1182 // \ | |
1183 // \| |
1184 // 2 V
1185 //
1186 v0 = PxVec3(PxReal(row ), h0, PxReal(column ));
1187 v1 = PxVec3(PxReal(row ), h1, PxReal(column + 1));
1188 v2 = PxVec3(PxReal(row + 1), h2, PxReal(column ));
1189 }
1190 }
1191 else
1192 {
1193 if (isZerothVertexShared(cell))
1194 {
1195 // <---- COL
1196 // 0----2 R
1197 // | 1 / O
1198 // | / W
1199 // | / |
1200 // |/ |
1201 // 1 V
1202 //
1203 v0 = PxVec3(PxReal(row ), h1, PxReal(column + 1));
1204 v1 = PxVec3(PxReal(row + 1), h3, PxReal(column + 1));
1205 v2 = PxVec3(PxReal(row ), h0, PxReal(column ));
1206 }
1207 else
1208 {
1209 // <---- COL
1210 // 2 R
1211 // |\ O
1212 // | \ W
1213 // | \ |
1214 // | 1 \ |
1215 // 0----1 V
1216 //
1217 v0 = PxVec3(PxReal(row + 1), h3, PxReal(column + 1));
1218 v1 = PxVec3(PxReal(row + 1), h2, PxReal(column ));
1219 v2 = PxVec3(PxReal(row ), h1, PxReal(column + 1));
1220 }
1221 }
1222}
1223
1224PX_FORCE_INLINE const Gu::HeightFieldData* _getHFData(const PxHeightFieldGeometry& hfGeom)
1225{
1226 return &static_cast<const Gu::HeightField*>(hfGeom.heightField)->getData();
1227}
1228
1229}
1230
1231#endif
Definition base.h:1940
Definition GuHeightField.h:54
virtual PxVec3 getTriangleNormal(PxTriangleID triangleIndex) const
Returns a triangle face normal for a given triangle index.
Definition GuHeightField.h:93
virtual PxReal getHeight(PxReal x, PxReal z) const
Retrieves the height at the given coordinates in grid space.
Definition GuHeightField.h:87
virtual PxU32 getNbColumns() const
Retrieves the number of sample columns in the samples array.
Definition GuHeightField.h:82
virtual PxReal getConvexEdgeThreshold() const
Retrieves the convex edge threshold.
Definition GuHeightField.h:85
virtual PxU32 getTimestamp() const
Returns the number of times the heightfield data has been modified.
Definition GuHeightField.h:103
virtual PxHeightFieldFlags getFlags() const
Retrieves the flags bits, combined from values of the enum ::PxHeightFieldFlag.
Definition GuHeightField.h:86
virtual PxHeightFieldFormat::Enum getFormat() const
Retrieves the format of the sample data.
Definition GuHeightField.h:83
virtual PxU32 getNbRows() const
Retrieves the number of sample rows in the samples array.
Definition GuHeightField.h:81
virtual void acquireReference()
Acquires a counted reference to this object.
Definition GuHeightField.cpp:113
virtual void release()
Decrements the reference count of a height field and releases it if the new reference count is zero.
Definition GuHeightField.cpp:108
virtual bool modifySamples(PxI32 startCol, PxI32 startRow, const PxHeightFieldDesc &subfieldDesc, bool shrinkBounds)
Replaces a rectangular subfield in the sample data array.
Definition GuHeightField.cpp:125
virtual PxU32 getReferenceCount() const
Returns the reference count of the object.
Definition GuHeightField.cpp:118
virtual const PxHeightFieldSample & getSample(PxU32 row, PxU32 column) const
Returns heightfield sample of given row and column
Definition GuHeightField.h:98
virtual PxU32 getSampleStride() const
Retrieves the offset in bytes between consecutive samples in the array.
Definition GuHeightField.h:84
virtual PxMaterialTableIndex getTriangleMaterialIndex(PxTriangleID triangleIndex) const
Returns material table index of given triangle.
Definition GuHeightField.h:88
virtual PxU32 saveCells(void *destBuffer, PxU32 destBufferSize) const
Writes out the sample data array.
Definition GuHeightField.cpp:382
Definition GuMeshFactory.h:83
Binary deserialization context class.
Definition PxSerialFramework.h:174
Descriptor class for #PxHeightField.
Definition PxHeightFieldDesc.h:53
A height field class.
Definition PxHeightField.h:84
Input stream class for I/O.
Definition PxIO.h:50
Output stream class for I/O.
Definition PxIO.h:114
Callback class used to process PxBase objects.
Definition PxSerialFramework.h:81
Binary serialization context class.
Definition PxSerialFramework.h:99
Definition PxUserAllocated.h:43
3 Element vector class.
Definition PxVec3.h:50
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
#define PX_INLINE
Definition PxPreprocessor.h:320
GLM_FUNC_DECL genType::row_type row(genType const &m, length_t index)
Definition matrix_access.inl:23
GLM_FUNC_DECL genType::col_type column(genType const &m, length_t index)
Definition matrix_access.inl:53
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
Definition GuHeightFieldData.h:48
Enum
Definition PxHeightFieldFlag.h:49
Heightfield sample format.
Definition PxHeightFieldSample.h:67
PxBitAndByte materialIndex1
The triangle material index of the quad's upper triangle + reserved flag.
Definition PxHeightFieldSample.h:114
PxBitAndByte materialIndex0
The triangle material index of the quad's lower triangle + tesselation flag.
Definition PxHeightFieldSample.h:99