Initial commit
This commit is contained in:
763
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/NodeEditor.js
generated
vendored
Normal file
763
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/NodeEditor.js
generated
vendored
Normal file
@@ -0,0 +1,763 @@
|
||||
import { Styles, Canvas, CircleMenu, ButtonInput, ContextMenu, Tips, Search, Loader } from '../libs/flow.module.js';
|
||||
import { BasicMaterialEditor } from './materials/BasicMaterialEditor.js';
|
||||
import { StandardMaterialEditor } from './materials/StandardMaterialEditor.js';
|
||||
import { PointsMaterialEditor } from './materials/PointsMaterialEditor.js';
|
||||
import { OperatorEditor } from './math/OperatorEditor.js';
|
||||
import { NormalizeEditor } from './math/NormalizeEditor.js';
|
||||
import { InvertEditor } from './math/InvertEditor.js';
|
||||
import { LimiterEditor } from './math/LimiterEditor.js';
|
||||
import { DotEditor } from './math/DotEditor.js';
|
||||
import { PowerEditor } from './math/PowerEditor.js';
|
||||
import { AngleEditor } from './math/AngleEditor.js';
|
||||
import { TrigonometryEditor } from './math/TrigonometryEditor.js';
|
||||
import { FloatEditor } from './inputs/FloatEditor.js';
|
||||
import { Vector2Editor } from './inputs/Vector2Editor.js';
|
||||
import { Vector3Editor } from './inputs/Vector3Editor.js';
|
||||
import { Vector4Editor } from './inputs/Vector4Editor.js';
|
||||
import { SliderEditor } from './inputs/SliderEditor.js';
|
||||
import { ColorEditor } from './inputs/ColorEditor.js';
|
||||
import { TextureEditor } from './inputs/TextureEditor.js';
|
||||
import { BlendEditor } from './display/BlendEditor.js';
|
||||
import { NormalMapEditor } from './display/NormalMapEditor.js';
|
||||
import { UVEditor } from './accessors/UVEditor.js';
|
||||
import { PositionEditor } from './accessors/PositionEditor.js';
|
||||
import { NormalEditor } from './accessors/NormalEditor.js';
|
||||
import { PreviewEditor } from './utils/PreviewEditor.js';
|
||||
import { TimerEditor } from './utils/TimerEditor.js';
|
||||
import { OscillatorEditor } from './utils/OscillatorEditor.js';
|
||||
import { SplitEditor } from './utils/SplitEditor.js';
|
||||
import { JoinEditor } from './utils/JoinEditor.js';
|
||||
import { CheckerEditor } from './procedural/CheckerEditor.js';
|
||||
import { PointsEditor } from './scene/PointsEditor.js';
|
||||
import { MeshEditor } from './scene/MeshEditor.js';
|
||||
import { FileEditor } from './core/FileEditor.js';
|
||||
import { EventDispatcher } from 'three';
|
||||
|
||||
Styles.icons.unlink = 'ti ti-unlink';
|
||||
|
||||
export const NodeList = [
|
||||
{
|
||||
name: 'Inputs',
|
||||
icon: 'forms',
|
||||
children: [
|
||||
{
|
||||
name: 'Slider',
|
||||
icon: 'adjustments-horizontal',
|
||||
nodeClass: SliderEditor
|
||||
},
|
||||
{
|
||||
name: 'Float',
|
||||
icon: 'box-multiple-1',
|
||||
nodeClass: FloatEditor
|
||||
},
|
||||
{
|
||||
name: 'Vector 2',
|
||||
icon: 'box-multiple-2',
|
||||
nodeClass: Vector2Editor
|
||||
},
|
||||
{
|
||||
name: 'Vector 3',
|
||||
icon: 'box-multiple-3',
|
||||
nodeClass: Vector3Editor
|
||||
},
|
||||
{
|
||||
name: 'Vector 4',
|
||||
icon: 'box-multiple-4',
|
||||
nodeClass: Vector4Editor
|
||||
},
|
||||
{
|
||||
name: 'Color',
|
||||
icon: 'palette',
|
||||
nodeClass: ColorEditor
|
||||
},
|
||||
{
|
||||
name: 'Texture',
|
||||
icon: 'photo',
|
||||
nodeClass: TextureEditor
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Accessors',
|
||||
icon: 'vector-triangle',
|
||||
children: [
|
||||
{
|
||||
name: 'UV',
|
||||
icon: 'details',
|
||||
nodeClass: UVEditor
|
||||
},
|
||||
{
|
||||
name: 'Position',
|
||||
icon: 'hierarchy',
|
||||
nodeClass: PositionEditor
|
||||
},
|
||||
{
|
||||
name: 'Normal',
|
||||
icon: 'fold-up',
|
||||
nodeClass: NormalEditor
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Display',
|
||||
icon: 'brightness',
|
||||
children: [
|
||||
{
|
||||
name: 'Blend',
|
||||
icon: 'layers-subtract',
|
||||
nodeClass: BlendEditor
|
||||
},
|
||||
{
|
||||
name: 'Normal Map',
|
||||
icon: 'chart-line',
|
||||
nodeClass: NormalMapEditor
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Math',
|
||||
icon: 'calculator',
|
||||
children: [
|
||||
{
|
||||
name: 'Operator',
|
||||
icon: 'math-symbols',
|
||||
nodeClass: OperatorEditor
|
||||
},
|
||||
{
|
||||
name: 'Invert',
|
||||
icon: 'flip-vertical',
|
||||
tip: 'Negate',
|
||||
nodeClass: InvertEditor
|
||||
},
|
||||
{
|
||||
name: 'Limiter',
|
||||
icon: 'arrow-bar-to-up',
|
||||
tip: 'Min / Max',
|
||||
nodeClass: LimiterEditor
|
||||
},
|
||||
{
|
||||
name: 'Dot Product',
|
||||
icon: 'arrows-up-left',
|
||||
nodeClass: DotEditor
|
||||
},
|
||||
{
|
||||
name: 'Power',
|
||||
icon: 'arrow-up-right',
|
||||
nodeClass: PowerEditor
|
||||
},
|
||||
{
|
||||
name: 'Trigonometry',
|
||||
icon: 'wave-sine',
|
||||
tip: 'Sin / Cos / Tan / ...',
|
||||
nodeClass: TrigonometryEditor
|
||||
},
|
||||
{
|
||||
name: 'Angle',
|
||||
icon: 'angle',
|
||||
tip: 'Degress / Radians',
|
||||
nodeClass: AngleEditor
|
||||
},
|
||||
{
|
||||
name: 'Normalize',
|
||||
icon: 'fold',
|
||||
nodeClass: NormalizeEditor
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Procedural',
|
||||
icon: 'infinity',
|
||||
children: [
|
||||
{
|
||||
name: 'Checker',
|
||||
icon: 'border-outer',
|
||||
nodeClass: CheckerEditor
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Utils',
|
||||
icon: 'apps',
|
||||
children: [
|
||||
{
|
||||
name: 'Preview',
|
||||
icon: 'square-check',
|
||||
nodeClass: PreviewEditor
|
||||
},
|
||||
{
|
||||
name: 'Timer',
|
||||
icon: 'clock',
|
||||
nodeClass: TimerEditor
|
||||
},
|
||||
{
|
||||
name: 'Oscillator',
|
||||
icon: 'wave-sine',
|
||||
nodeClass: OscillatorEditor
|
||||
},
|
||||
{
|
||||
name: 'Split',
|
||||
icon: 'arrows-split-2',
|
||||
nodeClass: SplitEditor
|
||||
},
|
||||
{
|
||||
name: 'Join',
|
||||
icon: 'arrows-join-2',
|
||||
nodeClass: JoinEditor
|
||||
}
|
||||
]
|
||||
},
|
||||
/*{
|
||||
name: 'Scene',
|
||||
icon: '3d-cube-sphere',
|
||||
children: [
|
||||
{
|
||||
name: 'Mesh',
|
||||
icon: '3d-cube-sphere',
|
||||
nodeClass: MeshEditor
|
||||
}
|
||||
]
|
||||
},*/
|
||||
{
|
||||
name: 'Material',
|
||||
icon: 'circles',
|
||||
children: [
|
||||
{
|
||||
name: 'Basic Material',
|
||||
icon: 'circle',
|
||||
nodeClass: BasicMaterialEditor
|
||||
},
|
||||
{
|
||||
name: 'Standard Material',
|
||||
icon: 'circle',
|
||||
nodeClass: StandardMaterialEditor
|
||||
},
|
||||
{
|
||||
name: 'Points Material',
|
||||
icon: 'circle-dotted',
|
||||
nodeClass: PointsMaterialEditor
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
export const ClassLib = {
|
||||
BasicMaterialEditor,
|
||||
StandardMaterialEditor,
|
||||
PointsMaterialEditor,
|
||||
PointsEditor,
|
||||
MeshEditor,
|
||||
OperatorEditor,
|
||||
NormalizeEditor,
|
||||
InvertEditor,
|
||||
LimiterEditor,
|
||||
DotEditor,
|
||||
PowerEditor,
|
||||
AngleEditor,
|
||||
TrigonometryEditor,
|
||||
FloatEditor,
|
||||
Vector2Editor,
|
||||
Vector3Editor,
|
||||
Vector4Editor,
|
||||
SliderEditor,
|
||||
ColorEditor,
|
||||
TextureEditor,
|
||||
BlendEditor,
|
||||
NormalMapEditor,
|
||||
UVEditor,
|
||||
PositionEditor,
|
||||
NormalEditor,
|
||||
TimerEditor,
|
||||
OscillatorEditor,
|
||||
SplitEditor,
|
||||
JoinEditor,
|
||||
CheckerEditor
|
||||
};
|
||||
|
||||
export class NodeEditor extends EventDispatcher {
|
||||
|
||||
constructor( scene = null ) {
|
||||
|
||||
super();
|
||||
|
||||
const domElement = document.createElement( 'flow' );
|
||||
const canvas = new Canvas();
|
||||
|
||||
domElement.append( canvas.dom );
|
||||
|
||||
this.scene = scene;
|
||||
|
||||
this.canvas = canvas;
|
||||
this.domElement = domElement;
|
||||
|
||||
this.nodesContext = null;
|
||||
this.examplesContext = null;
|
||||
|
||||
this._initUpload();
|
||||
this._initTips();
|
||||
this._initMenu();
|
||||
this._initSearch();
|
||||
this._initNodesContext();
|
||||
this._initExamplesContext();
|
||||
|
||||
}
|
||||
|
||||
centralizeNode( node ) {
|
||||
|
||||
const canvas = this.canvas;
|
||||
const canvasRect = canvas.rect;
|
||||
|
||||
const nodeRect = node.dom.getBoundingClientRect();
|
||||
|
||||
const defaultOffsetX = nodeRect.width;
|
||||
const defaultOffsetY = nodeRect.height;
|
||||
|
||||
node.setPosition(
|
||||
( canvas.relativeX + ( canvasRect.width / 2 ) ) - defaultOffsetX,
|
||||
( canvas.relativeY + ( canvasRect.height / 2 ) ) - defaultOffsetY
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
add( node ) {
|
||||
|
||||
const onRemove = () => {
|
||||
|
||||
node.removeEventListener( 'remove', onRemove );
|
||||
|
||||
node.setEditor( null );
|
||||
|
||||
};
|
||||
|
||||
node.setEditor( this );
|
||||
node.addEventListener( 'remove', onRemove );
|
||||
|
||||
this.canvas.add( node );
|
||||
|
||||
this.dispatchEvent( { type: 'add', node } );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
get nodes() {
|
||||
|
||||
return this.canvas.nodes;
|
||||
|
||||
}
|
||||
|
||||
newProject() {
|
||||
|
||||
this.canvas.clear();
|
||||
|
||||
this.dispatchEvent( { type: 'new' } );
|
||||
|
||||
}
|
||||
|
||||
loadJSON( json ) {
|
||||
|
||||
const canvas = this.canvas;
|
||||
|
||||
canvas.clear();
|
||||
|
||||
canvas.deserialize( json );
|
||||
|
||||
for ( const node of canvas.nodes ) {
|
||||
|
||||
this.add( node );
|
||||
|
||||
}
|
||||
|
||||
this.dispatchEvent( { type: 'load' } );
|
||||
|
||||
}
|
||||
|
||||
_initUpload() {
|
||||
|
||||
const canvas = this.canvas;
|
||||
|
||||
canvas.onDrop( () => {
|
||||
|
||||
for ( const item of canvas.droppedItems ) {
|
||||
|
||||
if ( /^image\//.test( item.type ) === true ) {
|
||||
|
||||
const { relativeClientX, relativeClientY } = canvas;
|
||||
|
||||
const file = item.getAsFile();
|
||||
const fileEditor = new FileEditor( file );
|
||||
|
||||
fileEditor.setPosition(
|
||||
relativeClientX - ( fileEditor.getWidth() / 2 ),
|
||||
relativeClientY - 20
|
||||
);
|
||||
|
||||
this.add( fileEditor );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
_initTips() {
|
||||
|
||||
this.tips = new Tips();
|
||||
|
||||
this.domElement.append( this.tips.dom );
|
||||
|
||||
}
|
||||
|
||||
_initMenu() {
|
||||
|
||||
const menu = new CircleMenu();
|
||||
|
||||
const menuButton = new ButtonInput().setIcon( 'ti ti-apps' ).setToolTip( 'Add' );
|
||||
const examplesButton = new ButtonInput().setIcon( 'ti ti-file-symlink' ).setToolTip( 'Examples' );
|
||||
const newButton = new ButtonInput().setIcon( 'ti ti-file' ).setToolTip( 'New' );
|
||||
const openButton = new ButtonInput().setIcon( 'ti ti-upload' ).setToolTip( 'Open' );
|
||||
const saveButton = new ButtonInput().setIcon( 'ti ti-download' ).setToolTip( 'Save' );
|
||||
|
||||
menuButton.onClick( () => this.nodesContext.open() );
|
||||
examplesButton.onClick( () => this.examplesContext.open() );
|
||||
|
||||
newButton.onClick( () => {
|
||||
|
||||
if ( confirm( 'Are you sure?' ) === true ) {
|
||||
|
||||
this.newProject();
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
openButton.onClick( () => {
|
||||
|
||||
const input = document.createElement( 'input' );
|
||||
input.type = 'file';
|
||||
|
||||
input.onchange = e => {
|
||||
|
||||
const file = e.target.files[ 0 ];
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.readAsText( file, 'UTF-8' );
|
||||
|
||||
reader.onload = readerEvent => {
|
||||
|
||||
const loader = new Loader( Loader.OBJECTS );
|
||||
const json = loader.parse( JSON.parse( readerEvent.target.result ), ClassLib );
|
||||
|
||||
this.loadJSON( json );
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
input.click();
|
||||
|
||||
} );
|
||||
|
||||
saveButton.onClick( () => {
|
||||
|
||||
const json = JSON.stringify( this.canvas.toJSON() );
|
||||
|
||||
const a = document.createElement( 'a' );
|
||||
const file = new Blob( [ json ], { type: 'text/plain' } );
|
||||
|
||||
a.href = URL.createObjectURL( file );
|
||||
a.download = 'node_editor.json';
|
||||
a.click();
|
||||
|
||||
} );
|
||||
|
||||
menu.add( examplesButton )
|
||||
.add( menuButton )
|
||||
.add( newButton )
|
||||
.add( openButton )
|
||||
.add( saveButton );
|
||||
|
||||
this.domElement.append( menu.dom );
|
||||
|
||||
this.menu = menu;
|
||||
|
||||
}
|
||||
|
||||
_initExamplesContext() {
|
||||
|
||||
const context = new ContextMenu();
|
||||
|
||||
//**************//
|
||||
// MAIN
|
||||
//**************//
|
||||
|
||||
const onClickExample = async ( button ) => {
|
||||
|
||||
this.examplesContext.hide();
|
||||
|
||||
const filename = button.getExtra();
|
||||
|
||||
const loader = new Loader( Loader.OBJECTS );
|
||||
const json = await loader.load( `./jsm/node-editor/examples/${filename}.json`, ClassLib );
|
||||
|
||||
this.loadJSON( json );
|
||||
|
||||
};
|
||||
|
||||
const addExample = ( context, name, filename = null ) => {
|
||||
|
||||
filename = filename || name.replaceAll( ' ', '-' ).toLowerCase();
|
||||
|
||||
context.add( new ButtonInput( name )
|
||||
.setIcon( 'ti ti-file-symlink' )
|
||||
.onClick( onClickExample )
|
||||
.setExtra( filename )
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
//**************//
|
||||
// EXAMPLES
|
||||
//**************//
|
||||
|
||||
const basicContext = new ContextMenu();
|
||||
const advancedContext = new ContextMenu();
|
||||
|
||||
addExample( basicContext, 'Animate UV' );
|
||||
addExample( basicContext, 'Fake top light' );
|
||||
addExample( basicContext, 'Oscillator color' );
|
||||
|
||||
addExample( advancedContext, 'Rim' );
|
||||
|
||||
//**************//
|
||||
// MAIN
|
||||
//**************//
|
||||
|
||||
context.add( new ButtonInput( 'Basic' ), basicContext );
|
||||
context.add( new ButtonInput( 'Advanced' ), advancedContext );
|
||||
|
||||
this.examplesContext = context;
|
||||
|
||||
}
|
||||
|
||||
_initSearch() {
|
||||
|
||||
const traverseNodeEditors = ( item ) => {
|
||||
|
||||
if ( item.nodeClass ) {
|
||||
|
||||
const button = new ButtonInput( item.name );
|
||||
button.setIcon( `ti ti-${item.icon}` );
|
||||
button.addEventListener( 'complete', () => {
|
||||
|
||||
const node = new item.nodeClass();
|
||||
|
||||
this.add( node );
|
||||
|
||||
this.centralizeNode( node );
|
||||
|
||||
} );
|
||||
|
||||
search.add( button );
|
||||
|
||||
}
|
||||
|
||||
if ( item.children ) {
|
||||
|
||||
for ( const subItem of item.children ) {
|
||||
|
||||
traverseNodeEditors( subItem );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const search = new Search();
|
||||
search.forceAutoComplete = true;
|
||||
|
||||
search.onFilter( () => {
|
||||
|
||||
search.clear();
|
||||
|
||||
for ( const item of NodeList ) {
|
||||
|
||||
traverseNodeEditors( item );
|
||||
|
||||
}
|
||||
|
||||
const object3d = this.scene;
|
||||
|
||||
if ( object3d !== null ) {
|
||||
|
||||
object3d.traverse( ( obj3d ) => {
|
||||
|
||||
if ( obj3d.isMesh === true || obj3d.isPoints === true ) {
|
||||
|
||||
let prefix = null;
|
||||
let icon = null;
|
||||
let editorClass = null;
|
||||
|
||||
if ( obj3d.isMesh === true ) {
|
||||
|
||||
prefix = 'Mesh';
|
||||
icon = 'ti ti-3d-cube-sphere';
|
||||
editorClass = MeshEditor;
|
||||
|
||||
} else if ( obj3d.isPoints === true ) {
|
||||
|
||||
prefix = 'Points';
|
||||
icon = 'ti ti-border-none';
|
||||
editorClass = PointsEditor;
|
||||
|
||||
}
|
||||
|
||||
const button = new ButtonInput( `${prefix} - ${obj3d.name}` );
|
||||
button.setIcon( icon );
|
||||
button.addEventListener( 'complete', () => {
|
||||
|
||||
for ( const node of this.canvas.nodes ) {
|
||||
|
||||
if ( node.value === obj3d ) {
|
||||
|
||||
// prevent duplicated node
|
||||
|
||||
this.canvas.select( node );
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const node = new editorClass( obj3d );
|
||||
|
||||
this.add( node );
|
||||
|
||||
this.centralizeNode( node );
|
||||
|
||||
} );
|
||||
|
||||
search.add( button );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
search.onSubmit( () => {
|
||||
|
||||
if ( search.currentFiltered !== null ) {
|
||||
|
||||
search.currentFiltered.button.dispatchEvent( new Event( 'complete' ) );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
this.domElement.append( search.dom );
|
||||
|
||||
}
|
||||
|
||||
_initNodesContext() {
|
||||
|
||||
const context = new ContextMenu( this.domElement );
|
||||
|
||||
let isContext = false;
|
||||
const contextPosition = {};
|
||||
|
||||
const add = ( node ) => {
|
||||
|
||||
if ( isContext ) {
|
||||
|
||||
node.setPosition(
|
||||
Math.round( contextPosition.x ),
|
||||
Math.round( contextPosition.y )
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
this.centralizeNode( node );
|
||||
|
||||
}
|
||||
|
||||
context.hide();
|
||||
|
||||
this.add( node );
|
||||
|
||||
this.canvas.select( node );
|
||||
|
||||
isContext = false;
|
||||
|
||||
};
|
||||
|
||||
context.onContext( () => {
|
||||
|
||||
isContext = true;
|
||||
|
||||
const { relativeClientX, relativeClientY } = this.canvas;
|
||||
|
||||
contextPosition.x = Math.round( relativeClientX );
|
||||
contextPosition.y = Math.round( relativeClientY );
|
||||
|
||||
} );
|
||||
|
||||
//**************//
|
||||
// INPUTS
|
||||
//**************//
|
||||
|
||||
const createButtonMenu = ( item ) => {
|
||||
|
||||
const button = new ButtonInput( item.name );
|
||||
button.setIcon( `ti ti-${item.icon}` );
|
||||
|
||||
let context = null;
|
||||
|
||||
if ( item.nodeClass ) {
|
||||
|
||||
button.onClick( () => add( new item.nodeClass() ) );
|
||||
|
||||
}
|
||||
|
||||
if ( item.tip ) {
|
||||
|
||||
button.setToolTip( item.tip );
|
||||
|
||||
}
|
||||
|
||||
if ( item.children ) {
|
||||
|
||||
context = new ContextMenu();
|
||||
|
||||
for ( const subItem of item.children ) {
|
||||
|
||||
const buttonMenu = createButtonMenu( subItem );
|
||||
|
||||
context.add( buttonMenu.button, buttonMenu.context );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return { button, context };
|
||||
|
||||
};
|
||||
|
||||
for ( const item of NodeList ) {
|
||||
|
||||
const buttonMenu = createButtonMenu( item );
|
||||
|
||||
context.add( buttonMenu.button, buttonMenu.context );
|
||||
|
||||
}
|
||||
|
||||
this.nodesContext = context;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
30
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/accessors/NormalEditor.js
generated
vendored
Normal file
30
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/accessors/NormalEditor.js
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
import { SelectInput, Element } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { NormalNode } from 'three-nodes/Nodes.js';
|
||||
|
||||
export class NormalEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new NormalNode();
|
||||
|
||||
super( 'Normal', 3, node, 200 );
|
||||
|
||||
const optionsField = new SelectInput( [
|
||||
{ name: 'Local', value: NormalNode.LOCAL },
|
||||
{ name: 'World', value: NormalNode.WORLD },
|
||||
{ name: 'View', value: NormalNode.VIEW },
|
||||
{ name: 'Geometry', value: NormalNode.GEOMETRY }
|
||||
], NormalNode.LOCAL ).onChange( () => {
|
||||
|
||||
node.scope = optionsField.getValue();
|
||||
|
||||
this.invalidate();
|
||||
|
||||
} );
|
||||
|
||||
this.add( new Element().add( optionsField ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
30
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/accessors/PositionEditor.js
generated
vendored
Normal file
30
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/accessors/PositionEditor.js
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
import { SelectInput, Element } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { PositionNode } from 'three-nodes/Nodes.js';
|
||||
|
||||
export class PositionEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new PositionNode();
|
||||
|
||||
super( 'Position', 3, node, 200 );
|
||||
|
||||
const optionsField = new SelectInput( [
|
||||
{ name: 'Local', value: PositionNode.LOCAL },
|
||||
{ name: 'World', value: PositionNode.WORLD },
|
||||
{ name: 'View', value: PositionNode.VIEW },
|
||||
{ name: 'View Direction', value: PositionNode.VIEW_DIRECTION }
|
||||
], PositionNode.LOCAL ).onChange( () => {
|
||||
|
||||
node.scope = optionsField.getValue();
|
||||
|
||||
this.invalidate();
|
||||
|
||||
} );
|
||||
|
||||
this.add( new Element().add( optionsField ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
25
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/accessors/UVEditor.js
generated
vendored
Normal file
25
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/accessors/UVEditor.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
import { SelectInput, LabelElement } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { UVNode } from 'three-nodes/Nodes.js';
|
||||
|
||||
export class UVEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new UVNode();
|
||||
|
||||
super( 'UV', 2, node, 200 );
|
||||
|
||||
const optionsField = new SelectInput( [ '1', '2' ], 0 ).onChange( () => {
|
||||
|
||||
node.index = Number( optionsField.getValue() );
|
||||
|
||||
this.invalidate();
|
||||
|
||||
} );
|
||||
|
||||
this.add( new LabelElement( 'Channel' ).add( optionsField ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
89
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/core/BaseNode.js
generated
vendored
Normal file
89
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/core/BaseNode.js
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
import { ObjectNode } from '../../libs/flow.module.js';
|
||||
|
||||
export const onNodeValidElement = ( inputElement, outputElement ) => {
|
||||
|
||||
const outputObject = outputElement.getObject();
|
||||
|
||||
if ( ! outputObject || ! outputObject.isNode ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export class BaseNode extends ObjectNode {
|
||||
|
||||
constructor( name, inputLength, value = null, width = 300 ) {
|
||||
|
||||
const getObjectCallback = ( /*output = null*/ ) => {
|
||||
|
||||
return this.value;
|
||||
|
||||
};
|
||||
|
||||
super( name, inputLength, getObjectCallback, width );
|
||||
|
||||
this.setOutputColor( this.getColorValueFromValue( value ) );
|
||||
|
||||
this.editor = null;
|
||||
|
||||
this.value = value;
|
||||
|
||||
this.onValidElement = onNodeValidElement;
|
||||
|
||||
}
|
||||
|
||||
serialize( data ) {
|
||||
|
||||
super.serialize( data );
|
||||
|
||||
delete data.width;
|
||||
|
||||
}
|
||||
|
||||
deserialize( data ) {
|
||||
|
||||
delete data.width;
|
||||
|
||||
super.deserialize( data );
|
||||
|
||||
}
|
||||
|
||||
setEditor( value ) {
|
||||
|
||||
this.editor = value;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getColorValueFromValue( value ) {
|
||||
|
||||
if ( ! value ) return;
|
||||
|
||||
if ( value.isMaterial === true ) {
|
||||
|
||||
return 'forestgreen';
|
||||
|
||||
} else if ( value.isObject3D === true ) {
|
||||
|
||||
return 'orange';
|
||||
|
||||
} else if ( value instanceof File ) {
|
||||
|
||||
return 'aqua';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
add( element ) {
|
||||
|
||||
element.onValid( ( source, target ) => this.onValidElement( source, target ) );
|
||||
|
||||
return super.add( element );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
17
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/core/FileEditor.js
generated
vendored
Normal file
17
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/core/FileEditor.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import { StringInput, Element } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
|
||||
export class FileEditor extends BaseNode {
|
||||
|
||||
constructor( file ) {
|
||||
|
||||
super( 'File', 1, file, 250 );
|
||||
|
||||
this.file = file;
|
||||
this.nameInput = new StringInput( file.name ).setReadOnly( true );
|
||||
|
||||
this.add( new Element().add( this.nameInput ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
44
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/display/BlendEditor.js
generated
vendored
Normal file
44
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/display/BlendEditor.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
import { LabelElement } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { MathNode, FloatNode } from 'three-nodes/Nodes.js';
|
||||
|
||||
const NULL_VALUE = new FloatNode();
|
||||
const ONE_VALUE = new FloatNode( 1 );
|
||||
|
||||
export class BlendEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new MathNode( MathNode.MIX, NULL_VALUE, NULL_VALUE, ONE_VALUE );
|
||||
|
||||
super( 'Blend', 3, node, 200 );
|
||||
|
||||
const aElement = new LabelElement( 'Base' ).setInput( 3 );
|
||||
const bElement = new LabelElement( 'Blend' ).setInput( 3 );
|
||||
const cElement = new LabelElement( 'Opacity' ).setInput( 1 );
|
||||
|
||||
aElement.onConnect( () => {
|
||||
|
||||
node.aNode = aElement.getLinkedObject() || NULL_VALUE;
|
||||
|
||||
} );
|
||||
|
||||
bElement.onConnect( () => {
|
||||
|
||||
node.bNode = bElement.getLinkedObject() || NULL_VALUE;
|
||||
|
||||
} );
|
||||
|
||||
cElement.onConnect( () => {
|
||||
|
||||
node.cNode = cElement.getLinkedObject() || ONE_VALUE;
|
||||
|
||||
} );
|
||||
|
||||
this.add( aElement )
|
||||
.add( bElement )
|
||||
.add( cElement );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
49
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/display/NormalMapEditor.js
generated
vendored
Normal file
49
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/display/NormalMapEditor.js
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
import { SelectInput, Element, LabelElement } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { NormalMapNode, FloatNode } from 'three-nodes/Nodes.js';
|
||||
import { TangentSpaceNormalMap, ObjectSpaceNormalMap } from 'three';
|
||||
|
||||
const nullValue = new FloatNode( 0 ).setConst( true );
|
||||
|
||||
export class NormalMapEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new NormalMapNode( nullValue );
|
||||
|
||||
super( 'Normal Map', 3, node, 175 );
|
||||
|
||||
const source = new LabelElement( 'Source' ).setInput( 3 ).onConnect( () => {
|
||||
|
||||
node.node = source.getLinkedObject() || nullValue;
|
||||
|
||||
this.invalidate();
|
||||
|
||||
} );
|
||||
|
||||
const scale = new LabelElement( 'Scale' ).setInput( 3 ).onConnect( () => {
|
||||
|
||||
node.scaleNode = scale.getLinkedObject();
|
||||
|
||||
this.invalidate();
|
||||
|
||||
} );
|
||||
|
||||
const optionsField = new SelectInput( [
|
||||
{ name: 'Tangent Space', value: TangentSpaceNormalMap },
|
||||
{ name: 'Object Space', value: ObjectSpaceNormalMap }
|
||||
], TangentSpaceNormalMap ).onChange( () => {
|
||||
|
||||
node.normalMapType = Number( optionsField.getValue() );
|
||||
|
||||
this.invalidate();
|
||||
|
||||
} );
|
||||
|
||||
this.add( new Element().add( optionsField ) )
|
||||
.add( source )
|
||||
.add( scale );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
1
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/examples/animate-uv.json
generated
vendored
Normal file
1
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/examples/animate-uv.json
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"objects":{"733":{"x":1718,"y":136,"width":300,"elements":[734,736,737,738,739],"id":733,"type":"StandardMaterialEditor"},"734":{"outputLength":1,"style":"blue","title":"Standard Material","id":734,"type":"TitleElement"},"736":{"inputLength":3,"inputs":[740],"links":[809],"label":"Color","id":736,"type":"LabelElement"},"737":{"inputLength":1,"inputs":[741],"label":"Opacity","icon":"ti ti-layers-subtract","id":737,"type":"LabelElement"},"738":{"inputLength":1,"inputs":[743],"label":"Metalness","id":738,"type":"LabelElement"},"739":{"inputLength":1,"inputs":[745],"label":"Roughness","id":739,"type":"LabelElement"},"740":{"value":16777215,"id":740,"type":"ColorInput"},"741":{"min":0,"max":1,"value":1,"id":741,"type":"SliderInput"},"743":{"min":0,"max":1,"value":0,"id":743,"type":"SliderInput"},"745":{"min":0,"max":1,"value":1,"id":745,"type":"SliderInput"},"752":{"x":155,"y":230,"width":250,"elements":[753,759,760,757],"id":752,"type":"TimerEditor"},"753":{"outputLength":1,"title":"Timer","icon":"ti ti-clock","id":753,"type":"TitleElement"},"755":{"value":0.218,"id":755,"type":"NumberInput"},"756":{"value":0.04,"id":756,"type":"NumberInput"},"757":{"inputs":[758],"id":757,"type":"Element"},"758":{"value":"Reset","id":758,"type":"ButtonInput"},"759":{"inputs":[755],"id":759,"type":"Element"},"760":{"inputs":[756],"label":"Scale","id":760,"type":"LabelElement"},"768":{"x":202,"y":79,"width":250,"elements":[769,772],"id":768,"type":"UVEditor"},"769":{"outputLength":2,"style":"red","title":"UV","id":769,"type":"TitleElement"},"771":{"options":["1","2"],"value":"0","id":771,"type":"SelectInput"},"772":{"inputs":[771],"label":"Channel","id":772,"type":"LabelElement"},"776":{"x":612,"y":102,"width":250,"elements":[777,782,780,781],"id":776,"type":"OperatorEditor"},"777":{"outputLength":1,"title":"Operator","id":777,"type":"TitleElement"},"779":{"options":[{"name":"+ Addition","value":"+"},{"name":"- Subtraction","value":"-"},{"name":"* Multiplication","value":"*"},{"name":"/ Division","value":"/"}],"value":"+","id":779,"type":"SelectInput"},"780":{"inputLength":3,"links":[769],"label":"A","id":780,"type":"LabelElement"},"781":{"inputLength":3,"links":[753],"label":"B","id":781,"type":"LabelElement"},"782":{"inputs":[779],"id":782,"type":"Element"},"788":{"x":1047,"y":158,"width":250,"elements":[789,794,792,793],"id":788,"type":"OperatorEditor"},"789":{"outputLength":1,"title":"Operator","id":789,"type":"TitleElement"},"791":{"options":[{"name":"+ Addition","value":"+"},{"name":"- Subtraction","value":"-"},{"name":"* Multiplication","value":"*"},{"name":"/ Division","value":"/"}],"value":"*","id":791,"type":"SelectInput"},"792":{"inputLength":3,"links":[777],"label":"A","id":792,"type":"LabelElement"},"793":{"inputLength":3,"links":[801],"label":"B","id":793,"type":"LabelElement"},"794":{"inputs":[791],"id":794,"type":"Element"},"800":{"x":601,"y":345,"width":250,"elements":[801,804],"id":800,"type":"FloatEditor"},"801":{"outputLength":1,"title":"Float","icon":"ti ti-box-multiple-1","id":801,"type":"TitleElement"},"803":{"value":24.12,"id":803,"type":"NumberInput"},"804":{"inputs":[803],"id":804,"type":"Element"},"808":{"x":1402,"y":14,"width":200,"elements":[809,811],"id":808,"type":"CheckerEditor"},"809":{"outputLength":1,"title":"Checker","id":809,"type":"TitleElement"},"811":{"inputLength":2,"links":[789],"label":"UV","id":811,"type":"LabelElement"},"837":{"x":2160,"y":128,"width":300,"elements":[838,841,851,852,853,854],"id":837,"type":"MeshEditor"},"838":{"outputLength":1,"title":"Mesh","id":838,"type":"TitleElement"},"840":{"value":"Stanford_Bunny","id":840,"type":"StringInput"},"841":{"inputs":[840],"label":"Name","id":841,"type":"LabelElement"},"842":{"value":0,"id":842,"type":"NumberInput"},"843":{"value":0,"id":843,"type":"NumberInput"},"844":{"value":10,"id":844,"type":"NumberInput"},"845":{"value":0,"id":845,"type":"NumberInput"},"846":{"value":0,"id":846,"type":"NumberInput"},"847":{"value":0,"id":847,"type":"NumberInput"},"848":{"value":100,"id":848,"type":"NumberInput"},"849":{"value":100,"id":849,"type":"NumberInput"},"850":{"value":100,"id":850,"type":"NumberInput"},"851":{"inputs":[842,843,844],"label":"Position","id":851,"type":"LabelElement"},"852":{"inputs":[845,846,847],"label":"Rotation","id":852,"type":"LabelElement"},"853":{"inputs":[848,849,850],"label":"Scale","id":853,"type":"LabelElement"},"854":{"inputLength":1,"links":[734],"label":"Material","id":854,"type":"LabelElement"}},"nodes":[733,752,768,776,788,800,808,837],"id":2,"type":"Canvas"}
|
||||
1
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/examples/fake-top-light.json
generated
vendored
Normal file
1
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/examples/fake-top-light.json
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"objects":{"389":{"x":885,"y":119,"width":300,"elements":[390,392,393,394,395],"id":389,"type":"StandardMaterialEditor"},"390":{"outputLength":1,"style":"blue","title":"Standard Material","id":390,"type":"TitleElement"},"392":{"inputLength":3,"inputs":[396],"links":[421],"label":"Color","id":392,"type":"LabelElement"},"393":{"inputLength":1,"inputs":[397],"label":"Opacity","icon":"ti ti-layers-subtract","id":393,"type":"LabelElement"},"394":{"inputLength":1,"inputs":[399],"label":"Metalness","id":394,"type":"LabelElement"},"395":{"inputLength":1,"inputs":[401],"label":"Roughness","id":395,"type":"LabelElement"},"396":{"value":16777215,"id":396,"type":"ColorInput"},"397":{"min":0,"max":1,"value":1,"id":397,"type":"SliderInput"},"399":{"min":0,"max":1,"value":0,"id":399,"type":"SliderInput"},"401":{"min":0,"max":1,"value":1,"id":401,"type":"SliderInput"},"408":{"x":73,"y":296,"width":325,"elements":[409,414],"id":408,"type":"Vector3Editor"},"409":{"outputLength":3,"title":"Vector 3","icon":"ti ti-box-multiple-3","id":409,"type":"TitleElement"},"411":{"value":0,"id":411,"type":"NumberInput"},"412":{"value":1,"id":412,"type":"NumberInput"},"413":{"value":0,"id":413,"type":"NumberInput"},"414":{"inputs":[411,412,413],"label":"Values","id":414,"type":"LabelElement"},"420":{"x":541,"y":199,"width":200,"elements":[421,423,424],"id":420,"type":"DotEditor"},"421":{"outputLength":1,"title":"Dot Product","id":421,"type":"TitleElement"},"423":{"inputLength":3,"links":[429],"label":"A","id":423,"type":"LabelElement"},"424":{"inputLength":3,"links":[409],"label":"B","id":424,"type":"LabelElement"},"428":{"x":106,"y":158,"width":250,"elements":[429,432],"id":428,"type":"NormalEditor"},"429":{"outputLength":3,"style":"red","title":"Normal","id":429,"type":"TitleElement"},"431":{"options":[{"name":"Local","value":"local"},{"name":"World","value":"world"},{"name":"View","value":"view"}],"value":"world","id":431,"type":"SelectInput"},"432":{"inputs":[431],"id":432,"type":"Element"},"473":{"x":1314,"y":113,"width":300,"elements":[474,477,487,488,489,490],"id":473,"type":"MeshEditor"},"474":{"outputLength":1,"title":"Mesh","id":474,"type":"TitleElement"},"476":{"value":"Stanford_Bunny","id":476,"type":"StringInput"},"477":{"inputs":[476],"label":"Name","id":477,"type":"LabelElement"},"478":{"value":0,"id":478,"type":"NumberInput"},"479":{"value":0,"id":479,"type":"NumberInput"},"480":{"value":10,"id":480,"type":"NumberInput"},"481":{"value":0,"id":481,"type":"NumberInput"},"482":{"value":0,"id":482,"type":"NumberInput"},"483":{"value":0,"id":483,"type":"NumberInput"},"484":{"value":100,"id":484,"type":"NumberInput"},"485":{"value":100,"id":485,"type":"NumberInput"},"486":{"value":100,"id":486,"type":"NumberInput"},"487":{"inputs":[478,479,480],"label":"Position","id":487,"type":"LabelElement"},"488":{"inputs":[481,482,483],"label":"Rotation","id":488,"type":"LabelElement"},"489":{"inputs":[484,485,486],"label":"Scale","id":489,"type":"LabelElement"},"490":{"inputLength":1,"links":[390],"label":"Material","id":490,"type":"LabelElement"}},"nodes":[389,408,420,428,473],"id":2,"type":"Canvas"}
|
||||
1
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/examples/oscillator-color.json
generated
vendored
Normal file
1
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/examples/oscillator-color.json
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"objects":{"247":{"x":1602,"y":-3,"width":300,"elements":[248,250,251,252,253],"id":247,"type":"StandardMaterialEditor"},"248":{"outputLength":1,"style":"blue","title":"Standard Material","id":248,"type":"TitleElement"},"250":{"inputLength":3,"inputs":[254],"links":[293],"label":"Color","id":250,"type":"LabelElement"},"251":{"inputLength":1,"inputs":[255],"label":"Opacity","icon":"ti ti-layers-subtract","id":251,"type":"LabelElement"},"252":{"inputLength":1,"inputs":[257],"label":"Metalness","id":252,"type":"LabelElement"},"253":{"inputLength":1,"inputs":[259],"label":"Roughness","id":253,"type":"LabelElement"},"254":{"value":16777215,"id":254,"type":"ColorInput"},"255":{"min":0,"max":1,"value":1,"id":255,"type":"SliderInput"},"257":{"min":0,"max":1,"value":0,"id":257,"type":"SliderInput"},"259":{"min":0,"max":1,"value":1,"id":259,"type":"SliderInput"},"266":{"x":123,"y":207,"width":250,"elements":[267,273,274,271],"id":266,"type":"TimerEditor"},"267":{"outputLength":1,"title":"Timer","icon":"ti ti-clock","id":267,"type":"TitleElement"},"269":{"value":1.985,"id":269,"type":"NumberInput"},"270":{"value":0.37,"id":270,"type":"NumberInput"},"271":{"inputs":[272],"id":271,"type":"Element"},"272":{"value":"Reset","id":272,"type":"ButtonInput"},"273":{"inputs":[269],"id":273,"type":"Element"},"274":{"inputs":[270],"label":"Scale","id":274,"type":"LabelElement"},"282":{"x":485,"y":94,"width":250,"elements":[283,287,286],"id":282,"type":"OscillatorEditor"},"283":{"outputLength":1,"title":"Oscillator","id":283,"type":"TitleElement"},"285":{"options":[{"name":"Sine","value":"sine"},{"name":"Square","value":"square"},{"name":"Triangle","value":"triangle"},{"name":"Sawtooth","value":"sawtooth"}],"value":"sine","id":285,"type":"SelectInput"},"286":{"inputLength":1,"links":[267],"label":"Time","id":286,"type":"LabelElement"},"287":{"inputs":[285],"id":287,"type":"Element"},"292":{"x":1208,"y":66,"width":200,"elements":[293,295,296,297],"id":292,"type":"BlendEditor"},"293":{"outputLength":3,"title":"Blend","id":293,"type":"TitleElement"},"295":{"inputLength":3,"links":[303],"label":"Base","id":295,"type":"LabelElement"},"296":{"inputLength":3,"links":[323],"label":"Blend","id":296,"type":"LabelElement"},"297":{"inputLength":1,"links":[283],"label":"Opacity","id":297,"type":"LabelElement"},"302":{"x":797,"y":-55,"width":300,"elements":[303,310,311,312],"id":302,"type":"ColorEditor"},"303":{"outputLength":1,"title":"Color","icon":"ti ti-palette","id":303,"type":"TitleElement"},"305":{"value":16580865,"id":305,"type":"ColorInput"},"306":{"value":"#FD0101","id":306,"type":"StringInput"},"307":{"min":0,"max":1,"step":0.01,"value":0.996,"id":307,"type":"NumberInput"},"308":{"min":0,"max":1,"step":0.01,"value":0.004,"id":308,"type":"NumberInput"},"309":{"min":0,"max":1,"step":0.01,"value":0.004,"id":309,"type":"NumberInput"},"310":{"inputs":[305],"id":310,"type":"Element"},"311":{"inputs":[306],"label":"Hex","id":311,"type":"LabelElement"},"312":{"inputs":[307,308,309],"label":"RGB","id":312,"type":"LabelElement"},"322":{"x":810,"y":220,"width":300,"elements":[323,330,331,332],"id":322,"type":"ColorEditor"},"323":{"outputLength":1,"title":"Color","icon":"ti ti-palette","id":323,"type":"TitleElement"},"325":{"value":19455,"id":325,"type":"ColorInput"},"326":{"value":"#004BFF","id":326,"type":"StringInput"},"327":{"min":0,"max":1,"step":0.01,"value":0,"id":327,"type":"NumberInput"},"328":{"min":0,"max":1,"step":0.01,"value":0.298,"id":328,"type":"NumberInput"},"329":{"min":0,"max":1,"step":0.01,"value":1,"id":329,"type":"NumberInput"},"330":{"inputs":[325],"id":330,"type":"Element"},"331":{"inputs":[326],"label":"Hex","id":331,"type":"LabelElement"},"332":{"inputs":[327,328,329],"label":"RGB","id":332,"type":"LabelElement"},"371":{"x":2064,"y":-17,"width":300,"elements":[372,375,385,386,387,388],"id":371,"type":"MeshEditor"},"372":{"outputLength":1,"title":"Mesh","id":372,"type":"TitleElement"},"374":{"value":"Stanford_Bunny","id":374,"type":"StringInput"},"375":{"inputs":[374],"label":"Name","id":375,"type":"LabelElement"},"376":{"value":0,"id":376,"type":"NumberInput"},"377":{"value":0,"id":377,"type":"NumberInput"},"378":{"value":10,"id":378,"type":"NumberInput"},"379":{"value":0,"id":379,"type":"NumberInput"},"380":{"value":0,"id":380,"type":"NumberInput"},"381":{"value":0,"id":381,"type":"NumberInput"},"382":{"value":100,"id":382,"type":"NumberInput"},"383":{"value":100,"id":383,"type":"NumberInput"},"384":{"value":100,"id":384,"type":"NumberInput"},"385":{"inputs":[376,377,378],"label":"Position","id":385,"type":"LabelElement"},"386":{"inputs":[379,380,381],"label":"Rotation","id":386,"type":"LabelElement"},"387":{"inputs":[382,383,384],"label":"Scale","id":387,"type":"LabelElement"},"388":{"inputLength":1,"links":[248],"label":"Material","id":388,"type":"LabelElement"}},"nodes":[247,266,282,292,302,322,371],"id":2,"type":"Canvas"}
|
||||
1
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/examples/rim.json
generated
vendored
Normal file
1
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/examples/rim.json
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
95
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/inputs/ColorEditor.js
generated
vendored
Normal file
95
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/inputs/ColorEditor.js
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
import { ColorInput, StringInput, NumberInput, LabelElement, Element } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { ColorNode } from 'three-nodes/Nodes.js';
|
||||
|
||||
export class ColorEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new ColorNode();
|
||||
|
||||
super( 'Color', 3, node );
|
||||
|
||||
const updateFields = ( editing ) => {
|
||||
|
||||
const value = node.value;
|
||||
const hexValue = value.getHex();
|
||||
const hexString = hexValue.toString( 16 ).toUpperCase().padStart( 6, '0' );
|
||||
|
||||
if ( editing !== 'color' ) {
|
||||
|
||||
field.setValue( hexValue, false );
|
||||
|
||||
}
|
||||
|
||||
if ( editing !== 'hex' ) {
|
||||
|
||||
hexField.setValue( '#' + hexString, false );
|
||||
|
||||
}
|
||||
|
||||
if ( editing !== 'rgb' ) {
|
||||
|
||||
fieldR.setValue( value.r.toFixed( 3 ), false );
|
||||
fieldG.setValue( value.g.toFixed( 3 ), false );
|
||||
fieldB.setValue( value.b.toFixed( 3 ), false );
|
||||
|
||||
}
|
||||
|
||||
fieldR.setTagColor( `#${hexString.slice( 0, 2 )}0000` );
|
||||
fieldG.setTagColor( `#00${hexString.slice( 2, 4 )}00` );
|
||||
fieldB.setTagColor( `#0000${hexString.slice( 4, 6 )}` );
|
||||
|
||||
};
|
||||
|
||||
const field = new ColorInput( 0xFFFFFF ).onChange( () => {
|
||||
|
||||
node.value.setHex( field.getValue() );
|
||||
|
||||
updateFields( 'picker' );
|
||||
|
||||
} );
|
||||
|
||||
const hexField = new StringInput().onChange( () => {
|
||||
|
||||
const value = hexField.getValue();
|
||||
|
||||
if ( value.indexOf( '#' ) === 0 ) {
|
||||
|
||||
const hexStr = value.slice( 1 ).padEnd( 6, '0' );
|
||||
|
||||
node.value.setHex( parseInt( hexStr, 16 ) );
|
||||
|
||||
updateFields( 'hex' );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
hexField.addEventListener( 'blur', () => {
|
||||
|
||||
updateFields();
|
||||
|
||||
} );
|
||||
|
||||
const onChangeRGB = () => {
|
||||
|
||||
node.value.setRGB( fieldR.getValue(), fieldG.getValue(), fieldB.getValue() );
|
||||
|
||||
updateFields( 'rgb' );
|
||||
|
||||
};
|
||||
|
||||
const fieldR = new NumberInput( 1, 0, 1 ).setTagColor( 'red' ).onChange( onChangeRGB );
|
||||
const fieldG = new NumberInput( 1, 0, 1 ).setTagColor( 'green' ).onChange( onChangeRGB );
|
||||
const fieldB = new NumberInput( 1, 0, 1 ).setTagColor( 'blue' ).onChange( onChangeRGB );
|
||||
|
||||
this.add( new Element().add( field ).setSerializable( false ) )
|
||||
.add( new LabelElement( 'Hex' ).add( hexField ).setSerializable( false ) )
|
||||
.add( new LabelElement( 'RGB' ).add( fieldR ).add( fieldG ).add( fieldB ) );
|
||||
|
||||
updateFields();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
23
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/inputs/FloatEditor.js
generated
vendored
Normal file
23
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/inputs/FloatEditor.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import { NumberInput, Element } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { FloatNode } from 'three-nodes/Nodes.js';
|
||||
|
||||
export class FloatEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new FloatNode();
|
||||
|
||||
super( 'Float', 1, node, 150 );
|
||||
|
||||
const field = new NumberInput().setTagColor( 'red' ).onChange( () => {
|
||||
|
||||
node.value = field.getValue();
|
||||
|
||||
} );
|
||||
|
||||
this.add( new Element().add( field ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
67
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/inputs/SliderEditor.js
generated
vendored
Normal file
67
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/inputs/SliderEditor.js
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
import { ButtonInput, SliderInput, NumberInput, LabelElement, Element } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { FloatNode } from 'three-nodes/Nodes.js';
|
||||
|
||||
export class SliderEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new FloatNode();
|
||||
|
||||
super( 'Slider', 1, node );
|
||||
|
||||
this.collapse = true;
|
||||
|
||||
const field = new SliderInput( 0, 0, 1 ).onChange( () => {
|
||||
|
||||
node.value = field.getValue();
|
||||
|
||||
} );
|
||||
|
||||
const updateRange = () => {
|
||||
|
||||
const min = minInput.getValue();
|
||||
const max = maxInput.getValue();
|
||||
|
||||
if ( min <= max ) {
|
||||
|
||||
field.setRange( min, max );
|
||||
|
||||
} else {
|
||||
|
||||
maxInput.setValue( min );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const minInput = new NumberInput().onChange( updateRange );
|
||||
const maxInput = new NumberInput( 1 ).onChange( updateRange );
|
||||
|
||||
const minElement = new LabelElement( 'Min.' ).add( minInput ).setVisible( false );
|
||||
const maxElement = new LabelElement( 'Max.' ).add( maxInput ).setVisible( false );
|
||||
|
||||
const moreElement = new Element().add( new ButtonInput( 'More' ).onClick( () => {
|
||||
|
||||
minElement.setVisible( true );
|
||||
maxElement.setVisible( true );
|
||||
moreElement.setVisible( false );
|
||||
|
||||
} ) ).setSerializable( false );
|
||||
|
||||
this.add( new Element().add( field ) )
|
||||
.add( minElement )
|
||||
.add( maxElement )
|
||||
.add( moreElement );
|
||||
|
||||
this.onBlur( () => {
|
||||
|
||||
minElement.setVisible( false );
|
||||
maxElement.setVisible( false );
|
||||
moreElement.setVisible( true );
|
||||
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
145
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/inputs/TextureEditor.js
generated
vendored
Normal file
145
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/inputs/TextureEditor.js
generated
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
import { LabelElement, ToggleInput, SelectInput } from '../../libs/flow.module.js';
|
||||
import { BaseNode, onNodeValidElement } from '../core/BaseNode.js';
|
||||
import { TextureNode, UVNode } from 'three-nodes/Nodes.js';
|
||||
import { Texture, TextureLoader, RepeatWrapping, ClampToEdgeWrapping, MirroredRepeatWrapping } from 'three';
|
||||
|
||||
const fileTexture = new WeakMap();
|
||||
const textureLoader = new TextureLoader();
|
||||
const defaultTexture = new Texture();
|
||||
const defaultUV = new UVNode();
|
||||
|
||||
const getTextureFromFile = ( file ) => {
|
||||
|
||||
let texture = fileTexture.get( file );
|
||||
|
||||
if ( texture === undefined ) {
|
||||
|
||||
texture = textureLoader.load( URL.createObjectURL( file ) );
|
||||
|
||||
fileTexture.set( file, texture );
|
||||
|
||||
}
|
||||
|
||||
return texture;
|
||||
|
||||
};
|
||||
|
||||
export class TextureEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new TextureNode( defaultTexture );
|
||||
|
||||
super( 'Texture', 4, node, 250 );
|
||||
|
||||
this.texture = null;
|
||||
|
||||
this._initFile();
|
||||
this._initParams();
|
||||
|
||||
this.onValidElement = () => {};
|
||||
|
||||
}
|
||||
|
||||
_initFile() {
|
||||
|
||||
const fileElement = new LabelElement( 'File' ).setInputColor( 'aqua' ).setInput( 1 );
|
||||
|
||||
fileElement.onValid( ( source, target, stage ) => {
|
||||
|
||||
const object = target.getObject();
|
||||
|
||||
if ( object && ( object instanceof File ) === false ) {
|
||||
|
||||
if ( stage === 'dragged' ) {
|
||||
|
||||
const name = target.node.getName();
|
||||
|
||||
this.editor.tips.error( `"${name}" is not a File.` );
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
} ).onConnect( () => {
|
||||
|
||||
const file = fileElement.getLinkedObject();
|
||||
const node = this.value;
|
||||
|
||||
this.texture = file ? getTextureFromFile( file ) : null;
|
||||
|
||||
node.value = this.texture || defaultTexture;
|
||||
|
||||
this.update();
|
||||
|
||||
} );
|
||||
|
||||
this.add( fileElement );
|
||||
|
||||
}
|
||||
|
||||
_initParams() {
|
||||
|
||||
const uvField = new LabelElement( 'UV' ).setInput( 2 );
|
||||
|
||||
uvField.onValid( onNodeValidElement ).onConnect( () => {
|
||||
|
||||
const node = this.value;
|
||||
|
||||
node.uvNode = uvField.getLinkedObject() || defaultUV;
|
||||
|
||||
} );
|
||||
|
||||
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 ).onClick( () => {
|
||||
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
27
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/inputs/Vector2Editor.js
generated
vendored
Normal file
27
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/inputs/Vector2Editor.js
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
import { NumberInput, LabelElement } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { Vector2Node } from 'three-nodes/Nodes.js';
|
||||
|
||||
export class Vector2Editor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new Vector2Node();
|
||||
|
||||
super( 'Vector 2', 2, node );
|
||||
|
||||
const onUpdate = () => {
|
||||
|
||||
node.value.x = fieldX.getValue();
|
||||
node.value.y = fieldY.getValue();
|
||||
|
||||
};
|
||||
|
||||
const fieldX = new NumberInput().setTagColor( 'red' ).onChange( onUpdate );
|
||||
const fieldY = new NumberInput().setTagColor( 'green' ).onChange( onUpdate );
|
||||
|
||||
this.add( new LabelElement( 'XY' ).add( fieldX ).add( fieldY ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
29
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/inputs/Vector3Editor.js
generated
vendored
Normal file
29
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/inputs/Vector3Editor.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
import { NumberInput, LabelElement } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { Vector3Node } from 'three-nodes/Nodes.js';
|
||||
|
||||
export class Vector3Editor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new Vector3Node();
|
||||
|
||||
super( 'Vector 3', 3, node, 325 );
|
||||
|
||||
const onUpdate = () => {
|
||||
|
||||
node.value.x = fieldX.getValue();
|
||||
node.value.y = fieldY.getValue();
|
||||
node.value.z = fieldZ.getValue();
|
||||
|
||||
};
|
||||
|
||||
const fieldX = new NumberInput().setTagColor( 'red' ).onChange( onUpdate );
|
||||
const fieldY = new NumberInput().setTagColor( 'green' ).onChange( onUpdate );
|
||||
const fieldZ = new NumberInput().setTagColor( 'blue' ).onChange( onUpdate );
|
||||
|
||||
this.add( new LabelElement( 'XYZ' ).add( fieldX ).add( fieldY ).add( fieldZ ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
36
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/inputs/Vector4Editor.js
generated
vendored
Normal file
36
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/inputs/Vector4Editor.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
import { NumberInput, LabelElement } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { Vector4Node } from 'three-nodes/Nodes.js';
|
||||
|
||||
export class Vector4Editor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new Vector4Node();
|
||||
|
||||
super( 'Vector 4', 4, node, 350 );
|
||||
|
||||
const onUpdate = () => {
|
||||
|
||||
node.value.x = fieldX.getValue();
|
||||
node.value.y = fieldY.getValue();
|
||||
node.value.z = fieldZ.getValue();
|
||||
node.value.w = fieldW.getValue();
|
||||
|
||||
};
|
||||
|
||||
const fieldX = new NumberInput().setTagColor( 'red' ).onChange( onUpdate );
|
||||
const fieldY = new NumberInput().setTagColor( 'green' ).onChange( onUpdate );
|
||||
const fieldZ = new NumberInput().setTagColor( 'blue' ).onChange( onUpdate );
|
||||
const fieldW = new NumberInput( 1 ).setTagColor( 'white' ).onChange( onUpdate );
|
||||
|
||||
this.add( new LabelElement( 'XYZW' )
|
||||
.add( fieldX )
|
||||
.add( fieldY )
|
||||
.add( fieldZ )
|
||||
.add( fieldW )
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
87
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/materials/BasicMaterialEditor.js
generated
vendored
Normal file
87
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/materials/BasicMaterialEditor.js
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
import { ColorInput, SliderInput, LabelElement } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { MeshBasicNodeMaterial } from 'three-nodes/Nodes.js';
|
||||
import { MathUtils } from 'three';
|
||||
|
||||
export class BasicMaterialEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const material = new MeshBasicNodeMaterial();
|
||||
|
||||
super( 'Basic Material', 1, material );
|
||||
|
||||
this.setWidth( 300 );
|
||||
|
||||
const color = new LabelElement( 'color' ).setInput( 3 );
|
||||
const opacity = new LabelElement( 'opacity' ).setInput( 1 );
|
||||
const position = new LabelElement( 'position' ).setInput( 3 );
|
||||
|
||||
color.add( new ColorInput( material.color.getHex() ).onChange( ( input ) => {
|
||||
|
||||
material.color.setHex( input.getValue() );
|
||||
|
||||
} ) );
|
||||
|
||||
opacity.add( new SliderInput( material.opacity, 0, 1 ).onChange( ( input ) => {
|
||||
|
||||
material.opacity = input.getValue();
|
||||
|
||||
this.updateTransparent();
|
||||
|
||||
} ) );
|
||||
|
||||
color.onConnect( () => this.update(), true );
|
||||
opacity.onConnect( () => this.update(), true );
|
||||
position.onConnect( () => this.update(), true );
|
||||
|
||||
this.add( color )
|
||||
.add( opacity )
|
||||
.add( position );
|
||||
|
||||
this.color = color;
|
||||
this.opacity = opacity;
|
||||
this.position = position;
|
||||
|
||||
this.material = material;
|
||||
|
||||
this.update();
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
const { material, color, opacity, position } = this;
|
||||
|
||||
color.setEnabledInputs( ! color.getLinkedObject() );
|
||||
opacity.setEnabledInputs( ! opacity.getLinkedObject() );
|
||||
|
||||
material.colorNode = color.getLinkedObject();
|
||||
material.opacityNode = opacity.getLinkedObject() || null;
|
||||
|
||||
material.positionNode = position.getLinkedObject() || null;
|
||||
|
||||
material.dispose();
|
||||
|
||||
this.updateTransparent();
|
||||
|
||||
// TODO: Fix on NodeMaterial System
|
||||
material.customProgramCacheKey = () => {
|
||||
|
||||
return MathUtils.generateUUID();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
updateTransparent() {
|
||||
|
||||
const { material, opacity } = this;
|
||||
|
||||
material.transparent = opacity.getLinkedObject() || material.opacity < 1 ? true : false;
|
||||
|
||||
opacity.setIcon( material.transparent ? 'ti ti-layers-intersect' : 'ti ti-layers-subtract' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
102
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/materials/PointsMaterialEditor.js
generated
vendored
Normal file
102
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/materials/PointsMaterialEditor.js
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
import { ColorInput, ToggleInput, SliderInput, LabelElement } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { PointsNodeMaterial } from 'three-nodes/Nodes.js';
|
||||
import * as THREE from 'three';
|
||||
|
||||
export class PointsMaterialEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const material = new PointsNodeMaterial();
|
||||
|
||||
super( 'Points Material', 1, material );
|
||||
|
||||
this.setWidth( 300 );
|
||||
|
||||
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' );
|
||||
|
||||
color.add( new ColorInput( material.color.getHex() ).onChange( ( input ) => {
|
||||
|
||||
material.color.setHex( input.getValue() );
|
||||
|
||||
} ) );
|
||||
|
||||
opacity.add( new SliderInput( material.opacity, 0, 1 ).onChange( ( input ) => {
|
||||
|
||||
material.opacity = input.getValue();
|
||||
|
||||
this.updateTransparent();
|
||||
|
||||
} ) );
|
||||
|
||||
sizeAttenuation.add( new ToggleInput( material.sizeAttenuation ).onClick( ( input ) => {
|
||||
|
||||
material.sizeAttenuation = input.getValue();
|
||||
material.dispose();
|
||||
|
||||
} ) );
|
||||
|
||||
color.onConnect( () => this.update(), true );
|
||||
opacity.onConnect( () => this.update(), true );
|
||||
size.onConnect( () => this.update(), true );
|
||||
position.onConnect( () => this.update(), true );
|
||||
|
||||
this.add( color )
|
||||
.add( opacity )
|
||||
.add( size )
|
||||
.add( position )
|
||||
.add( sizeAttenuation );
|
||||
|
||||
this.color = color;
|
||||
this.opacity = opacity;
|
||||
this.size = size;
|
||||
this.position = position;
|
||||
this.sizeAttenuation = sizeAttenuation;
|
||||
|
||||
this.material = material;
|
||||
|
||||
this.update();
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
const { material, color, opacity, size, position } = this;
|
||||
|
||||
color.setEnabledInputs( ! color.getLinkedObject() );
|
||||
opacity.setEnabledInputs( ! opacity.getLinkedObject() );
|
||||
|
||||
material.colorNode = color.getLinkedObject();
|
||||
material.opacityNode = opacity.getLinkedObject() || null;
|
||||
|
||||
material.sizeNode = size.getLinkedObject() || null;
|
||||
material.positionNode = position.getLinkedObject() || null;
|
||||
|
||||
material.dispose();
|
||||
|
||||
this.updateTransparent();
|
||||
|
||||
// TODO: Fix on NodeMaterial System
|
||||
material.customProgramCacheKey = () => {
|
||||
|
||||
return THREE.MathUtils.generateUUID();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
updateTransparent() {
|
||||
|
||||
const { material, opacity } = this;
|
||||
|
||||
material.transparent = opacity.getLinkedObject() || material.opacity < 1 ? true : false;
|
||||
|
||||
opacity.setIcon( material.transparent ? 'ti ti-layers-intersect' : 'ti ti-layers-subtract' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
121
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/materials/StandardMaterialEditor.js
generated
vendored
Normal file
121
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/materials/StandardMaterialEditor.js
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
import { ColorInput, SliderInput, LabelElement } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { MeshStandardNodeMaterial } from 'three-nodes/Nodes.js';
|
||||
import * as THREE from 'three';
|
||||
|
||||
export class StandardMaterialEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const material = new MeshStandardNodeMaterial();
|
||||
|
||||
super( 'Standard Material', 1, material );
|
||||
|
||||
this.setWidth( 300 );
|
||||
|
||||
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 );
|
||||
|
||||
color.add( new ColorInput( material.color.getHex() ).onChange( ( input ) => {
|
||||
|
||||
material.color.setHex( input.getValue() );
|
||||
|
||||
} ) );
|
||||
|
||||
opacity.add( new SliderInput( material.opacity, 0, 1 ).onChange( ( input ) => {
|
||||
|
||||
material.opacity = input.getValue();
|
||||
|
||||
this.updateTransparent();
|
||||
|
||||
} ) );
|
||||
|
||||
metalness.add( new SliderInput( material.metalness, 0, 1 ).onChange( ( input ) => {
|
||||
|
||||
material.metalness = input.getValue();
|
||||
|
||||
} ) );
|
||||
|
||||
roughness.add( new SliderInput( material.roughness, 0, 1 ).onChange( ( input ) => {
|
||||
|
||||
material.roughness = input.getValue();
|
||||
|
||||
} ) );
|
||||
|
||||
color.onConnect( () => this.update(), true );
|
||||
opacity.onConnect( () => this.update(), true );
|
||||
metalness.onConnect( () => this.update(), true );
|
||||
roughness.onConnect( () => this.update(), true );
|
||||
emissive.onConnect( () => this.update(), true );
|
||||
normal.onConnect( () => this.update(), true );
|
||||
position.onConnect( () => this.update(), true );
|
||||
|
||||
this.add( color )
|
||||
.add( opacity )
|
||||
.add( metalness )
|
||||
.add( roughness )
|
||||
.add( emissive )
|
||||
.add( normal )
|
||||
.add( position );
|
||||
|
||||
this.color = color;
|
||||
this.opacity = opacity;
|
||||
this.metalness = metalness;
|
||||
this.roughness = roughness;
|
||||
this.emissive = emissive;
|
||||
this.normal = normal;
|
||||
this.position = position;
|
||||
|
||||
this.material = material;
|
||||
|
||||
this.update();
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
const { material, color, opacity, emissive, roughness, metalness, normal, position } = this;
|
||||
|
||||
color.setEnabledInputs( ! color.getLinkedObject() );
|
||||
opacity.setEnabledInputs( ! opacity.getLinkedObject() );
|
||||
roughness.setEnabledInputs( ! roughness.getLinkedObject() );
|
||||
metalness.setEnabledInputs( ! metalness.getLinkedObject() );
|
||||
|
||||
material.colorNode = color.getLinkedObject();
|
||||
material.opacityNode = opacity.getLinkedObject();
|
||||
material.metalnessNode = metalness.getLinkedObject();
|
||||
material.roughnessNode = roughness.getLinkedObject();
|
||||
material.emissiveNode = emissive.getLinkedObject();
|
||||
material.normalNode = normal.getLinkedObject();
|
||||
|
||||
material.positionNode = position.getLinkedObject();
|
||||
|
||||
material.dispose();
|
||||
|
||||
this.updateTransparent();
|
||||
|
||||
// TODO: Fix on NodeMaterial System
|
||||
material.customProgramCacheKey = () => {
|
||||
|
||||
return THREE.MathUtils.generateUUID();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
updateTransparent() {
|
||||
|
||||
const { material, opacity } = this;
|
||||
|
||||
material.transparent = opacity.getLinkedObject() || material.opacity < 1 ? true : false;
|
||||
|
||||
opacity.setIcon( material.transparent ? 'ti ti-layers-intersect' : 'ti ti-layers-subtract' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
39
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/math/AngleEditor.js
generated
vendored
Normal file
39
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/math/AngleEditor.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
import { SelectInput, Element, LabelElement } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { MathNode, Vector3Node } from 'three-nodes/Nodes.js';
|
||||
|
||||
const DEFAULT_VALUE = new Vector3Node();
|
||||
|
||||
export class AngleEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new MathNode( MathNode.SIN, DEFAULT_VALUE );
|
||||
|
||||
super( 'Angle', 1, node, 175 );
|
||||
|
||||
const optionsField = new SelectInput( [
|
||||
{ name: 'Degrees to Radians', value: MathNode.RAD },
|
||||
{ name: 'Radians to Degrees', value: MathNode.DEG }
|
||||
], MathNode.RAD ).onChange( () => {
|
||||
|
||||
node.method = optionsField.getValue();
|
||||
|
||||
this.invalidate();
|
||||
|
||||
} );
|
||||
|
||||
const input = new LabelElement( 'A' ).setInput( 1 );
|
||||
|
||||
input.onConnect( () => {
|
||||
|
||||
node.aNode = input.getLinkedObject() || DEFAULT_VALUE;
|
||||
|
||||
} );
|
||||
|
||||
this.add( new Element().add( optionsField ) )
|
||||
.add( input );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
35
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/math/DotEditor.js
generated
vendored
Normal file
35
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/math/DotEditor.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
import { LabelElement } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { MathNode, FloatNode } from 'three-nodes/Nodes.js';
|
||||
|
||||
const NULL_VALUE = new FloatNode();
|
||||
|
||||
export class DotEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new MathNode( MathNode.DOT, NULL_VALUE, NULL_VALUE );
|
||||
|
||||
super( 'Dot Product', 1, node, 175 );
|
||||
|
||||
const aElement = new LabelElement( 'A' ).setInput( 3 );
|
||||
const bElement = new LabelElement( 'B' ).setInput( 3 );
|
||||
|
||||
aElement.onConnect( () => {
|
||||
|
||||
node.aNode = aElement.getLinkedObject() || NULL_VALUE;
|
||||
|
||||
} );
|
||||
|
||||
bElement.onConnect( () => {
|
||||
|
||||
node.bNode = bElement.getLinkedObject() || NULL_VALUE;
|
||||
|
||||
} );
|
||||
|
||||
this.add( aElement )
|
||||
.add( bElement );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
39
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/math/InvertEditor.js
generated
vendored
Normal file
39
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/math/InvertEditor.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
import { SelectInput, LabelElement } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { MathNode, FloatNode } from 'three-nodes/Nodes.js';
|
||||
|
||||
const DEFAULT_VALUE = new FloatNode();
|
||||
|
||||
export class InvertEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new MathNode( MathNode.INVERT, DEFAULT_VALUE );
|
||||
|
||||
super( 'Invert / Negate', 1, node, 175 );
|
||||
|
||||
const optionsField = new SelectInput( [
|
||||
{ name: 'Invert ( 1 - Source )', value: MathNode.INVERT },
|
||||
{ name: 'Negate ( - Source )', value: MathNode.NEGATE }
|
||||
], MathNode.INVERT ).onChange( () => {
|
||||
|
||||
node.method = optionsField.getValue();
|
||||
|
||||
this.invalidate();
|
||||
|
||||
} );
|
||||
|
||||
const input = new LabelElement( 'Source' ).setInput( 1 );
|
||||
|
||||
input.onConnect( () => {
|
||||
|
||||
node.aNode = input.getLinkedObject() || DEFAULT_VALUE;
|
||||
|
||||
} );
|
||||
|
||||
this.add( new LabelElement( 'Method' ).add( optionsField ) )
|
||||
.add( input );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
63
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/math/LimiterEditor.js
generated
vendored
Normal file
63
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/math/LimiterEditor.js
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
import { SelectInput, LabelElement, Element, NumberInput } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { MathNode, FloatNode } from 'three-nodes/Nodes.js';
|
||||
|
||||
|
||||
export class LimiterEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const NULL_VALUE = new FloatNode();
|
||||
|
||||
const node = new MathNode( MathNode.MIN, NULL_VALUE, NULL_VALUE );
|
||||
|
||||
super( 'Limiter', 1, node, 175 );
|
||||
|
||||
const methodInput = new SelectInput( [
|
||||
{ name: 'Min', value: MathNode.MIN },
|
||||
{ name: 'Max', value: MathNode.MAX },
|
||||
// { name: 'Clamp', value: MathNode.CLAMP }
|
||||
{ name: 'Saturate', value: MathNode.SATURATE }
|
||||
], MathNode.MIN );
|
||||
|
||||
methodInput.onChange( ( data ) => {
|
||||
|
||||
node.method = data.getValue();
|
||||
bElement.setVisible( data.getValue() !== MathNode.SATURATE );
|
||||
|
||||
this.invalidate();
|
||||
|
||||
} );
|
||||
|
||||
const aElement = new LabelElement( 'A' ).setInput( 1 );
|
||||
const bElement = new LabelElement( 'B' ).setInput( 1 );
|
||||
|
||||
aElement.add( new NumberInput().onChange( ( field ) => {
|
||||
|
||||
node.aNode.value = field.getValue();
|
||||
|
||||
} ) ).onConnect( ( elmt ) => {
|
||||
|
||||
elmt.setEnabledInputs( ! elmt.getLinkedObject() );
|
||||
node.aNode = elmt.getLinkedObject() || NULL_VALUE;
|
||||
|
||||
} );
|
||||
|
||||
bElement.add( new NumberInput().onChange( ( field ) => {
|
||||
|
||||
node.bNode.value = field.getValue();
|
||||
|
||||
} ) ).onConnect( ( elmt ) => {
|
||||
|
||||
elmt.setEnabledInputs( ! elmt.getLinkedObject() );
|
||||
node.bNode = elmt.getLinkedObject() || NULL_VALUE;
|
||||
|
||||
} );
|
||||
|
||||
this.add( new Element().add( methodInput ) )
|
||||
.add( aElement )
|
||||
.add( bElement );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
27
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/math/NormalizeEditor.js
generated
vendored
Normal file
27
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/math/NormalizeEditor.js
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
import { LabelElement } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { MathNode, Vector3Node } from 'three-nodes/Nodes.js';
|
||||
|
||||
const DEFAULT_VALUE = new Vector3Node();
|
||||
|
||||
export class NormalizeEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new MathNode( MathNode.NORMALIZE, DEFAULT_VALUE );
|
||||
|
||||
super( 'Normalize', 3, node, 175 );
|
||||
|
||||
const input = new LabelElement( 'A' ).setInput( 3 );
|
||||
|
||||
input.onConnect( () => {
|
||||
|
||||
node.aNode = input.getLinkedObject() || DEFAULT_VALUE;
|
||||
|
||||
} );
|
||||
|
||||
this.add( input );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
64
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/math/OperatorEditor.js
generated
vendored
Normal file
64
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/math/OperatorEditor.js
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
import { Element, LabelElement, NumberInput, SelectInput } from '../../libs/flow.module.js';
|
||||
import { FloatNode, OperatorNode } from 'three-nodes/Nodes.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
|
||||
|
||||
export class OperatorEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const NULL_VALUE = new FloatNode();
|
||||
|
||||
const node = new OperatorNode( '+', NULL_VALUE, NULL_VALUE );
|
||||
|
||||
super( 'Operator', 1, node, 150 );
|
||||
|
||||
const opInput = new SelectInput( [
|
||||
{ name: 'Addition ( + )', value: '+' },
|
||||
{ name: 'Subtraction ( - )', value: '-' },
|
||||
{ name: 'Multiplication ( * )', value: '*' },
|
||||
{ name: 'Division ( / )', value: '/' }
|
||||
], '+' );
|
||||
|
||||
opInput.onChange( ( data ) => {
|
||||
|
||||
node.op = data.getValue();
|
||||
|
||||
this.invalidate();
|
||||
|
||||
} );
|
||||
|
||||
const aElement = new LabelElement( 'A' ).setInput( 3 );
|
||||
const bElement = new LabelElement( 'B' ).setInput( 3 );
|
||||
|
||||
|
||||
aElement.add( new NumberInput().onChange( ( field ) => {
|
||||
|
||||
node.aNode.value = field.getValue();
|
||||
|
||||
} ) ).onConnect( ( elmt ) => {
|
||||
|
||||
elmt.setEnabledInputs( ! elmt.getLinkedObject() );
|
||||
node.aNode = elmt.getLinkedObject() || NULL_VALUE;
|
||||
|
||||
} );
|
||||
|
||||
bElement.add( new NumberInput().onChange( ( field ) => {
|
||||
|
||||
node.bNode.value = field.getValue();
|
||||
|
||||
} ) ).onConnect( ( elmt ) => {
|
||||
|
||||
elmt.setEnabledInputs( ! elmt.getLinkedObject() );
|
||||
node.bNode = elmt.getLinkedObject() || NULL_VALUE;
|
||||
|
||||
} );
|
||||
|
||||
|
||||
this.add( new Element().add( opInput ) )
|
||||
.add( aElement )
|
||||
.add( bElement );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
45
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/math/PowerEditor.js
generated
vendored
Normal file
45
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/math/PowerEditor.js
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
import { LabelElement, NumberInput } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { MathNode, FloatNode } from 'three-nodes/Nodes.js';
|
||||
|
||||
|
||||
export class PowerEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const NULL_VALUE = new FloatNode();
|
||||
const node = new MathNode( MathNode.POW, NULL_VALUE, NULL_VALUE );
|
||||
|
||||
super( 'Power', 1, node, 175 );
|
||||
|
||||
const aElement = new LabelElement( 'A' ).setInput( 1 );
|
||||
const bElement = new LabelElement( 'B' ).setInput( 1 );
|
||||
|
||||
aElement.add( new NumberInput().onChange( ( field ) => {
|
||||
|
||||
node.aNode.value = field.getValue();
|
||||
|
||||
} ) ).onConnect( ( elmt ) => {
|
||||
|
||||
elmt.setEnabledInputs( ! elmt.getLinkedObject() );
|
||||
node.aNode = elmt.getLinkedObject() || NULL_VALUE;
|
||||
|
||||
} );
|
||||
|
||||
bElement.add( new NumberInput().onChange( ( field ) => {
|
||||
|
||||
node.bNode.value = field.getValue();
|
||||
|
||||
} ) ).onConnect( ( elmt ) => {
|
||||
|
||||
elmt.setEnabledInputs( ! elmt.getLinkedObject() );
|
||||
node.bNode = elmt.getLinkedObject() || NULL_VALUE;
|
||||
|
||||
} );
|
||||
|
||||
this.add( aElement )
|
||||
.add( bElement );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
44
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/math/TrigonometryEditor.js
generated
vendored
Normal file
44
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/math/TrigonometryEditor.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
import { SelectInput, Element, LabelElement } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { MathNode, Vector3Node } from 'three-nodes/Nodes.js';
|
||||
|
||||
const DEFAULT_VALUE = new Vector3Node();
|
||||
|
||||
export class TrigonometryEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new MathNode( MathNode.SIN, DEFAULT_VALUE );
|
||||
|
||||
super( 'Trigonometry', 1, node, 175 );
|
||||
|
||||
const optionsField = new SelectInput( [
|
||||
{ name: 'Sin', value: MathNode.SIN },
|
||||
{ name: 'Cos', value: MathNode.COS },
|
||||
{ name: 'Tan', value: MathNode.TAN },
|
||||
|
||||
{ name: 'asin', value: MathNode.ASIN },
|
||||
{ name: 'acos', value: MathNode.ACOS },
|
||||
{ name: 'atan', value: MathNode.ATAN }
|
||||
], MathNode.SIN ).onChange( () => {
|
||||
|
||||
node.method = optionsField.getValue();
|
||||
|
||||
this.invalidate();
|
||||
|
||||
} );
|
||||
|
||||
const input = new LabelElement( 'A' ).setInput( 1 );
|
||||
|
||||
input.onConnect( () => {
|
||||
|
||||
node.aNode = input.getLinkedObject() || DEFAULT_VALUE;
|
||||
|
||||
} );
|
||||
|
||||
this.add( new Element().add( optionsField ) )
|
||||
.add( input );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
27
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/procedural/CheckerEditor.js
generated
vendored
Normal file
27
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/procedural/CheckerEditor.js
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
import { LabelElement } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { CheckerNode, UVNode } from 'three-nodes/Nodes.js';
|
||||
|
||||
const defaultUV = new UVNode();
|
||||
|
||||
export class CheckerEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new CheckerNode( defaultUV );
|
||||
|
||||
super( 'Checker', 1, node, 200 );
|
||||
|
||||
const field = new LabelElement( 'UV' ).setInput( 2 );
|
||||
|
||||
field.onConnect( () => {
|
||||
|
||||
node.uvNode = field.getLinkedObject() || defaultUV;
|
||||
|
||||
} );
|
||||
|
||||
this.add( field );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
99
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/scene/MeshEditor.js
generated
vendored
Normal file
99
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/scene/MeshEditor.js
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
import { LabelElement } from '../../libs/flow.module.js';
|
||||
import { Object3DEditor } from './Object3DEditor.js';
|
||||
import { Mesh } from 'three';
|
||||
|
||||
export class MeshEditor extends Object3DEditor {
|
||||
|
||||
constructor( mesh = null ) {
|
||||
|
||||
if ( mesh === null ) {
|
||||
|
||||
mesh = new Mesh();
|
||||
|
||||
}
|
||||
|
||||
super( mesh, 'Mesh' );
|
||||
|
||||
this.material = null;
|
||||
|
||||
this.defaultMaterial = null;
|
||||
|
||||
this._initMaterial();
|
||||
|
||||
this.updateDefault();
|
||||
this.restoreDefault();
|
||||
this.update();
|
||||
|
||||
}
|
||||
|
||||
get mesh() {
|
||||
|
||||
return this.value;
|
||||
|
||||
}
|
||||
|
||||
_initMaterial() {
|
||||
|
||||
const materialElement = new LabelElement( 'Material' ).setInputColor( 'forestgreen' ).setInput( 1 );
|
||||
|
||||
materialElement.onValid( ( source, target, stage ) => {
|
||||
|
||||
const object = target.getObject();
|
||||
|
||||
if ( object && object.isMaterial !== true ) {
|
||||
|
||||
if ( stage === 'dragged' ) {
|
||||
|
||||
const name = target.node.getName();
|
||||
|
||||
this.editor.tips.error( `"${name}" is not a Material.` );
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
} ).onConnect( () => {
|
||||
|
||||
this.material = materialElement.getLinkedObject() || this.defaultMaterial;
|
||||
|
||||
this.update();
|
||||
|
||||
} );
|
||||
|
||||
this.add( materialElement );
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
super.update();
|
||||
|
||||
const mesh = this.mesh;
|
||||
|
||||
if ( mesh ) {
|
||||
|
||||
mesh.material = this.material || this.defaultMaterial;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateDefault() {
|
||||
|
||||
super.updateDefault();
|
||||
|
||||
this.defaultMaterial = this.mesh.material;
|
||||
|
||||
}
|
||||
|
||||
restoreDefault() {
|
||||
|
||||
super.restoreDefault();
|
||||
|
||||
this.mesh.material = this.defaultMaterial;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
160
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/scene/Object3DEditor.js
generated
vendored
Normal file
160
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/scene/Object3DEditor.js
generated
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
import { NumberInput, StringInput, LabelElement } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { Group, MathUtils, Vector3 } from 'three';
|
||||
|
||||
export class Object3DEditor extends BaseNode {
|
||||
|
||||
constructor( object3d = null, name = 'Object 3D' ) {
|
||||
|
||||
if ( object3d === null ) {
|
||||
|
||||
object3d = new Group();
|
||||
|
||||
}
|
||||
|
||||
super( name, 1, object3d );
|
||||
|
||||
this.defaultPosition = new Vector3();
|
||||
this.defaultRotation = new Vector3();
|
||||
this.defaultScale = new Vector3( 100, 100, 100 );
|
||||
|
||||
this._initTags();
|
||||
this._initTransform();
|
||||
|
||||
this.onValidElement = () => {};
|
||||
|
||||
}
|
||||
|
||||
setEditor( editor ) {
|
||||
|
||||
if ( this.editor ) {
|
||||
|
||||
this.restoreDefault();
|
||||
|
||||
}
|
||||
|
||||
super.setEditor( editor );
|
||||
|
||||
if ( editor ) {
|
||||
|
||||
const name = this.nameInput.getValue();
|
||||
const object3d = editor.scene.getObjectByName( name );
|
||||
|
||||
this.value = object3d;
|
||||
|
||||
this.updateDefault();
|
||||
this.restoreDefault();
|
||||
this.update();
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
get object3d() {
|
||||
|
||||
return this.value;
|
||||
|
||||
}
|
||||
|
||||
_initTags() {
|
||||
|
||||
this.nameInput = new StringInput( this.object3d.name ).setReadOnly( true )
|
||||
.onChange( () => this.object3d.name = this.nameInput.getValue() );
|
||||
|
||||
this.add( new LabelElement( 'Name' ).add( this.nameInput ) );
|
||||
|
||||
}
|
||||
|
||||
_initTransform() {
|
||||
|
||||
const update = () => this.update();
|
||||
|
||||
const posX = new NumberInput().setTagColor( 'red' ).onChange( update );
|
||||
const posY = new NumberInput().setTagColor( 'green' ).onChange( update );
|
||||
const posZ = new NumberInput().setTagColor( 'blue' ).onChange( update );
|
||||
|
||||
const rotationStep = 1;
|
||||
|
||||
const rotX = new NumberInput().setTagColor( 'red' ).setStep( rotationStep ).onChange( update );
|
||||
const rotY = new NumberInput().setTagColor( 'green' ).setStep( rotationStep ).onChange( update );
|
||||
const rotZ = new NumberInput().setTagColor( 'blue' ).setStep( rotationStep ).onChange( update );
|
||||
|
||||
const scaleX = new NumberInput( 100 ).setTagColor( 'red' ).setStep( rotationStep ).onChange( update );
|
||||
const scaleY = new NumberInput( 100 ).setTagColor( 'green' ).setStep( rotationStep ).onChange( update );
|
||||
const scaleZ = new NumberInput( 100 ).setTagColor( 'blue' ).setStep( rotationStep ).onChange( update );
|
||||
|
||||
this.add( new LabelElement( 'Position' ).add( posX ).add( posY ).add( posZ ) )
|
||||
.add( new LabelElement( 'Rotation' ).add( rotX ).add( rotY ).add( rotZ ) )
|
||||
.add( new LabelElement( 'Scale' ).add( scaleX ).add( scaleY ).add( scaleZ ) );
|
||||
|
||||
this.posX = posX;
|
||||
this.posY = posY;
|
||||
this.posZ = posZ;
|
||||
|
||||
this.rotX = rotX;
|
||||
this.rotY = rotY;
|
||||
this.rotZ = rotZ;
|
||||
|
||||
this.scaleX = scaleX;
|
||||
this.scaleY = scaleY;
|
||||
this.scaleZ = scaleZ;
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
const object3d = this.object3d;
|
||||
|
||||
if ( object3d ) {
|
||||
|
||||
const { position, rotation, scale } = object3d;
|
||||
|
||||
position.x = this.posX.getValue();
|
||||
position.y = this.posY.getValue();
|
||||
position.z = this.posZ.getValue();
|
||||
|
||||
rotation.x = MathUtils.degToRad( this.rotX.getValue() );
|
||||
rotation.y = MathUtils.degToRad( this.rotY.getValue() );
|
||||
rotation.z = MathUtils.degToRad( this.rotZ.getValue() );
|
||||
|
||||
scale.x = this.scaleX.getValue() / 100;
|
||||
scale.y = this.scaleY.getValue() / 100;
|
||||
scale.z = this.scaleZ.getValue() / 100;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateDefault() {
|
||||
|
||||
const { position, rotation, scale } = this.object3d;
|
||||
|
||||
this.defaultPosition = position.clone();
|
||||
this.defaultRotation = new Vector3( MathUtils.radToDeg( rotation.x ), MathUtils.radToDeg( rotation.y ), MathUtils.radToDeg( rotation.z ) );
|
||||
this.defaultScale = scale.clone().multiplyScalar( 100 );
|
||||
|
||||
}
|
||||
|
||||
restoreDefault() {
|
||||
|
||||
const position = this.defaultPosition;
|
||||
const rotation = this.defaultRotation;
|
||||
const scale = this.defaultScale;
|
||||
|
||||
this.posX.setValue( position.x );
|
||||
this.posY.setValue( position.y );
|
||||
this.posZ.setValue( position.z );
|
||||
|
||||
this.rotX.setValue( rotation.x );
|
||||
this.rotY.setValue( rotation.y );
|
||||
this.rotZ.setValue( rotation.z );
|
||||
|
||||
this.scaleX.setValue( scale.x );
|
||||
this.scaleY.setValue( scale.y );
|
||||
this.scaleZ.setValue( scale.z );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
99
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/scene/PointsEditor.js
generated
vendored
Normal file
99
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/scene/PointsEditor.js
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
import { LabelElement } from '../../libs/flow.module.js';
|
||||
import { Object3DEditor } from './Object3DEditor.js';
|
||||
import { Points } from 'three';
|
||||
|
||||
export class PointsEditor extends Object3DEditor {
|
||||
|
||||
constructor( points = null ) {
|
||||
|
||||
if ( points === null ) {
|
||||
|
||||
points = new Points();
|
||||
|
||||
}
|
||||
|
||||
super( points, 'Points' );
|
||||
|
||||
this.material = null;
|
||||
|
||||
this.defaultMaterial = null;
|
||||
|
||||
this._initMaterial();
|
||||
|
||||
this.updateDefault();
|
||||
this.restoreDefault();
|
||||
this.update();
|
||||
|
||||
}
|
||||
|
||||
get points() {
|
||||
|
||||
return this.value;
|
||||
|
||||
}
|
||||
|
||||
_initMaterial() {
|
||||
|
||||
const materialElement = new LabelElement( 'Material' ).setInputColor( 'forestgreen' ).setInput( 1 );
|
||||
|
||||
materialElement.onValid( ( source, target, stage ) => {
|
||||
|
||||
const object = target.getObject();
|
||||
|
||||
if ( object && object.isMaterial !== true ) {
|
||||
|
||||
if ( stage === 'dragged' ) {
|
||||
|
||||
const name = target.node.getName();
|
||||
|
||||
this.editor.tips.error( `"${name}" is not a Material.` );
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
} ).onConnect( () => {
|
||||
|
||||
this.material = materialElement.getLinkedObject() || this.defaultMaterial;
|
||||
|
||||
this.update();
|
||||
|
||||
} );
|
||||
|
||||
this.add( materialElement );
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
super.update();
|
||||
|
||||
const points = this.points;
|
||||
|
||||
if ( points ) {
|
||||
|
||||
points.material = this.material || this.defaultMaterial;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateDefault() {
|
||||
|
||||
super.updateDefault();
|
||||
|
||||
this.defaultMaterial = this.points.material;
|
||||
|
||||
}
|
||||
|
||||
restoreDefault() {
|
||||
|
||||
super.restoreDefault();
|
||||
|
||||
this.points.material = this.defaultMaterial;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
58
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/utils/JoinEditor.js
generated
vendored
Normal file
58
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/utils/JoinEditor.js
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
import { LabelElement } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { JoinNode, FloatNode } from 'three-nodes/Nodes.js';
|
||||
|
||||
const NULL_VALUE = new FloatNode();
|
||||
|
||||
export class JoinEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new JoinNode();
|
||||
|
||||
super( 'Join', 1, node, 175 );
|
||||
|
||||
const update = () => {
|
||||
|
||||
const values = [
|
||||
xElement.getLinkedObject(),
|
||||
yElement.getLinkedObject(),
|
||||
zElement.getLinkedObject(),
|
||||
wElement.getLinkedObject()
|
||||
];
|
||||
|
||||
let length = 1;
|
||||
|
||||
if ( values[ 3 ] !== null ) length = 4;
|
||||
else if ( values[ 2 ] !== null ) length = 3;
|
||||
else if ( values[ 1 ] !== null ) length = 2;
|
||||
|
||||
const nodes = [];
|
||||
|
||||
for ( let i = 0; i < length; i ++ ) {
|
||||
|
||||
nodes.push( values[ i ] || NULL_VALUE );
|
||||
|
||||
}
|
||||
|
||||
node.nodes = nodes;
|
||||
|
||||
this.invalidate();
|
||||
|
||||
};
|
||||
|
||||
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 );
|
||||
|
||||
this.add( xElement )
|
||||
.add( yElement )
|
||||
.add( zElement )
|
||||
.add( wElement );
|
||||
|
||||
update();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
43
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/utils/OscillatorEditor.js
generated
vendored
Normal file
43
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/utils/OscillatorEditor.js
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
import { SelectInput, LabelElement, Element } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { OscNode, FloatNode } from 'three-nodes/Nodes.js';
|
||||
|
||||
const NULL_VALUE = new FloatNode();
|
||||
|
||||
export class OscillatorEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new OscNode( OscNode.SINE, NULL_VALUE );
|
||||
|
||||
super( 'Oscillator', 1, node, 175 );
|
||||
|
||||
const methodInput = new SelectInput( [
|
||||
{ name: 'Sine', value: OscNode.SINE },
|
||||
{ name: 'Square', value: OscNode.SQUARE },
|
||||
{ name: 'Triangle', value: OscNode.TRIANGLE },
|
||||
{ name: 'Sawtooth', value: OscNode.SAWTOOTH }
|
||||
], OscNode.SINE );
|
||||
|
||||
methodInput.onChange( () => {
|
||||
|
||||
node.method = methodInput.getValue();
|
||||
|
||||
this.invalidate();
|
||||
|
||||
} );
|
||||
|
||||
const timeElement = new LabelElement( 'Time' ).setInput( 1 );
|
||||
|
||||
timeElement.onConnect( () => {
|
||||
|
||||
node.timeNode = timeElement.getLinkedObject() || NULL_VALUE;
|
||||
|
||||
} );
|
||||
|
||||
this.add( new Element().add( methodInput ) )
|
||||
.add( timeElement );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
166
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/utils/PreviewEditor.js
generated
vendored
Normal file
166
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/utils/PreviewEditor.js
generated
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
import { OrbitControls } from 'three-addons/controls/OrbitControls.js';
|
||||
import { ViewHelper } from 'three-addons/helpers/ViewHelper.js';
|
||||
import { Element, LabelElement, SelectInput } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { MeshBasicNodeMaterial, FloatNode } from 'three-nodes/Nodes.js';
|
||||
import { WebGLRenderer, PerspectiveCamera, Scene, Mesh, DoubleSide, SphereGeometry, BoxGeometry, PlaneGeometry, TorusKnotGeometry } from 'three';
|
||||
|
||||
const nullValue = new FloatNode().setConst( true );
|
||||
|
||||
const sceneDict = {};
|
||||
|
||||
const getScene = ( name ) => {
|
||||
|
||||
let scene = sceneDict[ name ];
|
||||
|
||||
if ( scene === undefined ) {
|
||||
|
||||
scene = new Scene();
|
||||
|
||||
if ( name === 'box' ) {
|
||||
|
||||
const box = new Mesh( new BoxGeometry( 1.3, 1.3, 1.3 ) );
|
||||
scene.add( box );
|
||||
|
||||
} else if ( name === 'sphere' ) {
|
||||
|
||||
const sphere = new Mesh( new SphereGeometry( 1, 32, 16 ) );
|
||||
scene.add( sphere );
|
||||
|
||||
} else if ( name === 'plane' || name === 'sprite' ) {
|
||||
|
||||
const plane = new Mesh( new PlaneGeometry( 2, 2 ) );
|
||||
scene.add( plane );
|
||||
|
||||
|
||||
} else if ( name === 'torus' ) {
|
||||
|
||||
const torus = new Mesh( new TorusKnotGeometry( .7, .1, 100, 16 ) );
|
||||
scene.add( torus );
|
||||
|
||||
}
|
||||
|
||||
sceneDict[ name ] = scene;
|
||||
|
||||
}
|
||||
|
||||
return scene;
|
||||
|
||||
};
|
||||
|
||||
export class PreviewEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const width = 300;
|
||||
const height = 300;
|
||||
|
||||
super( 'Preview', 0, null, height );
|
||||
|
||||
const material = new MeshBasicNodeMaterial();
|
||||
material.colorNode = nullValue;
|
||||
material.side = DoubleSide;
|
||||
material.transparent = true;
|
||||
|
||||
const previewElement = new Element();
|
||||
previewElement.dom.style[ 'padding-top' ] = 0;
|
||||
previewElement.dom.style[ 'padding-bottom' ] = 0;
|
||||
|
||||
const sceneInput = new SelectInput( [
|
||||
{ name: 'Box', value: 'box' },
|
||||
{ name: 'Sphere', value: 'sphere' },
|
||||
{ name: 'Plane', value: 'plane' },
|
||||
{ name: 'Sprite', value: 'sprite' },
|
||||
{ name: 'Torus', value: 'torus' }
|
||||
], 'box' );
|
||||
|
||||
const inputElement = new LabelElement( 'Input' ).setInput( 4 ).onConnect( () => {
|
||||
|
||||
material.colorNode = inputElement.getLinkedObject() || nullValue;
|
||||
material.dispose();
|
||||
|
||||
}, true );
|
||||
|
||||
const canvas = document.createElement( 'canvas' );
|
||||
canvas.style.position = 'absolute';
|
||||
previewElement.dom.append( canvas );
|
||||
previewElement.setHeight( height );
|
||||
|
||||
const renderer = new WebGLRenderer( {
|
||||
canvas,
|
||||
alpha: true
|
||||
} );
|
||||
|
||||
renderer.autoClear = false;
|
||||
renderer.setSize( width, height, true );
|
||||
renderer.setPixelRatio( window.devicePixelRatio );
|
||||
|
||||
const camera = new PerspectiveCamera( 45, width / height, 0.1, 100 );
|
||||
camera.aspect = width / height;
|
||||
camera.updateProjectionMatrix();
|
||||
camera.position.set( - 2, 2, 2 );
|
||||
camera.lookAt( 0, 0, 0 );
|
||||
|
||||
const controls = new OrbitControls( camera, previewElement.dom );
|
||||
controls.enableKeys = false;
|
||||
controls.update();
|
||||
|
||||
const viewHelper = new ViewHelper( camera, previewElement.dom );
|
||||
|
||||
this.sceneInput = sceneInput;
|
||||
this.viewHelper = viewHelper;
|
||||
this.material = material;
|
||||
this.camera = camera;
|
||||
this.renderer = renderer;
|
||||
|
||||
this.add( inputElement )
|
||||
.add( new LabelElement( 'Object' ).add( sceneInput ) )
|
||||
.add( previewElement );
|
||||
|
||||
}
|
||||
|
||||
setEditor( editor ) {
|
||||
|
||||
super.setEditor( editor );
|
||||
|
||||
this.updateAnimationRequest();
|
||||
|
||||
}
|
||||
|
||||
updateAnimationRequest() {
|
||||
|
||||
if ( this.editor !== null ) {
|
||||
|
||||
requestAnimationFrame( () => this.update() );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
const { viewHelper, material, renderer, camera, sceneInput } = this;
|
||||
|
||||
this.updateAnimationRequest();
|
||||
|
||||
const sceneName = sceneInput.getValue();
|
||||
|
||||
const scene = getScene( sceneName );
|
||||
const mesh = scene.children[ 0 ];
|
||||
|
||||
mesh.material = material;
|
||||
|
||||
if ( sceneName === 'sprite' ) {
|
||||
|
||||
mesh.lookAt( camera.position );
|
||||
|
||||
}
|
||||
|
||||
renderer.clear();
|
||||
renderer.render( scene, camera );
|
||||
|
||||
viewHelper.render( renderer );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
39
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/utils/SplitEditor.js
generated
vendored
Normal file
39
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/utils/SplitEditor.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
import { SelectInput, Element } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { SplitNode, FloatNode } from 'three-nodes/Nodes.js';
|
||||
|
||||
const NULL_VALUE = new FloatNode();
|
||||
|
||||
export class SplitEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new SplitNode( NULL_VALUE, 'x' );
|
||||
|
||||
super( 'Split', 1, node, 175 );
|
||||
|
||||
const componentsField = new SelectInput( [
|
||||
{ name: 'X | R', value: 'x' },
|
||||
{ name: 'Y | G', value: 'y' },
|
||||
{ name: 'Z | B', value: 'z' },
|
||||
{ name: 'W | A', value: 'w' }
|
||||
], node.components ).onChange( () => {
|
||||
|
||||
node.components = componentsField.getValue();
|
||||
|
||||
this.invalidate();
|
||||
|
||||
} );
|
||||
|
||||
const componentsElement = new Element().add( componentsField ).setInput( 1 )
|
||||
.onConnect( () => {
|
||||
|
||||
node.node = componentsElement.getLinkedObject() || NULL_VALUE;
|
||||
|
||||
} );
|
||||
|
||||
this.add( componentsElement );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
58
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/utils/TimerEditor.js
generated
vendored
Normal file
58
HTML/ThreeJS/node_modules/three/examples/jsm/node-editor/utils/TimerEditor.js
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
import { NumberInput, LabelElement, Element, ButtonInput } from '../../libs/flow.module.js';
|
||||
import { BaseNode } from '../core/BaseNode.js';
|
||||
import { TimerNode } from 'three-nodes/Nodes.js';
|
||||
|
||||
export class TimerEditor extends BaseNode {
|
||||
|
||||
constructor() {
|
||||
|
||||
const node = new TimerNode();
|
||||
|
||||
super( 'Timer', 1, node, 200 );
|
||||
|
||||
this.title.setIcon( 'ti ti-clock' );
|
||||
|
||||
const updateField = () => {
|
||||
|
||||
field.setValue( node.value.toFixed( 3 ) );
|
||||
|
||||
};
|
||||
|
||||
const field = new NumberInput().onChange( () => {
|
||||
|
||||
node.value = field.getValue();
|
||||
|
||||
} );
|
||||
|
||||
const scaleField = new NumberInput( 1 ).onChange( () => {
|
||||
|
||||
node.scale = scaleField.getValue();
|
||||
|
||||
} );
|
||||
|
||||
const moreElement = new Element().add( new ButtonInput( 'Reset' ).onClick( () => {
|
||||
|
||||
node.value = 0;
|
||||
|
||||
updateField();
|
||||
|
||||
} ) ).setSerializable( false );
|
||||
|
||||
this.add( new Element().add( field ).setSerializable( false ) )
|
||||
.add( new LabelElement( 'Speed' ).add( scaleField ) )
|
||||
.add( moreElement );
|
||||
|
||||
// extends node
|
||||
|
||||
node._update = node.update;
|
||||
node.update = function ( ...params ) {
|
||||
|
||||
this._update( ...params );
|
||||
|
||||
updateField();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user