~smspillaz/nux/nux.fix_1036521

« back to all changes in this revision

Viewing changes to NuxCore/Math/MathUtility.h

  • Committer: Neil Jagdish Patel
  • Date: 2010-09-01 19:25:37 UTC
  • Revision ID: neil.patel@canonical.com-20100901192537-mfz7rm6q262pewg6
Import and build NuxCore

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef MATHUTILITY_H
 
2
#define MATHUTILITY_H
 
3
 
 
4
#include <cstdio>
 
5
#include <cstdlib>
 
6
#include <cstdarg>
 
7
#include <cmath>
 
8
#include <cstring>
 
9
#include <ctime>
 
10
 
 
11
#include "Constants.h"
 
12
 
 
13
NAMESPACE_BEGIN
 
14
    template< class T > inline T Max3( const T A, const T B, const T C )
 
15
    {
 
16
        return Max ( Max( A, B ), C );
 
17
    }
 
18
 
 
19
    template< class T > inline T Min3( const T A, const T B, const T C )
 
20
    {
 
21
        return Min ( Min( A, B ), C );
 
22
    }
 
23
 
 
24
    template< class T > inline T Square( const T A )
 
25
    {
 
26
        return A*A;
 
27
    }
 
28
    template< class T > inline T Clamp( const T X, const T Min, const T Max )
 
29
    {
 
30
        return X<Min ? Min : X<Max ? X : Max;
 
31
    }
 
32
 
 
33
    template< class T > inline T ClampUp( const T X, const T Min, const T Max )
 
34
    {
 
35
        return X<Min ? Min : X;
 
36
    }
 
37
 
 
38
    template< class T > inline T ClampDown( const T X, const T Max )
 
39
    {
 
40
        return X>Max ? Max : X;
 
41
    }
 
42
 
 
43
    template< class T > inline T Align( const T Ptr, int Alignment )
 
44
    {
 
45
        return (T)(((INL_POINTER)Ptr + Alignment - 1) & ~(Alignment-1));
 
46
    }
 
47
 
 
48
    //Bitwise rotation on the left. 
 
49
    template<typename T> inline const T Rol(const T& a,const unsigned int n=1) { return (a<<n)|(a>>((sizeof(T)<<3)-n)); }
 
50
    //Bitwise rotation on the right.
 
51
    template<typename T> inline const T Ror(const T& a,const unsigned int n=1) { return (a>>n)|(a<<((sizeof(T)<<3)-n)); }
 
52
 
 
53
    // Exchange the values of variables a and b
 
54
    template<typename T> inline void Swap(T& a,T& b) { const T t=a; a=b; b=t; }
 
55
    template<typename T> inline void Swap(T& a1,T& b1,T& a2,T& b2) { Swap(a1,b1); Swap(a2,b2); }
 
56
    template<typename T> inline void Swap(T& a1,T& b1,T& a2,T& b2,T& a3,T& b3) { Swap(a1,b1,a2,b2); Swap(a3,b3); }
 
57
    template<typename T> inline void Swap(T& a1,T& b1,T& a2,T& b2,T& a3,T& b3,T& a4,T& b4) { Swap(a1,b1,a2,b2,a3,b3); Swap(a4,b4); }
 
58
    template<typename T> inline void Swap(T& a1,T& b1,T& a2,T& b2,T& a3,T& b3,T& a4,T& b4,T& a5,T& b5)
 
59
    {
 
60
        Swap(a1,b1,a2,b2,a3,b3,a4,b4); Swap(a5,b5); 
 
61
    }
 
62
    template<typename T> inline void Swap(T& a1,T& b1,T& a2,T& b2,T& a3,T& b3,T& a4,T& b4,T& a5,T& b5,T& a6,T& b6)
 
63
    {
 
64
        Swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5); Swap(a6,b6);
 
65
    }
 
66
 
 
67
    //Return the absolute value of a. 
 
68
    template<typename T> inline const T Abs(const T& a) { return a>=0?a:-a; }
 
69
    //Return the minimum between a and b. 
 
70
    template<typename T> inline const T& Min(const T& a,const T& b) { return a<=b?a:b; }
 
71
    //Return the minimum between a, b and c. 
 
