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