1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_ParticleTime.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: 25420 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NW_GFX_PARTICLETIME_H_
17 #define NW_GFX_PARTICLETIME_H_
18 
19 #include <nw/math.h>
20 #include <nw/gfx/gfx_Common.h>
21 
22 //! この定義を有効にするとパーティクルの時間管理がf32になります。
23 //#define NW_GFX_NO_USE_PARTICLETIME
24 
25 namespace nw
26 {
27 namespace gfx
28 {
29 
30 #ifdef NW_GFX_PARTICLE_COMPAT_1_1
31 
32 //! @brief パーティクル処理用の時間の型です。
33 typedef f32 ParticleTime;
34 
35 #else
36 
37 #ifndef NW_GFX_NO_USE_PARTICLETIME
38 //--------------------------------------------------------------------------
39 //! @brief        パーティクル処理用の時間のユーティリティです。
40 //---------------------------------------------------------------------------
41 class ParticleTime
42 {
43     friend ParticleTime operator -(const ParticleTime& rhs);
44 
45 public:
46     //! @brief        デフォルトコンストラクタです。
47     ParticleTime() : m_ParticleTime(0) {}
48 
49     //! @brief        コンストラクタです。
50     //!
51     //! @param[in]    value   ParticleTimeです。
52     ParticleTime(const ParticleTime& value)
53     {
54         m_ParticleTime = value.m_ParticleTime;
55     }
56 
57     //! @brief        コンストラクタです。
58     //!
59     //! @param[in]    ivalue   整数値です。
60     ParticleTime(s32 value)
61     {
62         m_ParticleTime = S32ToParticleTime(value);
63     }
64 
65     //! @brief        コンストラクタです。
66     //!
67     //! @param[in]    fvalue   32bit 浮動小数の値です。
68     ParticleTime(f32 value)
69     {
70         m_ParticleTime = Float32ToParticleTime(value);
71     }
72 
73     //! @brief        浮動小数点数で値を取得します。
74     //! @return       値を浮動小数点数で返します。
75     f32     GetFloat32Value() const { return ParticleTimeToFloat32(m_ParticleTime); }
76 
77     //! @brief        符号付き整数で値を取得します。
78     //! @return       値を符号付き整数で返します。
79     s32     GetS32Value() const { return m_ParticleTime / 0x100; }
80 
81     //! @brief        内部表現で値を取得します。
82     //! @details :private
83     //! @return       値を内部表現で返します。
84     s32     GetParticleTimeValue() const { return m_ParticleTime; }
85 
86     ParticleTime operator +(ParticleTime right) const
87     {
88         ParticleTime result;
89         result.m_ParticleTime = this->m_ParticleTime + right.m_ParticleTime;
90         return result;
91     }
92 
93     ParticleTime operator -(ParticleTime right) const
94     {
95         ParticleTime result;
96         result.m_ParticleTime = this->m_ParticleTime - right.m_ParticleTime;
97         return result;
98     }
99 
100     //! @brief        整数部を取得します。
101     //! @return       整数部を符号付き整数で返します。
102     s32 GetIntegralParts() const
103     {
104         return m_ParticleTime / 0x100;
105     }
106 
107     //! @brief        小数部を取得します。
108     //! @return       小数部を浮動小数点数で返します。
109     f32 GetFractionalParts() const
110     {
111         return (m_ParticleTime & 0xff) / 0x100;
112     }
113 
114     //! @brief        格納している値を超えない最大の整数を取得します。
115     //! @return       格納している値を超えない最大の整数を返します。
116     s32 Floor() const
117     {
118         return m_ParticleTime / 0x100;
119     }
120 
121     //! @brief        格納している値を下回らない最小の整数を取得します。
122     //! @return       格納している値を下回らない最小の整数を返します。
123     s32 Ceil() const
124     {
125         return (m_ParticleTime + 0xff) / 0x100;
126     }
127 
128     //! @brief        格納している値の剰余を取得します。
129     //! @param[in] value 格納している値を割る値です。
130     //! @return       剰余をParticleTimeで返します。
131     ParticleTime& FMod(s32 value)
132     {
133         this->m_ParticleTime %= S32ToParticleTime(value);
134         return *this;
135     }
136 
137     ParticleTime& operator =(f32 value) { this->m_ParticleTime = Float32ToParticleTime(value); return *this; }
138     ParticleTime& operator =(s32 value) { this->m_ParticleTime = S32ToParticleTime(value); return *this; }
139     ParticleTime& operator =(ParticleTime value) { this->m_ParticleTime = value.m_ParticleTime; return *this; }
140     ParticleTime& operator +=(f32 value) { this->m_ParticleTime += Float32ToParticleTime(value); return *this; }
141     ParticleTime& operator +=(s32 value) { this->m_ParticleTime += S32ToParticleTime(value); return *this; }
142     ParticleTime& operator +=(ParticleTime value) { this->m_ParticleTime += value.m_ParticleTime; return *this; }
143     ParticleTime& operator -=(f32 value) { this->m_ParticleTime -= Float32ToParticleTime(value); return *this; }
144     ParticleTime& operator -=(s32 value) { this->m_ParticleTime -= S32ToParticleTime(value); return *this; }
145     ParticleTime& operator -=(ParticleTime value) { this->m_ParticleTime -= value.m_ParticleTime; return *this; }
146 
147     bool operator ==(const ParticleTime& rhs) const { return this->m_ParticleTime == rhs.m_ParticleTime; }
148     bool operator !=(const ParticleTime& rhs) const { return this->m_ParticleTime == rhs.m_ParticleTime; }
149     bool operator >=(const ParticleTime& rhs) const { return this->m_ParticleTime >= rhs.m_ParticleTime; }
150     bool operator <=(const ParticleTime& rhs) const { return this->m_ParticleTime <= rhs.m_ParticleTime; }
151     bool operator >(const ParticleTime& rhs) const { return this->m_ParticleTime > rhs.m_ParticleTime; }
152     bool operator <(const ParticleTime& rhs) const { return this->m_ParticleTime < rhs.m_ParticleTime; }
153 
154     bool operator ==(s32 rhs) const { return this->m_ParticleTime == S32ToParticleTime(rhs); }
155     bool operator !=(s32 rhs) const { return this->m_ParticleTime == S32ToParticleTime(rhs); }
156     bool operator >=(s32 rhs) const { return this->m_ParticleTime >= S32ToParticleTime(rhs); }
157     bool operator <=(s32 rhs) const { return this->m_ParticleTime <= S32ToParticleTime(rhs); }
158     bool operator >(s32 rhs) const { return this->m_ParticleTime > S32ToParticleTime(rhs); }
159     bool operator <(s32 rhs) const { return this->m_ParticleTime < S32ToParticleTime(rhs); }
160 
161     // 暗黙的にf32に変換されると遅くなるので、f32への変換は用意していない
162 
163     //! @detail :private
164     //! lengthで割ってからfactorを掛ける
165     //! オーバーフローを考慮していないので16ビット程度の値に留めること
166     ParticleTime Interp(const ParticleTime& length, s32 factor) const
167     {
168         s32 work = this->m_ParticleTime * factor * 0x100;
169         work /= length.m_ParticleTime;
170 
171         ParticleTime result;
172         result.m_ParticleTime = work;
173         return result;
174     }
175 
176     //! @brief        パーティクル用時間から 32bit float に変換します。
177     //! @param[in]    particleTime   パーティクル用時間を表現した整数値です。
178     //! @return       f32 に変換した値を返します。
179     static f32 ParticleTimeToFloat32(s32 particleTime)
180     {
181         f32 float32 = static_cast<f32>(particleTime);
182         return float32 / 0x100;
183     }
184 
185     //! @brief        f32 からパーティクル用時間に変換します。
186     //! @param[in]    value   32bit float の値です。
187     //! @return       パーティクル用時間を返します。
188     static s32 Float32ToParticleTime(f32 value)
189     {
190         s32 fixed = (int)(value * 0x100);
191         return fixed;
192     }
193 
194     //! @brief        s32 からパーティクル用時間に変換します。
195     //! @param[in]    value   32bit signed int の値です。
196     //! @return       パーティクル用時間を返します。
197     static s32 S32ToParticleTime(s32 value)
198     {
199         return value * 0x100;
200     }
201 
202 private:
203     s32 m_ParticleTime;
204 };
205 
206 NW_FORCE_INLINE ParticleTime operator -(const ParticleTime& rhs)
207 {
208     ParticleTime result;
209     result.m_ParticleTime = -rhs.m_ParticleTime;
210     return result;
211 }
212 
213 #else // f32と互換にします
214 
215 //--------------------------------------------------------------------------
216 //! @brief        パーティクル処理用の時間のユーティリティです。
217 //---------------------------------------------------------------------------
218 class ParticleTime
219 {
220     friend ParticleTime operator -(const ParticleTime& rhs);
221 
222 public:
223     //! @brief        デフォルトコンストラクタです。
224     ParticleTime() : m_ParticleTime(0) {}
225 
226     //! @brief        コンストラクタです。
227     //! @param[in]    value   ParticleTimeです。
228     ParticleTime(const ParticleTime& value)
229     {
230         m_ParticleTime = value.m_ParticleTime;
231     }
232 
233     //! @brief        コンストラクタです。
234     //! @param[in]    ivalue   整数値です。
235     ParticleTime(s32 ivalue)
236     {
237         m_ParticleTime = ivalue;
238     }
239 
240     //! @brief        コンストラクタです。
241     //! @param[in]    fvalue   32bit 浮動小数の値です。
242     ParticleTime(f32 fvalue)
243     {
244         m_ParticleTime = Float32ToParticleTime(fvalue);
245     }
246 
247     //! @brief        浮動小数点数で値を取得します。
248     //! @return       値を浮動小数点数で返します。
249     f32     GetFloat32Value() const { return m_ParticleTime; }
250 
251     //! @brief        符号付き整数で値を取得します。
252     //! @return       値を符号付き整数で返します。
253     s32     GetS32Value() const { return m_ParticleTime; }
254 
255     //! @brief        内部表現で値を取得します。
256     //! @details :private
257     //! @return       値を内部表現で返します。
258     f32     GetParticleTimeValue() const { return m_ParticleTime; }
259 
260     ParticleTime operator +(ParticleTime right) const
261     {
262         return ParticleTime(this->m_ParticleTime + right.m_ParticleTime);
263     }
264 
265     ParticleTime operator -(ParticleTime right) const
266     {
267         return ParticleTime(this->m_ParticleTime - right.m_ParticleTime);
268     }
269 
270     //! @brief        整数部を取得します。
271     //! @return       整数部を符号付き整数で返します。
272     s32 GetIntegralParts() const
273     {
274         return (int)m_ParticleTime;
275     }
276 
277     //! @brief        小数部を取得します。
278     //! @return       小数部を浮動小数点数で返します。
279     f32 GetFractionalParts() const
280     {
281         return m_ParticleTime - (int)m_ParticleTime;
282     }
283 
284     //! @brief        格納している値を超えない最大の整数を取得します。
285     //! @return       格納している値を超えない最大の整数を返します。
286     s32 Floor() const
287     {
288         return math::FFloor(m_ParticleTime);
289     }
290 
291     //! @brief        格納している値を下回らない最小の整数を取得します。
292     //! @return       格納している値を下回らない最小の整数を返します。
293     s32 Ceil() const
294     {
295         return math::FCeil(m_ParticleTime);
296     }
297 
298     //! @brief        格納している値の剰余を取得します。
299     //! @param[in] value 格納している値を割る値です。
300     //! @return       剰余をParticleTimeで返します。
301     ParticleTime& FMod(s32 value)
302     {
303         this->m_ParticleTime = nw::math::FMod(this->m_ParticleTime, static_cast<f32>(value));
304         return *this;
305     }
306 
307     ParticleTime& operator =(f32 value) { this->m_ParticleTime = Float32ToParticleTime(value); return *this; }
308     ParticleTime& operator =(s32 value) { this->m_ParticleTime = value; return *this; }
309     ParticleTime& operator =(ParticleTime value) { this->m_ParticleTime = value.m_ParticleTime; return *this; }
310     ParticleTime& operator +=(f32 value) { this->m_ParticleTime += value; return *this; }
311     ParticleTime& operator +=(s32 value) { this->m_ParticleTime += value; return *this; }
312     ParticleTime& operator +=(ParticleTime value) { this->m_ParticleTime += value.m_ParticleTime; return *this; }
313     ParticleTime& operator -=(f32 value) { this->m_ParticleTime -= value; return *this; }
314     ParticleTime& operator -=(s32 value) { this->m_ParticleTime -= value; return *this; }
315     ParticleTime& operator -=(ParticleTime value) { this->m_ParticleTime -= value.m_ParticleTime; return *this; }
316 
317     bool operator ==(const ParticleTime& rhs) const { return this->m_ParticleTime == rhs.m_ParticleTime; }
318     bool operator !=(const ParticleTime& rhs) const { return this->m_ParticleTime == rhs.m_ParticleTime; }
319     bool operator >=(const ParticleTime& rhs) const { return this->m_ParticleTime >= rhs.m_ParticleTime; }
320     bool operator <=(const ParticleTime& rhs) const { return this->m_ParticleTime <= rhs.m_ParticleTime; }
321     bool operator >(const ParticleTime& rhs) const { return this->m_ParticleTime > rhs.m_ParticleTime; }
322     bool operator <(const ParticleTime& rhs) const { return this->m_ParticleTime < rhs.m_ParticleTime; }
323 
324     bool operator ==(s32 rhs) const { return this->m_ParticleTime == rhs; }
325     bool operator !=(s32 rhs) const { return this->m_ParticleTime == rhs; }
326     bool operator >=(s32 rhs) const { return this->m_ParticleTime >= rhs; }
327     bool operator <=(s32 rhs) const { return this->m_ParticleTime <= rhs; }
328     bool operator >(s32 rhs) const { return this->m_ParticleTime > rhs; }
329     bool operator <(s32 rhs) const { return this->m_ParticleTime < rhs; }
330 
331     // 暗黙的にf32に変換されると遅くなるので、f32への変換は用意していない
332 
333     ParticleTime Interp(const ParticleTime& length, s32 factor) const
334     {
335         return ParticleTime(this->GetFloat32Value() / length.GetFloat32Value() * factor);
336     }
337 
338     //! @brief        パーティクル用時間から 32bit float に変換します。
339     //! @param[in]    particleTime   パーティクル用時間を表現した整数値です。
340     //! @return       f32 に変換した値を返します。
341     static f32 ParticleTimeToFloat32(f32 particleTime)
342     {
343         return particleTime;
344     }
345 
346     //! @brief        f32 からパーティクル用時間に変換します。
347     //! @param[in]    value   32bit float の値です。
348     //! @return       パーティクル用時間を返します。
349     static f32 Float32ToParticleTime(f32 value)
350     {
351         return value;
352     }
353 
354 private:
355     f32 m_ParticleTime;
356 };
357 
358 NW_FORCE_INLINE ParticleTime operator -(const ParticleTime& rhs)
359 {
360     return ParticleTime(-rhs.m_ParticleTime);
361 }
362 
363 
364 #endif
365 #endif
366 
367 } // namespace gfx
368 } // namespace nw
369 
370 #endif // NW_GFX_PARTICLETIME_H_
371