1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: MultiAnimationDemo.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: 19751 $
14 *---------------------------------------------------------------------------*/
15
16 #define NW_DEBUG_CHECK_MEMORY_LEAK
17
18 #include <nn/os.h>
19 #include <nn/fs.h>
20
21 #include <nw/types.h>
22
23 #include <nw/demo.h>
24 #include <nw/dev.h>
25 #include <nw/gfx.h>
26 #include <nw/ut.h>
27 #include <nw/anim.h>
28
29 namespace
30 {
31
32 //----------------------------------------
33 // メモリ関係
34
35 // デバイスメモリを確保するためのアロケータです。
36 nw::demo::DemoAllocator s_DeviceAllocator;
37
38 //----------------------------------------
39 // ファイル名の定義です。
40 const wchar_t* SKY_SPHERE_FILE_NAME = NW_DEMO_FILE_PATH(L"SkySphere.bcmdl");
41
42 const wchar_t* RESOURCE_FILES[] =
43 {
44 NW_DEMO_FILE_PATH(L"MultiAnimation.bcmdl"),
45 NW_DEMO_FILE_PATH(L"SceneEnvironmentSetting.bcenv"),
46 NW_DEMO_FILE_PATH(L"FragmentLight.bcenv"),
47 NW_DEMO_FILE_PATH(L"Walk.bcskla"),
48 NW_DEMO_FILE_PATH(L"MatAnim.bcmata"),
49 NW_DEMO_FILE_PATH(L"VisibilityAnim.bcmdla"),
50 NW_DEMO_FILE_PATH(L"CameraAnim.bccam"),
51 NW_DEMO_FILE_PATH(L"LightAnim.bclgt"),
52 NW_DEMO_FILE_PATH(L"LightAnim.bcenv"),
53 NW_DEMO_FILE_PATH(L"Pierrot.bcskla"),
54 NW_DEMO_FILE_PATH(L"Robot.bcskla")
55 };
56
57 const wchar_t* LUT_RESOURCE_FILE = NW_DEMO_FILE_PATH(L"LightAnim.bcres");
58
59 //----------------------------------------
60 // 描画関係
61 const int RENDER_TARGET_COUNT = 1;
62 typedef nw::ut::FixedSizeArray<nw::gfx::IRenderTarget*, RENDER_TARGET_COUNT> RenderTargetArray;
63
64 RenderTargetArray s_RenderTargets;
65 nw::demo::SceneSystem* s_SceneSystem = NULL;
66 nw::demo::RenderSystem* s_RenderSystem = NULL;
67
68 nw::demo::GraphicsDrawing s_GraphicsDrawing;
69
70 //----------------------------------------
71 // リソース関係
72 nw::demo::ResourceArray s_Resources;
73 nw::demo::ResourceSet* s_LutResource;
74
75 //----------------------------------------
76 // シーン関係
77 nw::gfx::SceneNode* s_SceneRoot = NULL;
78 s32 s_FrameCount = 0;
79 nw::gfx::Camera* s_BaseCamera = NULL;
80 nw::gfx::Camera* s_LeftCamera = NULL;
81 nw::gfx::Camera* s_RightCamera = NULL;
82 nw::gfx::Camera* s_AnimCamera = NULL;
83 nw::gfx::Camera* s_ActiveCamera = NULL;
84
85 const f32 s_fNearPlane = 0.1f;
86
87 nw::gfx::SceneNode* s_SceneRootInvisible = NULL;
88 nw::gfx::SceneNode* s_SkeletalRoot = NULL;
89 nw::gfx::SceneNode* s_MaterialRoot = NULL;
90 nw::gfx::SceneNode* s_VisibilityRoot = NULL;
91 nw::gfx::SceneNode* s_CameraRoot = NULL;
92 nw::gfx::SceneNode* s_LightRoot = NULL;
93
94 //----------------------------------------
95 // シーン環境関係
96 const s32 ENVIRONMENT_SETTINGS_COUNT = 2;
97
98 typedef nw::ut::FixedSizeArray<nw::gfx::SceneEnvironmentSetting*, ENVIRONMENT_SETTINGS_COUNT> SceneEnvironmentSettingArray;
99 SceneEnvironmentSettingArray s_SceneEnvironmentSettings;
100
101 const s32 s_BaseCameraIndex = 0;
102 const s32 s_AnimCameraIndex = 1;
103
104 //----------------------------------------
105 // アニメーション関係
106 const int MAX_ANIM_OBJECTS = 10;
107 nw::ut::FixedSizeArray<nw::gfx::AnimObject*, MAX_ANIM_OBJECTS> s_AnimObjects;
108 float s_AnimWeight0 = 0.5f;
109 float s_AnimWeight1 = 0.5f;
110
111 s32 s_ActiveCameraIndex = s_BaseCameraIndex;
112 const int ANIMATION_RESOURCES_COUNT =11;
113 const int ANIMATION_TARGETS_COUNT = 17;
114
115 nw::ut::FixedSizeArray<nw::gfx::ResGraphicsFile, ANIMATION_RESOURCES_COUNT> s_ResAnims;
116 nw::ut::FixedSizeArray<nw::gfx::SceneObject*, ANIMATION_TARGETS_COUNT> s_AnimTargets;
117
118 struct AnimBindingTable
119 {
120 const char* targetName;
121 const char* animName;
122 nw::demo::Utility::AnimationType animType;
123 };
124
125 const AnimBindingTable ANIM_BINDING_TABLE[] =
126 {
127 { "Male", "Walk", nw::demo::Utility::SKELETAL_ANIMATION },
128 { "Pierrot", "Pierrot", nw::demo::Utility::SKELETAL_ANIMATION },
129 { "Robot", "Robot", nw::demo::Utility::SKELETAL_ANIMATION },
130 { "MatAnim", "MatAnim", nw::demo::Utility::MATERIAL_ANIMATION },
131 { "VisibilityAnim", "VisibilityAnim", nw::demo::Utility::VISIBILITY_ANIMATION },
132 { "AnimCamera", "CameraAnim", nw::demo::Utility::CAMERA_ANIMATION },
133 { "pointLight1", "pointLight1", nw::demo::Utility::LIGHT_ANIMATION },
134 { "pointLight2", "pointLight2", nw::demo::Utility::LIGHT_ANIMATION },
135 { "pointLight3", "pointLight3", nw::demo::Utility::LIGHT_ANIMATION }
136 };
137
138 //----------------------------------------
139 // 操作関係
140 int s_AnimMode = 0;
141
142 /*!--------------------------------------------------------------------------*
143 @brief グラフィックス関連の初期化を行います。
144 *---------------------------------------------------------------------------*/
145 void
InitializeGraphics()146 InitializeGraphics()
147 {
148 nw::gfx::CommandCacheManager::SetAllocator( &s_DeviceAllocator );
149
150 // renderDescriptionへステレオの設定を行います。
151 nw::demo::RenderSystem::Description renderDescription;
152
153 renderDescription.reusableCommandBufferSize = 0x100000;
154 renderDescription.reusableCommandRequestCount = 512;
155 renderDescription.upperScreenMode = nw::demo::UPPER_SCREEN_MODE_STEREO;
156
157 s_RenderSystem = nw::demo::RenderSystem::Create(&s_DeviceAllocator, renderDescription);
158
159 s_GraphicsDrawing.SetScreenSize(
160 renderDescription.lowerScreenDescription.width,
161 renderDescription.lowerScreenDescription.height
162 );
163
164 nw::demo::Utility::InitializeGraphicsDrawing(&s_DeviceAllocator, s_GraphicsDrawing);
165
166 s_RenderTargets.push_back(
167 nw::demo::Utility::CreateUpperScreenBuffer(&s_DeviceAllocator, renderDescription)
168 );
169 NW_ASSERT(!s_RenderTargets.empty());
170 s_RenderSystem->GetRenderContext()->SetRenderTarget(s_RenderTargets.front());
171
172 // sceneDescriptionへの標準的な設定はコンストラクタで行われています。
173 nw::demo::SceneSystem::Description sceneDescription;
174 s_SceneSystem = nw::demo::SceneSystem::Create(&s_DeviceAllocator, sceneDescription);
175
176 // デモ用の最遠景モデルをレンダリングシステムに設定します。
177 // gfx のデモでは glClear などを用いずに背景で塗りつぶしを行います。
178 s_RenderSystem->LoadSkyModel(SKY_SPHERE_FILE_NAME);
179
180 NW_GL_ASSERT();
181 }
182
183 /*!--------------------------------------------------------------------------*
184 @brief グラフィックス関連の後始末をします。
185 *---------------------------------------------------------------------------*/
186 void
TerminateGraphics()187 TerminateGraphics()
188 {
189 nw::gfx::SafeDestroy(s_LeftCamera);
190
191 nw::gfx::SafeDestroy(s_RightCamera);
192
193 nw::gfx::SafeDestroy(s_SceneSystem);
194
195 nw::gfx::SafeDestroyAll(s_RenderTargets);
196
197 s_GraphicsDrawing.Finalize();
198
199 nw::gfx::SafeDestroy(s_RenderSystem);
200
201 NW_GL_ASSERT();
202 }
203
204 /*!--------------------------------------------------------------------------*
205 @brief アニメーションの後始末をします。
206 *---------------------------------------------------------------------------*/
207 void
TerminateAnim(void)208 TerminateAnim(void)
209 {
210 for (int animIdx = 0; animIdx < s_AnimObjects.Size(); ++animIdx)
211 {
212 nw::gfx::SafeDestroy(s_AnimObjects[animIdx]);
213 }
214 s_AnimObjects.clear();
215 }
216
217 /*!--------------------------------------------------------------------------*
218 @brief カメラを切り替えます。
219 *---------------------------------------------------------------------------*/
220 void
ChangeCamera(s32 cameraIndex)221 ChangeCamera(s32 cameraIndex)
222 {
223 s_RenderSystem->GetRenderContext()->SetActiveCamera(cameraIndex);
224
225 s_ActiveCamera = s_RenderSystem->GetRenderContext()->GetActiveCamera();
226 s_ActiveCameraIndex = cameraIndex;
227
228 nw::demo::Utility::SetCameraAspectRatio(s_ActiveCamera, s_RenderTargets[0]);
229 }
230
231 /*!--------------------------------------------------------------------------*
232 @brief ルートノード関連の構築をします。
233 *---------------------------------------------------------------------------*/
234 void
BuildRootNodes()235 BuildRootNodes()
236 {
237 NW_ASSERT(s_SceneRoot == NULL);
238 s_SceneRoot = nw::gfx::TransformNode::DynamicBuilder()
239 .IsFixedSizeMemory(false)
240 .Create(&s_DeviceAllocator);
241 NW_NULL_ASSERT(s_SceneRoot);
242
243 NW_ASSERT(s_SceneRootInvisible == NULL);
244 s_SceneRootInvisible = nw::gfx::TransformNode::DynamicBuilder()
245 .IsFixedSizeMemory(false)
246 .Create(&s_DeviceAllocator);
247
248 // 各アニメーション毎にルートノードを作成します。
249 NW_ASSERT(s_SkeletalRoot == NULL);
250 s_SkeletalRoot = nw::gfx::TransformNode::DynamicBuilder()
251 .IsFixedSizeMemory(false)
252 .Create(&s_DeviceAllocator);
253 s_SceneRootInvisible->AttachChild(s_SkeletalRoot);
254 NW_NULL_ASSERT(s_SkeletalRoot);
255
256 NW_ASSERT(s_MaterialRoot == NULL);
257 s_MaterialRoot = nw::gfx::TransformNode::DynamicBuilder()
258 .IsFixedSizeMemory(false)
259 .Create(&s_DeviceAllocator);
260 s_SceneRootInvisible->AttachChild(s_MaterialRoot);
261 NW_NULL_ASSERT(s_MaterialRoot);
262
263 NW_ASSERT(s_VisibilityRoot == NULL);
264 s_VisibilityRoot = nw::gfx::TransformNode::DynamicBuilder()
265 .IsFixedSizeMemory(false)
266 .Create(&s_DeviceAllocator);
267 s_SceneRootInvisible->AttachChild(s_VisibilityRoot);
268 NW_NULL_ASSERT(s_VisibilityRoot);
269
270 NW_ASSERT(s_CameraRoot == NULL);
271 s_CameraRoot = nw::gfx::TransformNode::DynamicBuilder()
272 .IsFixedSizeMemory(false)
273 .Create(&s_DeviceAllocator);
274 s_SceneRootInvisible->AttachChild(s_CameraRoot);
275 NW_NULL_ASSERT(s_CameraRoot);
276
277 NW_ASSERT(s_LightRoot == NULL);
278 s_LightRoot = nw::gfx::TransformNode::DynamicBuilder()
279 .IsFixedSizeMemory(false)
280 .Create(&s_DeviceAllocator);
281 s_SceneRootInvisible->AttachChild(s_LightRoot);
282 NW_NULL_ASSERT(s_LightRoot);
283 }
284
285 /*!--------------------------------------------------------------------------*
286 @brief カメラ関連の構築をします。
287 *---------------------------------------------------------------------------*/
288 void
BuildCameras()289 BuildCameras()
290 {
291 nw::demo::Utility::CreateStereoCameras(
292 &s_BaseCamera,
293 &s_LeftCamera,
294 &s_RightCamera,
295 &s_DeviceAllocator,
296 nw::math::VEC3(20.0f, 15.0f, 20.0f),
297 nw::math::VEC3(0.0f, 0.0f, 0.0f),
298 s_fNearPlane
299 );
300
301 s_SceneRoot->AttachChild(s_BaseCamera);
302 s_SceneSystem->GetCameraController()->Register(s_BaseCamera);
303 }
304
305 /*!--------------------------------------------------------------------------*
306 @brief リソース関連の構築をします。
307 *---------------------------------------------------------------------------*/
308 void
BuildResources(nw::demo::ResourceSet * resourceSet)309 BuildResources(nw::demo::ResourceSet* resourceSet)
310 {
311 resourceSet->resource.ForeachTexture(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP));
312 resourceSet->resource.ForeachIndexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
313 resourceSet->resource.ForeachVertexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
314
315 nw::gfx::Result result = resourceSet->resource.Setup(&s_DeviceAllocator);
316 if (result.GetDescription() & nw::gfx::RESOURCE_RESULT_NOT_FOUND_LUT)
317 {
318 result = resourceSet->resource.Setup(&s_DeviceAllocator, s_LutResource->resource);
319 }
320 if (result.IsFailure())
321 {
322 NW_FATAL_ERROR("Fail to set up model. A result code is 0x%x", result.GetCode());
323 }
324
325 nw::ut::MoveArray<nw::gfx::SceneNode*> sceneNodeArray(&s_DeviceAllocator);
326
327 nw::gfx::ResModelArray models = resourceSet->resource.GetModels();
328 nw::gfx::ResModelArray::iterator modelsEnd = models.end();
329 for (nw::gfx::ResModelArray::iterator modelResource = models.begin();
330 modelResource != modelsEnd; ++modelResource)
331 {
332 nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
333 &s_DeviceAllocator,
334 (*modelResource)
335 );
336 NW_NULL_ASSERT(node);
337 sceneNodeArray.push_back(node);
338
339 s_AnimTargets.push_back(node);
340 }
341
342 nw::gfx::ResLightArray lights = resourceSet->resource.GetLights();
343 nw::gfx::ResLightArray::iterator lightsEnd = lights.end();
344 for (nw::gfx::ResLightArray::iterator lightResource = lights.begin();
345 lightResource != lightsEnd; ++lightResource)
346 {
347 nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
348 &s_DeviceAllocator,
349 (*lightResource)
350 );
351 NW_NULL_ASSERT(node);
352 sceneNodeArray.push_back(node);
353
354 s_AnimTargets.push_back(node);
355 }
356
357 nw::gfx::ResCameraArray cameras = resourceSet->resource.GetCameras();
358 nw::gfx::ResCameraArray::iterator camerasEnd = cameras.end();
359 for (nw::gfx::ResCameraArray::iterator cameraResource = cameras.begin();
360 cameraResource != camerasEnd; ++cameraResource)
361 {
362 nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
363 &s_DeviceAllocator,
364 (*cameraResource)
365 );
366 NW_NULL_ASSERT(node);
367 sceneNodeArray.push_back(node);
368
369 s_AnimTargets.push_back(node);
370 }
371
372 // 親子付け参照関係を解決
373 nw::gfx::SceneHelper::ResolveReference(sceneNodeArray);
374
375 // モデルをシーンに追加
376 nw::gfx::SceneHelper::ForeachRootNodes(
377 sceneNodeArray.Begin(),
378 sceneNodeArray.End(),
379 nw::gfx::AttachNode(s_SceneRoot)
380 );
381
382 nw::gfx::ResSceneEnvironmentSettingArray settings = resourceSet->resource.GetSceneEnvironmentSettings();
383 nw::gfx::ResSceneEnvironmentSettingArray::iterator settingsEnd = settings.end();
384 for (nw::gfx::ResSceneEnvironmentSettingArray::iterator settingResource = settings.begin();
385 settingResource != settingsEnd; ++settingResource)
386 {
387 nw::gfx::SceneObject* sceneObject = nw::gfx::SceneBuilder()
388 .Resource(*settingResource)
389 .CreateObject(&s_DeviceAllocator, &s_DeviceAllocator);
390
391 nw::gfx::SceneEnvironmentSetting* sceneEnvironmentSetting =
392 nw::ut::DynamicCast<nw::gfx::SceneEnvironmentSetting*>(sceneObject);
393
394 NW_NULL_ASSERT(sceneEnvironmentSetting);
395 s_SceneEnvironmentSettings.push_back(sceneEnvironmentSetting);
396 }
397 }
398
399 /*!--------------------------------------------------------------------------*
400 @brief アニメーション関連の構築をします。
401 *---------------------------------------------------------------------------*/
402 void
BuildAnimations()403 BuildAnimations()
404 {
405 s_AnimCamera = NULL;
406
407 NW_FOREACH(AnimBindingTable animBindingTable, ANIM_BINDING_TABLE)
408 {
409 nw::anim::ResAnim resAnim;
410 resAnim = nw::demo::Utility::FindResAnimByName(
411 s_ResAnims,
412 animBindingTable.animName,
413 animBindingTable.animType);
414 NW_ASSERT(resAnim.IsValid());
415
416 nw::gfx::SceneObject* targetObject;
417 targetObject = nw::demo::Utility::FindObjectByName(
418 s_AnimTargets,
419 animBindingTable.targetName);
420 NW_NULL_ASSERT(targetObject);
421
422 // フルベイク形式のアニメーションリソースであれば、
423 // スケルタルモデルの設定を行ないます。
424 if (resAnim.IsFullBakedAnim())
425 {
426 nw::gfx::SkeletalModel* skeletalModel = nw::ut::DynamicCast<nw::gfx::SkeletalModel*>(targetObject);
427 NW_NULL_ASSERT(skeletalModel);
428
429 skeletalModel->SetFullBakedAnimEnabled(true);
430 }
431
432 // アニメーション評価を生成し、バインドします。
433 s_AnimObjects.PushBack(
434 nw::demo::Utility::BindAnimation(
435 &s_DeviceAllocator,
436 targetObject,
437 resAnim,
438 animBindingTable.animType,
439 false)
440 );
441
442 // カメラアニメーションの場合は、バインド対象のカメラを保持しておきます。
443 if (animBindingTable.animType == nw::demo::Utility::CAMERA_ANIMATION)
444 {
445 s_AnimCamera = nw::ut::DynamicCast<nw::gfx::Camera*>
446 (nw::demo::Utility::FindObjectByName(s_AnimTargets, animBindingTable.targetName));
447 }
448 }
449
450 NW_NULL_ASSERT(s_AnimCamera);
451 }
452
453 /*!--------------------------------------------------------------------------*
454 @brief 指定した名前のオブジェクトを指定したシーンルートに再配置します。
455 *---------------------------------------------------------------------------*/
456 void
ReattachObjectByName(const char * name,nw::gfx::SceneNode * root)457 ReattachObjectByName(const char* name, nw::gfx::SceneNode* root)
458 {
459 nw::gfx::SceneNode* node = nw::ut::DynamicCast<nw::gfx::SceneNode*>
460 (nw::demo::Utility::FindObjectByName(s_AnimTargets, name));
461
462 NW_NULL_ASSERT(node);
463
464 node->GetParent()->DetachChild( node );
465 root->AttachChild( node );
466 }
467
468 /*!--------------------------------------------------------------------------*
469 @brief 指定した名前のオブジェクトを移動します。
470 *---------------------------------------------------------------------------*/
471 void
MoveObjectByName(const char * name,f32 x,f32 y,f32 z)472 MoveObjectByName(const char* name, f32 x, f32 y, f32 z)
473 {
474 nw::gfx::TransformNode* node = nw::ut::DynamicCast<nw::gfx::TransformNode*>
475 (nw::demo::Utility::FindObjectByName(s_AnimTargets, name));
476
477 NW_NULL_ASSERT(node);
478
479 node->Transform().SetTranslate(x,y,z);
480 }
481
482 /*!--------------------------------------------------------------------------*
483 @brief オブジェクトを各シーンルートに再配置します。
484 *---------------------------------------------------------------------------*/
485 void
ReattachObjects()486 ReattachObjects()
487 {
488 // スケルタルアニメーション
489 ReattachObjectByName("Male", s_SkeletalRoot);
490 MoveObjectByName("Male", 0.0f, -8.0f, 0.0f);
491 ReattachObjectByName("Pierrot", s_SkeletalRoot);
492 MoveObjectByName("Pierrot", 10.0f, -8.0f, 0.0f);
493 ReattachObjectByName("Robot", s_SkeletalRoot);
494 MoveObjectByName("Robot", -10.0f, -8.0f, 0.0f);
495
496 // マテリアルアニメーション
497 ReattachObjectByName("MatAnim", s_MaterialRoot);
498
499 // ビジビリティアニメーション
500 ReattachObjectByName("VisibilityAnim", s_VisibilityRoot);
501 MoveObjectByName("VisibilityAnim", 0.0f, -8.0f, 0.0f);
502
503 // カメラアニメーション
504 ReattachObjectByName("CameraAnim", s_CameraRoot);
505
506 // ライトアニメーション
507 ReattachObjectByName("LightAnim", s_LightRoot);
508 }
509
510 /*!--------------------------------------------------------------------------*
511 @brief アニメーションを切り替えます。
512 *---------------------------------------------------------------------------*/
513 void
ToggleAnimationMode(bool isIncremental)514 ToggleAnimationMode(bool isIncremental)
515 {
516 // s_SceneRoot から取り外したシーンノードは描画されなくなります。
517 // 不可視にするためには取り外すだけで十分なのですが、
518 // 破棄などの処理を行いやすくするために、描画しないシーンノードは
519 // s_SceneRootInvisible という別のシーンルートに取り付けておきます。
520
521 switch (s_AnimMode)
522 {
523 case 0:
524 s_SceneRoot->DetachChild(s_SkeletalRoot);
525 s_SceneRootInvisible->AttachChild(s_SkeletalRoot);
526 break;
527 case 1:
528 s_SceneRoot->DetachChild(s_MaterialRoot);
529 s_SceneRootInvisible->AttachChild(s_MaterialRoot);
530 break;
531 case 2:
532 s_SceneRoot->DetachChild(s_VisibilityRoot);
533 s_SceneRootInvisible->AttachChild(s_VisibilityRoot);
534 break;
535 case 3:
536 ChangeCamera(s_BaseCameraIndex);
537 s_SceneRoot->DetachChild(s_CameraRoot);
538 s_SceneRootInvisible->AttachChild(s_CameraRoot);
539 break;
540 case 4:
541 s_SceneRoot->DetachChild(s_LightRoot);
542 s_SceneRootInvisible->AttachChild(s_LightRoot);
543 break;
544 default:
545 NW_ASSERT(false);
546 }
547
548 if (isIncremental)
549 {
550 s_AnimMode++;
551 if (s_AnimMode > 4)
552 {
553 s_AnimMode = 0;
554 }
555 }
556 else
557 {
558 s_AnimMode--;
559 if (s_AnimMode < 0)
560 {
561 s_AnimMode = 4;
562 }
563 }
564
565 switch (s_AnimMode)
566 {
567 case 0:
568 s_SceneRootInvisible->DetachChild(s_SkeletalRoot);
569 s_SceneRoot->AttachChild(s_SkeletalRoot);
570 break;
571 case 1:
572 s_SceneRootInvisible->DetachChild(s_MaterialRoot);
573 s_SceneRoot->AttachChild(s_MaterialRoot);
574 break;
575 case 2:
576 s_SceneRootInvisible->DetachChild(s_VisibilityRoot);
577 s_SceneRoot->AttachChild(s_VisibilityRoot);
578 break;
579 case 3:
580 s_SceneRootInvisible->DetachChild(s_CameraRoot);
581 s_SceneRoot->AttachChild(s_CameraRoot);
582 ChangeCamera(s_AnimCameraIndex);
583 break;
584 case 4:
585 s_SceneRootInvisible->DetachChild(s_LightRoot);
586 s_SceneRoot->AttachChild(s_LightRoot);
587 break;
588 default:
589 NW_ASSERT(false);
590 }
591
592 // シーン構造が変化したので、シーンの初期化を行います。
593 s_SceneSystem->InitializeScene(s_SceneRoot);
594 }
595 /*!--------------------------------------------------------------------------*
596 @brief シーンを初期化します。
597 *---------------------------------------------------------------------------*/
598 void
InitializeScenes()599 InitializeScenes()
600 {
601 BuildRootNodes();
602
603 BuildCameras();
604
605 // LUT を持ったリソースを読み込みます。
606 s_LutResource = nw::demo::Utility::LoadResources(s_Resources, LUT_RESOURCE_FILE, &s_DeviceAllocator);
607 BuildResources(s_LutResource);
608
609 // モデルやそれ以外のリソースを読み込みます。
610 NW_FOREACH(const wchar_t* name, RESOURCE_FILES)
611 {
612 nw::demo::ResourceSet* resourceSet = nw::demo::Utility::LoadResources(s_Resources, name, &s_DeviceAllocator);
613 BuildResources(resourceSet);
614 s_ResAnims.push_back(resourceSet->resource);
615 }
616
617 BuildAnimations();
618 ReattachObjects();
619
620 // ライトアニメーションを表示します
621 s_SceneRootInvisible->DetachChild(s_LightRoot);
622 s_SceneRoot->AttachChild(s_LightRoot);
623 s_AnimMode = 4;
624
625 // シーンツリーを巡回して初期化を行います。
626 s_SceneSystem->InitializeScene(s_SceneRoot);
627 s_SceneSystem->UpdateScene();
628
629 // シーン環境の参照解決を行い設定します。
630 s_RenderSystem->SetSceneEnvironmentSettings(s_SceneSystem, &s_SceneEnvironmentSettings);
631 nw::gfx::SceneEnvironment& sceneEnvironment = s_RenderSystem->GetSceneEnvironment();
632 sceneEnvironment.SetCamera(s_BaseCameraIndex, s_BaseCamera);
633 sceneEnvironment.SetCamera(s_AnimCameraIndex, s_AnimCamera);
634 ChangeCamera(s_BaseCameraIndex);
635
636 NW_GL_ASSERT();
637
638 s_FrameCount = 0;
639 }
640
641 /*!--------------------------------------------------------------------------*
642 @brief シーン関連の後始末をします。
643 *---------------------------------------------------------------------------*/
644 void
TerminateScenes()645 TerminateScenes()
646 {
647 // 表示されていないシーンオブジェクトも破棄するために s_SceneRootInvisible に対して SafeDestroyBranch を実行します。
648 nw::gfx::SafeDestroyBranch(s_SceneRoot);
649 nw::gfx::SafeDestroyBranch(s_SceneRootInvisible);
650 nw::demo::SafeCleanupResources(s_Resources);
651 nw::ut::SafeDestroyAll(s_SceneEnvironmentSettings);
652
653 TerminateAnim();
654
655 NW_GL_ASSERT();
656
657 s_Resources.clear();
658 s_SceneEnvironmentSettings.clear();
659
660 s_SceneRoot = NULL;
661 s_SkeletalRoot = NULL;
662 s_MaterialRoot = NULL;
663 s_VisibilityRoot = NULL;
664 s_CameraRoot = NULL;
665 s_LightRoot = NULL;
666 }
667
668 /*!--------------------------------------------------------------------------*
669 @brief シーンを更新します。
670 *---------------------------------------------------------------------------*/
671 void
UpdateScene()672 UpdateScene()
673 {
674 s_SceneSystem->GetCameraController()->Update();
675
676 s_SceneSystem->UpdateScene();
677
678 s_ActiveCamera->UpdateCameraMatrix();
679
680 f32 near = s_ActiveCamera->GetNear();
681
682 s_RenderSystem->CalcStereoCamera(
683 s_LeftCamera,
684 s_RightCamera,
685 s_ActiveCamera,
686 near + 5.0f);
687
688 ++s_FrameCount;
689 }
690
691 /*!--------------------------------------------------------------------------*
692 @brief 負荷表示やテスト機能の処理をおこないます。
693 *---------------------------------------------------------------------------*/
694 void
ReportDemo()695 ReportDemo()
696 {
697 NW_PROFILE("ReportDemo");
698
699 // 負荷表示からはこれらの負荷は除きます。
700 s_RenderSystem->SuspendLoadMeter();
701
702 nw::demo::DebugUtility::CalcLoadMeter(s_RenderSystem);
703
704 s_GraphicsDrawing.BeginDrawingShape();
705
706 nw::demo::DebugUtility::DrawLoadMeter(
707 s_RenderSystem,
708 &s_GraphicsDrawing
709 );
710
711 s_GraphicsDrawing.EndDrawingShape();
712
713 s_GraphicsDrawing.BeginDrawingString();
714
715 nw::demo::DebugUtility::DrawLoadMeterText(
716 s_RenderSystem,
717 &s_GraphicsDrawing
718 );
719
720 const int dumpPositionX = 10;
721 const int dumpPositionY = 10;
722 const char* mode;
723 switch (s_AnimMode)
724 {
725 case 0:
726 mode = "Skeletal";
727 break;
728 case 1:
729 mode = "Material";
730 break;
731 case 2:
732 mode = "Visibility";
733 break;
734 case 3:
735 mode = "Camera";
736 break;
737 case 4:
738 mode = "Light";
739 break;
740 default:
741 mode = "";
742 break;
743 }
744 s_GraphicsDrawing.DrawString(
745 dumpPositionX,
746 dumpPositionY,
747 "%s",
748 mode
749 );
750
751 s_GraphicsDrawing.EndDrawingString();
752
753 s_RenderSystem->ResumeLoadMeter();
754 }
755
756 /*!--------------------------------------------------------------------------*
757 @brief シーンをデモンストレーションします。
758 *---------------------------------------------------------------------------*/
759 void
DemoScene()760 DemoScene()
761 {
762 NW_ASSERT(!s_RenderTargets.empty());
763
764 nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
765
766 InitializeScenes();
767
768 nw::demo::DebugUtility::PostInitializeScenes();
769
770 bool isContinuing = true;
771
772 while ( isContinuing )
773 {
774 nw::demo::DebugUtility::AdvanceAutoTestFrame();
775
776 nw::demo::PadFactory::GetPad()->Update();
777
778 if (nw::demo::PadFactory::GetPad()->IsButtonDown( nw::demo::Pad::BUTTON_L ))
779 {
780 ToggleAnimationMode(true);
781 }
782 if (nw::demo::PadFactory::GetPad()->IsButtonDown( nw::demo::Pad::BUTTON_R ))
783 {
784 ToggleAnimationMode(false);
785 }
786 UpdateScene();
787
788 renderContext->SetActiveCamera(s_ActiveCameraIndex);
789 s_RenderSystem->SubmitView(s_SceneSystem);
790
791 s_RenderSystem->SetRenderTarget(s_RenderTargets[0]);
792 s_RenderSystem->RenderStereoScene(s_LeftCamera, s_RightCamera);
793
794 s_RenderSystem->ClearBySkyModel(renderContext->GetActiveCamera());
795 ReportDemo();
796 s_RenderSystem->TransferBuffer(nw::demo::LOWER_SCREEN);
797
798 s_RenderSystem->PresentBuffer(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN);
799
800 renderContext->ResetState();
801
802 if (nw::demo::Utility::IsTerminating())
803 {
804 isContinuing = false;
805 }
806 }
807
808 nw::demo::DebugUtility::PreTerminateScenes();
809
810 TerminateScenes();
811 }
812
813 } // namespace
814
815 /*!--------------------------------------------------------------------------*
816 @brief メイン関数です。
817 *---------------------------------------------------------------------------*/
818 void
nnMain()819 nnMain()
820 {
821 nw::demo::InitializeGraphicsSystem(&s_DeviceAllocator);
822
823 nw::demo::PadFactory::Initialize(&s_DeviceAllocator);
824
825 NW_DEMO_TEST_LOOP(&s_DeviceAllocator, NULL, &s_RenderSystem)
826 {
827 InitializeGraphics();
828
829 DemoScene();
830
831 TerminateGraphics();
832 }
833
834 nw::demo::PadFactory::Finalize();
835
836 nw::demo::FinalizeGraphicsSystem();
837 }
838