BufferAttribute subclasses force unnecessary memory allocation

For example, check out the Float32BufferAttribute class:

It is impossible to bypass the forced buffer allocation:

const existingBuffer = new Float32Array(...)

new Float32BufferAttribute(existingBuffer, 3) // forces a new Float32Array, which could be expensive

Can we make update these to do a check? For example something like this:

class Float32BufferAttribute extends BufferAttribute {

	constructor( array, itemSize, normalized ) {

		super(

			array instanceof Float32Array ? array : new Float32Array( array ),
			itemSize,
			normalized

		);

	}

}

It would be more intuitive, as it would align with the behavior of plain BufferAttribute which accepts the array as-is.

This would align more with Three.js patterns in general, where re-allocation is something that is actively avoided, and people typically have the ability to choose tore-allocate or not. This particular case does not offer the choice.


In my particular case, this led me to not intuit a correct assumption: I thought I could modify the Float32Array directly, but it wasn’t working:

// code that owns the buffer:
const existingBuffer = new Float32Array(...)

// some other component that received the buffer:
someGeometry.attributes.foo = new Float32BufferAttribute(existingBuffer, 3)

// code that owns the buffer:
existingBuffer[123] = 456 // <----------- why not working?

Workaround

For now I’ve replaced all instances of Float32BufferAttribute, Uint32BufferAttribute, etc, with plain BufferAttribute, but this makes the data types less obvious across the code. Reading the Float32/Uint32/etc prefixes is useful for semantics when reading various code locations.