diff options
author | dan miller | 2007-10-19 05:24:38 +0000 |
---|---|---|
committer | dan miller | 2007-10-19 05:24:38 +0000 |
commit | f205de7847da7ae1c10212d82e7042d0100b4ce0 (patch) | |
tree | 9acc9608a6880502aaeda43af52c33e278e95b9c /libraries/ode-0.9/OPCODE/Ice/IceUtils.h | |
parent | trying to fix my screwup part deux (diff) | |
download | opensim-SC-f205de7847da7ae1c10212d82e7042d0100b4ce0.zip opensim-SC-f205de7847da7ae1c10212d82e7042d0100b4ce0.tar.gz opensim-SC-f205de7847da7ae1c10212d82e7042d0100b4ce0.tar.bz2 opensim-SC-f205de7847da7ae1c10212d82e7042d0100b4ce0.tar.xz |
from the start... checking in ode-0.9
Diffstat (limited to 'libraries/ode-0.9/OPCODE/Ice/IceUtils.h')
-rw-r--r-- | libraries/ode-0.9/OPCODE/Ice/IceUtils.h | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceUtils.h b/libraries/ode-0.9/OPCODE/Ice/IceUtils.h new file mode 100644 index 0000000..f4552ec --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceUtils.h | |||
@@ -0,0 +1,256 @@ | |||
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__ | ||