45 lines
1.1 KiB
JavaScript
45 lines
1.1 KiB
JavaScript
var pool = require('./pool')
|
|
|
|
var FLOAT = new Float32Array(1)
|
|
var INT = new Uint32Array(FLOAT.buffer)
|
|
|
|
var GL_UNSIGNED_SHORT = 5123
|
|
|
|
module.exports = function convertToHalfFloat (array) {
|
|
var ushorts = pool.allocType(GL_UNSIGNED_SHORT, array.length)
|
|
|
|
for (var i = 0; i < array.length; ++i) {
|
|
if (isNaN(array[i])) {
|
|
ushorts[i] = 0xffff
|
|
} else if (array[i] === Infinity) {
|
|
ushorts[i] = 0x7c00
|
|
} else if (array[i] === -Infinity) {
|
|
ushorts[i] = 0xfc00
|
|
} else {
|
|
FLOAT[0] = array[i]
|
|
var x = INT[0]
|
|
|
|
var sgn = (x >>> 31) << 15
|
|
var exp = ((x << 1) >>> 24) - 127
|
|
var frac = (x >> 13) & ((1 << 10) - 1)
|
|
|
|
if (exp < -24) {
|
|
// round non-representable denormals to 0
|
|
ushorts[i] = sgn
|
|
} else if (exp < -14) {
|
|
// handle denormals
|
|
var s = -14 - exp
|
|
ushorts[i] = sgn + ((frac + (1 << 10)) >> s)
|
|
} else if (exp > 15) {
|
|
// round overflow to +/- Infinity
|
|
ushorts[i] = sgn + 0x7c00
|
|
} else {
|
|
// otherwise convert directly
|
|
ushorts[i] = sgn + ((exp + 15) << 10) + frac
|
|
}
|
|
}
|
|
}
|
|
|
|
return ushorts
|
|
}
|