aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Documentation/PhysXGuide/Manual/Geometry.html
blob: ac98ab4a1c94d2cb30261e740c024e2e42b3e5d8 (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
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>Geometry &mdash; NVIDIA PhysX SDK 3.4.2 Documentation</title>
    
    <link rel="stylesheet" href="../_static/nvidia.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <link rel="stylesheet" href="../_static/breathe.css" type="text/css" />
    
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../',
        VERSION:     '3.4.2',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <link rel="top" title="NVIDIA PhysX SDK 3.4.2 Documentation" href="../index.html" />
    <link rel="up" title="User&#39;s Guide" href="Index.html" />
    <link rel="next" title="Rigid Body Overview" href="RigidBodyOverview.html" />
    <link rel="prev" title="Threading" href="Threading.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="RigidBodyOverview.html" title="Rigid Body Overview"
             accesskey="N">next</a></li>
        <li class="right" >
          <a href="Threading.html" title="Threading"
             accesskey="P">previous</a> |</li>
        <li><a href="../Index.html">NVIDIA PhysX SDK 3.4.2 Documentation</a> &raquo;</li>
          <li><a href="Index.html" accesskey="U">User's Guide</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="geometry">
<span id="id1"></span><h1>Geometry<a class="headerlink" href="#geometry" title="Permalink to this headline"></a></h1>
<div class="section" id="introduction">
<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p>This section discusses the PhysX geometry classes. Geometries are used to build shapes for rigid bodies, as collision triggers, and as volumes in PhysX' scene query system. PhysX also provides standalone functions for testing intersection between geometries, raycasting against them, and sweeping one geometry against another.</p>
<p>Geometries are value types, and inherit from a common base class, PxGeometry. Each geometry class defines a volume or surface with a fixed position and orientation. A transform specifies the frame in which the geometry is interpreted. For plane and capsule geometry types PhysX provides helper functions to construct these transforms from common alternative representations.</p>
<p>Geometries fall into two classes:</p>
<ul class="simple">
<li>primitives (PxBoxGeometry, PxSphereGeometry, PxCapsuleGeometry, PxPlaneGeometry) where the geometry object contains all of the data</li>
<li>meshes or height fields (PxConvexMeshGeometry, PxTriangleMeshGeometry, PxHeightFieldGeometry), where the geometry object contains a pointer to a much larger object (PxConvexMesh, PxTriangleMesh, PxHeightField respectively) You can use these objects with different scales in each PxGeometry type which references them. The larger objects must be created using a <em>cooking</em> process, described for each type below.</li>
</ul>
<p>When passed into and out of the SDK for use as simulation geometry, the geometry is copied into and out of a PxShape class. It can be awkward in this case to retrieve the geometry without knowing its type, so PhysX provides a union-like wrapper class (PxGeometryHolder) that can be used to pass any geometry type by value. Each mesh (or height field) has a reference count that tracks the number of PxShapes whose geometries reference the mesh.</p>
</div>
<div class="section" id="geometry-types">
<h2>Geometry Types<a class="headerlink" href="#geometry-types" title="Permalink to this headline"></a></h2>
<div class="section" id="spheres">
<h3>Spheres<a class="headerlink" href="#spheres" title="Permalink to this headline"></a></h3>
<img alt="../_images/GeomTypeSphere.png" src="../_images/GeomTypeSphere.png" />
<p>A PxSphereGeometry is specified by one attribute, its radius, and is centered at the origin.</p>
</div>
<div class="section" id="capsules">
<h3>Capsules<a class="headerlink" href="#capsules" title="Permalink to this headline"></a></h3>
<img alt="../_images/GeomTypeCapsule.png" src="../_images/GeomTypeCapsule.png" />
<p>A PxCapsuleGeometry is centered at the origin. It is specified by a radius and a half-height value by which its axis extends along the positive and negative X-axis.</p>
<p>To create a dynamic actor whose geometry is a capsule standing upright, the shape needs a relative transform that rotates it around the Z-axis by a quarter-circle. By doing this, the capsule will extend along the Y-axis of the actor instead of the X-axis. Setting up the shape and actor is otherwise the same as for the sphere:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxRigidDynamic</span><span class="o">*</span> <span class="n">aCapsuleActor</span> <span class="o">=</span> <span class="n">thePhysics</span><span class="o">-&gt;</span><span class="n">createRigidDynamic</span><span class="p">(</span><span class="n">PxTransform</span><span class="p">(</span><span class="n">position</span><span class="p">));</span>
<span class="n">PxTransform</span> <span class="nf">relativePose</span><span class="p">(</span><span class="n">PxQuat</span><span class="p">(</span><span class="n">PxHalfPi</span><span class="p">,</span> <span class="n">PxVec</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">)));</span>
<span class="n">PxShape</span><span class="o">*</span> <span class="n">aCapsuleShape</span> <span class="o">=</span> <span class="n">PxRigidActorExt</span><span class="o">::</span><span class="n">createExclusiveShape</span><span class="p">(</span><span class="o">*</span><span class="n">aCapsuleActor</span><span class="p">,</span>
    <span class="n">PxCapsuleGeometry</span><span class="p">(</span><span class="n">radius</span><span class="p">,</span> <span class="n">halfHeight</span><span class="p">),</span> <span class="n">aMaterial</span><span class="p">);</span>
<span class="n">aCapsuleShape</span><span class="o">-&gt;</span><span class="n">setLocalPose</span><span class="p">(</span><span class="n">relativePose</span><span class="p">);</span>
<span class="n">PxRigidBodyExt</span><span class="o">::</span><span class="n">updateMassAndInertia</span><span class="p">(</span><span class="o">*</span><span class="n">aCapsuleActor</span><span class="p">,</span> <span class="n">capsuleDensity</span><span class="p">);</span>
<span class="n">aScene</span><span class="o">-&gt;</span><span class="n">addActor</span><span class="p">(</span><span class="n">aCapsuleActor</span><span class="p">);</span>
</pre></div>
</div>
<p>The function PxTransformFromSegment() converts from a line segment defining the capsule axis to a transform and halfheight.</p>
</div>
<div class="section" id="boxes">
<h3>Boxes<a class="headerlink" href="#boxes" title="Permalink to this headline"></a></h3>
<img alt="../_images/GeomTypeBox.png" src="../_images/GeomTypeBox.png" />
<p>A PxBoxGeometry has three attributes, the three extents halved:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxShape</span><span class="o">*</span> <span class="n">aBoxShape</span> <span class="o">=</span> <span class="n">PxRigidActorExt</span><span class="o">::</span><span class="n">createExclusiveShape</span><span class="p">(</span><span class="o">*</span><span class="n">aBoxActor</span><span class="p">,</span>
    <span class="n">PxBoxGeometry</span><span class="p">(</span><span class="n">a</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span> <span class="n">b</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span> <span class="n">c</span><span class="o">/</span><span class="mi">2</span><span class="p">),</span> <span class="n">aMaterial</span><span class="p">);</span>
</pre></div>
</div>
<p>Where a, b and c are the side lengths of the resulting box.</p>
</div>
<div class="section" id="planes">
<h3>Planes<a class="headerlink" href="#planes" title="Permalink to this headline"></a></h3>
<img alt="../_images/GeomTypePlane.png" src="../_images/GeomTypePlane.png" />
<p>Planes divide space into &quot;above&quot; and &quot;below&quot; them. Everything &quot;below&quot; the plane will collide with it.</p>
<p>The Plane lies on the YZ plane with &quot;above&quot; pointing towards positive X. To convert from a plane equation to an equivalent transform, use the function PxTransformFromPlaneEquation(). PxPlaneEquationFromTransform() performs the reverse conversion.</p>
<p>A PxPlaneGeometry has no attributes, since the shape's pose entirely defines the plane's collision volume.</p>
<p>Shapes with a PxPlaneGeometry may only be created for static actors.</p>
</div>
<div class="section" id="convex-meshes">
<h3>Convex Meshes<a class="headerlink" href="#convex-meshes" title="Permalink to this headline"></a></h3>
<img alt="../_images/GeomTypeConvex.png" src="../_images/GeomTypeConvex.png" />
<p>A shape is convex if, given any two points within the shape, the shape contains the line between them. A PxConvexMesh is a convex polyhedron represented as a set of vertices and polygonal faces. The number of vertices and faces of a convex mesh in PhysX is limited to 255.</p>
<p>Creating a PxConvexMesh requires cooking. It is assumed here that the cooking library has already been initialized (see <a class="reference internal" href="Startup.html#startup"><em>Startup and Shutdown</em></a>.) The following steps explain how to create a simple square pyramid.</p>
<p>First, define the vertices of the convex object:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">static</span> <span class="k">const</span> <span class="n">PxVec3</span> <span class="n">convexVerts</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="n">PxVec3</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">),</span><span class="n">PxVec3</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">),</span><span class="n">PxVec3</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">),</span><span class="n">PxVec3</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span>
    <span class="n">PxVec3</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">)};</span>
</pre></div>
</div>
<p>Then construct a description of the convex data layout:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxConvexMeshDesc</span> <span class="n">convexDesc</span><span class="p">;</span>
<span class="n">convexDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">count</span>     <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="n">convexDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">stride</span>    <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">PxVec3</span><span class="p">);</span>
<span class="n">convexDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">data</span>      <span class="o">=</span> <span class="n">convexVerts</span><span class="p">;</span>
<span class="n">convexDesc</span><span class="p">.</span><span class="n">flags</span>            <span class="o">=</span> <span class="n">PxConvexFlag</span><span class="o">::</span><span class="n">eCOMPUTE_CONVEX</span><span class="p">;</span>
</pre></div>
</div>
<p>Now use the cooking library to construct a PxConvexMesh:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxDefaultMemoryOutputStream</span> <span class="n">buf</span><span class="p">;</span>
<span class="n">PxConvexMeshCookingResult</span><span class="o">::</span><span class="n">Enum</span> <span class="n">result</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">cooking</span><span class="p">.</span><span class="n">cookConvexMesh</span><span class="p">(</span><span class="n">convexDesc</span><span class="p">,</span> <span class="n">buf</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">result</span><span class="p">))</span>
    <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">PxDefaultMemoryInputData</span> <span class="nf">input</span><span class="p">(</span><span class="n">buf</span><span class="p">.</span><span class="n">getData</span><span class="p">(),</span> <span class="n">buf</span><span class="p">.</span><span class="n">getSize</span><span class="p">());</span>
