You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
3.2 KiB
168 lines
3.2 KiB
6 months ago
|
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 );
|