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
12    <p>This page describes the various precautions to keep in mind when using particles.</p>
13
14
15    <h2>Precautions when Calling <CODE>ParticleSet::UpdateParticle</CODE> Multiple Times</h2>
16    <p>When there is only a single command buffer, it is possible to call <CODE>UpdateParticle</CODE> multiple times within a single frame. When command buffers are doubled, the implementation makes alternate use of the rendering buffers (doubled) within the particles, so it is not possible to <CODE>UpdateParticle</CODE> multiple times within a single frame.</p>
17    <pre>
18    Ex: Calling UpdateParticle multiple times within a single frame when command buffers are doubled
19    CPU: UpdateParticle(DrawBuff0) -&gt; UpdateParticle(DrawBuff1)
20    GPU: Draw(DrawBuff1)
21
22    In the second call, <CODE>UpdateParticle(DrawBuff1)</CODE>, overwrites <CODE>DrawBuff1</CODE> as its being processed by the GPU.
23    </pre>
24    <p>Use one of the following approaches to allow calling <CODE>UpdateParticle</CODE> multiple times in a single frame.</p>
25    <ul>
26   <li>Adjust on the particle step frame and call just once.
27   <li>Wait until the GPU is done processing to call <CODE>UpdateParticle</CODE> again.
28    </ul>
29
30
31    <h2>Delete Shader Resources During Binary Output</h2>
32    <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>
33
34
35    <h2>Delete Unnecessary Animation Members</h2>
36    <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.
37    </p>
38    <pre>
39    Sample XML with all animation members deleted:
40
41    &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
42    &lt;OptimizeAnimationMemberSettings&gt;
43      &lt;Filters Mode=&quot;positive&quot;&gt;
44      &lt;/Filters&gt;
45    &lt;/OptimizeAnimationMemberSettings&gt;</pre>
46
47
48    <h2>Precautions when Using Doubled Command Buffers</h2>
49    <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>
50    <pre>
51    Ex: Rendering after updating
52
53    0th frame:
54    CPU: UpdateParticle(DrawBuff0) → Draw(DrawBuff0)
55    GPU:  -
56
57    1st frame:
58    CPU: UpdateParticle(DrawBuff1) → Draw(DrawBuff1)
59    GPU: Draw(DrawBuff0)
60
61    2nd frame:
62    CPU: UpdateParticle(DrawBuff0) → Draw(DrawBuff0)
63    GPU: Draw(DrawBuff1)
64
65
66    Ex: Updating after rendering
67
68    0th frame:
69    CPU: Draw(DrawBuff0) → UpdateParticle(DrawBuff1)
70    GPU:  -
71
72    1st frame:
73    CPU: Draw(DrawBuff1) → UpdateParticle(DrawBuff0)
74    GPU: Draw(DrawBuff0)
75
76    <CODE>UpdateParticle</CODE> overwrites <CODE>DrawBuff0</CODE> as the GPU is processing it.</pre>
77
78
79    <h2>Precautions when Deleting Instances</h2>
80    <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>
81    <pre>
82    Ex: When there are only single command buffers
83    CPU: UpdateParticle(DrawBuff0) → Draw(DrawBuff0)
84    GPU:                                   → Draw(DrawBuff0)
85
86    It is dangerous to delete an instance after CPU rendering.
87    To delete after CPU rendering, wait until the GPU is done processing.
88
89
90    Ex: When command buffers are doubled
91    CPU: UpdateParticle(DrawBuff0) → Draw(DrawBuff0)
92    GPU: Draw(DrawBuff1)
93
94    The preceding frame's rendering buffer is used by the GPU. You must factor this in when deleting an instance.
95    (Such as by halting the render and deleting one frame later)</pre>
96
97
98    <h2>Precautions Regarding Random Numbers</h2>
99    <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>
100
101
102    <h2><a name="reuse" id="reuse"></a>About Reusing Instances</h2>
103
104    <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.
105    </p>
106
107<pre>
108Ex: How to reuse an instance
109
110Generates nodes.
111nw::gfx::ParticleModel*   particleModel   = nw::gfx::SceneBuilder();
112nw::gfx::ParticleEmitter* particleEmitter = nw::gfx::SceneBuilder();
113
114// Attach node to scene.
115sceneRoot-&gt;AttachChild(particleModel);
116sceneRoot-&gt;AttachChild(particleEmitter);
117
118   :
119
120// Detach from scene once scene is done playing.
121sceneRoot-&gt;DetachChild(particleModel);
122sceneRoot-&gt;DetachChild(particleEmitter);
123
124   :
125
126// When reusing, reset ParticleModel and ParticleEmitter objects, and reattach to the scene.
127//
128particleEmitter-&gt;Reset();
129particleModel-&gt;ForeachParticleSet(nw::gfx::ParticleSetsClear());
130particleModel-&gt;ParticleAnimFrameController().SetFrame(0.f);
131
132sceneRoot-&gt;AttachChild(particleModel);
133sceneRoot-&gt;AttachChild(particleEmitter);
134</pre>
135
136    <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>
137
138
139    <h2>About Instances that Are Done Playing</h2>
140    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.
141<pre>
142Ex: Code sample for checking if a node is done playing
143bool IsDone()
144{
145    nw::gfx::ParticleModel*   particleModel;
146    nw::gfx::ParticleEmitter* particleEmitter;
147
148    // Are any particles playing?
149    if  (particleModel-&gt;HasParticle())
150    {
151        return false;
152    }
153
154    // Is emitter done?
155    if (particleEmitter-&gt;IsAlive())
156    {
157        return false;
158    }
159
160    return true;
161}
162</pre>
163
164
165  </div>
166  <hr><p>CONFIDENTIAL</p></body>
167</html>