<span class="n">PxConvexMesh</span><span class="o">*</span> <span class="n">convexMesh</span> <span class="o">=</span> <span class="n">physics</span><span class="o">-&gt;</span><span class="n">createConvexMesh</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
</pre></div>
</div>
<p>Finally, create a shape using a PxConvexMeshGeometry which instances the mesh:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxShape</span><span class="o">*</span> <span class="n">aConvexShape</span> <span class="o">=</span> <span class="n">PxRigidActorExt</span><span class="o">::</span><span class="n">createExclusiveShape</span><span class="p">(</span><span class="o">*</span><span class="n">aConvexActor</span><span class="p">,</span>
    <span class="n">PxConvexMeshGeometry</span><span class="p">(</span><span class="n">convexMesh</span><span class="p">),</span> <span class="n">aMaterial</span><span class="p">);</span>
</pre></div>
</div>
<p>Alternatively the PxConvexMesh can be cooked and directly inserted into PxPhysics without stream serialization. This is useful if real-time cooking is required. It is strongly recommended to use offline cooking and streams. Here is an example showing how to improve cooking speed if needed:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxConvexMeshDesc</span> <span class="n">convexDesc</span><span class="p">;</span>
<span class="n">convexDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">count</span>     <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="n">convexDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">stride</span>    <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">PxVec3</span><span class="p">);</span>
<span class="n">convexDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">data</span>      <span class="o">=</span> <span class="n">convexVerts</span><span class="p">;</span>
<span class="n">convexDesc</span><span class="p">.</span><span class="n">flags</span>            <span class="o">=</span> <span class="n">PxConvexFlag</span><span class="o">::</span><span class="n">eCOMPUTE_CONVEX</span> <span class="o">|</span> <span class="n">PxConvexFlag</span><span class="o">::</span><span class="n">eDISABLE_MESH_VALIDATION</span> <span class="o">|</span> <span class="n">PxConvexFlag</span><span class="o">::</span><span class="n">eFAST_INERTIA_COMPUTATION</span><span class="p">;</span>

<span class="cp">#ifdef _DEBUG</span>
    <span class="c1">// mesh should be validated before cooking without the mesh cleaning</span>
    <span class="kt">bool</span> <span class="n">res</span> <span class="o">=</span> <span class="n">theCooking</span><span class="o">-&gt;</span><span class="n">validateConvexMesh</span><span class="p">(</span><span class="n">convexDesc</span><span class="p">);</span>
    <span class="n">PX_ASSERT</span><span class="p">(</span><span class="n">res</span><span class="p">);</span>
<span class="cp">#endif</span>

<span class="n">PxConvexMesh</span><span class="o">*</span> <span class="n">aConvexMesh</span> <span class="o">=</span> <span class="n">theCooking</span><span class="o">-&gt;</span><span class="n">createConvexMesh</span><span class="p">(</span><span class="n">convexDesc</span><span class="p">,</span>
    <span class="n">thePhysics</span><span class="o">-&gt;</span><span class="n">getPhysicsInsertionCallback</span><span class="p">());</span>
</pre></div>
</div>
<p>Please note that mesh validation is required for debug and checked builds, as creating meshes from unvalidated input descriptors may result in undefined behavior. Providing PxConvexFlag::eFAST_INERTIA_COMPUTATION flag the volume integration will use SIMD code path which does faster computation but with lesser precision.</p>
<p>The user can optionally provide a per-instance PxMeshScale in the PxConvexMeshGeometry. The scale defaults to identity. Negative scale is not supported for convex meshes.</p>
<p>PxConvexMeshGeometry also contains flags to tweak some aspects of the convex object. By default the system computes approximate (loose) bounds around convex objects. Using PxConvexMeshGeometryFlag::eTIGHT_BOUNDS enables smaller/tighter bounds, which are more expensive to compute but could result in improved simulation performance when a lot of convex objects are interacting with each other.</p>
<p>PxConvexMeshGeometry also contains a variable called maxMargin. By default, it is set to be 3.4e38f. If the maxMargin is smaller than the margin amount calculcated by the PCM contact gen, it will choose the smallest margin for the shrunk shape to perform incremental update using GJK algorithm. In this case, application might notice some artefacts around the vertex collision. If the maxMargin is set to be a small value, this can reduce the visibility of these artefacts. If maxMargin is set to zero, PCM will use the original shape for the GJK algorithm. This will result in no artefacts for this approach. However, there is a trade off between performance and accuracy.</p>
</div>
<div class="section" id="convex-mesh-cooking">
<h3>Convex Mesh cooking<a class="headerlink" href="#convex-mesh-cooking" title="Permalink to this headline"></a></h3>
<p>Convex Mesh cooking transforms the mesh data into a form which allows the SDK to perform efficient collision detection. The input to cooking is defined using the input PxConvexMeshDesc.</p>
<p>There are different ways to fill in this structure, depending on whether you want to produce a convex mesh starting from just a cloud of vertices, or whether you have the vertices and faces of a polyhedron already.</p>
<div class="section" id="if-only-vertex-points-are-provided">
<h4>If Only Vertex Points are Provided<a class="headerlink" href="#if-only-vertex-points-are-provided" title="Permalink to this headline"></a></h4>
<p>When providing only vertices, set the PxConvexFlag::eCOMPUTE_CONVEX flag to compute the mesh:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxConvexMeshDesc</span> <span class="n">convexDesc</span><span class="p">;</span>
<span class="n">convexDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">count</span>     <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
<span class="n">convexDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">stride</span>    <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">PxVec3</span><span class="p">);</span>
<span class="n">convexDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">data</span>      <span class="o">=</span> <span class="n">convexVerts</span><span class="p">;</span>
<span class="n">convexDesc</span><span class="p">.</span><span class="n">flags</span>            <span class="o">=</span> <span class="n">PxConvexFlag</span><span class="o">::</span><span class="n">eCOMPUTE_CONVEX</span><span class="p">;</span>
<span class="n">convexDesc</span><span class="p">.</span><span class="n">maxVerts</span>         <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>

<span class="n">PxDefaultMemoryOutputStream</span> <span class="n">buf</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">cooking</span><span class="p">.</span><span class="n">cookConvexMesh</span><span class="p">(</span><span class="n">convexDesc</span><span class="p">,</span> <span class="n">buf</span><span class="p">))</span>
    <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
</pre></div>
</div>
<p>The algorithm tries to create a convex mesh from the source vertices. The field convexDesc.vertexLimit specifies the limit for the maximum number of vertices in the resulting hull.</p>
<p>This routine can sometimes fail when the source data is geometrically challenging, for example if it contains a lot of vertices close to each-other. If cooking fails, an error is reported to the error stream and the routine returns false.</p>
<p>If PxConvexFlag::eCHECK_ZERO_AREA_TRIANGLES is used, the algorithm does not include triangles with an area less than PxCookingParams::areaTestEpsilon. If the algorithm cannot find 4 initial vertices without a small triangle, PxConvexMeshCookingResult::eZERO_AREA_TEST_FAILED is returned. This means that the provided vertices were in a very small area and the cooker could not produce a valid hull.
The toolkit helper function PxToolkit::createConvexMeshSafe illustrates the most robust strategy for convex mesh cooking. First it tries to create the hull without inflation. If that fails it tries inflation, and if that also fails, uses an AABB or OBB.</p>
<p>It is recommended to provide vertices around origin and put transformation in PxShape, otherwise addional PxConvexFlag::eSHIFT_VERTICES flag for the mesh computation.</p>
<p>If huge amount of input vertices are provided, it might be useful to quantize the input vertices, in this case use PxConvexFlag::eQUANTIZE_INPUT and set the required PxConvexMeshDesc::quantizedCount.</p>
<p>Convex cooking supports two different algorithms:</p>
<div class="section" id="quickhull-algorithm">
<h5>Quickhull Algorithm<a class="headerlink" href="#quickhull-algorithm" title="Permalink to this headline"></a></h5>
<p>This algorithm does not use inflation. It creates a convex mesh whose vertices are a subset of the original vertices, and the number of vertices is guaranteed to be no more than the specified maximum.</p>
<p>The Quickhull algorithm performs these steps:</p>
<ul class="simple">
<li>Cleans the vertices - removes duplicates etc.</li>
<li>Finds a subset of vertices, no more than vertexLimit, that enclose the input set.</li>
<li>If the vertexLimit is reached, expand the limited hull around the input vertices to ensure we encapsulate all the input vertices.</li>
<li>Compute a vertex map table. (Requires at least 3 neighbor polygons for each vertex.)</li>
<li>Checks the polygon data - verifies that all vertices are on or inside the hull, etc.</li>
<li>Computes mass and inertia tensor assuming density is 1.</li>
<li>Saves data to stream.</li>
</ul>
<p>When the hull is constructed each new vertex added must be further than PxCookingParams::planeTolerance from the hull, if not that vertex is dropped.</p>
</div>
<div class="section" id="inflation-based-incremental-algorithm">
<h5>Inflation Based Incremental Algorithm<a class="headerlink" href="#inflation-based-incremental-algorithm" title="Permalink to this headline"></a></h5>
<p>This algorithm always uses the PxConvexFlag::eINFLATE_CONVEX flag and inflates the hull planes by PxCookingParams::skinWidth.</p>
<p>The Inflation Incremental Algorithm performs these steps:</p>
<ul class="simple">
<li>Cleans the vertices - removes duplicates etc.</li>
<li>Finds a subset of vertices, no more than vertexLimit, that enclose the input set.</li>
<li>Creates planes from the produced enclosed hull.</li>
<li>Inflates planes by defined PxCookingParams::skinWidth.</li>
<li>Crops the AABB by the inflated planes and produces a new hull.</li>
<li>Computes vertex map table. (Requires at least 3 neighbor polygons for each vertex.)</li>
<li>Checks polygon data - verifies all vertices are on or inside the hull, etc.</li>
<li>Computes mass and inertia tensor assuming density is 1.</li>
<li>Saves data to stream.</li>
</ul>
<p>Note that the inflation based algorithm can produce hulls with more input vertices. The algorithm is significantly slower than the quickhull and produces significantly less stable results. It is recommended to use the quickhull algorithm.</p>
</div>
<div class="section" id="vertex-limit-algorithms">
<h5>Vertex Limit Algorithms<a class="headerlink" href="#vertex-limit-algorithms" title="Permalink to this headline"></a></h5>
<p>If a vertex limit has been provided, there are two algorithms that handle vertex limitation.</p>
<p>The default algorithm computes the full hull, and an OBB around the input vertices. This OBB is then sliced with the hull planes until the vertex limit is reached. The default algorithm requires the vertex limit to be set to at least 8, and typically produces results that are much better quality than are produced by plane shifting.</p>
<p>When plane shifting is enabled (PxConvexFlag::ePLANE_SHIFTING), the hull computation stops when vertex limit is reached. The hull planes are then shifted to contain all input vertices, and the new plane intersection points are then used to generate the final hull with the given vertex limit. Plane shifting may produce sharp edges to vertices very far away from the input cloud, and does not guarantee that all input vertices are inside the resulting hull. However, it can be used with a vertex limit as low as 4, and so may be a better choice for cases such as small pieces of debris with very low vertex counts.</p>
</div>
</div>
<div class="section" id="vertex-points-indices-and-polygons-are-provided">
<h4>Vertex Points, Indices and Polygons are Provided<a class="headerlink" href="#vertex-points-indices-and-polygons-are-provided" title="Permalink to this headline"></a></h4>
<p>To create a PxConvexMesh given a set of input vertices (convexVerts) and polygons (hullPolygons):</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxConvexMeshDesc</span> <span class="n">convexDesc</span><span class="p">;</span>
<span class="n">convexDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">count</span>             <span class="o">=</span> <span class="mi">12</span><span class="p">;</span>
<span class="n">convexDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">stride</span>            <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">PxVec3</span><span class="p">);</span>
<span class="n">convexDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">data</span>              <span class="o">=</span> <span class="n">convexVerts</span><span class="p">;</span>
<span class="n">convexDescPolygons</span><span class="p">.</span><span class="n">polygons</span><span class="p">.</span><span class="n">count</span>   <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
<span class="n">convexDescPolygons</span><span class="p">.</span><span class="n">polygons</span><span class="p">.</span><span class="n">stride</span>  <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">PxHullPolygon</span><span class="p">);</span>
<span class="n">convexDescPolygons</span><span class="p">.</span><span class="n">polygons</span><span class="p">.</span><span class="n">data</span>    <span class="o">=</span> <span class="n">hullPolygons</span><span class="p">;</span>
<span class="n">convexDesc</span><span class="p">.</span><span class="n">flags</span>                    <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

