1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     demo_Utility.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: 31311 $
16  *---------------------------------------------------------------------------*/
17 
18 #include <nw/types.h>
19 #include <nw/os.h>
20 #include <nw/ut/ut_Inlines.h>
21 #include <nw/demo/demo_Utility.h>
22 #include <nw/gfx.h>
23 
24 #include <nn/fs.h>
25 #include <nn/pl.h>
26 
27 namespace nw {
28 namespace demo {
29 
30 const nw::math::VEC3 Utility::CAMERA_POSITION = nw::math::VEC3(7.0f, 3.5f, -5.0f);
31 const nw::math::VEC3 Utility::TARGET_POSITION = nw::math::VEC3(0.0f, 0.0f, 0.0f);
32 const f32 Utility::NEAR_CLIP = 0.1f;
33 const f32 Utility::FAR_CLIP = 1000.0f;
34 const f32 Utility::FOVY_RADIAN = NW_MATH_DEG_TO_RAD(37.8f);
35 const nw::math::VEC2 Utility::PROJECTION_CENTER = nw::math::VEC2(0.0f, 0.0f);
36 const f32 Utility::PROJECTION_HEIGHT = 1.0f;
37 
38 const wchar_t* Utility::FONT_SHADER_FILE_NAME = NW_DEMO_FILE_PATH(L"nwfont_RectDrawerShader.shbin");
39 const wchar_t* Utility::SHAPE_2D_SHADER_FILE_NAME = NW_DEMO_FILE_PATH(L"nwdemo_Common.shbin");
40 bool Utility::s_SharedFontAlreadyInitialized = false;
41 
42 //----------------------------------------
43 void
InitializeGraphicsDrawing(os::IAllocator * allocator,nw::demo::GraphicsDrawing & graphicsDrawing)44 Utility::InitializeGraphicsDrawing(
45     os::IAllocator* allocator,
46     nw::demo::GraphicsDrawing&  graphicsDrawing
47 )
48 {
49     bool result = false;
50 
51     result = InitializeSharedFont(allocator, graphicsDrawing);
52     NN_ASSERTMSG(result, "Fail to load Font.");
53 
54     result = graphicsDrawing.InitializeShape(allocator, SHAPE_2D_SHADER_FILE_NAME);
55     NN_ASSERTMSG(result, "Fail to initialize shape drawing.");
56 
57     NW_UNUSED_VARIABLE(result);
58 }
59 
60 //----------------------------------------
61 ResourceSet*
LoadResources(ResourceArray & resourceArray,const wchar_t * resourcePath,os::IAllocator * allocator)62 Utility::LoadResources(ResourceArray& resourceArray, const wchar_t* resourcePath, os::IAllocator* allocator)
63 {
64     ResourceSet resourceSet;
65     // 現在、デバイスメモリ上に読み込む方式にのみ対応しています。
66     // テクスチャをロードするには128byteアライメントを行う必要があります。
67     const int resourceAlignment = 128;
68     resourceSet.buffer = nw::demo::Utility::LoadFile(allocator, resourcePath, resourceAlignment);
69 
70     if (!resourceSet.buffer)
71     {
72         return NULL;
73     }
74 
75     resourceSet.resource = nw::gfx::ResGraphicsFile(&(resourceSet.buffer.front()));
76 
77     bool isPushed = resourceArray.push_back(resourceSet);
78 
79     NW_ASSERT(isPushed);
80 
81     return &(resourceArray.back());
82 }
83 
84 //----------------------------------------
85 nw::gfx::Camera*
CreateCamera(os::IAllocator * allocator,const nw::math::VEC3 & cameraPosition,const nw::math::VEC3 & targetPosition,f32 nearClip,f32 farClip,f32 fovyRadian,nw::math::PivotDirection pivotDirection,f32 wScale)86 Utility::CreateCamera(
87     os::IAllocator* allocator,
88     const nw::math::VEC3& cameraPosition,
89     const nw::math::VEC3& targetPosition,
90     f32 nearClip,
91     f32 farClip,
92     f32 fovyRadian,
93     nw::math::PivotDirection pivotDirection,
94     f32 wScale
95 )
96 {
97     NW_POINTER_ASSERT(allocator);
98 
99     nw::gfx::LookAtTargetViewUpdater* viewUpdater =
100         nw::gfx::LookAtTargetViewUpdater::Create(allocator);
101     NW_POINTER_ASSERT(viewUpdater);
102 
103     nw::gfx::ResLookAtTargetViewUpdater resViewUpdater =
104         nw::gfx::ResStaticCast<nw::gfx::ResLookAtTargetViewUpdater>(viewUpdater->GetResource());
105 
106     resViewUpdater.SetTargetPosition(targetPosition);
107     resViewUpdater.SetUpwardVector(0.0f,1.0f,0.0f);
108 
109     nw::gfx::PerspectiveProjectionUpdater* projectionUpdater =
110         nw::gfx::PerspectiveProjectionUpdater::Create(allocator);
111     NW_POINTER_ASSERT(projectionUpdater);
112 
113     projectionUpdater->SetPivotDirection(pivotDirection);
114 
115     nw::gfx::ResPerspectiveProjectionUpdater resProjectionUpdater =
116         nw::gfx::ResStaticCast<nw::gfx::ResPerspectiveProjectionUpdater>(
117         projectionUpdater->GetResource());
118     resProjectionUpdater.SetNear(nearClip);
119     resProjectionUpdater.SetFar(farClip);
120     resProjectionUpdater.SetFovy(fovyRadian);
121 
122     nw::gfx::Camera* camera =
123         nw::gfx::Camera::DynamicBuilder()
124         .MaxChildren(0)
125         .MaxCallbacks(0)
126         .ViewUpdater(viewUpdater)
127         .ProjectionUpdater(projectionUpdater)
128         .Create(allocator);
129 
130     NW_POINTER_ASSERT(camera);
131 
132     camera->Transform().SetTranslate(cameraPosition);
133     camera->SetWScale(wScale);
134 
135     return camera;
136 }
137 
138 //----------------------------------------
139 nw::gfx::Camera*
CreateAimCamera(os::IAllocator * allocator,const nw::math::VEC3 & cameraPosition,const nw::math::VEC3 & targetPosition,f32 nearClip,f32 farClip,f32 fovyRadian,nw::math::PivotDirection pivotDirection,f32 wScale)140 Utility::CreateAimCamera(
141     os::IAllocator* allocator,
142     const nw::math::VEC3& cameraPosition,
143     const nw::math::VEC3& targetPosition,
144     f32 nearClip,
145     f32 farClip,
146     f32 fovyRadian,
147     nw::math::PivotDirection pivotDirection,
148     f32 wScale
149 )
150 {
151     NW_POINTER_ASSERT(allocator);
152 
153     nw::gfx::AimTargetViewUpdater* viewUpdater =
154         nw::gfx::AimTargetViewUpdater::Create(allocator);
155     NW_POINTER_ASSERT(viewUpdater);
156 
157     nw::gfx::ResAimTargetViewUpdater resViewUpdater =
158         nw::gfx::ResStaticCast<nw::gfx::ResAimTargetViewUpdater>(viewUpdater->GetResource());
159 
160     resViewUpdater.SetTargetPosition(targetPosition);
161     resViewUpdater.SetTwist(0.0f);
162 
163     nw::gfx::PerspectiveProjectionUpdater* projectionUpdater =
164         nw::gfx::PerspectiveProjectionUpdater::Create(allocator);
165     NW_POINTER_ASSERT(projectionUpdater);
166 
167     projectionUpdater->SetPivotDirection(pivotDirection);
168 
169     nw::gfx::ResPerspectiveProjectionUpdater resProjectionUpdater =
170         nw::gfx::ResStaticCast<nw::gfx::ResPerspectiveProjectionUpdater>(
171         projectionUpdater->GetResource());
172     resProjectionUpdater.SetNear(nearClip);
173     resProjectionUpdater.SetFar(farClip);
174     resProjectionUpdater.SetFovy(fovyRadian);
175 
176     nw::gfx::Camera* camera =
177         nw::gfx::Camera::DynamicBuilder()
178         .MaxChildren(0)
179         .MaxCallbacks(0)
180         .ViewUpdater(viewUpdater)
181         .ProjectionUpdater(projectionUpdater)
182         .Create(allocator);
183 
184     NW_POINTER_ASSERT(camera);
185 
186     camera->Transform().SetTranslate(cameraPosition);
187     camera->SetWScale(wScale);
188 
189     return camera;
190 }
191 
192 //----------------------------------------
193 nw::gfx::Camera*
CreateFrustumCamera(os::IAllocator * allocator,const nw::math::VEC3 & cameraPosition,const nw::math::VEC3 & targetPosition,f32 nearClip,f32 farClip,const nw::math::VEC2 & projectionCenter,f32 projectionHeight,nw::math::PivotDirection pivotDirection,f32 wScale)194 Utility::CreateFrustumCamera(
195     os::IAllocator* allocator,
196     const nw::math::VEC3& cameraPosition,
197     const nw::math::VEC3& targetPosition,
198     f32 nearClip,
199     f32 farClip,
200     const nw::math::VEC2& projectionCenter,
201     f32 projectionHeight,
202     nw::math::PivotDirection pivotDirection,
203     f32 wScale
204 )
205 {
206     NW_POINTER_ASSERT(allocator);
207 
208     nw::gfx::LookAtTargetViewUpdater* viewUpdater =
209         nw::gfx::LookAtTargetViewUpdater::Create(allocator);
210     NW_POINTER_ASSERT(viewUpdater);
211 
212     nw::gfx::ResLookAtTargetViewUpdater resViewUpdater =
213         nw::gfx::ResStaticCast<nw::gfx::ResLookAtTargetViewUpdater>(viewUpdater->GetResource());
214 
215     resViewUpdater.SetTargetPosition(targetPosition);
216     resViewUpdater.SetUpwardVector(0.0f,1.0f,0.0f);
217 
218     nw::gfx::FrustumProjectionUpdater* projectionUpdater =
219         nw::gfx::FrustumProjectionUpdater::Create(allocator);
220     NW_POINTER_ASSERT(projectionUpdater);
221 
222     projectionUpdater->SetPivotDirection(pivotDirection);
223 
224     nw::gfx::ResFrustumProjectionUpdater resProjectionUpdater =
225         nw::gfx::ResStaticCast<nw::gfx::ResFrustumProjectionUpdater>(
226         projectionUpdater->GetResource());
227     resProjectionUpdater.SetNear(nearClip);
228     resProjectionUpdater.SetFar(farClip);
229     nw::gfx::ResProjectionRect rect = resProjectionUpdater.GetRect();
230     rect.m_Center = projectionCenter;
231     rect.m_Height = projectionHeight;
232     resProjectionUpdater.SetRect(rect);
233 
234     nw::gfx::Camera* camera =
235         nw::gfx::Camera::DynamicBuilder()
236         .MaxChildren(0)
237         .MaxCallbacks(0)
238         .ViewUpdater(viewUpdater)
239         .ProjectionUpdater(projectionUpdater)
240         .Create(allocator);
241 
242     NW_POINTER_ASSERT(camera);
243 
244     camera->Transform().SetTranslate(cameraPosition);
245     camera->SetWScale(wScale);
246 
247     return camera;
248 }
249 
250 //----------------------------------------
251 nw::gfx::Camera*
CreateOrthoCamera(os::IAllocator * allocator,const nw::math::VEC3 & cameraPosition,const nw::math::VEC3 & targetPosition,f32 nearClip,f32 farClip,const nw::math::VEC2 & projectionCenter,f32 projectionHeight,nw::math::PivotDirection pivotDirection,f32 wScale)252 Utility::CreateOrthoCamera(
253     os::IAllocator* allocator,
254     const nw::math::VEC3& cameraPosition,
255     const nw::math::VEC3& targetPosition,
256     f32 nearClip,
257     f32 farClip,
258     const nw::math::VEC2& projectionCenter,
259     f32 projectionHeight,
260     nw::math::PivotDirection pivotDirection,
261     f32 wScale
262 )
263 {
264     NW_POINTER_ASSERT(allocator);
265 
266     nw::gfx::LookAtTargetViewUpdater* viewUpdater =
267         nw::gfx::LookAtTargetViewUpdater::Create(allocator);
268     NW_POINTER_ASSERT(viewUpdater);
269 
270     nw::gfx::ResLookAtTargetViewUpdater resViewUpdater =
271         nw::gfx::ResStaticCast<nw::gfx::ResLookAtTargetViewUpdater>(viewUpdater->GetResource());
272 
273     resViewUpdater.SetTargetPosition(targetPosition);
274     resViewUpdater.SetUpwardVector(0.0f,1.0f,0.0f);
275 
276     nw::gfx::OrthoProjectionUpdater* projectionUpdater =
277         nw::gfx::OrthoProjectionUpdater::Create(allocator);
278     NW_POINTER_ASSERT(projectionUpdater);
279 
280     projectionUpdater->SetPivotDirection(pivotDirection);
281 
282     nw::gfx::ResOrthoProjectionUpdater resProjectionUpdater =
283         nw::gfx::ResStaticCast<nw::gfx::ResOrthoProjectionUpdater>(
284         projectionUpdater->GetResource());
285     resProjectionUpdater.SetNear(nearClip);
286     resProjectionUpdater.SetFar(farClip);
287     nw::gfx::ResProjectionRect rect = resProjectionUpdater.GetRect();
288     rect.m_Center = projectionCenter;
289     rect.m_Height = projectionHeight;
290     resProjectionUpdater.SetRect(rect);
291 
292     nw::gfx::Camera* camera =
293         nw::gfx::Camera::DynamicBuilder()
294         .MaxChildren(0)
295         .MaxCallbacks(0)
296         .ViewUpdater(viewUpdater)
297         .ProjectionUpdater(projectionUpdater)
298         .Create(allocator);
299 
300     NW_POINTER_ASSERT(camera);
301 
302     camera->Transform().SetTranslate(cameraPosition);
303     camera->SetWScale(wScale);
304 
305     return camera;
306 }
307 
308 //----------------------------------------
309 void
CreateStereoCameras(nw::gfx::Camera ** ppBaseCamera,nw::gfx::Camera ** ppLeftCamera,nw::gfx::Camera ** ppRightCamera,os::IAllocator * allocator,const nw::math::VEC3 & cameraPosition,const nw::math::VEC3 & targetPosition,f32 nearClip,f32 farClip,f32 fovyRadian,f32 wScale)310 Utility::CreateStereoCameras(
311     nw::gfx::Camera** ppBaseCamera,
312     nw::gfx::Camera** ppLeftCamera,
313     nw::gfx::Camera** ppRightCamera,
314     os::IAllocator* allocator,
315     const nw::math::VEC3& cameraPosition,
316     const nw::math::VEC3& targetPosition,
317     f32 nearClip,
318     f32 farClip,
319     f32 fovyRadian,
320     f32 wScale
321 )
322 {
323     NW_POINTER_ASSERT(ppBaseCamera);
324     NW_POINTER_ASSERT(ppLeftCamera);
325     NW_POINTER_ASSERT(ppRightCamera);
326     NW_POINTER_ASSERT(allocator);
327 
328     *ppBaseCamera = nw::demo::Utility::CreateCamera(
329         allocator,
330         cameraPosition,
331         targetPosition,
332         nearClip,
333         farClip,
334         fovyRadian,
335         nw::math::PIVOT_NONE
336     );
337     (*ppBaseCamera)->SetWScale(wScale);
338 
339     *ppLeftCamera =
340         nw::gfx::Camera::DynamicBuilder()
341         .MaxChildren(0)
342         .MaxCallbacks(0)
343         .Create(allocator);
344 
345     NW_POINTER_ASSERT(*ppLeftCamera);
346 
347     (*ppLeftCamera)->SetWScale(wScale);
348 
349     *ppRightCamera =
350         nw::gfx::Camera::DynamicBuilder()
351         .MaxChildren(0)
352         .MaxCallbacks(0)
353         .Create(allocator);
354 
355     NW_POINTER_ASSERT(*ppRightCamera);
356 
357     (*ppRightCamera)->SetWScale(wScale);
358 }
359 
360 
361 //----------------------------------------
362 void
SetCameraAspectRatio(nw::gfx::Camera * camera,f32 aspectRatio)363 Utility::SetCameraAspectRatio(
364     nw::gfx::Camera* camera,
365     f32 aspectRatio
366 )
367 {
368     NW_POINTER_ASSERT(camera);
369 
370     f32 fovy;
371     f32 near;
372     f32 far;
373     camera->GetPerspective(&fovy, NULL, &near, &far);
374 
375     camera->SetPerspective(fovy, aspectRatio, near, far);
376 
377     camera->UpdateCameraMatrix();
378 }
379 
380 //----------------------------------------
381 nw::gfx::IRenderTarget*
CreateUpperScreenBuffer(os::IAllocator * allocator,nw::demo::RenderSystem::Description & renderDescription)382 Utility::CreateUpperScreenBuffer(
383     os::IAllocator* allocator,
384     nw::demo::RenderSystem::Description& renderDescription
385 )
386 {
387     // オンスクリーンバッファは縦と横が逆になっているため、
388     // 幅と高さを逆に設定しています。
389 
390     s32 heigthRatio;
391     s32 widthRatio;
392 
393     switch(renderDescription.upperScreenDescription.transferMode)
394     {
395     case nw::demo::TRANSFER_MODE_ANTIALIASE_NOT_USED:
396         heigthRatio = 1;
397         widthRatio = 1;
398         break;
399     case nw::demo::TRANSFER_MODE_ANTIALIASE_2x1:
400         heigthRatio = 2;
401         widthRatio = 1;
402         break;
403     case nw::demo::TRANSFER_MODE_ANTIALIASE_2x2:
404         heigthRatio = 2;
405         widthRatio = 2;
406         break;
407     default:
408         NW_FATAL_ERROR("Unsupported antialiasing mode\n");
409     }
410 
411     return nw::gfx::IRenderTarget::Builder()
412         .BufferSize(
413             renderDescription.upperScreenDescription.height * heigthRatio,
414             renderDescription.upperScreenDescription.width * widthRatio
415         )
416         .ColorFormat(renderDescription.renderColorFormat)
417         .Create(allocator);
418 }
419 
420 //----------------------------------------
421 nw::gfx::IRenderTarget*
CreateLowerScreenBuffer(os::IAllocator * allocator,nw::demo::RenderSystem::Description & renderDescription)422 Utility::CreateLowerScreenBuffer(
423     os::IAllocator* allocator,
424     nw::demo::RenderSystem::Description& renderDescription
425 )
426 {
427     // オンスクリーンバッファは縦と横が逆になっているため、
428     // 幅と高さを逆に設定しています。
429     return nw::gfx::IRenderTarget::Builder()
430         .BufferSize(
431             renderDescription.lowerScreenDescription.height,
432             renderDescription.lowerScreenDescription.width
433         )
434         .ColorFormat(renderDescription.renderColorFormat)
435         .Create(allocator);
436 }
437 
438 //----------------------------------------
439 nw::gfx::SceneNode*
CreateSceneNode(os::IAllocator * deviceAllocator,nw::gfx::ResSceneObject resource,bool isAnimationEnabled,nw::gfx::Model::BufferOption bufferOption,s32 maxAnimObjects)440 Utility::CreateSceneNode(
441     os::IAllocator* deviceAllocator,
442     nw::gfx::ResSceneObject resource,
443     bool isAnimationEnabled,
444     nw::gfx::Model::BufferOption bufferOption,
445     s32 maxAnimObjects
446 )
447 {
448     nw::gfx::SceneObject* sceneObject = nw::gfx::SceneBuilder()
449         .Resource(resource)
450         .BufferOption(bufferOption)
451         .MaxAnimObjectsPerGroup(maxAnimObjects)
452         .IsAnimationEnabled(isAnimationEnabled)
453         .CreateObject(deviceAllocator, deviceAllocator);
454 
455     nw::gfx::SceneNode* node = nw::ut::DynamicCast<nw::gfx::SceneNode*>(sceneObject);
456 
457     return node;
458 }
459 
460 //----------------------------------------
461 ut::MoveArray<u8>
LoadFile(os::IAllocator * allocator,const wchar_t * filePath,u32 align)462 Utility::LoadFile(
463     os::IAllocator* allocator,
464     const wchar_t* filePath,
465     u32 align /* = 32 */
466 )
467 {
468     nn::fs::FileReader fileReader;
469 
470     nn::Result result = fileReader.TryInitialize(filePath);
471     if (result.IsFailure())
472     {
473         return nw::ut::MoveArray<u8>();
474     }
475     s32 fileSize = static_cast<s32>(fileReader.GetSize());
476 
477     void* memory = allocator->Alloc(fileSize, static_cast<u8>(align));
478     nw::ut::MoveArray<u8> buffer(memory, fileSize, allocator);
479     buffer.resize(fileSize);
480 
481     fileReader.Read(&buffer.front(), fileSize);
482 
483     fileReader.Finalize();
484 
485     // コンテナを返してますが、バッファはコピーされません。
486     // 所有権が移動します。
487     return buffer;
488 }
489 
490 //----------------------------------------
491 nw::gfx::AnimGroup*
GetAnimGroup(nw::gfx::SceneObject * object,AnimationType animationType)492 Utility::GetAnimGroup(
493     nw::gfx::SceneObject* object,
494     AnimationType animationType
495 )
496 {
497     // アニメーショングループを取得します。
498     nw::gfx::AnimGroup* animGroup = NULL;
499 
500     switch (animationType)
501     {
502     case SKELETAL_ANIMATION:
503         {
504             nw::gfx::SkeletalModel* skeletalModel = nw::ut::DynamicCast<nw::gfx::SkeletalModel*>(object);
505             NW_ASSERT(skeletalModel);
506             animGroup = skeletalModel->GetSkeletalAnimGroup();
507         }
508         break;
509     case MATERIAL_ANIMATION:
510         {
511             nw::gfx::Model* model = nw::ut::DynamicCast<nw::gfx::Model*>(object);
512             NW_ASSERT(model);
513             animGroup = model->GetMaterialAnimGroup();
514         }
515         break;
516     case VISIBILITY_ANIMATION:
517         {
518             nw::gfx::Model* model = nw::ut::DynamicCast<nw::gfx::Model*>(object);
519             NW_ASSERT(model);
520             animGroup = model->GetVisibilityAnimGroup();
521         }
522         break;
523     case CAMERA_ANIMATION:
524         {
525             nw::gfx::Camera* camera = nw::ut::DynamicCast<nw::gfx::Camera*>(object);
526             NW_ASSERT(camera);
527             animGroup = camera->GetAnimGroup();
528         }
529         break;
530     case LIGHT_ANIMATION:
531         {
532             nw::gfx::Light* light = nw::ut::DynamicCast<nw::gfx::Light*>(object);
533             NW_ASSERT(light);
534             animGroup = light->GetAnimGroup();
535         }
536         break;
537     default:
538         NW_FATAL_ERROR("Invalid animation type");
539     }
540 
541     return animGroup;
542 }
543 
544 
545 //----------------------------------------
546 bool
InitializeSharedFont(os::IAllocator * allocator,nw::demo::GraphicsDrawing & graphicsDrawing)547 Utility::InitializeSharedFont(
548     os::IAllocator* allocator,
549     nw::demo::GraphicsDrawing&  graphicsDrawing
550 )
551 {
552     if (!s_SharedFontAlreadyInitialized)
553     {
554         nn::pl::Initialize();
555 
556         NN_UTIL_PANIC_IF_FAILED(nn::pl::InitializeSharedFont());
557 
558         // 共有フォントのロードが完了するまで待機します。
559         while (nn::pl::GetSharedFontLoadState() != nn::pl::SHARED_FONT_LOAD_STATE_LOADED &&
560                nn::pl::GetSharedFontLoadState() != nn::pl::SHARED_FONT_LOAD_STATE_FAILED)
561         {
562             NN_LOG("loading SharedFont ...\n");
563             nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(10));
564         }
565         NW_ASSERT(nn::pl::GetSharedFontLoadState() != nn::pl::SHARED_FONT_LOAD_STATE_FAILED);
566 
567         nn::pl::Finalize();
568 
569         s_SharedFontAlreadyInitialized = true;
570     }
571 
572     void* fontBuffer = nn::pl::GetSharedFontAddress();
573     size_t fontSize = nn::pl::GetSharedFontSize();
574 
575     return graphicsDrawing.InitializeFont( allocator, FONT_SHADER_FILE_NAME, fontBuffer, fontSize );
576 }
577 
578 
579 //----------------------------------------
580 bool
BindAnimationObject(nw::gfx::SceneObject * object,nw::gfx::AnimObject * animObject,AnimationType animationType)581 Utility::BindAnimationObject(
582     nw::gfx::SceneObject* object,
583     nw::gfx::AnimObject* animObject,
584     AnimationType animationType
585 )
586 {
587     nw::gfx::AnimGroup* animGroup = GetAnimGroup(object, animationType);
588     if (!animGroup)
589     {
590         return false;
591     }
592 
593     if (animObject->TryBind( animGroup ).IsFailure())
594     {
595         return false;
596     }
597 
598     switch (animationType)
599     {
600     case SKELETAL_ANIMATION:
601         {
602             nw::gfx::SkeletalModel* skeletalModel = nw::ut::DynamicCast<nw::gfx::SkeletalModel*>(object);
603             NW_ASSERT(skeletalModel);
604             skeletalModel->SetSkeletalAnimObject(animObject);
605         }
606         break;
607     case MATERIAL_ANIMATION:
608         {
609             nw::gfx::Model* model = nw::ut::DynamicCast<nw::gfx::Model*>(object);
610             NW_ASSERT(model);
611             model->SetMaterialAnimObject(animObject);
612         }
613         break;
614     case VISIBILITY_ANIMATION:
615         {
616             nw::gfx::Model* model = nw::ut::DynamicCast<nw::gfx::Model*>(object);
617             NW_ASSERT(model);
618             model->SetVisibilityAnimObject(animObject);
619         }
620         break;
621     case CAMERA_ANIMATION:
622         {
623             nw::gfx::Camera* camera = nw::ut::DynamicCast<nw::gfx::Camera*>(object);
624             NW_ASSERT(camera);
625             camera->SetAnimObject(animObject);
626         }
627         break;
628     case LIGHT_ANIMATION:
629         {
630             nw::gfx::Light* light = nw::ut::DynamicCast<nw::gfx::Light*>(object);
631             NW_ASSERT(light);
632             light->SetAnimObject(animObject);
633         }
634         break;
635     default:
636         NW_FATAL_ERROR("Invalid animation type");
637     }
638 
639     return true;
640 }
641 
642 
643 namespace internal {
644 
645 //----------------------------------------
646 bool
IsTerminatingImpl()647 IsTerminatingImpl()
648 {
649     return false;
650 }
651 
652 } // namespace internal
653 
654 } /* namespace demo */
655 } /* namespace nw   */
656