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: 27868 $
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,const ParticleModel::Description &)95 ParticleModel::GetDeviceMemorySizeInternal(
96 os::MemorySizeCalculator* pSize,
97 ResParticleModel resNode,
98 const ParticleModel::Description&)
99 {
100 os::MemorySizeCalculator& size = *pSize;
101
102 int setCount = resNode.GetParticleSetsCount();
103 NW_ASSERT(setCount == resNode.GetShapesCount());
104 for (int i = 0; i < setCount; ++i)
105 {
106 nw::gfx::ResParticleSet resParticleSet = resNode.GetParticleSets(i);
107
108 nw::gfx::ResParticleShape resParticleShape =
109 ResDynamicCast<ResParticleShape>(resNode.GetShapes(i));
110 NW_ASSERT(resParticleShape.IsValid());
111
112 ParticleShape::GetDeviceMemorySizeInternal(
113 pSize, resParticleSet.GetParticleCollection().GetCapacity());
114
115 ParticleSet::GetDeviceMemorySizeInternal(pSize, resParticleSet);
116 }
117 }
118
119 //----------------------------------------
120 ParticleModel*
Create(SceneNode * parent,ResSceneObject resource,const ParticleModel::Description & modelDescription,os::IAllocator * mainAllocator,os::IAllocator * deviceAllocator)121 ParticleModel::Create(
122 SceneNode* parent,
123 ResSceneObject resource,
124 const ParticleModel::Description& modelDescription,
125 os::IAllocator* mainAllocator,
126 os::IAllocator* deviceAllocator
127 )
128 {
129 NW_NULL_ASSERT(mainAllocator);
130 NW_NULL_ASSERT(deviceAllocator);
131
132 ResParticleModel resNode = ResDynamicCast<ResParticleModel>(resource);
133 NW_ASSERT(resNode.IsValid());
134
135 void* memory = mainAllocator->Alloc(sizeof(ParticleModel));
136 if (memory == NULL)
137 {
138 return NULL;
139 }
140
141 ParticleModel* node = new(memory) ParticleModel(
142 mainAllocator,
143 resNode,
144 modelDescription);
145
146 {
147 Result result = node->Initialize(mainAllocator);
148 if (!result.IsSuccess())
149 {
150 SafeDestroy(node);
151 return NULL;
152 }
153 }
154
155 bool isSuccess = true;
156
157 int setCount = resNode.GetParticleSetsCount();
158 NW_ASSERT(setCount == resNode.GetShapesCount());
159 for (int i = 0; i < setCount; ++i)
160 {
161 nw::gfx::ResParticleSet resParticleSet = resNode.GetParticleSets(i);
162
163 nw::gfx::ResParticleShape resParticleShape =
164 ResDynamicCast<ResParticleShape>(resNode.GetShapes(i));
165 NW_ASSERT(resParticleShape.IsValid());
166
167 ParticleShape* shapeNode = ParticleShape::Create(
168 resParticleShape,
169 resParticleSet.GetParticleCollection().GetCapacity(),
170 mainAllocator,
171 deviceAllocator);
172
173 if (shapeNode == NULL)
174 {
175 isSuccess = false;
176 break;
177 }
178
179 node->AttachParticleShape(shapeNode);
180
181 ParticleSet::Description description;
182 description.maxCallbacks = 0;
183 description.maxChildren = 0;
184 description.isFixedSizeMemory = true;
185
186 ParticleSet* setNode = ParticleSet::Create(
187 node,
188 resParticleSet,
189 description,
190 mainAllocator,
191 deviceAllocator,
192 shapeNode);
193
194 if (setNode == NULL)
195 {
196 isSuccess = false;
197 break;
198 }
199
200 node->AttachParticleSet(setNode);
201 }
202
203 if (isSuccess == false)
204 {
205 for (int i = 0; i < node->m_MaximumParticleSet; ++i) // TBD
206 {
207 if (node->m_ParticleSets[i] != NULL)
208 {
209 SafeDestroy(node->m_ParticleSets[i]);
210 node->m_ParticleSets[i] = NULL;
211 }
212 }
213
214 SafeDestroy(node);
215 return NULL;
216 }
217
218 if (parent)
219 {
220 bool result = parent->AttachChild(node);
221 NW_ASSERT(result);
222 }
223
224 return node;
225 }
226
227 //----------------------------------------
228 void
Accept(ISceneVisitor * visitor)229 ParticleModel::Accept(
230 ISceneVisitor* visitor
231 )
232 {
233 visitor->VisitParticleModel(this);
234 AcceptChildren(visitor);
235 }
236
237 void
GetMemorySizeForInitialize(os::MemorySizeCalculator * pSize,ResParticleModel resource,const ParticleModel::Description & description)238 ParticleModel::GetMemorySizeForInitialize(
239 os::MemorySizeCalculator* pSize,
240 ResParticleModel resource,
241 const ParticleModel::Description& description)
242 {
243 os::MemorySizeCalculator& size = *pSize;
244
245 Model::GetMemorySizeForInitialize(pSize, resource, description);
246
247 size += sizeof(ParticleSet*) * description.particleSetCount;
248 size += sizeof(ParticleShape*) * description.particleSetCount;
249 }
250
251 //----------------------------------------
252 Result
Initialize(os::IAllocator * allocator)253 ParticleModel::Initialize(os::IAllocator* allocator)
254 {
255 Result result = INITIALIZE_RESULT_OK;
256
257 result |= Model::Initialize(allocator);
258 NW_ENSURE_AND_RETURN(result);
259
260 if (m_MaximumParticleSet != 0)
261 {
262 void* memory = allocator->Alloc(sizeof(ParticleSet*) * m_MaximumParticleSet);
263 if (!memory)
264 {
265 result |= Result::MASK_FAIL_BIT;
266 }
267 NW_ENSURE_AND_RETURN(result);
268
269 m_ParticleSets = ut::MoveArray<ParticleSet*>(memory, m_MaximumParticleSet, allocator);
270 m_ParticleSets.Resize(m_MaximumParticleSet);
271 for (int i = 0; i < m_ParticleSets.size(); ++i)
272 {
273 m_ParticleSets[i] = NULL;
274 }
275 }
276
277 if (m_MaximumParticleSet != 0)
278 {
279 void* memory = allocator->Alloc(sizeof(ParticleShape*) * m_MaximumParticleSet);
280 if (!memory)
281 {
282 result |= Result::MASK_FAIL_BIT;
283 }
284 NW_ENSURE_AND_RETURN(result);
285
286 m_ParticleShapes = ut::MoveArray<ParticleShape*>(memory, m_MaximumParticleSet, allocator);
287 m_ParticleShapes.Resize(m_MaximumParticleSet);
288 for (int i = 0; i < m_ParticleShapes.size(); ++i)
289 {
290 m_ParticleShapes[i] = NULL;
291 }
292 }
293
294 return result;
295
296 }
297
298 } // namespace gfx
299 } // namespace nw
300