Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Playground: Color sockets based on node input/output types #27759

Open
wants to merge 9 commits into
base: dev
Choose a base branch
from
41 changes: 9 additions & 32 deletions 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 {

Expand All @@ -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( () => {

Expand Down Expand Up @@ -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;

}

Expand Down Expand Up @@ -162,16 +157,6 @@ export class BaseNodeEditor extends Node {

}

setOutputLength( value ) {

this.outputLength = value;

this.updateOutputConnection();

return;

}

setObjectCallback( callback ) {

this.title.setObjectCallback( callback );
Expand All @@ -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' ) );
Expand Down
174 changes: 174 additions & 0 deletions playground/DataTypeLib.js
@@ -0,0 +1,174 @@
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',
vec2: '#0000ff',
vec3: '#0000ff',
vec4: '#0000ff',
mat2: '#70d030',
mat3: '#70d030',
mat4: '#70d030',
color: '#00ffff',
// cpu
String: '#ff0000',
Number: '#eeeeee',
Vector2: '#0000ff',
Vector3: '#0000ff',
Vector4: '#0000ff',
Color: '#00ffff',
// cpu: other stuff
Material: '#228b22',
Object3D: '#00a1ff',
CodeNode: '#ff00ff',
Texture: '#ffa500',
URL: '#ff0080',
node: '#ff00ff'
};

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;

}
49 changes: 3 additions & 46 deletions 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 ) {

Expand Down Expand Up @@ -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( () => {
Expand Down Expand Up @@ -306,19 +265,17 @@ 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 ) );

}

if ( outputType ) {

element.setInputColor( getColorFromType( outputType ) );
setOutputAestheticsFromType( element, outputType );
//element.setInputStyle( 'dotted' ); // 'border-style: dotted;'
element.setOutput( 1 );

}

Expand Down
7 changes: 4 additions & 3 deletions 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 {

Expand All @@ -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 ) => {

Expand Down
2 changes: 0 additions & 2 deletions playground/editors/ColorEditor.js
Expand Up @@ -12,8 +12,6 @@ export class ColorEditor extends BaseNodeEditor {

super( 'Color', node );

this.setOutputLength( 3 );

const updateFields = ( editing ) => {

const value = node.value;
Expand Down
5 changes: 4 additions & 1 deletion playground/editors/CustomNodeEditor.js
Expand Up @@ -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,
Expand Down Expand Up @@ -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 ) {

Expand Down Expand Up @@ -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 );
Expand Down
2 changes: 0 additions & 2 deletions playground/editors/FloatEditor.js
Expand Up @@ -12,8 +12,6 @@ export class FloatEditor extends BaseNodeEditor {

super( 'Float', inputNode, 150 );

this.setOutputLength( 1 );

element.addEventListener( 'changeInput', () => this.invalidate() );

this.add( element );
Expand Down