diff options
Diffstat (limited to 'linden/indra/llmath/llmath.h')
-rw-r--r-- | linden/indra/llmath/llmath.h | 90 |
1 files changed, 44 insertions, 46 deletions
diff --git a/linden/indra/llmath/llmath.h b/linden/indra/llmath/llmath.h index b2d4d26..9f8e539 100644 --- a/linden/indra/llmath/llmath.h +++ b/linden/indra/llmath/llmath.h | |||
@@ -17,7 +17,8 @@ | |||
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | 20 | * online at |
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | 22 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 23 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 24 | * that you have read and understood your obligations described above, |
@@ -37,6 +38,10 @@ | |||
37 | #include "lldefs.h" | 38 | #include "lldefs.h" |
38 | #include "llstl.h" // *TODO: Remove when LLString is gone | 39 | #include "llstl.h" // *TODO: Remove when LLString is gone |
39 | #include "llstring.h" // *TODO: Remove when LLString is gone | 40 | #include "llstring.h" // *TODO: Remove when LLString is gone |
41 | // lltut.h uses is_approx_equal_fraction(). This was moved to its own header | ||
42 | // file in llcommon so we can use lltut.h for llcommon tests without making | ||
43 | // llcommon depend on llmath. | ||
44 | #include "is_approx_equal_fraction.h" | ||
40 | 45 | ||
41 | // work around for Windows & older gcc non-standard function names. | 46 | // work around for Windows & older gcc non-standard function names. |
42 | #if LL_WINDOWS | 47 | #if LL_WINDOWS |
@@ -55,9 +60,7 @@ | |||
55 | #endif | 60 | #endif |
56 | 61 | ||
57 | // Single Precision Floating Point Routines | 62 | // Single Precision Floating Point Routines |
58 | #ifndef fsqrtf | 63 | #if _MSC_VER < 1400 |
59 | #define fsqrtf(x) ((F32)sqrt((F64)(x))) | ||
60 | #endif | ||
61 | #ifndef sqrtf | 64 | #ifndef sqrtf |
62 | #define sqrtf(x) ((F32)sqrt((F64)(x))) | 65 | #define sqrtf(x) ((F32)sqrt((F64)(x))) |
63 | #endif | 66 | #endif |
@@ -78,6 +81,11 @@ | |||
78 | #ifndef powf | 81 | #ifndef powf |
79 | #define powf(x,y) ((F32)pow((F64)(x),(F64)(y))) | 82 | #define powf(x,y) ((F32)pow((F64)(x),(F64)(y))) |
80 | #endif | 83 | #endif |
84 | #endif | ||
85 | |||
86 | #ifndef fsqrtf | ||
87 | #define fsqrtf(x) sqrtf(x) | ||
88 | #endif | ||
81 | 89 | ||
82 | const F32 GRAVITY = -9.8f; | 90 | const F32 GRAVITY = -9.8f; |
83 | 91 | ||
@@ -85,6 +93,8 @@ const F32 GRAVITY = -9.8f; | |||
85 | const F32 F_PI = 3.1415926535897932384626433832795f; | 93 | const F32 F_PI = 3.1415926535897932384626433832795f; |
86 | const F32 F_TWO_PI = 6.283185307179586476925286766559f; | 94 | const F32 F_TWO_PI = 6.283185307179586476925286766559f; |
87 | const F32 F_PI_BY_TWO = 1.5707963267948966192313216916398f; | 95 | const F32 F_PI_BY_TWO = 1.5707963267948966192313216916398f; |
96 | const F32 F_SQRT_TWO_PI = 2.506628274631000502415765284811f; | ||
97 | const F32 F_E = 2.71828182845904523536f; | ||
88 | const F32 F_SQRT2 = 1.4142135623730950488016887242097f; | 98 | const F32 F_SQRT2 = 1.4142135623730950488016887242097f; |
89 | const F32 F_SQRT3 = 1.73205080756888288657986402541f; | 99 | const F32 F_SQRT3 = 1.73205080756888288657986402541f; |
90 | const F32 OO_SQRT2 = 0.7071067811865475244008443621049f; | 100 | const F32 OO_SQRT2 = 0.7071067811865475244008443621049f; |
@@ -103,6 +113,30 @@ const F32 FP_MAG_THRESHOLD = 0.0000001f; | |||
103 | // TODO: Replace with logic like is_approx_equal | 113 | // TODO: Replace with logic like is_approx_equal |
104 | inline BOOL is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f < F_APPROXIMATELY_ZERO); } | 114 | inline BOOL is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f < F_APPROXIMATELY_ZERO); } |
105 | 115 | ||
116 | // These functions work by interpreting sign+exp+mantissa as an unsigned | ||
117 | // integer. | ||
118 | // For example: | ||
119 | // x = <sign>1 <exponent>00000010 <mantissa>00000000000000000000000 | ||
120 | // y = <sign>1 <exponent>00000001 <mantissa>11111111111111111111111 | ||
121 | // | ||
122 | // interpreted as ints = | ||
123 | // x = 10000001000000000000000000000000 | ||
124 | // y = 10000000111111111111111111111111 | ||
125 | // which is clearly a different of 1 in the least significant bit | ||
126 | // Values with the same exponent can be trivially shown to work. | ||
127 | // | ||
128 | // WARNING: Denormals of opposite sign do not work | ||
129 | // x = <sign>1 <exponent>00000000 <mantissa>00000000000000000000001 | ||
130 | // y = <sign>0 <exponent>00000000 <mantissa>00000000000000000000001 | ||
131 | // Although these values differ by 2 in the LSB, the sign bit makes | ||
132 | // the int comparison fail. | ||
133 | // | ||
134 | // WARNING: NaNs can compare equal | ||
135 | // There is no special treatment of exceptional values like NaNs | ||
136 | // | ||
137 | // WARNING: Infinity is comparable with F32_MAX and negative | ||
138 | // infinity is comparable with F32_MIN | ||
139 | |||
106 | inline BOOL is_approx_equal(F32 x, F32 y) | 140 | inline BOOL is_approx_equal(F32 x, F32 y) |
107 | { | 141 | { |
108 | const S32 COMPARE_MANTISSA_UP_TO_BIT = 0x02; | 142 | const S32 COMPARE_MANTISSA_UP_TO_BIT = 0x02; |
@@ -115,48 +149,6 @@ inline BOOL is_approx_equal(F64 x, F64 y) | |||
115 | return (std::abs((S32) ((U64&)x - (U64&)y) ) < COMPARE_MANTISSA_UP_TO_BIT); | 149 | return (std::abs((S32) ((U64&)x - (U64&)y) ) < COMPARE_MANTISSA_UP_TO_BIT); |
116 | } | 150 | } |
117 | 151 | ||
118 | inline BOOL is_approx_equal_fraction(F32 x, F32 y, U32 frac_bits) | ||
119 | { | ||
120 | BOOL ret = TRUE; | ||
121 | F32 diff = (F32) fabs(x - y); | ||
122 | |||
123 | S32 diffInt = (S32) diff; | ||
124 | S32 diffFracTolerance = (S32) ((diff - (F32) diffInt) * (1 << frac_bits)); | ||
125 | |||
126 | // if integer portion is not equal, not enough bits were used for packing | ||
127 | // so error out since either the use case is not correct OR there is | ||
128 | // an issue with pack/unpack. should fail in either case. | ||
129 | // for decimal portion, make sure that the delta is no more than 1 | ||
130 | // based on the number of bits used for packing decimal portion. | ||
131 | if (diffInt != 0 || diffFracTolerance > 1) | ||
132 | { | ||
133 | ret = FALSE; | ||
134 | } | ||
135 | |||
136 | return ret; | ||
137 | } | ||
138 | |||
139 | inline BOOL is_approx_equal_fraction(F64 x, F64 y, U32 frac_bits) | ||
140 | { | ||
141 | BOOL ret = TRUE; | ||
142 | F64 diff = (F64) fabs(x - y); | ||
143 | |||
144 | S32 diffInt = (S32) diff; | ||
145 | S32 diffFracTolerance = (S32) ((diff - (F64) diffInt) * (1 << frac_bits)); | ||
146 | |||
147 | // if integer portion is not equal, not enough bits were used for packing | ||
148 | // so error out since either the use case is not correct OR there is | ||
149 | // an issue with pack/unpack. should fail in either case. | ||
150 | // for decimal portion, make sure that the delta is no more than 1 | ||
151 | // based on the number of bits used for packing decimal portion. | ||
152 | if (diffInt != 0 || diffFracTolerance > 1) | ||
153 | { | ||
154 | ret = FALSE; | ||
155 | } | ||
156 | |||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | inline S32 llabs(const S32 a) | 152 | inline S32 llabs(const S32 a) |
161 | { | 153 | { |
162 | return S32(std::labs(a)); | 154 | return S32(std::labs(a)); |
@@ -523,4 +515,10 @@ inline U32 get_next_power_two(U32 val, U32 max_power_two) | |||
523 | return val; | 515 | return val; |
524 | } | 516 | } |
525 | 517 | ||
518 | //get the gaussian value given the linear distance from axis x and guassian value o | ||
519 | inline F32 llgaussian(F32 x, F32 o) | ||
520 | { | ||
521 | return 1.f/(F_SQRT_TWO_PI*o)*powf(F_E, -(x*x)/(2*o*o)); | ||
522 | } | ||
523 | |||
526 | #endif | 524 | #endif |