2
0

RangeNode.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import Node, { addNodeClass } from '../core/Node.js';
  2. import { getValueType } from '../core/NodeUtils.js';
  3. import { attribute } from '../core/AttributeNode.js';
  4. import { nodeProxy, float } from '../shadernode/ShaderNode.js';
  5. import { MathUtils, InstancedBufferAttribute } from 'three';
  6. class RangeNode extends Node {
  7. constructor( minNode = float(), maxNode = float() ) {
  8. super();
  9. this.minNode = minNode;
  10. this.maxNode = maxNode;
  11. }
  12. getVectorLength( builder ) {
  13. const minLength = builder.getTypeLength( getValueType( this.minNode.value ) );
  14. const maxLength = builder.getTypeLength( getValueType( this.maxNode.value ) );
  15. return minLength > maxLength ? minLength : maxLength;
  16. }
  17. getNodeType( builder ) {
  18. return builder.object.isInstancedMesh === true ? builder.getTypeFromLength( this.getVectorLength( builder ) ) : 'float';
  19. }
  20. construct( builder ) {
  21. const object = builder.object;
  22. let output = null;
  23. if ( object.isInstancedMesh === true ) {
  24. const geometry = builder.geometry;
  25. let min = this.minNode.value;
  26. let max = this.maxNode.value;
  27. const minLength = builder.getTypeLength( getValueType( min ) );
  28. const maxLength = builder.getTypeLength( getValueType( max ) );
  29. if ( minLength > maxLength && maxLength > 1 ) max = new min.constructor().fromArray( min.toArray() );
  30. else if ( minLength > maxLength && maxLength === 1 ) max = new min.constructor().setScalar( max );
  31. else if ( maxLength > minLength && minLength > 1 ) min = new max.constructor().fromArray( min.toArray() );
  32. else if ( maxLength > minLength && minLength === 1 ) min = new max.constructor().setScalar( min );
  33. const vectorLength = this.getVectorLength( builder );
  34. const attributeName = 'node' + this.id;
  35. const length = vectorLength * object.count;
  36. const array = new Float32Array( length );
  37. const attributeGeometry = geometry.getAttribute( attributeName );
  38. if ( attributeGeometry === undefined || attributeGeometry.array.length < length ) {
  39. if ( vectorLength === 1 ) {
  40. for ( let i = 0; i < length; i ++ ) {
  41. array[ i ] = MathUtils.lerp( min, max, Math.random() );
  42. }
  43. } else if ( min.isColor ) {
  44. for ( let i = 0; i < length; i += 3 ) {
  45. array[ i ] = MathUtils.lerp( min.r, max.r, Math.random() );
  46. array[ i + 1 ] = MathUtils.lerp( min.g, max.g, Math.random() );
  47. array[ i + 2 ] = MathUtils.lerp( min.b, max.b, Math.random() );
  48. }
  49. } else {
  50. for ( let i = 0; i < length; i ++ ) {
  51. const index = i % vectorLength;
  52. const minValue = min.getComponent( index );
  53. const maxValue = max.getComponent( index );
  54. array[ i ] = MathUtils.lerp( minValue, maxValue, Math.random() );
  55. }
  56. }
  57. geometry.setAttribute( attributeName, new InstancedBufferAttribute( array, vectorLength ) );
  58. geometry.dispose();
  59. }
  60. output = attribute( attributeName, builder.getTypeFromLength( vectorLength ) );
  61. } else {
  62. output = float( 0 );
  63. }
  64. return output;
  65. }
  66. }
  67. export default RangeNode;
  68. export const range = nodeProxy( RangeNode );
  69. addNodeClass( RangeNode );