72
    template<typename T> inline const T& Min(const T& a,const T& b,const T& c) { return min(min(a,b),c); }
 
73
    //Return the minimum between a, b, c and d.
 
74
    template<typename T> inline const T& Min(const T& a,const T& b,const T& c,const T& d) { return min(min(min(a,b),c),d); }
 
75
    //Return the maximum between a and b. 
 
76
    template<typename T> inline const T& Max(const T& a,const T& b) { return a>=b?a:b; }
 
77
    //Return the maximum between a, b and c. 
 
78
    template<typename T> inline const T& Max(const T& a,const T& b,const T& c) { return max(max(a,b),c); }
 
79
    //Return the maximum between a,b,c and d. 
 
80
    template<typename T> inline const T& Max(const T& a,const T& b,const T& c,const T& d) { return max(max(a,b,c),d); }
 
81
    //Return the sign of x. 
 
82
    template<typename T> inline T Sign(const T& x) { return (x<0)?-1:(x==0?0:1); }
 
83
 
 
84
 
 
85
    template<typename T> inline T Modulo(const T& x,const T& m) { return x-m*(T)std::floor((double)x/m); }
 
86
 
 
87
    inline int ModuloInt(const int x,const int m) { return x>=0?x%m:(x%m?m+x%m:0); }
 
88
 
 
89
    template<typename T> inline T MinMod(const T& a,const T& b) { return a*b<=0?0:(a>0?(a<b?a:b):(a<b?b:a)); }
 
90
 
 
91
    //Return a random variable between [0,1] (uniform distribution). 
 
92
    inline double Random() { return (double)std::rand()/RAND_MAX; }
 
93
 
 
94
    //Return a random variable between [-1,1] (uniform distribution). 
 
95
    inline double CRandom() { return 1-2*std::rand(); }
 
96
 
 
97
    //Return a random variable using a gaussian distribution and a variance of 1. 
 
98
    inline double RandomGaussian() { return std::sqrt(-2*std::log((double)(1e-10 + (1-2e-10)*std::rand())))*std::cos((double)(2*3.14f/*Const::pi*/*std::rand())); }
 
99
 
 
100
    inline unsigned int RandomUInt() { return std::rand(); }
 
101
 
 
102
    inline unsigned int RandomUInt(unsigned int max_random) { return std::rand() % max_random; }
 
103
 
 
104
    inline t_size DiffPointer(void* Ptr0, void* Ptr1) {if((t_size)Ptr0 >= (t_size)Ptr1) return (t_size)((t_size)Ptr0 - (t_size)Ptr1); return (t_size)((t_size)Ptr1 - (t_size)Ptr0);}
 
105
    // Dangerous to use!
 
106
    template<typename T> inline T SubstractPointer(void* Ptr, t_size Value) {return (T)(((t_size)Ptr) - Value);}
 
107
    template<typename T> inline T AddPointer(void* Ptr, t_size Value) {return (T)(((t_size)Ptr) + Value);}
 
108
 
 
109
    //! Round up to the nearest multiple of Alignment that is greater or equal to Value
 
110
    /*!
 
111
        @param Alignment Must be a power of 2
 
112
    */
 
113
    template<typename T> inline T RoundUp(T Value, int Alignment)
 
114
    {   
 
115
        return (Value + (Alignment-1)) & ~(Alignment-1);
 
116
    }
 
117
 
 
118
    //! Round down to the nearest multiple of Alignment that is smaller or equal to Value
 
119
    /*!
 
120
        @param Alignment Must be a power of 2
 
121
    */
 
122
    template<typename T> inline T RoundDown(T Value, int Alignment)
 
123
    {   
 
124
        return ((Value) & ~(Alignment-1));
 
125
    }
 
126
 
 
127
    //! Return true is Value is aligned on Alignment
 
128
    /*!
 
129
        @param Alignment Must be a power of 2
 
130
    */
 
131
    template<typename T> inline bool IsAligned(T Value, int Alignment)
 
132
    {   
 
133
        return (((Value) & ~(Alignment-1)) == 0);
 
134
    }
 
135
 
 
136
    /*!
 
137
        Revert Byte order
 
138
        0x0011 -> 0x1100
 
139
    */
 
