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