609 lines
58 KiB
HTML
609 lines
58 KiB
HTML
|
|
|
|
<!DOCTYPE html>
|
|
<!--[if IE 8]><html class="no-js lt-ie9" lang="" > <![endif]-->
|
|
<!--[if gt IE 8]><!--> <html class="no-js" lang="" > <!--<![endif]-->
|
|
<head>
|
|
<meta charset="utf-8">
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
|
<title>Rigid Body Collision — NVIDIA PhysX SDK 4.1 Documentation</title>
|
|
|
|
|
|
|
|
<link rel="shortcut icon" href="_static/images/favicon.ico"/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
|
<link rel="stylesheet" href="../_static/breathe.css" type="text/css" />
|
|
<link rel="next" title="Rigid Body Dynamics" href="RigidBodyDynamics.html" />
|
|
<link rel="prev" title="Rigid Body Overview" href="RigidBodyOverview.html" />
|
|
<link href="../_static/css/nvidia_theme.css" rel="stylesheet" type="text/css">
|
|
|
|
|
|
<style>
|
|
.wy-nav-content::before {
|
|
content: "PhysX 4.1 SDK Guide";
|
|
}
|
|
</style>
|
|
|
|
|
|
|
|
|
|
<script src="../_static/js/modernizr.min.js"></script>
|
|
|
|
</head>
|
|
|
|
<body class="wy-body-for-nav">
|
|
|
|
|
|
<div class="wy-grid-for-nav">
|
|
|
|
|
|
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
|
<div class="wy-side-scroll">
|
|
<div class="wy-side-nav-search">
|
|
|
|
|
|
|
|
<a href="../Index.html" class="icon icon-home"> Python
|
|
|
|
|
|
|
|
</a>
|
|
|
|
|
|
|
|
|
|
<div role="search">
|
|
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
|
|
<input type="text" name="q" placeholder="Search docs" />
|
|
<input type="hidden" name="check_keywords" value="yes" />
|
|
<input type="hidden" name="area" value="default" />
|
|
</form>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<ul class="current">
|
|
<li class="toctree-l1 current"><a class="reference internal" href="Index.html">User's Guide</a><ul class="current">
|
|
<li class="toctree-l2"><a class="reference internal" href="License.html">PhysX License</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="Introduction.html">Welcome to PhysX</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="HelloWorld.html">Snippets</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="BuildingWithPhysX.html">Building with PhysX</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="API.html">The PhysX API</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="Startup.html">Startup and Shutdown</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="Threading.html">Threading</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="Geometry.html">Geometry</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="RigidBodyOverview.html">Rigid Body Overview</a></li>
|
|
<li class="toctree-l2 current"><a class="current reference internal" href="">Rigid Body Collision</a><ul>
|
|
<li class="toctree-l3"><a class="reference internal" href="#introduction">Introduction</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="#shapes">Shapes</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="#simulation-shapes-and-scene-query-shapes">Simulation Shapes and Scene Query Shapes</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="#kinematic-triangle-meshes-planes-heighfields">Kinematic Triangle Meshes (Planes, Heighfields)</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="#broad-phase-algorithms">Broad-phase Algorithms</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="#regions-of-interest">Regions of Interest</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="#broad-phase-callback">Broad-phase Callback</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="#collision-filtering">Collision Filtering</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="#aggregates">Aggregates</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="#creating-an-aggregate">Creating an Aggregate</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="#populating-an-aggregate">Populating an Aggregate</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="#releasing-an-aggregate">Releasing an Aggregate</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="#amortizing-insertion">Amortizing Insertion</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="#trigger-shapes">Trigger Shapes</a></li>
|
|
<li class="toctree-l3"><a class="reference internal" href="#interactions">Interactions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li class="toctree-l2"><a class="reference internal" href="RigidBodyDynamics.html">Rigid Body Dynamics</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="Simulation.html">Simulation</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="AdvancedCollisionDetection.html">Advanced Collision Detection</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="Joints.html">Joints</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="Articulations.html">Articulations</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="Articulations.html#maximal-coordinate-and-reduced-articulations">Maximal Coordinate and Reduced Articulations</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="Articulations.html#maximal-coordinate-articulations">Maximal Coordinate Articulations</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="Articulations.html#reduced-coordinate-articulations">Reduced Coordinate Articulations</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="OriginShift.html">Scene Origin</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="GPURigidBodies.html">GPU Rigid Bodies</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="GeometryQueries.html">Geometry Queries</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="SceneQueries.html">Scene Queries</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="Vehicles.html">Vehicles</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="CharacterControllers.html">Character Controllers</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="DebugVisualization.html">Debug Visualization</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="VisualDebugger.html">PhysX Visual Debugger (PVD)</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="Statistics.html">Simulation Statistics</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="Serialization.html">Serialization</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="ExtendingSerialization.html">Extending Serialization</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="BestPractices.html">Best Practices Guide</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="MigrationFrom28.html">Migrating From PhysX SDK 2.x to 3.x</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="MigrationTo33.html">Migrating From PhysX SDK 3.2 to 3.3</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="MigrationTo34.html">Migrating From PhysX SDK 3.3 to 3.4</a></li>
|
|
<li class="toctree-l2"><a class="reference internal" href="MigrationTo40.html">Migrating From PhysX SDK 3.4 to 4.0</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
|
|
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
|
|
|
|
|
<nav class="wy-nav-top" aria-label="top navigation">
|
|
|
|
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
|
<a href="../Index.html">Python</a>
|
|
|
|
</nav>
|
|
|
|
|
|
<div class="wy-nav-content">
|
|
|
|
<div class="rst-content">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div role="navigation" aria-label="breadcrumbs navigation">
|
|
|
|
<ul class="wy-breadcrumbs">
|
|
|
|
<li><a href="../Index.html">Docs</a> »</li>
|
|
|
|
<li><a href="Index.html">User's Guide</a> »</li>
|
|
|
|
<li>Rigid Body Collision</li>
|
|
|
|
|
|
<li class="wy-breadcrumbs-aside">
|
|
|
|
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
|
|
<hr/>
|
|
</div>
|
|
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
|
<div itemprop="articleBody">
|
|
|
|
<div class="section" id="rigid-body-collision">
|
|
<span id="rigidbodycollision"></span><h1>Rigid Body Collision<a class="headerlink" href="#rigid-body-collision" 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 will introduce the fundamentals of rigid body collision.</p>
|
|
</div>
|
|
<div class="section" id="shapes">
|
|
<span id="rigidbodycollisionshapes"></span><h2>Shapes<a class="headerlink" href="#shapes" title="Permalink to this headline">¶</a></h2>
|
|
<p>Shapes describe the spatial extent and collision properties of actors. They are used for three purposes within PhysX: intersection tests that determine the contacting features of rigid objects, scene query tests such as raycasts, and defining trigger volumes that generate notifications when other shapes intersect with them.</p>
|
|
<p>Shapes are reference counted, see <a class="reference internal" href="API.html#basicreferencecounting"><em>Reference Counting</em></a>.</p>
|
|
<p>Each shape contains a PxGeometry object and a reference to a PxMaterial, which must both be specified upon creation.
|
|
The following code creates a shape with a sphere geometry and a specific material:</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="o">=</span> <span class="n">physics</span><span class="p">.</span><span class="n">createShape</span><span class="p">(</span><span class="n">PxSphereGeometry</span><span class="p">(</span><span class="mf">1.0f</span><span class="p">),</span> <span class="n">myMaterial</span><span class="p">,</span> <span class="nb">true</span><span class="p">);</span>
|
|
<span class="n">myActor</span><span class="p">.</span><span class="n">attachShape</span><span class="p">(</span><span class="o">*</span><span class="n">shape</span><span class="p">);</span>
|
|
<span class="n">shape</span><span class="o">-></span><span class="n">release</span><span class="p">();</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>The method PxRigidActorExt::createExclusiveShape() is equivalent to the three lines above.</p>
|
|
<div class="admonition note">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last">for reference counting behavior of deserialized shapes refer to <a class="reference internal" href="Serialization.html#deserializereferencecounting"><em>Reference Counting of Deserialized Objects</em></a>.</p>
|
|
</div>
|
|
<p>The parameter 'true' to createShape() informs the SDK that the shape will not be shared with other actors. You can use shape sharing to reduce the memory costs of your simulation when you have many actors with identical geometry, but shared shapes have a very strong restriction: you cannot update the attributes of a shared shape while it is attached to an actor.</p>
|
|
<p>Optionally you may configure a shape by specifying shape flags of type PxShapeFlags. By default a shape is configured as</p>
|
|
<ul class="simple">
|
|
<li>a simulation shape (enabled for contact generation during simulation)</li>
|
|
<li>a scene query shape (enabled for scene queries)</li>
|
|
<li>being visualized if debug rendering is enabled</li>
|
|
</ul>
|
|
<p>When a geometry object is specified for a shape, the geometry object is copied into the shape. There are some restrictions on which geometries may be specified for a shape, depending on the shape flags and the type of the parent actors.</p>
|
|
<ul class="simple">
|
|
<li>TriangleMesh, HeightField and Plane geometries are not supported for simulation shapes that are attached to dynamic actors, unless the dynamic actors are configured to be kinematic.</li>
|
|
<li>TriangleMesh and HeightField geometries are not supported for trigger shapes.</li>
|
|
</ul>
|
|
<p>See the following sections for more details.</p>
|
|
<p>Detach the shape from the actor as follows:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="n">myActor</span><span class="p">.</span><span class="n">detachShape</span><span class="p">(</span><span class="o">*</span><span class="n">shape</span><span class="p">);</span>
|
|
</pre></div>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="simulation-shapes-and-scene-query-shapes">
|
|
<h2>Simulation Shapes and Scene Query Shapes<a class="headerlink" href="#simulation-shapes-and-scene-query-shapes" title="Permalink to this headline">¶</a></h2>
|
|
<p>Shapes may be independently configured to participate in either or both of scene queries and contact tests. By default, a shape will participate in both.</p>
|
|
<p>The following pseudo-code configures a PxShape instance so that it no longer participates in shape pair intersection tests:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="kt">void</span> <span class="nf">disableShapeInContactTests</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="p">{</span>
|
|
<span class="n">shape</span><span class="o">-></span><span class="n">setFlag</span><span class="p">(</span><span class="n">PxShapeFlag</span><span class="o">::</span><span class="n">eSIMULATION_SHAPE</span><span class="p">,</span><span class="nb">false</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>A PxShape instance can be configured to participate in shape pair intersection tests as follows:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="kt">void</span> <span class="nf">enableShapeInContactTests</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="p">{</span>
|
|
<span class="n">shape</span><span class="o">-></span><span class="n">setFlag</span><span class="p">(</span><span class="n">PxShapeFlag</span><span class="o">::</span><span class="n">eSIMULATION_SHAPE</span><span class="p">,</span><span class="nb">true</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>To disable a PxShape instance from scene query tests:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="kt">void</span> <span class="nf">disableShapeInSceneQueryTests</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="p">{</span>
|
|
<span class="n">shape</span><span class="o">-></span><span class="n">setFlag</span><span class="p">(</span><span class="n">PxShapeFlag</span><span class="o">::</span><span class="n">eSCENE_QUERY_SHAPE</span><span class="p">,</span><span class="nb">false</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>Finally, a PxShape instance can be re-enabled in scene query tests:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="kt">void</span> <span class="nf">enableShapeInSceneQueryTests</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="p">{</span>
|
|
<span class="n">shape</span><span class="o">-></span><span class="n">setFlag</span><span class="p">(</span><span class="n">PxShapeFlag</span><span class="o">::</span><span class="n">eSCENE_QUERY_SHAPE</span><span class="p">,</span><span class="nb">true</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
</div>
|
|
<div class="admonition note">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last">If the movement of the shape's actor does not need to be controlled by the simulation at all, i.e., the shape is used for scene queries only and gets moved manually if necessary, then memory can be saved by additionally disabling simulation on the actor (see the API documentation on PxActorFlag::eDISABLE_SIMULATION).</p>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="kinematic-triangle-meshes-planes-heighfields">
|
|
<h2>Kinematic Triangle Meshes (Planes, Heighfields)<a class="headerlink" href="#kinematic-triangle-meshes-planes-heighfields" title="Permalink to this headline">¶</a></h2>
|
|
<p>It is possible to create a kinematic PxRigidDynamic which can have a triangle mesh (plane, heighfield) shape. If this shape has a simulation shape flag, this actor must stay kinematic. If you change the flag to not simulated, you can switch even the kinematic flag.</p>
|
|
<p>To setup kinematic triangle mesh see following code:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxRigidDynamic</span><span class="o">*</span> <span class="n">meshActor</span> <span class="o">=</span> <span class="n">getPhysics</span><span class="p">().</span><span class="n">createRigidDynamic</span><span class="p">(</span><span class="n">PxTransform</span><span class="p">(</span><span class="mf">1.0f</span><span class="p">));</span>
|
|
<span class="n">PxShape</span><span class="o">*</span> <span class="n">meshShape</span><span class="p">;</span>
|
|
<span class="k">if</span><span class="p">(</span><span class="n">meshActor</span><span class="p">)</span>
|
|
<span class="p">{</span>
|
|
<span class="n">meshActor</span><span class="o">-></span><span class="n">setRigidDynamicFlag</span><span class="p">(</span><span class="n">PxRigidDynamicFlag</span><span class="o">::</span><span class="n">eKINEMATIC</span><span class="p">,</span> <span class="nb">true</span><span class="p">);</span>
|
|
|
|
<span class="n">PxTriangleMeshGeometry</span> <span class="n">triGeom</span><span class="p">;</span>
|
|
<span class="n">triGeom</span><span class="p">.</span><span class="n">triangleMesh</span> <span class="o">=</span> <span class="n">triangleMesh</span><span class="p">;</span>
|
|
<span class="n">meshShape</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">meshActor</span><span class="p">,</span><span class="n">triGeom</span><span class="p">,</span>
|
|
<span class="n">defaultMaterial</span><span class="p">);</span>
|
|
<span class="n">getScene</span><span class="p">().</span><span class="n">addActor</span><span class="p">(</span><span class="o">*</span><span class="n">meshActor</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>To switch a kinematic triangle mesh actor to a dynamic actor:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxRigidDynamic</span><span class="o">*</span> <span class="n">meshActor</span> <span class="o">=</span> <span class="n">getPhysics</span><span class="p">().</span><span class="n">createRigidDynamic</span><span class="p">(</span><span class="n">PxTransform</span><span class="p">(</span><span class="mf">1.0f</span><span class="p">));</span>
|
|
<span class="n">PxShape</span><span class="o">*</span> <span class="n">meshShape</span><span class="p">;</span>
|
|
<span class="k">if</span><span class="p">(</span><span class="n">meshActor</span><span class="p">)</span>
|
|
<span class="p">{</span>
|
|
<span class="n">meshActor</span><span class="o">-></span><span class="n">setRigidDynamicFlag</span><span class="p">(</span><span class="n">PxRigidDynamicFlag</span><span class="o">::</span><span class="n">eKINEMATIC</span><span class="p">,</span> <span class="nb">true</span><span class="p">);</span>
|
|
|
|
<span class="n">PxTriangleMeshGeometry</span> <span class="n">triGeom</span><span class="p">;</span>
|
|
<span class="n">triGeom</span><span class="p">.</span><span class="n">triangleMesh</span> <span class="o">=</span> <span class="n">triangleMesh</span><span class="p">;</span>
|
|
<span class="n">meshShape</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">meshActor</span><span class="p">,</span> <span class="n">triGeom</span><span class="p">,</span>
|
|
<span class="n">defaultMaterial</span><span class="p">);</span>
|
|
<span class="n">getScene</span><span class="p">().</span><span class="n">addActor</span><span class="p">(</span><span class="o">*</span><span class="n">meshActor</span><span class="p">);</span>
|
|
|
|
<span class="n">PxConvexMeshGeometry</span> <span class="n">convexGeom</span> <span class="o">=</span> <span class="n">PxConvexMeshGeometry</span><span class="p">(</span><span class="n">convexBox</span><span class="p">);</span>
|
|
<span class="n">convexShape</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">meshActor</span><span class="p">,</span> <span class="n">convexGeom</span><span class="p">,</span>
|
|
<span class="n">defaultMaterial</span><span class="p">);</span>
|
|
</pre></div>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="broad-phase-algorithms">
|
|
<h2>Broad-phase Algorithms<a class="headerlink" href="#broad-phase-algorithms" title="Permalink to this headline">¶</a></h2>
|
|
<p>PhysX supports several broad-phase algorithms:</p>
|
|
<ul class="simple">
|
|
<li><em>sweep-and-prune (SAP)</em></li>
|
|
<li><em>multi box pruning (MBP)</em></li>
|
|
<li><em>automatic box pruning (ABP)</em></li>
|
|
</ul>
|
|
<p><em>PxBroadPhaseType::eSAP</em> is a good generic choice with great performance when many objects are sleeping. Performance can degrade significantly though, when all objects are moving, or when large numbers of objects are added to or removed from the broad-phase. This algorithm does not need world bounds to be defined in order to work.</p>
|
|
<p><em>PxBroadPhaseType::eMBP</em> is a new algorithm introduced in PhysX 3.3. It is an alternative broad-phase algorithm that does not suffer from the same performance issues as eSAP when all objects are moving or when inserting large numbers of objects. However its generic performance when many objects are sleeping might be inferior to eSAP, and it requires users to define world bounds in order to work.</p>
|
|
<p><em>PxBroadPhaseType::eABP</em> is a revisited implementation of <em>PxBroadPhaseType::eMBP</em> introduced in PhysX 4. It automatically manages world bounds and broad-phase regions, thus offering the convenience of <em>PxBroadPhaseType::eSAP</em> coupled to the performance of <em>PxBroadPhaseType::eMBP</em>. While <em>PxBroadPhaseType::eSAP</em> can remain faster when most objects are sleeping and <em>PxBroadPhaseType::eMBP</em> can remain faster when it uses a large number of properly-defined regions, <em>PxBroadPhaseType::eABP</em> often gives the best performance on average and the best memory usage. It is a good default choice for the broadphase.</p>
|
|
<p>The desired broad-phase algorithm is controlled by the <em>PxBroadPhaseType</em> enum, within the <em>PxSceneDesc</em> structure.</p>
|
|
</div>
|
|
<div class="section" id="regions-of-interest">
|
|
<h2>Regions of Interest<a class="headerlink" href="#regions-of-interest" title="Permalink to this headline">¶</a></h2>
|
|
<p>A region of interest is a world-space AABB around a volume of space controlled by the broad-phase. Objects contained inside those regions are properly handled by the broad-phase. Objects falling outside of those regions lose all collision detection. Ideally those regions should cover the whole simulation space, while limiting the amount of covered empty space.</p>
|
|
<p>Regions can overlap, although for maximum efficiency it is recommended to minimize the amount of overlap between regions as much as possible. Note that two regions whose AABBs just touch are not considered overlapping. For example the <em>PxBroadPhaseExt::createRegionsFromWorldBounds</em> helper function creates a number of non-overlapping region bounds by simply subdividing a given world AABB into a regular 2D grid.</p>
|
|
<p>Regions can be defined by the <em>PxBroadPhaseRegion</em> structure, along with a user-data assigned to them. They can be defined at scene creation time or at runtime using the <em>PxScene::addBroadPhaseRegion</em> function. The SDK returns handles assigned to the newly created regions, that can be used later to remove regions using the <em>PxScene::removeBroadPhaseRegion</em> function.</p>
|
|
<p>A newly added region may overlap already existing objects. The SDK can automatically add those objects to the new region, if the <em>populateRegion</em> parameter from the <em>PxScene::addBroadPhaseRegion</em> call is set. However this operation is not cheap and might have a high impact on performance, especially when several regions are added in the same frame. Thus, it is recommended to disable it whenever possible. The region would then be created empty, and it would only be populated either with objects added to the scene after the region has been created, or with previously existing objects when they are updated (i.e. when they move).</p>
|
|
<p>Note that only <em>PxBroadPhaseType::eMBP</em> requires regions to be defined. The <em>PxBroadPhaseType::eSAP</em> and <em>PxBroadPhaseType::eABP</em> algorithms do not. This information is captured within the <em>PxBroadPhaseCaps</em> structure, which lists information and capabilities of each broad-phase algorithm. This structure can be retrieved by the <em>PxScene::getBroadPhaseCaps</em> function.</p>
|
|
<p>Runtime information about current regions can be retrieved using the <em>PxScene::getNbBroadPhaseRegions</em> and <em>PxScene::getBroadPhaseRegions</em> functions.</p>
|
|
<p>The maximum number of regions is currently limited to 256.</p>
|
|
</div>
|
|
<div class="section" id="broad-phase-callback">
|
|
<h2>Broad-phase Callback<a class="headerlink" href="#broad-phase-callback" title="Permalink to this headline">¶</a></h2>
|
|
<p>A callback for broad-phase-related events can be defined within the <em>PxSceneDesc</em> structure. This <em>PxBroadPhaseCallback</em> object will be called when objects are found out of the specified regions of interest, i.e. "out of bounds". The SDK disables collision detection for those objects. It is re-enabled automatically as soon as the objects re-enter a valid region.</p>
|
|
<p>It is up to users to decide what to do with out-of-bounds objects. Typical options are:</p>
|
|
<ul class="simple">
|
|
<li>delete the objects</li>
|
|
<li>let them continue their motion without collisions until they re-enter a valid region</li>
|
|
<li>artificially teleport them back to a valid place</li>
|
|
</ul>
|
|
</div>
|
|
<div class="section" id="collision-filtering">
|
|
<span id="collisionfiltering"></span><h2>Collision Filtering<a class="headerlink" href="#collision-filtering" title="Permalink to this headline">¶</a></h2>
|
|
<p>In almost all applications beyond the trivial, the need arises to exempt certain pairs of objects from interacting, or to configure the SDK collision detection behavior in a particular way for an interacting pair. In the submarine sample, like indicated above, we need to be notified when the submarine touched a mine, or the chain of a mine, so that we can have them blow up. The crab's AI also needs to know when crabs touch the heightfield.</p>
|
|
<p>Before we can understand what the sample does to achieve this, we need to understand the possibilities of the SDK filtering system. Because filtering potentially interacting pairs happens in the deepest parts of the simulation engine, and needs to be applied to all pairs of objects that come near each other, it is particularly performance sensitive. The simplest way to implement it would be to always call a callback function to each potentially interacting pair, where the application, based on the two object pointers could determine, using some custom logic -- like consulting its world data base -- whether the pair should interact. Unfortunately this quickly becomes too slow if done for a very large game world, especially if the collision detection processing happens on a remote processor like the GPU or an other kind of vector processor with local memory, which would have to suspend its parallel computations, interrupt the main processor that runs game code, and have it execute the callback before it can continue. Even if it were to be executed on a CPU, it would likely be done so simultaneously on multiple cores or hyperthreads, and thread safe code would have to be put in place to make sure that concurrent access to shared data is safe. Far better is to use some kind of fixed function logic that can execute on the remote processor. This is what we did in PhysX 2.x -- unfortunately the simple group based filtering rules we provided were not flexible enough to cover all applications. In 3.0, we introduce both a shader system, which lets the developer implement an arbitrary system of rules using code that runs on the vector processor (and is therefore not able to access any eventual game data base in main memory), which is more flexible than 2.x fixed function filtering, but just as efficient, and a totally flexible callback mechanism where the filter shader calls a CPU callback function that is able to access any application data, at the cost of performance -- see PxSimulationFilterCallback for details. The best part is that an application can decide on a per-pair basis to make this speed vs. flexibility trade-off.</p>
|
|
<p>Let us look at the shader system first: Here is the filter shader implemented by SampleSubmarine:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxFilterFlags</span> <span class="nf">SampleSubmarineFilterShader</span><span class="p">(</span>
|
|
<span class="n">PxFilterObjectAttributes</span> <span class="n">attributes0</span><span class="p">,</span> <span class="n">PxFilterData</span> <span class="n">filterData0</span><span class="p">,</span>
|
|
<span class="n">PxFilterObjectAttributes</span> <span class="n">attributes1</span><span class="p">,</span> <span class="n">PxFilterData</span> <span class="n">filterData1</span><span class="p">,</span>
|
|
<span class="n">PxPairFlags</span><span class="o">&</span> <span class="n">pairFlags</span><span class="p">,</span> <span class="k">const</span> <span class="kt">void</span><span class="o">*</span> <span class="n">constantBlock</span><span class="p">,</span> <span class="n">PxU32</span> <span class="n">constantBlockSize</span><span class="p">)</span>
|
|
<span class="p">{</span>
|
|
<span class="c1">// let triggers through</span>
|
|
<span class="k">if</span><span class="p">(</span><span class="n">PxFilterObjectIsTrigger</span><span class="p">(</span><span class="n">attributes0</span><span class="p">)</span> <span class="o">||</span> <span class="n">PxFilterObjectIsTrigger</span><span class="p">(</span><span class="n">attributes1</span><span class="p">))</span>
|
|
<span class="p">{</span>
|
|
<span class="n">pairFlags</span> <span class="o">=</span> <span class="n">PxPairFlag</span><span class="o">::</span><span class="n">eTRIGGER_DEFAULT</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="n">PxFilterFlag</span><span class="o">::</span><span class="n">eDEFAULT</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="c1">// generate contacts for all that were not filtered above</span>
|
|
<span class="n">pairFlags</span> <span class="o">=</span> <span class="n">PxPairFlag</span><span class="o">::</span><span class="n">eCONTACT_DEFAULT</span><span class="p">;</span>
|
|
|
|
<span class="c1">// trigger the contact callback for pairs (A,B) where</span>
|
|
<span class="c1">// the filtermask of A contains the ID of B and vice versa.</span>
|
|
<span class="k">if</span><span class="p">((</span><span class="n">filterData0</span><span class="p">.</span><span class="n">word0</span> <span class="o">&</span> <span class="n">filterData1</span><span class="p">.</span><span class="n">word1</span><span class="p">)</span> <span class="o">&&</span> <span class="p">(</span><span class="n">filterData1</span><span class="p">.</span><span class="n">word0</span> <span class="o">&</span> <span class="n">filterData0</span><span class="p">.</span><span class="n">word1</span><span class="p">))</span>
|
|
<span class="n">pairFlags</span> <span class="o">|=</span> <span class="n">PxPairFlag</span><span class="o">::</span><span class="n">eNOTIFY_TOUCH_FOUND</span><span class="p">;</span>
|
|
|
|
<span class="k">return</span> <span class="n">PxFilterFlag</span><span class="o">::</span><span class="n">eDEFAULT</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>SampleSubmarineFilterShader is a simple shader function that is an implementation of the PxSimulationFilterShader prototype declared in PxFiltering.h. The shader filter function (called SampleSubmarineFilterShader above) may not reference any memory other than arguments of the function and its own local stack variables -- because the function may be compiled and executed on a remote processor.</p>
|
|
<p>SampleSubmarineFilterShader() will be called for all pairs of shapes that come near each other -- more precisely: for all pairs of shapes whose axis aligned bounding boxes in world space are found to intersect for the first time. All behavior beyond that is determined by what SampleSubmarineFilterShader() returns.</p>
|
|
<p>The arguments of SampleSubmarineFilterShader() include PxFilterObjectAttributes and PxFilterData for the two objects, and a constant block of memory. Note that the pointers to the two objects are NOT passed, because those pointers refer to the computer's main memory, and that may, as we said, not be available to the shader, so the pointers would not be very useful, as dereferencing them would likely cause a crash. PxFilterObjectAttributes and PxFilterData are intended to contain all the useful information that one could quickly glean from the pointers. PxFilterObjectAttributes are 32 bits of data, that encode the type of object: For example PxFilterObjectType::eRIGID_STATIC or ::eRIGID_DYNAMIC. Additionally, it lets you find out if the object is kinematic, or a trigger.</p>
|
|
<p>Each PxShape has a member variable of type PxFilterData. This is 128 bits of user defined data that can be used to store application specific information related to collision filtering. This is the other variable that is passed to SampleSubmarineFilterShader() for each object.</p>
|
|
<p>There is also the constant block. This is a chunk of per-scene global information that the application can give to the shader to operate on. You will want to use this to encode rules about what to filter and what not.</p>
|
|
<p>Finally, SampleSubmarineFilterShader() also has a PxPairFlags parameter. This is an output, like the return value PxFilterFlags, though used slightly differently. PxFilterFlags tells the SDK if it should ignore the pair for good (eKILL), ignore the pair while it is overlapping, but ask again, when filtering related data changes for one of the objects (eSUPPRESS), or call the low performance but more flexible CPU callback if the shader cannot decide (eCALLBACK).</p>
|
|
<p>PxPairFlags specifies additional flags that stand for actions that the simulation should take in the future for this pair. For example, eNOTIFY_TOUCH_FOUND means notify the user when the pair really starts to touch, not just potentially.</p>
|
|
<p>Let us look at what the above shader does:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="c1">// let triggers through</span>
|
|
<span class="k">if</span><span class="p">(</span><span class="n">PxFilterObjectIsTrigger</span><span class="p">(</span><span class="n">attributes0</span><span class="p">)</span> <span class="o">||</span> <span class="n">PxFilterObjectIsTrigger</span><span class="p">(</span><span class="n">attributes1</span><span class="p">))</span>
|
|
<span class="p">{</span>
|
|
<span class="n">pairFlags</span> <span class="o">=</span> <span class="n">PxPairFlag</span><span class="o">::</span><span class="n">eTRIGGER_DEFAULT</span><span class="p">;</span>
|
|
<span class="k">return</span> <span class="n">PxFilterFlag</span><span class="o">::</span><span class="n">eDEFAULT</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>This means that if either object is a trigger, then perform default trigger behavior (notify the application about start and end of touch), and otherwise perform 'default' collision detection between them.</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="c1">// generate contacts for all that were not filtered above</span>
|
|
<span class="n">pairFlags</span> <span class="o">=</span> <span class="n">PxPairFlag</span><span class="o">::</span><span class="n">eCONTACT_DEFAULT</span><span class="p">;</span>
|
|
|
|
<span class="c1">// trigger the contact callback for pairs (A,B) where</span>
|
|
<span class="c1">// the filtermask of A contains the ID of B and vice versa.</span>
|
|
<span class="k">if</span><span class="p">((</span><span class="n">filterData0</span><span class="p">.</span><span class="n">word0</span> <span class="o">&</span> <span class="n">filterData1</span><span class="p">.</span><span class="n">word1</span><span class="p">)</span> <span class="o">&&</span> <span class="p">(</span><span class="n">filterData1</span><span class="p">.</span><span class="n">word0</span> <span class="o">&</span> <span class="n">filterData0</span><span class="p">.</span><span class="n">word1</span><span class="p">))</span>
|
|
<span class="n">pairFlags</span> <span class="o">|=</span> <span class="n">PxPairFlag</span><span class="o">::</span><span class="n">eNOTIFY_TOUCH_FOUND</span><span class="p">;</span>
|
|
|
|
<span class="k">return</span> <span class="n">PxFilterFlag</span><span class="o">::</span><span class="n">eDEFAULT</span><span class="p">;</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>This says that for all other objects, perform 'default' collision handling. In addition, there is a rule based on the filterDatas that determines particular pairs where we ask for touch notifications. To understand what this means, we need to know the special meaning that the sample gives to the filterDatas.</p>
|
|
<p>The needs of the sample are very basic, so we will use a very simple scheme to take care of it. The sample first gives named codes to the different object types using a custom enumeration:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="k">struct</span> <span class="n">FilterGroup</span>
|
|
<span class="p">{</span>
|
|
<span class="k">enum</span> <span class="n">Enum</span>
|
|
<span class="p">{</span>
|
|
<span class="n">eSUBMARINE</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span> <span class="o"><<</span> <span class="mi">0</span><span class="p">),</span>
|
|
<span class="n">eMINE_HEAD</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span> <span class="o"><<</span> <span class="mi">1</span><span class="p">),</span>
|
|
<span class="n">eMINE_LINK</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span> <span class="o"><<</span> <span class="mi">2</span><span class="p">),</span>
|
|
<span class="n">eCRAB</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span> <span class="o"><<</span> <span class="mi">3</span><span class="p">),</span>
|
|
<span class="n">eHEIGHTFIELD</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span> <span class="o"><<</span> <span class="mi">4</span><span class="p">),</span>
|
|
<span class="p">};</span>
|
|
<span class="p">};</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>The sample identifies each shape's type by assigning its PxFilterData::word0 to this FilterGroup type. Then, it puts a bit mask that specifies each type of object that should generate a report when touched by an object of type word0 into word1. This could be done in the samples whenever a shape is created, but because shape creation is a bit encapsulated in SampleBase, it is done after the fact, using this function:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="kt">void</span> <span class="nf">setupFiltering</span><span class="p">(</span><span class="n">PxRigidActor</span><span class="o">*</span> <span class="n">actor</span><span class="p">,</span> <span class="n">PxU32</span> <span class="n">filterGroup</span><span class="p">,</span> <span class="n">PxU32</span> <span class="n">filterMask</span><span class="p">)</span>
|
|
<span class="p">{</span>
|
|
<span class="n">PxFilterData</span> <span class="n">filterData</span><span class="p">;</span>
|
|
<span class="n">filterData</span><span class="p">.</span><span class="n">word0</span> <span class="o">=</span> <span class="n">filterGroup</span><span class="p">;</span> <span class="c1">// word0 = own ID</span>
|
|
<span class="n">filterData</span><span class="p">.</span><span class="n">word1</span> <span class="o">=</span> <span class="n">filterMask</span><span class="p">;</span> <span class="c1">// word1 = ID mask to filter pairs that trigger a</span>
|
|
<span class="c1">// contact callback;</span>
|
|
<span class="k">const</span> <span class="n">PxU32</span> <span class="n">numShapes</span> <span class="o">=</span> <span class="n">actor</span><span class="o">-></span><span class="n">getNbShapes</span><span class="p">();</span>
|
|
<span class="n">PxShape</span><span class="o">**</span> <span class="n">shapes</span> <span class="o">=</span> <span class="p">(</span><span class="n">PxShape</span><span class="o">**</span><span class="p">)</span><span class="n">SAMPLE_ALLOC</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">PxShape</span><span class="o">*</span><span class="p">)</span><span class="o">*</span><span class="n">numShapes</span><span class="p">);</span>
|
|
<span class="n">actor</span><span class="o">-></span><span class="n">getShapes</span><span class="p">(</span><span class="n">shapes</span><span class="p">,</span> <span class="n">numShapes</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"><</span> <span class="n">numShapes</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">PxShape</span><span class="o">*</span> <span class="n">shape</span> <span class="o">=</span> <span class="n">shapes</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
|
|
<span class="n">shape</span><span class="o">-></span><span class="n">setSimulationFilterData</span><span class="p">(</span><span class="n">filterData</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="n">SAMPLE_FREE</span><span class="p">(</span><span class="n">shapes</span><span class="p">);</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>This sets up the PxFilterDatas of each shape belonging to the passed actor. Here are some examples how this is used in SampleSubmarine:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="n">setupFiltering</span><span class="p">(</span><span class="n">mSubmarineActor</span><span class="p">,</span> <span class="n">FilterGroup</span><span class="o">::</span><span class="n">eSUBMARINE</span><span class="p">,</span> <span class="n">FilterGroup</span><span class="o">::</span><span class="n">eMINE_HEAD</span> <span class="o">|</span>
|
|
<span class="n">FilterGroup</span><span class="o">::</span><span class="n">eMINE_LINK</span><span class="p">);</span>
|
|
<span class="n">setupFiltering</span><span class="p">(</span><span class="n">link</span><span class="p">,</span> <span class="n">FilterGroup</span><span class="o">::</span><span class="n">eMINE_LINK</span><span class="p">,</span> <span class="n">FilterGroup</span><span class="o">::</span><span class="n">eSUBMARINE</span><span class="p">);</span>
|
|
<span class="n">setupFiltering</span><span class="p">(</span><span class="n">mineHead</span><span class="p">,</span> <span class="n">FilterGroup</span><span class="o">::</span><span class="n">eMINE_HEAD</span><span class="p">,</span> <span class="n">FilterGroup</span><span class="o">::</span><span class="n">eSUBMARINE</span><span class="p">);</span>
|
|
|
|
<span class="n">setupFiltering</span><span class="p">(</span><span class="n">heightField</span><span class="p">,</span> <span class="n">FilterGroup</span><span class="o">::</span><span class="n">eHEIGHTFIELD</span><span class="p">,</span> <span class="n">FilterGroup</span><span class="o">::</span><span class="n">eCRAB</span><span class="p">);</span>
|
|
<span class="n">setupFiltering</span><span class="p">(</span><span class="n">mCrabBody</span><span class="p">,</span> <span class="n">FilterGroup</span><span class="o">::</span><span class="n">eCRAB</span><span class="p">,</span> <span class="n">FilterGroup</span><span class="o">::</span><span class="n">eHEIGHTFIELD</span><span class="p">);</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>This scheme is probably too simplistic to use in a serious application, but it shows the basic usage of the filter shader, and it will ensure that SampleSubmarine::onContact() is called for all interesting pairs.</p>
|
|
<p>An alternative group based filtering mechanism is provided with source in the extensions function PxDefaultSimulationFilterShader. And, again, if this shader based system is too inflexible, consider using the callback approach provided with PxSimulationFilterCallback.</p>
|
|
</div>
|
|
<div class="section" id="aggregates">
|
|
<h2>Aggregates<a class="headerlink" href="#aggregates" title="Permalink to this headline">¶</a></h2>
|
|
<p>An aggregate is a collection of actors. Aggregates do not provide extra simulation or query features, but allow you to tell the SDK that a set of actors will be clustered together, which in turn allows the SDK to optimize its spatial data operations. A typical use case is a ragdoll, made of multiple different actors. Without aggregates, this gives rise to as many broad-phase entries as there are shapes in the ragdoll. It is typically more efficient to represent the ragdoll in the broad-phase as a single entity, and perform internal overlap tests in a second pass if necessary. Another potential use case is a single actor with a large number of attached shapes.</p>
|
|
</div>
|
|
<div class="section" id="creating-an-aggregate">
|
|
<h2>Creating an Aggregate<a class="headerlink" href="#creating-an-aggregate" title="Permalink to this headline">¶</a></h2>
|
|
<p>Create an aggregate from the <em>PxPhysics</em> object:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxPhysics</span><span class="o">*</span> <span class="n">physics</span><span class="p">;</span> <span class="c1">// The physics SDK object</span>
|
|
|
|
<span class="n">PxU32</span> <span class="n">nbActors</span><span class="p">;</span> <span class="c1">// Max number of actors expected in the aggregate</span>
|
|
<span class="kt">bool</span> <span class="n">selfCollisions</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
|
|
|
|
<span class="n">PxAggregate</span><span class="o">*</span> <span class="n">aggregate</span> <span class="o">=</span> <span class="n">physics</span><span class="o">-></span><span class="n">createAggregate</span><span class="p">(</span><span class="n">nbActors</span><span class="p">,</span> <span class="n">selfCollisions</span><span class="p">);</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>The maximum number of actors is currently limited to 128, and for efficiency should be set as low as possible.</p>
|
|
<p>If you will never need collisions between the actors of the aggregate, disable them at creation time. This is much more efficient than using the scene filtering mechanism, as it bypasses all internal filtering logic. A typical use case would be an aggregate of static or kinematic actors.</p>
|
|
<p>Note that both the maximum number of actors and the self-collision attribute are immutable.</p>
|
|
</div>
|
|
<div class="section" id="populating-an-aggregate">
|
|
<h2>Populating an Aggregate<a class="headerlink" href="#populating-an-aggregate" title="Permalink to this headline">¶</a></h2>
|
|
<p>Adds an actor to an aggregate as follows:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxActor</span><span class="o">&</span> <span class="n">actor</span><span class="p">;</span> <span class="c1">// Some actor, previously created</span>
|
|
<span class="n">aggregate</span><span class="o">-></span><span class="n">addActor</span><span class="p">(</span><span class="n">actor</span><span class="p">);</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>Note that if the actor already belongs to a scene, the call is ignored. Either add the actors to an aggregate and then add the aggregate to the scene, or add the aggregate to the scene and then the actors to the aggregate.</p>
|
|
<p>To add the aggregate to a scene (before or after populating it):</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="n">scene</span><span class="o">-></span><span class="n">addAggregate</span><span class="p">(</span><span class="o">*</span><span class="n">aggregate</span><span class="p">);</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>Similarly, to remove the aggregate from the scene:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="n">scene</span><span class="o">-></span><span class="n">removeAggregate</span><span class="p">(</span><span class="o">*</span><span class="n">aggregate</span><span class="p">);</span>
|
|
</pre></div>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="releasing-an-aggregate">
|
|
<h2>Releasing an Aggregate<a class="headerlink" href="#releasing-an-aggregate" title="Permalink to this headline">¶</a></h2>
|
|
<p>To release an aggregate:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxAggregate</span><span class="o">*</span> <span class="n">aggregate</span><span class="p">;</span> <span class="c1">// The aggregate we previously created</span>
|
|
<span class="n">aggregate</span><span class="o">-></span><span class="n">release</span><span class="p">();</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>Releasing the PxAggregate does not release the aggregated actors. If the PxAggregate belongs to a scene, the actors are automatically re-inserted in that scene. If you intend to delete both the PxAggregate and its actors, it is most efficient to release the actors first, then release the PxAggregate when it is empty.</p>
|
|
</div>
|
|
<div class="section" id="amortizing-insertion">
|
|
<h2>Amortizing Insertion<a class="headerlink" href="#amortizing-insertion" title="Permalink to this headline">¶</a></h2>
|
|
<p>Adding many objects to a scene in one frame can be a costly operation. This can be the case for a ragdoll, which as discussed is a good candidate for PxAggregate. Another case is localized debris, for which self-collisions are often disabled. To amortize the cost of object insertion into the broad-phase structure over several, spawn the debris in a PxAggregate, then remove each actor from the aggregate and and re-insert it into the scene over those frames.</p>
|
|
</div>
|
|
<div class="section" id="trigger-shapes">
|
|
<h2>Trigger Shapes<a class="headerlink" href="#trigger-shapes" title="Permalink to this headline">¶</a></h2>
|
|
<p>Trigger shapes play no part in the simulation of the scene (though they can be configured to participate in scene queries). Instead, their role is to report that there has been an overlap with another shape. Contacts are not generated for the intersection, and as a result contact reports are not available for trigger shapes. Further, because triggers play no part in the simulation, the SDK will not allow the the eSIMULATION_SHAPE eTRIGGER_SHAPE flags to be raised simultaneously; that is, if one flag is raised then attempts to raise the other will be rejected, and an error will be passed to the error stream.</p>
|
|
<p>Trigger shapes have been used in SampleSubmarine to determine if the submarine has reached the treasure. In the following code the PxActor representing the treasure has its solitary shape configured as a trigger shapes:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="n">PxShape</span><span class="o">*</span> <span class="n">treasureShape</span><span class="p">;</span>
|
|
<span class="n">gTreasureActor</span><span class="o">-></span><span class="n">getShapes</span><span class="p">(</span><span class="o">&</span><span class="n">treasureShape</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
|
|
<span class="n">treasureShape</span><span class="o">-></span><span class="n">setFlag</span><span class="p">(</span><span class="n">PxShapeFlag</span><span class="o">::</span><span class="n">eSIMULATION_SHAPE</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span>
|
|
<span class="n">treasureShape</span><span class="o">-></span><span class="n">setFlag</span><span class="p">(</span><span class="n">PxShapeFlag</span><span class="o">::</span><span class="n">eTRIGGER_SHAPE</span><span class="p">,</span> <span class="nb">true</span><span class="p">);</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>The overlaps with trigger shapes are reported in SampleSubmarine through the implementation of PxSimulationEventCallback::onTrigger in the PxSampleSubmarine class, a sub-class of PxSimulationEventCallback:</p>
|
|
<div class="highlight-c++"><div class="highlight"><pre><span class="kt">void</span> <span class="n">SampleSubmarine</span><span class="o">::</span><span class="n">onTrigger</span><span class="p">(</span><span class="n">PxTriggerPair</span><span class="o">*</span> <span class="n">pairs</span><span class="p">,</span> <span class="n">PxU32</span> <span class="n">count</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">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">count</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
|
|
<span class="p">{</span>
|
|
<span class="c1">// ignore pairs when shapes have been deleted</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="n">pairs</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">flags</span> <span class="o">&</span> <span class="p">(</span><span class="n">PxTriggerPairFlag</span><span class="o">::</span><span class="n">eREMOVED_SHAPE_TRIGGER</span> <span class="o">|</span>
|
|
<span class="n">PxTriggerPairFlag</span><span class="o">::</span><span class="n">eREMOVED_SHAPE_OTHER</span><span class="p">))</span>
|
|
<span class="k">continue</span><span class="p">;</span>
|
|
|
|
<span class="k">if</span> <span class="p">((</span><span class="o">&</span><span class="n">pairs</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">otherShape</span><span class="o">-></span><span class="n">getActor</span><span class="p">()</span> <span class="o">==</span> <span class="n">mSubmarineActor</span><span class="p">)</span> <span class="o">&&</span>
|
|
<span class="p">(</span><span class="o">&</span><span class="n">pairs</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">triggerShape</span><span class="o">-></span><span class="n">getActor</span><span class="p">()</span> <span class="o">==</span> <span class="n">gTreasureActor</span><span class="p">))</span>
|
|
<span class="p">{</span>
|
|
<span class="n">gTreasureFound</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>The code above iterates through all pairs of overlapping shapes that involve a trigger shape. If it is found that the treasure has been touched by the submarine then the flag gTreasureFound is set true.</p>
|
|
</div>
|
|
<div class="section" id="interactions">
|
|
<h2>Interactions<a class="headerlink" href="#interactions" title="Permalink to this headline">¶</a></h2>
|
|
<p>The SDK internally creates an interaction object for each overlapping pair reported by the broad-phase. These objects are not only created for pairs of colliding rigid bodies, but also for pairs of overlapping triggers. Generally speaking users should assume that such objects are created regardless of the involved objects' types (rigid body, trigger, etc) and regardless of involved <em>PxFilterFlag</em> flags.</p>
|
|
<p>There is currently a limit of 65535 such interaction objects for each actor. If more than 65535 interactions involve the same actor, then the SDK outputs an error message and the extra interactions are ignored.</p>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
<footer>
|
|
|
|
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
|
|
|
|
<a href="RigidBodyDynamics.html" class="btn btn-neutral float-right" title="Rigid Body Dynamics" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
|
|
|
|
|
|
<a href="RigidBodyOverview.html" class="btn btn-neutral" title="Rigid Body Overview" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
|
|
|
|
</div>
|
|
|
|
|
|
<hr/>
|
|
|
|
<div role="contentinfo">
|
|
<p>
|
|
© Copyright 2008-2021 NVIDIA Corporation, 2788 San Tomas Expressway, Santa Clara, CA 95051 U.S.A. All rights reserved
|
|
|
|
</p>
|
|
</div>
|
|
|
|
</footer>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</section>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script type="text/javascript">
|
|
var DOCUMENTATION_OPTIONS = {
|
|
URL_ROOT:'../',
|
|
VERSION:'4.1',
|
|
LANGUAGE:'',
|
|
COLLAPSE_INDEX:false,
|
|
FILE_SUFFIX:'.html',
|
|
HAS_SOURCE: true,
|
|
SOURCELINK_SUFFIX: ''
|
|
};
|
|
</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>
|
|
|
|
|
|
|
|
|
|
<script type="text/javascript" src="../_static/js/theme.js"></script>
|
|
|
|
<script type="text/javascript">
|
|
jQuery(function () {
|
|
SphinxRtdTheme.Navigation.enable(false);
|
|
});
|
|
</script>
|
|
|
|
</body>
|
|
</html> |