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