Path: blob/master/thirdparty/meshoptimizer/quantization.cpp
9903 views
// This file is part of meshoptimizer library; see meshoptimizer.h for version/license details1#include "meshoptimizer.h"23#include <assert.h>45union FloatBits6{7float f;8unsigned int ui;9};1011unsigned short meshopt_quantizeHalf(float v)12{13FloatBits u = {v};14unsigned int ui = u.ui;1516int s = (ui >> 16) & 0x8000;17int em = ui & 0x7fffffff;1819// bias exponent and round to nearest; 112 is relative exponent bias (127-15)20int h = (em - (112 << 23) + (1 << 12)) >> 13;2122// underflow: flush to zero; 113 encodes exponent -1423h = (em < (113 << 23)) ? 0 : h;2425// overflow: infinity; 143 encodes exponent 1626h = (em >= (143 << 23)) ? 0x7c00 : h;2728// NaN; note that we convert all types of NaN to qNaN29h = (em > (255 << 23)) ? 0x7e00 : h;3031return (unsigned short)(s | h);32}3334float meshopt_quantizeFloat(float v, int N)35{36assert(N >= 0 && N <= 23);3738FloatBits u = {v};39unsigned int ui = u.ui;4041const int mask = (1 << (23 - N)) - 1;42const int round = (1 << (23 - N)) >> 1;4344int e = ui & 0x7f800000;45unsigned int rui = (ui + round) & ~mask;4647// round all numbers except inf/nan; this is important to make sure nan doesn't overflow into -048ui = e == 0x7f800000 ? ui : rui;4950// flush denormals to zero51ui = e == 0 ? 0 : ui;5253u.ui = ui;54return u.f;55}5657float meshopt_dequantizeHalf(unsigned short h)58{59unsigned int s = unsigned(h & 0x8000) << 16;60int em = h & 0x7fff;6162// bias exponent and pad mantissa with 0; 112 is relative exponent bias (127-15)63int r = (em + (112 << 10)) << 13;6465// denormal: flush to zero66r = (em < (1 << 10)) ? 0 : r;6768// infinity/NaN; note that we preserve NaN payload as a byproduct of unifying inf/nan cases69// 112 is an exponent bias fixup; since we already applied it once, applying it twice converts 31 to 25570r += (em >= (31 << 10)) ? (112 << 23) : 0;7172FloatBits u;73u.ui = s | r;74return u.f;75}767778