You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
2.7 KiB
JavaScript
120 lines
2.7 KiB
JavaScript
import { LabelElement, ToggleInput, SelectInput } from 'flow';
|
|
import { BaseNodeEditor } from '../BaseNodeEditor.js';
|
|
import { onValidNode, onValidType } from '../NodeEditorUtils.js';
|
|
import { texture, uv } from 'three/tsl';
|
|
import { Texture, TextureLoader, RepeatWrapping, ClampToEdgeWrapping, MirroredRepeatWrapping } from 'three';
|
|
import { setInputAestheticsFromType } from '../DataTypeLib.js';
|
|
|
|
const textureLoader = new TextureLoader();
|
|
const defaultTexture = new Texture();
|
|
|
|
let defaultUV = null;
|
|
|
|
const getTexture = ( url ) => {
|
|
|
|
return textureLoader.load( url );
|
|
|
|
};
|
|
|
|
export class TextureEditor extends BaseNodeEditor {
|
|
|
|
constructor() {
|
|
|
|
const node = texture( defaultTexture );
|
|
|
|
super( 'Texture', node, 250 );
|
|
|
|
this.texture = null;
|
|
|
|
this._initFile();
|
|
this._initParams();
|
|
|
|
this.onValidElement = () => {};
|
|
|
|
}
|
|
|
|
_initFile() {
|
|
|
|
const fileElement = setInputAestheticsFromType( new LabelElement( 'File' ), 'URL' );
|
|
|
|
fileElement.onValid( onValidType( 'URL' ) ).onConnect( () => {
|
|
|
|
const textureNode = this.value;
|
|
const fileEditorElement = fileElement.getLinkedElement();
|
|
|
|
this.texture = fileEditorElement ? getTexture( fileEditorElement.node.getURL() ) : null;
|
|
|
|
textureNode.value = this.texture || defaultTexture;
|
|
|
|
this.update();
|
|
|
|
}, true );
|
|
|
|
this.add( fileElement );
|
|
|
|
}
|
|
|
|
_initParams() {
|
|
|
|
const uvField = setInputAestheticsFromType( new LabelElement( 'UV' ), 'Vector2' );
|
|
|
|
uvField.onValid( onValidNode ).onConnect( () => {
|
|
|
|
const node = this.value;
|
|
|
|
node.uvNode = uvField.getLinkedObject() || defaultUV || ( defaultUV = uv() );
|
|
|
|
} );
|
|
|
|
this.wrapSInput = new SelectInput( [
|
|
{ name: 'Repeat Wrapping', value: RepeatWrapping },
|
|
{ name: 'Clamp To Edge Wrapping', value: ClampToEdgeWrapping },
|
|
{ name: 'Mirrored Repeat Wrapping', value: MirroredRepeatWrapping }
|
|
], RepeatWrapping ).onChange( () => {
|
|
|
|
this.update();
|
|
|
|
} );
|
|
|
|
this.wrapTInput = new SelectInput( [
|
|
{ name: 'Repeat Wrapping', value: RepeatWrapping },
|
|
{ name: 'Clamp To Edge Wrapping', value: ClampToEdgeWrapping },
|
|
{ name: 'Mirrored Repeat Wrapping', value: MirroredRepeatWrapping }
|
|
], RepeatWrapping ).onChange( () => {
|
|
|
|
this.update();
|
|
|
|
} );
|
|
|
|
this.flipYInput = new ToggleInput( false ).onChange( () => {
|
|
|
|
this.update();
|
|
|
|
} );
|
|
|
|
this.add( uvField )
|
|
.add( new LabelElement( 'Wrap S' ).add( this.wrapSInput ) )
|
|
.add( new LabelElement( 'Wrap T' ).add( this.wrapTInput ) )
|
|
.add( new LabelElement( 'Flip Y' ).add( this.flipYInput ) );
|
|
|
|
}
|
|
|
|
update() {
|
|
|
|
const texture = this.texture;
|
|
|
|
if ( texture ) {
|
|
|
|
texture.wrapS = Number( this.wrapSInput.getValue() );
|
|
texture.wrapT = Number( this.wrapTInput.getValue() );
|
|
texture.flipY = this.flipYInput.getValue();
|
|
texture.dispose();
|
|
|
|
this.invalidate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|