1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_ParticleContext.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_PARTICLECONTEXT_H_
19 #define NW_GFX_PARTICLECONTEXT_H_
20 
21 #include <nw/math.h>
22 #include <nw/ut/ut_Preprocessor.h>
23 #include <nw/ut/ut_MoveArray.h>
24 #include <nw/gfx/gfx_GfxObject.h>
25 #include <nw/gfx/gfx_ParticleRandom.h>
26 
27 namespace nw
28 {
29 namespace gfx
30 {
31 
32 //---------------------------------------------------------------------------
33 //! @brief        パーティクルの更新時の内容を保持させるためのクラスです。
34 //---------------------------------------------------------------------------
35 class ParticleContext : public GfxObject
36 {
37 private:
38     NW_DISALLOW_COPY_AND_ASSIGN(ParticleContext);
39 
40 public:
41     //! VEC3の Array の定義です。
42     typedef ut::MoveArray<nw::math::VEC3> VEC3Array;
43 
44     //! F32の Array の定義です。
45     typedef ut::MoveArray<f32> F32Array;
46 
47     //! U16の Array の定義です。
48     typedef ut::MoveArray<u16> U16Array;
49 
50     //----------------------------------------
51     //! @name 作成
52     //@{
53 
54     //! シーンコンテキストクラスを構築するためのクラスです。
55     //!
56     //! IsFixedSizeMemory の初期値は true です。false に変更すると、各種最大数の設定は無視されます。
57     class Builder
58     {
59     public:
60         //! @brief コンストラクタです。
Builder()61         Builder()
62         : m_IsFixedSizeMemory(true),
63           m_MaxEmission(1000),
64           m_MaxStreamLength(1000),
65           m_UseDoubleBuffer(false) {}
66 
67         //! @brief 生成時以外にもメモリを確保するかどうかのフラグを設定します。
68         //!
69         //!        true を指定すると、生成時のみ固定サイズのメモリ確保を行います。
70         //!
71         //!        false を指定すると、生成時以外にも必要に応じて動的にメモリ確保が行われます。
IsFixedSizeMemory(bool isFixedSizeMemory)72         Builder& IsFixedSizeMemory(bool isFixedSizeMemory)
73         {
74             m_IsFixedSizeMemory = isFixedSizeMemory;
75             return *this;
76         }
77 
78         //! @brief 放出量の最大数を設定します。
79         //! @param[in] maxEmission 放出量の最大数です。
80         //! @return ビルダーを返します。
MaxEmission(int maxEmission)81         Builder& MaxEmission(int maxEmission) { m_MaxEmission = maxEmission; return *this; }
82 
83         //! @brief ストリーム長の最大数を設定します。
84         //! @param[in] maxStreamLength ストリーム長の最大数です。
85         //! @return ビルダーを返します。
MaxStreamLength(int maxStreamLength)86         Builder& MaxStreamLength(int maxStreamLength) { m_MaxStreamLength = maxStreamLength; return *this; }
87 
88         //! @brief ダブルバッファで複数回更新を有効にします。
89         //! @details ダブルバッファでUpdateを複数回実行するときに必要なバッファを確保します。
90         //! @param[in] maxRuntimeWork ランタイムワークサイズの最大値です。
91         //! @return ビルダーを返します。
UseDoubleBuffer(int useDoubleBuffer)92         Builder& UseDoubleBuffer(int useDoubleBuffer) { m_UseDoubleBuffer = useDoubleBuffer; return *this; }
93 
94         //! @brief シーンコンテキストを構築します。
95         //! @param[in] allocator メモリのアロケータです。
96         //! @return シーンコンテキストを返します。
97         ParticleContext* Create(os::IAllocator* allocator);
98 
99     private:
100         bool m_IsFixedSizeMemory;
101         int m_MaxEmission;
102         int m_MaxStreamLength;
103         bool m_UseDoubleBuffer;
104     };
105 
106     //@}
107 
108     //----------------------------------------
109     //! @name 取得/設定
110     //@{
111 
112     //! @brief 放出時の位置のワークメモリの容量を取得します。
113     //! @return ワークメモリの容量を返します。
GetEmissionWorkCapacity()114     int GetEmissionWorkCapacity() const
115     {
116         return m_EmissionPositionWork.Capacity();
117     }
118 
119     //! @brief 放出時の位置のワークメモリを取得します。
120     //! @details requireSizeは、NW_MOVE_ARRAY_VARIABILITY_ENABLEDが有効な場合のみ機能します。
121     //! @param[in] requireSize 必要なサイズ
122     //! @return 放出時の位置のワークメモリを返します。
123     VEC3Array::iterator GetEmissionPositionWork(int requireSize = 0)
124     {
125 #ifdef NW_MOVE_ARRAY_VARIABILITY_ENABLED
126         if (m_EmissionPositionWork.GetArrayKind() == ut::ARRAY_VARIABILITY)
127         {
128             if (m_EmissionPositionWork.capacity() < requireSize)
129             {
130                 m_EmissionPositionWork.resize(requireSize);
131             }
132         }
133 #endif
134 
135         return m_EmissionPositionWork.Begin();
136     }
137 
138     //! @brief 放出時の親パーティクルのワークメモリを取得します。
139     //! @details requireSizeは、NW_MOVE_ARRAY_VARIABILITY_ENABLEDが有効な場合のみ機能します。
140     //! @param[in] requireSize 必要なサイズ
141     //! @return 放出時の親パーティクルのワークメモリを返します。
142     U16Array::iterator GetEmissionParentWork(int requireSize = 0)
143     {
144 #ifdef NW_MOVE_ARRAY_VARIABILITY_ENABLED
145         if (m_EmissionParentWork.GetArrayKind() == ut::ARRAY_VARIABILITY)
146         {
147             if (m_EmissionParentWork.capacity() < requireSize)
148             {
149                 m_EmissionParentWork.resize(requireSize);
150             }
151         }
152 #endif
153 
154         return m_EmissionParentWork.Begin();
155     }
156 
157     //! @brief パーティクルのストリーム処理用のワークメモリを取得します。
158     //! @return パーティクルのストリーム処理用のワークメモリを返します。
GetParticleWorkF32()159     F32Array::iterator GetParticleWorkF32()
160     {
161         return m_ParticleWorkF32.Begin();
162     }
163 
164     //! @brief ダブルバッファ時の複数回アップデート用のワークメモリを取得します。
165     //! @details requireSizeは、NW_MOVE_ARRAY_VARIABILITY_ENABLEDが有効な場合のみ機能します。
166     //! @param[in] requireSize 必要なサイズ
167     //! @return ダブルバッファ時の複数回アップデート用のワークメモリを返します。
168     VEC3Array::iterator GetPrevTranslateWork(int requireSize = 0)
169     {
170 #ifdef NW_MOVE_ARRAY_VARIABILITY_ENABLED
171         if (m_PrevTranslateWork.GetArrayKind() == ut::ARRAY_VARIABILITY)
172         {
173             if (m_PrevTranslateWork.capacity() < requireSize)
174             {
175                 m_PrevTranslateWork.resize(requireSize);
176             }
177         }
178 #endif
179 
180         return m_PrevTranslateWork.Begin();
181     }
182 
183     //! @brief ダブルバッファ時の複数回アップデート用のワークメモリの容量を取得します。
184     //! @details :private
185     //! @return ダブルバッファ時の複数回アップデート用のワークメモリの容量を返します。
GetPrevTranslateWorkCapacity()186     int GetPrevTranslateWorkCapacity() const
187     {
188         return m_PrevTranslateWork.Capacity();
189     }
190 
191     //! @brief 乱数種を設定します。
192     //!
193     //! @param[in] seed 乱数種です。
Srand(u32 seed)194     void Srand(u32 seed)
195     {
196         m_ParticleRandom.Srand(seed);
197     }
198 
199     //! @details :private
GetRandom()200     u16 GetRandom()
201     {
202         return m_ParticleRandom.Next(0xffff);
203     }
204 
205     //@}
206 
207 private:
ParticleContext(os::IAllocator * allocator,VEC3Array emissionPositionWork,U16Array emissionParentWork,F32Array particleWorkF32,VEC3Array prevTranslateWork)208     ParticleContext(
209         os::IAllocator* allocator,
210         VEC3Array emissionPositionWork,
211         U16Array emissionParentWork,
212         F32Array particleWorkF32,
213         VEC3Array prevTranslateWork)
214     : GfxObject(allocator),
215       m_EmissionPositionWork(emissionPositionWork),
216       m_EmissionParentWork(emissionParentWork),
217       m_ParticleWorkF32(particleWorkF32),
218       m_PrevTranslateWork(prevTranslateWork)
219     {}
~ParticleContext()220     virtual ~ParticleContext() {}
221 
222     VEC3Array m_EmissionPositionWork;
223     U16Array m_EmissionParentWork;
224     F32Array m_ParticleWorkF32;
225     VEC3Array m_PrevTranslateWork;
226 
227     ParticleRandom m_ParticleRandom;
228 };
229 
230 } // namespace gfx
231 } // namespace nw
232 
233 #endif // NW_GFX_PARTICLECONTEXT_H_
234