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