123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- import Node, { addNodeClass } from '../core/Node.js';
- import { getValueType } from '../core/NodeUtils.js';
- import { attribute } from '../core/AttributeNode.js';
- import { nodeProxy, float } from '../shadernode/ShaderNode.js';
- import { MathUtils, InstancedBufferAttribute } 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 ) {
- const geometry = builder.geometry;
- 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 attributeName = 'node' + this.id;
- const length = vectorLength * object.count;
- const array = new Float32Array( length );
- const attributeGeometry = geometry.getAttribute( attributeName );
- if ( attributeGeometry === undefined || attributeGeometry.array.length < 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() );
- }
- }
- geometry.setAttribute( attributeName, new InstancedBufferAttribute( array, vectorLength ) );
- geometry.dispose();
- }
- output = attribute( attributeName, builder.getTypeFromLength( vectorLength ) );
- } else {
- output = float( 0 );
- }
- return output;
- }
- }
- export default RangeNode;
- export const range = nodeProxy( RangeNode );
- addNodeClass( RangeNode );
|