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