@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
50 lines (37 loc) • 1.53 kB
JavaScript
import { assert } from "../assert.js";
/**
* Convert uint16 encoded half float (float16) value to a full 32bit float
* Useful for decoding 16bit packed data, such as that from serialized files of GPU textures
* Reverse of {@link to_half_float_uint16}
* @param {number} uint16val
* @returns {number} decoded float
*/
export function half_to_float_uint16(uint16val) {
assert.isNonNegativeInteger(uint16val, 'uint16val');
// See https://en.wikipedia.org/wiki/Half-precision_floating-point_format for details
// see https://stackoverflow.com/questions/5678432/decompressing-half-precision-floats-in-javascript
// PORTED from https://github.com/YoYoGames/GameMaker-HTML5/blob/ada1ca2188b2145f222a8d6f9dda01b6d4770aca/scripts/libWebGL/libWebGL.js#L1808
// which is Apache 2.0 licensed
let ret = 0.0;
const exponent = (uint16val & 0x7C00) >> 10;
const fraction = uint16val & 0x03FF;
let sign = 1.0;
if ((uint16val >> 15) !== 0) {
sign = -1.0;
}
if (exponent !== 0) {
if (exponent === 0x1f) {
if (fraction !== 0) {
ret = NaN;
} else {
ret = Infinity;
}
} else {
ret = sign * Math.pow(2, exponent - 15) * (1 + (fraction / 0x400));
}
} else {
// 0.00006103515625 is the minimum exponent value (2 to the power -14)
ret = sign * (0.00006103515625 * (fraction / 0x400));
}
return ret;
}