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