diff --git a/examples/jsm/utils/BufferGeometryUtils.js b/examples/jsm/utils/BufferGeometryUtils.js index 7fc6d9de60f37d..6c86bdcfa4c5c6 100644 --- a/examples/jsm/utils/BufferGeometryUtils.js +++ b/examples/jsm/utils/BufferGeometryUtils.js @@ -5,7 +5,6 @@ import { InstancedBufferAttribute, InterleavedBuffer, InterleavedBufferAttribute, - MathUtils, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, @@ -36,17 +35,16 @@ function computeMikkTSpaceTangents( geometry, MikkTSpace, negateSign = true ) { if ( attribute.normalized || attribute.isInterleavedBufferAttribute ) { - const srcArray = attribute.isInterleavedBufferAttribute ? attribute.data.array : attribute.array; const dstArray = new Float32Array( attribute.getCount() * attribute.itemSize ); for ( let i = 0, j = 0; i < attribute.getCount(); i ++ ) { - dstArray[ j ++ ] = MathUtils.denormalize( attribute.getX( i ), srcArray ); - dstArray[ j ++ ] = MathUtils.denormalize( attribute.getY( i ), srcArray ); + dstArray[ j ++ ] = attribute.getX( i ); + dstArray[ j ++ ] = attribute.getY( i ); if ( attribute.itemSize > 2 ) { - dstArray[ j ++ ] = MathUtils.denormalize( attribute.getZ( i ), srcArray ); + dstArray[ j ++ ] = attribute.getZ( i ); } diff --git a/src/Three.js b/src/Three.js index 372352c7f91e24..a2be2b394707dd 100644 --- a/src/Three.js +++ b/src/Three.js @@ -98,7 +98,19 @@ export { InstancedInterleavedBuffer } from './core/InstancedInterleavedBuffer.js export { InterleavedBuffer } from './core/InterleavedBuffer.js'; export { InstancedBufferAttribute } from './core/InstancedBufferAttribute.js'; export { GLBufferAttribute } from './core/GLBufferAttribute.js'; -export * from './core/BufferAttribute.js'; +export { + Float64BufferAttribute, + Float32BufferAttribute, + Float16BufferAttribute, + Uint32BufferAttribute, + Int32BufferAttribute, + Uint16BufferAttribute, + Int16BufferAttribute, + Uint8ClampedBufferAttribute, + Uint8BufferAttribute, + Int8BufferAttribute, + BufferAttribute +} from './core/BufferAttribute.js'; export { Object3D } from './core/Object3D.js'; export { Raycaster } from './core/Raycaster.js'; export { Layers } from './core/Layers.js'; diff --git a/src/core/BufferAttribute.js b/src/core/BufferAttribute.js index 36387329478e0e..b466181c4459da 100644 --- a/src/core/BufferAttribute.js +++ b/src/core/BufferAttribute.js @@ -2,8 +2,7 @@ import { Vector4 } from '../math/Vector4.js'; import { Vector3 } from '../math/Vector3.js'; import { Vector2 } from '../math/Vector2.js'; import { Color } from '../math/Color.js'; -import { denormalize, normalize } from '../math/MathUtils.js'; -import { StaticDrawUsage } from '../constants.js'; +import { ByteType, FloatType, IntType, ShortType, StaticDrawUsage, UnsignedByteType, UnsignedIntType, UnsignedShortType } from '../constants.js'; const _vector = /*@__PURE__*/ new Vector3(); const _vector2 = /*@__PURE__*/ new Vector2(); @@ -27,6 +26,8 @@ class BufferAttribute { this.count = array !== undefined ? array.length / itemSize : 0; this.normalized = normalized === true; + this.type = getArrayType( array ); + this.usage = StaticDrawUsage; this.updateRange = { offset: 0, count: - 1 }; @@ -58,6 +59,8 @@ class BufferAttribute { this.count = source.count; this.normalized = source.normalized; + this.type = source.type; + this.usage = source.usage; return this; @@ -105,9 +108,9 @@ class BufferAttribute { if ( this.normalized ) { - array[ offset ++ ] = normalize( color.r, array ); - array[ offset ++ ] = normalize( color.g, array ); - array[ offset ++ ] = normalize( color.b, array ); + array[ offset ++ ] = denormalize( color.r, this.type ); + array[ offset ++ ] = denormalize( color.g, this.type ); + array[ offset ++ ] = denormalize( color.b, this.type ); } else { @@ -141,8 +144,8 @@ class BufferAttribute { if ( this.normalized ) { - array[ offset ++ ] = normalize( vector.x, array ); - array[ offset ++ ] = normalize( vector.y, array ); + array[ offset ++ ] = denormalize( vector.x, this.type ); + array[ offset ++ ] = denormalize( vector.y, this.type ); } else { @@ -175,9 +178,9 @@ class BufferAttribute { if ( this.normalized ) { - array[ offset ++ ] = normalize( vector.x, array ); - array[ offset ++ ] = normalize( vector.y, array ); - array[ offset ++ ] = normalize( vector.z, array ); + array[ offset ++ ] = denormalize( vector.x, this.type ); + array[ offset ++ ] = denormalize( vector.y, this.type ); + array[ offset ++ ] = denormalize( vector.z, this.type ); } else { @@ -211,10 +214,10 @@ class BufferAttribute { if ( this.normalized ) { - array[ offset ++ ] = normalize( vector.x, array ); - array[ offset ++ ] = normalize( vector.y, array ); - array[ offset ++ ] = normalize( vector.z, array ); - array[ offset ++ ] = normalize( vector.w, array ); + array[ offset ++ ] = denormalize( vector.x, this.type ); + array[ offset ++ ] = denormalize( vector.y, this.type ); + array[ offset ++ ] = denormalize( vector.z, this.type ); + array[ offset ++ ] = denormalize( vector.w, this.type ); } else { @@ -311,7 +314,11 @@ class BufferAttribute { set( value, offset = 0 ) { - if ( this.normalized ) value = normalize( value, this.array ); + if ( this.normalized && Array.isArray( value ) ) { + + throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); + + } this.array.set( value, offset ); @@ -323,7 +330,7 @@ class BufferAttribute { let x = this.array[ index * this.itemSize ]; - if ( this.normalized ) x = denormalize( x, this.array ); + if ( this.normalized ) x = normalize( x, this.type ); return x; @@ -331,7 +338,7 @@ class BufferAttribute { setX( index, x ) { - if ( this.normalized ) x = normalize( x, this.array ); + if ( this.normalized ) x = denormalize( x, this.type ); this.array[ index * this.itemSize ] = x; @@ -343,7 +350,7 @@ class BufferAttribute { let y = this.array[ index * this.itemSize + 1 ]; - if ( this.normalized ) y = denormalize( y, this.array ); + if ( this.normalized ) y = normalize( y, this.type ); return y; @@ -351,7 +358,7 @@ class BufferAttribute { setY( index, y ) { - if ( this.normalized ) y = normalize( y, this.array ); + if ( this.normalized ) y = denormalize( y, this.type ); this.array[ index * this.itemSize + 1 ] = y; @@ -363,7 +370,7 @@ class BufferAttribute { let z = this.array[ index * this.itemSize + 2 ]; - if ( this.normalized ) z = denormalize( z, this.array ); + if ( this.normalized ) z = normalize( z, this.type ); return z; @@ -371,7 +378,7 @@ class BufferAttribute { setZ( index, z ) { - if ( this.normalized ) z = normalize( z, this.array ); + if ( this.normalized ) z = denormalize( z, this.type ); this.array[ index * this.itemSize + 2 ] = z; @@ -383,7 +390,7 @@ class BufferAttribute { let w = this.array[ index * this.itemSize + 3 ]; - if ( this.normalized ) w = denormalize( w, this.array ); + if ( this.normalized ) w = normalize( w, this.type ); return w; @@ -391,7 +398,7 @@ class BufferAttribute { setW( index, w ) { - if ( this.normalized ) w = normalize( w, this.array ); + if ( this.normalized ) w = denormalize( w, this.type ); this.array[ index * this.itemSize + 3 ] = w; @@ -405,8 +412,8 @@ class BufferAttribute { if ( this.normalized ) { - x = normalize( x, this.array ); - y = normalize( y, this.array ); + x = denormalize( x, this.type ); + y = denormalize( y, this.type ); } @@ -423,9 +430,9 @@ class BufferAttribute { if ( this.normalized ) { - x = normalize( x, this.array ); - y = normalize( y, this.array ); - z = normalize( z, this.array ); + x = denormalize( x, this.type ); + y = denormalize( y, this.type ); + z = denormalize( z, this.type ); } @@ -443,10 +450,10 @@ class BufferAttribute { if ( this.normalized ) { - x = normalize( x, this.array ); - y = normalize( y, this.array ); - z = normalize( z, this.array ); - w = normalize( w, this.array ); + x = denormalize( x, this.type ); + y = denormalize( y, this.type ); + z = denormalize( z, this.type ); + w = denormalize( w, this.type ); } @@ -599,6 +606,114 @@ class Float64BufferAttribute extends BufferAttribute { // +function getArrayType( array ) { + + switch ( array.constructor ) { + + case Uint32Array: + + return UnsignedIntType; + + case Uint16Array: + + return UnsignedShortType; + + case Uint8Array: + case Uint8ClampedArray: + + return UnsignedByteType; + + case Int32Array: + + return IntType; + + case Int16Array: + + return ShortType; + + case Int8Array: + + return ByteType; + + case Float32Array: + case Float64Array: + + return FloatType; + + default: + + throw new Error( 'THREE.BufferAttribute: Invalid type.' ); + + } + +} + +function normalize( value, type ) { + + switch ( type ) { + + case FloatType: + + return value; + + case UnsignedShortType: + + return value / 65535.0; + + case UnsignedByteType: + + return value / 255.0; + + case ShortType: + + return Math.max( value / 32767.0, - 1.0 ); + + case ByteType: + + return Math.max( value / 127.0, - 1.0 ); + + default: + + throw new Error( 'THREE.BufferAttribute: Invalid type.' ); + + } + +} + +function denormalize( value, type ) { + + switch ( type ) { + + case FloatType: + + return value; + + case UnsignedShortType: + + return Math.round( value * 65535.0 ); + + case UnsignedByteType: + + return Math.round( value * 255.0 ); + + case ShortType: + + return Math.round( value * 32767.0 ); + + case ByteType: + + return Math.round( value * 127.0 ); + + default: + + throw new Error( 'THREE.BufferAttribute: Invalid type.' ); + + } + +} + +// + export { Float64BufferAttribute, Float32BufferAttribute, @@ -610,5 +725,8 @@ export { Uint8ClampedBufferAttribute, Uint8BufferAttribute, Int8BufferAttribute, - BufferAttribute + BufferAttribute, + normalize, + denormalize, + getArrayType }; diff --git a/src/core/InterleavedBufferAttribute.js b/src/core/InterleavedBufferAttribute.js index c7aa7ef30cb096..edc8d16bb78cbe 100644 --- a/src/core/InterleavedBufferAttribute.js +++ b/src/core/InterleavedBufferAttribute.js @@ -1,6 +1,5 @@ import { Vector3 } from '../math/Vector3.js'; -import { BufferAttribute } from './BufferAttribute.js'; -import { denormalize, normalize } from '../math/MathUtils.js'; +import { BufferAttribute, getArrayType, normalize, denormalize } from './BufferAttribute.js'; const _vector = /*@__PURE__*/ new Vector3(); @@ -18,6 +17,8 @@ class InterleavedBufferAttribute { this.normalized = normalized === true; + this.type = getArrayType( this.array ); + } get count() { @@ -88,7 +89,7 @@ class InterleavedBufferAttribute { setX( index, x ) { - if ( this.normalized ) x = normalize( x, this.array ); + if ( this.normalized ) x = denormalize( x, this.type ); this.data.array[ index * this.data.stride + this.offset ] = x; @@ -98,7 +99,7 @@ class InterleavedBufferAttribute { setY( index, y ) { - if ( this.normalized ) y = normalize( y, this.array ); + if ( this.normalized ) y = denormalize( y, this.type ); this.data.array[ index * this.data.stride + this.offset + 1 ] = y; @@ -108,7 +109,7 @@ class InterleavedBufferAttribute { setZ( index, z ) { - if ( this.normalized ) z = normalize( z, this.array ); + if ( this.normalized ) z = denormalize( z, this.type ); this.data.array[ index * this.data.stride + this.offset + 2 ] = z; @@ -118,7 +119,7 @@ class InterleavedBufferAttribute { setW( index, w ) { - if ( this.normalized ) w = normalize( w, this.array ); + if ( this.normalized ) w = denormalize( w, this.type ); this.data.array[ index * this.data.stride + this.offset + 3 ] = w; @@ -130,7 +131,7 @@ class InterleavedBufferAttribute { let x = this.data.array[ index * this.data.stride + this.offset ]; - if ( this.normalized ) x = denormalize( x, this.array ); + if ( this.normalized ) x = normalize( x, this.type ); return x; @@ -140,7 +141,7 @@ class InterleavedBufferAttribute { let y = this.data.array[ index * this.data.stride + this.offset + 1 ]; - if ( this.normalized ) y = denormalize( y, this.array ); + if ( this.normalized ) y = normalize( y, this.type ); return y; @@ -150,7 +151,7 @@ class InterleavedBufferAttribute { let z = this.data.array[ index * this.data.stride + this.offset + 2 ]; - if ( this.normalized ) z = denormalize( z, this.array ); + if ( this.normalized ) z = normalize( z, this.type ); return z; @@ -160,7 +161,7 @@ class InterleavedBufferAttribute { let w = this.data.array[ index * this.data.stride + this.offset + 3 ]; - if ( this.normalized ) w = denormalize( w, this.array ); + if ( this.normalized ) w = normalize( w, this.type ); return w; @@ -172,8 +173,8 @@ class InterleavedBufferAttribute { if ( this.normalized ) { - x = normalize( x, this.array ); - y = normalize( y, this.array ); + x = denormalize( x, this.type ); + y = denormalize( y, this.type ); } @@ -190,9 +191,9 @@ class InterleavedBufferAttribute { if ( this.normalized ) { - x = normalize( x, this.array ); - y = normalize( y, this.array ); - z = normalize( z, this.array ); + x = denormalize( x, this.type ); + y = denormalize( y, this.type ); + z = denormalize( z, this.type ); } @@ -210,10 +211,10 @@ class InterleavedBufferAttribute { if ( this.normalized ) { - x = normalize( x, this.array ); - y = normalize( y, this.array ); - z = normalize( z, this.array ); - w = normalize( w, this.array ); + x = denormalize( x, this.type ); + y = denormalize( y, this.type ); + z = denormalize( z, this.type ); + w = denormalize( w, this.type ); } diff --git a/src/math/MathUtils.js b/src/math/MathUtils.js index f64985edf8d892..39303d3c8fb74c 100644 --- a/src/math/MathUtils.js +++ b/src/math/MathUtils.js @@ -227,72 +227,6 @@ function setQuaternionFromProperEuler( q, a, b, c, order ) { } -function denormalize( value, array ) { - - switch ( array.constructor ) { - - case Float32Array: - - return value; - - case Uint16Array: - - return value / 65535.0; - - case Uint8Array: - - return value / 255.0; - - case Int16Array: - - return Math.max( value / 32767.0, - 1.0 ); - - case Int8Array: - - return Math.max( value / 127.0, - 1.0 ); - - default: - - throw new Error( 'Invalid component type.' ); - - } - -} - -function normalize( value, array ) { - - switch ( array.constructor ) { - - case Float32Array: - - return value; - - case Uint16Array: - - return Math.round( value * 65535.0 ); - - case Uint8Array: - - return Math.round( value * 255.0 ); - - case Int16Array: - - return Math.round( value * 32767.0 ); - - case Int8Array: - - return Math.round( value * 127.0 ); - - default: - - throw new Error( 'Invalid component type.' ); - - } - -} - - - export { DEG2RAD, RAD2DEG, @@ -315,7 +249,5 @@ export { isPowerOfTwo, ceilPowerOfTwo, floorPowerOfTwo, - setQuaternionFromProperEuler, - normalize, - denormalize, + setQuaternionFromProperEuler };