1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2<html xml:lang="en-US" lang="en-US">
3  <head>
4    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5    <meta http-equiv="Content-Style-Type" content="text/css" />
6    <link rel="stylesheet" href="../../../css/document.css" type="text/css" />
7    <title>Precautions</title>
8  </head>
9  <body>
10    <h1>Precautions</h1>
11    <p>This page describes the various precautions to keep in mind when using particles.</p>
12    <h2>Precautions when Calling <CODE>ParticleSet::UpdateParticle</CODE> Multiple Times</h2>
13    <p><CODE>UpdateParticle</CODE> can be called multiple times within a single frame regardless of settings when there is only a single command buffer, but special settings are necessary when command buffers are doubled, because the implementation makes alternate use of the rendering buffers (doubled) maintained withing the particle set. The UpdateParticle function can be called multiple times within a single frame without settings.<BR></p>
14    <pre>
15    Ex: Calling UpdateParticle multiple times within a single frame when command buffers are doubled
16    CPU: UpdateParticle(DrawBuff0) -&gt; UpdateParticle(DrawBuff1)
17    GPU: Draw(DrawBuff1)
18    On the second call to UpdateParticle(DrawBuff1),
19    UpdateParticle overwrites DrawBuff0 as the GPU is processes it.</pre>
20    <p>Use one of the following approaches to allow calling UpdateParticle multiple times in a single frame.  </p>
21    <ul>
22    <li>Adjust on the particle step frame and call just once.
23 
24    <li>Make special settings to allow multiple updates and then perform the following.
25</ul>
26    <p>Adjusting the step frame is one method where the playback rate can be increased by gathering updates together and forming one big update. Although this is useful in terms of execution speed, the results differ slightly from per frame processing. </p>
27    <p>Making multiple updates using a single, internal buffer is another method. Although this requires a looping CPU process, results match the per frame processing.</p>
28    <p>For details, see <a href="../demo/ParticleDropFrameDemo.html">ParticleDropFrameDemo</a>.</p>
29<h2>Delete Shader Resources During Binary Output</h2>
30    <p>During ordinary binary output with no arguments specified, the binary includes shader resources. Delete shader resources from the binary output to reduce the particle binary file size by up to 70%. However, when loading binaries without shader resources, you must attach the shader resources to load separately. See <a href="../Particle/GenerateDestruction.html#resgraphics"><CODE>ResGraphicsFile</CODE> Operations</a> for details.</p>
31
32    <h2>Deleting Unnecessary Animation Members</h2>
33    <p>Delete any unnecessary animation members to reduce the binary file size by up to 15%. Deleting these from the binary files should be quite effective for particle data that does not use material animations. See <I>Optimization Tips</I> for details.
34    </p>
35    <pre>
36    Sample XML with all animation members deleted:
37
38    &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
39    &lt;OptimizeAnimationMemberSettings&gt;
40      &lt;Filters Mode=&quot;positive&quot;&gt;
41      &lt;/Filters&gt;
42    &lt;/OptimizeAnimationMemberSettings&gt;</pre>
43    <h2>Precautions when Using Doubled Command Buffers</h2>
44    <p>When command buffers are doubled, the implementation makes alternate use of the rendering buffers (doubled) within the particles, so you cannot update or change the rendering order.</p>
45    <pre>
46    Ex: Rendering after updating
47    0th frame:
48    CPU: UpdateParticle(DrawBuff0) → Draw(DrawBuff0)
49    GPU:  -
50    1st frame:
51    CPU: UpdateParticle(DrawBuff1) → Draw(DrawBuff1)
52    GPU: Draw(DrawBuff0)
53    2nd frame:
54    CPU: UpdateParticle(DrawBuff0) → Draw(DrawBuff0)
55    GPU: Draw(DrawBuff1)
56    Ex: Updating after rendering
57    0th frame:
58    CPU: Draw(DrawBuff0) → UpdateParticle(DrawBuff1)
59    GPU:  -
60    1st frame:
61    CPU: Draw(DrawBuff1) → UpdateParticle(DrawBuff0)
62    GPU: Draw(DrawBuff0)
63    <CODE>UpdateParticle</CODE> overwrites <CODE>DrawBuff0</CODE> as the GPU is processing it.</pre>
64    <h2>Precautions when Deleting Instances</h2>
65    <p>Deleting an instance at the wrong time can cause the destruction of a particle's rendering buffer as it is in use by the GPU, possibly causing the GPU to hang.</p>
66    <pre>
67    Ex: When there are only single command buffers
68    CPU: UpdateParticle(DrawBuff0) → Draw(DrawBuff0)
69    GPU:                                   → Draw(DrawBuff0)
70    It is dangerous to delete an instance after CPU rendering.
71    To delete after CPU rendering, wait until the GPU is done processing.
72    Ex: When command buffers are doubled
73    CPU: UpdateParticle(DrawBuff0) → Draw(DrawBuff0)
74    GPU: Draw(DrawBuff1)
75    Because the render buffer from the previous frame is used by the GPU,
76    you account for this fact when deleting instances. (Such as by halting the render and deleting one frame later)</pre>
77    <h2>Precautions Regarding Random Numbers</h2>
78    <p>The <CODE>ParticleContext</CODE>, <CODE>ParticleEmitter</CODE>, and <CODE>ParticleSet</CODE> classes all have objects of the <CODE>ParticleRandom</CODE> class. You must configure an appropriate seed for each of these <CODE>ParticleRandom</CODE> objects. Use the <CODE>ParticleUtil::SetupParticleObject</CODE> function to properly configure the random number seed. Not using this function will result in the animation using the same fixed particle emission pattern each time, so you must properly configure the random number seed on the user side for the <CODE>ParticleEmitter</CODE> and <CODE>ParticleSet</CODE> objects.</p>
79    <h2><a name="reuse" id="reuse"></a>About Reusing Instances</h2>
80    <p>Particle creation and destruction are very expensive processes. Every time the effect occurs, an instance (node) is generated and then destroyed again after playback, causing considerable CPU processing load. Nintendo recommends deleting unnecessary instances beforehand and reusing instances where possible.
81    </p>
82<pre>
83Ex: How to reuse an instance
84Generates nodes.
85nw::gfx::ParticleModel*   particleModel   = nw::gfx::SceneBuilder();
86nw::gfx::ParticleEmitter* particleEmitter = nw::gfx::SceneBuilder();
87// Attach node to scene.
88sceneRoot-&gt;AttachChild(particleModel);
89sceneRoot-&gt;AttachChild(particleEmitter);
90   :
91// Detach from scene once scene is done playing.
92sceneRoot-&gt;DetachChild(particleModel);
93sceneRoot-&gt;DetachChild(particleEmitter);
94   :
95// A reset process for ParticleModel and ParticleEmitter classes if re-used.
96// These are then re-attached to the scene.
97particleEmitter-&gt;Reset();
98particleModel-&gt;ForeachParticleSet(nw::gfx::ParticleSetsClear());
99particleModel-&gt;ParticleAnimFrameController().SetFrame(0.f);
100sceneRoot-&gt;AttachChild(particleModel);
101sceneRoot-&gt;AttachChild(particleEmitter);
102</pre>
103    <p>When using doubled command buffers, take care when calling <CODE>nw::gfx::ParticleSetsClear</CODE>, as this can wind up clearing the buffer referenced by the GPU.</p>
104    <h2>Precautions When Using ParticleSet::ClearParticleCollection</h2>
105    <p>If doubling the command buffer, the buffer being accessed by the GPU may be cleared if ClearParticleCollection is called.</p>
106
107    <p>nw::gfx::ParticleSetClear calls ClearParticleSetCollection internally.</p>
108    <p>These functions are for initialization when re-using a ParticleSet currently not being used. They cannot be used during rendering.<BR>
109    <p>If the ParticleSet currently in use is cleared, use ParticleCollection::KillParticles instead.
110    <h2>About Instances that Are Done Playing</h2>
111    Nintendo recommends immediately detaching nodes once they are done playing to reduce the processing load. Use code like the following to check if a node is done playing.
112<pre>
113Ex: Code sample for checking if a node is done playing
114bool IsDone()
115{
116    nw::gfx::ParticleModel*   particleModel;
117    nw::gfx::ParticleEmitter* particleEmitter;
118    // Are any particles playing?
119    if  (particleModel-&gt;HasParticle())
120    {
121        return false;
122    }
123    // Is emitter done?
124    if (particleEmitter-&gt;IsAlive())
125    {
126        return false;
127    }
128    return true;
129}
130</pre>
131  </div>
132  <hr><p>CONFIDENTIAL</p></body>
133</html>
134