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