1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_ParticleModel.cpp
4
5 Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain proprietary
8 information of Nintendo and/or its licensed developers and are protected by
9 national and international copyright laws. They may not be disclosed to third
10 parties or copied or duplicated in any form, in whole or in part, without the
11 prior written consent of Nintendo.
12
13 The content herein is highly confidential and should be handled accordingly.
14
15 $Revision: 31829 $
16 *---------------------------------------------------------------------------*/
17
18 #include "precompiled.h"
19
20 #include <nw/gfx/gfx_ParticleModel.h>
21 #include <nw/gfx/gfx_ParticleSet.h>
22 #include <nw/gfx/gfx_ParticleShape.h>
23 #include <nw/gfx/gfx_ISceneVisitor.h>
24
25 #include <nw/ut/ut_ResUtil.h>
26 #include <nw/ut/ut_ResDictionary.h>
27 #include <nw/ut/ut_Foreach.h>
28
29 namespace nw
30 {
31 namespace gfx
32 {
33
34 NW_UT_RUNTIME_TYPEINFO_DEFINITION( ParticleModel, Model );
35
36 //----------------------------------------
37 void
operator ()(const ParticleSet * particleSet)38 ParticleSetsAreEmpty::operator()(const ParticleSet* particleSet)
39 {
40 if (particleSet->GetParticleCollection()->GetCount() > 0)
41 {
42 *this->m_Result = false;
43 }
44 }
45
46 //----------------------------------------
47 void
operator ()(ParticleSet * particleSet)48 ParticleSetsResetDebugHint::operator()(ParticleSet* particleSet)
49 {
50 particleSet->ResetDebugHint();
51 }
52
53 //----------------------------------------
54 void
operator ()(ParticleSet * particleSet)55 ParticleSetsClear::operator()(ParticleSet* particleSet)
56 {
57 particleSet->ClearParticleCollection();
58 }
59
60 //----------------------------------------
61 void
GetMemorySizeInternal(os::MemorySizeCalculator * pSize,ResParticleModel resNode,const ParticleModel::Description & description)62 ParticleModel::GetMemorySizeInternal(
63 os::MemorySizeCalculator* pSize,
64 ResParticleModel resNode,
65 const ParticleModel::Description& description)
66 {
67 os::MemorySizeCalculator& size = *pSize;
68
69 size += sizeof(ParticleModel);
70
71 ParticleModel::GetMemorySizeForInitialize(
72 &size,
73 resNode,
74 description);
75
76 int setCount = resNode.GetParticleSetsCount();
77 NW_ASSERT(setCount == resNode.GetShapesCount());
78 for (int i = 0; i < setCount; ++i)
79 {
80 nw::gfx::ResParticleSet resParticleSet = resNode.GetParticleSets(i);
81
82 nw::gfx::ResParticleShape resParticleShape =
83 ResDynamicCast<ResParticleShape>(resNode.GetShapes(i));
84 NW_ASSERT(resParticleShape.IsValid());
85
86 ParticleShape::GetMemorySizeInternal(
87 &size,
88 resParticleSet.GetParticleCollection().GetCapacity());
89
90 ParticleSet::Description particleSetDescription;
91 particleSetDescription.maxCallbacks = 0;
92 particleSetDescription.maxChildren = 0;
93 particleSetDescription.isFixedSizeMemory = true;
94
95 ParticleSet::GetMemorySizeInternal(
96 &size,
97 resParticleSet,
98 particleSetDescription);
99 }
100 }
101
102 //----------------------------------------
103 void
GetDeviceMemorySizeInternal(os::MemorySizeCalculator * pSize,ResParticleModel resNode,const ParticleModel::Description &)104 ParticleModel::GetDeviceMemorySizeInternal(
105 os::MemorySizeCalculator* pSize,
106 ResParticleModel resNode,
107 const ParticleModel::Description&)
108 {
109 os::MemorySizeCalculator& size = *pSize;
110
111 int setCount = resNode.GetParticleSetsCount();
112 NW_ASSERT(setCount == resNode.GetShapesCount());
113 for (int i = 0; i < setCount; ++i)
114 {
115 nw::gfx::ResParticleSet resParticleSet = resNode.GetParticleSets(i);
116
117 nw::gfx::ResParticleShape resParticleShape =
118 ResDynamicCast<ResParticleShape>(resNode.GetShapes(i));
119 NW_ASSERT(resParticleShape.IsValid());
120
121 ParticleShape::GetDeviceMemorySizeInternal(
122 pSize, resParticleSet.GetParticleCollection().GetCapacity());
123
124 ParticleSet::GetDeviceMemorySizeInternal(pSize, resParticleSet);
125 }
126 }
127
128 //----------------------------------------
129 ParticleModel*
Create(SceneNode * parent,ResSceneObject resource,const ParticleModel::Description & modelDescription,os::IAllocator * mainAllocator,os::IAllocator * deviceAllocator)130 ParticleModel::Create(
131 SceneNode* parent,
132 ResSceneObject resource,
133 const ParticleModel::Description& modelDescription,
134 os::IAllocator* mainAllocator,
135 os::IAllocator* deviceAllocator
136 )
137 {
138 NW_NULL_ASSERT(mainAllocator);
139 NW_NULL_ASSERT(deviceAllocator);
140
141 ResParticleModel resNode = ResDynamicCast<ResParticleModel>(resource);
142 NW_ASSERT(resNode.IsValid());
143
144 void* memory = mainAllocator->Alloc(sizeof(ParticleModel));
145 if (memory == NULL)
146 {
147 return NULL;
148 }
149
150 ParticleModel* node = new(memory) ParticleModel(
151 mainAllocator,
152 resNode,
153 modelDescription);
154
155 {
156 Result result = node->Initialize(mainAllocator);
157 if (!result.IsSuccess())
158 {
159 SafeDestroy(node);
160 return NULL;
161 }
162 }
163
164 bool isSuccess = true;
165
166 int setCount = resNode.GetParticleSetsCount();
167 NW_ASSERT(setCount == resNode.GetShapesCount());
168 for (int i = 0; i < setCount; ++i)
169 {
170 nw::gfx::ResParticleSet resParticleSet = resNode.GetParticleSets(i);
171
172 nw::gfx::ResParticleShape resParticleShape =
173 ResDynamicCast<ResParticleShape>(resNode.GetShapes(i));
174 NW_ASSERT(resParticleShape.IsValid());
175
176 ParticleShape* shapeNode = ParticleShape::Create(
177 resParticleShape,
178 resParticleSet.GetParticleCollection().GetCapacity(),
179 mainAllocator,
180 deviceAllocator);
181
182 if (shapeNode == NULL)
183 {
184 isSuccess = false;
185 break;
186 }
187
188 node->AttachParticleShape(shapeNode);
189
190 ParticleSet::Description description;
191 description.maxCallbacks = 0;
192 description.maxChildren = 0;
193 description.isFixedSizeMemory = true;
194
195 ParticleSet* setNode = ParticleSet::Create(
196 node,
197 resParticleSet,
198 description,
199 mainAllocator,
200 deviceAllocator,
201 shapeNode);
202
203 if (setNode == NULL)
204 {
205 isSuccess = false;
206 break;
207 }
208
209 node->AttachParticleSet(setNode);
210 }
211
212 if (isSuccess == false)
213 {
214 for (int i = 0; i < node->m_MaximumParticleSet; ++i) // TBD
215 {
216 if (node->m_ParticleSets[i] != NULL)
217 {
218 SafeDestroy(node->m_ParticleSets[i]);
219 node->m_ParticleSets[i] = NULL;
220 }
221 }
222
223 SafeDestroy(node);
224 return NULL;
225 }
226
227 if (parent)
228 {
229 bool result = parent->AttachChild(node);
230 NW_ASSERT(result);
231 }
232
233 return node;
234 }
235
236 //----------------------------------------
237 void
Accept(ISceneVisitor * visitor)238 ParticleModel::Accept(
239 ISceneVisitor* visitor
240 )
241 {
242 visitor->VisitParticleModel(this);
243 AcceptChildren(visitor);
244 }
245
246 void
GetMemorySizeForInitialize(os::MemorySizeCalculator * pSize,ResParticleModel resource,const ParticleModel::Description & description)247 ParticleModel::GetMemorySizeForInitialize(
248 os::MemorySizeCalculator* pSize,
249 ResParticleModel resource,
250 const ParticleModel::Description& description)
251 {
252 os::MemorySizeCalculator& size = *pSize;
253
254 Model::GetMemorySizeForInitialize(pSize, resource, description);
255
256 size += sizeof(ParticleSet*) * description.particleSetCount;
257 size += sizeof(ParticleShape*) * description.particleSetCount;
258 }
259
260 //----------------------------------------
261 Result
Initialize(os::IAllocator * allocator)262 ParticleModel::Initialize(os::IAllocator* allocator)
263 {
264 Result result = INITIALIZE_RESULT_OK;
265
266 result |= Model::Initialize(allocator);
267 NW_ENSURE_AND_RETURN(result);
268
269 if (m_MaximumParticleSet != 0)
270 {
271 void* memory = allocator->Alloc(sizeof(ParticleSet*) * m_MaximumParticleSet);
272 if (!memory)
273 {
274 result |= Result::MASK_FAIL_BIT;
275 }
276 NW_ENSURE_AND_RETURN(result);
277
278 m_ParticleSets = ut::MoveArray<ParticleSet*>(memory, m_MaximumParticleSet, allocator);
279 m_ParticleSets.Resize(m_MaximumParticleSet);
280 for (int i = 0; i < m_ParticleSets.size(); ++i)
281 {
282 m_ParticleSets[i] = NULL;
283 }
284 }
285
286 if (m_MaximumParticleSet != 0)
287 {
288 void* memory = allocator->Alloc(sizeof(ParticleShape*) * m_MaximumParticleSet);
289 if (!memory)
290 {
291 result |= Result::MASK_FAIL_BIT;
292 }
293 NW_ENSURE_AND_RETURN(result);
294
295 m_ParticleShapes = ut::MoveArray<ParticleShape*>(memory, m_MaximumParticleSet, allocator);
296 m_ParticleShapes.Resize(m_MaximumParticleSet);
297 for (int i = 0; i < m_ParticleShapes.size(); ++i)
298 {
299 m_ParticleShapes[i] = NULL;
300 }
301 }
302
303 return result;
304
305 }
306
307 } // namespace gfx
308 } // namespace nw
309