import Node, { addNodeClass } from '../core/Node.js'; import { getValueType } from '../core/NodeUtils.js'; import { bufferAttribute } from '../accessors/BufferAttributeNode.js'; import { nodeProxy, float } from '../shadernode/ShaderNode.js'; import { MathUtils } from 'three'; class RangeNode extends Node { constructor( minNode = float(), maxNode = float() ) { super(); this.minNode = minNode; this.maxNode = maxNode; } getVectorLength( builder ) { const minLength = builder.getTypeLength( getValueType( this.minNode.value ) ); const maxLength = builder.getTypeLength( getValueType( this.maxNode.value ) ); return minLength > maxLength ? minLength : maxLength; } getNodeType( builder ) { return builder.object.isInstancedMesh === true ? builder.getTypeFromLength( this.getVectorLength( builder ) ) : 'float'; } construct( builder ) { const object = builder.object; let output = null; if ( object.isInstancedMesh === true ) { let min = this.minNode.value; let max = this.maxNode.value; const minLength = builder.getTypeLength( getValueType( min ) ); const maxLength = builder.getTypeLength( getValueType( max ) ); if ( minLength > maxLength && maxLength > 1 ) max = new min.constructor().fromArray( min.toArray() ); else if ( minLength > maxLength && maxLength === 1 ) max = new min.constructor().setScalar( max ); else if ( maxLength > minLength && minLength > 1 ) min = new max.constructor().fromArray( min.toArray() ); else if ( maxLength > minLength && minLength === 1 ) min = new max.constructor().setScalar( min ); const vectorLength = this.getVectorLength( builder ); const length = vectorLength * object.count; const array = new Float32Array( length ); if ( vectorLength === 1 ) { for ( let i = 0; i < length; i ++ ) { array[ i ] = MathUtils.lerp( min, max, Math.random() ); } } else if ( min.isColor ) { for ( let i = 0; i < length; i += 3 ) { array[ i ] = MathUtils.lerp( min.r, max.r, Math.random() ); array[ i + 1 ] = MathUtils.lerp( min.g, max.g, Math.random() ); array[ i + 2 ] = MathUtils.lerp( min.b, max.b, Math.random() ); } } else { for ( let i = 0; i < length; i ++ ) { const index = i % vectorLength; const minValue = min.getComponent( index ); const maxValue = max.getComponent( index ); array[ i ] = MathUtils.lerp( minValue, maxValue, Math.random() ); } } output = bufferAttribute( array, builder.getTypeFromLength( vectorLength ) ); } else { output = float( 0 ); } return output; } } export default RangeNode; export const range = nodeProxy( RangeNode ); addNodeClass( RangeNode );