three 基础库
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.

219 lines
3.6 KiB

2 years ago
import { MathUtils } from '../../../../build/three.module.js';
class Node {
constructor( type ) {
this.uuid = MathUtils.generateUUID();
this.name = '';
this.type = type;
this.userData = {};
}
analyze( builder, settings = {} ) {
builder.analyzing = true;
this.build( builder.addFlow( settings.slot, settings.cache, settings.context ), 'v4' );
builder.clearVertexNodeCode();
builder.clearFragmentNodeCode();
builder.removeFlow();
builder.analyzing = false;
}
analyzeAndFlow( builder, output, settings = {} ) {
this.analyze( builder, settings );
return this.flow( builder, output, settings );
}
flow( builder, output, settings = {} ) {
builder.addFlow( settings.slot, settings.cache, settings.context );
const flow = {};
flow.result = this.build( builder, output );
flow.code = builder.clearNodeCode();
flow.extra = builder.context.extra;
builder.removeFlow();
return flow;
}
build( builder, output, uuid ) {
output = output || this.getType( builder, output );
const data = builder.getNodeData( uuid || this );
if ( builder.analyzing ) {
this.appendDepsNode( builder, data, output );
}
if ( builder.nodes.indexOf( this ) === - 1 ) {
builder.nodes.push( this );
}
if ( this.updateFrame !== undefined && builder.updaters.indexOf( this ) === - 1 ) {
builder.updaters.push( this );
}
return this.generate( builder, output, uuid );
}
generate( /* builder, output, uuid, type, ns */ ) {
// This method needs to be implemented in subclasses
}
getHash() {
let hash = '{';
let prop, obj;
for ( prop in this ) {
obj = this[ prop ];
if ( obj instanceof Node ) {
hash += '"' + prop + '":' + obj.getHash() + ',';
}
}
if ( this.hashProperties ) {
for ( let i = 0; i < this.hashProperties.length; i ++ ) {
prop = this.hashProperties[ i ];
obj = this[ prop ];
hash += '"' + prop + '":"' + String( obj ) + '",';
}
}
hash += '"id":"' + this.uuid + '"}';
return hash;
}
appendDepsNode( builder, data, output ) {
data.deps = ( data.deps || 0 ) + 1;
const outputLen = builder.getTypeLength( output );
if ( outputLen > ( data.outputMax || 0 ) || this.getType( builder, output ) ) {
data.outputMax = outputLen;
data.output = output;
}
}
setName( name ) {
this.name = name;
return this;
}
getName( /* builder */ ) {
return this.name;
}
getType( builder, output ) {
return output === 'sampler2D' || output === 'samplerCube' ? output : this.type;
}
getJSONNode( meta ) {
const isRootObject = ( meta === undefined || typeof meta === 'string' );
if ( ! isRootObject && meta.nodes[ this.uuid ] !== undefined ) {
return meta.nodes[ this.uuid ];
}
}
copy( source ) {
if ( source.name !== undefined ) this.name = source.name;
if ( source.userData !== undefined ) this.userData = JSON.parse( JSON.stringify( source.userData ) );
return this;
}
createJSONNode( meta ) {
const isRootObject = ( meta === undefined || typeof meta === 'string' );
const data = {};
if ( typeof this.nodeType !== 'string' ) throw new Error( 'Node does not allow serialization.' );
data.uuid = this.uuid;
data.nodeType = this.nodeType;
if ( this.name !== '' ) data.name = this.name;
if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData;
if ( ! isRootObject ) {
meta.nodes[ this.uuid ] = data;
}
return data;
}
toJSON( meta ) {
return this.getJSONNode( meta ) || this.createJSONNode( meta );
}
}
Node.prototype.isNode = true;
Node.prototype.hashProperties = undefined;
export { Node };