forked from windystrife/UnrealEngine_NVIDIAGameWorks
-
Notifications
You must be signed in to change notification settings - Fork 0
/
FLEXUe4_Containers.html
308 lines (293 loc) · 26.4 KB
/
FLEXUe4_Containers.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
<!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" />
<meta http-equiv="x-ua-compatible" content="IE=Edge"/>
<title>Containers — Flex Artist Tools 1.0 documentation</title>
<link rel="stylesheet" href="_static/flex.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="_static/breathe.css" type="text/css" />
<link rel="stylesheet" href="_static/application.css" type="text/css" />
<link rel="stylesheet" href="_static/styleguide.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '1.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>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/javascript" src="_static/bootstrap.js"></script>
<script type="text/javascript" src="_static/jquery.cookie.js"></script>
<script type="text/javascript" src="_static/jquery.storageapi.js"></script>
<link rel="top" title="Flex Artist Tools 1.0 documentation" href="index.html" />
<link rel="next" title="Assets" href="FLEXUe4_Assets.html" />
<link rel="prev" title="Particles" href="FLEXUe4_Phases.html" />
</head>
<body>
<nav class="navbar navbar-inverse navbar-default">
<div class="row">
<div class="navbar-brand">
<img class="logo" src="_static/developerzone_gameworks_logo.png" alt="Logo"/>
</div>
<div id="searchbox" style="display: none; float:right; padding-top:4px; padding-right:4px">
<form class="search form-inline" action="search.html" method="get">
<div class="form-group">
<input type="text" name="q" class="form-control" />
<input type="submit" value="Search" class="btn btn-primary" />
</div>
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</nav>
<div class="masthead">
<div class="row">
<ul class="breadcrumb">
<li><a href="index.html">Flex Artist Tools 1.0 documentation</a></li>
</ul>
</div>
</div>
<div class="row">
<div class="col-md-3 bs-sidenav" style="white-space: nowrap; overflow: auto;">
<div class="bs-sidebar">
<div id="sidebar_toc">
<h4>Table Of Contents</h4>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="FLEXUe4_Intro.html">Introduction</a></li>
<li class="toctree-l1"><a class="reference internal" href="FLEXUe4_Intro.html#prerequisites">Prerequisites</a></li>
<li class="toctree-l1"><a class="reference internal" href="FLEXUe4_Phases.html">Particles</a><ul>
<li class="toctree-l2"><a class="reference internal" href="FLEXUe4_Phases.html#radius">Radius</a></li>
<li class="toctree-l2"><a class="reference internal" href="FLEXUe4_Phases.html#phases">Phases</a></li>
</ul>
</li>
<li class="toctree-l1 current"><a class="current reference internal" href="">Containers</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#flex-container">Flex Container</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#simulation">Simulation</a></li>
<li class="toctree-l3"><a class="reference internal" href="#collision">Collision</a></li>
<li class="toctree-l3"><a class="reference internal" href="#cloth">Cloth</a></li>
<li class="toctree-l3"><a class="reference internal" href="#fluid">Fluid</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="FLEXUe4_Assets.html">Assets</a><ul>
<li class="toctree-l2"><a class="reference internal" href="FLEXUe4_Assets.html#soft-bodies">Soft Bodies</a><ul>
<li class="toctree-l3"><a class="reference internal" href="FLEXUe4_Assets.html#flex-soft-asset">Flex Soft Asset</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="FLEXUe4_Assets.html#cloth">Cloth</a><ul>
<li class="toctree-l3"><a class="reference internal" href="FLEXUe4_Assets.html#flex-cloth-asset">Flex Cloth Asset</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="FLEXUe4_Assets.html#rigids">Rigids</a><ul>
<li class="toctree-l3"><a class="reference internal" href="FLEXUe4_Assets.html#flex-solid-asset">Flex Solid Asset</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="FLEXUe4_Actors.html">Actors</a></li>
<li class="toctree-l1"><a class="reference internal" href="FLEXUe4_Particles.html">Emitters</a><ul>
<li class="toctree-l2"><a class="reference internal" href="FLEXUe4_Particles.html#particle-emitter">Particle Emitter</a></li>
<li class="toctree-l2"><a class="reference internal" href="FLEXUe4_Particles.html#particle-modules">Particle Modules</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="FLEXUe4_Ropes.html">Ropes</a></li>
<li class="toctree-l1"><a class="reference internal" href="FLEXUe4_Forces.html">Forces</a><ul>
<li class="toctree-l2"><a class="reference internal" href="FLEXUe4_Forces.html#radial-force-component">Radial Force Component</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="FLEXUe4_DrainsAndCounting.html">Counting and Draining</a><ul>
<li class="toctree-l2"><a class="reference internal" href="FLEXUe4_DrainsAndCounting.html#creating-a-drain">Creating a Drain</a></li>
<li class="toctree-l2"><a class="reference internal" href="FLEXUe4_DrainsAndCounting.html#counting-particles">Counting Particles</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="FLEXUe4_FluidSurfaceRendering.html">Fluid Rendering</a><ul>
<li class="toctree-l2"><a class="reference internal" href="FLEXUe4_FluidSurfaceRendering.html#creating-a-flex-fluid-surface">Creating a Flex Fluid Surface</a></li>
<li class="toctree-l2"><a class="reference internal" href="FLEXUe4_FluidSurfaceRendering.html#fluid-surface-properties">Fluid Surface Properties</a></li>
<li class="toctree-l2"><a class="reference internal" href="FLEXUe4_FluidSurfaceRendering.html#emitter-settings">Emitter Settings</a></li>
<li class="toctree-l2"><a class="reference internal" href="FLEXUe4_FluidSurfaceRendering.html#surface-material">Surface Material</a></li>
<li class="toctree-l2"><a class="reference internal" href="FLEXUe4_FluidSurfaceRendering.html#container">Container</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="FLEXUe4_LocalSpace.html">Local Space Simulation</a></li>
<li class="toctree-l1"><a class="reference internal" href="FLEXUe4_Debug.html">Debug Commands</a><ul>
<li class="toctree-l2"><a class="reference internal" href="FLEXUe4_Debug.html#console-commands">Console Commands</a></li>
<li class="toctree-l2"><a class="reference internal" href="FLEXUe4_Debug.html#stats">Stats</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="releasenotes.html">Release Notes</a><ul>
<li class="toctree-l2"><a class="reference internal" href="releasenotes.html#what-s-new">What’s New</a></li>
<li class="toctree-l2"><a class="reference internal" href="releasenotes.html#known-limitations">Known Limitations</a></li>
</ul>
</li>
</ul>
</div>
<h4>Previous topic</h4>
<p class="topless"><a href="FLEXUe4_Phases.html"
title="previous chapter">Particles</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="FLEXUe4_Assets.html"
title="next chapter">Assets</a></p>
<div id="searchbox" style="display: none">
<h4>Quick search</h4>
<form class="search form-inline" action="search.html" method="get">
<div class="form-group">
<input type="text" name="q" class="form-control" />
<input type="submit" value="Search" class="btn btn-primary" />
</div>
<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="document col-md-8">
<div class="body">
<div class="section" id="containers">
<span id="flexue4-containers"></span><h1>Containers<a class="headerlink" href="#containers" title="Permalink to this headline">¶</a></h1>
<p>Containers are where all simulation happens in Flex. They can be thought of as a type of scene, although you can have more than one container active in a level at any one time. Actors, such as particle systems, static meshes, or ropes will emit particles and constraints into the container, and will be simulated as the level is ticked.</p>
<p>Although containers can hold any type of Flex objects, it can make sense to specialize containers for different object types.</p>
<p>To create a container, right-click in the Content Browser, and choose <strong>Create Advanced Asset->Physics->FlexContainer</strong>.</p>
<a class="reference internal image-reference" href="_images/NewContainerX.jpg"><img alt="_images/NewContainerX.jpg" src="_images/NewContainerX.jpg" style="width: 600px;" /></a>
<p>Give your container an appropriate name, e.g.: FlexRigidContainer, and double click to open it’s property sheet.</p>
<div class="section" id="flex-container">
<h2>Flex Container<a class="headerlink" href="#flex-container" title="Permalink to this headline">¶</a></h2>
<p>The container holds a wide range of simulation parameters, broken into categories according to the objects they affect.</p>
<ul class="simple">
<li><strong>Radius</strong> See Radius section.</li>
<li><strong>Max Particles</strong> Each container can accommodate a fixed number of particles which may be added from any number of sources, e.g. particle emitters, rigid bodies, clothing. If the container is full then new particles will not be added, and objects may appear to stop being simulated. Max particles should be set to a conservative upper bound on the expected number of particles required.</li>
<li><strong>Debug Draw</strong> Enables debug draw for this container when the level is being played. Note that debug draw can also be turned on for all containers via the “FlexVIS” console command.</li>
</ul>
<div class="section" id="simulation">
<h3>Simulation<a class="headerlink" href="#simulation" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><strong>Num Iterations</strong> Flex solves the constraints in an effect iteratively. The number of iterations affects the overall stiffness of the constraints. More complex scenes might require more iterations to reach the level of stiffness achieved with fewer iterations in simpler scenes. For long pieces of hanging cloth 8-10 iterations may be necessary, whereas for simple fluid emitters 1-3 iterations may be sufficient. For performance reasons this should be set to the lowest number possible to achieve the desired effect.</li>
<li><strong>Num Substeps</strong> Substeps allow subdividing the game’s time-step for more accurate simulation. Increasing the number of substeps reduces the chance of missed collisions and tunneling. Each substep will perform collision detection and Num Iterations (see above) constraint solves. So a setting of 2 substeps and 3 iterations performs 6 constraint iterations total per-frame which will make objects appear stiffer. Each additional sub-step is also a multiplier on performance cost, for instance 2 substeps will generally take twice as long as 1 to compute.</li>
<li><strong>Min Frame Rate</strong> Controls the minimum frame-rate that Flex will attempt to sub-step. If the actual frame-rate is smaller, Flex will limit the amount of substeps corresponding to the minimum frame-rate parameter. Setting this lower will result in more sub-steps being taken so it should be set as high as possible, (although the simulation will appear to run slower than real-time if the game cannot maintain this frame rate).</li>
<li><strong>Fixed Time Step</strong> Many games use a variable time-step for each frame which can cause stability problems for physics simulations. To avoid this, it is recommended to enable the Fixed Time Step option which will automatically subdivide the game’s frame time into a number of substeps each with a constant time delta. This approach can result in some de-synchronization between physics and animation but should only be disabled if noticeable problems are observed.</li>
<li><strong>Gravity</strong> Constant acceleration applied to all particles at the start of the time-step.</li>
<li><strong>Sleep Threshold</strong> Particles which moved < this distance during the time-step will be set back to their original position. This can be used to stop particles drifting down slopes indefinitely, or to approximate static friction. It does not provide any computational performance advantage as the constraints will still be solved on these particles in order to determine the sleep condition.</li>
<li><strong>Max Velocity</strong> This is a limiter on the maximum particle velocity. It can be used to reduce tunneling when using a low number of sub-steps.</li>
<li><strong>Max Container Bound</strong> Limits the maximum bounding box of the container used to gather collision shapes. This parameter can be used to stop the bounds from growing too large and causing scene queries to return a high number of shapes, e.g.: when particles fall out of the level.</li>
<li><strong>Relaxation Mode</strong> The relaxation mode provides a fine tuning control of how constraints are solved. It can be used to improve convergence (stiffness), which can allow you to reduce the iteration count and improve performance.</li>
<li><strong>Local</strong> In this mode a local averaging is performed per-particle. The sum of all constraints affecting a particle is averaged before updating the position and velocity. This method is very robust and will generally converge even in difficult circumstances, for example when competing or redundant constraints are present. However it tends to converge quite slowly, and requires many iterations to appear stiff. To improve convergence in this mode Relaxation Factor can be set to a value > 1.0, this is called over-relaxation. Values much larger than 1.0 will occasionally cause the simulation to blow up so it should be set carefully.</li>
<li><strong>Global</strong> In this mode the effect of constraints is weighted by a global factor, no averaging is performed. This mode tends to converge faster than the local mode, but may cause divergence in difficult cases. In this mode the relaxation factor, Relaxation Factor should be set to a value < 1.0, e.g.: 0.25-0.5 to ensure convergence. Global relaxation often works well for cloth, and can noticeable improve convergence at low-iteration counts.</li>
<li><strong>Relaxation Factor</strong> See notes the Relaxation Mode for more details on the meaning of this parameter.</li>
<li><strong>Damping</strong> This parameter controls a viscous damping force that acts like an air-resistance on particles. Generally some level of damping is desirable to encourage particles to come to rest quickly.</li>
</ul>
</div>
<div class="section" id="collision">
<h3>Collision<a class="headerlink" href="#collision" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><strong>Complex Collision</strong> If true then this container will use the complex collision (triangle meshes) from the Unreal assets. If false, it will use the approximate convex mesh shapes associated with each asset. Note that triangle mesh collision is generally less robust than convex collision so this should be disabled where possible, especially when dealing with moving shapes.</li>
<li><strong>Object Type</strong> This is the object type that is used when the container queries the world to find overlapping collision shapes for the Flex particles. To stop an Actor colliding with Flex particles it should disable collision against the object type set on the container, usually this will be left at the default (Flex).</li>
<li><strong>Response to Channels</strong> Controls which types of objects the Flex container will consider when gathering collision shapes from the world. To stop the container particles colliding against a particular object type it’s response should be set to Ignore. Note that Blocking needs to be set up on individual FlexActors to work as expected.</li>
<li><strong>Collision Distance</strong> This is the distance that particles will try to maintain from static objects. Generally it should be > 0.0 and set to some fraction of the radius, i.e.: 0.5*radius.</li>
<li><strong>Shape Friction</strong> The coefficient of friction used for particle collisions against static objects.</li>
<li><strong>Particle Friction</strong> The coefficient of friction used for particle collisions against other particles.</li>
<li><strong>Restitution</strong> Restitution coefficient against static objects.</li>
<li><strong>Adhesion</strong> Adhesion is an attractive force which tries to keep particles in contact with static geometry. It can be used to generate “sticky” liquids that hang on an object when turned upside down.</li>
<li><strong>Dissipation</strong> Dissipation will cause particles to lose energy when they come into contact with each other. This can be used to slow down particles and cause the formation of large piles. It is not momentum conserving so if set too high then particles may appear to freeze in mid-air when they come in contact.</li>
<li><strong>Collision Margin Particles</strong> The collision margin allows expanding the particle’s radius during collision detection against particles. Because Flex performs collision detection once per-substep, new collisions can be missed if a particle moves too far during the step. The next step the new collision is found and the particle will be ejected causing “popping”. Increasing the collision margin reduces the chance of missing collisions by gathering more potential neighbors during collision. Generally it should be set as a fraction of the radius, e.g.: if the radius is set to 15 and you see popping artifacts then increasing the collision margin to 2-5 should resolve any issues. Note that this can impact performance because it greatly increases the number of potential neighbors that are checked for collision.</li>
<li><strong>Collision Margin Shapes</strong> This parameter controls how to expand the particle radius when finding collisions against shapes. This can be increased to avoid missing collisions against static geometry, and is usually best set to some fraction of the Collision Distance. Note that Flex has an internal limit of 4 contacts per-particle, so if this margin is made too large then this limit may be overflowed and contacts dropped.</li>
<li><strong>Enable CCD</strong> For collision against triangle meshes Flex always uses line-segment tests to detect if the particle has passed through the geometry. These tests are performed at the start of the time-step. This option enables a second collision detection pass against triangle meshes at the <em>end</em> of the time-step. This can help resolve tunneling against static shapes when particles are “squished” between some object and the mesh. Generally it should be left disabled unless tunneling artifacts against triangle meshes are noticed as it has high performance cost.</li>
<li><strong>Shock Propagation</strong> Shock propagation is a method for increasing the apparent stiffness of piles and stacks of rigid bodies. It works by artificially increasing the mass of lower bodies so that they become more resistant to pressure from above. Unless trying to generate large piles of particles this can be left disabled.</li>
</ul>
</div>
<div class="section" id="cloth">
<h3>Cloth<a class="headerlink" href="#cloth" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><strong>Wind</strong> Applies a global acceleration to particles connected to cloth triangles. Note that the force due to wind is a function of the triangle drag coefficient (see below), so drag should be set > 1.0 to see the effect of wind.</li>
<li><strong>Drag</strong> This is a force similiar to Damping but only affects particles that are connected to cloth triangles. It applies a drag force similiar to air-resistance, taking into account the face orientation relative to the wind and current velocity.</li>
<li><strong>Lift</strong> Lift is a force that acts perpendicular to the triangle plane and the relative velocity. The lift model in Flex is an approximation of the thin-airfoil model and can generate interesting tumbling and fluttering effects as cloth falls.</li>
</ul>
</div>
<div class="section" id="fluid">
<h3>Fluid<a class="headerlink" href="#fluid" title="Permalink to this headline">¶</a></h3>
<ul class="simple">
<li><strong>Fluid</strong> When true, particles with the Fluid flag enabled on their Phase will be treated as fluid particles. This means they no-longer use the hard-sphere collision, and instead use a fluid density constraint to maintain a fixed rest density. When this is enabled the particle radius specifies the “smoothing radius” of the fluid kernels.</li>
<li><strong>Rest Distance</strong> The rest distance determines the particle density for fluids. This parameter is a fraction of the particle radius, e.g.: if the particle radius is 15, and the fluid Rest Distance is 0.5 then the density constraint will attempt to keep particles approximately 7.5 units away from each other. Note that the rest-distance has a large impact on the behavior and performance cost of the fluid. Small rest-distances generate a “smoother” fluid because particles are closer together but the smoothing happens over more neighbors making simulation more expensive. Large rest-distances (near 0.75-1.0) make fluids less smooth but mean that less neighbors are considered, making the simulation cheaper. Generally the rest distance should not be < 0.5, a rest distance of 1.0 would mean that particles behave more like hard-spheres again as there is no smoothing.</li>
<li><strong>Cohesion</strong> Cohesion is an attractive force between particles. It is responsible for much of the behavior we assign to fluids. Low cohesion values will mean particles separate freely and do not “gel” together. Cohesion acts similarly to surface tension but tends to generate longer filaments of fluid rather than rounded droplets.</li>
<li><strong>Surface Tension</strong> Surface tension is the tendency for liquids to try and minimize their surface area. This is what gives rise to spherical droplets and the “pinching off” of a stream of water as it separates. Surface tension is quite expensive to calculate so it should not be enabled unless the situation warrants it. Also, surface tension is mostly visible at smaller scales, e.g.: individual droplets, water from a tap. Not for large streams of water.</li>
<li><strong>Viscosity</strong> Viscosity attempts to average the velocity field of the fluid. This can generate fluids that seem to “move together”. It is a similar to, but weaker than, cohesion. Viscosity also helps stabilize the simulation so it should almost always bet set > 0.0.</li>
<li><strong>Vorticity Confinement</strong> Particle based fluid simulations tend to damp their velocity quite quickly. Vorticity confinement is one method for addressing this by re-injecting some rotational motion into the fluid. It is mostly useful for bodies of water, not so much for splashes. It also has some associated performance overhead so should be used sparingly.</li>
</ul>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="col-md-1"></div>
</div>
<div class="masthead">
<div class="row">
<ul class="breadcrumb">
<li><a href="index.html">Flex Artist Tools 1.0 documentation</a></li>
</ul>
</div>
</div>
<footer>
<div class="footer-boilerplate">
<div class="row">
<div class="boilerplate">
Copyright © 2014-2016, NVIDIA Corporation | <a href="http://www.nvidia.com/object/about-nvidia.html" onclick="s_objectID="http://www.nvidia.com/object/about-nvidia.html_1";return this.s_oc?this.s_oc(e):true">About NVIDIA </a> | <a href="http://www.nvidia.com/object/legal_info.html" onclick="s_objectID="http://www.nvidia.com/object/legal_info.html_1";return this.s_oc?this.s_oc(e):true">Legal Information </a> | <a href="http://www.nvidia.com/object/privacy_policy.html" onclick="s_objectID="http://www.nvidia.com/object/privacy_policy.html_1";return this.s_oc?this.s_oc(e):true">Privacy Policy </a>
</div>
</div>
</div>
</div>
</footer>
<script>
var treestatename = 'GWDocsTreeState';
var protocol = location.href.split('/')[0].toLowerCase();
var storage;
if (protocol.substring(0,4) == 'http') {
storage = $.cookieStorage;
storage.setPath('/');
} else {
storage = $.localStorage;
}
if (storage.isEmpty(treestatename)) {
storage.set(treestatename, {});
}
var treestate = storage.get(treestatename);
$.each($("#sidebar_toc ul li"), toc_walker);
function toc_walker(key, value) {
var handleSpan = $("<span></span>")
.addClass("toc_handle").prependTo(value);
handleSpan.attr("id", $(value).closest("div").attr("id") + "." + key);
if($(value).has("ul li").size() > 0) {
var id = handleSpan.attr("id");
if (!(id in treestate)) {
treestate[id] = false;
}
handleSpan.addClass("toc_expanded").click(function() {
$(this).toggleClass("toc_expanded toc_collapsed").siblings("ul").toggle();
treestate[$(this).attr('id')] = $(this).hasClass('toc_expanded');
storage.set(treestatename, treestate);
});
if(!($(this).hasClass('current') || treestate[id])) {
handleSpan.click();
}
if($(this).hasClass('current')) {
treestate[handleSpan.attr('id')] = handleSpan.hasClass('toc_expanded');
storage.set(treestatename, treestate);
}
}
}
</script>
</body>
</html>