1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: AnimationBlendDemo.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: 22362 $
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* MODEL_RESOURCE_FILES[] =
43 {
44 NW_DEMO_FILE_PATH(L"Male.bcmdl"),
45 NW_DEMO_FILE_PATH(L"SceneEnvironmentSetting.bcenv"),
46 NW_DEMO_FILE_PATH(L"FragmentLight.bcenv"),
47 };
48
49 const wchar_t* SKELETAL_ANIM_RESOURCE_FILES[] =
50 {
51 NW_DEMO_FILE_PATH(L"Walk.bcskla"),
52 NW_DEMO_FILE_PATH(L"Run.bcskla")
53 };
54
55 const wchar_t* MATERIAL_ANIM_RESOURCE_FILES[] =
56 {
57 NW_DEMO_FILE_PATH(L"RedFading.bcmata"),
58 NW_DEMO_FILE_PATH(L"GreenFading.bcmata")
59 };
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
76 //----------------------------------------
77 // シーン関係
78 const int SCENE_NODE_COUNT = 4;
79 nw::gfx::SceneNode* s_SceneRoot = NULL;
80 nw::gfx::SceneNode* s_ModelRoot = NULL;
81 s32 s_FrameCount = 0;
82 nw::gfx::Camera* s_BaseCamera = NULL;
83 nw::gfx::Camera* s_LeftCamera = NULL;
84 nw::gfx::Camera* s_RightCamera = NULL;
85 const f32 s_fNearPlane = 0.1f;
86
87 //----------------------------------------
88 // シーン環境関係
89 const s32 ENVIRONMENT_SETTINGS_COUNT = 1;
90
91 typedef nw::ut::FixedSizeArray<nw::gfx::SceneEnvironmentSetting*, ENVIRONMENT_SETTINGS_COUNT> SceneEnvironmentSettingArray;
92 SceneEnvironmentSettingArray s_SceneEnvironmentSettings;
93
94 const s32 s_BaseCameraIndex = 0;
95
96 //----------------------------------------
97 // アニメーション関係
98 nw::gfx::SkeletalModel* s_AnimModel = NULL;
99 const int MAX_ANIM_OBJECTS = 6;
100 nw::ut::FixedSizeArray<nw::gfx::AnimObject*, MAX_ANIM_OBJECTS> s_AnimObjects;
101 float s_SkeletalAnimWeight0 = 0.5f;
102 float s_SkeletalAnimWeight1 = 0.5f;
103 float s_MaterialAnimWeight0 = 0.5f;
104 float s_MaterialAnimWeight1 = 0.5f;
105
106 /*!--------------------------------------------------------------------------*
107 @brief グラフィックス関連の初期化を行います。
108 *---------------------------------------------------------------------------*/
109 void
InitializeGraphics()110 InitializeGraphics()
111 {
112 nw::gfx::CommandCacheManager::SetAllocator( &s_DeviceAllocator );
113
114 // renderDescriptionへステレオの設定を行います。
115 nw::demo::RenderSystem::Description renderDescription;
116
117 renderDescription.reusableCommandBufferSize = 0x100000;
118 renderDescription.reusableCommandRequestCount = 512;
119 renderDescription.upperScreenMode = nw::demo::UPPER_SCREEN_MODE_STEREO;
120
121 s_RenderSystem = nw::demo::RenderSystem::Create(&s_DeviceAllocator, renderDescription);
122
123 s_GraphicsDrawing.SetScreenSize(
124 renderDescription.lowerScreenDescription.width,
125 renderDescription.lowerScreenDescription.height
126 );
127
128 nw::demo::Utility::InitializeGraphicsDrawing(&s_DeviceAllocator, s_GraphicsDrawing);
129
130 s_RenderTargets.push_back(
131 nw::demo::Utility::CreateUpperScreenBuffer(&s_DeviceAllocator, renderDescription)
132 );
133 NW_ASSERT(!s_RenderTargets.empty());
134 s_RenderSystem->GetRenderContext()->SetRenderTarget(s_RenderTargets.front());
135
136 // sceneDescriptionへの標準的な設定はコンストラクタで行われています。
137 nw::demo::SceneSystem::Description sceneDescription;
138 sceneDescription.isFixedSizeMemory = true;
139 s_SceneSystem = nw::demo::SceneSystem::Create(&s_DeviceAllocator, sceneDescription);
140
141 // デモ用の最遠景モデルをレンダリングシステムに設定します。
142 // gfx のデモでは glClear などを用いずに背景で塗りつぶしを行います。
143 s_RenderSystem->LoadSkyModel(SKY_SPHERE_FILE_NAME);
144
145 NW_GL_ASSERT();
146 }
147
148 /*!--------------------------------------------------------------------------*
149 @brief グラフィックス関連の後始末をします。
150 *---------------------------------------------------------------------------*/
151 void
TerminateGraphics()152 TerminateGraphics()
153 {
154 nw::gfx::SafeDestroy(s_LeftCamera);
155
156 nw::gfx::SafeDestroy(s_RightCamera);
157
158 nw::gfx::SafeDestroy(s_SceneSystem);
159
160 nw::gfx::SafeDestroyAll(s_RenderTargets);
161
162 s_GraphicsDrawing.Finalize();
163
164 nw::gfx::SafeDestroy(s_RenderSystem);
165
166 NW_GL_ASSERT();
167 }
168
169 /*!--------------------------------------------------------------------------*
170 @brief ファイルから TransformAnimEvaluator を生成します。
171
172 リソースからアニメーションを計算するための AnimEvaluator(アニメーション評価)を生成します。
173
174 @param[in] maxBones 最大メンバ数です。
175 @param[in] translateAnimEnabled 移動アニメーションが有効かどうかです。
176 @param[in] filePath トランスフォームアニメーションファイルのフルパスです。
177
178 @return トランスフォームアニメーション評価です。
179 *---------------------------------------------------------------------------*/
180 nw::gfx::TransformAnimEvaluator*
CreateTransformAnimEvaluator(const int maxMembers,const bool translateAnimEnabled,const wchar_t * filePath)181 CreateTransformAnimEvaluator(
182 const int maxMembers,
183 const bool translateAnimEnabled,
184 const wchar_t* filePath
185 )
186 {
187 // ファイルからアニメーションデータのインスタンスを生成します。
188 nw::demo::ResourceSet* resourceSet = nw::demo::Utility::LoadResources(s_Resources, filePath, &s_DeviceAllocator);
189 if (resourceSet->resource.GetSkeletalAnimsCount() == 0)
190 {
191 // スケルタルアニメーション用のアニメーションデータがありません。
192 return NULL;
193 }
194 nw::anim::ResAnim resAnim = resourceSet->resource.GetSkeletalAnims(0);
195
196 if (!resAnim.IsValid())
197 {
198 return NULL;
199 }
200
201 // resAnim から、AnimEvaluator::Builder を用いて AnimEvaluator を生成します。
202 // スケルタルアニメーションの場合は、TransformAnimEvaluator::Builder を使用します。
203 //
204 // アニメーションを1つのモデルにのみ適用する場合や、
205 // コマ形式データの場合は、 AllocCache を false にすると処理負荷が下がります。
206 nw::gfx::TransformAnimEvaluator* evaluator = nw::gfx::TransformAnimEvaluator::Builder()
207 .AnimData(resAnim)
208 .MaxMembers(maxMembers)
209 .MaxAnimMembers(resAnim.GetMemberAnimSetCount())
210 .AllocCache(false)
211 .Create(&s_DeviceAllocator);
212
213 // 移動アニメーションの無効化フラグを設定します。
214 evaluator->SetIsTranslateDisabled(!translateAnimEnabled);
215
216 return evaluator;
217 }
218
219 /*!--------------------------------------------------------------------------*
220 @brief ファイルからマテリアルアニメーション評価を生成します。
221
222 @param[in] maxBones 最大メンバ数です。
223 @param[in] filePath マテリアルアニメーションファイルのフルパスです。
224
225 @return マテリアルアニメーション評価です。
226 *---------------------------------------------------------------------------*/
227 nw::gfx::AnimEvaluator*
CreateMaterialAnimEvaluator(const int maxMembers,const wchar_t * filePath)228 CreateMaterialAnimEvaluator(
229 const int maxMembers,
230 const wchar_t* filePath
231 )
232 {
233 //----------------------------------------
234 // アニメーションリソースを生成します。
235 nw::demo::ResourceSet* resourceSet = nw::demo::Utility::LoadResources(s_Resources, filePath, &s_DeviceAllocator);
236 if (resourceSet->resource.GetMaterialAnimsCount() == 0)
237 {
238 return NULL;
239 }
240
241 nw::anim::ResAnim resAnim = resourceSet->resource.GetMaterialAnims(0);
242 if (!resAnim.IsValid())
243 {
244 return NULL;
245 }
246
247 //----------------------------------------
248 // マテリアルアニメーション評価を生成します。
249 nw::gfx::AnimEvaluator* evaluator = nw::gfx::AnimEvaluator::Builder()
250 .AnimData(resAnim)
251 .MaxMembers(maxMembers)
252 .MaxAnimMembers(resAnim.GetMemberAnimSetCount())
253 .AllocCache(true)
254 .Create(&s_DeviceAllocator);
255
256 return evaluator;
257 }
258
259 /*!--------------------------------------------------------------------------*
260 @brief スケルタルアニメーションを初期化します。
261
262 アニメーション補間を生成し、2 つのアニメーション評価の結果をブレンドします。
263
264 @param[in] model スケルタルモデルです。
265 *---------------------------------------------------------------------------*/
266 void
InitializeSkeletalAnim(nw::gfx::SkeletalModel * model)267 InitializeSkeletalAnim(nw::gfx::SkeletalModel* model)
268 {
269 nw::gfx::AnimGroup* animGroup = model->GetSkeletalAnimGroup();
270 if (animGroup == NULL) // スケルタルアニメーション用のアニメーショングループがありません。
271 {
272 return;
273 }
274
275 nw::gfx::ResSkeletalModel resModel = model->GetResSkeletalModel();
276 nw::gfx::ResSkeleton resSkeleton = resModel.GetSkeleton();
277 const int maxBones = resSkeleton.GetBonesCount();
278 const bool translateAnimEnabled =
279 nw::ut::CheckFlag(resSkeleton.GetFlags(), nw::gfx::ResSkeletonData::FLAG_TRANSLATE_ANIMATION_ENABLED);
280
281 //----------------------------------------
282 // アニメーション評価を生成します。
283 nw::gfx::TransformAnimEvaluator* evaluator0 = CreateTransformAnimEvaluator(
284 maxBones, translateAnimEnabled, SKELETAL_ANIM_RESOURCE_FILES[0]);
285 if (evaluator0 == NULL)
286 {
287 return;
288 }
289
290 // アニメーションをバインドします。
291 evaluator0->Bind(animGroup);
292 s_AnimObjects.PushBack(evaluator0);
293
294 //----------------------------------------
295 // 2 つめのアニメーション評価を生成します。
296 nw::gfx::TransformAnimEvaluator* evaluator1 = CreateTransformAnimEvaluator(
297 maxBones, translateAnimEnabled, SKELETAL_ANIM_RESOURCE_FILES[1]);
298
299 if (evaluator1 == NULL)
300 {
301 return;
302 }
303
304 evaluator1->Bind(animGroup);
305 s_AnimObjects.PushBack(evaluator1);
306
307 // 自然な絵になるように、2つのアニメーションの再生時間を合わせます。
308 float frameSize0 = evaluator0->AnimFrameController().GetEndFrame();
309 float frameSize1 = evaluator1->AnimFrameController().GetEndFrame();
310 evaluator1->SetStepFrame(frameSize1 / frameSize0);
311
312 //----------------------------------------
313 // スケルタルアニメーション補間を生成します。
314 nw::gfx::TransformAnimInterpolator* blender = nw::gfx::TransformAnimInterpolator::Builder()
315 .MaxAnimObjects(2)
316 .Create(&s_DeviceAllocator);
317
318 blender->Bind(animGroup);
319 blender->AddAnimObject(evaluator0);
320 blender->AddAnimObject(evaluator1);
321 blender->SetWeight(0, s_SkeletalAnimWeight0);
322 blender->SetWeight(1, s_SkeletalAnimWeight1);
323
324 // 設定する重みは常に合計が 1 になり正規化は不要なので、正規化を無効にします。
325 // 合計が 1 にならないような重みを設定する場合は true を指定します。
326 blender->SetNormalizationEnabled(false);
327
328 model->SetSkeletalAnimObject(blender);
329 s_AnimObjects.PushBack(blender);
330 }
331
332 /*!--------------------------------------------------------------------------*
333 @brief マテリアルアニメーションを初期化します。
334
335 アニメーション補間を生成し、2 つのアニメーション評価の結果をブレンドします。
336
337 @param[in] model モデルです。
338 *---------------------------------------------------------------------------*/
339 void
InitializeMaterialAnim(nw::gfx::Model * model)340 InitializeMaterialAnim(nw::gfx::Model* model)
341 {
342 nw::gfx::AnimGroup* animGroup = model->GetMaterialAnimGroup();
343
344 if (animGroup == NULL) // アニメーション用のアニメーショングループがありません。
345 {
346 return;
347 }
348
349 int maxMembers = animGroup->GetMemberCount();
350
351 //----------------------------------------
352 // アニメーション評価を生成します。
353 nw::gfx::AnimEvaluator* evaluator0 = CreateMaterialAnimEvaluator(
354 maxMembers, MATERIAL_ANIM_RESOURCE_FILES[0]);
355 if (evaluator0 == NULL)
356 {
357 return;
358 }
359
360 // アニメーションをバインドします。
361 evaluator0->Bind(animGroup);
362 s_AnimObjects.PushBack(evaluator0);
363
364 //----------------------------------------
365 // 2 つめのアニメーション評価を生成します。
366 nw::gfx::AnimEvaluator* evaluator1 = CreateMaterialAnimEvaluator(
367 maxMembers, MATERIAL_ANIM_RESOURCE_FILES[1]);
368
369 if (evaluator1 == NULL)
370 {
371 return;
372 }
373
374 evaluator1->Bind(animGroup);
375 s_AnimObjects.PushBack(evaluator1);
376
377 //----------------------------------------
378 // アニメーション補間を生成します。
379 nw::gfx::AnimInterpolator* blender = nw::gfx::AnimInterpolator::Builder()
380 .MaxAnimObjects(2)
381 .Create(&s_DeviceAllocator);
382
383 blender->Bind(animGroup);
384 blender->AddAnimObject(evaluator0);
385 blender->AddAnimObject(evaluator1);
386 blender->SetWeight(0, s_MaterialAnimWeight0);
387 blender->SetWeight(1, s_MaterialAnimWeight0);
388
389 // 設定する重みは常に合計が 1 になり正規化は不要なので、正規化を無効にします。
390 // 合計が 1 にならないような重みを設定する場合は true を指定します。
391 blender->SetNormalizationEnabled(false);
392
393 model->SetMaterialAnimObject(blender);
394 s_AnimObjects.PushBack(blender);
395 }
396
397 /*!--------------------------------------------------------------------------*
398 @brief ブレンダーを更新します。
399
400 @param[in] model モデルです。
401 *---------------------------------------------------------------------------*/
402 void
UpdateBlender(nw::gfx::SkeletalModel * model)403 UpdateBlender(nw::gfx::SkeletalModel* model)
404 {
405 NW_PROFILE("UpdateBlender");
406
407 if (model == NULL)
408 {
409 return;
410 }
411
412 // ブレンドのウェイト値を設定します。
413 nw::gfx::AnimObject* skeletalAnimObject = model->GetSkeletalAnimObject();
414 nw::gfx::TransformAnimInterpolator* skeletalInterpolator =
415 nw::ut::DynamicCast<nw::gfx::TransformAnimInterpolator*>(skeletalAnimObject);
416 if (skeletalInterpolator != NULL)
417 {
418 bool weightChanged = false;
419 nw::demo::Pad* pad = nw::demo::PadFactory::GetPad();
420 if (pad->IsButtonPress(nw::demo::Pad::BUTTON_LEFT))
421 {
422 s_SkeletalAnimWeight1 -= 0.02f;
423 weightChanged = true;
424 }
425 if (pad->IsButtonPress(nw::demo::Pad::BUTTON_RIGHT))
426 {
427 s_SkeletalAnimWeight1 += 0.02f;
428 weightChanged = true;
429 }
430 if (weightChanged)
431 {
432 s_SkeletalAnimWeight1 = nw::ut::Clamp(s_SkeletalAnimWeight1, 0.0f, 1.0f);
433 s_SkeletalAnimWeight0 = 1.0f - s_SkeletalAnimWeight1;
434
435 skeletalInterpolator->SetWeight(0, s_SkeletalAnimWeight0);
436 skeletalInterpolator->SetWeight(1, s_SkeletalAnimWeight1);
437 }
438 }
439
440 nw::gfx::AnimObject* materialAnimObject = model->GetMaterialAnimObject();
441 nw::gfx::AnimInterpolator* materialInterpolator =
442 nw::ut::DynamicCast<nw::gfx::AnimInterpolator*>(materialAnimObject);
443 if (materialInterpolator != NULL)
444 {
445 bool weightChanged = false;
446 nw::demo::Pad* pad = nw::demo::PadFactory::GetPad();
447 if (pad->IsButtonPress(nw::demo::Pad::BUTTON_UP))
448 {
449 s_MaterialAnimWeight1 -= 0.02f;
450 weightChanged = true;
451 }
452 if (pad->IsButtonPress(nw::demo::Pad::BUTTON_DOWN))
453 {
454 s_MaterialAnimWeight1 += 0.02f;
455 weightChanged = true;
456 }
457 if (weightChanged)
458 {
459 s_MaterialAnimWeight1 = nw::ut::Clamp(s_MaterialAnimWeight1, 0.0f, 1.0f);
460 s_MaterialAnimWeight0 = 1.0f - s_MaterialAnimWeight1;
461
462 materialInterpolator->SetWeight(0, s_MaterialAnimWeight1);
463 materialInterpolator->SetWeight(1, s_MaterialAnimWeight0);
464 }
465 }
466 }
467
468 /*!--------------------------------------------------------------------------*
469 @brief アニメーションの後始末をします。
470 *---------------------------------------------------------------------------*/
471 void
TerminateAnim(void)472 TerminateAnim(void)
473 {
474 for (int animIdx = 0; animIdx < s_AnimObjects.Size(); ++animIdx)
475 {
476 nw::gfx::SafeDestroy(s_AnimObjects[animIdx]);
477 }
478 s_AnimObjects.clear();
479 }
480
481 /*!--------------------------------------------------------------------------*
482 @brief ルートノード関連の構築をします。
483 *---------------------------------------------------------------------------*/
484 void
BuildRootNodes()485 BuildRootNodes()
486 {
487 NW_ASSERT(s_SceneRoot == NULL);
488 s_SceneRoot = nw::gfx::TransformNode::DynamicBuilder()
489 .Create(&s_DeviceAllocator);
490 NW_NULL_ASSERT(s_SceneRoot);
491
492 NW_ASSERT(s_ModelRoot == NULL);
493 s_ModelRoot = nw::gfx::TransformNode::DynamicBuilder()
494 .Create(&s_DeviceAllocator);
495 s_SceneRoot->AttachChild(s_ModelRoot);
496 NW_NULL_ASSERT(s_ModelRoot);
497 }
498
499 /*!--------------------------------------------------------------------------*
500 @brief カメラ関連の構築をします。
501 *---------------------------------------------------------------------------*/
502 void
BuildCameras()503 BuildCameras()
504 {
505 nw::demo::Utility::CreateStereoCameras(
506 &s_BaseCamera,
507 &s_LeftCamera,
508 &s_RightCamera,
509 &s_DeviceAllocator,
510 nw::math::VEC3(20.0f, 15.0f, 20.0f),
511 nw::math::VEC3(0.0f, 10.0f, 0.0f),
512 s_fNearPlane
513 );
514
515 s_SceneRoot->AttachChild(s_BaseCamera);
516 s_SceneSystem->GetCameraController()->Register(s_BaseCamera);
517 }
518
519 /*!--------------------------------------------------------------------------*
520 @brief リソース関連の構築をします。
521 *---------------------------------------------------------------------------*/
522 void
BuildResources(nw::demo::ResourceSet * resourceSet)523 BuildResources(nw::demo::ResourceSet* resourceSet)
524 {
525 resourceSet->resource.ForeachTexture(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP));
526 resourceSet->resource.ForeachIndexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
527 resourceSet->resource.ForeachVertexStream(nw::gfx::LocationFlagSetter(NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));
528
529 nw::gfx::Result result = resourceSet->resource.Setup(&s_DeviceAllocator);
530 if (result.IsFailure())
531 {
532 NW_FATAL_ERROR("Fail to set up model. A result code is 0x%x", result.GetCode());
533 }
534
535 nw::ut::MoveArray<nw::gfx::SceneNode*> sceneNodeArray(SCENE_NODE_COUNT, &s_DeviceAllocator);
536
537 nw::gfx::ResModelArray models = resourceSet->resource.GetModels();
538 nw::gfx::ResModelArray::iterator modelsEnd = models.end();
539 for (nw::gfx::ResModelArray::iterator modelResource = models.begin();
540 modelResource != modelsEnd; ++modelResource)
541 {
542 nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
543 &s_DeviceAllocator,
544 (*modelResource)
545 );
546 NW_NULL_ASSERT(node);
547 sceneNodeArray.push_back(node);
548 s_AnimModel = nw::ut::DynamicCast<nw::gfx::SkeletalModel*>(node);
549 }
550
551 nw::gfx::ResLightArray lights = resourceSet->resource.GetLights();
552 nw::gfx::ResLightArray::iterator lightsEnd = lights.end();
553 for (nw::gfx::ResLightArray::iterator lightResource = lights.begin();
554 lightResource != lightsEnd; ++lightResource)
555 {
556 nw::gfx::SceneNode* node = nw::demo::Utility::CreateSceneNode(
557 &s_DeviceAllocator,
558 (*lightResource)
559 );
560 NW_NULL_ASSERT(node);
561 sceneNodeArray.push_back(node);
562 }
563
564 // 親子付け参照関係を解決
565 nw::gfx::SceneHelper::ResolveReference(sceneNodeArray);
566
567 // モデルをシーンに追加
568 nw::gfx::SceneHelper::ForeachRootNodes(
569 sceneNodeArray.Begin(),
570 sceneNodeArray.End(),
571 nw::gfx::AttachNode(s_ModelRoot)
572 );
573
574 nw::gfx::ResSceneEnvironmentSettingArray settings = resourceSet->resource.GetSceneEnvironmentSettings();
575 nw::gfx::ResSceneEnvironmentSettingArray::iterator settingsEnd = settings.end();
576 for (nw::gfx::ResSceneEnvironmentSettingArray::iterator settingResource = settings.begin();
577 settingResource != settingsEnd; ++settingResource)
578 {
579 nw::gfx::SceneObject* sceneObject = nw::gfx::SceneBuilder()
580 .Resource(*settingResource)
581 .CreateObject(&s_DeviceAllocator, &s_DeviceAllocator);
582
583 nw::gfx::SceneEnvironmentSetting* sceneEnvironmentSetting =
584 nw::ut::DynamicCast<nw::gfx::SceneEnvironmentSetting*>(sceneObject);
585
586 NW_NULL_ASSERT(sceneEnvironmentSetting);
587 s_SceneEnvironmentSettings.push_back(sceneEnvironmentSetting);
588 }
589 }
590
591 /*!--------------------------------------------------------------------------*
592 @brief シーンを初期化します。
593 *---------------------------------------------------------------------------*/
594 void
InitializeScenes()595 InitializeScenes()
596 {
597 s_SkeletalAnimWeight0 = 0.5f;
598 s_SkeletalAnimWeight1 = 0.5f;
599 s_MaterialAnimWeight0 = 0.5f;
600 s_MaterialAnimWeight1 = 0.5f;
601
602 BuildRootNodes();
603
604 BuildCameras();
605
606 NW_FOREACH(const wchar_t* name, MODEL_RESOURCE_FILES)
607 {
608 BuildResources(nw::demo::Utility::LoadResources(s_Resources, name, &s_DeviceAllocator));
609 }
610
611 if (s_AnimModel != NULL)
612 {
613 InitializeSkeletalAnim(s_AnimModel);
614 InitializeMaterialAnim(s_AnimModel);
615 }
616
617 // シーンツリーを巡回して初期化を行います。
618 s_SceneSystem->InitializeScene(s_SceneRoot);
619 s_SceneSystem->UpdateScene();
620
621 // シーン環境の参照解決を行い設定します。
622 s_RenderSystem->SetSceneEnvironmentSettings(s_SceneSystem, &s_SceneEnvironmentSettings);
623
624 // カメラを設定します。
625 nw::gfx::SceneEnvironment& sceneEnvironment = s_RenderSystem->GetSceneEnvironment();
626 sceneEnvironment.SetCamera(s_BaseCameraIndex, s_BaseCamera);
627 nw::demo::Utility::SetCameraAspectRatio(s_BaseCamera, s_RenderTargets[0]);
628
629 NW_GL_ASSERT();
630
631 s_FrameCount = 0;
632 }
633
634 /*!--------------------------------------------------------------------------*
635 @brief シーン関連の後始末をします。
636 *---------------------------------------------------------------------------*/
637 void
TerminateScenes()638 TerminateScenes()
639 {
640 nw::gfx::SafeDestroyBranch(s_SceneRoot);
641 nw::demo::SafeCleanupResources(s_Resources);
642 nw::ut::SafeDestroyAll(s_SceneEnvironmentSettings);
643 TerminateAnim();
644
645 NW_GL_ASSERT();
646
647 s_Resources.clear();
648 s_SceneEnvironmentSettings.clear();
649 s_ModelRoot = NULL;
650 }
651
652 /*!--------------------------------------------------------------------------*
653 @brief シーンを更新します。
654 *---------------------------------------------------------------------------*/
655 void
UpdateScene()656 UpdateScene()
657 {
658 UpdateBlender(s_AnimModel);
659
660 s_SceneSystem->GetCameraController()->Update();
661
662 s_SceneSystem->UpdateScene();
663
664 s_BaseCamera->UpdateCameraMatrix();
665
666 s_RenderSystem->CalcStereoCamera(s_LeftCamera, s_RightCamera, s_BaseCamera, s_fNearPlane + 5.0f);
667
668 ++s_FrameCount;
669 }
670
671 /*!--------------------------------------------------------------------------*
672 @brief 負荷表示やテスト機能の処理をおこないます。
673 *---------------------------------------------------------------------------*/
674 void
ReportDemo()675 ReportDemo()
676 {
677 NW_PROFILE("ReportDemo");
678
679 // 負荷表示からはこれらの負荷は除きます。
680 s_RenderSystem->SuspendLoadMeter();
681
682 nw::demo::DebugUtility::CalcLoadMeter(s_RenderSystem);
683
684 s_GraphicsDrawing.BeginDrawingShape();
685
686 nw::demo::DebugUtility::DrawLoadMeter(
687 s_RenderSystem,
688 &s_GraphicsDrawing
689 );
690
691 s_GraphicsDrawing.EndDrawingShape();
692
693 s_GraphicsDrawing.BeginDrawingString();
694
695 nw::demo::DebugUtility::DrawLoadMeterText(
696 s_RenderSystem,
697 &s_GraphicsDrawing
698 );
699
700 const int dumpPositionX = 10;
701 const int dumpPositionY = 10;
702 s_GraphicsDrawing.DrawString(
703 dumpPositionX,
704 dumpPositionY,
705 "weight: %0.2f %0.2f",
706 s_SkeletalAnimWeight1,
707 s_MaterialAnimWeight1
708 );
709
710 s_GraphicsDrawing.EndDrawingString();
711
712 s_RenderSystem->ResumeLoadMeter();
713 }
714
715 /*!--------------------------------------------------------------------------*
716 @brief シーンをデモンストレーションします。
717 *---------------------------------------------------------------------------*/
718 void
DemoScene()719 DemoScene()
720 {
721 NW_ASSERT(!s_RenderTargets.empty());
722
723 nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
724
725 InitializeScenes();
726
727 nw::demo::DebugUtility::PostInitializeScenes();
728
729 NW_LOG("[Animation Blend Demo usage]\n");
730 NW_LOG("up/down : change material animation blender weight\n");
731 NW_LOG("left/right: change skeletal animation blender weight\n");
732
733 bool isContinuing = true;
734
735 while ( isContinuing )
736 {
737 nw::demo::DebugUtility::AdvanceAutoTestFrame();
738
739 nw::demo::PadFactory::GetPad()->Update();
740
741 UpdateScene();
742
743 renderContext->SetActiveCamera(s_BaseCameraIndex);
744 s_RenderSystem->SubmitView(s_SceneSystem);
745
746 s_RenderSystem->SetRenderTarget(s_RenderTargets[0]);
747 s_RenderSystem->RenderStereoScene(s_LeftCamera, s_RightCamera);
748
749 s_RenderSystem->ClearBySkyModel(s_BaseCamera);
750 ReportDemo();
751 s_RenderSystem->TransferBuffer(nw::demo::LOWER_SCREEN);
752
753 s_RenderSystem->PresentBuffer(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN);
754
755 renderContext->ResetState();
756
757 if (nw::demo::Utility::IsTerminating())
758 {
759 isContinuing = false;
760 }
761 }
762
763 nw::demo::DebugUtility::PreTerminateScenes();
764
765 TerminateScenes();
766 }
767
768 } // namespace
769
770 /*!--------------------------------------------------------------------------*
771 @brief メイン関数です。
772 *---------------------------------------------------------------------------*/
773 void
nnMain()774 nnMain()
775 {
776 nw::demo::InitializeGraphicsSystem(&s_DeviceAllocator);
777
778 nw::demo::PadFactory::Initialize(&s_DeviceAllocator);
779
780 NW_DEMO_TEST_LOOP(&s_DeviceAllocator, NULL, &s_RenderSystem)
781 {
782 InitializeGraphics();
783
784 DemoScene();
785
786 TerminateGraphics();
787 }
788
789 nw::demo::PadFactory::Finalize();
790
791 nw::demo::FinalizeGraphicsSystem();
792 }
793