<span class="n">PxDefaultMemoryOutputStream</span> <span class="n">buf</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">cooking</span><span class="p">.</span><span class="n">cookConvexMesh</span><span class="p">(</span><span class="n">convexDesc</span><span class="p">,</span> <span class="n">buf</span><span class="p">))</span>
    <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
</pre></div>
</div>
<p>When points and polygons are provided, the SDK validates the mesh and creates the PxConvexmesh directly. This is the fastest way to create a convex mesh. Note that the SDK requires at least 3 neighbor polygons for each vertex. Otherwise acceleration structure for PCM is not created and it does result in performance penalty if PCM is enabled.</p>
<p>(NOTE: the SDK should reject such a mesh as invalid)</p>
<p>Internal steps during convex cooking:</p>
<ul class="simple">
<li>Compute vertex map table, requires at least 3 neighbor polygons for each vertex.</li>
<li>Check polygons data - check if all vertices are on or inside the hull, etc.</li>
<li>Compute mass and inertia tensor assuming density 1.</li>
<li>Save data to stream.</li>
</ul>
</div>
</div>
<div class="section" id="triangle-meshes">
<h3>Triangle Meshes<a class="headerlink" href="#triangle-meshes" title="Permalink to this headline"></a></h3>
<img alt="../_images/GeomTypeMesh.png" src="../_images/GeomTypeMesh.png" />
<p>Like graphical triangle meshes, a collision triangle mesh consists of a collection of vertices and the triangle indices. Triangle mesh creation requires use of the cooking library. It is assumed here that the cooking library has already been initialized (see <a class="reference internal" href="Startup.html#startup"><em>Startup and Shutdown</em></a>.):</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxTriangleMeshDesc</span> <span class="n">meshDesc</span><span class="p">;</span>
<span class="n">meshDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">count</span>           <span class="o">=</span> <span class="n">nbVerts</span><span class="p">;</span>
<span class="n">meshDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">stride</span>          <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">PxVec3</span><span class="p">);</span>
<span class="n">meshDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">data</span>            <span class="o">=</span> <span class="n">verts</span><span class="p">;</span>

<span class="n">meshDesc</span><span class="p">.</span><span class="n">triangles</span><span class="p">.</span><span class="n">count</span>        <span class="o">=</span> <span class="n">triCount</span><span class="p">;</span>
<span class="n">meshDesc</span><span class="p">.</span><span class="n">triangles</span><span class="p">.</span><span class="n">stride</span>       <span class="o">=</span> <span class="mi">3</span><span class="o">*</span><span class="k">sizeof</span><span class="p">(</span><span class="n">PxU32</span><span class="p">);</span>
<span class="n">meshDesc</span><span class="p">.</span><span class="n">triangles</span><span class="p">.</span><span class="n">data</span>         <span class="o">=</span> <span class="n">indices32</span><span class="p">;</span>

<span class="n">PxDefaultMemoryOutputStream</span> <span class="n">writeBuffer</span><span class="p">;</span>
<span class="n">PxTriangleMeshCookingResult</span><span class="o">::</span><span class="n">Enum</span> <span class="n">result</span><span class="p">;</span>
<span class="kt">bool</span> <span class="n">status</span> <span class="o">=</span> <span class="n">cooking</span><span class="p">.</span><span class="n">cookTriangleMesh</span><span class="p">(</span><span class="n">meshDesc</span><span class="p">,</span> <span class="n">writeBuffer</span><span class="p">,</span><span class="n">result</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">status</span><span class="p">)</span>
    <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>

<span class="n">PxDefaultMemoryInputData</span> <span class="nf">readBuffer</span><span class="p">(</span><span class="n">writeBuffer</span><span class="p">.</span><span class="n">getData</span><span class="p">(),</span> <span class="n">writeBuffer</span><span class="p">.</span><span class="n">getSize</span><span class="p">());</span>
<span class="k">return</span> <span class="n">physics</span><span class="p">.</span><span class="n">createTriangleMesh</span><span class="p">(</span><span class="n">readBuffer</span><span class="p">);</span>
</pre></div>
</div>
<p>Alternatively <em>PxTriangleMesh</em> can be cooked and directly inserted into <em>PxPhysics</em> without stream serialization. This is useful if real-time cooking is required. It is strongly recommended to use offline cooking and streams. Example how to improve cooking speed if needed:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxTolerancesScale</span> <span class="n">scale</span><span class="p">;</span>
<span class="n">PxCookingParams</span> <span class="nf">params</span><span class="p">(</span><span class="n">scale</span><span class="p">);</span>
<span class="c1">// disable mesh cleaning - perform mesh validation on development configurations</span>
<span class="n">params</span><span class="p">.</span><span class="n">meshPreprocessParams</span> <span class="o">|=</span> <span class="n">PxMeshPreprocessingFlag</span><span class="o">::</span><span class="n">eDISABLE_CLEAN_MESH</span><span class="p">;</span>
<span class="c1">// disable edge precompute, edges are set for each triangle, slows contact generation</span>
<span class="n">params</span><span class="p">.</span><span class="n">meshPreprocessParams</span> <span class="o">|=</span> <span class="n">PxMeshPreprocessingFlag</span><span class="o">::</span><span class="n">eDISABLE_ACTIVE_EDGES_PRECOMPUTE</span><span class="p">;</span>
<span class="c1">// lower hierarchy for internal mesh</span>
<span class="n">params</span><span class="p">.</span><span class="n">meshCookingHint</span> <span class="o">=</span> <span class="n">PxMeshCookingHint</span><span class="o">::</span><span class="n">eCOOKING_PERFORMANCE</span><span class="p">;</span>

<span class="n">theCooking</span><span class="o">-&gt;</span><span class="n">setParams</span><span class="p">(</span><span class="n">params</span><span class="p">);</span>

<span class="n">PxTriangleMeshDesc</span> <span class="n">meshDesc</span><span class="p">;</span>
<span class="n">meshDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">count</span>           <span class="o">=</span> <span class="n">nbVerts</span><span class="p">;</span>
<span class="n">meshDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">stride</span>          <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">PxVec3</span><span class="p">);</span>
<span class="n">meshDesc</span><span class="p">.</span><span class="n">points</span><span class="p">.</span><span class="n">data</span>            <span class="o">=</span> <span class="n">verts</span><span class="p">;</span>

<span class="n">meshDesc</span><span class="p">.</span><span class="n">triangles</span><span class="p">.</span><span class="n">count</span>        <span class="o">=</span> <span class="n">triCount</span><span class="p">;</span>
<span class="n">meshDesc</span><span class="p">.</span><span class="n">triangles</span><span class="p">.</span><span class="n">stride</span>       <span class="o">=</span> <span class="mi">3</span><span class="o">*</span><span class="k">sizeof</span><span class="p">(</span><span class="n">PxU32</span><span class="p">);</span>
<span class="n">meshDesc</span><span class="p">.</span><span class="n">triangles</span><span class="p">.</span><span class="n">data</span>         <span class="o">=</span> <span class="n">indices32</span><span class="p">;</span>

