|
@@ -2,153 +2,177 @@ import { clamp } from '../math/MathUtils.js';
|
|
|
|
|
|
// Fast Half Float Conversions, http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf
|
|
|
|
|
|
-class DataUtils {
|
|
|
+const {
|
|
|
+ floatView: _floatView,
|
|
|
+ uint32View: _uint32View,
|
|
|
+ baseTable: _baseTable,
|
|
|
+ shiftTable: _shiftTable,
|
|
|
+ mantissaTable: _mantissaTable,
|
|
|
+ exponentTable: _exponentTable,
|
|
|
+ offsetTable: _offsetTable
|
|
|
+} = /*@__PURE__*/ _generateTables();
|
|
|
|
|
|
- // float32 to float16
|
|
|
+function _generateTables() {
|
|
|
|
|
|
- static toHalfFloat( val ) {
|
|
|
+ // float32 to float16 helpers
|
|
|
|
|
|
- if ( Math.abs( val ) > 65504 ) console.warn( 'THREE.DataUtils.toHalfFloat(): Value out of range.' );
|
|
|
+ const buffer = new ArrayBuffer( 4 );
|
|
|
+ const floatView = new Float32Array( buffer );
|
|
|
+ const uint32View = new Uint32Array( buffer );
|
|
|
|
|
|
- val = clamp( val, - 65504, 65504 );
|
|
|
+ const baseTable = new Uint32Array( 512 );
|
|
|
+ const shiftTable = new Uint32Array( 512 );
|
|
|
|
|
|
- _floatView[ 0 ] = val;
|
|
|
- const f = _uint32View[ 0 ];
|
|
|
- const e = ( f >> 23 ) & 0x1ff;
|
|
|
- return _baseTable[ e ] + ( ( f & 0x007fffff ) >> _shiftTable[ e ] );
|
|
|
+ for ( let i = 0; i < 256; ++ i ) {
|
|
|
|
|
|
- }
|
|
|
+ const e = i - 127;
|
|
|
|
|
|
- // float16 to float32
|
|
|
+ // very small number (0, -0)
|
|
|
|
|
|
- static fromHalfFloat( val ) {
|
|
|
+ if ( e < - 27 ) {
|
|
|
|
|
|
- const m = val >> 10;
|
|
|
- _uint32View[ 0 ] = _mantissaTable[ _offsetTable[ m ] + ( val & 0x3ff ) ] + _exponentTable[ m ];
|
|
|
- return _floatView[ 0 ];
|
|
|
+ baseTable[ i ] = 0x0000;
|
|
|
+ baseTable[ i | 0x100 ] = 0x8000;
|
|
|
+ shiftTable[ i ] = 24;
|
|
|
+ shiftTable[ i | 0x100 ] = 24;
|
|
|
|
|
|
- }
|
|
|
+ // small number (denorm)
|
|
|
|
|
|
-}
|
|
|
+ } else if ( e < - 14 ) {
|
|
|
|
|
|
-// float32 to float16 helpers
|
|
|
+ baseTable[ i ] = 0x0400 >> ( - e - 14 );
|
|
|
+ baseTable[ i | 0x100 ] = ( 0x0400 >> ( - e - 14 ) ) | 0x8000;
|
|
|
+ shiftTable[ i ] = - e - 1;
|
|
|
+ shiftTable[ i | 0x100 ] = - e - 1;
|
|
|
|
|
|
-const _buffer = new ArrayBuffer( 4 );
|
|
|
-const _floatView = new Float32Array( _buffer );
|
|
|
-const _uint32View = new Uint32Array( _buffer );
|
|
|
+ // normal number
|
|
|
|
|
|
-const _baseTable = new Uint32Array( 512 );
|
|
|
-const _shiftTable = new Uint32Array( 512 );
|
|
|
+ } else if ( e <= 15 ) {
|
|
|
|
|
|
-for ( let i = 0; i < 256; ++ i ) {
|
|
|
+ baseTable[ i ] = ( e + 15 ) << 10;
|
|
|
+ baseTable[ i | 0x100 ] = ( ( e + 15 ) << 10 ) | 0x8000;
|
|
|
+ shiftTable[ i ] = 13;
|
|
|
+ shiftTable[ i | 0x100 ] = 13;
|
|
|
|
|
|
- const e = i - 127;
|
|
|
+ // large number (Infinity, -Infinity)
|
|
|
|
|
|
- // very small number (0, -0)
|
|
|
+ } else if ( e < 128 ) {
|
|
|
|
|
|
- if ( e < - 27 ) {
|
|
|
+ baseTable[ i ] = 0x7c00;
|
|
|
+ baseTable[ i | 0x100 ] = 0xfc00;
|
|
|
+ shiftTable[ i ] = 24;
|
|
|
+ shiftTable[ i | 0x100 ] = 24;
|
|
|
|
|
|
- _baseTable[ i ] = 0x0000;
|
|
|
- _baseTable[ i | 0x100 ] = 0x8000;
|
|
|
- _shiftTable[ i ] = 24;
|
|
|
- _shiftTable[ i | 0x100 ] = 24;
|
|
|
+ // stay (NaN, Infinity, -Infinity)
|
|
|
|
|
|
- // small number (denorm)
|
|
|
+ } else {
|
|
|
|
|
|
- } else if ( e < - 14 ) {
|
|
|
+ baseTable[ i ] = 0x7c00;
|
|
|
+ baseTable[ i | 0x100 ] = 0xfc00;
|
|
|
+ shiftTable[ i ] = 13;
|
|
|
+ shiftTable[ i | 0x100 ] = 13;
|
|
|
|
|
|
- _baseTable[ i ] = 0x0400 >> ( - e - 14 );
|
|
|
- _baseTable[ i | 0x100 ] = ( 0x0400 >> ( - e - 14 ) ) | 0x8000;
|
|
|
- _shiftTable[ i ] = - e - 1;
|
|
|
- _shiftTable[ i | 0x100 ] = - e - 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- // normal number
|
|
|
+ // float16 to float32 helpers
|
|
|
|
|
|
- } else if ( e <= 15 ) {
|
|
|
+ const mantissaTable = new Uint32Array( 2048 );
|
|
|
+ const exponentTable = new Uint32Array( 64 );
|
|
|
+ const offsetTable = new Uint32Array( 64 );
|
|
|
|
|
|
- _baseTable[ i ] = ( e + 15 ) << 10;
|
|
|
- _baseTable[ i | 0x100 ] = ( ( e + 15 ) << 10 ) | 0x8000;
|
|
|
- _shiftTable[ i ] = 13;
|
|
|
- _shiftTable[ i | 0x100 ] = 13;
|
|
|
+ for ( let i = 1; i < 1024; ++ i ) {
|
|
|
|
|
|
- // large number (Infinity, -Infinity)
|
|
|
+ let m = i << 13; // zero pad mantissa bits
|
|
|
+ let e = 0; // zero exponent
|
|
|
|
|
|
- } else if ( e < 128 ) {
|
|
|
+ // normalized
|
|
|
+ while ( ( m & 0x00800000 ) === 0 ) {
|
|
|
|
|
|
- _baseTable[ i ] = 0x7c00;
|
|
|
- _baseTable[ i | 0x100 ] = 0xfc00;
|
|
|
- _shiftTable[ i ] = 24;
|
|
|
- _shiftTable[ i | 0x100 ] = 24;
|
|
|
+ m <<= 1;
|
|
|
+ e -= 0x00800000; // decrement exponent
|
|
|
|
|
|
- // stay (NaN, Infinity, -Infinity)
|
|
|
+ }
|
|
|
|
|
|
- } else {
|
|
|
+ m &= ~ 0x00800000; // clear leading 1 bit
|
|
|
+ e += 0x38800000; // adjust bias
|
|
|
|
|
|
- _baseTable[ i ] = 0x7c00;
|
|
|
- _baseTable[ i | 0x100 ] = 0xfc00;
|
|
|
- _shiftTable[ i ] = 13;
|
|
|
- _shiftTable[ i | 0x100 ] = 13;
|
|
|
+ mantissaTable[ i ] = m | e;
|
|
|
|
|
|
}
|
|
|
|
|
|
-}
|
|
|
+ for ( let i = 1024; i < 2048; ++ i ) {
|
|
|
|
|
|
-// float16 to float32 helpers
|
|
|
+ mantissaTable[ i ] = 0x38000000 + ( ( i - 1024 ) << 13 );
|
|
|
|
|
|
-const _mantissaTable = new Uint32Array( 2048 );
|
|
|
-const _exponentTable = new Uint32Array( 64 );
|
|
|
-const _offsetTable = new Uint32Array( 64 );
|
|
|
+ }
|
|
|
|
|
|
-for ( let i = 1; i < 1024; ++ i ) {
|
|
|
+ for ( let i = 1; i < 31; ++ i ) {
|
|
|
|
|
|
- let m = i << 13; // zero pad mantissa bits
|
|
|
- let e = 0; // zero exponent
|
|
|
+ exponentTable[ i ] = i << 23;
|
|
|
|
|
|
- // normalized
|
|
|
- while ( ( m & 0x00800000 ) === 0 ) {
|
|
|
+ }
|
|
|
|
|
|
- m <<= 1;
|
|
|
- e -= 0x00800000; // decrement exponent
|
|
|
+ exponentTable[ 31 ] = 0x47800000;
|
|
|
+ exponentTable[ 32 ] = 0x80000000;
|
|
|
|
|
|
- }
|
|
|
+ for ( let i = 33; i < 63; ++ i ) {
|
|
|
|
|
|
- m &= ~ 0x00800000; // clear leading 1 bit
|
|
|
- e += 0x38800000; // adjust bias
|
|
|
+ exponentTable[ i ] = 0x80000000 + ( ( i - 32 ) << 23 );
|
|
|
|
|
|
- _mantissaTable[ i ] = m | e;
|
|
|
+ }
|
|
|
|
|
|
-}
|
|
|
+ exponentTable[ 63 ] = 0xc7800000;
|
|
|
|
|
|
-for ( let i = 1024; i < 2048; ++ i ) {
|
|
|
+ for ( let i = 1; i < 64; ++ i ) {
|
|
|
|
|
|
- _mantissaTable[ i ] = 0x38000000 + ( ( i - 1024 ) << 13 );
|
|
|
+ if ( i !== 32 ) {
|
|
|
|
|
|
-}
|
|
|
+ offsetTable[ i ] = 1024;
|
|
|
|
|
|
-for ( let i = 1; i < 31; ++ i ) {
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- _exponentTable[ i ] = i << 23;
|
|
|
+ return {
|
|
|
+ floatView: floatView,
|
|
|
+ uint32View: uint32View,
|
|
|
+ baseTable: baseTable,
|
|
|
+ shiftTable: shiftTable,
|
|
|
+ mantissaTable: mantissaTable,
|
|
|
+ exponentTable: exponentTable,
|
|
|
+ offsetTable: offsetTable,
|
|
|
+ };
|
|
|
|
|
|
}
|
|
|
|
|
|
-_exponentTable[ 31 ] = 0x47800000;
|
|
|
-_exponentTable[ 32 ] = 0x80000000;
|
|
|
-for ( let i = 33; i < 63; ++ i ) {
|
|
|
+// float32 to float16
|
|
|
|
|
|
- _exponentTable[ i ] = 0x80000000 + ( ( i - 32 ) << 23 );
|
|
|
+function toHalfFloat( val ) {
|
|
|
|
|
|
-}
|
|
|
+ if ( Math.abs( val ) > 65504 ) console.warn( 'THREE.DataUtils.toHalfFloat(): Value out of range.' );
|
|
|
+
|
|
|
+ val = clamp( val, - 65504, 65504 );
|
|
|
|
|
|
-_exponentTable[ 63 ] = 0xc7800000;
|
|
|
+ _floatView[ 0 ] = val;
|
|
|
+ const f = _uint32View[ 0 ];
|
|
|
+ const e = ( f >> 23 ) & 0x1ff;
|
|
|
+ return _baseTable[ e ] + ( ( f & 0x007fffff ) >> _shiftTable[ e ] );
|
|
|
|
|
|
-for ( let i = 1; i < 64; ++ i ) {
|
|
|
+}
|
|
|
|
|
|
- if ( i !== 32 ) {
|
|
|
+// float16 to float32
|
|
|
|
|
|
- _offsetTable[ i ] = 1024;
|
|
|
+function fromHalfFloat( val ) {
|
|
|
|
|
|
- }
|
|
|
+ const m = val >> 10;
|
|
|
+ _uint32View[ 0 ] = _mantissaTable[ _offsetTable[ m ] + ( val & 0x3ff ) ] + _exponentTable[ m ];
|
|
|
+ return _floatView[ 0 ];
|
|
|
|
|
|
}
|
|
|
|
|
|
-export { DataUtils };
|
|
|
+export {
|
|
|
+ toHalfFloat,
|
|
|
+ fromHalfFloat,
|
|
|
+};
|