1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_Camera.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: 28677 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NW_GFX_CAMERA_H_
17 #define NW_GFX_CAMERA_H_
18 
19 #include <nw/gfx/gfx_CameraViewUpdater.h>
20 #include <nw/gfx/gfx_CameraProjectionUpdater.h>
21 #include <nw/gfx/gfx_TransformNode.h>
22 #include <nw/gfx/gfx_Viewport.h>
23 
24 namespace nw
25 {
26 namespace gfx
27 {
28 
29 //---------------------------------------------------------------------------
30 //! @brief        カメラを表すクラスです。
31 //---------------------------------------------------------------------------
32 class Camera : public TransformNode
33 {
34 private:
35     NW_DISALLOW_COPY_AND_ASSIGN(Camera);
36 
37 public:
38     NW_UT_RUNTIME_TYPEINFO;
39 
40     //! @brief 設定内容です。
41     struct Description : public TransformNode::Description
42     {
43         //! @brief コンストラクタです。
DescriptionDescription44         Description()
45         {}
46     };
47 
48     //----------------------------------------
49     //! @name 作成/破棄
50     //@{
51 
52     //! @brief カメラを動的に構築するためのクラスです。
53     //!
54     //! IsFixedSizeMemory の初期値は true です。false に変更すると、各種最大数の設定は無視されます。
55     class DynamicBuilder
56     {
57     public:
58         //! コンストラクタです。
DynamicBuilder()59         DynamicBuilder() {}
60 
61         //! デストラクタです。
~DynamicBuilder()62         ~DynamicBuilder() {}
63 
64         //! @brief 生成時以外にもメモリを確保するかどうかのフラグを設定します。
65         //!
66         //!        true を指定すると、生成時のみ固定サイズのメモリ確保を行います。
67         //!
68         //!        false を指定すると、生成時以外にも必要に応じて動的にメモリ確保が行われます。
IsFixedSizeMemory(bool isFixedSizeMemory)69         DynamicBuilder& IsFixedSizeMemory(bool isFixedSizeMemory)
70         {
71             m_Description.isFixedSizeMemory = isFixedSizeMemory;
72             return *this;
73         }
74 
75         //! 子の最大数を設定します。
MaxChildren(int maxChildren)76         DynamicBuilder& MaxChildren(int maxChildren)
77         {
78             m_Description.maxChildren = maxChildren;
79             return *this;
80         }
81 
82         //! 管理できるコールバックの最大数を設定します。
MaxCallbacks(int maxCallbacks)83         DynamicBuilder& MaxCallbacks(int maxCallbacks)
84         {
85             m_Description.maxCallbacks = maxCallbacks;
86             return *this;
87         }
88 
89         //! @brief ビューマトリクスを更新するクラスを設定します。
90         //!        所有権が移動しますので Camera を破棄する際に一緒に破棄されます。
ViewUpdater(CameraViewUpdater * viewUpdater)91         DynamicBuilder& ViewUpdater(CameraViewUpdater* viewUpdater) { m_ViewUpdater.Reset(viewUpdater); return *this; }
92 
93         //! @brief プロジェクションマトリクスを更新するクラスを設定します。
94         //!        所有権が移動しますので Camera を破棄する際に一緒に破棄されます。
ProjectionUpdater(CameraProjectionUpdater * projectionUpdater)95         DynamicBuilder& ProjectionUpdater(CameraProjectionUpdater* projectionUpdater) { m_ProjectionUpdater.Reset(projectionUpdater); return *this; }
96 
97         //! @brief        カメラを生成します。
98         //!
99         //! @param[in]    allocator アロケータです。
100         //!
101         //! @return       生成したカメラを返します。
102         //!
103         Camera* Create(os::IAllocator* allocator);
104 
105         //! @brief 生成時に必要なメモリサイズを取得します。
106         //!
107         //! メモリサイズは Builder の設定によって変化します。
108         //! すべての設定が終わった後にこの関数を呼び出してください。
109         //!
110         //! @param[in] alignment 計算に用いるアライメントです。2 のべき乗である必要があります。
111         size_t GetMemorySize(size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) const;
112 
113     private:
114         Camera::Description m_Description;
115         GfxPtr<CameraViewUpdater> m_ViewUpdater;
116         GfxPtr<CameraProjectionUpdater> m_ProjectionUpdater;
117     };
118 
119     //! @brief        リソースからカメラを生成します。
120     //!
121     //! @param[in]    parent 親のノードです。
122     //! @param[in]    resource リソースです。
123     //! @param[in]    description 設定内容です。
124     //! @param[in]    allocator アロケータです。
125     //!
126     //! @return       生成されたカメラです。
127     //!
128     static Camera* Create(
129         SceneNode* parent,
130         ResSceneObject resource,
131         const Camera::Description& description,
132         os::IAllocator* allocator);
133 
134     //! @brief        生成時に必要なメモリサイズを取得します。
135     //!
136     //! @param[in]    resource リソースです。
137     //! @param[in]    description 設定内容です。
138     //! @param[in]    alignment 計算に用いるアライメントです。2 のべき乗である必要があります。
139     static size_t GetMemorySize(
140         ResCamera resource,
141         Description description,
142         size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT
143     )
144     {
145         os::MemorySizeCalculator size(alignment);
146 
147         GetMemorySizeInternal(&size, resource, description);
148 
149         return size.GetSizeWithPadding(alignment);
150     }
151 
152     //! @details :private
153     static void GetMemorySizeInternal(
154         os::MemorySizeCalculator* pSize,
155         ResCamera resource,
156         Description description);
157 
158     //@}
159 
160     //----------------------------------------
161     //! @name シーンツリー
162     //@{
163 
164     //! @brief        ビジターを受け付けます。
165     //!
166     //! @param[in]    visitor ビジターです。
167     //!
168     virtual void Accept(ISceneVisitor* visitor);
169 
170     //@}
171 
172     //----------------------------------------
173     //! @name リソース
174     //@{
175 
176     //! @brief カメラのリソースを取得します。
GetResCamera()177     ResCamera GetResCamera() { return ResStaticCast<ResCamera>(GetResSceneObject()); }
178 
179     //! @brief カメラのリソースを取得します。
GetResCamera()180     const ResCamera GetResCamera() const { return ResStaticCast<ResCamera>(GetResSceneObject()); }
181 
182     //@}
183 
184     //----------------------------------------
185     //! @name カメラマトリクス
186     //@{
187 
188     //! @brief ビューマトリクスとプロジェクションマトリクスを更新します。
189     void UpdateCameraMatrix();
190 
191     //! @brief プロジェクションマトリクスを取得します。
ProjectionMatrix()192     math::MTX44& ProjectionMatrix() { return m_ProjectionMatrix; }
193 
194     //! @brief プロジェクションマトリクスを取得します。
ProjectionMatrix()195     const math::MTX44& ProjectionMatrix() const { return m_ProjectionMatrix; }
196 
197     //! @brief プロジェクションマトリクスの逆行列を取得します。
InverseProjectionMatrix()198     math::MTX44& InverseProjectionMatrix() { return m_InverseProjectionMatrix; }
199 
200     //! @brief プロジェクションマトリクスの逆行列を取得します。
InverseProjectionMatrix()201     const math::MTX44& InverseProjectionMatrix() const { return m_InverseProjectionMatrix; }
202 
203     //! @brief ビューマトリクスを取得します。
ViewMatrix()204     math::MTX34& ViewMatrix() { return m_ViewMatrix; }
205 
206     //! @brief ビューマトリクスを取得します。
ViewMatrix()207     const math::MTX34& ViewMatrix() const { return m_ViewMatrix; }
208 
209     //! @brief ビューマトリクスの逆行列を取得します。
InverseViewMatrix()210     math::MTX34& InverseViewMatrix() { return m_InverseViewMatrix; }
211 
212     //! @brief ビューマトリクスの逆行列を取得します。
InverseViewMatrix()213     const math::MTX34& InverseViewMatrix() const { return m_InverseViewMatrix; }
214 
215     //! @brief プロジェクションテクスチャマッピング用の射影行列を取得します。
TextureProjectionMatrix()216     math::MTX34& TextureProjectionMatrix() { return m_TextureProjectionMatrix; }
217 
218     //! @brief プロジェクションテクスチャマッピング用の射影行列を取得します。
TextureProjectionMatrix()219     const math::MTX34& TextureProjectionMatrix() const { return m_TextureProjectionMatrix; }
220 
221     //@}
222 
223     //----------------------------------------
224     //! @name アップデータ
225     //@{
226 
227     //! @brief ビューマトリクスのアップデータを取得します。
GetViewUpdater()228     CameraViewUpdater* GetViewUpdater() { return this->m_ViewUpdater.Get(); }
229 
230     //! @brief ビューマトリクスのアップデータを取得します。
GetViewUpdater()231     const CameraViewUpdater* GetViewUpdater() const { return this->m_ViewUpdater.Get(); }
232 
233     //! @brief ビューマトリクスのアップデータを設定します。
SetViewUpdater(CameraViewUpdater * viewUpdater)234     void SetViewUpdater(CameraViewUpdater* viewUpdater) { this->m_ViewUpdater.Reset(viewUpdater); }
235 
236     //! @brief ビューマトリクスのアップデータを変更します。
237     //!        既に設定されているビューマトリクスのアップデータは破棄されずに戻り値として帰ります。
238     //!
239     //! @param[in] viewUpdater 変更するビューマトリクスのアップデータです。
240     //!
241     //! @return 元々設定されていたビューマトリクスのアップデータです。
242     //!
SwapViewUpdater(CameraViewUpdater * viewUpdater)243     CameraViewUpdater* SwapViewUpdater(CameraViewUpdater* viewUpdater)
244     {
245         NW_NULL_ASSERT(viewUpdater);
246         CameraViewUpdater* cameraViewUpdater = this->m_ViewUpdater.Release();
247         this->m_ViewUpdater.Reset(viewUpdater);
248         return cameraViewUpdater;
249     }
250 
251     //! @brief プロジェクションマトリクスのアップデータを取得します。
GetProjectionUpdater()252     CameraProjectionUpdater* GetProjectionUpdater() { return this->m_ProjectionUpdater.Get(); }
253 
254     //! @brief プロジェクションマトリクスのアップデータを取得します。
GetProjectionUpdater()255     const CameraProjectionUpdater* GetProjectionUpdater() const { return this->m_ProjectionUpdater.Get(); }
256 
257     //! @brief プロジェクションマトリクスのアップデータを設定します。
SetProjectionUpdater(CameraProjectionUpdater * projectionUpdater)258     void SetProjectionUpdater(CameraProjectionUpdater* projectionUpdater) { this->m_ProjectionUpdater.Reset(projectionUpdater); }
259 
260 
261     //! @brief プロジェクションマトリクスのアップデータを変更します。
262     //!        既に設定されているプロジェクションマトリクスのアップデータは破棄されずに戻り値として帰ります。
263     //!
264     //! @param[in] viewUpdater 変更するプロジェクションマトリクスのアップデータです。
265     //!
266     //! @return 元々設定されていたプロジェクションマトリクスのアップデータです。
267     //!
SwapProjectionUpdater(CameraProjectionUpdater * projectionUpdater)268     CameraProjectionUpdater* SwapProjectionUpdater(CameraProjectionUpdater* projectionUpdater)
269     {
270         NW_NULL_ASSERT(projectionUpdater);
271         CameraProjectionUpdater* cameraProjectionUpdater = this->m_ProjectionUpdater.Release();
272         this->m_ProjectionUpdater.Reset(projectionUpdater);
273         return cameraProjectionUpdater;
274     }
275 
276     //@}
277 
278     //----------------------------------------
279     //! @name WScale
280     //@{
281 
282     //! @brief WScaleを取得します。
GetWScale()283     f32 GetWScale() const { return this->m_WScale; }
284 
285     //! @brief WScaleを設定します。
SetWScale(f32 wScale)286     void SetWScale(f32 wScale) { m_WScale = wScale; }
287 
288     //@}
289 
290     //----------------------------------------
291     //! @name アニメーション
292     //@{
293 
294     //! @brief アニメーショングループを取得します。
295     //!
296     //! カメラを DynamicBuilder で生成した場合は NULL を返します。
297     //! その場合、アニメーションは設定できません。
GetAnimGroup()298     AnimGroup* GetAnimGroup() { return m_AnimGroup; }
299 
300     //! @brief アニメーショングループを取得します。
301     //!
302     //! カメラを DynamicBuilder で生成した場合は NULL を返します。
303     //! その場合、アニメーションは設定できません。
GetAnimGroup()304     const AnimGroup* GetAnimGroup() const { return m_AnimGroup; }
305 
306     //! @brief アニメーションオブジェクトを取得します。
GetAnimObject()307     AnimObject* GetAnimObject()
308     {
309         NW_NULL_ASSERT(m_AnimBinding);
310         return m_AnimBinding->GetAnimObject(0);
311     }
312 
313     //! @brief アニメーションオブジェクトを取得します。
GetAnimObject()314     const AnimObject* GetAnimObject() const
315     {
316         NW_NULL_ASSERT(m_AnimBinding);
317         return m_AnimBinding->GetAnimObject(0);
318     }
319 
320     //! @brief アニメーションオブジェクトを設定します。
321     //!
322     //! @param[in] animObject 設定するアニメーションオブジェクトです。NULL を指定するとアニメーションを解除します。
SetAnimObject(AnimObject * animObject)323     void SetAnimObject(AnimObject* animObject)
324     {
325         NW_NULL_ASSERT(m_AnimBinding);
326         NW_FAILSAFE_IF(!ValidateCameraAnimType(animObject))
327         {
328             NW_LOG("type mismatch between Camera and Animation. Animation did not set.\n");
329             return;
330         }
331         m_AnimBinding->SetAnimObject(0, animObject);
332     }
333 
334     //@}
335 
336     //----------------------------------------
337     //! @name ビューアップデータ ユーティリティ関数
338     //@{
339 
340     //---------------------------------------------------------------------------
341     //! @brief        設定されているビューアップデータのターゲット座標を取得します。
342     //!
343     //!               この関数はパラメータを簡単に取得するためのユーティリティ関数です。
344     //!               設定されているビューアップデータがAimカメラ用かLookAtカメラ用でなかった場合、プログラムは停止しますので注意してください。
345     //!
346     //! @return       ターゲット座標ベクトルです。
347     //---------------------------------------------------------------------------
348     const nw::math::VEC3& GetTargetPosition() const;
349 
350     //---------------------------------------------------------------------------
351     //! @brief        設定されているビューアップデータのターゲット座標を設定します。
352     //!
353     //!               この関数はパラメータを簡単に設定するためのユーティリティ関数です。
354     //!               設定されているビューアップデータがAimカメラ用かLookAtカメラ用でなかった場合、プログラムは停止しますので注意してください。
355     //!
356     //! @param[in]    targetPosition ターゲット座標ベクトルです。
357     //---------------------------------------------------------------------------
358     void SetTargetPosition(const nw::math::VEC3& targetPosition);
359 
360     //---------------------------------------------------------------------------
361     //! @brief        設定されているビューアップデータのターゲット座標を設定します。
362     //!
363     //!               この関数はパラメータを簡単に設定するためのユーティリティ関数です。
364     //!               設定されているビューアップデータがAimカメラ用かLookAtカメラ用でなかった場合、プログラムは停止しますので注意してください。
365     //!
366     //! @param[in]    x ターゲットのX座標です。
367     //! @param[in]    y ターゲットのY座標です。
368     //! @param[in]    z ターゲットのZ座標です。
369     //---------------------------------------------------------------------------
SetTargetPosition(f32 x,f32 y,f32 z)370     void SetTargetPosition(f32 x, f32 y, f32 z)
371     {
372         SetTargetPosition(nw::math::VEC3(x, y, z));
373     }
374 
375     //---------------------------------------------------------------------------
376     //! @brief        設定されているビューアップデータのアップベクトルを取得します。
377     //!
378     //!               この関数はパラメータを簡単に取得するためのユーティリティ関数です。
379     //!               設定されているビューアップデータがLookAtカメラ用でなかった場合、プログラムは停止しますので注意してください。
380     //!
381     //! @return       アップベクトルです。
382     //---------------------------------------------------------------------------
383     const nw::math::VEC3& GetUpwardVector() const;
384 
385     //---------------------------------------------------------------------------
386     //! @brief        設定されているビューアップデータのアップベクトルを設定します。
387     //!
388     //!               この関数はパラメータを簡単に設定するためのユーティリティ関数です。
389     //!               設定されているビューアップデータがLookAtカメラ用でなかった場合、プログラムは停止しますので注意してください。
390     //!
391     //! @param[in]    upwardVector アップベクトルです。
392     //---------------------------------------------------------------------------
393     void SetUpwardVector(const nw::math::VEC3& upwardVector);
394 
395     //---------------------------------------------------------------------------
396     //! @brief        設定されているビューアップデータのアップベクトルを設定します。
397     //!
398     //!               この関数はパラメータを簡単に設定するためのユーティリティ関数です。
399     //!               設定されているビューアップデータがLookAtカメラ用でなかった場合、プログラムは停止しますので注意してください。
400     //!
401     //! @param[in]    x アップベクトルのX成分です。
402     //! @param[in]    y アップベクトルのY成分です。
403     //! @param[in]    z アップベクトルのZ成分です。
404     //---------------------------------------------------------------------------
SetUpwardVector(f32 x,f32 y,f32 z)405     void SetUpwardVector(f32 x, f32 y, f32 z)
406     {
407         SetUpwardVector(nw::math::VEC3(x, y, z));
408     }
409 
410     //---------------------------------------------------------------------------
411     //! @brief        設定されているビューアップデータのツイストを取得します。
412     //!
413     //!               この関数はパラメータを簡単に取得するためのユーティリティ関数です。
414     //!               設定されているビューアップデータがAimカメラ用でなかった場合、プログラムは停止しますので注意してください。
415     //!
416     //! @return       ラジアン単位のツイストです。
417     //---------------------------------------------------------------------------
418     f32 GetTwist() const;
419 
420     //---------------------------------------------------------------------------
421     //! @brief        設定されているビューアップデータのツイストを設定します。
422     //!
423     //!               この関数はパラメータを簡単に設定するためのユーティリティ関数です。
424     //!               設定されているビューアップデータがAimカメラ用でなかった場合、プログラムは停止しますので注意してください。
425     //!
426     //! @param[in]    twist ラジアン単位のツイストです。
427     //---------------------------------------------------------------------------
428     void SetTwist(f32 twist);
429 
430     //---------------------------------------------------------------------------
431     //! @brief        設定されているビューアップデータの回転角度を取得します。
432     //!
433     //!               この関数はパラメータを簡単に取得するためのユーティリティ関数です。
434     //!               設定されているビューアップデータがRotateカメラ用でなかった場合、プログラムは停止しますので注意してください。
435     //!
436     //! @return       回転角度ベクトルです。各成分の単位はラジアンです。
437     //---------------------------------------------------------------------------
438     const nw::math::VEC3& GetViewRotate() const;
439 
440     //---------------------------------------------------------------------------
441     //! @brief        設定されているビューアップデータの回転角度を設定します。
442     //!
443     //!               この関数はパラメータを簡単に設定するためのユーティリティ関数です。
444     //!               設定されているビューアップデータがRotateカメラ用でなかった場合、プログラムは停止しますので注意してください。
445     //!
446     //! @param[in]    viewRotate 角度ベクトルです。各成分の単位はラジアンです。
447     //---------------------------------------------------------------------------
448     void SetViewRotate(const nw::math::VEC3& viewRotate);
449 
450     //---------------------------------------------------------------------------
451     //! @brief        設定されているビューアップデータの回転角度を設定します。
452     //!
453     //!               この関数はパラメータを簡単に設定するためのユーティリティ関数です。
454     //!               設定されているビューアップデータがRotateカメラ用でなかった場合、プログラムは停止しますので注意してください。
455     //!
456     //! @param[in]    x X軸の回転角度です。単位はラジアンです。
457     //! @param[in]    y Y軸の回転角度です。単位はラジアンです。
458     //! @param[in]    z Z軸の回転角度です。単位はラジアンです。
459     //---------------------------------------------------------------------------
SetViewRotate(f32 x,f32 y,f32 z)460     void SetViewRotate(f32 x, f32 y, f32 z){
461         SetViewRotate(nw::math::VEC3(x, y, z));
462     }
463 
464     //@}
465 
466     //----------------------------------------
467     //! @name プロジェクションアップデータ ユーティリティ関数
468     //@{
469 
470     //---------------------------------------------------------------------------
471     //! @brief        設定されているPerspective用プロジェクションアップデータのパラメータを取得します。
472     //!
473     //!               この関数はパラメータを簡単に取得するためのユーティリティ関数です。
474     //!               設定されているプロジェクションアップデータがPerspective用でなかった場合、プログラムは停止しますので注意してください。
475     //!               引数にNULLを設定されたパラメータは取得されません。
476     //!
477     //! @param[in]    fovy        縦方向の視野角(ラジアン単位)を格納するポインタです。
478     //! @param[in]    aspectRatio 視野のアスペクト比(幅/高さ)を格納するポインタです。
479     //! @param[in]    nearClip    ニアクリッピング面までの距離を格納するポインタです。
480     //! @param[in]    farClip     ファークリッピング面までの距離を格納するポインタです。
481     //---------------------------------------------------------------------------
482     void GetPerspective(
483         f32* fovy,
484         f32* aspectRatio,
485         f32* nearClip,
486         f32* farClip
487     ) const;
488 
489     //---------------------------------------------------------------------------
490     //! @brief        設定されているPerspective用プロジェクションアップデータのパラメータを設定します。
491     //!
492     //!               この関数はパラメータを簡単に設定するためのユーティリティ関数です。
493     //!               設定されているプロジェクションアップデータがPerspective用でなかった場合、プログラムは停止しますので注意してください。
494     //!
495     //! @param[in]    fovy        縦方向の視野角(ラジアン単位)です。
496     //! @param[in]    aspectRatio 視野のアスペクト比(幅/高さ)です。
497     //! @param[in]    nearClip    ニアクリッピング面までの距離です。
498     //! @param[in]    farClip     ファークリッピング面までの距離です。
499     //---------------------------------------------------------------------------
500     void SetPerspective(
501         f32 fovy,
502         f32 aspectRatio,
503         f32 nearClip,
504         f32 farClip
505     );
506 
507     //---------------------------------------------------------------------------
508     //! @brief        設定されているFrustum用プロジェクションアップデータのパラメータを取得します。
509     //!
510     //!               この関数はパラメータを簡単に取得するためのユーティリティ関数です。
511     //!               設定されているプロジェクションアップデータがFrustum用でなかった場合、プログラムは停止しますので注意してください。
512     //!               引数にNULLを設定されたパラメータは取得されません。
513     //!
514     //! @param[in]    left        ニアクリッピング面での視錐台左辺のX座標を格納するポインタです。
515     //! @param[in]    right       ニアクリッピング面での視錐台右辺のX座標を格納するポインタです。
516     //! @param[in]    bottom      ニアクリッピング面での視錐台下辺のY座標を格納するポインタです。
517     //! @param[in]    top         ニアクリッピング面での視錐台上辺のY座標を格納するポインタです。
518     //! @param[in]    nearClip    ニアクリッピング面までの距離を格納するポインタです。
519     //! @param[in]    farClip     ファークリッピング面までの距離を格納するポインタです。
520     //---------------------------------------------------------------------------
521     void GetFrustum(
522         f32* left,
523         f32* right,
524         f32* bottom,
525         f32* top,
526         f32* nearClip,
527         f32* farClip
528     ) const;
529 
530     //---------------------------------------------------------------------------
531     //! @brief        設定されているFrustum用プロジェクションアップデータのパラメータを設定します。
532     //!
533     //!               この関数はパラメータを簡単に取得するためのユーティリティ関数です。
534     //!               設定されているプロジェクションアップデータがFrustum用でなかった場合、プログラムは停止しますので注意してください。
535     //!
536     //! @param[in]    left        ニアクリッピング面での視錐台左辺のX座標です。
537     //! @param[in]    right       ニアクリッピング面での視錐台右辺のX座標です。
538     //! @param[in]    bottom      ニアクリッピング面での視錐台下辺のY座標です。
539     //! @param[in]    top         ニアクリッピング面での視錐台上辺のY座標です。
540     //! @param[in]    nearClip    ニアクリッピング面までの距離です。
541     //! @param[in]    farClip     ファークリッピング面までの距離です。
542     //---------------------------------------------------------------------------
543     void SetFrustum(
544         f32 left,
545         f32 right,
546         f32 bottom,
547         f32 top,
548         f32 nearClip,
549         f32 farClip
550     );
551 
552     //---------------------------------------------------------------------------
553     //! @brief        設定されているFrustum用プロジェクションアップデータのパラメータを取得します。
554     //!
555     //!               この関数はパラメータを簡単に取得するためのユーティリティ関数です。
556     //!               設定されているプロジェクションアップデータがFrustum用でなかった場合、プログラムは停止しますので注意してください。
557     //!               引数にNULLを設定されたパラメータは取得されません。
558     //!
559     //! @param[in]    rect        ニアクリッピング面での視錐台近平面の矩形を格納するポインタです。
560     //! @param[in]    nearClip    ニアクリッピング面までの距離を格納するポインタです。
561     //! @param[in]    farClip     ファークリッピング面までの距離を格納するポインタです。
562     //---------------------------------------------------------------------------
563     void GetFrustum(
564         ut::Rect* rect,
565         f32* nearClip,
566         f32* farClip
567     ) const;
568 
569     //---------------------------------------------------------------------------
570     //! @brief        設定されているFrustum用プロジェクションアップデータのパラメータを設定します。
571     //!
572     //!               この関数はパラメータを簡単に設定するためのユーティリティ関数です。
573     //!               設定されているプロジェクションアップデータがFrustum用でなかった場合、プログラムは停止しますので注意してください。
574     //!
575     //! @param[in]    rect        ニアクリッピング面での視錐台近平面の矩形です。
576     //! @param[in]    nearClip    ニアクリッピング面までの距離です。
577     //! @param[in]    farClip     ファークリッピング面までの距離です。
578     //---------------------------------------------------------------------------
579     void SetFrustum(
580         const ut::Rect& rect,
581         f32 nearClip,
582         f32 farClip
583     );
584 
585     //---------------------------------------------------------------------------
586     //! @brief        設定されているFrustum用プロジェクションアップデータのパラメータを設定します。
587     //!
588     //!               与えられたビューポートをもとにパラメータを設定します。
589     //!               この関数はパラメータを簡単に設定するためのユーティリティ関数です。
590     //!               設定されているプロジェクションアップデータがFrustum用でなかった場合、プログラムは停止しますので注意してください。
591     //!
592     //! @param[in]    viewport    ビューポートです。
593     //---------------------------------------------------------------------------
594     void SetFrustum(
595         const Viewport& viewport
596     );
597 
598     //---------------------------------------------------------------------------
599     //! @brief        設定されているOrtho用プロジェクションアップデータのパラメータを取得します。
600     //!
601     //!               この関数はパラメータを簡単に取得するためのユーティリティ関数です。
602     //!               設定されているプロジェクションアップデータがOrtho用でなかった場合、プログラムは停止しますので注意してください。
603     //!               引数にNULLを設定されたパラメータは取得されません。
604     //!
605     //! @param[in]    left        ニアクリッピング面での視錐台左辺のX座標を格納するポインタです。
606     //! @param[in]    right       ニアクリッピング面での視錐台右辺のX座標を格納するポインタです。
607     //! @param[in]    bottom      ニアクリッピング面での視錐台下辺のY座標を格納するポインタです。
608     //! @param[in]    top         ニアクリッピング面での視錐台上辺のY座標を格納するポインタです。
609     //! @param[in]    nearClip    ニアクリッピング面までの距離を格納するポインタです。
610     //! @param[in]    farClip     ファークリッピング面までの距離を格納するポインタです。
611     //---------------------------------------------------------------------------
612     void GetOrtho(
613         f32* left,
614         f32* right,
615         f32* bottom,
616         f32* top,
617         f32* nearClip,
618         f32* farClip
619     ) const;
620 
621     //---------------------------------------------------------------------------
622     //! @brief        設定されているOrtho用プロジェクションアップデータのパラメータを設定します。
623     //!
624     //!               この関数はパラメータを簡単に設定するためのユーティリティ関数です。
625     //!               設定されているプロジェクションアップデータがOrtho用でなかった場合、プログラムは停止しますので注意してください。
626     //!
627     //! @param[in]    left        ニアクリッピング面での視錐台左辺のX座標です。
628     //! @param[in]    right       ニアクリッピング面での視錐台右辺のX座標です。
629     //! @param[in]    bottom      ニアクリッピング面での視錐台下辺のY座標です。
630     //! @param[in]    top         ニアクリッピング面での視錐台上辺のY座標です。
631     //! @param[in]    nearClip    ニアクリッピング面までの距離です。
632     //! @param[in]    farClip     ファークリッピング面までの距離です。
633     //---------------------------------------------------------------------------
634     void SetOrtho(
635         f32 left,
636         f32 right,
637         f32 bottom,
638         f32 top,
639         f32 nearClip,
640         f32 farClip
641     );
642 
643     //---------------------------------------------------------------------------
644     //! @brief        設定されているOrtho用プロジェクションアップデータのパラメータを取得します。
645     //!
646     //!               この関数はパラメータを簡単に取得するためのユーティリティ関数です。
647     //!               設定されているプロジェクションアップデータがOrtho用でなかった場合、プログラムは停止しますので注意してください。
648     //!               引数にNULLを設定されたパラメータは取得されません。
649     //!
650     //! @param[in]    rect        ニアクリッピング面での視錐台近平面の矩形を格納するポインタです。
651     //! @param[in]    nearClip    ニアクリッピング面までの距離を格納するポインタです。
652     //! @param[in]    farClip     ファークリッピング面までの距離を格納するポインタです。
653     //---------------------------------------------------------------------------
654     void GetOrtho(
655         ut::Rect* rect,
656         f32* nearClip,
657         f32* farClip
658     ) const;
659 
660     //---------------------------------------------------------------------------
661     //! @brief        設定されているOrtho用プロジェクションアップデータのパラメータを設定します。
662     //!
663     //!               この関数はパラメータを簡単に設定するためのユーティリティ関数です。
664     //!               設定されているプロジェクションアップデータがOrtho用でなかった場合、プログラムは停止しますので注意してください。
665     //!
666     //! @param[in]    rect        ニアクリッピング面での視錐台近平面の矩形です。
667     //! @param[in]    nearClip    ニアクリッピング面までの距離です。
668     //! @param[in]    farClip     ファークリッピング面までの距離です。
669     //---------------------------------------------------------------------------
670     void SetOrtho(
671         const ut::Rect& rect,
672         f32 nearClip,
673         f32 farClip
674     );
675 
676     //---------------------------------------------------------------------------
677     //! @brief        設定されているOrtho用プロジェクションアップデータのパラメータを設定します。
678     //!
679     //!               与えられたビューポートをもとにパラメータを設定します。
680     //!               この関数はパラメータを簡単に設定するためのユーティリティ関数です。
681     //!               設定されているプロジェクションアップデータがOrtho用でなかった場合、プログラムは停止しますので注意してください。
682     //!
683     //! @param[in]    viewport    設定元のビューポートです。
684     //---------------------------------------------------------------------------
685     void SetOrtho(
686         const Viewport& viewport
687     );
688 
689     //---------------------------------------------------------------------------
690     //! @brief        設定されているプロジェクションアップデータのニアクリップまでの距離を取得します。
691     //!
692     //!               この関数はパラメータを簡単に取得するためのユーティリティ関数です。
693     //!
694     //! @return       ニアクリップまでの距離です。
695     //---------------------------------------------------------------------------
696     f32 GetNear() const;
697 
698     //---------------------------------------------------------------------------
699     //! @brief        設定されているプロジェクションアップデータのニアクリップまでの距離を設定します。
700     //!
701     //!               この関数はパラメータを簡単に取得するためのユーティリティ関数です。
702     //!
703     //! @param[in] near ニアクリップまでの距離です。
704     //---------------------------------------------------------------------------
705     void SetNear(f32 near);
706 
707     //---------------------------------------------------------------------------
708     //! @brief        設定されているプロジェクションアップデータのファークリップまでの距離を取得します。
709     //!
710     //!               この関数はパラメータを簡単に取得するためのユーティリティ関数です。
711     //!
712     //! @return       ファークリップまでの距離です。
713     //---------------------------------------------------------------------------
714     f32 GetFar() const;
715 
716     //---------------------------------------------------------------------------
717     //! @brief        設定されているプロジェクションアップデータのファークリップまでの距離を設定します。
718     //!
719     //!               この関数はパラメータを簡単に取得するためのユーティリティ関数です。
720     //!
721     //! @param[in] far ファークリップまでの距離です。
722     //---------------------------------------------------------------------------
723     void SetFar(f32 far);
724 
725     //@}
726 
727 protected:
728     //----------------------------------------
729     //! @name コンストラクタ/デストラクタ
730     //@{
731 
732     //! コンストラクタです。
733     Camera(
734         os::IAllocator* allocator,
735         ResTransformNode resObj,
736         const Camera::Description& description,
737         GfxPtr<CameraViewUpdater> viewUpdater,
738         GfxPtr<CameraProjectionUpdater> projectionUpdater,
739         f32 wscale,
740         bool isDynamic);
741 
742     //! デストラクタです。
743     virtual ~Camera();
744 
745     //@}
746 
747     struct ResCameraDestroyer : public std::unary_function<ResCamera, void>
748     {
m_AllocatorResCameraDestroyer749         ResCameraDestroyer(os::IAllocator* allocator = 0) : m_Allocator(allocator)
750         {}
operatorResCameraDestroyer751         result_type operator()(argument_type data)
752         {
753             DestroyResCamera(m_Allocator, data);
754         }
755 
756         os::IAllocator* m_Allocator;
757     };
758 
759 private:
760     virtual Result Initialize(os::IAllocator* allocator);
761 
762     //! アニメーションを初期状態に戻すため、初期化時の状態を保存します。
763     Result StoreOriginal(os::IAllocator* allocator);
764 
765     //---------------------------------------------------------------------------
766     //! @brief        ResCamera のリソースを破棄します。
767     //!
768     //! @param[in]    allocator        リソース用のメモリを解放するアロケータです。
769     //! @param[in]    resCamera        解放するリソースです。
770     //---------------------------------------------------------------------------
771     static void DestroyResCamera(os::IAllocator* allocator, ResCamera resCamera);
772 
773     Result CreateAnimGroup(os::IAllocator* allocator);
774 
775     //! @brief アニメーションに登録するモデルデータのポインタを取得します。
776     void* GetAnimTargetObject(const anim::ResAnimGroupMember& anim);
777 
778     //! @details :private
779     //  アニメーションとカメラで、view/projectionのupdaterが一致しているかチェックします。
780     bool ValidateCameraAnimType(AnimObject* animObject);
781 
782     math::MTX34 m_ViewMatrix;
783     math::MTX34 m_InverseViewMatrix;
784     math::MTX44 m_ProjectionMatrix;
785     math::MTX44 m_InverseProjectionMatrix;
786     math::MTX34 m_TextureProjectionMatrix;
787 
788     GfxPtr<CameraViewUpdater> m_ViewUpdater;
789     GfxPtr<CameraProjectionUpdater> m_ProjectionUpdater;
790 
791     AnimGroup* m_AnimGroup;
792 
793     ResCamera m_OriginalValue;
794     math::Transform3 m_OriginalTransform;
795     f32 m_WScale;
796     bool m_IsDynamic;
797 };
798 
799 } // namespace gfx
800 } // namespace nw
801 
802 #endif // NW_GFX_CAMERA_H_
803