Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ode/ode-0.9/OPCODE/Ice/IceUtils.h @ 216

Last change on this file since 216 was 216, checked in by mathiask, 16 years ago

[Physik] add ode-0.9

File size: 10.7 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 *      Contains misc. useful macros & defines.
4 *      \file           IceUtils.h
5 *      \author         Pierre Terdiman (collected from various sources)
6 *      \date           April, 4, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11// Include Guard
12#ifndef __ICEUTILS_H__
13#define __ICEUTILS_H__
14
15        #define START_RUNONCE   { static bool __RunOnce__ = false;      if(!__RunOnce__){
16        #define END_RUNONCE             __RunOnce__ = true;}}
17
18        //! Reverse all the bits in a 32 bit word (from Steve Baker's Cute Code Collection)
19        //! (each line can be done in any order.
20        inline_ void    ReverseBits(udword& n)
21        {
22                n = ((n >>  1) & 0x55555555) | ((n <<  1) & 0xaaaaaaaa);
23                n = ((n >>  2) & 0x33333333) | ((n <<  2) & 0xcccccccc);
24                n = ((n >>  4) & 0x0f0f0f0f) | ((n <<  4) & 0xf0f0f0f0);
25                n = ((n >>  8) & 0x00ff00ff) | ((n <<  8) & 0xff00ff00);
26                n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);
27                // Etc for larger intergers (64 bits in Java)
28                // NOTE: the >> operation must be unsigned! (>>> in java)
29        }
30
31        //! Count the number of '1' bits in a 32 bit word (from Steve Baker's Cute Code Collection)
32        inline_ udword  CountBits(udword n)
33        {
34                // This relies of the fact that the count of n bits can NOT overflow
35                // an n bit interger. EG: 1 bit count takes a 1 bit interger, 2 bit counts
36                // 2 bit interger, 3 bit count requires only a 2 bit interger.
37                // So we add all bit pairs, then each nible, then each byte etc...
38                n = (n & 0x55555555) + ((n & 0xaaaaaaaa) >> 1);
39                n = (n & 0x33333333) + ((n & 0xcccccccc) >> 2);
40                n = (n & 0x0f0f0f0f) + ((n & 0xf0f0f0f0) >> 4);
41                n = (n & 0x00ff00ff) + ((n & 0xff00ff00) >> 8);
42                n = (n & 0x0000ffff) + ((n & 0xffff0000) >> 16);
43                // Etc for larger intergers (64 bits in Java)
44                // NOTE: the >> operation must be unsigned! (>>> in java)
45                return n;
46        }
47
48        //! Even faster?
49        inline_ udword  CountBits2(udword bits)
50        {
51                bits = bits - ((bits >> 1) & 0x55555555);
52                bits = ((bits >> 2) & 0x33333333) + (bits & 0x33333333);
53                bits = ((bits >> 4) + bits) & 0x0F0F0F0F;
54                return (bits * 0x01010101) >> 24;
55        }
56
57        //! Spread out bits.    EG      00001111  ->   0101010101
58        //!                                             00001010  ->   0100010000
59        //! This is used to interleve to intergers to produce a `Morten Key'
60        //! used in Space Filling Curves (See DrDobbs Journal, July 1999)
61        //! Order is important.
62        inline_ void    SpreadBits(udword& n)
63        {
64                n = ( n & 0x0000ffff) | (( n & 0xffff0000) << 16);
65                n = ( n & 0x000000ff) | (( n & 0x0000ff00) <<  8);
66                n = ( n & 0x000f000f) | (( n & 0x00f000f0) <<  4);
67                n = ( n & 0x03030303) | (( n & 0x0c0c0c0c) <<  2);
68                n = ( n & 0x11111111) | (( n & 0x22222222) <<  1);
69        }
70
71        // Next Largest Power of 2
72        // Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
73        // that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
74        // the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next
75        // largest power of 2. For a 32-bit value:
76        inline_ udword  nlpo2(udword x)
77        {
78                x |= (x >> 1);
79                x |= (x >> 2);
80                x |= (x >> 4);
81                x |= (x >> 8);
82                x |= (x >> 16);
83                return x+1;
84        }
85
86        //! Test to see if a number is an exact power of two (from Steve Baker's Cute Code Collection)
87        inline_ bool    IsPowerOfTwo(udword n)                          { return ((n&(n-1))==0);                                        }
88
89        //! Zero the least significant '1' bit in a word. (from Steve Baker's Cute Code Collection)
90        inline_ void    ZeroLeastSetBit(udword& n)                      { n&=(n-1);                                                                     }
91
92        //! Set the least significant N bits in a word. (from Steve Baker's Cute Code Collection)
93        inline_ void    SetLeastNBits(udword& x, udword n)      { x|=~(~0<<n);                                                          }
94
95        //! Classic XOR swap (from Steve Baker's Cute Code Collection)
96        //! x ^= y;             /* x' = (x^y) */
97        //! y ^= x;             /* y' = (y^(x^y)) = x */
98        //! x ^= y;             /* x' = (x^y)^x = y */
99        inline_ void    Swap(udword& x, udword& y)                      { x ^= y; y ^= x; x ^= y;                                       }
100
101        //! Little/Big endian (from Steve Baker's Cute Code Collection)
102        //!
103        //! Extra comments by Kenny Hoff:
104        //! Determines the byte-ordering of the current machine (little or big endian)
105        //! by setting an integer value to 1 (so least significant bit is now 1); take
106        //! the address of the int and cast to a byte pointer (treat integer as an
107        //! array of four bytes); check the value of the first byte (must be 0 or 1).
108        //! If the value is 1, then the first byte least significant byte and this
109        //! implies LITTLE endian. If the value is 0, the first byte is the most
110        //! significant byte, BIG endian. Examples:
111        //!      integer 1 on BIG endian: 00000000 00000000 00000000 00000001
112        //!   integer 1 on LITTLE endian: 00000001 00000000 00000000 00000000
113        //!---------------------------------------------------------------------------
114        //! int IsLittleEndian()        { int x=1;      return ( ((char*)(&x))[0] );    }
115        inline_ char    LittleEndian()                                          { int i = 1; return *((char*)&i);                       }
116
117        //!< Alternative abs function
118        inline_ udword  abs_(sdword x)                                  { sdword y= x >> 31;    return (x^y)-y;         }
119
120        //!< Alternative min function
121        inline_ sdword  min_(sdword a, sdword b)                        { sdword delta = b-a;   return a + (delta&(delta>>31)); }
122
123        // Determine if one of the bytes in a 4 byte word is zero
124        inline_ BOOL    HasNullByte(udword x)                   { return ((x + 0xfefefeff) & (~x) & 0x80808080);                }
125
126        // To find the smallest 1 bit in a word  EG: ~~~~~~10---0    =>    0----010---0
127        inline_ udword  LowestOneBit(udword w)                  { return ((w) & (~(w)+1));                                      }
128//      inline_ udword  LowestOneBit_(udword w)                 { return ((w) & (-(w)));                                        }
129
130        // Most Significant 1 Bit
131        // Given a binary integer value x, the most significant 1 bit (highest numbered element of a bit set)
132        // can be computed using a SWAR algorithm that recursively "folds" the upper bits into the lower bits.
133        // This process yields a bit vector with the same most significant 1 as x, but all 1's below it.
134         // Bitwise AND of the original value with the complement of the "folded" value shifted down by one
135        // yields the most significant bit. For a 32-bit value:
136        inline_ udword  msb32(udword x)
137        {
138                x |= (x >> 1);
139                x |= (x >> 2);
140                x |= (x >> 4);
141                x |= (x >> 8);
142                x |= (x >> 16);
143                return (x & ~(x >> 1));
144        }
145
146        /*
147        "Just call it repeatedly with various input values and always with the same variable as "memory".
148        The sharpness determines the degree of filtering, where 0 completely filters out the input, and 1
149        does no filtering at all.
150
151        I seem to recall from college that this is called an IIR (Infinite Impulse Response) filter. As opposed
152        to the more typical FIR (Finite Impulse Response).
153
154        Also, I'd say that you can make more intelligent and interesting filters than this, for example filters
155        that remove wrong responses from the mouse because it's being moved too fast. You'd want such a filter
156        to be applied before this one, of course."
157
158        (JCAB on Flipcode)
159        */
160        inline_ float   FeedbackFilter(float val, float& memory, float sharpness)
161        {
162                ASSERT(sharpness>=0.0f && sharpness<=1.0f && "Invalid sharpness value in feedback filter");
163                                if(sharpness<0.0f)      sharpness = 0.0f;
164                else    if(sharpness>1.0f)      sharpness = 1.0f;
165                return memory = val * sharpness + memory * (1.0f - sharpness);
166        }
167
168        //! If you can guarantee that your input domain (i.e. value of x) is slightly
169        //! limited (abs(x) must be < ((1<<31u)-32767)), then you can use the
170        //! following code to clamp the resulting value into [-32768,+32767] range:
171        inline_ int     ClampToInt16(int x)
172        {
173//              ASSERT(abs(x) < (int)((1<<31u)-32767));
174
175                int delta = 32767 - x;
176                x += (delta>>31) & delta;
177                delta = x + 32768;
178                x -= (delta>>31) & delta;
179                return x;
180        }
181
182        // Generic functions
183        template<class Type> inline_ void TSwap(Type& a, Type& b)                                                               { const Type c = a; a = b; b = c;                       }
184        template<class Type> inline_ Type TClamp(const Type& x, const Type& lo, const Type& hi) { return ((x<lo) ? lo : (x>hi) ? hi : x);       }
185
186        template<class Type> inline_ void TSort(Type& a, Type& b)
187        {
188                if(a>b) TSwap(a, b);
189        }
190
191        template<class Type> inline_ void TSort(Type& a, Type& b, Type& c)
192        {
193                if(a>b) TSwap(a, b);
194                if(b>c) TSwap(b, c);
195                if(a>b) TSwap(a, b);
196                if(b>c) TSwap(b, c);
197        }
198
199        // Prevent nasty user-manipulations (strategy borrowed from Charles Bloom)
200//      #define PREVENT_COPY(curclass)  void operator = (const curclass& object)        {       ASSERT(!"Bad use of operator =");       }
201        // ... actually this is better !
202        #define PREVENT_COPY(cur_class) private: cur_class(const cur_class& object);    cur_class& operator=(const cur_class& object);
203
204        //! TO BE DOCUMENTED
205        #define OFFSET_OF(Class, Member)        (size_t)&(((Class*)0)->Member)
206        //! TO BE DOCUMENTED
207        #define ARRAYSIZE(p)                            (sizeof(p)/sizeof(p[0]))
208
209        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
210        /**
211         *      Returns the alignment of the input address.
212         *      \fn                     Alignment()
213         *      \param          address [in] address to check
214         *      \return         the best alignment (e.g. 1 for odd addresses, etc)
215         */
216        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
217        FUNCTION ICECORE_API udword Alignment(udword address);
218
219        #define IS_ALIGNED_2(x)         ((x&1)==0)
220        #define IS_ALIGNED_4(x)         ((x&3)==0)
221        #define IS_ALIGNED_8(x)         ((x&7)==0)
222
223        inline_ void _prefetch(void const* ptr)         { (void)*(char const volatile *)ptr;    }
224
225        // Compute implicit coords from an index:
226        // The idea is to get back 2D coords from a 1D index.
227        // For example:
228        //
229        // 0            1               2       ...     nbu-1
230        // nbu          nbu+1   i       ...
231        //
232        // We have i, we're looking for the equivalent (u=2, v=1) location.
233        //              i = u + v*nbu
234        // <=>  i/nbu = u/nbu + v
235        // Since 0 <= u < nbu, u/nbu = 0 (integer)
236        // Hence: v = i/nbu
237        // Then we simply put it back in the original equation to compute u = i - v*nbu
238        inline_ void Compute2DCoords(udword& u, udword& v, udword i, udword nbu)
239        {
240                v = i / nbu;
241                u = i - (v * nbu);
242        }
243
244        // In 3D:       i = u + v*nbu + w*nbu*nbv
245        // <=>          i/(nbu*nbv) = u/(nbu*nbv) + v/nbv + w
246        // u/(nbu*nbv) is null since u/nbu was null already.
247        // v/nbv is null as well for the same reason.
248        // Hence w = i/(nbu*nbv)
249        // Then we're left with a 2D problem: i' = i - w*nbu*nbv = u + v*nbu
250        inline_ void Compute3DCoords(udword& u, udword& v, udword& w, udword i, udword nbu, udword nbu_nbv)
251        {
252                w = i / (nbu_nbv);
253                Compute2DCoords(u, v, i - (w * nbu_nbv), nbu);
254        }
255
256#endif // __ICEUTILS_H__
Note: See TracBrowser for help on using the repository browser.