TextureEditor.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import { LabelElement, ToggleInput, SelectInput } from 'flow';
  2. import { BaseNodeEditor } from '../BaseNodeEditor.js';
  3. import { onValidNode, onValidType } from '../NodeEditorUtils.js';
  4. import { texture, uv } from 'three/nodes';
  5. import { Texture, TextureLoader, RepeatWrapping, ClampToEdgeWrapping, MirroredRepeatWrapping } from 'three';
  6. import { setInputAestheticsFromType } from '../DataTypeLib.js';
  7. const textureLoader = new TextureLoader();
  8. const defaultTexture = new Texture();
  9. let defaultUV = null;
  10. const getTexture = ( url ) => {
  11. return textureLoader.load( url );
  12. };
  13. export class TextureEditor extends BaseNodeEditor {
  14. constructor() {
  15. const node = texture( defaultTexture );
  16. super( 'Texture', node, 250 );
  17. this.texture = null;
  18. this._initFile();
  19. this._initParams();
  20. this.onValidElement = () => {};
  21. }
  22. _initFile() {
  23. const fileElement = setInputAestheticsFromType( new LabelElement( 'File' ), 'URL' );
  24. fileElement.onValid( onValidType( 'URL' ) ).onConnect( () => {
  25. const textureNode = this.value;
  26. const fileEditorElement = fileElement.getLinkedElement();
  27. this.texture = fileEditorElement ? getTexture( fileEditorElement.node.getURL() ) : null;
  28. textureNode.value = this.texture || defaultTexture;
  29. this.update();
  30. }, true );
  31. this.add( fileElement );
  32. }
  33. _initParams() {
  34. const uvField = setInputAestheticsFromType( new LabelElement( 'UV' ), 'Vector2' );
  35. uvField.onValid( onValidNode ).onConnect( () => {
  36. const node = this.value;
  37. node.uvNode = uvField.getLinkedObject() || defaultUV || ( defaultUV = uv() );
  38. } );
  39. this.wrapSInput = new SelectInput( [
  40. { name: 'Repeat Wrapping', value: RepeatWrapping },
  41. { name: 'Clamp To Edge Wrapping', value: ClampToEdgeWrapping },
  42. { name: 'Mirrored Repeat Wrapping', value: MirroredRepeatWrapping }
  43. ], RepeatWrapping ).onChange( () => {
  44. this.update();
  45. } );
  46. this.wrapTInput = new SelectInput( [
  47. { name: 'Repeat Wrapping', value: RepeatWrapping },
  48. { name: 'Clamp To Edge Wrapping', value: ClampToEdgeWrapping },
  49. { name: 'Mirrored Repeat Wrapping', value: MirroredRepeatWrapping }
  50. ], RepeatWrapping ).onChange( () => {
  51. this.update();
  52. } );
  53. this.flipYInput = new ToggleInput( false ).onChange( () => {
  54. this.update();
  55. } );
  56. this.add( uvField )
  57. .add( new LabelElement( 'Wrap S' ).add( this.wrapSInput ) )
  58. .add( new LabelElement( 'Wrap T' ).add( this.wrapTInput ) )
  59. .add( new LabelElement( 'Flip Y' ).add( this.flipYInput ) );
  60. }
  61. update() {
  62. const texture = this.texture;
  63. if ( texture ) {
  64. texture.wrapS = Number( this.wrapSInput.getValue() );
  65. texture.wrapT = Number( this.wrapTInput.getValue() );
  66. texture.flipY = this.flipYInput.getValue();
  67. texture.dispose();
  68. this.invalidate();
  69. }
  70. }
  71. }