140
    inline t_u16 ReverseByteOrdering(t_u16 value)
 
141
    {
 
142
        t_u16 temp;
 
143
        t_u8 * src = (t_u8 *) &value;
 
144
        t_u8 * dest = (t_u8 *) &temp;
 
145
 
 
146
        dest[0] = src[1];
 
147
        dest[1] = src[0];
 
148
 
 
149
        return temp;
 
150
    }
 
151
 
 
152
    /*!
 
153
        Revert Byte order
 
154
        0x00112233 -> 0x33221100
 
155
    */
 
156
    inline t_u32 ReverseByteOrdering(t_u32 value)
 
157
    {
 
158
        t_u32 temp;
 
159
        t_u8 * src = (t_u8 *) &value;
 
160
        t_u8 * dest = (t_u8 *) &temp;
 
161
 
 
162
        dest[0] = src[3];
 
163
        dest[1] = src[2];
 
164
        dest[2] = src[1];
 
165
        dest[3] = src[0];
 
166
 
 
167
        return temp;
 
168
    }
 
169
 
 
170
    /*!
 
171
        Revert Byte order
 
172
        0x0011223344556677 -> 0x7766554433221100
 
173
    */
 
174
    inline t_u64 ReverseByteOrdering(t_u64 value)
 
175
    {
 
176
        t_u64 temp;
 
177
        t_u8 * src = (t_u8 *) &value;
 
178
        t_u8 * dest = (t_u8 *) &temp;
 
179
 
 
180
        dest[0] = src[7];
 
181
        dest[1] = src[6];
 
182
        dest[2] = src[5];
 
183
        dest[3] = src[4];
 
184
        dest[4] = src[3];
 
185
        dest[5] = src[2];
 
186
        dest[6] = src[1];
 
187
        dest[7] = src[0];
 
188
 
 
189
        return temp;
 
190
    }
 
191
 
 
192
    // Bit Hack
 
193
 
 
194
    // Determining if an integer is a power of 2
 
195
    // http://graphics.stanford.edu/~seander/bithacks.html
 
196
    inline bool IsPowerOf2(unsigned int n)
 
197
    {
 
198
        // The algorithm does not 0 consider 0 a power of two. (this is right)
 
199
        return !(n & (n - 1)) && n;
 
200
    }
 
201
 
 
202
    // Compute the next highest power of 2 of 32-bit v
 
203
    // http://graphics.stanford.edu/~seander/bithacks.html
 
204
    inline unsigned int NextPowerOfTwo(unsigned int x)
 
205
    {
 
206
        x = x - 1;
 
207
        x = x | (x >> 1);
 
208
        x = x | (x >> 2);
 
209
        x = x | (x >> 4);
 
210
        x = x | (x >> 8);
 
211
        x = x | (x >> 16);
 
212
        return x + 1;
 
213
    }
 
214
 
 
215
    inline unsigned int GetLowerPowerOfTwoExponent(unsigned int x)
 
216
    {
 
217
        int count = 0;
 
218
        while(x > 1)
 
219
        {
 
220
            x >>= 1;
 
221
            count++;
 
222
        }
 
223
        return count;
 
224
    }
 
225
 
 
226
    inline unsigned int PowerOfTwo(int i)
 
227
    {
 
228
        int e = 0;
 
229
        unsigned int power = 1;
 
230
        while(e < i)
 
231
        {
 
232
            power = power << 1;
 
233
            e++;
 
234
        }
 
235
        return power;
 
236
    }
 
237
 
 
238
    // ClearLSBBit(0x01001100) = 0x01001000
 
239
    inline unsigned int Hak32_ClearLSBBit(unsigned int N)
 
240
    {
 
241
        return N &(N-1);
 
242
    }
 
243
 
 
244
    // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
 
245
    // Hak32_CountNumBits(0x01001100) = 3
 
246
    inline unsigned int Hak32_CountNumBits(unsigned int N)
 
247
    {
 
248
        unsigned int v = N; // count the number of bits set in v
 
249
        unsigned int c; // c accumulates the total bits set in v
 
250
        for(c = 0; v; c++)
 
251
        {
 
252
            v &= v - 1; // clear the least significant bit set
 
253
        }
 
254
        return c;
 
255
    }
 
