sunag 3 недель назад
Родитель
Сommit
76ff395a5a

+ 1 - 154
examples/webgpu_materials.html

@@ -34,9 +34,8 @@
 		<script type="module">
 
 			import * as THREE from 'three/webgpu';
-			import * as TSL from 'three/tsl';
 
-			import { Fn, wgslFn, positionLocal, scriptable, positionWorld, normalLocal, normalWorld, normalView, color, texture, uv, float, vec2, vec3, vec4, oscSine, triplanarTexture, screenUV, js, string, Loop, cameraProjectionMatrix, ScriptableNodeResources } from 'three/tsl';
+			import { Fn, wgslFn, positionLocal, positionWorld, normalLocal, normalWorld, normalView, color, texture, uv, float, vec2, vec3, vec4, oscSine, triplanarTexture, screenUV, Loop, cameraProjectionMatrix } from 'three/tsl';
 
 			import { TeapotGeometry } from 'three/addons/geometries/TeapotGeometry.js';
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
@@ -254,111 +253,6 @@
 
 				} );
 
-				// Scriptable
-
-				ScriptableNodeResources.set( 'TSL', TSL );
-
-				const asyncNode = scriptable( js( `
-
-					layout = {
-						outputType: 'node'
-					};
-
-					const { float } = TSL;
-
-					function init() {
-
-						setTimeout( () => {
-
-							local.set( 'result', float( 1.0 ) );
-
-							refresh(); // refresh the node
-
-						}, 1000 );
-
-						return float( 0.0 );
-
-					}
-
-					function main() {
-
-						const result = local.get( 'result', init );
-
-						//console.log( 'result', result );
-
-						return result;
-
-					}
-
-				` ) );
-
-				const scriptableNode = scriptable( js( `
-
-					layout = {
-						outputType: 'node',
-						elements: [
-							{ name: 'source', inputType: 'node' },
-							{ name: 'contrast', inputType: 'node' },
-							{ name: 'vector3', inputType: 'Vector3' },
-							{ name: 'message', inputType: 'string' },
-							{ name: 'binary', inputType: 'ArrayBuffer' },
-							{ name: 'object3d', inputType: 'Object3D' },
-							{ name: 'execFrom', inputType: 'string' }
-						]
-					};
-
-					const { saturation, float, oscSine, mul } = TSL;
-
-					function helloWorld() {
-
-						console.log( "Hello World!" );
-
-					}
-
-					function main() {
-
-						const source = parameters.get( 'source' ) || float();
-						const contrast = parameters.get( 'contrast' ) || float();
-
-						const material = local.get( 'material' );
-
-						//console.log( 'vector3', parameters.get( 'vector3' ) );
-
-						if ( parameters.get( 'execFrom' ) === 'serialized' ) {
-
-							//console.log( 'message', parameters.get( 'message' ).value );
-							//console.log( 'binary', parameters.get( 'binary' ) );
-							//console.log( 'object3d', parameters.get( 'object3d' ) ); // unserializable yet
-
-							//console.log( global.get( 'renderer' ) );
-
-						}
-
-						if ( material ) material.needsUpdate = true;
-
-						return mul( saturation( source, oscSine() ), contrast );
-
-					}
-
-					output = { helloWorld };
-
-				` ) );
-
-				scriptableNode.setParameter( 'source', texture( uvTexture ).xyz );
-				scriptableNode.setParameter( 'contrast', asyncNode );
-				scriptableNode.setParameter( 'vector3', vec3( new THREE.Vector3( 1, 1, 1 ) ) );
-				scriptableNode.setParameter( 'message', string( 'Hello World!' ) );
-				scriptableNode.setParameter( 'binary', new ArrayBuffer( 4 ) );
-				scriptableNode.setParameter( 'object3d', new THREE.Group() );
-
-				scriptableNode.call( 'helloWorld' );
-
-				material = new THREE.MeshBasicNodeMaterial();
-				material.colorNode = scriptableNode;
-				materials.push( material );
-
-				scriptableNode.setLocal( 'material', material );
-
 				//
 				// Geometry
 				//
@@ -371,8 +265,6 @@
 
 				}
 
-				const serializeMesh = scene.children[ scene.children.length - 1 ];
-
 				//
 
 				renderer = new THREE.WebGPURenderer( { antialias: true } );
