aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmath/llmath.h
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llmath/llmath.h')
-rw-r--r--linden/indra/llmath/llmath.h90
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
82const F32 GRAVITY = -9.8f; 90const F32 GRAVITY = -9.8f;
83 91
@@ -85,6 +93,8 @@ const F32 GRAVITY = -9.8f;
85const F32 F_PI = 3.1415926535897932384626433832795f; 93const F32 F_PI = 3.1415926535897932384626433832795f;
86const F32 F_TWO_PI = 6.283185307179586476925286766559f; 94const F32 F_TWO_PI = 6.283185307179586476925286766559f;
87const F32 F_PI_BY_TWO = 1.5707963267948966192313216916398f; 95const F32 F_PI_BY_TWO = 1.5707963267948966192313216916398f;
96const F32 F_SQRT_TWO_PI = 2.506628274631000502415765284811f;
97const F32 F_E = 2.71828182845904523536f;
88const F32 F_SQRT2 = 1.4142135623730950488016887242097f; 98const F32 F_SQRT2 = 1.4142135623730950488016887242097f;
89const F32 F_SQRT3 = 1.73205080756888288657986402541f; 99const F32 F_SQRT3 = 1.73205080756888288657986402541f;
90const F32 OO_SQRT2 = 0.7071067811865475244008443621049f; 100const 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
104inline BOOL is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f < F_APPROXIMATELY_ZERO); } 114inline 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
106inline BOOL is_approx_equal(F32 x, F32 y) 140inline 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
118inline 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
139inline 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
160inline S32 llabs(const S32 a) 152inline 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
519inline 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