diff options
author | Joel Bodenmann <joel@unormal.org> | 2013-11-10 21:07:16 +0100 |
---|---|---|
committer | Joel Bodenmann <joel@unormal.org> | 2013-11-10 21:07:16 +0100 |
commit | da2740b706d720292113445ee1db30f8a9873dc4 (patch) | |
tree | 8f8b1902d4af6a23b3daf26990f580b76ea31ea4 /src/gmisc | |
parent | 6ca3537a696e7ace8098771a9a7105380604253d (diff) | |
parent | a8ce005e2621b0108863297948cea0fa52c8bf2a (diff) | |
download | uGFX-da2740b706d720292113445ee1db30f8a9873dc4.tar.gz uGFX-da2740b706d720292113445ee1db30f8a9873dc4.tar.bz2 uGFX-da2740b706d720292113445ee1db30f8a9873dc4.zip |
merging GDISPStreaming
Diffstat (limited to 'src/gmisc')
-rw-r--r-- | src/gmisc/trig.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/gmisc/trig.c b/src/gmisc/trig.c index 510ee597..3c6dd461 100644 --- a/src/gmisc/trig.c +++ b/src/gmisc/trig.c @@ -142,5 +142,49 @@ #endif +#if GMISC_NEED_INVSQRT + // Algorithm based on Quake code. + #if GMISC_INVSQRT_REAL_SLOW + #include <math.h> + float invsqrt(float n) { + return 1.0/sqrt(n); + } + #else + float invsqrt(float n) { + int32_t i; + float x2; + + x2 = n * 0.5F; + + // Convert into an int32 (no binary format conversion) + #if GMISC_INVSQRT_MIXED_ENDIAN + ((char *)&i)[0] = ((char *)&n)[3]; + ((char *)&i)[1] = ((char *)&n)[2]; + ((char *)&i)[2] = ((char *)&n)[1]; + ((char *)&i)[3] = ((char *)&n)[0]; + #else + i = *(int32_t *)&n; + #endif + + // evil floating point bit level hacking + i = 0x5F375A86 - (i >> 1); // The quake code used 0x5F3759DF but this is better. + + // Convert back to a float (no binary format conversion) + #if GMISC_INVSQRT_MIXED_ENDIAN + ((char *)&n)[0] = ((char *)&i)[3]; + ((char *)&n)[1] = ((char *)&i)[2]; + ((char *)&n)[2] = ((char *)&i)[1]; + ((char *)&n)[3] = ((char *)&i)[0]; + #else + n = *(float *)&i; + #endif + + n = n * (1.5F - (x2 * n * n)); // 1st iteration + //n = n * (1.5F - (x2 * n * n)); // 2nd iteration for extra precision, this can be removed + return n; + } + #endif +#endif + #endif /* GFX_USE_GMISC */ /** @} */ |