<span class="cp">#ifdef _DEBUG</span>
    <span class="c1">// mesh should be validated before cooked without the mesh cleaning</span>
    <span class="kt">bool</span> <span class="n">res</span> <span class="o">=</span> <span class="n">theCooking</span><span class="o">-&gt;</span><span class="n">validateTriangleMesh</span><span class="p">(</span><span class="n">meshDesc</span><span class="p">);</span>
    <span class="n">PX_ASSERT</span><span class="p">(</span><span class="n">res</span><span class="p">);</span>
<span class="cp">#endif</span>

<span class="n">PxTriangleMesh</span><span class="o">*</span> <span class="n">aTriangleMesh</span> <span class="o">=</span> <span class="n">theCooking</span><span class="o">-&gt;</span><span class="n">createTriangleMesh</span><span class="p">(</span><span class="n">meshDesc</span><span class="p">,</span>
    <span class="n">thePhysics</span><span class="o">-&gt;</span><span class="n">getPhysicsInsertionCallback</span><span class="p">());</span>
</pre></div>
</div>
<p>Indices can be 16 or 32 bit. The strides used here assume that vertices and indices are arrays of PxVec3s and 32bit integers respectively with no gaps in the data layout.</p>
<p>Returned result enum <em>PxTriangleMeshCookingResult::eLARGE_TRIANGLE</em> does warn the user if the mesh contains large triangles, which should be tessellated to ensure better simulation and CCT stability.</p>
<p>Like height fields, triangle meshes support per-triangle material indices. To use per-triangle materials for a mesh, provide per-triangle indices to the cooking library in the mesh descriptor. Later, when creating the PxShape, supply a table mapping the index values in the mesh to material instances.</p>
<div class="section" id="triangle-mesh-cooking">
<h4>Triangle Mesh cooking<a class="headerlink" href="#triangle-mesh-cooking" title="Permalink to this headline"></a></h4>
<p>Triangle mesh cooking proceeds as follows:</p>
<ul class="simple">
<li>Check validity of input vertices.</li>
<li>Weld vertices and check triangle sizes.</li>
<li>create acceleration structure for queries.</li>
<li>Compute edge convexity information and adjacencies.</li>
<li>Save data to stream.</li>
</ul>
<p>Note that mesh cleaning may result in the set of triangles produced by cooking being a subset different from the original input set. Mesh cleaning removes invalid triangles (containing out-of-range vertex references), duplicate triangles, and zero-area triangles. When this happens, PhysX optionally outputs a mesh remapping table that links each internal triangle to its source triangle in the user's data.</p>
<p>There are multiple parameters to control mesh creation.</p>
<p>In <em>PxTriangleMeshDesc</em>:</p>
<ul class="simple">
<li><em>materialIndices</em> defines per triangle materials. When a triangle mesh collides with another object, a material is required at the collision point. If materialIndices is NULL, then the material of the PxShape instance is used.</li>
</ul>
<p>In <em>PxCookingParams</em>:</p>
<ul>
<li><p class="first"><em>scale</em> defines Tolerance scale is used to check if cooked triangles are not too huge. This check will help with simulation stability.</p>
</li>
<li><p class="first"><em>suppressTriangleMeshRemapTable</em> specifies whether the face remap table is created. If not, this saves a significant amount of memory, but the SDK will not be able to provide information about which original mesh triangle is hit in collisions, sweeps or raycasts hits.</p>
</li>
<li><p class="first"><em>buildTriangleAdjacencies</em> specifies if the triangle adjacency information is created. The adjacent triangles can be retrieved for a given triangle using the getTriangle.</p>
</li>
<li><dl class="first docutils">
<dt><em>meshPreprocessParams</em> specifies mesh pre-processing parameters.</dt>
<dd><ul class="first last simple">
<li><em>PxMeshPreprocessingFlag::eWELD_VERTICES</em> enables vertex welding during triangle mesh cooking.</li>
<li><em>PxMeshPreprocessingFlag::eDISABLE_CLEAN_MESH</em> disables mesh clean process. Vertices duplicities are not searched, huge triangles test is not done. Vertices welding is not done. Does speed up the cooking.</li>
<li><em>PxMeshPreprocessingFlag::eDISABLE_ACTIVE_EDGES_PRECOMPUTE</em> disables vertex edge precomputation. Makes cooking faster but slow up contact generation.</li>
</ul>
</dd>
</dl>
</li>
<li><p class="first"><em>meshWeldTolerance</em> - If mesh welding is enabled, this controls the distance at which vertices are welded. If mesh welding is not enabled, this value defines the acceptance distance for mesh validation. Provided no two vertices are within this distance, the mesh is considered to be clean. If not, a warning will be emitted. Having a clean mesh is required to achieve the best possible performance.</p>
</li>
<li><dl class="first docutils">
<dt><em>midphaseDesc</em> specifies the desired midphase acceleration structure descriptor.</dt>
<dd><ul class="first last simple">
<li><em>PxBVH33MidphaseDesc - PxMeshMidPhase::eBVH33</em> is the default structure. It was the one used in recent PhysX versions up to PhysX 3.3. It has great performance and is supported on all platforms.</li>
<li><em>PxBVH34MidphaseDesc - PxMeshMidPhase::eBVH34</em> is a revisited implementation introduced in PhysX 3.4. It can be significantly faster both in terms of cooking performance and runtime performance, but it is currently only available on platforms supporting the SSE2 instuction set.</li>
</ul>
</dd>
</dl>
</li>
</ul>
<p><em>PxBVH33MidphaseDesc params</em>:</p>
<ul class="simple">
<li><em>meshCookingHint</em> specifies mesh hierarchy construction preferences. Enables better cooking performance over collision performance, for applications where cooking performance is more important than best quality mesh creation.</li>
<li><em>meshSizePerformanceTradeOff</em> specifies the trade-off between mesh size and runtime performance.</li>
</ul>
<p><em>PxBVH34MidphaseDesc params</em>:</p>
<ul class="simple">
<li><em>numTrisPerLeaf</em> specifies the number of triangles per leaf. Less triangles per leaf produces larger meshes with general better runtime performance and worse cooking performance.</li>
</ul>
</div>
</div>
<div class="section" id="height-fields">
<h3>Height Fields<a class="headerlink" href="#height-fields" title="Permalink to this headline"></a></h3>
<img alt="../_images/GeomTypeHeightField.png" src="../_images/GeomTypeHeightField.png" />
<dl class="docutils">
<dt>Local space axes for the height fields are:</dt>
<dd><ul class="first last simple">
<li>Row - X axis</li>
<li>Column - Z axis</li>
<li>Height - Y axis</li>
</ul>
</dd>
</dl>
<p>As the name suggests, terrains can be described by just the height values on a regular, rectangular sampling grid:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxHeightFieldSample</span><span class="o">*</span> <span class="n">samples</span> <span class="o">=</span> <span class="p">(</span><span class="n">PxHeightFieldSample</span><span class="o">*</span><span class="p">)</span><span class="n">alloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">PxHeightFieldSample</span><span class="p">)</span><span class="o">*</span>
    <span class="p">(</span><span class="n">numRows</span><span class="o">*</span><span class="n">numCols</span><span class="p">));</span>
</pre></div>
</div>
<p>Each sample consists of a 16 bit integer height value, two materials (for the two triangles in the samples rectangle) and a tessellation flag.</p>
<p>The flag and materials refer to the cell below and to the right of the sample point, and indicate along which diagonal to split it into triangles, and the materials of those triangles.  A special predefined material <tt class="docutils literal"><span class="pre">PxHeightFieldMaterial::eHOLE</span></tt> specifies a hole in the height field. See the reference documentation for <em>PxHeightFieldSample</em> for more details.</p>
<table border="1" class="docutils">
<colgroup>
<col width="50%" />
<col width="50%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Tesselation flag not set</th>
<th class="head">Tesselation flag set</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><img alt="../_images/heightfieldTriMat1.png" class="first last" src="../_images/heightfieldTriMat1.png" />
</td>
<td><img alt="../_images/heightfieldTriMat2.png" class="first last" src="../_images/heightfieldTriMat2.png" />
</td>
</tr>
</tbody>
</table>
<p>Examples:</p>
<table border="1" class="docutils">
<colgroup>
<col width="31%" />
<col width="69%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Tesselation flags</th>
<th class="head">Result</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><div class="first last line-block">
<div class="line">0,0,0</div>
<div class="line">0,0,0</div>
<div class="line">0,0,0</div>
</div>
</td>
<td><img alt="../_images/heightfieldTess2.png" class="first last" src="../_images/heightfieldTess2.png" />
</td>
</tr>
<tr class="row-odd"><td><div class="first last line-block">
<div class="line">1,1,1</div>
<div class="line">1,1,1</div>
<div class="line">1,1,1</div>
</div>
</td>
<td><img alt="../_images/heightfieldTess1.png" class="first last" src="../_images/heightfieldTess1.png" />
</td>
</tr>
<tr class="row-even"><td><div class="first last line-block">
<div class="line">1,0,1</div>
<div class="line">0,1,0</div>
<div class="line">1,0,1</div>
</div>
</td>
<td><img alt="../_images/heightfieldTess3.png" class="first last" src="../_images/heightfieldTess3.png" />
</td>
</tr>
</tbody>
</table>
<p>To tell the system the number of sampled heights in each direction, use a descriptor to instantiate a PxHeightField object:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxHeightFieldDesc</span> <span class="n">hfDesc</span><span class="p">;</span>
<span class="n">hfDesc</span><span class="p">.</span><span class="n">format</span>             <span class="o">=</span> <span class="n">PxHeightFieldFormat</span><span class="o">::</span><span class="n">eS16_TM</span><span class="p">;</span>
<span class="n">hfDesc</span><span class="p">.</span><span class="n">nbColumns</span>          <span class="o">=</span> <span class="n">numCols</span><span class="p">;</span>
<span class="n">hfDesc</span><span class="p">.</span><span class="n">nbRows</span>             <span class="o">=</span> <span class="n">numRows</span><span class="p">;</span>
<span class="n">hfDesc</span><span class="p">.</span><span class="n">samples</span><span class="p">.</span><span class="n">data</span>       <span class="o">=</span> <span class="n">samples</span><span class="p">;</span>
<span class="n">hfDesc</span><span class="p">.</span><span class="n">samples</span><span class="p">.</span><span class="n">stride</span>     <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">PxHeightFieldSample</span><span class="p">);</span>

