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