168 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			168 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								import Node, { addNodeClass } from '../core/Node.js';
							 | 
						||
| 
								 | 
							
								import { arrayBufferToBase64, base64ToArrayBuffer } from '../core/NodeUtils.js';
							 | 
						||
| 
								 | 
							
								import { addNodeElement, nodeProxy, float } from '../shadernode/ShaderNode.js';
							 | 
						||
| 
								 | 
							
								import { EventDispatcher } from 'three';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class ScriptableValueNode extends Node {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									constructor( value = null ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										super();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this._value = value;
							 | 
						||
| 
								 | 
							
										this._cache = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.inputType = null;
							 | 
						||
| 
								 | 
							
										this.outpuType = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.events = new EventDispatcher();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.isScriptableValueNode = 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();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									get value() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return this._value;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									refresh() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.events.dispatchEvent( { type: 'refresh' } );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									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;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									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;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export const scriptableValue = nodeProxy( ScriptableValueNode );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								addNodeElement( 'scriptableValue', scriptableValue );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								addNodeClass( 'ScriptableValueNode', ScriptableValueNode );
							 |