Переглянути джерело

Playground: Fix connection lengths and let them be based on node input/output types (#27891)

* Test proper input and output coloring

* Add Type library for colors and in/output lengths

* Overwrite node nodetype with predefined nodetype if necessary

* Add DataType entries for matrices

* Calculate output length based on data type

* Improve code style and spacings

* Reduce color length from 4 to 3

* further clean up code; Allow color to be null
abc013 1 рік тому
батько
коміт
9d61527176

+ 9 - 32
playground/BaseNodeEditor.js

@@ -1,5 +1,6 @@
 import { Node, ButtonInput, TitleElement, ContextMenu } from 'flow';
-import { exportJSON, onValidNode, getColorFromValue, getTypeFromValue, getColorFromType } from './NodeEditorUtils.js';
+import { exportJSON, onValidNode } from './NodeEditorUtils.js';
+import { setOutputAestheticsFromNode, getColorFromNode, getLengthFromNode } from './DataTypeLib.js';
 
 export class BaseNodeEditor extends Node {
 
@@ -15,12 +16,11 @@ export class BaseNodeEditor extends Node {
 
 		this.setWidth( width );
 
-		this.outputLength = 1;
-
 		const title = new TitleElement( name )
 			.setObjectCallback( getObjectCallback )
-			.setSerializable( false )
-			.setOutput( this.outputLength );
+			.setSerializable( false );
+		
+		setOutputAestheticsFromNode( title, value );
 
 		const contextButton = new ButtonInput().onClick( () => {
 
@@ -78,19 +78,14 @@ export class BaseNodeEditor extends Node {
 
 		this.onValidElement = onValidNode;
 
-		this.updateOutputConnection();
-
-	}
-
-	getOutputType() {
-
-		return getTypeFromValue( this.value );
-
+		this.outputLength = getLengthFromNode( value );
 	}
 
 	getColor() {
 
-		return ( getColorFromType( this.getOutputType() ) || '#777777' ) + 'BB';
+		const color = getColorFromNode( this.value );
+
+		return color ? color + 'BB' : null;
 
 	}
 
@@ -162,16 +157,6 @@ export class BaseNodeEditor extends Node {
 
 	}
 
-	setOutputLength( value ) {
-
-		this.outputLength = value;
-
-		this.updateOutputConnection();
-
-		return;
-
-	}
-
 	setObjectCallback( callback ) {
 
 		this.title.setObjectCallback( callback );
@@ -194,14 +179,6 @@ export class BaseNodeEditor extends Node {
 
 	}
 
-	updateOutputConnection() {
-
-		this.title.setOutputColor( getColorFromValue( this.value ) );
-
-		this.title.setOutput( this.value ? this.outputLength : 0 );
-
-	}
-
 	invalidate() {
 
 		this.title.dispatchEvent( new Event( 'connect' ) );

+ 165 - 0
playground/DataTypeLib.js

@@ -0,0 +1,165 @@
+export const typeToLengthLib = {
+	// gpu
+	string: 1,
+	float: 1,
+	bool: 1,
+	vec2: 2,
+	vec3: 3,
+	vec4: 4,
+	color: 3,
+	mat2: 1,
+	mat3: 1,
+	mat4: 1,
+	// cpu
+	String: 1,
+	Number: 1,
+	Vector2: 2,
+	Vector3: 3,
+	Vector4: 4,
+	Color: 3,
+	// cpu: other stuff
+	Material: 1,
+	Object3D: 1,
+	CodeNode: 1,
+	Texture: 1,
+	URL: 1,
+	node: 1
+};
+
+export const defaultLength = 1;
+
+export function getLengthFromType( type ) {
+
+	return typeToLengthLib[ type ] || defaultLength;
+
+}
+
+export function getLengthFromNode( value ) {
+
+	let type = getTypeFromNode( value );
+
+	return getLengthFromType( type );
+
+}
+
+export const typeToColorLib = {
+	// gpu
+	string: '#ff0000',
+	float: '#eeeeee',
+	bool: '#00dd00',
+	mat2: '#70d030',
+	mat3: '#70d030',
+	mat4: '#70d030',
+	// cpu
+	String: '#ff0000',
+	Number: '#eeeeee',
+	// cpu: other stuff
+	Material: '#228b22',
+	Object3D: '#00a1ff',
+	CodeNode: '#ff00ff',
+	Texture: '#ffa500',
+	URL: '#ff0080'
+};
+
+export function getColorFromType( type ) {
+
+	return typeToColorLib[ type ] || null;
+
+}
+
+export function getColorFromNode( value ) {
+
+	let type = getTypeFromNode( value );
+
+	return getColorFromType( type );
+
+}
+
+function getTypeFromNode( value ) {
+
+	if ( value ) {
+
+		if ( value.isMaterial ) return 'Material';
+
+		return value.nodeType === 'ArrayBuffer' ? 'URL' : ( value.nodeType || getTypeFromValue( value.value ) );
+	}
+
+}
+
+function getTypeFromValue( value ) {
+
+	if ( value && value.isScriptableValueNode ) value = value.value;
+	if ( ! value ) return;
+
+	if ( value.isNode && value.nodeType === 'string' ) return 'string';
+	if ( value.isNode && value.nodeType === 'ArrayBuffer' ) return 'URL';
+
+	for ( const type of Object.keys( typeToLengthLib ).reverse() ) {
+
+		if ( value[ 'is' + type ] === true ) return type;
+
+	}
+
+}
+
+export function setInputAestheticsFromType( element, type ) {
+
+	element.setInput( getLengthFromType( type ) );
+
+	const color = getColorFromType( type );
+
+	if ( color ) {
+
+		element.setInputColor( color );
+
+	}
+
+	return element;
+
+}
+
+export function setOutputAestheticsFromNode( element, node ) {
+
+	if ( ! node ) {
+
+		element.setOutput( 0 );
+
+		return element;
+
+	}
+
+	return setOutputAestheticsFromType( element, getTypeFromNode( node ) );
+
+}
+
+export function setOutputAestheticsFromType( element, type ) {
+
+	if ( ! type ) {
+
+		element.setOutput( 1 );
+
+		return element;
+
+	}
+
+	if ( type == 'void' ) {
+
+		element.setOutput( 0 );
+
+		return element;
+
+	}
+
+	element.setOutput( getLengthFromType( type ) );
+
+	const color = getColorFromType( type );
+
+	if ( color ) {
+
+		element.setOutputColor( color );
+
+	}
+
+	return element;
+
+}

+ 3 - 46
playground/NodeEditorUtils.js

@@ -1,5 +1,6 @@
 import { StringInput, NumberInput, ColorInput, Element, LabelElement } from 'flow';
 import { string, float, vec2, vec3, vec4, color } from 'three/nodes';
+import { setInputAestheticsFromType, setOutputAestheticsFromType } from './DataTypeLib.js';
 
 export function exportJSON( object, name ) {
 
@@ -58,48 +59,6 @@ export function disposeMaterial( material )	{
 
 }
 
-export const colorLib = {
-	// gpu
-	string: '#ff0000',
-	// cpu
-	Material: '#228b22',
-	Object3D: '#00a1ff',
-	CodeNode: '#ff00ff',
-	Texture: '#ffa500',
-	URL: '#ff0080',
-	String: '#ff0000'
-};
-
-export function getColorFromType( type ) {
-
-	return colorLib[ type ];
-
-}
-
-export function getTypeFromValue( value ) {
-
-	if ( value && value.isScriptableValueNode ) value = value.value;
-	if ( ! value ) return;
-
-	if ( value.isNode && value.nodeType === 'string' ) return 'string';
-	if ( value.isNode && value.nodeType === 'ArrayBuffer' ) return 'URL';
-
-	for ( const type of Object.keys( colorLib ).reverse() ) {
-
-		if ( value[ 'is' + type ] === true ) return type;
-
-	}
-
-}
-
-export function getColorFromValue( value ) {
-
-	const type = getTypeFromValue( value );
-
-	return getColorFromType( type );
-
-}
-
 export const createColorInput = ( node, element ) => {
 
 	const input = new ColorInput().onChange( () => {
@@ -306,9 +265,8 @@ export function createElementFromJSON( json ) {
 
 	if ( inputType && json.inputConnection !== false ) {
 
-		element.setInputColor( getColorFromType( inputType ) );
+		setInputAestheticsFromType( element, inputType );
 		//element.setInputStyle( 'dotted' ); // 'border-style: dotted;'
-		element.setInput( 1 );
 
 		element.onValid( onValidType( inputType ) );
 
@@ -316,9 +274,8 @@ export function createElementFromJSON( json ) {
 
 	if ( outputType ) {
 
-		element.setInputColor( getColorFromType( outputType ) );
+		setOutputAestheticsFromType( element, outputType );
 		//element.setInputStyle( 'dotted' ); // 'border-style: dotted;'
-		element.setOutput( 1 );
 
 	}
 

+ 4 - 3
playground/editors/BasicMaterialEditor.js

@@ -1,6 +1,7 @@
 import { ColorInput, SliderInput, LabelElement } from 'flow';
 import { MaterialEditor } from './MaterialEditor.js';
 import { MeshBasicNodeMaterial } from 'three/nodes';
+import { setInputAestheticsFromType } from '../DataTypeLib.js';
 
 export class BasicMaterialEditor extends MaterialEditor {
 
@@ -10,9 +11,9 @@ export class BasicMaterialEditor extends MaterialEditor {
 
 		super( 'Basic Material', material );
 
-		const color = new LabelElement( 'color' ).setInput( 3 );
-		const opacity = new LabelElement( 'opacity' ).setInput( 1 );
-		const position = new LabelElement( 'position' ).setInput( 3 );
+		const color = setInputAestheticsFromType( new LabelElement( 'color' ), 'Color' );
+		const opacity = setInputAestheticsFromType( new LabelElement( 'opacity' ), 'Number' );
+		const position = setInputAestheticsFromType( new LabelElement( 'position' ), 'Vector3' );
 
 		color.add( new ColorInput( material.color.getHex() ).onChange( ( input ) => {
 

+ 0 - 2
playground/editors/ColorEditor.js

@@ -12,8 +12,6 @@ export class ColorEditor extends BaseNodeEditor {
 
 		super( 'Color', node );
 
-		this.setOutputLength( 3 );
-
 		const updateFields = ( editing ) => {
 
 			const value = node.value;

+ 4 - 1
playground/editors/CustomNodeEditor.js

@@ -4,6 +4,7 @@ import * as Nodes from 'three/nodes';
 import { uniform } from 'three/nodes';
 import { BaseNodeEditor } from '../BaseNodeEditor.js';
 import { createInputLib } from '../NodeEditorUtils.js';
+import { setInputAestheticsFromType } from '../DataTypeLib.js';
 
 const typeToValue = {
 	'color': Color,
@@ -33,7 +34,7 @@ const createElementFromProperty = ( node, property ) => {
 
 	node[ property.name ] = defaultValue;
 
-	const element = new LabelElement( label ).setInput( property.defaultLength || 1 );
+	const element = setInputAestheticsFromType( new LabelElement( label ), nodeType );
 
 	if ( createInputLib[ nodeType ] !== undefined ) {
 
@@ -79,6 +80,8 @@ export class CustomNodeEditor extends BaseNodeEditor {
 
 		}
 
+		node.nodeType = node.nodeType || settings.nodeType;
+
 		super( settings.name, node, 300 );
 
 		this.title.setIcon( 'ti ti-' + settings.icon );

+ 0 - 2
playground/editors/FloatEditor.js

@@ -12,8 +12,6 @@ export class FloatEditor extends BaseNodeEditor {
 
 		super( 'Float', inputNode, 150 );
 
-		this.setOutputLength( 1 );
-
 		element.addEventListener( 'changeInput', () => this.invalidate() );
 
 		this.add( element );

+ 5 - 4
playground/editors/JoinEditor.js

@@ -1,6 +1,7 @@
 import { LabelElement } from 'flow';
 import { BaseNodeEditor } from '../BaseNodeEditor.js';
 import { JoinNode, UniformNode, float } from 'three/nodes';
+import { setInputAestheticsFromType } from '../DataTypeLib.js';
 
 const NULL_VALUE = new UniformNode( 0 );
 
@@ -41,10 +42,10 @@ export class JoinEditor extends BaseNodeEditor {
 
 		};
 
-		const xElement = new LabelElement( 'x | r' ).setInput( 1 ).onConnect( update );
-		const yElement = new LabelElement( 'y | g' ).setInput( 1 ).onConnect( update );
-		const zElement = new LabelElement( 'z | b' ).setInput( 1 ).onConnect( update );
-		const wElement = new LabelElement( 'w | a' ).setInput( 1 ).onConnect( update );
+		const xElement = setInputAestheticsFromType( new LabelElement( 'x | r' ), 'Number' ).onConnect( update );
+		const yElement = setInputAestheticsFromType( new LabelElement( 'y | g' ), 'Number' ).onConnect( update );
+		const zElement = setInputAestheticsFromType( new LabelElement( 'z | b' ), 'Number' ).onConnect( update );
+		const wElement = setInputAestheticsFromType( new LabelElement( 'w | a' ), 'Number' ).onConnect( update );
 
 		this.add( xElement )
 			.add( yElement )

+ 6 - 5
playground/editors/PointsMaterialEditor.js

@@ -2,6 +2,7 @@ import { ColorInput, ToggleInput, SliderInput, LabelElement } from 'flow';
 import { MaterialEditor } from './MaterialEditor.js';
 import { PointsNodeMaterial } from 'three/nodes';
 import * as THREE from 'three';
+import { setInputAestheticsFromType } from '../DataTypeLib.js';
 
 export class PointsMaterialEditor extends MaterialEditor {
 
@@ -11,11 +12,11 @@ export class PointsMaterialEditor extends MaterialEditor {
 
 		super( 'Points Material', material );
 
-		const color = new LabelElement( 'color' ).setInput( 3 );
-		const opacity = new LabelElement( 'opacity' ).setInput( 1 );
-		const size = new LabelElement( 'size' ).setInput( 1 );
-		const position = new LabelElement( 'position' ).setInput( 3 );
-		const sizeAttenuation = new LabelElement( 'Size Attenuation' );
+		const color = setInputAestheticsFromType( new LabelElement( 'color' ), 'Color' );
+		const opacity = setInputAestheticsFromType( new LabelElement( 'opacity' ), 'Number' );
+		const size = setInputAestheticsFromType( new LabelElement( 'size' ), 'Number' );
+		const position = setInputAestheticsFromType( new LabelElement( 'position' ), 'Vector3' );
+		const sizeAttenuation = setInputAestheticsFromType( new LabelElement( 'Size Attenuation' ), 'Number' );
 
 		color.add( new ColorInput( material.color.getHex() ).onChange( ( input ) => {
 

+ 3 - 2
playground/editors/PreviewEditor.js

@@ -4,6 +4,7 @@ import { Element, LabelElement, SelectInput } from 'flow';
 import { BaseNodeEditor } from '../BaseNodeEditor.js';
 import { MeshBasicNodeMaterial, float } from 'three/nodes';
 import { WebGLRenderer, PerspectiveCamera, Scene, Mesh, DoubleSide, SphereGeometry, BoxGeometry, PlaneGeometry, TorusKnotGeometry } from 'three';
+import { setInputAestheticsFromType } from '../DataTypeLib.js';
 
 const sceneDict = {};
 
@@ -53,7 +54,7 @@ export class PreviewEditor extends BaseNodeEditor {
 		const width = 300;
 		const height = 300;
 
-		super( 'Preview', null, height );
+		super( 'Preview', null, width );
 
 		const material = new MeshBasicNodeMaterial();
 		material.colorNode = float();
@@ -74,7 +75,7 @@ export class PreviewEditor extends BaseNodeEditor {
 			{ name: 'Torus', value: 'torus' }
 		], 'box' );
 
-		const inputElement = new LabelElement( 'Input' ).setInput( 4 ).onConnect( () => {
+		const inputElement = setInputAestheticsFromType( new LabelElement( 'Input' ), 'Color' ).onConnect( () => {
 
 			material.colorNode = inputElement.getLinkedObject() || float();
 			material.dispose();

+ 8 - 6
playground/editors/ScriptableEditor.js

@@ -1,7 +1,8 @@
 import { BaseNodeEditor } from '../BaseNodeEditor.js';
 import { CodeEditorElement } from '../elements/CodeEditorElement.js';
-import { disposeScene, getColorFromType, createElementFromJSON, isGPUNode, onValidType } from '../NodeEditorUtils.js';
+import { disposeScene, createElementFromJSON, isGPUNode, onValidType } from '../NodeEditorUtils.js';
 import { global, scriptable, js, scriptableValue } from 'three/nodes';
+import { getColorFromType, setInputAestheticsFromType, setOutputAestheticsFromType } from '../DataTypeLib.js';
 
 const defaultTitle = 'Scriptable';
 const defaultWidth = 500;
@@ -67,9 +68,11 @@ export class ScriptableEditor extends BaseNodeEditor {
 
 	}
 
-	getOutputType() {
+	getColor() {
 
-		return this.layout ? this.layout.outputType : null;
+		const color = getColorFromType( this.layout ? this.layout.outputType : null );
+
+		return color ? color + 'BB' : null;
 
 	}
 
@@ -170,8 +173,7 @@ export class ScriptableEditor extends BaseNodeEditor {
 
 			const outputType = layout.outputType;
 
-			this.title.setOutputColor( getColorFromType( outputType ) );
-			this.title.setOutput( outputType && outputType !== 'void' ? this.outputLength : 0 );
+			setOutputAestheticsFromType( this.title, outputType );
 
 		} else {
 
@@ -406,7 +408,7 @@ export class ScriptableEditor extends BaseNodeEditor {
 
 	_initExternalConnection() {
 
-		this.title.setInputColor( getColorFromType( 'CodeNode' ) ).setInput( 1 ).onValid( onValidType( 'CodeNode' ) ).onConnect( () => {
+		setInputAestheticsFromType(this.title, 'CodeNode' ).onValid( onValidType( 'CodeNode' ) ).onConnect( () => {
 
 			this.hasExternalEditor ? this._toExternal() : this._toInternal();
 

+ 6 - 5
playground/editors/SplitEditor.js

@@ -1,6 +1,7 @@
 import { LabelElement } from 'flow';
 import { BaseNodeEditor } from '../BaseNodeEditor.js';
 import { nodeObject, float } from 'three/nodes';
+import { setInputAestheticsFromType } from '../DataTypeLib.js';
 
 export class SplitEditor extends BaseNodeEditor {
 
@@ -10,7 +11,7 @@ export class SplitEditor extends BaseNodeEditor {
 
 		let node = null;
 
-		const inputElement = new LabelElement( 'Input' ).setInput( 1 ).onConnect( () => {
+		const inputElement = setInputAestheticsFromType( new LabelElement( 'Input' ), 'node' ).onConnect( () => {
 
 			node = inputElement.getLinkedObject();
 
@@ -34,10 +35,10 @@ export class SplitEditor extends BaseNodeEditor {
 
 		this.add( inputElement );
 
-		const xElement = new LabelElement( 'x | r' ).setOutput( 1 ).setObject( float() );
-		const yElement = new LabelElement( 'y | g' ).setOutput( 1 ).setObject( float() );
-		const zElement = new LabelElement( 'z | b' ).setOutput( 1 ).setObject( float() );
-		const wElement = new LabelElement( 'w | a' ).setOutput( 1 ).setObject( float() );
+		const xElement = setInputAestheticsFromType( new LabelElement( 'x | r' ), 'Number' ).setObject( float() );
+		const yElement = setInputAestheticsFromType( new LabelElement( 'y | g' ), 'Number' ).setObject( float() );
+		const zElement = setInputAestheticsFromType( new LabelElement( 'z | b' ), 'Number' ).setObject( float() );
+		const wElement = setInputAestheticsFromType( new LabelElement( 'w | a' ), 'Number' ).setObject( float() );
 
 		this.add( inputElement )
 			.add( xElement )

+ 8 - 7
playground/editors/StandardMaterialEditor.js

@@ -1,6 +1,7 @@
 import { ColorInput, SliderInput, LabelElement } from 'flow';
 import { MaterialEditor } from './MaterialEditor.js';
 import { MeshStandardNodeMaterial } from 'three/nodes';
+import { setInputAestheticsFromType } from '../DataTypeLib.js';
 
 export class StandardMaterialEditor extends MaterialEditor {
 
@@ -10,13 +11,13 @@ export class StandardMaterialEditor extends MaterialEditor {
 
 		super( 'Standard Material', material );
 
-		const color = new LabelElement( 'color' ).setInput( 3 );
-		const opacity = new LabelElement( 'opacity' ).setInput( 1 );
-		const metalness = new LabelElement( 'metalness' ).setInput( 1 );
-		const roughness = new LabelElement( 'roughness' ).setInput( 1 );
-		const emissive = new LabelElement( 'emissive' ).setInput( 3 );
-		const normal = new LabelElement( 'normal' ).setInput( 3 );
-		const position = new LabelElement( 'position' ).setInput( 3 );
+		const color = setInputAestheticsFromType( new LabelElement( 'color' ), 'Color' );
+		const opacity = setInputAestheticsFromType( new LabelElement( 'opacity' ), 'Number' );
+		const metalness = setInputAestheticsFromType( new LabelElement( 'metalness' ), 'Number' );
+		const roughness = setInputAestheticsFromType( new LabelElement( 'roughness' ), 'Number' );
+		const emissive = setInputAestheticsFromType( new LabelElement( 'emissive' ), 'Color' );
+		const normal = setInputAestheticsFromType( new LabelElement( 'normal' ), 'Vector3' );
+		const position = setInputAestheticsFromType( new LabelElement( 'position' ), 'Vector3' );
 
 		color.add( new ColorInput( material.color.getHex() ).onChange( ( input ) => {
 

+ 0 - 2
playground/editors/StringEditor.js

@@ -12,8 +12,6 @@ export class StringEditor extends BaseNodeEditor {
 
 		super( 'String', inputNode, 350 );
 
-		this.setOutputLength( 1 );
-
 		element.addEventListener( 'changeInput', () => this.invalidate() );
 
 		this.add( element );

+ 2 - 1
playground/editors/SwizzleEditor.js

@@ -2,6 +2,7 @@ import { LabelElement } from 'flow';
 import { BaseNodeEditor } from '../BaseNodeEditor.js';
 import { createElementFromJSON } from '../NodeEditorUtils.js';
 import { split, float } from 'three/nodes';
+import { setInputAestheticsFromType } from '../DataTypeLib.js';
 
 export class SwizzleEditor extends BaseNodeEditor {
 
@@ -11,7 +12,7 @@ export class SwizzleEditor extends BaseNodeEditor {
 
 		super( 'Swizzle', node, 175 );
 
-		const inputElement = new LabelElement( 'Input' ).setInput( 1 ).onConnect( () => {
+		const inputElement = setInputAestheticsFromType( new LabelElement( 'Input' ), 'node' ).onConnect( () => {
 
 			node.node = inputElement.getLinkedObject() || float();
 

+ 4 - 5
playground/editors/TextureEditor.js

@@ -1,8 +1,9 @@
 import { LabelElement, ToggleInput, SelectInput } from 'flow';
 import { BaseNodeEditor } from '../BaseNodeEditor.js';
-import { onValidNode, onValidType, getColorFromType } from '../NodeEditorUtils.js';
+import { onValidNode, onValidType } from '../NodeEditorUtils.js';
 import { texture, uv } from 'three/nodes';
 import { Texture, TextureLoader, RepeatWrapping, ClampToEdgeWrapping, MirroredRepeatWrapping } from 'three';
+import { setInputAestheticsFromType } from '../DataTypeLib.js';
 
 const textureLoader = new TextureLoader();
 const defaultTexture = new Texture();
@@ -23,8 +24,6 @@ export class TextureEditor extends BaseNodeEditor {
 
 		super( 'Texture', node, 250 );
 
-		this.setOutputLength( 4 );
-
 		this.texture = null;
 
 		this._initFile();
@@ -36,7 +35,7 @@ export class TextureEditor extends BaseNodeEditor {
 
 	_initFile() {
 
-		const fileElement = new LabelElement( 'File' ).setInputColor( getColorFromType( 'URL' ) ).setInput( 1 );
+		const fileElement = setInputAestheticsFromType( new LabelElement( 'File' ), 'URL' );
 
 		fileElement.onValid( onValidType( 'URL' ) ).onConnect( () => {
 
@@ -57,7 +56,7 @@ export class TextureEditor extends BaseNodeEditor {
 
 	_initParams() {
 
-		const uvField = new LabelElement( 'UV' ).setInput( 2 );
+		const uvField = setInputAestheticsFromType( new LabelElement( 'UV' ), 'Vector2' );
 
 		uvField.onValid( onValidNode ).onConnect( () => {
 

+ 0 - 2
playground/editors/UVEditor.js

@@ -10,8 +10,6 @@ export class UVEditor extends BaseNodeEditor {
 
 		super( 'UV', node, 200 );
 
-		this.setOutputLength( 2 );
-
 		const optionsField = new SelectInput( [ '0', '1', '2', '3' ], 0 ).onChange( () => {
 
 			node.index = Number( optionsField.getValue() );

+ 0 - 2
playground/editors/Vector2Editor.js

@@ -12,8 +12,6 @@ export class Vector2Editor extends BaseNodeEditor {
 
 		super( 'Vector 2', inputNode );
 
-		this.setOutputLength( 2 );
-
 		element.addEventListener( 'changeInput', () => this.invalidate() );
 
 		this.add( element );

+ 0 - 2
playground/editors/Vector3Editor.js

@@ -12,8 +12,6 @@ export class Vector3Editor extends BaseNodeEditor {
 
 		super( 'Vector 3', inputNode, 325 );
 
-		this.setOutputLength( 3 );
-
 		element.addEventListener( 'changeInput', () => this.invalidate() );
 
 		this.add( element );

+ 0 - 2
playground/editors/Vector4Editor.js

@@ -12,8 +12,6 @@ export class Vector4Editor extends BaseNodeEditor {
 
 		super( 'Vector 4', inputNode, 350 );
 
-		this.setOutputLength( 4 );
-
 		element.addEventListener( 'changeInput', () => this.invalidate() );
 
 		this.add( element );