1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_Fog.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_GFX_FOG_H_
19 #define NW_GFX_FOG_H_
20 
21 #include <nw/gfx/gfx_TransformNode.h>
22 #include <nw/gfx/res/gfx_ResFog.h>
23 
24 #include <nw/ut/ut_MovePtr.h>
25 #include <functional>
26 
27 namespace nw
28 {
29 namespace gfx
30 {
31 
32 class Camera;
33 
34 //---------------------------------------------------------------------------
35 //! @brief        フォグを表すクラスです。
36 //---------------------------------------------------------------------------
37 class Fog : public TransformNode
38 {
39 private:
40     NW_DISALLOW_COPY_AND_ASSIGN(Fog);
41 
42     #define NW_FOG_TABLE_COMMAND_NUM    (132)   // idex(2) + table128(129) + terminate(1)
43     #define NW_FOG_TABLE_COMMAND_SIZE   (NW_FOG_TABLE_COMMAND_NUM * 4)
44 
45 public:
46     NW_UT_RUNTIME_TYPEINFO;
47 
48     //! @brief 設定内容です。
49     struct Description : public TransformNode::Description
50     {
51         //! @brief コンストラクタです。
DescriptionDescription52         Description(){}
53     };
54 
55     //---------------------------------------------------------------------------
56     //! @brief フォグを更新するための関数オブジェクトです。
57     //---------------------------------------------------------------------------
58     struct UpdateFunctor
59     {
UpdateFunctorUpdateFunctor60         UpdateFunctor(Camera* camera) : camera(camera) {}
61 
operatorUpdateFunctor62         void operator() (Fog* fog)
63         {
64             if (fog != NULL)
65             {
66                 fog->Update(camera);
67             }
68         }
69 
70         Camera* camera;
71     };
72 
73     //----------------------------------------
74     //! @name 作成/破棄
75     //@{
76 
77     //! フォグを動的に構築するためのクラスです。
78     //!
79     //! IsFixedSizeMemory の初期値は true です。false に変更すると、各種最大数の設定は無視されます。
80     class DynamicBuilder
81     {
82     public:
83         //! コンストラクタです。
DynamicBuilder()84         DynamicBuilder() {}
85         //! デストラクタです。
~DynamicBuilder()86         ~DynamicBuilder() {}
87 
88         //! @brief 生成時以外にもメモリを確保するかどうかのフラグを設定します。
89         //!
90         //!        true を指定すると、生成時のみ固定サイズのメモリ確保を行います。
91         //!
92         //!        false を指定すると、生成時以外にも必要に応じて動的にメモリ確保が行われます。
IsFixedSizeMemory(bool isFixedSizeMemory)93         DynamicBuilder& IsFixedSizeMemory(bool isFixedSizeMemory)
94         {
95             m_Description.isFixedSizeMemory = isFixedSizeMemory;
96             return *this;
97         }
98 
99         //! 子の最大数を設定します。
MaxChildren(int maxChildren)100         DynamicBuilder& MaxChildren(int maxChildren)
101         {
102             m_Description.maxChildren = maxChildren;
103             return *this;
104         }
105 
106         //! 管理できるコールバックの最大数を設定します。
MaxCallbacks(int maxCallbacks)107         DynamicBuilder& MaxCallbacks(int maxCallbacks)
108         {
109             m_Description.maxCallbacks = maxCallbacks;
110             return *this;
111         }
112 
113         //! @brief        フォグを生成します。
114         //!
115         //! @param[in]    allocator アロケータです。
116         //!
117         //! @return       生成したフォグを返します。
118         //!
119         Fog* Create(os::IAllocator* allocator);
120 
121         //! @brief 生成時に必要なメモリサイズを取得します。
122         //!
123         //! メモリサイズは Builder の設定によって変化します。
124         //! すべての設定が終わった後にこの関数を呼び出してください。
125         //!
126         //! @param[in] alignment 計算に用いるアライメントです。2 のべき乗である必要があります。
127         size_t GetMemorySize(size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) const;
128 
129     private:
130         Fog::Description m_Description;
131     };
132 
133     //! @brief        フォグを生成します。
134     //!
135     //! @param[in]    parent 親のノードです。
136     //! @param[in]    resource リソースです。
137     //! @param[in]    description 設定内容です。
138     //! @param[in]    allocator アロケータです。
139     //!
140     //! @return       生成されたフォグです。
141     //!
142     static Fog* Create(
143         SceneNode* parent,
144         ResSceneObject resource,
145         const Fog::Description& description,
146         os::IAllocator* allocator);
147 
148     //! @brief        生成時に必要なメモリサイズを取得します。
149     //!
150     //! @param[in]    resource リソースです。
151     //! @param[in]    description 設定内容です。
152     //! @param[in]    alignment 計算に用いるアライメントです。2 のべき乗である必要があります。
153     static size_t GetMemorySize(
154         ResFog resource,
155         Description description,
156         size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT
157     )
158     {
159         os::MemorySizeCalculator size(alignment);
160 
161         GetMemorySizeInternal(&size, resource, description);
162 
163         return size.GetSizeWithPadding(alignment);
164     }
165 
166     //! @details :private
167     static void GetMemorySizeInternal(
168         os::MemorySizeCalculator* pSize,
169         ResFog resource,
170         Description description);
171 
172     //@}
173 
174     //----------------------------------------
175     //! @name 参照テーブル
176     //@{
177 
178     //! @brief フォグの参照テーブルを更新します。
179     //!
180     //! @param[in] camera カメラです。
181     //!
182     void Update(const Camera* camera);
183 
184     //@}
185 
186     //----------------------------------------
187     //! @name シーンツリー
188     //@{
189 
190     //! @brief        ビジターを受け付けます。
191     //!
192     //! @param[in]    visitor ビジターです。
193     //!
194     virtual void Accept(ISceneVisitor* visitor);
195 
196     //@}
197 
198     //----------------------------------------
199     //! @name リソース
200     //@{
201 
202     //! フォグのリソースを取得します。
GetResFog()203     ResFog GetResFog()
204     {
205         return ResStaticCast<ResFog>(this->GetResSceneObject());
206     }
207 
208     //! フォグのリソースを取得します。
GetResFog()209     const ResFog GetResFog() const
210     {
211         return ResStaticCast<ResFog>(this->GetResSceneObject());
212     }
213 
214     //@}
215 
216     //----------------------------------------
217     //! @name アニメーション
218     //@{
219 
220     //! アニメーショングループを取得します。
GetAnimGroup()221     AnimGroup* GetAnimGroup() { return m_AnimGroup; }
222 
223     //! アニメーショングループを取得します。
GetAnimGroup()224     const AnimGroup* GetAnimGroup() const { return m_AnimGroup; }
225 
226     //! アニメーションオブジェクトを取得します。
GetAnimObject()227     AnimObject* GetAnimObject() { return m_AnimBinding->GetAnimObject(0); }
228 
229     //! アニメーションオブジェクトを取得します。
GetAnimObject()230     const AnimObject* GetAnimObject() const { return m_AnimBinding->GetAnimObject(0); }
231 
232     //! @brief アニメーションオブジェクトを設定します。
233     //!
234     //! @param[in] animObject 設定するアニメーションオブジェクトです。NULL を指定するとアニメーションを解除します。
SetAnimObject(AnimObject * animObject)235     void SetAnimObject(AnimObject* animObject) { m_AnimBinding->SetAnimObject(0, animObject); }
236 
237     //@}
238 protected:
239     struct ResFogDataDestroyer : public std::unary_function<ResFogData*, void>
240     {
m_AllocatorResFogDataDestroyer241         ResFogDataDestroyer(os::IAllocator* allocator = 0) : m_Allocator(allocator)
242         {}
operatorResFogDataDestroyer243         result_type operator()(argument_type data)
244         {
245             DestroyResFog(m_Allocator, data);
246         }
247 
248         os::IAllocator* m_Allocator;
249     };
250 
251     struct ResFogUpdaterDataDestroyer : public std::unary_function<ResFogUpdaterData*, void>
252     {
m_AllocatorResFogUpdaterDataDestroyer253         ResFogUpdaterDataDestroyer(os::IAllocator* allocator = 0) : m_Allocator(allocator)
254         {}
operatorResFogUpdaterDataDestroyer255         result_type operator()(argument_type data)
256         {
257             DestroyResFogUpdater(m_Allocator, data);
258         }
259 
260         os::IAllocator* m_Allocator;
261     };
262 
263     //! 動的生成したフォグリソースを破棄するための MovePtr の定義です。
264     typedef ut::MovePtr<ResFogData, ResFogDataDestroyer> ResPtr;
265     typedef ut::MovePtr<ResFogUpdaterData, ResFogUpdaterDataDestroyer> ResUpdaterPtr;
266 
267     //----------------------------------------
268     //! @name コンストラクタ/デストラクタ
269     //@{
270 
271     //! コンストラクタです。
Fog(os::IAllocator * allocator,ResFog resObj,const Fog::Description & description)272     Fog(
273         os::IAllocator* allocator,
274         ResFog resObj,
275         const Fog::Description& description)
276      : TransformNode(
277         allocator,
278         resObj,
279         description),
280         m_Near(0.0f),
281         m_Far(0.0f),
282         m_WScale(0.0f),
283         m_AnimGroup(NULL),
284         m_OriginalValue(NULL)
285     {}
286 
287     //! コンストラクタです。
Fog(os::IAllocator * allocator,ResPtr resource,const Fog::Description & description)288     Fog(
289         os::IAllocator* allocator,
290         ResPtr resource,
291         const Fog::Description& description)
292     : TransformNode(
293         allocator,
294         ResFog(resource.Get()),
295         description),
296       m_Resource(resource),
297       m_Near(0.0f),
298       m_Far(0.0f),
299       m_WScale(0.0f),
300       m_AnimGroup(NULL),
301       m_OriginalValue(NULL)
302     {}
303 
304     //! デストラクタです。
~Fog()305     virtual ~Fog()
306     {
307         ut::SafeDestroy(m_AnimGroup);
308 
309         if (m_OriginalValue.IsValid())
310         {
311             GetAllocator().Free(m_OriginalValue.ptr());
312             m_OriginalValue = ResFog(NULL);
313         }
314     }
315 
316     //@}
317 
318 private:
319     virtual Result Initialize(os::IAllocator* allocator);
320 
321     // アニメーショングループを作成します。
322     Result CreateAnimGroup(os::IAllocator* allocator);
323 
324     // アニメメンバへの参照を解決します。
325     void BindAnim(AnimGroup* animGroup);
326 
327     Result CreateOriginalValue(os::IAllocator* allocator);
328 
329     //---------------------------------------------------------------------------
330     //! @brief        ResFogData のリソースを生成します。
331     //!
332     //! @param[in]    allocator   リソース用のメモリを確保するアロケータです。
333     //! @param[in]    name        リソースにつける名前へのポインタです。名前が必要ない場合には NULL を指定してください。
334     //!
335     //! @return       ResFogData へのポインタです。
336     //---------------------------------------------------------------------------
337     static ResFogData*    CreateResFog(os::IAllocator* allocator, const char* name = NULL);
338 
339     //---------------------------------------------------------------------------
340     //! @brief        ResFogData のリソースを破棄します。
341     //!
342     //! @param[in]    allocator        リソース用のメモリを開放するアロケータです。
343     //! @param[in]    resFog ResFogData へのポインタです。
344     //---------------------------------------------------------------------------
345     static void DestroyResFog(os::IAllocator* allocator, ResFogData* resFog);
346 
347     //---------------------------------------------------------------------------
348     //! @brief        ResFogUpdaterData のリソースを生成します。
349     //!
350     //! @param[in]    allocator   リソース用のメモリを確保するアロケータです。
351     //!
352     //! @return       ResFogUpdaterData へのポインタです。
353     //---------------------------------------------------------------------------
354     static ResFogUpdaterData*    CreateResFogUpdater(os::IAllocator* allocator);
355 
356     //---------------------------------------------------------------------------
357     //! @brief        ResFogData のリソースを破棄します。
358     //!
359     //! @param[in]    allocator        リソース用のメモリを開放するアロケータです。
360     //! @param[in]    resFogUpdater ResFogUpdaterData へのポインタです。
361     //---------------------------------------------------------------------------
362     static void DestroyResFogUpdater(os::IAllocator* allocator, ResFogUpdaterData* resFogUpdater);
363 
364     void SetupFogSampler(
365         ResImageLookupTable fogSampler,
366         ResFogUpdater fogUpdater,
367         const math::MTX44& inverseProjectionMatrix);
368 
369     ResPtr m_Resource;
370     ResUpdaterPtr m_UpdaterCache;
371     f32 m_Near;
372     f32 m_Far;
373     f32 m_WScale;
374     AnimGroup* m_AnimGroup;
375     ResFog m_OriginalValue;
376     static const float FOG_DENSITY;
377     static const ResFogUpdater::FogUpdaterType FOG_UPDATER_TYPE;
378     static const float FOG_MAX_DEPTH;
379     static const float FOG_MIN_DEPTH;
380 };
381 
382 } // namespace gfx
383 } // namespace nw
384 
385 #endif // NW_GFX_FOG_H_
386