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: 24209 $
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     private:
131         FragmentLight::Description m_Description;
132     };
133 
134     //! @brief        フラグメントライトを生成します。
135     //!
136     //! @param[in]    parent 親のノードです。
137     //! @param[in]    resource リソースです。
138     //! @param[in]    description 設定内容です。
139     //! @param[in]    allocator アロケータです。
140     //!
141     //! @return       生成されたフラグメントライトです。
142     //!
143     static FragmentLight* Create(
144         SceneNode* parent,
145         ResSceneObject resource,
146         const FragmentLight::Description& description,
147         os::IAllocator* allocator);
148 
149     //@}
150 
151     //----------------------------------------
152     //! @name トランスフォーム
153     //@{
154 
155     //! @brief 方向情報を更新します。
156     virtual void UpdateDirection();
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     //! フラグメントライトのリソースを取得します。
GetResFragmentLight()177     ResFragmentLight GetResFragmentLight()
178     {
179         return ResStaticCast<ResFragmentLight>(this->GetResSceneObject());
180     }
181 
182     //! フラグメントライトのリソースを取得します。
GetResFragmentLight()183     const ResFragmentLight GetResFragmentLight() const
184     {
185         return ResStaticCast<ResFragmentLight>(this->GetResSceneObject());
186     }
187 
188     //@}
189 
190 protected:
191     struct ResFragmentLightDataDestroyer : public std::unary_function<ResFragmentLightData*, void>
192     {
m_AllocatorResFragmentLightDataDestroyer193         ResFragmentLightDataDestroyer(os::IAllocator* allocator = 0) : m_Allocator(allocator)
194         {}
operatorResFragmentLightDataDestroyer195         result_type operator()(argument_type data)
196         {
197             DestroyResFragmentLight(m_Allocator, data);
198         }
199 
200         os::IAllocator* m_Allocator;
201     };
202 
203     //! 動的生成したライトリソースを破棄するための MovePtr の定義です。
204     typedef ut::MovePtr<ResFragmentLightData, ResFragmentLightDataDestroyer> ResPtr;
205 
206     //----------------------------------------
207     //! @name コンストラクタ/デストラクタ
208     //@{
209 
210     //! コンストラクタです。
FragmentLight(os::IAllocator * allocator,ResFragmentLight resObj,const FragmentLight::Description & description)211     FragmentLight(
212         os::IAllocator* allocator,
213         ResFragmentLight resObj,
214         const FragmentLight::Description& description)
215     : Light(
216         allocator,
217         resObj,
218         description),
219       m_Direction(resObj.GetDirection())
220     {}
221 
222     //! コンストラクタです。
FragmentLight(os::IAllocator * allocator,ResPtr resource,const FragmentLight::Description & description)223     FragmentLight(
224         os::IAllocator* allocator,
225         ResPtr resource,
226         const FragmentLight::Description& description)
227     : Light(
228         allocator,
229         ResFragmentLight(resource.Get()),
230         description),
231       m_Resource(resource)
232     {
233         m_Direction = this->GetResFragmentLight().GetDirection();
234     }
235 
236     //! デストラクタです。
~FragmentLight()237     virtual ~FragmentLight()
238     {
239         DestroyOriginalValue();
240     }
241 
242     //@}
243 
244 private:
245     virtual Result Initialize(os::IAllocator* allocator);
246 
247     //---------------------------------------------------------------------------
248     //! @brief        ResFragmentLightData のリソースを生成します。
249     //!
250     //! @param[in]    allocator   リソース用のメモリを確保するアロケータです。
251     //! @param[in]    name        リソースにつける名前へのポインタです。名前が必要ない場合には NULL を指定してください。
252     //!
253     //! @return       ResFragmentLightData へのポインタです。
254     //---------------------------------------------------------------------------
255     static ResFragmentLightData*    CreateResFragmentLight(os::IAllocator* allocator, const char* name = NULL);
256 
257     //---------------------------------------------------------------------------
258     //! @brief        ResFragmentLightData のリソースを破棄します。
259     //!
260     //! @param[in]    resFragmentLight ResFragmentLightData へのポインタです。
261     //! @param[in]    allocator        リソース用のメモリを開放するアロケータです。
262     //---------------------------------------------------------------------------
263     static void DestroyResFragmentLight(os::IAllocator* allocator, ResFragmentLightData* resFragmentLight);
264 
265     //! アニメーションを初期状態に戻すため、初期化時の状態を保存します。
266     Result CreateOriginalValue(os::IAllocator* allocator);
267 
268     ResPtr m_Resource;
269     math::VEC3 m_Direction;
270 };
271 
272 } // namespace gfx
273 } // namespace nw
274 
275 #endif // NW_GFX_FRAGMENTLIGHT_H_
276