<span class="n">PxHeightField</span><span class="o">*</span> <span class="n">aHeightField</span> <span class="o">=</span> <span class="n">theCooking</span><span class="o">-&gt;</span><span class="n">createHeightField</span><span class="p">(</span><span class="n">hfDesc</span><span class="p">,</span>
    <span class="n">thePhysics</span><span class="o">-&gt;</span><span class="n">getPhysicsInsertionCallback</span><span class="p">());</span>
</pre></div>
</div>
<p>Now create a PxHeightFieldGeometry and a shape:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxHeightFieldGeometry</span> <span class="nf">hfGeom</span><span class="p">(</span><span class="n">aHeightField</span><span class="p">,</span> <span class="n">PxMeshGeometryFlags</span><span class="p">(),</span> <span class="n">heightScale</span><span class="p">,</span> <span class="n">rowScale</span><span class="p">,</span>
    <span class="n">colScale</span><span class="p">);</span>
<span class="n">PxShape</span><span class="o">*</span> <span class="n">aHeightFieldShape</span> <span class="o">=</span> <span class="n">PxRigidActorExt</span><span class="o">::</span><span class="n">createExclusiveShape</span><span class="p">(</span><span class="o">*</span><span class="n">aHeightFieldActor</span><span class="p">,</span>
    <span class="n">hfGeom</span><span class="p">,</span> <span class="n">aMaterialArray</span><span class="p">,</span> <span class="n">nbMaterials</span><span class="p">);</span>
</pre></div>
</div>
<p>The row and column scales tell the system how far apart the sampled points lie in the associated direction. The height scale scales the integer height values to a floating point range.</p>
<p>The variant of <em>createExclusiveShape()</em> used here specifies an array of materials for the height field, which will be indexed by the material indices of each cell to resolve collisions with that cell. The single-material variant may be used instead, but the height field material indices must all be a single value or the special value <tt class="docutils literal"><span class="pre">eHOLE</span></tt>.</p>
<p>Contact generation with triangle edges at the terrain's borders can be disabled using the <em>PxHeightFieldFlag::eNO_BOUNDARY_EDGES</em> flag, allowing more efficient contact generation when there are multiple heightfield shapes arranged so that their edges touch.</p>
<div class="section" id="heightfield-cooking">
<h4>Heightfield cooking<a class="headerlink" href="#heightfield-cooking" title="Permalink to this headline"></a></h4>
<p>Heightfield data can be cooked in offline and then used to createHeightField. The cooking does precompute and store the edge information. This allows much faster create of the heightfield, since the edges are already precomputed. It is very useful if you need to create heightfields in the runtime, since it does improve the speed of createHeightField significantly.</p>
<p>Heightfield cooking proceeds as follows:</p>
<ul class="simple">
<li>Load heightfield samples into internal memory.</li>
<li>Precompute edge collision information.</li>
<li>Save data to stream.</li>
</ul>
</div>
<div class="section" id="unified-heightfields">
<h4>Unified Heightfields<a class="headerlink" href="#unified-heightfields" title="Permalink to this headline"></a></h4>
<p>PhysX provides two contact generation approaches for heightfields. These are:</p>
<ul class="simple">
<li>Default unified heightfield contact generation.</li>
<li>Legacy heightfield contact generation.</li>
</ul>
<p>The default unified heightfield contact generation approach extracts triangles from the heightfield and utilizes the same low-level contact generation code that is used for contact generation against triangle meshes. This approach ensures equivalent behavior and performance if triangle meshes or heightfields are used interchangeably. However, with this approach, the heightfield surface has no thickness so fast-moving objects may tunnel if CCD is not enabled.</p>
<p>The legacy heightfield collision code, which was default in previous versions of PhysX, works differently from triangle mesh contact generation. In addition to generating contacts with shapes touching the surface of the heightfield, it generates contacts with shapes that are beneath the surface. The heightfield's &quot;thickness&quot; is used to control how far beneath the surface contacts are generated. This works by extruding the AABB of the heightfield in the broad phase by the &quot;thickness&quot; along the vertical axis. Contacts are generated for any shape below the surface whose bounds intersects the heightfields extruded bounds.</p>
<p>Unified heightfield contact generation is enabled by calling:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxRegisterHeightFields</span><span class="p">(</span><span class="n">PxPhysics</span><span class="o">&amp;</span> <span class="n">physics</span><span class="p">);</span>
</pre></div>
</div>
<p>Legacy heightfield contact generation is enabled by calling:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxRegisterLegacyHeightFields</span><span class="p">(</span><span class="n">PxPhysics</span><span class="o">&amp;</span> <span class="n">physics</span><span class="p">);</span>
</pre></div>
</div>
<p>These calls must be made before and scenes have been created, otherwise warnings will be issued. The heightfield collision setting is a global setting, and it applies to all scenes.</p>
<p>If PxCreatePhysics(...) is called, this will automatically call PxRegisterHeightFields(...) to register the default, unified heightfield collision approach. If PxCreateBasePhysics(...) is called, no heightfield contact generation is registered by default. If heightfields are used, the application must call the appropriate heightfield registration function.</p>
</div>
</div>
</div>
<div class="section" id="deformable-meshes">
<h2>Deformable meshes<a class="headerlink" href="#deformable-meshes" title="Permalink to this headline"></a></h2>
<p>PhysX supports deformable meshes, i.e. meshes whose vertices move over time (while the topology, i.e. the triangle indices, remains fixed).</p>
<p>Deformable meshes are only supported with the <em>PxMeshMidPhase::eBVH33</em> data structure. Because the mesh vertices are going to be updated, the mapping between the user-defined vertices and PhysX' internal vertices must also be preserved. That is, PhysX should not reorder vertices during cooking. So all cooking operations that could reorder vertices should be disabled, and it is the user's responsability to make sure that the passed vertices are correct w.r.t. disabled operations. For example the mesh cleaning phase should be disabled:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">cookingParams</span><span class="p">.</span><span class="n">midphaseDesc</span><span class="p">.</span><span class="n">setToDefault</span><span class="p">(</span><span class="n">PxMeshMidPhase</span><span class="o">::</span><span class="n">eBVH33</span><span class="p">);</span>
    <span class="n">cookingParams</span><span class="p">.</span><span class="n">meshPreprocessParams</span>      <span class="o">=</span> <span class="n">PxMeshPreprocessingFlag</span><span class="o">::</span><span class="n">eDISABLE_CLEAN_MESH</span><span class="p">;</span>
</pre></div>
</div>
<p>It is possible to mix eBVH33 and eBVH34 meshes in the same scene, so the default cooking parameters can still be used for non-deformable / static meshes.</p>
<p>To modify the vertices, use the <em>PxTriangleMesh::getVerticesForModification()</em> and <em>PxTriangleMesh::refitBVH()</em> functions before simulating the scene:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="c1">// get vertex array</span>
<span class="n">PxVec3</span><span class="o">*</span> <span class="n">verts</span> <span class="o">=</span> <span class="n">mesh</span><span class="o">-&gt;</span><span class="n">getVerticesForModification</span><span class="p">();</span>

<span class="c1">// update the vertices here</span>
<span class="p">...</span>

