aboutsummaryrefslogtreecommitdiff
path: root/NvCloth/docs/documentation/Solver/Index.html
diff options
context:
space:
mode:
authormtamis <[email protected]>2017-02-15 16:06:25 +0100
committermtamis <[email protected]>2017-02-15 16:06:25 +0100
commit85305930aeeb1d513e23522bd91f29ba81aa6d14 (patch)
tree45f1bb20a45a300d1fef107e436cac95602a0e57 /NvCloth/docs/documentation/Solver/Index.html
downloadnvcloth-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.html367
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 &mdash; 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> &raquo;</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 &lt;= 0) current.w = 0</span>
+<span class="c1">// computeBounds()</span>
+<span class="c1">// - if(current.w &gt; 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 &#39;damping&#39;</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&lt;T&gt;::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 &lt; \left|d\right|^2,&amp; 0\\
+ \text{else},&amp; 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">&gt;</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">&lt;=</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 &amp; 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">&gt;</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">&lt;</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> &raquo;</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