1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_SceneBuilder.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: 13148 $
14 *---------------------------------------------------------------------------*/
15
16 #include "precompiled.h"
17
18 #include <nw/gfx/gfx_SceneBuilder.h>
19
20 #include <nw/gfx/gfx_SceneNode.h>
21 #include <nw/gfx/gfx_TransformNode.h>
22 #include <nw/gfx/gfx_Model.h>
23 #include <nw/gfx/gfx_SkeletalModel.h>
24 #include <nw/gfx/gfx_ParticleModel.h>
25 #include <nw/gfx/gfx_ParticleEmitter.h>
26 #include <nw/gfx/gfx_ParticleSet.h>
27 #include <nw/gfx/gfx_FragmentLight.h>
28 #include <nw/gfx/gfx_VertexLight.h>
29 #include <nw/gfx/gfx_AmbientLight.h>
30 #include <nw/gfx/gfx_HemiSphereLight.h>
31 #include <nw/gfx/gfx_Fog.h>
32 #include <nw/gfx/gfx_Camera.h>
33
34 #include <nw/ut/ut_ResUtil.h>
35 #include <nw/ut/ut_ResDictionary.h>
36
37 namespace nw {
38 namespace gfx {
39
40 //----------------------------------------
41 SceneObject*
CreateObject(os::IAllocator * allocator,os::IAllocator * deviceAllocator)42 SceneBuilder::CreateObject(
43 os::IAllocator* allocator,
44 os::IAllocator* deviceAllocator
45 )
46 {
47 NW_NULL_ASSERT(allocator);
48 NW_ASSERT(m_Resource.IsValid());
49
50 // 子階層はたどらずに、このリソースのみを生成します。
51 SceneObject* root = BuildSceneObject(0, m_Resource, allocator, deviceAllocator, false);
52
53 return root;
54 }
55
56 //----------------------------------------
57 SceneObject*
CreateTree(os::IAllocator * allocator,os::IAllocator * deviceAllocator)58 SceneBuilder::CreateTree(
59 os::IAllocator* allocator,
60 os::IAllocator* deviceAllocator
61 )
62 {
63 NW_NULL_ASSERT(allocator);
64 NW_ASSERT(m_Resource.IsValid());
65
66 // 子階層を辿って生成します。
67 SceneObject* root = BuildSceneObject(0, m_Resource, allocator, deviceAllocator, true);
68
69 return root;
70 }
71
72 //----------------------------------------
73 SceneObject*
BuildSceneObject(SceneNode * parent,ResSceneObject resource,os::IAllocator * allocator,os::IAllocator * deviceAllocator,bool isRecursive)74 SceneBuilder::BuildSceneObject(
75 SceneNode* parent,
76 ResSceneObject resource,
77 os::IAllocator* allocator,
78 os::IAllocator* deviceAllocator,
79 bool isRecursive
80 )
81 {
82 NW_NULL_ASSERT(allocator);
83 if (!resource.IsValid()) { return 0; }
84
85 SceneObject* object = 0;
86
87 switch (resource.GetTypeInfo())
88 {
89 case ResSceneNode::TYPE_INFO:
90 {
91 SceneNode::Description description;
92 description.isFixedSizeMemory = m_IsFixedSizeMemory;
93 description.maxCallbacks = m_MaxCallbacks;
94 description.maxChildren = m_MaxChildren;
95 description.maxAnimObjectsPerGroup = m_MaxAnimObjectsPerGroup;
96 description.isAnimationEnabled = m_IsAnimationEnabled;
97
98 SceneNode* node = SceneNode::Create(
99 parent, resource, description, allocator);
100 object = node;
101 }
102 break;
103
104 case ResTransformNode::TYPE_INFO:
105 {
106 TransformNode::Description description;
107 description.isFixedSizeMemory = m_IsFixedSizeMemory;
108 description.maxCallbacks = m_MaxCallbacks;
109 description.maxChildren = m_MaxChildren;
110 description.maxAnimObjectsPerGroup = m_MaxAnimObjectsPerGroup;
111 description.isAnimationEnabled = m_IsAnimationEnabled;
112
113 TransformNode* node = TransformNode::Create(
114 parent,
115 resource,
116 description,
117 allocator);
118 object = node;
119 }
120 break;
121
122 case ResModel::TYPE_INFO:
123 {
124 Model::Description description;
125 description.isFixedSizeMemory = m_IsFixedSizeMemory;
126 description.maxCallbacks = m_MaxCallbacks;
127 description.maxChildren = m_MaxChildren;
128 description.bufferOption = m_BufferOption;
129 description.sharedMaterialModel = m_SharedMaterialModel;
130 description.isAnimationEnabled = m_IsAnimationEnabled;
131
132 description.maxAnimObjectsPerGroup = m_MaxAnimObjectsPerGroup;
133
134 Model* node = Model::Create(
135 parent,
136 resource,
137 description,
138 allocator);
139 object = node;
140 }
141 break;
142
143 case ResSkeletalModel::TYPE_INFO:
144 {
145 SkeletalModel* node = SkeletalModel::Builder()
146 .IsFixedSizeMemory(m_IsFixedSizeMemory)
147 .MaxCallbacks(m_MaxCallbacks)
148 .MaxChildren(m_MaxChildren)
149 .BufferOption(m_BufferOption)
150 .SharedMaterialModel(m_SharedMaterialModel)
151 .MaxAnimObjectsPerGroup(m_MaxAnimObjectsPerGroup)
152 .IsAnimationEnabled(m_IsAnimationEnabled)
153 .Create(parent, resource, allocator);
154 object = node;
155 }
156 break;
157
158 case ResParticleModel::TYPE_INFO:
159 {
160 ResParticleModel resNode = ResDynamicCast<ResParticleModel>(resource);
161 NW_ASSERT(resNode.IsValid());
162
163 ParticleModel::Description description;
164 description.isFixedSizeMemory = m_IsFixedSizeMemory;
165 description.maxCallbacks = m_MaxCallbacks;
166 description.bufferOption = m_BufferOption;
167 description.sharedMaterialModel = m_SharedMaterialModel;
168 description.maxChildren = resNode.GetChildrenCount() +
169 resNode.GetParticleSetsCount() +
170 m_ParticleSetMarginCount;
171 description.particleSetCount = resNode.GetParticleSetsCount() +
172 m_ParticleSetMarginCount;
173 description.isAnimationEnabled = m_IsAnimationEnabled;
174
175 ParticleModel* node = ParticleModel::Create(
176 parent,
177 resource,
178 description,
179 allocator,
180 deviceAllocator);
181 object = node;
182 }
183 break;
184
185 case ResParticleEmitter::TYPE_INFO:
186 {
187 ParticleEmitter::Description description;
188 description.isFixedSizeMemory = m_IsFixedSizeMemory;
189 description.maxCallbacks = m_MaxCallbacks;
190 description.maxChildren = m_MaxChildren;
191 description.isAnimationEnabled = m_IsAnimationEnabled;
192
193 ParticleEmitter* node = ParticleEmitter::Create(
194 parent,
195 resource,
196 description,
197 allocator);
198 object = node;
199 }
200 break;
201
202 case ResFragmentLight::TYPE_INFO:
203 {
204 FragmentLight::Description description;
205 description.isFixedSizeMemory = m_IsFixedSizeMemory;
206 description.maxCallbacks = m_MaxCallbacks;
207 description.maxChildren = m_MaxChildren;
208 description.maxAnimObjectsPerGroup = m_MaxAnimObjectsPerGroup;
209 description.isAnimationEnabled = m_IsAnimationEnabled;
210
211 FragmentLight* node = FragmentLight::Create(
212 parent,
213 resource,
214 description,
215 allocator);
216 object = node;
217 }
218 break;
219
220 #if defined(NW_GFX_VERTEX_LIGHT_ENABLED)
221 case ResVertexLight::TYPE_INFO:
222 {
223 VertexLight::Description description;
224 description.isFixedSizeMemory = m_IsFixedSizeMemory;
225 description.maxCallbacks = m_MaxCallbacks;
226 description.maxChildren = m_MaxChildren;
227 description.maxAnimObjectsPerGroup = m_MaxAnimObjectsPerGroup;
228 description.isAnimationEnabled = m_IsAnimationEnabled;
229
230 VertexLight* node = VertexLight::Create(
231 parent,
232 resource,
233 description,
234 allocator);
235 object = node;
236 }
237 break;
238 #endif
239 case ResAmbientLight::TYPE_INFO:
240 {
241 AmbientLight::Description description;
242 description.isFixedSizeMemory = m_IsFixedSizeMemory;
243 description.maxCallbacks = m_MaxCallbacks;
244 description.maxChildren = m_MaxChildren;
245 description.maxAnimObjectsPerGroup = m_MaxAnimObjectsPerGroup;
246 description.isAnimationEnabled = m_IsAnimationEnabled;
247
248 AmbientLight* node = AmbientLight::Create(
249 parent,
250 resource,
251 description,
252 allocator);
253 object = node;
254 }
255 break;
256
257 case ResHemiSphereLight::TYPE_INFO:
258 {
259 HemiSphereLight::Description description;
260 description.isFixedSizeMemory = m_IsFixedSizeMemory;
261 description.maxCallbacks = m_MaxCallbacks;
262 description.maxChildren = m_MaxChildren;
263 description.maxAnimObjectsPerGroup = m_MaxAnimObjectsPerGroup;
264 description.isAnimationEnabled = m_IsAnimationEnabled;
265
266 HemiSphereLight* node = HemiSphereLight::Create(
267 parent,
268 resource,
269 description,
270 allocator);
271 object = node;
272 }
273 break;
274
275 case ResFog::TYPE_INFO:
276 {
277 Fog::Description description;
278 description.isFixedSizeMemory = m_IsFixedSizeMemory;
279 description.maxCallbacks = m_MaxCallbacks;
280 description.maxChildren = m_MaxChildren;
281 description.isAnimationEnabled = m_IsAnimationEnabled;
282
283 Fog* node = Fog::Create(
284 parent,
285 resource,
286 description,
287 allocator);
288 object = node;
289 }
290 break;
291
292 case ResCamera::TYPE_INFO:
293 {
294 Camera::Description description;
295 description.isFixedSizeMemory = m_IsFixedSizeMemory;
296 description.maxCallbacks = m_MaxCallbacks;
297 description.maxChildren = m_MaxChildren;
298 description.maxAnimObjectsPerGroup = m_MaxAnimObjectsPerGroup;
299 description.isAnimationEnabled = m_IsAnimationEnabled;
300
301 Camera* node = Camera::Create(
302 parent,
303 resource,
304 description,
305 allocator);
306 object = node;
307 }
308 break;
309
310 case ResSceneEnvironmentSetting::TYPE_INFO:
311 {
312 SceneEnvironmentSetting::Description description;
313
314 SceneEnvironmentSetting* node = SceneEnvironmentSetting::Create(
315 resource,
316 description,
317 allocator);
318 object = node;
319 }
320 break;
321
322 default: NW_FATAL_ERROR("Unknown resource type."); break;
323 }
324
325 SceneNode* sceneNode = ut::DynamicCast<SceneNode*>(object);
326
327 // 子階層を初期化するなら、子をたどる
328 if (sceneNode != NULL && isRecursive)
329 {
330 BuildChildren(sceneNode, resource, allocator, deviceAllocator);
331 }
332
333 return object;
334 }
335
336 //----------------------------------------
337 void
BuildChildren(SceneNode * parent,ResSceneObject resource,os::IAllocator * allocator,os::IAllocator * deviceAllocator)338 SceneBuilder::BuildChildren(
339 SceneNode* parent,
340 ResSceneObject resource,
341 os::IAllocator* allocator,
342 os::IAllocator* deviceAllocator
343 )
344 {
345 NW_NULL_ASSERT(allocator);
346
347 ResSceneNode resNode = ResSceneNode(resource.ptr());
348 if (!resource.IsValid()) { return; }
349
350 typedef nw::ut::ResArrayClass<ResSceneObject>::type ResSceneObjectArray;
351 for (ResSceneObjectArray::iterator i = resNode.GetChildren().begin();
352 i != resNode.GetChildren().end(); ++i)
353 {
354 // 子階層をたどるときは、デフォルトで再帰的に生成を行う
355 SceneObject* child = BuildSceneObject(parent, *i, allocator, deviceAllocator, true);
356 }
357 }
358
359
360 } // namespace gfx
361 } // namespace nw
362