<span class="c1">// tell PhysX to update the mesh structure</span>
<span class="n">PxBounds3</span> <span class="n">newBounds</span> <span class="o">=</span> <span class="n">mesh</span><span class="o">-&gt;</span><span class="n">refitBVH</span><span class="p">();</span>
</pre></div>
</div>
<p>Then use <em>PxScene::resetFiltering()</em> for the corresponding mesh actor, to tell the broadphase its bounds have been modified:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">scene</span><span class="o">-&gt;</span><span class="n">resetFiltering</span><span class="p">(</span><span class="o">*</span><span class="n">actor</span><span class="p">);</span>
</pre></div>
</div>
<p>When the mesh deforms and moves away from the objects resting on it, said meshes can bounce and jitter slightly on the mesh. Using a slightly negative rest offset for the mesh shape can help reduce this effect:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxShape</span><span class="o">*</span> <span class="n">shape</span><span class="p">;</span>
<span class="n">mesh</span><span class="o">-&gt;</span><span class="n">getShapes</span><span class="p">(</span><span class="o">&amp;</span><span class="n">shape</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="n">shape</span><span class="o">-&gt;</span><span class="n">setRestOffset</span><span class="p">(</span><span class="o">-</span><span class="mf">0.5f</span><span class="p">);</span>   <span class="c1">// something negative, value depends on your game&#39;s scale</span>
</pre></div>
</div>
<p>This will let objects &quot;sink&quot; a bit into the dynamic mesh. That way contacts are not immediately lost and the motion remains smooth. Please refer to the deformable mesh snippet in the SDK for more details.</p>
</div>
<div class="section" id="mesh-scaling">
<h2>Mesh Scaling<a class="headerlink" href="#mesh-scaling" title="Permalink to this headline"></a></h2>
<p>A shared PxTriangleMesh or PxConvexMesh may be stretched or compressed when it is instanced by a geometry. This allows multiple instancing of the same mesh with different scale factors applied.  Scaling is specified with the PxMeshScale class, which defines scale factors to be applied along 3 orthogonal axes. A factor greater than 1.0 results in stretching, while a factor less than 1.0 results in compression. The directions of the axes are governed by a quaternion, and specified in the local frame of the shape.</p>
<p>Negative mesh scale is supported, with negative values producing a reflection along each corresponding axis. In addition PhysX will flip the normals for mesh triangles when scale.x*scale.y*scale.z &lt; 0.</p>
<p>The following code creates a shape with a PxTriangleMesh scaled by a factor of x along the x-axis, y along the y-axis, and z along the z-axis:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="c1">// created earlier</span>
<span class="n">PxRigidActor</span><span class="o">*</span> <span class="n">myActor</span><span class="p">;</span>
<span class="n">PxTriangleMesh</span><span class="o">*</span> <span class="n">myTriMesh</span><span class="p">;</span>
<span class="n">PxMaterial</span><span class="o">*</span> <span class="n">myMaterial</span><span class="p">;</span>

<span class="c1">// create a shape instancing a triangle mesh at the given scale</span>
<span class="n">PxMeshScale</span> <span class="nf">scale</span><span class="p">(</span><span class="n">PxVec3</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">,</span><span class="n">z</span><span class="p">),</span> <span class="n">PxQuat</span><span class="p">(</span><span class="n">PxIdentity</span><span class="p">));</span>
<span class="n">PxTriangleMeshGeometry</span> <span class="nf">geom</span><span class="p">(</span><span class="n">myTriMesh</span><span class="p">,</span><span class="n">scale</span><span class="p">);</span>
<span class="n">PxShape</span><span class="o">*</span> <span class="n">myTriMeshShape</span> <span class="o">=</span> <span class="n">PxRigidActorExt</span><span class="o">::</span><span class="n">createExclusiveShape</span><span class="p">(</span><span class="o">*</span><span class="n">myActor</span><span class="p">,</span><span class="n">geom</span><span class="p">,</span><span class="o">*</span><span class="n">myMaterial</span><span class="p">);</span>
</pre></div>
</div>
<p>Convex meshes are scaled using the PxMeshScale class in a similar manner.  The following code creates a shape with a PxConvexMesh scaled by a factor of x along (sqrt(1/2), 1.0, -sqrt(1/2)), by a factor of y along (0,1,0) and a by a factor of z along (sqrt(1/2), 1.0, sqrt(1/2)):</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxMeshScale</span> <span class="nf">scale</span><span class="p">(</span><span class="n">PxVec3</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">,</span><span class="n">z</span><span class="p">),</span> <span class="n">PxQuat</span> <span class="n">quat</span><span class="p">(</span><span class="n">PxPi</span><span class="o">*</span><span class="mf">0.25f</span><span class="p">,</span> <span class="n">PxVec3</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">)));</span>
<span class="n">PxConvexMeshGeometry</span> <span class="nf">geom</span><span class="p">(</span><span class="n">myTriMesh</span><span class="p">,</span><span class="n">scale</span><span class="p">);</span>
<span class="n">PxShape</span><span class="o">*</span> <span class="n">myConvexMeshShape</span> <span class="o">=</span> <span class="n">PxRigidActorExt</span><span class="o">::</span><span class="n">createExclusiveShape</span><span class="p">(</span><span class="o">*</span><span class="n">myActor</span><span class="p">,</span><span class="n">geom</span><span class="p">,</span><span class="o">*</span><span class="n">myMaterial</span><span class="p">);</span>
</pre></div>
</div>
<p>Height fields can also be scaled, using scale factors stored in PxHeightFieldGeometry. In this case the scale is assumed to be along the axes of the rows, columns and height directions of the height field. The scaling of is demonstrated in SampleNorthPole in SampleNorthPoleBuilder.cpp:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxHeightFieldGeometry</span> <span class="nf">hfGeom</span><span class="p">(</span><span class="n">heightField</span><span class="p">,</span> <span class="n">PxMeshGeometryFlags</span><span class="p">(),</span> <span class="n">heightScale</span><span class="p">,</span> <span class="n">hfScale</span><span class="p">,</span> <span class="n">hfScale</span><span class="p">);</span>
<span class="n">PxShape</span><span class="o">*</span> <span class="n">hfShape</span> <span class="o">=</span> <span class="n">PxRigidActorExt</span><span class="o">::</span><span class="n">createExclusiveShape</span><span class="p">(</span><span class="o">*</span><span class="n">hfActor</span><span class="p">,</span> <span class="n">hfGeom</span><span class="p">,</span> <span class="n">getDefaultMaterial</span><span class="p">());</span>
</pre></div>
</div>
<p>In this example, the coordinates along the x and z axes are scaled by hfScale, while the sample heights are scaled by heightScale.</p>
</div>
<div class="section" id="pxgeometryholder">
<h2>PxGeometryHolder<a class="headerlink" href="#pxgeometryholder" title="Permalink to this headline"></a></h2>
<p>When a geometry is provided for a shape, either on creation or with <em>PxShape::setGeometry()</em>, the geometry is copied into the SDK's internal structures. If you know the type of a shape's geometry you may retrieve it directly:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxBoxGeometry</span> <span class="n">boxGeom</span><span class="p">;</span>
<span class="kt">bool</span> <span class="n">status</span> <span class="o">=</span> <span class="n">shape</span><span class="o">-&gt;</span><span class="n">getBoxGeometry</span><span class="p">(</span><span class="n">geometry</span><span class="p">);</span>
</pre></div>
</div>
<p>The status return code is set to false if the shape's geometry is not of the expected type.</p>
<p>However, it is often convenient to retrieve a geometry object from a shape without first knowing its type - for example, to call a function which takes a PxGeometry reference as an argument.</p>
<p>PxGeometryHolder is a union-like class that allows the return of a PxGeometry object by value, regardless of type. Its use is illustrated in the <em>createRenderObjectFromShape()</em> function in PhysXSample.cpp:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxGeometryHolder</span> <span class="n">geom</span> <span class="o">=</span> <span class="n">shape</span><span class="o">-&gt;</span><span class="n">getGeometry</span><span class="p">();</span>

