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: 28534 $
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     ParticleTime operator *(ParticleTime right) const
101     {
102         ParticleTime result;
103         result.m_ParticleTime = (this->m_ParticleTime / right.m_ParticleTime) / 0x100;
104         return result;
105     }
106 
107     ParticleTime operator /(ParticleTime right) const
108     {
109         ParticleTime result;
110         result.m_ParticleTime = 0x100 * this->m_ParticleTime / right.m_ParticleTime;
111         return result;
112     }
113 
114     //! @brief        整数部を取得します。
115     //! @return       整数部を符号付き整数で返します。
116     s32 GetIntegralParts() const
117     {
118         return m_ParticleTime / 0x100;
119     }
120 
121     //! @brief        小数部を取得します。
122     //! @return       小数部を浮動小数点数で返します。
123     f32 GetFractionalParts() const
124     {
125         return (m_ParticleTime & 0xff) / 0x100;
126     }
127 
128     //! @brief        格納している値を超えない最大の整数を取得します。
129     //! @return       格納している値を超えない最大の整数を返します。
130     s32 Floor() const
131     {
132         return m_ParticleTime / 0x100;
133     }
134 
135     //! @brief        格納している値を下回らない最小の整数を取得します。
136     //! @return       格納している値を下回らない最小の整数を返します。
137     s32 Ceil() const
138     {
139         return (m_ParticleTime + 0xff) / 0x100;
140     }
141 
142     //! @brief        格納している値の剰余を取得します。
143     //! @param[in] value 格納している値を割る値です。
144     //! @return       剰余をParticleTimeで返します。
145     ParticleTime& FMod(s32 value)
146     {
147         this->m_ParticleTime %= S32ToParticleTime(value);
148         return *this;
149     }
150 
151     ParticleTime& operator =(f32 value) { this->m_ParticleTime = Float32ToParticleTime(value); return *this; }
152     ParticleTime& operator =(s32 value) { this->m_ParticleTime = S32ToParticleTime(value); return *this; }
153     ParticleTime& operator =(ParticleTime value) { this->m_ParticleTime = value.m_ParticleTime; return *this; }
154     ParticleTime& operator +=(f32 value) { this->m_ParticleTime += Float32ToParticleTime(value); return *this; }
155     ParticleTime& operator +=(s32 value) { this->m_ParticleTime += S32ToParticleTime(value); return *this; }
156     ParticleTime& operator +=(ParticleTime value) { this->m_ParticleTime += value.m_ParticleTime; return *this; }
157     ParticleTime& operator -=(f32 value) { this->m_ParticleTime -= Float32ToParticleTime(value); return *this; }
158     ParticleTime& operator -=(s32 value) { this->m_ParticleTime -= S32ToParticleTime(value); return *this; }
159     ParticleTime& operator -=(ParticleTime value) { this->m_ParticleTime -= value.m_ParticleTime; return *this; }
160 
161     bool operator ==(const ParticleTime& rhs) const { return this->m_ParticleTime == rhs.m_ParticleTime; }
162     bool operator !=(const ParticleTime& rhs) const { return this->m_ParticleTime == rhs.m_ParticleTime; }
163     bool operator >=(const ParticleTime& rhs) const { return this->m_ParticleTime >= rhs.m_ParticleTime; }
164     bool operator <=(const ParticleTime& rhs) const { return this->m_ParticleTime <= rhs.m_ParticleTime; }
165     bool operator >(const ParticleTime& rhs) const { return this->m_ParticleTime > rhs.m_ParticleTime; }
166     bool operator <(const ParticleTime& rhs) const { return this->m_ParticleTime < rhs.m_ParticleTime; }
167 
168     bool operator ==(s32 rhs) const { return this->m_ParticleTime == S32ToParticleTime(rhs); }
169     bool operator !=(s32 rhs) const { return this->m_ParticleTime == S32ToParticleTime(rhs); }
170     bool operator >=(s32 rhs) const { return this->m_ParticleTime >= S32ToParticleTime(rhs); }
171     bool operator <=(s32 rhs) const { return this->m_ParticleTime <= S32ToParticleTime(rhs); }
172     bool operator >(s32 rhs) const { return this->m_ParticleTime > S32ToParticleTime(rhs); }
173     bool operator <(s32 rhs) const { return this->m_ParticleTime < S32ToParticleTime(rhs); }
174 
175     // 暗黙的にf32に変換されると遅くなるので、f32への変換は用意していない
176 
177     //! @detail :private
178     //! lengthで割ってからfactorを掛ける
179     //! オーバーフローを考慮していないので16ビット程度の値に留めること
180     ParticleTime Interp(const ParticleTime& length, s32 factor) const
181     {
182         s32 work = this->m_ParticleTime * factor * 0x100;
183         work /= length.m_ParticleTime;
184 
185         ParticleTime result;
186         result.m_ParticleTime = work;
187         return result;
188     }
189 
190     //! @brief        パーティクル用時間から 32bit float に変換します。
191     //! @param[in]    particleTime   パーティクル用時間を表現した整数値です。
192     //! @return       f32 に変換した値を返します。
193     static f32 ParticleTimeToFloat32(s32 particleTime)
194     {
195         f32 float32 = static_cast<f32>(particleTime);
196         return float32 / 0x100;
197     }
198 
199     //! @brief        f32 からパーティクル用時間に変換します。
200     //! @param[in]    value   32bit float の値です。
201     //! @return       パーティクル用時間を返します。
202     static s32 Float32ToParticleTime(f32 value)
203     {
204         s32 fixed = (int)(value * 0x100);
205         return fixed;
206     }
207 
208     //! @brief        s32 からパーティクル用時間に変換します。
209     //! @param[in]    value   32bit signed int の値です。
210     //! @return       パーティクル用時間を返します。
211     static s32 S32ToParticleTime(s32 value)
212     {
213         return value * 0x100;
214     }
215 
216 private:
217     s32 m_ParticleTime;
218 };
219 
220 NW_FORCE_INLINE ParticleTime operator -(const ParticleTime& rhs)
221 {
222     ParticleTime result;
223     result.m_ParticleTime = -rhs.m_ParticleTime;
224     return result;
225 }
226 
227 #else // f32と互換にします
228 
229 //--------------------------------------------------------------------------
230 //! @brief        パーティクル処理用の時間のユーティリティです。
231 //---------------------------------------------------------------------------
232 class ParticleTime
233 {
234     friend ParticleTime operator -(const ParticleTime& rhs);
235 
236 public:
237     //! @brief        デフォルトコンストラクタです。
238     ParticleTime() : m_ParticleTime(0) {}
239 
240     //! @brief        コンストラクタです。
241     //! @param[in]    value   ParticleTimeです。
242     ParticleTime(const ParticleTime& value)
243     {
244         m_ParticleTime = value.m_ParticleTime;
245     }
246 
247     //! @brief        コンストラクタです。
248     //! @param[in]    ivalue   整数値です。
249     ParticleTime(s32 ivalue)
250     {
251         m_ParticleTime = ivalue;
252     }
253 
254     //! @brief        コンストラクタです。
255     //! @param[in]    fvalue   32bit 浮動小数の値です。
256     ParticleTime(f32 fvalue)
257     {
258         m_ParticleTime = Float32ToParticleTime(fvalue);
259     }
260 
261     //! @brief        浮動小数点数で値を取得します。
262     //! @return       値を浮動小数点数で返します。
263     f32     GetFloat32Value() const { return m_ParticleTime; }
264 
265     //! @brief        符号付き整数で値を取得します。
266     //! @return       値を符号付き整数で返します。
267     s32     GetS32Value() const { return m_ParticleTime; }
268 
269     //! @brief        内部表現で値を取得します。
270     //! @details :private
271     //! @return       値を内部表現で返します。
272     f32     GetParticleTimeValue() const { return m_ParticleTime; }
273 
274     ParticleTime operator +(ParticleTime right) const
275     {
276         return ParticleTime(this->m_ParticleTime + right.m_ParticleTime);
277     }
278 
279     ParticleTime operator -(ParticleTime right) const
280     {
281         return ParticleTime(this->m_ParticleTime - right.m_ParticleTime);
282     }
283 
284     //! @brief        整数部を取得します。
285     //! @return       整数部を符号付き整数で返します。
286     s32 GetIntegralParts() const
287     {
288         return (int)m_ParticleTime;
289     }
290 
291     //! @brief        小数部を取得します。
292     //! @return       小数部を浮動小数点数で返します。
293     f32 GetFractionalParts() const
294     {
295         return m_ParticleTime - (int)m_ParticleTime;
296     }
297 
298     //! @brief        格納している値を超えない最大の整数を取得します。
299     //! @return       格納している値を超えない最大の整数を返します。
300     s32 Floor() const
301     {
302         return math::FFloor(m_ParticleTime);
303     }
304 
305     //! @brief        格納している値を下回らない最小の整数を取得します。
306     //! @return       格納している値を下回らない最小の整数を返します。
307     s32 Ceil() const
308     {
309         return math::FCeil(m_ParticleTime);
310     }
311 
312     //! @brief        格納している値の剰余を取得します。
313     //! @param[in] value 格納している値を割る値です。
314     //! @return       剰余をParticleTimeで返します。
315     ParticleTime& FMod(s32 value)
316     {
317         this->m_ParticleTime = nw::math::FMod(this->m_ParticleTime, static_cast<f32>(value));
318         return *this;
319     }
320 
321     ParticleTime& operator =(f32 value) { this->m_ParticleTime = Float32ToParticleTime(value); return *this; }
322     ParticleTime& operator =(s32 value) { this->m_ParticleTime = value; return *this; }
323     ParticleTime& operator =(ParticleTime value) { this->m_ParticleTime = value.m_ParticleTime; return *this; }
324     ParticleTime& operator +=(f32 value) { this->m_ParticleTime += value; return *this; }
325     ParticleTime& operator +=(s32 value) { this->m_ParticleTime += value; return *this; }
326     ParticleTime& operator +=(ParticleTime value) { this->m_ParticleTime += value.m_ParticleTime; return *this; }
327     ParticleTime& operator -=(f32 value) { this->m_ParticleTime -= value; return *this; }
328     ParticleTime& operator -=(s32 value) { this->m_ParticleTime -= value; return *this; }
329     ParticleTime& operator -=(ParticleTime value) { this->m_ParticleTime -= value.m_ParticleTime; return *this; }
330 
331     bool operator ==(const ParticleTime& rhs) const { return this->m_ParticleTime == rhs.m_ParticleTime; }
332     bool operator !=(const ParticleTime& rhs) const { return this->m_ParticleTime == rhs.m_ParticleTime; }
333     bool operator >=(const ParticleTime& rhs) const { return this->m_ParticleTime >= rhs.m_ParticleTime; }
334     bool operator <=(const ParticleTime& rhs) const { return this->m_ParticleTime <= rhs.m_ParticleTime; }
335     bool operator >(const ParticleTime& rhs) const { return this->m_ParticleTime > rhs.m_ParticleTime; }
336     bool operator <(const ParticleTime& rhs) const { return this->m_ParticleTime < rhs.m_ParticleTime; }
337 
338     bool operator ==(s32 rhs) const { return this->m_ParticleTime == rhs; }
339     bool operator !=(s32 rhs) const { return this->m_ParticleTime == rhs; }
340     bool operator >=(s32 rhs) const { return this->m_ParticleTime >= rhs; }
341     bool operator <=(s32 rhs) const { return this->m_ParticleTime <= rhs; }
342     bool operator >(s32 rhs) const { return this->m_ParticleTime > rhs; }
343     bool operator <(s32 rhs) const { return this->m_ParticleTime < rhs; }
344 
345     // 暗黙的にf32に変換されると遅くなるので、f32への変換は用意していない
346 
347     ParticleTime Interp(const ParticleTime& length, s32 factor) const
348     {
349         return ParticleTime(this->GetFloat32Value() / length.GetFloat32Value() * factor);
350     }
351 
352     //! @brief        パーティクル用時間から 32bit float に変換します。
353     //! @param[in]    particleTime   パーティクル用時間を表現した整数値です。
354     //! @return       f32 に変換した値を返します。
355     static f32 ParticleTimeToFloat32(f32 particleTime)
356     {
357         return particleTime;
358     }
359 
360     //! @brief        f32 からパーティクル用時間に変換します。
361     //! @param[in]    value   32bit float の値です。
362     //! @return       パーティクル用時間を返します。
363     static f32 Float32ToParticleTime(f32 value)
364     {
365         return value;
366     }
367 
368 private:
369     f32 m_ParticleTime;
370 };
371 
372 NW_FORCE_INLINE ParticleTime operator -(const ParticleTime& rhs)
373 {
374     return ParticleTime(-rhs.m_ParticleTime);
375 }
376 
377 
378 #endif
379 #endif
380 
381 } // namespace gfx
382 } // namespace nw
383 
384 #endif // NW_GFX_PARTICLETIME_H_
385