105 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			105 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								import Node, { addNodeClass } from '../core/Node.js';
							 | 
						||
| 
								 | 
							
								import { getValueType } from '../core/NodeUtils.js';
							 | 
						||
| 
								 | 
							
								import { buffer } from '../accessors/BufferNode.js';
							 | 
						||
| 
								 | 
							
								//import { bufferAttribute } from '../accessors/BufferAttributeNode.js';
							 | 
						||
| 
								 | 
							
								import { instanceIndex } from '../core/IndexNode.js';
							 | 
						||
| 
								 | 
							
								import { nodeProxy, float } from '../shadernode/ShaderNode.js';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import { Vector4, MathUtils } from 'three';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								let min = null;
							 | 
						||
| 
								 | 
							
								let max = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									setup( builder ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const object = builder.object;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										let output = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( object.isInstancedMesh === true ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											const minValue = this.minNode.value;
							 | 
						||
| 
								 | 
							
											const maxValue = this.maxNode.value;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											const minLength = builder.getTypeLength( getValueType( minValue ) );
							 | 
						||
| 
								 | 
							
											const maxLength = builder.getTypeLength( getValueType( maxValue ) );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											min = min || new Vector4();
							 | 
						||
| 
								 | 
							
											max = max || new Vector4();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											min.setScalar( 0 );
							 | 
						||
| 
								 | 
							
											max.setScalar( 0 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( minLength === 1 ) min.setScalar( minValue );
							 | 
						||
| 
								 | 
							
											else if ( minValue.isColor ) min.set( minValue.r, minValue.g, minValue.b );
							 | 
						||
| 
								 | 
							
											else min.set( minValue.x, minValue.y, minValue.z || 0, minValue.w || 0 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( maxLength === 1 ) max.setScalar( maxValue );
							 | 
						||
| 
								 | 
							
											else if ( maxValue.isColor ) max.set( maxValue.r, maxValue.g, maxValue.b );
							 | 
						||
| 
								 | 
							
											else max.set( maxValue.x, maxValue.y, maxValue.z || 0, maxValue.w || 0 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											const stride = 4;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											const length = stride * object.count;
							 | 
						||
| 
								 | 
							
											const array = new Float32Array( length );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for ( let i = 0; i < length; i ++ ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												const index = i % stride;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												const minElementValue = min.getComponent( index );
							 | 
						||
| 
								 | 
							
												const maxElementValue = max.getComponent( index );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												array[ i ] = MathUtils.lerp( minElementValue, maxElementValue, Math.random() );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											const nodeType = this.getNodeType( builder );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											output = buffer( array, 'vec4', object.count ).element( instanceIndex ).convert( nodeType );
							 | 
						||
| 
								 | 
							
											//output = bufferAttribute( array, 'vec4', 4, 0 ).convert( nodeType );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										} else {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											output = float( 0 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return output;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export default RangeNode;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export const range = nodeProxy( RangeNode );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								addNodeClass( 'RangeNode', RangeNode );
							 |