<span class="k">switch</span><span class="p">(</span><span class="n">geom</span><span class="p">.</span><span class="n">getType</span><span class="p">())</span>
<span class="p">{</span>
<span class="k">case</span> <span class="n">PxGeometryType</span>:<span class="o">:</span><span class="n">eSPHERE</span><span class="o">:</span>
    <span class="n">shapeRenderActor</span> <span class="o">=</span> <span class="n">SAMPLE_NEW</span><span class="p">(</span><span class="n">RenderSphereActor</span><span class="p">)(</span><span class="n">renderer</span><span class="p">,</span> <span class="n">geom</span><span class="p">.</span><span class="n">sphere</span><span class="p">().</span><span class="n">radius</span><span class="p">);</span>
    <span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="n">PxGeometryType</span>:<span class="o">:</span><span class="n">eCAPSULE</span><span class="o">:</span>
    <span class="n">shapeRenderActor</span> <span class="o">=</span> <span class="n">SAMPLE_NEW</span><span class="p">(</span><span class="n">RenderCapsuleActor</span><span class="p">)(</span><span class="n">renderer</span><span class="p">,</span> <span class="n">geom</span><span class="p">.</span><span class="n">capsule</span><span class="p">().</span><span class="n">radius</span><span class="p">,</span>
        <span class="n">geom</span><span class="p">.</span><span class="n">capsule</span><span class="p">().</span><span class="n">halfHeight</span><span class="p">);</span>
    <span class="k">break</span><span class="p">;</span>
<span class="p">...</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The function <em>PxGeometryHolder::any()</em> returns a reference to a PxGeometry object. For example, to compare two shapes in a scene for overlap:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="kt">bool</span> <span class="nf">testForOverlap</span><span class="p">(</span><span class="k">const</span> <span class="n">PxShape</span><span class="o">&amp;</span> <span class="n">s0</span><span class="p">,</span> <span class="k">const</span> <span class="n">PxShape</span><span class="o">&amp;</span> <span class="n">s1</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="n">PxGeometryQuery</span><span class="o">::</span><span class="n">overlap</span><span class="p">(</span><span class="n">s0</span><span class="p">.</span><span class="n">getGeometry</span><span class="p">().</span><span class="n">any</span><span class="p">(),</span> <span class="n">PxShapeExt</span><span class="o">::</span><span class="n">getGlobalPose</span><span class="p">(</span><span class="n">s0</span><span class="p">),</span>
                                    <span class="n">s1</span><span class="p">.</span><span class="n">getGeometry</span><span class="p">().</span><span class="n">any</span><span class="p">(),</span> <span class="n">PxShapeExt</span><span class="o">::</span><span class="n">getGlobalPose</span><span class="p">(</span><span class="n">s1</span><span class="p">));</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="vertex-and-face-data">
<h2>Vertex and Face Data<a class="headerlink" href="#vertex-and-face-data" title="Permalink to this headline"></a></h2>
<p>Convex meshes, triangle meshes, and height fields can all be queried for vertex and face data.  This is particularly useful, for example, when rendering the mesh of the convex shape. The function:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">RenderBaseActor</span><span class="o">*</span> <span class="n">PhysXSample</span><span class="o">::</span><span class="n">createRenderObjectFromShape</span><span class="p">(</span><span class="n">PxShape</span><span class="o">*</span> <span class="n">shape</span><span class="p">,</span>
    <span class="n">RenderMaterial</span><span class="o">*</span> <span class="n">material</span><span class="p">)</span>
</pre></div>
</div>
<p>in PhysXSample.cpp contains a switch statement with a case for each shape type, illustrating the steps required to query the vertices and faces.</p>
<p>It is possible to get information about triangle from a triangle mesh or height field using PxMeshQuery::getTriangle function. You can also retrieve adjacent triangle indices for the given triangle (triangle triangleNeighbour[i] shares the edge vertex[i]-vertex[(i+1)%3] with triangle indexed as 'triangleIndex', where vertex is in the range from 0 to 2). To enable this feature the triangle mesh is cooked with buildTriangleAdjacencies parameter set to true.</p>
<div class="section" id="id2">
<h3>Convex Meshes<a class="headerlink" href="#id2" title="Permalink to this headline"></a></h3>
<p>A convex mesh contains an array of vertices, an array of faces, and an index buffer which concatenates the vertex indices for each face. To unpack a convex mesh, the first step is to extract the shared convex mesh:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxConvexMesh</span><span class="o">*</span> <span class="n">convexMesh</span> <span class="o">=</span> <span class="n">geom</span><span class="p">.</span><span class="n">convexMesh</span><span class="p">().</span><span class="n">convexMesh</span><span class="p">;</span>
</pre></div>
</div>
<p>Then obtain references to the vertex and index buffers:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxU32</span> <span class="n">nbVerts</span> <span class="o">=</span> <span class="n">convexMesh</span><span class="o">-&gt;</span><span class="n">getNbVertices</span><span class="p">();</span>
<span class="k">const</span> <span class="n">PxVec3</span><span class="o">*</span> <span class="n">convexVerts</span> <span class="o">=</span> <span class="n">convexMesh</span><span class="o">-&gt;</span><span class="n">getVertices</span><span class="p">();</span>
<span class="k">const</span> <span class="n">PxU8</span><span class="o">*</span> <span class="n">indexBuffer</span> <span class="o">=</span> <span class="n">convexMesh</span><span class="o">-&gt;</span><span class="n">getIndexBuffer</span><span class="p">();</span>
</pre></div>
</div>
<p>Now iterate over the array of faces to triangulate them:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxU32</span> <span class="n">offset</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="n">PxU32</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">nbPolygons</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">PxHullPolygon</span> <span class="n">face</span><span class="p">;</span>
    <span class="kt">bool</span> <span class="n">status</span> <span class="o">=</span> <span class="n">convexMesh</span><span class="o">-&gt;</span><span class="n">getPolygonData</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">face</span><span class="p">);</span>
    <span class="n">PX_ASSERT</span><span class="p">(</span><span class="n">status</span><span class="p">);</span>

    <span class="k">const</span> <span class="n">PxU8</span><span class="o">*</span> <span class="n">faceIndices</span> <span class="o">=</span> <span class="n">indexBuffer</span> <span class="o">+</span> <span class="n">face</span><span class="p">.</span><span class="n">mIndexBase</span><span class="p">;</span>
    <span class="k">for</span><span class="p">(</span><span class="n">PxU32</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">face</span><span class="p">.</span><span class="n">mNbVerts</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">vertices</span><span class="p">[</span><span class="n">offset</span><span class="o">+</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">convexVerts</span><span class="p">[</span><span class="n">faceIndices</span><span class="p">[</span><span class="n">j</span><span class="p">]];</span>
        <span class="n">normals</span><span class="p">[</span><span class="n">offset</span><span class="o">+</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">PxVec3</span><span class="p">(</span><span class="n">face</span><span class="p">.</span><span class="n">mPlane</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">face</span><span class="p">.</span><span class="n">mPlane</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">face</span><span class="p">.</span><span class="n">mPlane</span><span class="p">[</span><span class="mi">2</span><span class="p">]);</span>
    <span class="p">}</span>

    <span class="k">for</span><span class="p">(</span><span class="n">PxU32</span> <span class="n">j</span><span class="o">=</span><span class="mi">2</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">face</span><span class="p">.</span><span class="n">mNbVerts</span><span class="p">;</span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="o">*</span><span class="n">triangles</span><span class="o">++</span> <span class="o">=</span> <span class="n">PxU16</span><span class="p">(</span><span class="n">offset</span><span class="p">);</span>
        <span class="o">*</span><span class="n">triangles</span><span class="o">++</span> <span class="o">=</span> <span class="n">PxU16</span><span class="p">(</span><span class="n">offset</span><span class="o">+</span><span class="n">j</span><span class="p">);</span>
        <span class="o">*</span><span class="n">triangles</span><span class="o">++</span> <span class="o">=</span> <span class="n">PxU16</span><span class="p">(</span><span class="n">offset</span><span class="o">+</span><span class="n">j</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="n">offset</span> <span class="o">+=</span> <span class="n">face</span><span class="p">.</span><span class="n">mNbVerts</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Observe that the vertex indices of the polygon begin at indexBuffer[face.mIndexBase], and the count of vertices is given by face.mNbVerts.</p>
</div>
<div class="section" id="id3">
<h3>Triangle Meshes<a class="headerlink" href="#id3" title="Permalink to this headline"></a></h3>
<p>Triangle meshes contain arrays of vertices and index triplets which define the triangles by indexing into the vertex buffer. The arrays can be accessed directly from the shared triangle mesh:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxTriangleMesh</span><span class="o">*</span> <span class="n">tm</span> <span class="o">=</span> <span class="n">geom</span><span class="p">.</span><span class="n">triangleMesh</span><span class="p">().</span><span class="n">triangleMesh</span><span class="p">;</span>
<span class="k">const</span> <span class="n">PxU32</span> <span class="n">nbVerts</span> <span class="o">=</span> <span class="n">tm</span><span class="o">-&gt;</span><span class="n">getNbVertices</span><span class="p">();</span>
<span class="k">const</span> <span class="n">PxVec3</span><span class="o">*</span> <span class="n">verts</span> <span class="o">=</span> <span class="n">tm</span><span class="o">-&gt;</span><span class="n">getVertices</span><span class="p">();</span>
<span class="k">const</span> <span class="n">PxU32</span> <span class="n">nbTris</span> <span class="o">=</span> <span class="n">tm</span><span class="o">-&gt;</span><span class="n">getNbTriangles</span><span class="p">();</span>
<span class="k">const</span> <span class="kt">void</span><span class="o">*</span> <span class="n">tris</span> <span class="o">=</span> <span class="n">tm</span><span class="o">-&gt;</span><span class="n">getTriangles</span><span class="p">();</span>
</pre></div>
</div>
<p>The indices may be stored with either 16-bit or 32-bit values, specified when the mesh was originally cooked. To determine the storage format at runtime, use the API call:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">const</span> <span class="kt">bool</span> <span class="n">has16bitIndices</span> <span class="o">=</span> <span class="n">tm</span><span class="o">-&gt;</span><span class="n">has16BitTriangleIndices</span><span class="p">();</span>
</pre></div>
</div>
<p>Assuming that the triangle indices are stored in 16-bit format, find the jth vertex of the ith triangle by:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">const</span> <span class="n">PxU16</span><span class="o">*</span> <span class="n">triIndices</span> <span class="o">=</span> <span class="p">(</span><span class="k">const</span> <span class="n">PxU16</span><span class="o">*</span><span class="p">)</span><span class="n">tris</span><span class="p">;</span>
<span class="k">const</span> <span class="n">PxU16</span> <span class="n">index</span> <span class="o">=</span> <span class="n">triIndices</span><span class="p">[</span><span class="mi">3</span><span class="o">*</span><span class="n">i</span> <span class="o">+</span><span class="n">j</span><span class="p">];</span>
</pre></div>
</div>
<p>The corresponding vertex is:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">const</span> <span class="n">PxVec3</span><span class="o">&amp;</span> <span class="n">vertex</span> <span class="o">=</span> <span class="n">verts</span><span class="p">[</span><span class="n">index</span><span class="p">];</span>
</pre></div>
</div>
</div>
<div class="section" id="id4">
<h3>Height Fields<a class="headerlink" href="#id4" title="Permalink to this headline"></a></h3>
<p>The storage of height field data is platform-dependent, and therefore direct access to the height field samples is not provided. Instead, calls are provided to render the samples to a user-supplied buffer.</p>
<p>Again, the first step is to retrieve the geometry for the height field:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">const</span> <span class="n">PxHeightFieldGeometry</span><span class="o">&amp;</span> <span class="n">geometry</span> <span class="o">=</span> <span class="n">geom</span><span class="p">.</span><span class="n">heightField</span><span class="p">();</span>
</pre></div>
</div>
<p>The height field has three scaling parameters:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">const</span> <span class="n">PxReal</span>    <span class="n">rs</span> <span class="o">=</span> <span class="n">geometry</span><span class="p">.</span><span class="n">rowScale</span><span class="p">;</span>
<span class="k">const</span> <span class="n">PxReal</span>    <span class="n">hs</span> <span class="o">=</span> <span class="n">geometry</span><span class="p">.</span><span class="n">heightScale</span><span class="p">;</span>
<span class="k">const</span> <span class="n">PxReal</span>    <span class="n">cs</span> <span class="o">=</span> <span class="n">geometry</span><span class="p">.</span><span class="n">columnScale</span><span class="p">;</span>
</pre></div>
</div>
<p>And a shared data structure, which stores the row and column count:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxHeightField</span><span class="o">*</span>  <span class="n">hf</span> <span class="o">=</span> <span class="n">geometry</span><span class="p">.</span><span class="n">heightField</span><span class="p">;</span>
<span class="k">const</span> <span class="n">PxU32</span>     <span class="n">nbCols</span> <span class="o">=</span> <span class="n">hf</span><span class="o">-&gt;</span><span class="n">getNbColumns</span><span class="p">();</span>
<span class="k">const</span> <span class="n">PxU32</span>     <span class="n">nbRows</span> <span class="o">=</span> <span class="n">hf</span><span class="o">-&gt;</span><span class="n">getNbRows</span><span class="p">();</span>
</pre></div>
</div>
<p>To render the height field, first extract the samples to an array:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="k">const</span> <span class="n">PxU32</span> <span class="n">nbVerts</span> <span class="o">=</span> <span class="n">nbRows</span> <span class="o">*</span> <span class="n">nbCols</span><span class="p">;</span>
<span class="n">PxHeightFieldSample</span><span class="o">*</span> <span class="n">sampleBuffer</span> <span class="o">=</span> <span class="k">new</span> <span class="n">PxHeightFieldSample</span><span class="p">[</span><span class="n">nbVerts</span><span class="p">];</span>
<span class="n">hf</span><span class="o">-&gt;</span><span class="n">saveCells</span><span class="p">(</span><span class="n">sampleBuffer</span><span class="p">,</span> <span class="n">nbVerts</span> <span class="o">*</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">PxHeightFieldSample</span><span class="p">));</span>
</pre></div>
</div>
<p>The samples are stored in row-major order; that is, row0 is stored first, followed by row1, then row2, and so on. Thus the sample corresponding to the ith row and the jth column is i*nbCols + j.</p>
<p>Evaluate the scaled vertices of the height field as follows:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxVec3</span><span class="o">*</span> <span class="n">vertices</span> <span class="o">=</span> <span class="k">new</span> <span class="n">PxVec3</span><span class="p">[</span><span class="n">nbVerts</span><span class="p">];</span>
<span class="k">for</span><span class="p">(</span><span class="n">PxU32</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">nbRows</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">for</span><span class="p">(</span><span class="n">PxU32</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">nbCols</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">vertices</span><span class="p">[</span><span class="n">i</span> <span class="o">*</span> <span class="n">nbCols</span> <span class="o">+</span> <span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">PxVec3</span><span class="p">(</span><span class="n">PxReal</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="o">*</span> <span class="n">rs</span><span class="p">,</span> <span class="n">PxReal</span><span class="p">(</span><span class="n">sampleBuffer</span><span class="p">[</span><span class="n">j</span> <span class="o">+</span>
            <span class="p">(</span><span class="n">i</span><span class="o">*</span><span class="n">nbCols</span><span class="p">)].</span><span class="n">height</span><span class="p">)</span> <span class="o">*</span> <span class="n">hs</span><span class="p">,</span> <span class="n">PxReal</span><span class="p">(</span><span class="n">j</span><span class="p">)</span> <span class="o">*</span> <span class="n">cs</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Then tessellate the field from the samples as required.</p>
</div>
<div class="section" id="heightfield-modification">
<h3>Heightfield Modification<a class="headerlink" href="#heightfield-modification" title="Permalink to this headline"></a></h3>
<p>Heightfield samples can be modified at runtime in rectangular blocks. In the following code snippet we create a HF and modify its samples:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="c1">// create a 5x5 HF with height 100 and materials 2,3</span>
<span class="n">PxHeightFieldSample</span> <span class="n">samples1</span><span class="p">[</span><span class="mi">25</span><span class="p">];</span>
<span class="k">for</span> <span class="p">(</span><span class="n">PxU32</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">25</span><span class="p">;</span> <span class="n">i</span> <span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">samples1</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">height</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span>
    <span class="n">samples1</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">materialIndex0</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
    <span class="n">samples1</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">materialIndex1</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">PxHeightFieldDesc</span> <span class="n">heightFieldDesc</span><span class="p">;</span>
<span class="n">heightFieldDesc</span><span class="p">.</span><span class="n">nbColumns</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="n">heightFieldDesc</span><span class="p">.</span><span class="n">nbRows</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="n">heightFieldDesc</span><span class="p">.</span><span class="n">thickness</span> <span class="o">=</span> <span class="o">-</span><span class="mi">10</span><span class="p">;</span>
<span class="n">heightFieldDesc</span><span class="p">.</span><span class="n">convexEdgeThreshold</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
<span class="n">heightFieldDesc</span><span class="p">.</span><span class="n">samples</span><span class="p">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">samples1</span><span class="p">;</span>
<span class="n">heightFieldDesc</span><span class="p">.</span><span class="n">samples</span><span class="p">.</span><span class="n">stride</span> <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">PxHeightFieldSample</span><span class="p">);</span>

<span class="n">PxPhysics</span><span class="o">*</span> <span class="n">physics</span> <span class="o">=</span> <span class="n">getPhysics</span><span class="p">();</span>
<span class="n">PxHeightField</span><span class="o">*</span> <span class="n">pHeightField</span> <span class="o">=</span> <span class="n">cooking</span><span class="o">-&gt;</span><span class="n">createHeightField</span><span class="p">(</span><span class="n">heightFieldDesc</span><span class="p">,</span> <span class="n">physics</span><span class="o">-&gt;</span><span class="n">getPhysicsInsertionCallback</span><span class="p">());</span>

<span class="c1">// create modified HF samples, this 10-sample strip will be used as a modified row</span>
<span class="c1">// Source samples that are out of range of target heightfield will be clipped with no error.</span>
<span class="n">PxHeightFieldSample</span> <span class="n">samplesM</span><span class="p">[</span><span class="mi">10</span><span class="p">];</span>
<span class="k">for</span> <span class="p">(</span><span class="n">PxU32</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">;</span> <span class="n">i</span> <span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">samplesM</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">height</span> <span class="o">=</span> <span class="mi">1000</span><span class="p">;</span>
    <span class="n">samplesM</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">materialIndex0</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
    <span class="n">samplesM</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">materialIndex1</span> <span class="o">=</span> <span class="mi">127</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">PxHeightFieldDesc</span> <span class="n">desc10Rows</span><span class="p">;</span>
<span class="n">desc10Rows</span><span class="p">.</span><span class="n">nbColumns</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="n">desc10Rows</span><span class="p">.</span><span class="n">nbRows</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
<span class="n">desc10Rows</span><span class="p">.</span><span class="n">samples</span><span class="p">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">samplesM</span><span class="p">;</span>
<span class="n">desc10Rows</span><span class="p">.</span><span class="n">samples</span><span class="p">.</span><span class="n">stride</span> <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">PxHeightFieldSample</span><span class="p">);</span>

<span class="n">pHeightField</span><span class="o">-&gt;</span><span class="n">modifySamples</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">desc10Rows</span><span class="p">);</span> <span class="c1">// modify row 1 with new sample data</span>
</pre></div>
</div>
<p>PhysX does not keep a mapping from the heightfield to heightfield shapes that reference it. Call PxShape::setGeometry on each shape which references the height field, to ensure that internal data structures are updated to reflect the new geometry:</p>
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxShape</span> <span class="o">*</span><span class="n">hfShape</span> <span class="o">=</span> <span class="n">userGetHfShape</span><span class="p">();</span> <span class="c1">// the user is responsible for keeping track of</span>
                                     <span class="c1">// shapes associated with modified HF</span>
<span class="n">hfShape</span><span class="o">-&gt;</span><span class="n">setGeometry</span><span class="p">(</span><span class="n">PxHeightFieldGeometry</span><span class="p">(</span><span class="n">pHeightField</span><span class="p">,</span> <span class="p">...));</span>
</pre></div>
</div>
<p>Please also note that PxShape::setGeometry() does not guarantee correct/continuous behavior when objects are resting on top of old or new geometry.</p>
<p>The method PxHeightField::getTimestamp() returns the number of times a heightfield has been modified.</p>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../Index.html">Table Of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Geometry</a><ul>
<li><a class="reference internal" href="#introduction">Introduction</a></li>
<li><a class="reference internal" href="#geometry-types">Geometry Types</a><ul>
<li><a class="reference internal" href="#spheres">Spheres</a></li>
<li><a class="reference internal" href="#capsules">Capsules</a></li>
<li><a class="reference internal" href="#boxes">Boxes</a></li>
<li><a class="reference internal" href="#planes">Planes</a></li>
<li><a class="reference internal" href="#convex-meshes">Convex Meshes</a></li>
<li><a class="reference internal" href="#convex-mesh-cooking">Convex Mesh cooking</a><ul>
<li><a class="reference internal" href="#if-only-vertex-points-are-provided">If Only Vertex Points are Provided</a><ul>
<li><a class="reference internal" href="#quickhull-algorithm">Quickhull Algorithm</a></li>
<li><a class="reference internal" href="#inflation-based-incremental-algorithm">Inflation Based Incremental Algorithm</a></li>
<li><a class="reference internal" href="#vertex-limit-algorithms">Vertex Limit Algorithms</a></li>
</ul>
</li>
<li><a class="reference internal" href="#vertex-points-indices-and-polygons-are-provided">Vertex Points, Indices and Polygons are Provided</a></li>
</ul>
</li>
<li><a class="reference internal" href="#triangle-meshes">Triangle Meshes</a><ul>
<li><a class="reference internal" href="#triangle-mesh-cooking">Triangle Mesh cooking</a></li>
</ul>
</li>
<li><a class="reference internal" href="#height-fields">Height Fields</a><ul>
<li><a class="reference internal" href="#heightfield-cooking">Heightfield cooking</a></li>
<li><a class="reference internal" href="#unified-heightfields">Unified Heightfields</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#deformable-meshes">Deformable meshes</a></li>
<li><a class="reference internal" href="#mesh-scaling">Mesh Scaling</a></li>
<li><a class="reference internal" href="#pxgeometryholder">PxGeometryHolder</a></li>
<li><a class="reference internal" href="#vertex-and-face-data">Vertex and Face Data</a><ul>
<li><a class="reference internal" href="#id2">Convex Meshes</a></li>
<li><a class="reference internal" href="#id3">Triangle Meshes</a></li>
<li><a class="reference internal" href="#id4">Height Fields</a></li>
<li><a class="reference internal" href="#heightfield-modification">Heightfield Modification</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="Threading.html"
                        title="previous chapter">Threading</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="RigidBodyOverview.html"
                        title="next chapter">Rigid Body Overview</a></p>
<div id="searchbox" style="display: none">
  <h3>Quick search</h3>
    <form class="search" action="../search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    <p class="searchtip" style="font-size: 90%">
    Enter search terms or a module, class or function name.
    </p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="RigidBodyOverview.html" title="Rigid Body Overview"
             >next</a></li>
        <li class="right" >
          <a href="Threading.html" title="Threading"
             >previous</a> |</li>
        <li><a href="../Index.html">NVIDIA PhysX SDK 3.4.2 Documentation</a> &raquo;</li>
          <li><a href="Index.html" >User's Guide</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
        &copy; Copyright 2008-2018 NVIDIA Corporation, 2701 San Tomas Expressway, Santa Clara, CA 95050 U.S.A. All rights reserved.
    </div>
  </body>
</html>