-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
81 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// This file is part of meshoptimizer library; see meshoptimizer.h for version/license details | ||
#include "meshoptimizer.h" | ||
|
||
#include <assert.h> | ||
|
||
unsigned short meshopt_quantizeHalf(float v) | ||
{ | ||
union { float f; unsigned int ui; } u = {v}; | ||
unsigned int ui = u.ui; | ||
|
||
int s = (ui >> 16) & 0x8000; | ||
int em = ui & 0x7fffffff; | ||
|
||
// bias exponent and round to nearest; 112 is relative exponent bias (127-15) | ||
int h = (em - (112 << 23) + (1 << 12)) >> 13; | ||
|
||
// underflow: flush to zero; 113 encodes exponent -14 | ||
h = (em < (113 << 23)) ? 0 : h; | ||
|
||
// overflow: infinity; 143 encodes exponent 16 | ||
h = (em >= (143 << 23)) ? 0x7c00 : h; | ||
|
||
// NaN; note that we convert all types of NaN to qNaN | ||
h = (em > (255 << 23)) ? 0x7e00 : h; | ||
|
||
return (unsigned short)(s | h); | ||
} | ||
|
||
float meshopt_quantizeFloat(float v, int N) | ||
{ | ||
assert(N >= 0 && N <= 23); | ||
|
||
union { float f; unsigned int ui; } u = {v}; | ||
unsigned int ui = u.ui; | ||
|
||
const int mask = (1 << (23 - N)) - 1; | ||
const int round = (1 << (23 - N)) >> 1; | ||
|
||
int e = ui & 0x7f800000; | ||
unsigned int rui = (ui + round) & ~mask; | ||
|
||
// round all numbers except inf/nan; this is important to make sure nan doesn't overflow into -0 | ||
ui = e == 0x7f800000 ? ui : rui; | ||
|
||
// flush denormals to zero | ||
ui = e == 0 ? 0 : ui; | ||
|
||
u.ui = ui; | ||
return u.f; | ||
} | ||
|
||
float meshopt_dequantizeHalf(unsigned short h) | ||
{ | ||
unsigned int s = unsigned(h & 0x8000) << 16; | ||
int em = h & 0x7fff; | ||
|
||
// bias exponent and pad mantissa with 0; 112 is relative exponent bias (127-15) | ||
int r = (em + (112 << 10)) << 13; | ||
|
||
// denormal: flush to zero | ||
r = (em < (1 << 10)) ? 0 : r; | ||
|
||
// infinity/NaN; note that we preserve NaN payload as a byproduct of unifying inf/nan cases | ||
// 112 is an exponent bias fixup; since we already applied it once, applying it twice converts 31 to 255 | ||
r += (em >= (31 << 10)) ? (112 << 23) : 0; | ||
|
||
union { float f; unsigned int ui; } u; | ||
u.ui = s | r; | ||
return u.f; | ||
} |