1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     demo_Utility.h
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 #ifndef NW_DEMO_UTILITY_H_
19 #define NW_DEMO_UTILITY_H_
20 
21 #include <nw/types.h>
22 #include <nw/ut/ut_MoveArray.h>
23 #include <nw/demo/demo_GraphicsDrawing.h>
24 #include <nw/demo/demo_GraphicsSystem.h>
25 #include <nw/demo/demo_Pad.h>
26 
27 // ファイル名定義ユーティリティマクロです。
28 #define NW_DEMO_FILE_PATH(name) (L"rom:/" name)
29 
30 
31 namespace nw
32 {
33 
34 namespace demo
35 {
36 
37 namespace internal
38 {
39     bool IsTerminatingImpl();
40 } // namespace internal
41 
42 //============================================================================
43 //! @name ユーティリティ
44 //@{
45 
46 //---------------------------------------------------------------------------
47 //! @brief        デモに使用するユーティリティ関数をまとめたクラスです。
48 //---------------------------------------------------------------------------
49 class Utility
50 {
51 public:
52     static const nw::math::VEC3 CAMERA_POSITION; //!< カメラ位置のデフォルト値です。
53     static const nw::math::VEC3 TARGET_POSITION; //!< カメラターゲットのデフォルト値です。
54     static const f32 NEAR_CLIP; //!< ニアクリップのデフォルト値です。
55     static const f32 FAR_CLIP; //!< ファークリップのデフォルト値です。
56     static const f32 FOVY_RADIAN; //!< FOVのY方向のデフォルト値です。
57     static const nw::math::VEC2 PROJECTION_CENTER; //!< カメラの投影面の中心位置です。
58     static const f32 PROJECTION_HEIGHT; //!< カメラの投影面の高さです。
59 
60     //---------------------------------------------------------------------------
61     //! @brief        アニメーションの種類を表します。
62     //---------------------------------------------------------------------------
63     enum AnimationType {
64         SKELETAL_ANIMATION,       //!< スケルタルアニメーションを表します。
65         MATERIAL_ANIMATION,       //!< マテリアルアニメーションを表します。
66         VISIBILITY_ANIMATION,     //!< ビジビリティアニメーションを表します。
67         CAMERA_ANIMATION,         //!< カメラアニメーションを表します。
68         LIGHT_ANIMATION,          //!< ライトアニメーションを表します。
69         FOG_ANIMATION             //!< フォグアニメーションを表します。
70     };
71 
72     //=====================
73     //! @name 初期化
74     //@{
75 
76     //---------------------------------------------------------------------------
77     //! @brief        GraphicsDrawing の初期化を行います。
78     //!
79     //! @param[in]    allocator       アロケータです。
80     //! @param[in]    graphicsDrawing 初期化を行う GraphicsDrawing です。
81     //---------------------------------------------------------------------------
82     static void InitializeGraphicsDrawing(
83         os::IAllocator* allocator,
84         nw::demo::GraphicsDrawing&  graphicsDrawing
85     );
86 
87     //@}
88 
89     //=====================
90     //! @name ファイル
91     //@{
92 
93     //---------------------------------------------------------------------------
94     //! @brief        ファイルをロードします。
95     //!
96     //! @param[in]    allocator   アロケータです。
97     //! @param[in]    filePath    ファイルのパス名です。
98     //! @param[in]    align       アライメントです。
99     //!
100     //! @return       ロードしたファイルのバッファを返します。
101     //---------------------------------------------------------------------------
102     static ut::MoveArray<u8> LoadFile(
103         os::IAllocator* allocator,
104         const wchar_t* filePath,
105         u32 align = 32
106     );
107 
108     //---------------------------------------------------------------------------
109     //! @brief        グラフィックスリソースをロードします。
110     //!
111     //! @param[in]    resourceArray 追加を行うリソースの配列です。
112     //! @param[in]    resourcePath ファイルのパス名
113     //! @param[in]    allocator アロケータです。
114     //!
115     //! @return       ロードしたグラフィックス情報を返します。
116     //---------------------------------------------------------------------------
117     static ResourceSet*
118     LoadResources(ResourceArray& resourceArray, const wchar_t* resourcePath, os::IAllocator* allocator);
119 
120     //@}
121 
122     //=====================
123     //! @name カメラ
124     //@{
125 
126     //---------------------------------------------------------------------------
127     //! @brief        カメラを生成します。
128     //!
129     //! @param[in]    allocator 生成に使用するアロケーターです。
130     //! @param[in]    cameraPosition カメラの位置座標です。
131     //! @param[in]    targetPosition カメラターゲットの座標です。
132     //! @param[in]    nearClip ニアクリップの値です。
133     //! @param[in]    farClip ファークリップの値です。
134     //! @param[in]    fovyRadian FOVのY方向の値です。
135     //! @param[in]    pivotDirection 画面の上方向です。
136     //! @param[in]    wScale wScale の値です。
137     //!
138     //! @return       生成したカメラを返します。
139     //---------------------------------------------------------------------------
140     static nw::gfx::Camera* CreateCamera(
141         os::IAllocator* allocator,
142         const nw::math::VEC3& cameraPosition = CAMERA_POSITION,
143         const nw::math::VEC3& targetPosition = TARGET_POSITION,
144         f32 nearClip = NEAR_CLIP,
145         f32 farClip = FAR_CLIP,
146         f32 fovyRadian = FOVY_RADIAN,
147         nw::math::PivotDirection pivotDirection = nw::math::PIVOT_UPSIDE_TO_TOP,
148         f32 wScale = 0.0f
149     );
150 
151     //---------------------------------------------------------------------------
152     //! @brief        カメラを生成します。
153     //!
154     //! @param[in]    allocator 生成に使用するアロケーターです。
155     //! @param[in]    cameraPosition カメラの位置座標です。
156     //! @param[in]    targetPosition カメラターゲットの座標です。
157     //! @param[in]    nearClip ニアクリップの値です。
158     //! @param[in]    farClip ファークリップの値です。
159     //! @param[in]    fovyRadian FOVのY方向の値です。
160     //! @param[in]    pivotDirection 画面の上方向です。
161     //! @param[in]    wScale wScale の値です。
162     //!
163     //! @return       生成したカメラを返します。
164     //---------------------------------------------------------------------------
165     static nw::gfx::Camera* CreateAimCamera(
166         os::IAllocator* allocator,
167         const nw::math::VEC3& cameraPosition = CAMERA_POSITION,
168         const nw::math::VEC3& targetPosition = TARGET_POSITION,
169         f32 nearClip = NEAR_CLIP,
170         f32 farClip = FAR_CLIP,
171         f32 fovyRadian = FOVY_RADIAN,
172         nw::math::PivotDirection pivotDirection = nw::math::PIVOT_UPSIDE_TO_TOP,
173         f32 wScale = 0.0f
174     );
175 
176     //---------------------------------------------------------------------------
177     //! @brief        カメラを生成します。
178     //!
179     //! @param[in]    allocator 生成に使用するアロケーターです。
180     //! @param[in]    cameraPosition カメラの位置座標です。
181     //! @param[in]    targetPosition カメラターゲットの座標です。
182     //! @param[in]    nearClip ニアクリップの値です。
183     //! @param[in]    farClip ファークリップの値です。
184     //! @param[in]    projectionCenter 投影面の中心位置です。
185     //! @param[in]    projectionHeight 投影面の高さです。
186     //! @param[in]    pivotDirection 画面の上方向です。
187     //! @param[in]    wScale wScale の値です。
188     //!
189     //! @return       生成したカメラを返します。
190     //---------------------------------------------------------------------------
191     static nw::gfx::Camera* CreateFrustumCamera(
192         os::IAllocator* allocator,
193         const nw::math::VEC3& cameraPosition = CAMERA_POSITION,
194         const nw::math::VEC3& targetPosition = TARGET_POSITION,
195         f32 nearClip = NEAR_CLIP,
196         f32 farClip = FAR_CLIP,
197         const nw::math::VEC2& projectionCenter = PROJECTION_CENTER,
198         f32 projectionHeight = PROJECTION_HEIGHT,
199         nw::math::PivotDirection pivotDirection = nw::math::PIVOT_UPSIDE_TO_TOP,
200         f32 wScale = 0.0f
201     );
202 
203     //---------------------------------------------------------------------------
204     //! @brief        カメラを生成します。
205     //!
206     //! @param[in]    allocator 生成に使用するアロケーターです。
207     //! @param[in]    cameraPosition カメラの位置座標です。
208     //! @param[in]    targetPosition カメラターゲットの座標です。
209     //! @param[in]    nearClip ニアクリップの値です。
210     //! @param[in]    farClip ファークリップの値です。
211     //! @param[in]    projectionCenter 投影面の中心位置です。
212     //! @param[in]    projectionHeight 投影面の高さです。
213     //! @param[in]    pivotDirection 画面の上方向です。
214     //! @param[in]    wScale wScale の値です。
215     //!
216     //! @return       生成したカメラを返します。
217     //---------------------------------------------------------------------------
218     static nw::gfx::Camera* CreateOrthoCamera(
219         os::IAllocator* allocator,
220         const nw::math::VEC3& cameraPosition = CAMERA_POSITION,
221         const nw::math::VEC3& targetPosition = TARGET_POSITION,
222         f32 nearClip = NEAR_CLIP,
223         f32 farClip = FAR_CLIP,
224         const nw::math::VEC2& projectionCenter = PROJECTION_CENTER,
225         f32 projectionHeight = PROJECTION_HEIGHT,
226         nw::math::PivotDirection pivotDirection = nw::math::PIVOT_UPSIDE_TO_TOP,
227         f32 wScale = 0.0f
228     );
229 
230 
231 
232     // TODO: 「ベースカメラ」という表現が適切かどうかを確認する。
233     //---------------------------------------------------------------------------
234     //! @brief        立体視に使用するベースカメラと左右カメラを生成します。
235     //!
236     //!               実際は右目用カメラと左目用カメラの区別はありません。
237     //!
238     //! @param[out]   ppBaseCamera 生成したベースカメラを返すためのポインタです。
239     //! @param[out]   ppLeftCamera 生成した右目用カメラを返すためのポインタです。
240     //! @param[out]   ppRightCamera 生成した左目用カメラを返すためのポインタです。
241     //! @param[in]    allocator 生成に使用するアロケーターです。
242     //! @param[in]    cameraPosition カメラの位置座標です。
243     //! @param[in]    targetPosition カメラターゲットの座標です。
244     //! @param[in]    nearClip ニアクリップの値です。
245     //! @param[in]    farClip ファークリップの値です。
246     //! @param[in]    fovyRadian FOVのY方向の値です。
247     //! @param[in]    wScale wScale の値です。
248     //---------------------------------------------------------------------------
249     static void CreateStereoCameras(
250         nw::gfx::Camera** ppBaseCamera,
251         nw::gfx::Camera** ppLeftCamera,
252         nw::gfx::Camera** ppRightCamera,
253         os::IAllocator* allocator,
254         const nw::math::VEC3& cameraPosition = CAMERA_POSITION,
255         const nw::math::VEC3& targetPosition = TARGET_POSITION,
256         f32 nearClip = NEAR_CLIP,
257         f32 farClip = FAR_CLIP,
258         f32 fovyRadian = FOVY_RADIAN,
259         f32 wScale = 0.0f
260     );
261 
262     //---------------------------------------------------------------------------
263     //! @brief        カメラのアスペクト比を設定します。
264     //!
265     //!               指定したレンダーターゲットに合うように設定されます。
266     //!               カメラがアタッチされているシーンを更新してから実行する必要があります。
267     //!
268     //! @param[in]    camera 設定するカメラです。
269     //! @param[in]    renderTarget アスペクト比を合わせるレンダーターゲットです。
270     //---------------------------------------------------------------------------
SetCameraAspectRatio(nw::gfx::Camera * camera,const nw::gfx::IRenderTarget * renderTarget)271     static void SetCameraAspectRatio(
272         nw::gfx::Camera* camera,
273         const nw::gfx::IRenderTarget* renderTarget
274     )
275     {
276         NW_POINTER_ASSERT(renderTarget);
277         // オンスクリーンバッファは縦と横が逆になっているため、
278         // 幅と高さを逆にしてアスペクト比を求めています。
279         SetCameraAspectRatio(
280             camera,
281             static_cast<f32>(renderTarget->GetDescription().height) /
282                 static_cast<f32>(renderTarget->GetDescription().width)
283         );
284     }
285 
286     //---------------------------------------------------------------------------
287     //! @brief        カメラのアスペクト比を設定します。
288     //!
289     //!               カメラがアタッチされているシーンを更新してから実行する必要があります。
290     //!
291     //! @param[in]    camera 設定するカメラです。
292     //! @param[in]    aspectRatio アスペクト比です。
293     //---------------------------------------------------------------------------
294     static void SetCameraAspectRatio(
295         nw::gfx::Camera* camera,
296         f32 aspectRatio
297     );
298 
299     //@}
300 
301     //=====================
302     //! @name スクリーンバッファの生成
303     //@{
304 
305 
306     //---------------------------------------------------------------------------
307     //! @brief        上画面用のスクリーンバッファを生成します。
308     //!
309     //!               レンダーシステムの設定をもとにバッファサイズなどが決定されます。
310     //!
311     //! @param[in]    allocator 生成に使用するアロケーターです。
312     //! @param[in]    renderDescription レンダーシステムの設定です。
313     //!
314     //! @return       生成したスクリーンバッファを返します。
315     //---------------------------------------------------------------------------
316 
317     static nw::gfx::IRenderTarget* CreateUpperScreenBuffer(
318         os::IAllocator* allocator,
319         nw::demo::RenderSystem::Description& renderDescription
320     );
321 
322     //---------------------------------------------------------------------------
323     //! @brief        下画面用のスクリーンバッファを生成します。
324     //!
325     //!               レンダーシステムの設定をもとにバッファサイズなどが決定されます。
326     //!
327     //! @param[in]    allocator 生成に使用するアロケーターです。
328     //! @param[in]    renderDescription レンダーシステムの設定です。
329     //!
330     //! @return       生成したスクリーンバッファを返します。
331     //---------------------------------------------------------------------------
332 
333     static nw::gfx::IRenderTarget* CreateLowerScreenBuffer(
334         os::IAllocator* allocator,
335         nw::demo::RenderSystem::Description& renderDescription
336     );
337 
338     //@}
339 
340     //=====================
341     //! @name シーンノード関連
342     //@{
343 
344     //---------------------------------------------------------------------------
345     //! @brief        シーンオブジェクトのリソースからシーンノードのインスタンスを生成します。
346     //!
347     //! @param[in]    deviceAllocator 生成に使用するデバイスメモリのアロケーターです。
348     //! @param[in]    resource シーンオブジェクトのリソースです。
349     //! @param[in]    isAnimationEnabled アニメーションが有効かどうかを指定します。
350     //! @param[in]    bufferOption バッファの種類です。
351     //! @param[in]    maxAnimObjects AnimBindingが持てるAnimGroupごとのAnimObjectの最大数です。
352     //!
353     //! @return       生成したインスタンスを返します。
354     //---------------------------------------------------------------------------
355     static nw::gfx::SceneNode* CreateSceneNode(
356         os::IAllocator* deviceAllocator,
357         nw::gfx::ResSceneObject resource,
358         bool isAnimationEnabled = true,
359         nw::gfx::Model::BufferOption bufferOption = nw::gfx::Model::FLAG_BUFFER_NOT_USE,
360         s32 maxAnimObjects = 1
361     );
362 
363     //---------------------------------------------------------------------------
364     //! @brief          指定した名前のシーンオブジェクトを検索します。
365     //!
366     //!                 コレクションから指定した名前のシーンオブジェクトを探します。
367     //!                 線形探索を行っていますので、要素数の大きなコレクションを対象にする場合は注意が必要です。
368     //!
369     //!                 見つからなければ NULL を返します。
370     //!                 また、同じ名前のオブジェクトが複数存在する場合、最初に見つかったオブジェクトを返します。
371     //!
372     //! @param[in]      objects シーンオブジェクトのコレクションです。
373     //! @param[in]      objectName シーンオブジェクトの名前です。
374     //!
375     //! @return         見つかったシーンオブジェクトを返します。
376     //---------------------------------------------------------------------------
377     template <class TObjectArray>
FindObjectByName(TObjectArray & objects,const char * objectName)378     static nw::gfx::SceneObject* FindObjectByName(
379         TObjectArray& objects,
380         const char* objectName
381     )
382     {
383         // 指定した名前を持つシーンオブジェクトを探します。
384         nw::gfx::SceneObject* targetObject = NULL;
385 
386         typename TObjectArray::iterator objEnd = objects.end();
387         for (typename TObjectArray::iterator obj = objects.begin(); obj != objEnd; ++obj)
388         {
389             if (std::strcmp(objectName, (*obj)->GetName()) == 0)
390             {
391                 targetObject = *obj;
392                 break;
393             }
394         }
395 
396         return targetObject;
397     }
398 
399     //@}
400 
401     //=====================
402     //! @name アニメーション
403     //@{
404 
405     //---------------------------------------------------------------------------
406     //! @brief          指定した名前のアニメーションリソースを検索します。
407     //!
408     //!                 コレクションから指定した名前と種類のアニメーションリソースを探します。
409     //!                 コレクションの線形探索を行っていますので、要素数の大きなコレクションを対象にする場合は注意が必要です。
410     //!
411     //!                 見つからなければ無効なリソースを返しますので、IsValid() 関数で戻り値をチェックしてください。
412     //!                 また、同じ名前のリソースが複数存在する場合、最初に見つかったリソースを返します。
413     //!
414     //! @param[in]      resources アニメーションリソースのコレクションです。
415     //! @param[in]      animationName アニメーションリソースの名前です。
416     //! @param[in]      animationType アニメーションの種類です。
417     //!
418     //! @return         見つかったアニメーションリソースを返します。
419     //---------------------------------------------------------------------------
420     template <class TResArray>
FindResAnimByName(TResArray & resources,const char * animationName,AnimationType animationType)421     static nw::anim::ResAnim FindResAnimByName(
422         TResArray& resources,
423         const char* animationName,
424         AnimationType animationType
425     )
426     {
427         nw::anim::ResAnim resAnim;
428 
429         typename TResArray::iterator resEnd = resources.end();
430         for (typename TResArray::iterator res = resources.begin(); res != resEnd; ++res)
431         {
432             switch (animationType)
433             {
434             case SKELETAL_ANIMATION:
435                 resAnim = res->GetSkeletalAnims(animationName);
436                 break;
437             case MATERIAL_ANIMATION:
438                 resAnim = res->GetMaterialAnims(animationName);
439                 break;
440             case VISIBILITY_ANIMATION:
441                 resAnim = res->GetVisibilityAnims(animationName);
442                 break;
443             case CAMERA_ANIMATION:
444                 resAnim = res->GetCameraAnims(animationName);
445                 break;
446             case LIGHT_ANIMATION:
447                 resAnim = res->GetLightAnims(animationName);
448                 break;
449             default:
450                 NW_FATAL_ERROR("Invalid animation type");
451             }
452 
453             if (resAnim.IsValid())
454             {
455                 break;
456             }
457         }
458 
459         return resAnim;
460     }
461 
462 
463     //---------------------------------------------------------------------------
464     //! @brief          アニメーションをバインドします。
465     //!
466     //!                 アニメーションオブジェクトを生成し、指定したシーンオブジェクトとバインドします。
467     //!
468     //!                 シーンオブジェクトに指定した種類のアニメーショングループが存在しない場合や、
469     //!                 バインドに失敗した場合にこの関数は失敗し、NULL を返します。
470     //!
471     //!                 生成されるアニメーションオブジェクトは、
472     //!                 スケルタルアニメーションの場合は nw::gfx::TransformAnimEvaluator 、
473     //!                 その他の場合は nw::gfx::AnimEvaluator です。
474     //!
475     //! @param[in]      allocator アニメーションオブジェクトの生成に使用するアロケータです。
476     //! @param[in]      object シーンオブジェクトです。
477     //! @param[in]      resAnim アニメーションデータを持つアニメーションリソースです。
478     //! @param[in]      animationType アニメーションの種類です。
479     //! @param[in]      allocCache キャッシュバッファを確保してキャッシュを有効にするかどうかを設定します。
480     //!
481     //! @return         生成したアニメーションオブジェクトを返します。
482     //!
483     //! @sa             BindAnimationByName
484     //! @sa             nw::gfx::AnimObject::Bind
485     //! @sa             nw::gfx::SkeletalModel::SetSkeletalAnimObject
486     //! @sa             nw::gfx::Model::SetMaterialAnimObject
487     //! @sa             nw::gfx::Model::SetVisibilityAnimObject
488     //! @sa             nw::gfx::Camera::SetAnimObject
489     //! @sa             nw::gfx::Light::SetAnimObject
490     //---------------------------------------------------------------------------
BindAnimation(os::IAllocator * allocator,nw::gfx::SceneObject * object,nw::anim::ResAnim resAnim,AnimationType animationType,bool allocCache)491     static nw::gfx::BaseAnimEvaluator* BindAnimation(
492         os::IAllocator* allocator,
493         nw::gfx::SceneObject* object,
494         nw::anim::ResAnim resAnim,
495         AnimationType animationType,
496         bool allocCache
497     )
498     {
499         // アニメーショングループを取得します。
500         nw::gfx::AnimGroup* animGroup = GetAnimGroup(object, animationType);
501         if (!animGroup)
502         {
503             NW_LOG("BindAnimation() : Specified type animation group not found\n");
504             return NULL;
505         }
506 
507         // アニメーションオブジェクトを生成します。
508         nw::gfx::BaseAnimEvaluator* animObject;
509         if (animationType == SKELETAL_ANIMATION)
510         {
511             animObject = nw::gfx::TransformAnimEvaluator::Builder()
512                 .AnimData(resAnim)
513                 .MaxMembers(animGroup->GetMemberCount())
514                 .MaxAnimMembers(resAnim.GetMemberAnimSetCount())
515                 .AllocCache(allocCache)
516                 .Create(allocator);
517         }
518         else
519         {
520             animObject = nw::gfx::AnimEvaluator::Builder()
521                 .AnimData(resAnim)
522                 .MaxMembers(animGroup->GetMemberCount())
523                 .MaxAnimMembers(resAnim.GetMemberAnimSetCount())
524                 .AllocCache(allocCache)
525                 .Create(allocator);
526         }
527         NW_NULL_ASSERT(animObject);
528 
529         // スケルタルアニメーションであればであれば
530         // 移動アニメーションの無効化フラグを設定します。
531         if (animationType == SKELETAL_ANIMATION)
532         {
533             nw::gfx::SkeletalModel* skeletalModel =
534                 nw::ut::DynamicCast<nw::gfx::SkeletalModel*>(object);
535             nw::gfx::ResSkeleton resSkeleton = skeletalModel->GetSkeleton()->GetResSkeleton();
536             const bool translateAnimEnabled = nw::ut::CheckFlag(
537                 resSkeleton.GetFlags(),
538                 nw::gfx::ResSkeletonData::FLAG_TRANSLATE_ANIMATION_ENABLED
539             );
540             reinterpret_cast<nw::gfx::TransformAnimEvaluator*>(animObject)
541                 ->SetIsTranslateDisabled(!translateAnimEnabled);
542         }
543 
544         // アニメーションオブジェクトとシーンオブジェクトをバインドします。
545         if (!BindAnimationObject(object, animObject, animationType))
546         {
547 
548             NW_LOG("BindAnimation() : Failed to bind animation object\n");
549             nw::ut::SafeDestroy(animObject);
550             return NULL;
551         }
552 
553         return animObject;
554     }
555 
556 
557     //---------------------------------------------------------------------------
558     //! @brief          アニメーションブレンダーをバインドします。
559     //!
560     //!                 アニメーションブレンダーオブジェクトを生成し、指定したシーンオブジェクトとバインドします。
561     //!
562     //!                 シーンオブジェクトに指定した種類のアニメーショングループが存在しない場合や、
563     //!                 バインドに失敗した場合にこの関数は失敗し、NULL を返します。
564     //!
565     //! @tparam         TAnimObject  生成するアニメーションオブジェクトクラスです。
566     //! @param[in]      allocator アニメーションオブジェクトの生成に使用するアロケータです。
567     //! @param[in]      object シーンオブジェクトです。
568     //! @param[in]      maxAnimObjects 生成するブレンダーの最大アニメーションオブジェクト数です。
569     //! @param[in]      animationType アニメーションの種類です。
570     //!
571     //! @return         生成したアニメーションブレンダーオブジェクトを返します。
572     //!
573     //! @sa             BindAnimation
574     //! @sa             BindAnimationByName
575     //---------------------------------------------------------------------------
576     template <typename TAnimObject>
BindAnimationBlender(os::IAllocator * allocator,nw::gfx::SceneObject * object,int maxAnimObjects,AnimationType animationType)577     static TAnimObject* BindAnimationBlender(
578         os::IAllocator* allocator,
579         nw::gfx::SceneObject* object,
580         int maxAnimObjects,
581         AnimationType animationType
582     )
583     {
584         // アニメーショングループを取得します。
585         nw::gfx::AnimGroup* animGroup = GetAnimGroup(object, animationType);
586         if (!animGroup)
587         {
588             NW_LOG("BindAnimationBlender() : Specified type animation group not found\n");
589             return NULL;
590         }
591 
592         // アニメーションオブジェクトを生成します。
593         TAnimObject* animObject = TAnimObject::Builder()
594             .MaxAnimObjects(maxAnimObjects)
595             .Create(allocator);
596         NW_NULL_ASSERT(animObject);
597 
598 
599         // アニメーションオブジェクトとシーンオブジェクトをバインドします。
600         if (!BindAnimationObject(object, animObject, animationType))
601         {
602             NW_LOG("BindAnimationBlender() : Failed to bind animation object\n");
603             nw::ut::SafeDestroy(animObject);
604             return NULL;
605         }
606 
607         return animObject;
608     }
609 
610     //---------------------------------------------------------------------------
611     //! @brief          名前を指定してアニメーションをバインドします。
612     //!
613     //!                 指定した名前のオブジェクトとアニメーションデータを探してバインドします。
614     //!                 指定した名前のオブジェクトやアニメーションデータが見つからない場合や、
615     //!                 オブジェクトに指定した種類のアニメーショングループが存在しない場合、
616     //!                 バインドに失敗した場合にこの関数は失敗し、 NULL を返します。
617     //!
618     //!                 同じ名前のオブジェクトやアニメーションデータが存在する場合、
619     //!                 一番最初に見つかったものが使用されます。
620     //!
621     //!                 生成されるアニメーションオブジェクトは、
622     //!                 スケルタルアニメーションの場合は nw::gfx::TransformAnimEvaluator 、
623     //!                 その他の場合は nw::gfx::AnimEvaluator です。
624     //!
625     //! @tparam         TObjectArray  シーンオブジェクトのコレクション型です。
626     //! @tparam         TResArray  リソースのコレクション型です。
627     //! @param[in]      allocator アニメーションオブジェクトの生成に使用するアロケータです。
628     //! @param[in]      objects シーンオブジェクトのコレクションです。
629     //! @param[in]      resources リソースのコレクションです。
630     //! @param[in]      objectName オブジェクトの名前です。
631     //! @param[in]      animationName アニメーションデータの名前です。
632     //! @param[in]      animationType アニメーションの種類です。
633     //! @param[in]      allocCache キャッシュバッファを確保してキャッシュを有効にするかどうかを設定します。
634     //!
635     //! @return         生成したアニメーションオブジェクトを返します。
636     //!
637     //! @sa             BindAnimation
638     //! @sa             FindObjectByName
639     //! @sa             FindResAnimByName
640     //---------------------------------------------------------------------------
641     template <class TObjectArray, class TResArray>
BindAnimationByName(os::IAllocator * allocator,TObjectArray & objects,TResArray & resources,const char * objectName,const char * animationName,AnimationType animationType,bool allocCache)642     static nw::gfx::BaseAnimEvaluator* BindAnimationByName(
643         os::IAllocator* allocator,
644         TObjectArray& objects,
645         TResArray& resources,
646         const char* objectName,
647         const char* animationName,
648         AnimationType animationType,
649         bool allocCache
650     )
651     {
652         nw::gfx::SceneObject* targetObject = FindObjectByName(objects, objectName);
653 
654         if (!targetObject)
655         {
656             // 指定した名前のオブジェクトが見つからなかった場合 NULL を返します。
657             NW_LOG("BindAnimationByName() : Specified object not found [%s]\n", objectName);
658             return NULL;
659         }
660 
661 
662         // 指定した名前を持つアニメーションデータを探します。
663         nw::anim::ResAnim resAnim = FindResAnimByName(resources, animationName, animationType);
664 
665         if (!resAnim.IsValid())
666         {
667             // 指定した種類と名前のアニメーションデータが見つからなかった場合 NULL を返します。
668             NW_LOG("BindAnimationByName() : Specified animation resource not found [%s]\n", animationName);
669             return NULL;
670         }
671 
672         // アニメーションをバインドします。
673         nw::gfx::BaseAnimEvaluator* animObject = BindAnimation(
674             allocator,
675             targetObject,
676             resAnim,
677             animationType,
678             allocCache);
679 
680         return animObject;
681     }
682 
683     //---------------------------------------------------------------------------
684     //! @brief          アニメーショングループを取得します。
685     //!
686     //!                 シーンオブジェクトから指定した種類のアニメーショングループを取得します。
687     //!                 取得できない場合は NULL を返します。
688     //!
689     //! @param[in]      object シーンオブジェクトです。
690     //! @param[in]      animationType アニメーションの種類です。
691     //!
692     //! @return         取得したアニメーショングループを返します。
693     //---------------------------------------------------------------------------
694     static nw::gfx::AnimGroup* GetAnimGroup(
695         nw::gfx::SceneObject* object,
696         AnimationType animationType
697     );
698 
699     //@}
700 
701     //=====================
702     //! @name フォント
703     //@{
704 
705     //---------------------------------------------------------------------------
706     //! @brief          共有フォントを初期化します。
707     //!
708     //!                 共有フォントを用いてフォントの初期化を行います。
709     //!
710     //! @param[in]      allocator アロケータです。
711     //! @param[in]      graphicsDrawing 初期化を行う GraphicsDrawing です。
712     //---------------------------------------------------------------------------
713     static bool InitializeSharedFont(
714         os::IAllocator* allocator,
715         nw::demo::GraphicsDrawing&  graphicsDrawing
716     );
717 
718     //@}
719 
720     //=====================
721     //! @name 状態の取得
722     //@{
723 
724     //---------------------------------------------------------------------------
725     //! @brief        デモが終了状態かどうかを取得します。
726     //!
727     //!               NW_DEBUG_CHECK_MEMORY_LEAK マクロが有効な場合は、
728     //!               パッドのスタートボタンでも終了処理をおこなう為に true を返します。
729     //!               この関数はパッドの更新などを行わないので、あらかじめ PadFactory を初期化し、
730     //!               Pad::Update() 関数でパッドの状態を更新しておく必要があります。
731     //!
732     //! @return       終了状態の場合は true、そうでない場合は false を返します。
733     //---------------------------------------------------------------------------
734     static bool
IsTerminating()735     IsTerminating()
736     {
737         #if defined(NW_DEBUG_CHECK_MEMORY_LEAK)
738             nw::demo::Pad* pad = nw::demo::PadFactory::GetPad();
739             if (pad->IsButtonDown(nw::demo::Pad::BUTTON_START))
740             {
741                 return true;
742             }
743         #endif //defined(NW_DEBUG_CHECK_MEMORY_LEAK)
744 
745         return internal::IsTerminatingImpl();
746     }
747 
748     //@}
749 
750 private:
751 
752     //---------------------------------------------------------------------------
753     //! @brief          アニメーションオブジェクトとシーンオブジェクトをバインドします。
754     //!
755     //!                 アニメーションオブジェクトにシーンオブジェクトのアニメーショングループをバインドし、
756     //!                 シーンオブジェクトにアニメーションオブジェクトを設定します。
757     //!
758     //! @param[in]      object シーンオブジェクトです。
759     //! @param[in]      animObject アニメーションオブジェクトです。
760     //! @param[in]      animationType アニメーションの種類です。
761     //!
762     //! @return         成功したら trueを返します。
763     //---------------------------------------------------------------------------
764     static bool BindAnimationObject(
765         nw::gfx::SceneObject* object,
766         nw::gfx::AnimObject* animObject,
767         AnimationType animationType
768     );
769 
770 private:
771     static const wchar_t* FONT_SHADER_FILE_NAME;
772     static const wchar_t* SHAPE_2D_SHADER_FILE_NAME;
773     static bool s_SharedFontAlreadyInitialized;
774 };
775 
776 //@}
777 
778 //============================================================================
779 //! @name パーティクルユーティリティ
780 //@{
781 
782 /*!--------------------------------------------------------------------------*
783   @brief        キャッシュをフラッシュするテストコードです。
784  *---------------------------------------------------------------------------*/
785 class FlushCache
786 {
787 public:
788     //! @brief FulshCache クラスのインスタンスを生成します。
789     //!
790     //! @param[in] allocator 生成に使用するアロケーターです。
Create(nw::demo::DemoAllocator * allocator)791     static FlushCache* Create(nw::demo::DemoAllocator* allocator)
792     {
793         void* memory = allocator->Alloc(sizeof(FlushCache));
794         NW_NULL_ASSERT(memory);
795         return new (memory) FlushCache(allocator);
796     }
797 
798     //! @brief インスタンスを破棄します。
Destroy()799     void Destroy()
800     {
801         nw::os::IAllocator* allocator = m_Allocator;
802         this->~FlushCache();
803         allocator->Free(this);
804     }
805 
806     //! @brief キャッシュをフラッシュします。
807     void
Execute()808     Execute()
809     {
810         if (m_Buffer != NULL)
811         {
812             ::std::memcpy(m_Buffer + BufferSize / 2, m_Buffer, BufferSize / 2);
813         }
814     }
815 
816 private:
817     //! @brief コンストラクタです。
FlushCache(nw::demo::DemoAllocator * allocator)818     FlushCache(nw::demo::DemoAllocator* allocator)
819     {
820         m_Allocator = allocator;
821         m_Buffer = NULL;
822 
823         if (m_Allocator != NULL)
824         {
825             m_Buffer = (u8*)m_Allocator->Alloc(BufferSize);
826             NW_ASSERT(nw::os::IsDeviceMemory(m_Buffer));
827         }
828     }
829 
830     //! @brief デストラクタです。
~FlushCache()831     ~FlushCache()
832     {
833         if (m_Buffer != NULL)
834         {
835             m_Allocator->Free(m_Buffer);
836         }
837     }
838 
839     static const int BufferSize = 16 * 1024 * 2;
840     u8* m_Buffer;
841     nw::demo::DemoAllocator* m_Allocator;
842 };
843 
844 //@}
845 
846 } // namespace demo
847 } // namespace nw
848 
849 #endif // NW_DEMO_UTILITY_H_
850