diff options
| author | mtamis <[email protected]> | 2017-02-15 16:06:25 +0100 |
|---|---|---|
| committer | mtamis <[email protected]> | 2017-02-15 16:06:25 +0100 |
| commit | 85305930aeeb1d513e23522bd91f29ba81aa6d14 (patch) | |
| tree | 45f1bb20a45a300d1fef107e436cac95602a0e57 /NvCloth/docs/documentation/Solver/Index.html | |
| download | nvcloth-85305930aeeb1d513e23522bd91f29ba81aa6d14.tar.xz nvcloth-85305930aeeb1d513e23522bd91f29ba81aa6d14.zip | |
NvCloth library v1.0.0
Diffstat (limited to 'NvCloth/docs/documentation/Solver/Index.html')
| -rw-r--r-- | NvCloth/docs/documentation/Solver/Index.html | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/NvCloth/docs/documentation/Solver/Index.html b/NvCloth/docs/documentation/Solver/Index.html new file mode 100644 index 0000000..8c98c15 --- /dev/null +++ b/NvCloth/docs/documentation/Solver/Index.html @@ -0,0 +1,367 @@ + + +<!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>Internal solver function/algorithm documentation — NVIDIA NvCloth 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/custom.css" type="text/css" /> + <script type="text/javascript"> + var DOCUMENTATION_OPTIONS = { + URL_ROOT: '../', + VERSION: '0.0', + 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 NvCloth Documentation" href="../index.html" /> + </head> + <body> + <div class="related"> + <h3>Navigation</h3> + <ul> + <li><a href="../NvCloth.html">NVIDIA NvCloth Documentation</a> »</li> + </ul> + </div> + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + <div class="body"> + + <div class="section" id="internal-solver-function-algorithm-documentation"> +<h1>Internal solver function/algorithm documentation<a class="headerlink" href="#internal-solver-function-algorithm-documentation" title="Permalink to this headline">¶</a></h1> +<p>This document describes the internal workings of the solver. +We describe how the different parts work independent from platform specific features. Although we might occasionally comment on particular implementation details.</p> +<p>Todo: give this solver a name, so that we can differentiate when a new/different solver is added.</p> +<div class="toggle container"> +<div class="header container"> +Show/Hide Code</div> +<div class="togglecontent container"> +test togglecontent</div> +</div> +<div class="section" id="overview"> +<h2>Overview<a class="headerlink" href="#overview" title="Permalink to this headline">¶</a></h2> +<p>Overview of the general algorithm goes here.</p> +<ul class="simple"> +<li>Integrate particles (integrateParticles())</li> +<li>Simulate wind/drag/lift (applyWind())</li> +<li>Distance constraints (constrainMotion())</li> +<li>Tether constraints (constrainTether())</li> +<li>Solve edge constraints (solveFabric())</li> +<li>Solve separation constraints (constrainSeparation())</li> +<li>Collision (collideParticles())</li> +<li>Self collision (selfCollideParticles())</li> +<li>Update sleep state (updateSleepState())</li> +</ul> +</div> +<div class="section" id="particle-invmass-w-component"> +<h2>Particle invMass w component<a class="headerlink" href="#particle-invmass-w-component" title="Permalink to this headline">¶</a></h2> +<p>Todo: check and rewrite:</p> +<div class="highlight-c++"><div class="highlight"><pre><span class="c1">// note on invMass (stored in current/previous positions.w):</span> +<span class="c1">// integrateParticles()</span> +<span class="c1">// - if(current.w == 0) current.w = previous.w</span> +<span class="c1">// constraintMotion()</span> +<span class="c1">// - if(constraint.radius <= 0) current.w = 0</span> +<span class="c1">// computeBounds()</span> +<span class="c1">// - if(current.w > 0) current.w = previous.w</span> +<span class="c1">// collideParticles()</span> +<span class="c1">// - if(collides) current.w *= 1/massScale</span> +<span class="c1">// after simulate()</span> +<span class="c1">// - previous.w: original invMass as set by user</span> +<span class="c1">// - current.w: zeroed by motion constraints and mass-scaled by collision</span> +</pre></div> +</div> +</div> +<div class="section" id="slack"> +<h2>Slack<a class="headerlink" href="#slack" title="Permalink to this headline">¶</a></h2> +<p>The position constraint for keeping distance between points a and b is usually written as:</p> +<div class="highlight-c++"><div class="highlight"><pre><span class="n">error</span> <span class="o">=</span> <span class="o">|</span><span class="n">b</span><span class="o">-</span><span class="n">a</span><span class="o">|</span> <span class="o">-</span> <span class="n">restLength</span> +<span class="n">offset</span> <span class="o">=</span> <span class="n">error</span> <span class="o">*</span> <span class="p">(</span><span class="n">b</span><span class="o">-</span><span class="n">a</span><span class="p">)</span><span class="o">/|</span><span class="n">b</span><span class="o">-</span><span class="n">a</span><span class="o">|</span> + <span class="o">=</span> <span class="p">(</span><span class="n">b</span><span class="o">-</span><span class="n">a</span><span class="p">)</span> <span class="o">-</span> <span class="n">restLength</span><span class="o">*</span><span class="p">(</span><span class="n">b</span><span class="o">-</span><span class="n">a</span><span class="p">)</span><span class="o">/|</span><span class="n">b</span><span class="o">-</span><span class="n">a</span><span class="o">|</span> +</pre></div> +</div> +<p>The equation calculating <em>slack</em> pops up often in the solver code. +This does exactly the same as the above:</p> +<div class="highlight-c++"><div class="highlight"><pre><span class="n">slack</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">-</span> <span class="n">restLength</span> <span class="o">/</span> <span class="o">|</span><span class="n">b</span><span class="o">-</span><span class="n">a</span><span class="o">|</span> +<span class="n">offset</span> <span class="o">=</span> <span class="p">(</span><span class="n">b</span><span class="o">-</span><span class="n">a</span><span class="p">)</span> <span class="o">*</span> <span class="n">slack</span> + <span class="o">=</span> <span class="p">(</span><span class="n">b</span><span class="o">-</span><span class="n">a</span><span class="p">)</span> <span class="o">-</span> <span class="n">restLength</span><span class="o">*</span><span class="p">(</span><span class="n">b</span><span class="o">-</span><span class="n">a</span><span class="p">)</span><span class="o">/|</span><span class="n">b</span><span class="o">-</span><span class="n">a</span><span class="o">|</span> +</pre></div> +</div> +</div> +<div class="section" id="integration"> +<h2>Integration<a class="headerlink" href="#integration" title="Permalink to this headline">¶</a></h2> +<p>The first step of the cloth simulation is the integration. +Explicit Euler integration is used to calculate the new position of the particles. +The velocity of the particles is not stored, instead we use the position from the previous frame to calculate the velocity. +We need to compensate for differences in delta time. Large fluctuations can cause problems, so the delta time is damped.</p> +<p>The following pseudo code describes how this is implemented:</p> +<div class="highlight-c++"><div class="highlight"><pre><span class="c1">//calculate damping constants from user setting 'damping'</span> +<span class="n">logDamping</span> <span class="o">=</span> <span class="n">log_2</span><span class="p">(</span><span class="mi">1</span><span class="o">-</span><span class="n">damping</span><span class="p">)</span> <span class="c1">//from ClothImpl<T>::setDamping</span> +<span class="n">dampExponent</span> <span class="o">=</span> <span class="n">stiffnessFrequency</span> <span class="o">*</span> <span class="n">dt1</span> <span class="c1">//from IterationState::create</span> + +<span class="c1">//calculate delta time ajustment</span> +<span class="n">scale</span> <span class="o">=</span> <span class="n">e</span><span class="o">^</span><span class="p">{</span><span class="n">logDamping</span> <span class="o">*</span> <span class="n">dampExponent</span><span class="p">}</span> <span class="o">*</span> <span class="p">{</span><span class="n">dt1</span><span class="o">/</span><span class="n">dt0</span><span class="p">}</span> <span class="c1">//from IterationState::create</span> +<span class="c1">//Do the integration</span> +<span class="n">delta</span> <span class="o">=</span> <span class="p">(</span><span class="n">particle_position1</span><span class="o">-</span><span class="n">particle_position0</span><span class="p">)</span> <span class="o">*</span> <span class="n">scale</span> <span class="o">+</span> <span class="n">acceleration</span> +<span class="n">particle_position1</span> <span class="o">=</span> <span class="n">particle_position1</span> <span class="o">+</span> <span class="n">delta</span> +</pre></div> +</div> +<p>The integration code also replaces the current inverse mass with the previous inverse mass if the current is zero.</p> +<p>Todo: rotating reference frame.</p> +<p>Todo: how does damping work?</p> +</div> +<div class="section" id="wind-simulation"> +<h2>Wind simulation<a class="headerlink" href="#wind-simulation" title="Permalink to this headline">¶</a></h2> +<p>Drag and lift simulation is done in the applyWind() function. +The following algorithm is used:</p> +<div class="highlight-c++"><pre>for each triangle + \(p_j\) is the previous and \(c_j\) is the current position and \(m^{-1}_j\) is the inverse mass of the \(j\)th particle in of the triangle. + + //Calculate current and previous center of the triangle + \(c_t = \frac{1}{3} \cdot \left( c_0 + c_1 + c_2 \right)\) + \(p_t = \frac{1}{3} \cdot \left( p_0 + p_1 + p_2 \right)\) + + //Position difference including wind (same as flow speed times dt) + \(d = c_t - p_t + wind\) + + if rotating reference frame + \(d = c_t + R\left(d-c_t\right)\) //where \(R\) is the inverse local space rotation for one solver iteration + //Todo check/explain this + + //Unnormalized normal of the triangle + \(n = \left(c_2 - c_0\right) \times \left(c_1 - c_0\right) \) + + //Double the area of the triangle + \(a = \left|n\right| \) + + \(\Lrg{ \cos\left(\theta\right) = \frac{n \cdot d}{\left|n\right| \cdot \left|d \right|} }\) + \(\Lrg{ \sin\left(\theta\right) = \sqrt{\max(0, 1 - \cos\left(\theta\right)^2)}}\) + + //Lift direction is orthogonal to delta, in the delta-normal plane. Its length is \(\left|n\right|\cdot\left|d\right|\) + \(\Lrg{ l_{dir} = \frac{\left( d \times n\right) \times d}{\left|d \right|} }\) + + //Calculate the lift and drag impulse + //The lift is at its maximum when \(d\) is at an \(45^\circ\) angle to the triangle + //We use \(\sin\left(\theta\right)\cdot\cos\left(\theta\right) = \frac{1}{2}\sin\left(2\cdot \theta\right)\) to calculate this + \(i_{lift} = c_{lift} \cdot \cos\left(\theta\right) \cdot \sin\left(\theta\right) \cdot l_{dir} \) + \(i_{drag} = c_{drag} \cdot \left|\cos\left(\theta\right)\right| \cdot a \cdot d \) + //\(c_{lift} \) and \(c_{drag}\) are the lift and drag coefficients + //\(c_{drag}\) should be set to compensate for the double area in \(a\) + + //combined impulse + \(\Lrg{ i = + \begin{cases} + \epsilon < \left|d\right|^2,& 0\\ + \text{else},& i_{lift} + i_{drag} + \end{cases} + }\) + + //apply impulses to the particle positions + for each particle \(j = \left\{ 0, 1, 2 \right\} \) + \(c_j = c_j - i \cdot m^{-1}_j \)</pre> +</div> +<p>Note that when we combine the impulses we check if \(\left|d\right|\) is too small as this causes instabilities due to float division inaccuracies. +This can cause different drag and lift behavior depending on the time step size (or solver frequency). +Smaller time steps result in smaller position deltas which reach the \(\epsilon\) threshold sooner. +This results in less drag/lift at small time steps (high solver frequencies) for slow moving particles.</p> +</div> +<div class="section" id="distance-constraints"> +<h2>Distance constraints<a class="headerlink" href="#distance-constraints" title="Permalink to this headline">¶</a></h2> +<p>A distance constraint can limit the movement of a particle to the volume of a sphere. +The constraints are specified with an array of 4 dimensional vectors (physx::PxVec4) where the x, y, z elements define the center and w the radius of the sphere.</p> +<p>The constraints are interpolated between the start and target spheres if both are given.</p> +<p>The constrainMotion() function in the solver is responsible for enforcing these constraints. +The following pseudo code describes how this is implemented:</p> +<div class="highlight-c++"><div class="highlight"><pre><span class="n">delta</span> <span class="o">=</span> <span class="n">sphere_center</span> <span class="o">-</span> <span class="n">particle_position</span> +<span class="n">sqrLength</span> <span class="o">=</span> <span class="n">epsilon</span> <span class="o">+</span> <span class="o">|</span><span class="n">delta</span><span class="o">|^</span><span class="mi">2</span> +<span class="n">radius</span> <span class="o">=</span> <span class="n">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">sphere_radius</span> <span class="o">*</span> <span class="n">scale</span> <span class="o">+</span> <span class="n">bias</span><span class="p">)</span> +<span class="n">slack</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">-</span> <span class="n">radius</span> <span class="o">/</span> <span class="n">sqrt</span><span class="p">{</span><span class="n">sqrLength</span><span class="p">}</span> + +<span class="k">if</span><span class="p">(</span><span class="n">slack</span><span class="o">></span><span class="mi">0</span><span class="p">)</span> +<span class="p">{</span> + <span class="k">if</span><span class="p">(</span><span class="n">radius</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">)</span> + <span class="n">particle_invMass</span><span class="p">.</span><span class="n">w</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1">//Set the inverse mass to 0 if we are constrained to a zero radius sphere</span> + <span class="n">slack</span> <span class="o">=</span> <span class="n">slack</span> <span class="o">*</span> <span class="n">stiffness</span> + <span class="n">particle</span><span class="p">.</span><span class="n">xyz</span> <span class="o">+=</span> <span class="n">delta</span> <span class="o">*</span> <span class="n">slack</span> +<span class="p">}</span> +</pre></div> +</div> +</div> +<div class="section" id="tether-constraints"> +<h2>Tether constraints<a class="headerlink" href="#tether-constraints" title="Permalink to this headline">¶</a></h2> +<p>Tether constraints help with reducing the stretchiness of the cloth without increasing the solver iteration count. +This is done by adding additional max distance constraints connecting simulated particles with their nearest fixed particle(s). +The tether constraints are stored as an index & length pair. +The array of constraints has a multiple of particle count elements. +The constraints in the array are stored in order so that the first particle of the constraint is element%numParticles. +The index stored in the constraint defines the other (anchor) particle of the constraint.</p> +<p>The constraint for one particle is solved as follows:</p> +<div class="highlight-c++"><div class="highlight"><pre><span class="n">offset</span> <span class="o">=</span> <span class="mi">0</span> +<span class="k">for</span> <span class="n">each</span> <span class="n">tether</span> <span class="n">connecting</span> <span class="n">pb</span> + <span class="c1">//pa is the anchor particle</span> + <span class="n">delta</span> <span class="o">=</span> <span class="n">pa</span> <span class="o">-</span> <span class="n">pb</span> + <span class="n">radius</span> <span class="o">=</span> <span class="n">tetherLength</span> <span class="o">*</span> <span class="n">scale</span> + <span class="n">slack</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">-</span> <span class="n">radius</span> <span class="o">/</span> <span class="p">(</span><span class="o">|</span><span class="n">delta</span><span class="o">|</span> <span class="o">+</span> <span class="n">epsilon</span><span class="p">)</span> + <span class="n">offset</span> <span class="o">+=</span> <span class="n">delta</span> <span class="o">*</span> <span class="n">max</span><span class="p">(</span><span class="n">slack</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> +<span class="n">pb</span> <span class="o">+=</span> <span class="n">offset</span> <span class="o">*</span> <span class="n">stiffness</span> +</pre></div> +</div> +<p>The stiffness is calculated as follows:</p> +<div class="highlight-c++"><div class="highlight"><pre><span class="n">stiffness</span> <span class="o">=</span> <span class="n">tetherConstraintStiffness</span> <span class="o">*</span> <span class="n">numParticles</span> <span class="o">/</span> <span class="n">numTethers</span> +</pre></div> +</div> +</div> +<div class="section" id="edge-constraints"> +<h2>Edge constraints<a class="headerlink" href="#edge-constraints" title="Permalink to this headline">¶</a></h2> +<p>Algorithm:</p> +<div class="highlight-c++"><div class="highlight"><pre><span class="n">r</span> <span class="o">=</span> <span class="n">restlength</span> +<span class="n">pi</span> <span class="o">=</span> <span class="n">particle</span> <span class="n">i</span> +<span class="n">piw</span> <span class="o">=</span> <span class="n">inv</span> <span class="n">weight</span> <span class="n">of</span> <span class="n">particle</span> <span class="n">i</span> +<span class="n">h</span> <span class="o">=</span> <span class="n">pb</span><span class="o">-</span><span class="n">pa</span> +<span class="n">e2</span> <span class="o">=</span> <span class="n">epsilon</span> <span class="o">+</span> <span class="o">|</span><span class="n">h</span><span class="o">|^</span><span class="mi">2</span> +<span class="n">er</span> <span class="o">=</span> <span class="n">r</span><span class="o">></span><span class="mi">0</span> <span class="o">?</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="n">r</span> <span class="o">/</span> <span class="n">sqrt</span><span class="p">{</span><span class="n">e2</span><span class="p">})</span> <span class="o">:</span> <span class="mi">0</span> + +<span class="k">if</span><span class="p">(</span><span class="n">useMultiplier</span><span class="p">)</span> +<span class="p">{</span> + <span class="c1">//from PhaseConfig.h cloth::transform</span> + <span class="n">multiplierC</span> <span class="o">=</span> <span class="n">log2</span><span class="p">(</span><span class="n">stiffnessMultiplier</span><span class="p">)</span> + <span class="n">compressionLimitC</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">/</span> <span class="n">compressionLimit</span> + <span class="n">strechLimitC</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">/</span> <span class="n">stretchLimit</span> + <span class="n">er</span> <span class="o">-=</span> <span class="n">multiplierC</span> <span class="o">*</span> <span class="n">max</span><span class="p">(</span><span class="n">compressionLimitC</span><span class="p">,</span> <span class="n">min</span><span class="p">(</span><span class="n">er</span><span class="p">,</span> <span class="n">stretchLimitC</span><span class="p">))</span> +<span class="p">}</span> + +<span class="n">stiffnessExponent</span> <span class="o">=</span> <span class="n">stiffnessFrequency</span> <span class="o">*</span> <span class="n">dt</span><span class="o">/</span><span class="n">iterations</span> +<span class="n">stiffness</span> <span class="o">=</span> <span class="n">log2</span><span class="p">(</span><span class="mi">1</span><span class="o">-</span><span class="n">stiffness</span><span class="p">)</span> <span class="c1">//check when this happens //from PhaseConfig.h cloth::transform</span> +<span class="n">stiffnessC</span> <span class="o">=</span> <span class="mi">1</span><span class="o">-</span><span class="mi">2</span><span class="o">^</span><span class="p">{</span><span class="n">stiffness</span> <span class="o">*</span> <span class="n">stiffnessExponent</span><span class="p">}</span> +<span class="n">ex</span> <span class="o">=</span> <span class="n">er</span> <span class="o">*</span> <span class="n">stiffnessC</span> <span class="o">/</span> <span class="p">(</span><span class="n">pbw</span><span class="o">+</span><span class="n">paw</span><span class="p">)</span> + +<span class="n">pa</span> <span class="o">=</span> <span class="n">pa</span> <span class="o">+</span> <span class="n">h</span><span class="o">*</span><span class="n">ex</span> <span class="o">*</span> <span class="n">paw</span> +<span class="n">pb</span> <span class="o">=</span> <span class="n">pb</span> <span class="o">-</span> <span class="n">h</span><span class="o">*</span><span class="n">ex</span> <span class="o">*</span> <span class="n">pbw</span> +</pre></div> +</div> +</div> +<div class="section" id="separation-constraints"> +<h2>Separation constraints<a class="headerlink" href="#separation-constraints" title="Permalink to this headline">¶</a></h2> +<p>Separation constraints do exactly the opposite of distance constraints. +These constraints ensure that the particles remain outside the defined spheres.</p> +<p>The constraints are interpolated between the start and target spheres if both are given.</p> +<p>The constrainSeparation() function in the solver is responsible for enforcing these constraints. +Solving a single constraint is done as follows:</p> +<div class="highlight-c++"><div class="highlight"><pre><span class="c1">//p is the particle position</span> +<span class="c1">//c is the sphere center</span> +<span class="c1">//r is the sphere radius</span> +<span class="n">d</span> <span class="o">=</span> <span class="n">c</span><span class="o">-</span><span class="n">p</span> +<span class="n">l</span> <span class="o">=</span> <span class="o">|</span><span class="n">d</span><span class="o">|</span> +<span class="n">slack</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">-</span> <span class="n">r</span><span class="o">/</span><span class="n">l</span> +<span class="k">if</span><span class="p">(</span><span class="n">slack</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span> + <span class="n">p</span> <span class="o">+=</span> <span class="n">d</span> <span class="o">*</span> <span class="n">slack</span> +</pre></div> +</div> +</div> +<div class="section" id="fabric-data-structure"> +<h2>Fabric data structure<a class="headerlink" href="#fabric-data-structure" title="Permalink to this headline">¶</a></h2> +<p>The fabric data structure contains the constraint information that can be reused by multiple cloth instances. +The constraints are divided in different phases. +Each phase usually contains a different type of constraints such as (horizontal/vertical) stretching, searing, bending constraints.</p> +<p>mPhases contains indices indicating which set from mSets belongs to a phase.</p> +<p>mSets contains a list of start (and end) indices for mRestvalues and mIndices (if multiplied by 2). +The first rest value of set s is mRestvalues[mSets[s]] and the last is mRestvalues[mSets[s+1]-1].</p> +<p>mRestvalues contains the rest lengths / edge lengths of the constraints.</p> +<p>mIndices contains pairs of indices connected by a constraint. (mIndices.size()*2 == mRestvalues.size())</p> +</div> +</div> + + + </div> + </div> + </div> + <div class="sphinxsidebar"> + <div class="sphinxsidebarwrapper"> + <h3><a href="../NvCloth.html">Table Of Contents</a></h3> + <ul> +<li><a class="reference internal" href="#">Internal solver function/algorithm documentation</a><ul> +<li><a class="reference internal" href="#overview">Overview</a></li> +<li><a class="reference internal" href="#particle-invmass-w-component">Particle invMass w component</a></li> +<li><a class="reference internal" href="#slack">Slack</a></li> +<li><a class="reference internal" href="#integration">Integration</a></li> +<li><a class="reference internal" href="#wind-simulation">Wind simulation</a></li> +<li><a class="reference internal" href="#distance-constraints">Distance constraints</a></li> +<li><a class="reference internal" href="#tether-constraints">Tether constraints</a></li> +<li><a class="reference internal" href="#edge-constraints">Edge constraints</a></li> +<li><a class="reference internal" href="#separation-constraints">Separation constraints</a></li> +<li><a class="reference internal" href="#fabric-data-structure">Fabric data structure</a></li> +</ul> +</li> +</ul> + +<div id="searchbox" style="display: none"> + <h3>Quick search</h3> + <form class="search" action="../search.html" method="get"> + <input type="text" name="q" size="18" /> + <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><a href="../NvCloth.html">NVIDIA NvCloth Documentation</a> »</li> + </ul> + </div> + + <script type="text/javascript"> + $(document).ready(function() { + $(".toggle > *").hide(); + $(".toggle .header").show(); + $(".toggle .header").click(function() { + $(this).parent().children().not(".header").toggle(400); + $(this).parent().children(".header").toggleClass("open"); + }) + }); +</script> + + +<script type="text/x-mathjax-config"> + MathJax.Hub.Config({ + extensions: ["tex2jax.js"], + jax: ["input/TeX", "output/HTML-CSS"], + tex2jax: { + processEscapes: true, + skipTags: ["script","noscript","style","textarea"] + }, + "HTML-CSS": { availableFonts: ["TeX"] }, + TeX: { + Macros: { + Lrg: ['\\displaystyle{#1}', 1, ""] + } + } + }); +</script> + + +<script type="text/javascript" async + src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML"> +</script> + + + </body> +</html>
\ No newline at end of file |