256
    
 
257
    // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan : Compute parity in parallel
 
258
    inline unsigned int Hak32_BitParity(unsigned int N)
 
259
    {
 
260
        unsigned int v = N;  // word value to compute the parity of
 
261
        v ^= v >> 16;
 
262
        v ^= v >> 8;
 
263
        v ^= v >> 4;
 
264
        v &= 0xf;
 
265
        return (0x6996 >> v) & 1;
 
266
    }
 
267
 
 
268
    #define HAK32_SWAP(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))
 
269
 
 
270
    // Return true if the CPU is little endian
 
271
    inline bool Hak32_CPULittleEndian()
 
272
    {
 
273
        const int x=1;
 
274
        return ((unsigned char*)&x)[0]? true : false;
 
275
    }
 
276
 
 
277
    // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
 
278
    // Find the log base 10 of an N-bit integer in O(lg(N))
 
279
    inline unsigned int Hak32_Log2(unsigned int N)
 
280
    {
 
281
        unsigned int v = N; // find the log base 2 of 32-bit v
 
282
        int r;          // result goes here
 
283
 
 
284
        static const int MultiplyDeBruijnBitPosition[32] = 
 
285
        {
 
286
            0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 
 
287
            31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
 
288
        };
 
289
 
 
290
        v |= v >> 1; // first round down to power of 2 
 
291
        v |= v >> 2;
 
292
        v |= v >> 4;
 
293
        v |= v >> 8;
 
294
        v |= v >> 16;
 
295
        v = (v >> 1) + 1;
 
296
 
 
297
        r = MultiplyDeBruijnBitPosition[static_cast<unsigned int>(v * 0x077CB531UL) >> 27];
 
298
        return r;
 
299
    }
 
300
 
 
301
    // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
 
302
    // Find the log base 2 of an N-bit integer in O(lg(N))
 
303
    inline unsigned int Hak32_Log10(unsigned int N)
 
304
    {
 
305
      unsigned int v = N; // non-zero 32-bit integer value to compute the log base 10 of 
 
306
      int r;          // result goes here
 
307
      int t;          // temporary
 
308
 
 
309
      static unsigned int const PowersOf10[] = 
 
310
      {1, 10, 100, 1000, 10000, 100000,
 
311
      1000000, 10000000, 100000000, 1000000000};
 
312
 
 
313
      t = (Hak32_Log2(v) + 1) * 1233 >> 12; // (use a lg2 method from above)
 
314
      r = t - (v < PowersOf10[t]);
 
315
 
 
316
      return r;
 
317
    }
 
318
 
 
319
    // http://graphics.stanford.edu/~seander/bithacks.html
 
320
    // Count the consecutive zero bits (trailing) on the right by binary search 
 
321
    inline unsigned int Hack32_TrailingZeroRight(unsigned int N)
 
322
    {
 
323
        unsigned int v = N;     // 32-bit word input to count zero bits on right
 
324
        unsigned int c;     // c will be the number of zero bits on the right,
 
325
        // so if v is 1101000 (base 2), then c will be 3
 
326
        // NOTE: if 0 == v, then c = 31.
 
327
        if (v & 0x1) 
 
328
        {
 
329
            // special case for odd v (assumed to happen half of the time)
 
330
            c = 0;
 
331
        }
 
332
        else
 
333
        {
 
334
            c = 1;
 
335
            if ((v & 0xffff) == 0) 
 
336
            {  
 
337
                v >>= 16;  
 
338
                c += 16;
 
339
            }
 
340
            if ((v & 0xff) == 0) 
 
341
            {  
 
342
                v >>= 8;  
 
343
                c += 8;
 
344
            }
 
345
            if ((v & 0xf) == 0) 
 
346
            {  
 
347
                v >>= 4;
 
348
                c += 4;
 
349
            }
 
350
            if ((v & 0x3) == 0) 
 
351
            {  
 
352
                v >>= 2;
 
353
                c += 2;
 
354
            }
 
355
            c -= v & 0x1;
 
356
        }       
 
357
        return c;
 
358
    }
 
359
 
 
360
NAMESPACE_END
 
361
 
 
362
#endif // MATHUTILITY_H