352 lines
6.1 KiB
JavaScript
352 lines
6.1 KiB
JavaScript
import { Vector3 } from '../math/Vector3.js';
|
|
import { BufferAttribute } from './BufferAttribute.js';
|
|
import { denormalize, normalize } from '../math/MathUtils.js';
|
|
|
|
const _vector = /*@__PURE__*/ new Vector3();
|
|
|
|
class InterleavedBufferAttribute {
|
|
|
|
constructor( interleavedBuffer, itemSize, offset, normalized = false ) {
|
|
|
|
this.isInterleavedBufferAttribute = true;
|
|
|
|
this.name = '';
|
|
|
|
this.data = interleavedBuffer;
|
|
this.itemSize = itemSize;
|
|
this.offset = offset;
|
|
|
|
this.normalized = normalized;
|
|
|
|
}
|
|
|
|
get count() {
|
|
|
|
return this.data.count;
|
|
|
|
}
|
|
|
|
get array() {
|
|
|
|
return this.data.array;
|
|
|
|
}
|
|
|
|
set needsUpdate( value ) {
|
|
|
|
this.data.needsUpdate = value;
|
|
|
|
}
|
|
|
|
applyMatrix4( m ) {
|
|
|
|
for ( let i = 0, l = this.data.count; i < l; i ++ ) {
|
|
|
|
_vector.fromBufferAttribute( this, i );
|
|
|
|
_vector.applyMatrix4( m );
|
|
|
|
this.setXYZ( i, _vector.x, _vector.y, _vector.z );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
applyNormalMatrix( m ) {
|
|
|
|
for ( let i = 0, l = this.count; i < l; i ++ ) {
|
|
|
|
_vector.fromBufferAttribute( this, i );
|
|
|
|
_vector.applyNormalMatrix( m );
|
|
|
|
this.setXYZ( i, _vector.x, _vector.y, _vector.z );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
transformDirection( m ) {
|
|
|
|
for ( let i = 0, l = this.count; i < l; i ++ ) {
|
|
|
|
_vector.fromBufferAttribute( this, i );
|
|
|
|
_vector.transformDirection( m );
|
|
|
|
this.setXYZ( i, _vector.x, _vector.y, _vector.z );
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
getComponent( index, component ) {
|
|
|
|
let value = this.array[ index * this.data.stride + this.offset + component ];
|
|
|
|
if ( this.normalized ) value = denormalize( value, this.array );
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
setComponent( index, component, value ) {
|
|
|
|
if ( this.normalized ) value = normalize( value, this.array );
|
|
|
|
this.data.array[ index * this.data.stride + this.offset + component ] = value;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
setX( index, x ) {
|
|
|
|
if ( this.normalized ) x = normalize( x, this.array );
|
|
|
|
this.data.array[ index * this.data.stride + this.offset ] = x;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
setY( index, y ) {
|
|
|
|
if ( this.normalized ) y = normalize( y, this.array );
|
|
|
|
this.data.array[ index * this.data.stride + this.offset + 1 ] = y;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
setZ( index, z ) {
|
|
|
|
if ( this.normalized ) z = normalize( z, this.array );
|
|
|
|
this.data.array[ index * this.data.stride + this.offset + 2 ] = z;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
setW( index, w ) {
|
|
|
|
if ( this.normalized ) w = normalize( w, this.array );
|
|
|
|
this.data.array[ index * this.data.stride + this.offset + 3 ] = w;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
getX( index ) {
|
|
|
|
let x = this.data.array[ index * this.data.stride + this.offset ];
|
|
|
|
if ( this.normalized ) x = denormalize( x, this.array );
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
getY( index ) {
|
|
|
|
let y = this.data.array[ index * this.data.stride + this.offset + 1 ];
|
|
|
|
if ( this.normalized ) y = denormalize( y, this.array );
|
|
|
|
return y;
|
|
|
|
}
|
|
|
|
getZ( index ) {
|
|
|
|
let z = this.data.array[ index * this.data.stride + this.offset + 2 ];
|
|
|
|
if ( this.normalized ) z = denormalize( z, this.array );
|
|
|
|
return z;
|
|
|
|
}
|
|
|
|
getW( index ) {
|
|
|
|
let w = this.data.array[ index * this.data.stride + this.offset + 3 ];
|
|
|
|
if ( this.normalized ) w = denormalize( w, this.array );
|
|
|
|
return w;
|
|
|
|
}
|
|
|
|
setXY( index, x, y ) {
|
|
|
|
index = index * this.data.stride + this.offset;
|
|
|
|
if ( this.normalized ) {
|
|
|
|
x = normalize( x, this.array );
|
|
y = normalize( y, this.array );
|
|
|
|
}
|
|
|
|
this.data.array[ index + 0 ] = x;
|
|
this.data.array[ index + 1 ] = y;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
setXYZ( index, x, y, z ) {
|
|
|
|
index = index * this.data.stride + this.offset;
|
|
|
|
if ( this.normalized ) {
|
|
|
|
x = normalize( x, this.array );
|
|
y = normalize( y, this.array );
|
|
z = normalize( z, this.array );
|
|
|
|
}
|
|
|
|
this.data.array[ index + 0 ] = x;
|
|
this.data.array[ index + 1 ] = y;
|
|
this.data.array[ index + 2 ] = z;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
setXYZW( index, x, y, z, w ) {
|
|
|
|
index = index * this.data.stride + this.offset;
|
|
|
|
if ( this.normalized ) {
|
|
|
|
x = normalize( x, this.array );
|
|
y = normalize( y, this.array );
|
|
z = normalize( z, this.array );
|
|
w = normalize( w, this.array );
|
|
|
|
}
|
|
|
|
this.data.array[ index + 0 ] = x;
|
|
this.data.array[ index + 1 ] = y;
|
|
this.data.array[ index + 2 ] = z;
|
|
this.data.array[ index + 3 ] = w;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
clone( data ) {
|
|
|
|
if ( data === undefined ) {
|
|
|
|
console.log( 'THREE.InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data.' );
|
|
|
|
const array = [];
|
|
|
|
for ( let i = 0; i < this.count; i ++ ) {
|
|
|
|
const index = i * this.data.stride + this.offset;
|
|
|
|
for ( let j = 0; j < this.itemSize; j ++ ) {
|
|
|
|
array.push( this.data.array[ index + j ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return new BufferAttribute( new this.array.constructor( array ), this.itemSize, this.normalized );
|
|
|
|
} else {
|
|
|
|
if ( data.interleavedBuffers === undefined ) {
|
|
|
|
data.interleavedBuffers = {};
|
|
|
|
}
|
|
|
|
if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) {
|
|
|
|
data.interleavedBuffers[ this.data.uuid ] = this.data.clone( data );
|
|
|
|
}
|
|
|
|
return new InterleavedBufferAttribute( data.interleavedBuffers[ this.data.uuid ], this.itemSize, this.offset, this.normalized );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
toJSON( data ) {
|
|
|
|
if ( data === undefined ) {
|
|
|
|
console.log( 'THREE.InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will de-interleave buffer data.' );
|
|
|
|
const array = [];
|
|
|
|
for ( let i = 0; i < this.count; i ++ ) {
|
|
|
|
const index = i * this.data.stride + this.offset;
|
|
|
|
for ( let j = 0; j < this.itemSize; j ++ ) {
|
|
|
|
array.push( this.data.array[ index + j ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// de-interleave data and save it as an ordinary buffer attribute for now
|
|
|
|
return {
|
|
itemSize: this.itemSize,
|
|
type: this.array.constructor.name,
|
|
array: array,
|
|
normalized: this.normalized
|
|
};
|
|
|
|
} else {
|
|
|
|
// save as true interleaved attribute
|
|
|
|
if ( data.interleavedBuffers === undefined ) {
|
|
|
|
data.interleavedBuffers = {};
|
|
|
|
}
|
|
|
|
if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) {
|
|
|
|
data.interleavedBuffers[ this.data.uuid ] = this.data.toJSON( data );
|
|
|
|
}
|
|
|
|
return {
|
|
isInterleavedBufferAttribute: true,
|
|
itemSize: this.itemSize,
|
|
data: this.data.uuid,
|
|
offset: this.offset,
|
|
normalized: this.normalized
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
export { InterleavedBufferAttribute };
|