@@ -386,10 +278,6 @@
 
 				window.addEventListener( 'resize', onWindowResize );
 
-				//
-
-				setTimeout( () => testSerialization( serializeMesh ), 1000 );
-
 			}
 
 			function addMesh( geometry, material ) {
@@ -409,47 +297,6 @@
 
 			}
 
-			function moduleToLib( module ) {
-
-				const lib = {};
-
-				for ( const nodeElement of Object.values( module ) ) {
-
-					if ( typeof nodeElement === 'function' && nodeElement.type !== undefined ) {
-
-						lib[ nodeElement.type ] = nodeElement;
-
-					}
-
-				}
-
-				return lib;
-
-			}
-
-			function testSerialization( mesh ) {
-
-				const json = mesh.toJSON();
-				const loader = new THREE.NodeObjectLoader().setNodes( moduleToLib( THREE ) ).setNodeMaterials( moduleToLib( THREE ) );
-				const serializedMesh = loader.parse( json, () => {
-
-					serializedMesh.position.x = ( objects.length % 4 ) * 200 - 400;
-					serializedMesh.position.z = Math.floor( objects.length / 4 ) * 200 - 200;
-
-					const scriptableNode = serializedMesh.material.colorNode;
-
-					// it's because local.get( 'material' ) is used in the example ( local/global is unserializable )
-					scriptableNode.setLocal( 'material', serializedMesh.material );
-					scriptableNode.setParameter( 'execFrom', 'serialized' );
-
-					objects.push( serializedMesh );
-
-					scene.add( serializedMesh );
-
-				} );
-
-			}
-
 			function onWindowResize() {
 
 				camera.aspect = window.innerWidth / window.innerHeight;

+ 0 - 2
src/Three.TSL.js

@@ -484,8 +484,6 @@ export const screenCoordinate = TSL.screenCoordinate;
 export const screenDPR = TSL.screenDPR;
 export const screenSize = TSL.screenSize;
 export const screenUV = TSL.screenUV;
-export const scriptable = TSL.scriptable;
-export const scriptableValue = TSL.scriptableValue;
 export const select = TSL.select;
 export const setCurrentStack = TSL.setCurrentStack;
 export const setName = TSL.setName;

+ 0 - 2
src/nodes/Nodes.js

@@ -74,8 +74,6 @@ export { default as CodeNode } from './code/CodeNode.js';
 export { default as ExpressionNode } from './code/ExpressionNode.js';
 export { default as FunctionCallNode } from './code/FunctionCallNode.js';
 export { default as FunctionNode } from './code/FunctionNode.js';
-export { default as ScriptableNode } from './code/ScriptableNode.js';
-export { default as ScriptableValueNode } from './code/ScriptableValueNode.js';
 
 // display
 export { default as BumpMapNode } from './display/BumpMapNode.js';

+ 0 - 2
src/nodes/TSL.js

@@ -119,8 +119,6 @@ export * from './code/ExpressionNode.js';
 export * from './code/CodeNode.js';
 export * from './code/FunctionCallNode.js';
 export * from './code/FunctionNode.js';
-export * from './code/ScriptableNode.js';
-export * from './code/ScriptableValueNode.js';
 
 // fog
 export * from './fog/Fog.js';

+ 0 - 726
src/nodes/code/ScriptableNode.js

@@ -1,726 +0,0 @@
-import Node from '../core/Node.js';
-import { scriptableValue } from './ScriptableValueNode.js';
-import { nodeProxy, float } from '../tsl/TSLBase.js';
-import { hashArray, hashString } from '../core/NodeUtils.js';
-
-/**
- * A Map-like data structure for managing resources of scriptable nodes.
- *
- * @augments Map
- */
-class Resources extends Map {
-
-	get( key, callback = null, ...params ) {
-
-		if ( this.has( key ) ) return super.get( key );
-
-		if ( callback !== null ) {
-
-			const value = callback( ...params );
-			this.set( key, value );
-			return value;
-
-		}
-
-	}
-
-}
-
-class Parameters {
-
-	constructor( scriptableNode ) {
-
-		this.scriptableNode = scriptableNode;
-
-	}
-
-	get parameters() {
-
-		return this.scriptableNode.parameters;
-
-	}
-
-	get layout() {
-
-		return this.scriptableNode.getLayout();
-
-	}
-
-	getInputLayout( id ) {
-
-		return this.scriptableNode.getInputLayout( id );
-
-	}
-
-	get( name ) {
-
-		const param = this.parameters[ name ];
-		const value = param ? param.getValue() : null;
-
-		return value;
-
-	}
-
-}
-
-/**
- * Defines the resources (e.g. namespaces) of scriptable nodes.
- *
- * @type {Resources}
- */
-export const ScriptableNodeResources = new Resources();
-
-/**
- * This type of node allows to implement nodes with custom scripts. The script
- * section is represented as an instance of `CodeNode` written with JavaScript.
- * The script itself must adhere to a specific structure.
- *
- * - main(): Executed once by default and every time `node.needsUpdate` is set.
- * - layout: The layout object defines the script's interface (inputs and outputs).
- *
- * ```js
- * ScriptableNodeResources.set( 'TSL', TSL );
- *
- * const scriptableNode = scriptable( js( `
- * 	layout = {
- * 		outputType: 'node',
- * 		elements: [
- * 			{ name: 'source', inputType: 'node' },
- * 		]
- * 	};
- *
- * 	const { mul, oscSine } = TSL;
- *
- * 	function main() {
- * 		const source = parameters.get( 'source' ) || float();
- * 		return mul( source, oscSine() ) );
- * 	}
- *
- * ` ) );
- *
- * scriptableNode.setParameter( 'source', color( 1, 0, 0 ) );
- *
- * const material = new THREE.MeshBasicNodeMaterial();
- * material.colorNode = scriptableNode;
- * ```
- *
- * @augments Node
- */
-class ScriptableNode extends Node {
-
-	static get type() {
-
-		return 'ScriptableNode';
-
-	}
-
-	/**
-	 * Constructs a new scriptable node.
-	 *
-	 * @param {?CodeNode} [codeNode=null] - The code node.
-	 * @param {Object} [parameters={}] - The parameters definition.
-	 */
-	constructor( codeNode = null, parameters = {} ) {
-
-		super();
-
-		/**
-		 * The code node.
-		 *
-		 * @type {?CodeNode}
-		 * @default null
-		 */
-		this.codeNode = codeNode;
-
-		/**
-		 * The parameters definition.
-		 *
-		 * @type {Object}
-		 * @default {}
-		 */
-		this.parameters = parameters;
-
-		this._local = new Resources();
-		this._output = scriptableValue( null );
-		this._outputs = {};
-		this._source = this.source;
-		this._method = null;
-		this._object = null;
-		this._value = null;
-		this._needsOutputUpdate = true;
-
-		this.onRefresh = this.onRefresh.bind( this );
-
-		/**
-		 * This flag can be used for type testing.
-		 *
-		 * @type {boolean}
-		 * @readonly
-		 * @default true
-		 */
-		this.isScriptableNode = true;
-
-	}
-
-	/**
-	 * The source code of the scriptable node.
-	 *
-	 * @type {string}
-	 */
-	get source() {
-
-		return this.codeNode ? this.codeNode.code : '';
-
-	}
-
-	/**
-	 * Sets the reference of a local script variable.
-	 *
-	 * @param {string} name - The variable name.
-	 * @param {Object} value - The reference to set.
-	 * @return {Resources} The resource map
-	 */
-	setLocal( name, value ) {
-
-		return this._local.set( name, value );
-
-	}
-
-	/**
-	 * Gets the value of a local script variable.
-	 *
-	 * @param {string} name - The variable name.
-	 * @return {Object} The value.
-	 */
-	getLocal( name ) {
-
-		return this._local.get( name );
-
-	}
-
-	/**
-	 * Event listener for the `refresh` event.
-	 */
-	onRefresh() {
-
-		this._refresh();
-
-	}
-
-	/**
-	 * Returns an input from the layout with the given id/name.
-	 *
-	 * @param {string} id - The id/name of the input.
-	 * @return {Object} The element entry.
-	 */
-	getInputLayout( id ) {
-
-		for ( const element of this.getLayout() ) {
-
-			if ( element.inputType && ( element.id === id || element.name === id ) ) {
-
-				return element;
-
-			}
-
-		}
-
-	}
-
-	/**
-	 * Returns an output from the layout with the given id/name.
-	 *
-	 * @param {string} id - The id/name of the output.
-	 * @return {Object} The element entry.
-	 */
-	getOutputLayout( id ) {
-
-		for ( const element of this.getLayout() ) {
-
-			if ( element.outputType && ( element.id === id || element.name === id ) ) {
-
-				return element;
-
-			}
-
-		}
-
-	}
-
-	/**
-	 * Defines a script output for the given name and value.
-	 *
-	 * @param {string} name - The name of the output.
-	 * @param {Node} value - The node value.
-	 * @return {ScriptableNode} A reference to this node.
-	 */
-	setOutput( name, value ) {
-
-		const outputs = this._outputs;
-
-		if ( outputs[ name ] === undefined ) {
-
-			outputs[ name ] = scriptableValue( value );
-
-		} else {
-
-			outputs[ name ].value = value;
-
-		}
-
-		return this;
-
-	}
-
-	/**
-	 * Returns a script output for the given name.
-	 *
-	 * @param {string} name - The name of the output.
-	 * @return {ScriptableValueNode} The node value.
-	 */
-	getOutput( name ) {
-
-		return this._outputs[ name ];
-
-	}
-
-	/**
-	 * Returns a parameter for the given name
-	 *
-	 * @param {string} name - The name of the parameter.
-	 * @return {ScriptableValueNode} The node value.
-	 */
-	getParameter( name ) {
-
-		return this.parameters[ name ];
-
-	}
-
-	/**
-	 * Sets a value for the given parameter name.
-	 *
-	 * @param {string} name - The parameter name.
-	 * @param {any} value - The parameter value.
-	 * @return {ScriptableNode} A reference to this node.
-	 */
-	setParameter( name, value ) {
-
-		const parameters = this.parameters;
-
-		if ( value && value.isScriptableNode ) {
-
-			this.deleteParameter( name );
-
-			parameters[ name ] = value;
-			parameters[ name ].getDefaultOutput().events.addEventListener( 'refresh', this.onRefresh );
-
-		} else if ( value && value.isScriptableValueNode ) {
-
-			this.deleteParameter( name );
-
-			parameters[ name ] = value;
-			parameters[ name ].events.addEventListener( 'refresh', this.onRefresh );
-
-		} else if ( parameters[ name ] === undefined ) {
-
-			parameters[ name ] = scriptableValue( value );
-			parameters[ name ].events.addEventListener( 'refresh', this.onRefresh );
-
-		} else {
-
-			parameters[ name ].value = value;
-
-		}
-
-		return this;
-
-	}
-
-	/**
-	 * Returns the value of this node which is the value of
-	 * the default output.
-	 *
-	 * @return {Node} The value.
-	 */
-	getValue() {
-
-		return this.getDefaultOutput().getValue();
-
-	}
-
-	/**
-	 * Deletes a parameter from the script.
-	 *
-	 * @param {string} name - The parameter to remove.
-	 * @return {ScriptableNode} A reference to this node.
-	 */
-	deleteParameter( name ) {
-
-		let valueNode = this.parameters[ name ];
-
-		if ( valueNode ) {
-
-			if ( valueNode.isScriptableNode ) valueNode = valueNode.getDefaultOutput();
-
-			valueNode.events.removeEventListener( 'refresh', this.onRefresh );
-
-		}
-
-		return this;
-
-	}
-
-	/**
-	 * Deletes all parameters from the script.
-	 *
-	 * @return {ScriptableNode} A reference to this node.
-	 */
-	clearParameters() {
-
-		for ( const name of Object.keys( this.parameters ) ) {
-
-			this.deleteParameter( name );
-
-		}
-
-		this.needsUpdate = true;
-
-		return this;
-
-	}
-
-	/**
-	 * Calls a function from the script.
-	 *
-	 * @param {string} name - The function name.
-	 * @param {...any} params - A list of parameters.
-	 * @return {any} The result of the function call.
-	 */
-	call( name, ...params ) {
-
-		const object = this.getObject();
-		const method = object[ name ];
-
-		if ( typeof method === 'function' ) {
-
-			return method( ...params );
-
-		}
-
-	}
-
-	/**
-	 * Asynchronously calls a function from the script.
-	 *
-	 * @param {string} name - The function name.
-	 * @param {...any} params - A list of parameters.
-	 * @return {Promise<any>} The result of the function call.
-	 */
-	async callAsync( name, ...params ) {
-
-		const object = this.getObject();
-		const method = object[ name ];
-
-		if ( typeof method === 'function' ) {
-
-			return method.constructor.name === 'AsyncFunction' ? await method( ...params ) : method( ...params );
-
-		}
-
-	}
-
-	/**
-	 * Overwritten since the node types is inferred from the script's output.
-	 *
-	 * @param {NodeBuilder} builder - The current node builder
-	 * @return {string} The node type.
-	 */
-	getNodeType( builder ) {
-
-		return this.getDefaultOutputNode().getNodeType( builder );
-
-	}
-
-	/**
-	 * Refreshes the script node.
-	 *
-	 * @param {?string} [output=null] - An optional output.
-	 */
-	refresh( output = null ) {
-
-		if ( output !== null ) {
-
-			this.getOutput( output ).refresh();
-
-		} else {
-
-			this._refresh();
-
-		}
-
-	}
-
-	/**
-	 * Returns an object representation of the script.
-	 *
-	 * @return {Object} The result object.
-	 */
-	getObject() {
-
-		if ( this.needsUpdate ) this.dispose();
-		if ( this._object !== null ) return this._object;
-
-		//
-
-		const refresh = () => this.refresh();
-		const setOutput = ( id, value ) => this.setOutput( id, value );
-
-		const parameters = new Parameters( this );
-
-		const THREE = ScriptableNodeResources.get( 'THREE' );
-		const TSL = ScriptableNodeResources.get( 'TSL' );
-
-		const method = this.getMethod();
-		const params = [ parameters, this._local, ScriptableNodeResources, refresh, setOutput, THREE, TSL ];
-
-		this._object = method( ...params );
-
-		const layout = this._object.layout;
-
-		if ( layout ) {
-
-			if ( layout.cache === false ) {
-
-				this._local.clear();
-
-			}
-
-			// default output
-			this._output.outputType = layout.outputType || null;
-
-			if ( Array.isArray( layout.elements ) ) {
-
-				for ( const element of layout.elements ) {
-
-					const id = element.id || element.name;
-
-					if ( element.inputType ) {
-
-						if ( this.getParameter( id ) === undefined ) this.setParameter( id, null );
-
-						this.getParameter( id ).inputType = element.inputType;
-
-					}
-
-					if ( element.outputType ) {
-
-						if ( this.getOutput( id ) === undefined ) this.setOutput( id, null );
-
-						this.getOutput( id ).outputType = element.outputType;
-
-					}
-
-				}
-
-			}
-
-		}
-
-		return this._object;
-
-	}
-
-	deserialize( data ) {
-
-		super.deserialize( data );
-
-		for ( const name in this.parameters ) {
-
-			let valueNode = this.parameters[ name ];
-
-			if ( valueNode.isScriptableNode ) valueNode = valueNode.getDefaultOutput();
-
-			valueNode.events.addEventListener( 'refresh', this.onRefresh );
-
-		}
-
-	}
-
-	/**
-	 * Returns the layout of the script.
-	 *
-	 * @return {Object} The script's layout.
-	 */
-	getLayout() {
-
-		return this.getObject().layout;
-
-	}
-
-	/**
-	 * Returns default node output of the script.
-	 *
-	 * @return {Node} The default node output.
-	 */
-	getDefaultOutputNode() {
-
-		const output = this.getDefaultOutput().value;
-
-		if ( output && output.isNode ) {
-
-			return output;
-
-		}
-
-		return float();
-
-	}
-
-	/**
-	 * Returns default output of the script.
-	 *
-	 * @return {ScriptableValueNode} The default output.
-	 */
-	getDefaultOutput()	{
-
-		return this._exec()._output;
-
-	}
-
-	/**
-	 * Returns a function created from the node's script.
-	 *
-	 * @return {Function} The function representing the node's code.
-	 */
-	getMethod() {
-
-		if ( this.needsUpdate ) this.dispose();
-		if ( this._method !== null ) return this._method;
-
-		//
-
-		const parametersProps = [ 'parameters', 'local', 'global', 'refresh', 'setOutput', 'THREE', 'TSL' ];
-		const interfaceProps = [ 'layout', 'init', 'main', 'dispose' ];
-
-		const properties = interfaceProps.join( ', ' );
-		const declarations = 'var ' + properties + '; var output = {};\n';
-		const returns = '\nreturn { ...output, ' + properties + ' };';
-
-		const code = declarations + this.codeNode.code + returns;
-
-		//
-
-		this._method = new Function( ...parametersProps, code );
-
-		return this._method;
-
-	}
-
-	/**
-	 * Frees all internal resources.
-	 */
-	dispose() {
-
-		if ( this._method === null ) return;
-
-		if ( this._object && typeof this._object.dispose === 'function' ) {
-
-			this._object.dispose();
-
-		}
-
-		this._method = null;
-		this._object = null;
-		this._source = null;
-		this._value = null;
-		this._needsOutputUpdate = true;
-		this._output.value = null;
-		this._outputs = {};
-
-	}
-
-	setup() {
-
-		return this.getDefaultOutputNode();
-
-	}
-
-	getCacheKey( force ) {
-
-		const values = [ hashString( this.source ), this.getDefaultOutputNode().getCacheKey( force ) ];
-
-		for ( const param in this.parameters ) {
-
-			values.push( this.parameters[ param ].getCacheKey( force ) );
-
-		}
-
-		return hashArray( values );
-
-	}
-
-	set needsUpdate( value ) {
-
-		if ( value === true ) this.dispose();
-
-	}
-
-	get needsUpdate() {
-
-		return this.source !== this._source;
-
-	}
-
-	/**
-	 * Executes the `main` function of the script.
-	 *
-	 * @private
-	 * @return {ScriptableNode} A reference to this node.
-	 */
-	_exec()	{
-
-		if ( this.codeNode === null ) return this;
-
-		if ( this._needsOutputUpdate === true ) {
-
-			this._value = this.call( 'main' );
-
-			this._needsOutputUpdate = false;
-
-		}
-
-		this._output.value = this._value;
-
-		return this;
-
-	}
-
-	/**
-	 * Executes the refresh.
-	 *
-	 * @private
-	 */
-	_refresh() {
-
-		this.needsUpdate = true;
-
-		this._exec();
-
-		this._output.refresh();
-
-	}
-
-}
-
-export default ScriptableNode;
-
-/**
- * TSL function for creating a scriptable node.
- *
- * @tsl
- * @function
- * @param {CodeNode} [codeNode] - The code node.
- * @param {?Object} [parameters={}] - The parameters definition.
- * @returns {ScriptableNode}
- */
-export const scriptable = /*@__PURE__*/ nodeProxy( ScriptableNode ).setParameterLength( 1, 2 );

+ 0 - 253
src/nodes/code/ScriptableValueNode.js

@@ -1,253 +0,0 @@
-import Node from '../core/Node.js';
-import { arrayBufferToBase64, base64ToArrayBuffer } from '../core/NodeUtils.js';
-import { nodeProxy, float } from '../tsl/TSLBase.js';
-
-import { EventDispatcher } from '../../core/EventDispatcher.js';
-
-/**
- * `ScriptableNode` uses this class to manage script inputs and outputs.
- *
- * @augments Node
- */
-class ScriptableValueNode extends Node {
-
-	static get type() {
-
-		return 'ScriptableValueNode';
-
-	}
-
-	/**
-	 * Constructs a new scriptable node.
-	 *
-	 * @param {any} [value=null] - The value.
-	 */
-	constructor( value = null ) {
-
-		super();
-
-		/**
-		 * A reference to the value.
-		 *
-		 * @private
-		 * @default null
-		 */
-		this._value = value;
-
-		/**
-		 * Depending on the type of `_value`, this property might cache parsed data.
-		 *
-		 * @private
-		 * @default null
-		 */
-		this._cache = null;
-
-		/**
-		 * If this node represents an input, this property represents the input type.
-		 *
-		 * @type {?string}
-		 * @default null
-		 */
-		this.inputType = null;
-
-		/**
-		 * If this node represents an output, this property represents the output type.
-		 *
-		 * @type {?string}
-		 * @default null
-		 */
-		this.outputType = null;
-
-		/**
-		 * An event dispatcher for managing events.
-		 *
-		 * @type {EventDispatcher}
-		 */
-		this.events = new EventDispatcher();
-
-		/**
-		 * This flag can be used for type testing.
-		 *
-		 * @type {boolean}
-		 * @readonly
-		 * @default true
-		 */
-		this.isScriptableValueNode = true;
-
-	}
-
-	/**
-	 * Whether this node represents an output or not.
-	 *
-	 * @type {boolean}
-	 * @readonly
-	 * @default true
-	 */
-	get isScriptableOutputNode() {
-
-		return this.outputType !== null;
-
-	}
-
-	set value( val ) {
-
-		if ( this._value === val ) return;
-
-		if ( this._cache && this.inputType === 'URL' && this.value.value instanceof ArrayBuffer ) {
-
-			URL.revokeObjectURL( this._cache );
-
-			this._cache = null;
-
-		}
-
-		this._value = val;
-
-		this.events.dispatchEvent( { type: 'change' } );
-
-		this.refresh();
-
-	}
-
-	/**
-	 * The node's value.
-	 *
-	 * @type {any}
-	 */
-	get value() {
-
-		return this._value;
-
-	}
-
-	/**
-	 * Dispatches the `refresh` event.
-	 */
-	refresh() {
-
-		this.events.dispatchEvent( { type: 'refresh' } );
-
-	}
-
-	/**
-	 * The `value` property usually represents a node or even binary data in form of array buffers.
-	 * In this case, this method tries to return the actual value behind the complex type.
-	 *
-	 * @return {any} The value.
-	 */
-	getValue() {
-
-		const value = this.value;
-
-		if ( value && this._cache === null && this.inputType === 'URL' && value.value instanceof ArrayBuffer ) {
-
-			this._cache = URL.createObjectURL( new Blob( [ value.value ] ) );
-
-		} else if ( value && value.value !== null && value.value !== undefined && (
-			( ( this.inputType === 'URL' || this.inputType === 'String' ) && typeof value.value === 'string' ) ||
-			( this.inputType === 'Number' && typeof value.value === 'number' ) ||
-			( this.inputType === 'Vector2' && value.value.isVector2 ) ||
-			( this.inputType === 'Vector3' && value.value.isVector3 ) ||
-			( this.inputType === 'Vector4' && value.value.isVector4 ) ||
-			( this.inputType === 'Color' && value.value.isColor ) ||
-			( this.inputType === 'Matrix3' && value.value.isMatrix3 ) ||
-			( this.inputType === 'Matrix4' && value.value.isMatrix4 )
-		) ) {
-
-			return value.value;
-
-		}
-
-		return this._cache || value;
-
-	}
-
-	/**
-	 * Overwritten since the node type is inferred from the value.
-	 *
-	 * @param {NodeBuilder} builder - The current node builder.
-	 * @return {string} The node type.
-	 */
-	getNodeType( builder ) {
-
-		return this.value && this.value.isNode ? this.value.getNodeType( builder ) : 'float';
-
-	}
-
-	setup() {
-
-		return this.value && this.value.isNode ? this.value : float();
-
-	}
-
-	serialize( data ) {
-
-		super.serialize( data );
-
-		if ( this.value !== null ) {
-
-			if ( this.inputType === 'ArrayBuffer' ) {
-
-				data.value = arrayBufferToBase64( this.value );
-
-			} else {
-
-				data.value = this.value ? this.value.toJSON( data.meta ).uuid : null;
-
-			}
-
-		} else {
-
-			data.value = null;
-
-		}
-
-		data.inputType = this.inputType;
-		data.outputType = this.outputType;
-
-	}
-
-	deserialize( data ) {
-
-		super.deserialize( data );
-
-		let value = null;
-
-		if ( data.value !== null ) {
-
-			if ( data.inputType === 'ArrayBuffer' ) {
-
-				value = base64ToArrayBuffer( data.value );
-
-			} else if ( data.inputType === 'Texture' ) {
-
-				value = data.meta.textures[ data.value ];
-
-			} else {
-
-				value = data.meta.nodes[ data.value ] || null;
-
-			}
-
-		}
-
-		this.value = value;
-
-		this.inputType = data.inputType;
-		this.outputType = data.outputType;
-
-	}
-
-}
-
-export default ScriptableValueNode;
-
-/**
- * TSL function for creating a scriptable value node.
- *
- * @tsl
- * @function
- * @param {any} [value] - The value.
- * @returns {ScriptableValueNode}
- */
-export const scriptableValue = /*@__PURE__*/ nodeProxy( ScriptableValueNode ).setParameterLength( 1 );

粤ICP备19079148号