1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_FragmentLight.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_FRAGMENTLIGHT_H_
19 #define NW_GFX_FRAGMENTLIGHT_H_
20 
21 #include <nw/gfx/gfx_Light.h>
22 #include <nw/gfx/res/gfx_ResLight.h>
23 #include <nw/anim/res/anim_ResAnim.h>
24 
25 #include <nw/ut/ut_MovePtr.h>
26 #include <functional>
27 
28 namespace nw
29 {
30 namespace gfx
31 {
32 
33 //---------------------------------------------------------------------------
34 //! @brief        フラグメントライトを表すクラスです。
35 //---------------------------------------------------------------------------
36 class FragmentLight : public Light
37 {
38 private:
39     NW_DISALLOW_COPY_AND_ASSIGN(FragmentLight);
40 
41 public:
42     NW_UT_RUNTIME_TYPEINFO;
43 
44 
45     //----------------------------------------
46     //! @name 取得/設定
47     //@{
48 
49     //! @brief ライト方向を取得します。
50     //!
51     //! SceneUpdater で ResLight の m_Direction から親ノードの回転を継承フラグに応じて計算もしくはコピーされます。
52     //! Direction を変更する場合は、SceneUpdater::UpdateTransformNode の実行前ならば ResLight::SetDirection を用い、
53     //! SceneUpdater の実行後ではこちらの Direction を直接編集してください。
54     //!
55     //! @return ライト方向です。
56     //!
Direction()57     const math::VEC3& Direction() const
58     {
59         return this->m_Direction;
60     }
61 
62     //! @brief ライト方向を取得します。
63     //!
64     //! SceneUpdater で ResLight の m_Direction から親ノードの回転を継承フラグに応じて計算もしくはコピーされます。
65     //! Direction を変更する場合は、SceneUpdater::UpdateTransformNode の実行前ならば ResLight::SetDirection を用い、
66     //! SceneUpdater の実行後ではこちらの Direction を直接編集してください。
67     //!
68     //! @return ライト方向です。
69     //!
Direction()70     math::VEC3& Direction()
71     {
72         return this->m_Direction;
73     }
74 
75     //@}
76 
77     //! @brief 設定内容です。
78     struct Description : public Light::Description
79     {
80         //! @brief コンストラクタです。
DescriptionDescription81         Description(){}
82     };
83 
84     //----------------------------------------
85     //! @name 作成/破棄
86     //@{
87 
88     //! @brief フラグメントライトを動的に構築するためのクラスです。
89     //!
90     //! IsFixedSizeMemory の初期値は true です。false に変更すると、各種最大数の設定は無視されます。
91     class DynamicBuilder
92     {
93     public:
94         //! コンストラクタです。
DynamicBuilder()95         DynamicBuilder() {}
96 
97         //! デストラクタです。
~DynamicBuilder()98         ~DynamicBuilder() {}
99 
100         //! @brief 生成時以外にもメモリを確保するかどうかのフラグを設定します。
101         //!
102         //!        true を指定すると、生成時のみ固定サイズのメモリ確保を行います。
103         //!
104         //!        false を指定すると、生成時以外にも必要に応じて動的にメモリ確保が行われます。
IsFixedSizeMemory(bool isFixedSizeMemory)105         DynamicBuilder& IsFixedSizeMemory(bool isFixedSizeMemory)
106         {
107             m_Description.isFixedSizeMemory = isFixedSizeMemory;
108             return *this;
109         }
110 
111         //! 子の最大数を設定します。
MaxChildren(int maxChildren)112         DynamicBuilder& MaxChildren(int maxChildren)
113         {
114             m_Description.maxChildren = maxChildren;
115             return *this;
116         }
117 
118         //! 管理できるコールバックの最大数を設定します。
MaxCallbacks(int maxCallbacks)119         DynamicBuilder& MaxCallbacks(int maxCallbacks)
120         {
121             m_Description.maxCallbacks = maxCallbacks;
122             return *this;
123         }
124 
125         //! @brief        フラグメントライトを生成します。
126         //!
127         //! @param[in]    allocator アロケータです。
128         //!
129         //! @return       生成したフラグメントライトを返します。
130         //!
131         FragmentLight* Create(os::IAllocator* allocator);
132 
133         //! @brief 生成時に必要なメモリサイズを取得します。
134         //!
135         //! メモリサイズは Builder の設定によって変化します。
136         //! すべての設定が終わった後にこの関数を呼び出してください。
137         //!
138         //! @param[in] alignment 計算に用いるアライメントです。2 のべき乗である必要があります。
139         size_t GetMemorySize(size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) const;
140 
141     private:
142         FragmentLight::Description m_Description;
143     };
144 
145     //! @brief        フラグメントライトを生成します。
146     //!
147     //! @param[in]    parent 親のノードです。
148     //! @param[in]    resource リソースです。
149     //! @param[in]    description 設定内容です。
150     //! @param[in]    allocator アロケータです。
151     //!
152     //! @return       生成されたフラグメントライトです。
153     //!
154     static FragmentLight* Create(
155         SceneNode* parent,
156         ResSceneObject resource,
157         const FragmentLight::Description& description,
158         os::IAllocator* allocator);
159 
160     //! @brief        生成時に必要なメモリサイズを取得します。
161     //!
162     //! @param[in]    resource リソースです。
163     //! @param[in]    description 設定内容です。
164     //! @param[in]    alignment 計算に用いるアライメントです。2 のべき乗である必要があります。
165     static size_t GetMemorySize(
166         ResFragmentLight resource,
167         Description description,
168         size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT
169     )
170     {
171         os::MemorySizeCalculator size(alignment);
172 
173         GetMemorySizeInternal(&size, resource, description);
174 
175         return size.GetSizeWithPadding(alignment);
176     }
177 
178     //! @brief        リソースを複製し、フラグメントライトを生成します。
179     //!
180     //!               内部で複製したリソースを基にフラグメントライトを生成します。
181     //!               複製されたリソースは生成されたフラグメントライトを破棄するときに
182     //!               自動的に破棄されます。
183     //!
184     //!               リソースのメンバのうち Name, UserData, ChildrenTable などは複製されす NULL になります。
185     //!               また、LUT も複製されずにオリジナルと同じものを参照するため、複製元の LUT が破棄された後に使用すると
186     //!               正しい動作は保証されません。
187     //!
188     //! @param[in]    parent 親のノードです。
189     //! @param[in]    resource 複製元のリソースです。
190     //! @param[in]    description 設定内容です。
191     //! @param[in]    allocator アロケータです。
192     //!
193     //! @return       生成されたフラグメントライトです。
194     //!
195     static FragmentLight* CreateClone(
196         SceneNode* parent,
197         ResFragmentLight resource,
198         const FragmentLight::Description& description,
199         os::IAllocator* allocator);
200 
201     //! @brief        CreateClone による生成時に必要なメモリサイズを取得します。
202     //!
203     //! @param[in]    resource リソースです。
204     //! @param[in]    description 設定内容です。
205     //! @param[in]    alignment 計算に用いるアライメントです。2 のべき乗である必要があります。
206     static size_t GetMemorySizeForCreateClone(
207         ResFragmentLight resource,
208         Description description,
209         size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT
210     );
211 
212     //! @details :private
213     static void GetMemorySizeInternal(
214         os::MemorySizeCalculator* pSize,
215         ResFragmentLight resource,
216         Description description);
217 
218     //@}
219 
220     //----------------------------------------
221     //! @name トランスフォーム
222     //@{
223 
224     //! @brief 方向情報を更新します。
225     virtual void UpdateDirection();
226 
227     //@}
228 
229     //----------------------------------------
230     //! @name シーンツリー
231     //@{
232 
233     //! @brief        ビジターを受け付けます。
234     //!
235     //! @param[in]    visitor ビジターです。
236     //!
237     virtual void Accept(ISceneVisitor* visitor);
238 
239     //@}
240 
241     //----------------------------------------
242     //! @name リソース
243     //@{
244 
245     //! フラグメントライトのリソースを取得します。
GetResFragmentLight()246     ResFragmentLight GetResFragmentLight()
247     {
248         return ResStaticCast<ResFragmentLight>(this->GetResSceneObject());
249     }
250 
251     //! フラグメントライトのリソースを取得します。
GetResFragmentLight()252     const ResFragmentLight GetResFragmentLight() const
253     {
254         return ResStaticCast<ResFragmentLight>(this->GetResSceneObject());
255     }
256 
257     //@}
258 
259 protected:
260     struct ResFragmentLightDataDestroyer : public std::unary_function<ResFragmentLightData*, void>
261     {
262         ResFragmentLightDataDestroyer(
263             os::IAllocator* allocator = NULL
264         )
m_AllocatorResFragmentLightDataDestroyer265         : m_Allocator(allocator)
266         {}
operatorResFragmentLightDataDestroyer267         result_type operator()(argument_type data)
268         {
269             DestroyResFragmentLight(m_Allocator, data);
270         }
271 
272         os::IAllocator* m_Allocator;
273     };
274 
275     //! 動的生成したライトリソースを破棄するための MovePtr の定義です。
276     typedef ut::MovePtr<ResFragmentLightData, ResFragmentLightDataDestroyer> ResPtr;
277 
278     //----------------------------------------
279     //! @name コンストラクタ/デストラクタ
280     //@{
281 
282     //! コンストラクタです。
FragmentLight(os::IAllocator * allocator,ResFragmentLight resObj,const FragmentLight::Description & description)283     FragmentLight(
284         os::IAllocator* allocator,
285         ResFragmentLight resObj,
286         const FragmentLight::Description& description)
287     : Light(
288         allocator,
289         resObj,
290         description),
291       m_Direction(resObj.GetDirection())
292     {}
293 
294     //! コンストラクタです。
FragmentLight(os::IAllocator * allocator,ResPtr resource,const FragmentLight::Description & description)295     FragmentLight(
296         os::IAllocator* allocator,
297         ResPtr resource,
298         const FragmentLight::Description& description)
299     : Light(
300         allocator,
301         ResFragmentLight(resource.Get()),
302         description),
303       m_Resource(resource)
304     {
305         m_Direction = this->GetResFragmentLight().GetDirection();
306     }
307 
308     //! デストラクタです。
~FragmentLight()309     virtual ~FragmentLight()
310     {
311         DestroyOriginalValue();
312     }
313 
314     //@}
315 
316 private:
317     virtual Result Initialize(os::IAllocator* allocator);
318 
319     //---------------------------------------------------------------------------
320     //! @brief        ResFragmentLightData のリソースを生成します。
321     //!
322     //! @param[in]    allocator   リソース用のメモリを確保するアロケータです。
323     //! @param[in]    name        リソースにつける名前へのポインタです。名前が必要ない場合には NULL を指定してください。
324     //!
325     //! @return       ResFragmentLightData へのポインタです。
326     //---------------------------------------------------------------------------
327     static ResFragmentLightData*    CreateResFragmentLight(os::IAllocator* allocator, const char* name = NULL);
328 
329     //---------------------------------------------------------------------------
330     //! @brief        ResFragmentLightData のリソースを破棄します。
331     //!
332     //! @param[in]    resFragmentLight ResFragmentLightData へのポインタです。
333     //! @param[in]    allocator        リソース用のメモリを開放するアロケータです。
334     //---------------------------------------------------------------------------
335     static void DestroyResFragmentLight(os::IAllocator* allocator, ResFragmentLightData* resFragmentLight);
336 
337     //---------------------------------------------------------------------------
338     //! @brief        ResFragmentLightData のリソースを複製します。
339     //!
340     //! @param[in]    resource    複製元のリソースです。
341     //! @param[in]    allocator   リソース用のメモリを確保するアロケータです。
342     //!
343     //! @return       ResFragmentLightData へのポインタです。
344     //---------------------------------------------------------------------------
345     static ResFragmentLightData*    CloneResFragmentLight(ResFragmentLight resource, os::IAllocator* allocator);
346 
347     //! アニメーションを初期状態に戻すため、初期化時の状態を保存します。
348     Result CreateOriginalValue(os::IAllocator* allocator);
349 
350         //! :private
GetLightType()351     virtual u32 GetLightType() const
352     {
353         return anim::ResLightAnimData::LIGHT_TYPE_FRAGMENT;
354     }
355 
356     //! :private
GetLightKind()357     virtual u32 GetLightKind() const
358     {
359         return GetResFragmentLight().GetLightKind();
360     }
361 
362     ResPtr m_Resource;
363     math::VEC3 m_Direction;
364 };
365 
366 } // namespace gfx
367 } // namespace nw
368 
369 #endif // NW_GFX_FRAGMENTLIGHT_H_
370