添加关照、全局等高线、修改图层问题
This commit is contained in:
128
static/sdk/three/jsm/nodes/core/AssignNode.js
Normal file
128
static/sdk/three/jsm/nodes/core/AssignNode.js
Normal file
@ -0,0 +1,128 @@
|
||||
import { addNodeClass } from '../core/Node.js';
|
||||
import TempNode from '../core/TempNode.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
import { vectorComponents } from '../core/constants.js';
|
||||
|
||||
class AssignNode extends TempNode {
|
||||
|
||||
constructor( targetNode, sourceNode ) {
|
||||
|
||||
super();
|
||||
|
||||
this.targetNode = targetNode;
|
||||
this.sourceNode = sourceNode;
|
||||
|
||||
}
|
||||
|
||||
hasDependencies() {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder, output ) {
|
||||
|
||||
return output !== 'void' ? this.targetNode.getNodeType( builder ) : 'void';
|
||||
|
||||
}
|
||||
|
||||
needsSplitAssign( builder ) {
|
||||
|
||||
const { targetNode } = this;
|
||||
|
||||
if ( builder.isAvailable( 'swizzleAssign' ) === false && targetNode.isSplitNode && targetNode.components.length > 1 ) {
|
||||
|
||||
const targetLength = builder.getTypeLength( targetNode.node.getNodeType( builder ) );
|
||||
const assignDiferentVector = vectorComponents.join( '' ).slice( 0, targetLength ) !== targetNode.components;
|
||||
|
||||
return assignDiferentVector;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
const { targetNode, sourceNode } = this;
|
||||
|
||||
const needsSplitAssign = this.needsSplitAssign( builder );
|
||||
|
||||
const targetType = targetNode.getNodeType( builder );
|
||||
|
||||
const target = targetNode.context( { assign: true } ).build( builder );
|
||||
const source = sourceNode.build( builder, targetType );
|
||||
|
||||
const sourceType = sourceNode.getNodeType( builder );
|
||||
|
||||
const nodeData = builder.getDataFromNode( this );
|
||||
|
||||
//
|
||||
|
||||
let snippet;
|
||||
|
||||
if ( nodeData.initialized === true ) {
|
||||
|
||||
if ( output !== 'void' ) {
|
||||
|
||||
snippet = target;
|
||||
|
||||
}
|
||||
|
||||
} else if ( needsSplitAssign ) {
|
||||
|
||||
const sourceVar = builder.getVarFromNode( this, null, targetType );
|
||||
const sourceProperty = builder.getPropertyName( sourceVar );
|
||||
|
||||
builder.addLineFlowCode( `${ sourceProperty } = ${ source }` );
|
||||
|
||||
const targetRoot = targetNode.node.context( { assign: true } ).build( builder );
|
||||
|
||||
for ( let i = 0; i < targetNode.components.length; i ++ ) {
|
||||
|
||||
const component = targetNode.components[ i ];
|
||||
|
||||
builder.addLineFlowCode( `${ targetRoot }.${ component } = ${ sourceProperty }[ ${ i } ]` );
|
||||
|
||||
}
|
||||
|
||||
if ( output !== 'void' ) {
|
||||
|
||||
snippet = target;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
snippet = `${ target } = ${ source }`;
|
||||
|
||||
if ( output === 'void' || sourceType === 'void' ) {
|
||||
|
||||
builder.addLineFlowCode( snippet );
|
||||
|
||||
if ( output !== 'void' ) {
|
||||
|
||||
snippet = target;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
nodeData.initialized = true;
|
||||
|
||||
return builder.format( snippet, targetType, output );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default AssignNode;
|
||||
|
||||
export const assign = nodeProxy( AssignNode );
|
||||
|
||||
addNodeClass( 'AssignNode', AssignNode );
|
||||
|
||||
addNodeElement( 'assign', assign );
|
108
static/sdk/three/jsm/nodes/core/AttributeNode.js
Normal file
108
static/sdk/three/jsm/nodes/core/AttributeNode.js
Normal file
@ -0,0 +1,108 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { varying } from './VaryingNode.js';
|
||||
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class AttributeNode extends Node {
|
||||
|
||||
constructor( attributeName, nodeType = null ) {
|
||||
|
||||
super( nodeType );
|
||||
|
||||
this._attributeName = attributeName;
|
||||
|
||||
}
|
||||
|
||||
isGlobal() {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
getHash( builder ) {
|
||||
|
||||
return this.getAttributeName( builder );
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
let nodeType = super.getNodeType( builder );
|
||||
|
||||
if ( nodeType === null ) {
|
||||
|
||||
const attributeName = this.getAttributeName( builder );
|
||||
|
||||
if ( builder.hasGeometryAttribute( attributeName ) ) {
|
||||
|
||||
const attribute = builder.geometry.getAttribute( attributeName );
|
||||
|
||||
nodeType = builder.getTypeFromAttribute( attribute );
|
||||
|
||||
} else {
|
||||
|
||||
nodeType = 'float';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nodeType;
|
||||
|
||||
}
|
||||
|
||||
setAttributeName( attributeName ) {
|
||||
|
||||
this._attributeName = attributeName;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getAttributeName( /*builder*/ ) {
|
||||
|
||||
return this._attributeName;
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const attributeName = this.getAttributeName( builder );
|
||||
const nodeType = this.getNodeType( builder );
|
||||
const geometryAttribute = builder.hasGeometryAttribute( attributeName );
|
||||
|
||||
if ( geometryAttribute === true ) {
|
||||
|
||||
const attribute = builder.geometry.getAttribute( attributeName );
|
||||
const attributeType = builder.getTypeFromAttribute( attribute );
|
||||
|
||||
const nodeAttribute = builder.getAttribute( attributeName, attributeType );
|
||||
|
||||
if ( builder.shaderStage === 'vertex' ) {
|
||||
|
||||
return builder.format( nodeAttribute.name, attributeType, nodeType );
|
||||
|
||||
} else {
|
||||
|
||||
const nodeVarying = varying( this );
|
||||
|
||||
return nodeVarying.build( builder, nodeType );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
console.warn( `AttributeNode: Vertex attribute "${ attributeName }" not found on geometry.` );
|
||||
|
||||
return builder.generateConst( nodeType );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default AttributeNode;
|
||||
|
||||
export const attribute = ( name, nodeType ) => nodeObject( new AttributeNode( name, nodeType ) );
|
||||
|
||||
addNodeClass( 'AttributeNode', AttributeNode );
|
45
static/sdk/three/jsm/nodes/core/BypassNode.js
Normal file
45
static/sdk/three/jsm/nodes/core/BypassNode.js
Normal file
@ -0,0 +1,45 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class BypassNode extends Node {
|
||||
|
||||
constructor( returnNode, callNode ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isBypassNode = true;
|
||||
|
||||
this.outputNode = returnNode;
|
||||
this.callNode = callNode;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
return this.outputNode.getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const snippet = this.callNode.build( builder, 'void' );
|
||||
|
||||
if ( snippet !== '' ) {
|
||||
|
||||
builder.addLineFlowCode( snippet );
|
||||
|
||||
}
|
||||
|
||||
return this.outputNode.build( builder );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default BypassNode;
|
||||
|
||||
export const bypass = nodeProxy( BypassNode );
|
||||
|
||||
addNodeElement( 'bypass', bypass );
|
||||
|
||||
addNodeClass( 'BypassNode', BypassNode );
|
49
static/sdk/three/jsm/nodes/core/CacheNode.js
Normal file
49
static/sdk/three/jsm/nodes/core/CacheNode.js
Normal file
@ -0,0 +1,49 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import NodeCache from './NodeCache.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class CacheNode extends Node {
|
||||
|
||||
constructor( node, cache = new NodeCache() ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isCacheNode = true;
|
||||
|
||||
this.node = node;
|
||||
this.cache = cache;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
return this.node.getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
build( builder, ...params ) {
|
||||
|
||||
const previousCache = builder.getCache();
|
||||
const cache = this.cache || builder.globalCache;
|
||||
|
||||
builder.setCache( cache );
|
||||
|
||||
const data = this.node.build( builder, ...params );
|
||||
|
||||
builder.setCache( previousCache );
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default CacheNode;
|
||||
|
||||
export const cache = nodeProxy( CacheNode );
|
||||
export const globalCache = ( node ) => cache( node, null );
|
||||
|
||||
addNodeElement( 'cache', cache );
|
||||
addNodeElement( 'globalCache', globalCache );
|
||||
|
||||
addNodeClass( 'CacheNode', CacheNode );
|
32
static/sdk/three/jsm/nodes/core/ConstNode.js
Normal file
32
static/sdk/three/jsm/nodes/core/ConstNode.js
Normal file
@ -0,0 +1,32 @@
|
||||
import InputNode from './InputNode.js';
|
||||
import { addNodeClass } from './Node.js';
|
||||
|
||||
class ConstNode extends InputNode {
|
||||
|
||||
constructor( value, nodeType = null ) {
|
||||
|
||||
super( value, nodeType );
|
||||
|
||||
this.isConstNode = true;
|
||||
|
||||
}
|
||||
|
||||
generateConst( builder ) {
|
||||
|
||||
return builder.generateConst( this.getNodeType( builder ), this.value );
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
const type = this.getNodeType( builder );
|
||||
|
||||
return builder.format( this.generateConst( builder ), type, output );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ConstNode;
|
||||
|
||||
addNodeClass( 'ConstNode', ConstNode );
|
61
static/sdk/three/jsm/nodes/core/ContextNode.js
Normal file
61
static/sdk/three/jsm/nodes/core/ContextNode.js
Normal file
@ -0,0 +1,61 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class ContextNode extends Node {
|
||||
|
||||
constructor( node, context = {} ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isContextNode = true;
|
||||
|
||||
this.node = node;
|
||||
this.context = context;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
return this.node.getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
const previousContext = builder.getContext();
|
||||
|
||||
builder.setContext( { ...builder.context, ...this.context } );
|
||||
|
||||
const node = this.node.build( builder );
|
||||
|
||||
builder.setContext( previousContext );
|
||||
|
||||
return node;
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
const previousContext = builder.getContext();
|
||||
|
||||
builder.setContext( { ...builder.context, ...this.context } );
|
||||
|
||||
const snippet = this.node.build( builder, output );
|
||||
|
||||
builder.setContext( previousContext );
|
||||
|
||||
return snippet;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ContextNode;
|
||||
|
||||
export const context = nodeProxy( ContextNode );
|
||||
export const label = ( node, name ) => context( node, { label: name } );
|
||||
|
||||
addNodeElement( 'context', context );
|
||||
addNodeElement( 'label', label );
|
||||
|
||||
addNodeClass( 'ContextNode', ContextNode );
|
66
static/sdk/three/jsm/nodes/core/IndexNode.js
Normal file
66
static/sdk/three/jsm/nodes/core/IndexNode.js
Normal file
@ -0,0 +1,66 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { varying } from './VaryingNode.js';
|
||||
import { nodeImmutable } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class IndexNode extends Node {
|
||||
|
||||
constructor( scope ) {
|
||||
|
||||
super( 'uint' );
|
||||
|
||||
this.scope = scope;
|
||||
|
||||
this.isInstanceIndexNode = true;
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const nodeType = this.getNodeType( builder );
|
||||
const scope = this.scope;
|
||||
|
||||
let propertyName;
|
||||
|
||||
if ( scope === IndexNode.VERTEX ) {
|
||||
|
||||
propertyName = builder.getVertexIndex();
|
||||
|
||||
} else if ( scope === IndexNode.INSTANCE ) {
|
||||
|
||||
propertyName = builder.getInstanceIndex();
|
||||
|
||||
} else {
|
||||
|
||||
throw new Error( 'THREE.IndexNode: Unknown scope: ' + scope );
|
||||
|
||||
}
|
||||
|
||||
let output;
|
||||
|
||||
if ( builder.shaderStage === 'vertex' || builder.shaderStage === 'compute' ) {
|
||||
|
||||
output = propertyName;
|
||||
|
||||
} else {
|
||||
|
||||
const nodeVarying = varying( this );
|
||||
|
||||
output = nodeVarying.build( builder, nodeType );
|
||||
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
IndexNode.VERTEX = 'vertex';
|
||||
IndexNode.INSTANCE = 'instance';
|
||||
|
||||
export default IndexNode;
|
||||
|
||||
export const vertexIndex = nodeImmutable( IndexNode, IndexNode.VERTEX );
|
||||
export const instanceIndex = nodeImmutable( IndexNode, IndexNode.INSTANCE );
|
||||
|
||||
addNodeClass( 'IndexNode', IndexNode );
|
83
static/sdk/three/jsm/nodes/core/InputNode.js
Normal file
83
static/sdk/three/jsm/nodes/core/InputNode.js
Normal file
@ -0,0 +1,83 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { getValueType, getValueFromType, arrayBufferToBase64 } from './NodeUtils.js';
|
||||
|
||||
class InputNode extends Node {
|
||||
|
||||
constructor( value, nodeType = null ) {
|
||||
|
||||
super( nodeType );
|
||||
|
||||
this.isInputNode = true;
|
||||
|
||||
this.value = value;
|
||||
this.precision = null;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( /*builder*/ ) {
|
||||
|
||||
if ( this.nodeType === null ) {
|
||||
|
||||
return getValueType( this.value );
|
||||
|
||||
}
|
||||
|
||||
return this.nodeType;
|
||||
|
||||
}
|
||||
|
||||
getInputType( builder ) {
|
||||
|
||||
return this.getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
setPrecision( precision ) {
|
||||
|
||||
this.precision = precision;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
serialize( data ) {
|
||||
|
||||
super.serialize( data );
|
||||
|
||||
data.value = this.value;
|
||||
|
||||
if ( this.value && this.value.toArray ) data.value = this.value.toArray();
|
||||
|
||||
data.valueType = getValueType( this.value );
|
||||
data.nodeType = this.nodeType;
|
||||
|
||||
if ( data.valueType === 'ArrayBuffer' ) data.value = arrayBufferToBase64( data.value );
|
||||
|
||||
data.precision = this.precision;
|
||||
|
||||
}
|
||||
|
||||
deserialize( data ) {
|
||||
|
||||
super.deserialize( data );
|
||||
|
||||
this.nodeType = data.nodeType;
|
||||
this.value = Array.isArray( data.value ) ? getValueFromType( data.valueType, ...data.value ) : data.value;
|
||||
|
||||
this.precision = data.precision || null;
|
||||
|
||||
if ( this.value && this.value.fromArray ) this.value = this.value.fromArray( data.value );
|
||||
|
||||
}
|
||||
|
||||
generate( /*builder, output*/ ) {
|
||||
|
||||
console.warn( 'Abstract function.' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default InputNode;
|
||||
|
||||
addNodeClass( 'InputNode', InputNode );
|
17
static/sdk/three/jsm/nodes/core/LightingModel.js
Normal file
17
static/sdk/three/jsm/nodes/core/LightingModel.js
Normal file
@ -0,0 +1,17 @@
|
||||
class LightingModel {
|
||||
|
||||
start( /*input, stack, builder*/ ) { }
|
||||
|
||||
finish( /*input, stack, builder*/ ) { }
|
||||
|
||||
direct( /*input, stack, builder*/ ) { }
|
||||
|
||||
indirectDiffuse( /*input, stack, builder*/ ) { }
|
||||
|
||||
indirectSpecular( /*input, stack, builder*/ ) { }
|
||||
|
||||
ambientOcclusion( /*input, stack, builder*/ ) { }
|
||||
|
||||
}
|
||||
|
||||
export default LightingModel;
|
552
static/sdk/three/jsm/nodes/core/Node.js
Normal file
552
static/sdk/three/jsm/nodes/core/Node.js
Normal file
@ -0,0 +1,552 @@
|
||||
import { EventDispatcher } from 'three';
|
||||
import { NodeUpdateType } from './constants.js';
|
||||
import { getNodeChildren, getCacheKey } from './NodeUtils.js';
|
||||
import { MathUtils } from 'three';
|
||||
|
||||
const NodeClasses = new Map();
|
||||
|
||||
let _nodeId = 0;
|
||||
|
||||
class Node extends EventDispatcher {
|
||||
|
||||
constructor( nodeType = null ) {
|
||||
|
||||
super();
|
||||
|
||||
this.nodeType = nodeType;
|
||||
|
||||
this.updateType = NodeUpdateType.NONE;
|
||||
this.updateBeforeType = NodeUpdateType.NONE;
|
||||
|
||||
this.uuid = MathUtils.generateUUID();
|
||||
|
||||
this.version = 0;
|
||||
|
||||
this._cacheKey = null;
|
||||
this._cacheKeyVersion = 0;
|
||||
|
||||
this.isNode = true;
|
||||
|
||||
Object.defineProperty( this, 'id', { value: _nodeId ++ } );
|
||||
|
||||
}
|
||||
|
||||
set needsUpdate( value ) {
|
||||
|
||||
if ( value === true ) {
|
||||
|
||||
this.version ++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
get type() {
|
||||
|
||||
return this.constructor.type;
|
||||
|
||||
}
|
||||
|
||||
onUpdate( callback, updateType ) {
|
||||
|
||||
this.updateType = updateType;
|
||||
this.update = callback.bind( this.getSelf() );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
onFrameUpdate( callback ) {
|
||||
|
||||
return this.onUpdate( callback, NodeUpdateType.FRAME );
|
||||
|
||||
}
|
||||
|
||||
onRenderUpdate( callback ) {
|
||||
|
||||
return this.onUpdate( callback, NodeUpdateType.RENDER );
|
||||
|
||||
}
|
||||
|
||||
onObjectUpdate( callback ) {
|
||||
|
||||
return this.onUpdate( callback, NodeUpdateType.OBJECT );
|
||||
|
||||
}
|
||||
|
||||
onReference( callback ) {
|
||||
|
||||
this.updateReference = callback.bind( this.getSelf() );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getSelf() {
|
||||
|
||||
// Returns non-node object.
|
||||
|
||||
return this.self || this;
|
||||
|
||||
}
|
||||
|
||||
updateReference( /*state*/ ) {
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
isGlobal( /*builder*/ ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
* getChildren() {
|
||||
|
||||
for ( const { childNode } of getNodeChildren( this ) ) {
|
||||
|
||||
yield childNode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.dispatchEvent( { type: 'dispose' } );
|
||||
|
||||
}
|
||||
|
||||
traverse( callback ) {
|
||||
|
||||
callback( this );
|
||||
|
||||
for ( const childNode of this.getChildren() ) {
|
||||
|
||||
childNode.traverse( callback );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getCacheKey( force = false ) {
|
||||
|
||||
force = force || this.version !== this._cacheKeyVersion;
|
||||
|
||||
if ( force === true || this._cacheKey === null ) {
|
||||
|
||||
this._cacheKey = getCacheKey( this, force );
|
||||
this._cacheKeyVersion = this.version;
|
||||
|
||||
}
|
||||
|
||||
return this._cacheKey;
|
||||
|
||||
}
|
||||
|
||||
getHash( /*builder*/ ) {
|
||||
|
||||
return this.uuid;
|
||||
|
||||
}
|
||||
|
||||
getUpdateType() {
|
||||
|
||||
return this.updateType;
|
||||
|
||||
}
|
||||
|
||||
getUpdateBeforeType() {
|
||||
|
||||
return this.updateBeforeType;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
const nodeProperties = builder.getNodeProperties( this );
|
||||
|
||||
if ( nodeProperties.outputNode ) {
|
||||
|
||||
return nodeProperties.outputNode.getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
return this.nodeType;
|
||||
|
||||
}
|
||||
|
||||
getShared( builder ) {
|
||||
|
||||
const hash = this.getHash( builder );
|
||||
const nodeFromHash = builder.getNodeFromHash( hash );
|
||||
|
||||
return nodeFromHash || this;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
const nodeProperties = builder.getNodeProperties( this );
|
||||
|
||||
for ( const childNode of this.getChildren() ) {
|
||||
|
||||
nodeProperties[ '_node' + childNode.id ] = childNode;
|
||||
|
||||
}
|
||||
|
||||
// return a outputNode if exists
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
construct( builder ) { // @deprecated, r157
|
||||
|
||||
console.warn( 'THREE.Node: construct() is deprecated. Use setup() instead.' );
|
||||
|
||||
return this.setup( builder );
|
||||
|
||||
}
|
||||
|
||||
increaseUsage( builder ) {
|
||||
|
||||
const nodeData = builder.getDataFromNode( this );
|
||||
nodeData.usageCount = nodeData.usageCount === undefined ? 1 : nodeData.usageCount + 1;
|
||||
|
||||
return nodeData.usageCount;
|
||||
|
||||
}
|
||||
|
||||
analyze( builder ) {
|
||||
|
||||
const usageCount = this.increaseUsage( builder );
|
||||
|
||||
if ( usageCount === 1 ) {
|
||||
|
||||
// node flow children
|
||||
|
||||
const nodeProperties = builder.getNodeProperties( this );
|
||||
|
||||
for ( const childNode of Object.values( nodeProperties ) ) {
|
||||
|
||||
if ( childNode && childNode.isNode === true ) {
|
||||
|
||||
childNode.build( builder );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
const { outputNode } = builder.getNodeProperties( this );
|
||||
|
||||
if ( outputNode && outputNode.isNode === true ) {
|
||||
|
||||
return outputNode.build( builder, output );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateBefore( /*frame*/ ) {
|
||||
|
||||
console.warn( 'Abstract function.' );
|
||||
|
||||
}
|
||||
|
||||
update( /*frame*/ ) {
|
||||
|
||||
console.warn( 'Abstract function.' );
|
||||
|
||||
}
|
||||
|
||||
build( builder, output = null ) {
|
||||
|
||||
const refNode = this.getShared( builder );
|
||||
|
||||
if ( this !== refNode ) {
|
||||
|
||||
return refNode.build( builder, output );
|
||||
|
||||
}
|
||||
|
||||
builder.addNode( this );
|
||||
builder.addChain( this );
|
||||
|
||||
/* Build stages expected results:
|
||||
- "setup" -> Node
|
||||
- "analyze" -> null
|
||||
- "generate" -> String
|
||||
*/
|
||||
let result = null;
|
||||
|
||||
const buildStage = builder.getBuildStage();
|
||||
|
||||
if ( buildStage === 'setup' ) {
|
||||
|
||||
this.updateReference( builder );
|
||||
|
||||
const properties = builder.getNodeProperties( this );
|
||||
|
||||
if ( properties.initialized !== true || builder.context.tempRead === false ) {
|
||||
|
||||
const stackNodesBeforeSetup = builder.stack.nodes.length;
|
||||
|
||||
properties.initialized = true;
|
||||
properties.outputNode = this.setup( builder );
|
||||
|
||||
if ( properties.outputNode !== null && builder.stack.nodes.length !== stackNodesBeforeSetup ) {
|
||||
|
||||
properties.outputNode = builder.stack;
|
||||
|
||||
}
|
||||
|
||||
for ( const childNode of Object.values( properties ) ) {
|
||||
|
||||
if ( childNode && childNode.isNode === true ) {
|
||||
|
||||
childNode.build( builder );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( buildStage === 'analyze' ) {
|
||||
|
||||
this.analyze( builder );
|
||||
|
||||
} else if ( buildStage === 'generate' ) {
|
||||
|
||||
const isGenerateOnce = this.generate.length === 1;
|
||||
|
||||
if ( isGenerateOnce ) {
|
||||
|
||||
const type = this.getNodeType( builder );
|
||||
const nodeData = builder.getDataFromNode( this );
|
||||
|
||||
result = nodeData.snippet;
|
||||
|
||||
if ( result === undefined /*|| builder.context.tempRead === false*/ ) {
|
||||
|
||||
result = this.generate( builder ) || '';
|
||||
|
||||
nodeData.snippet = result;
|
||||
|
||||
}
|
||||
|
||||
result = builder.format( result, type, output );
|
||||
|
||||
} else {
|
||||
|
||||
result = this.generate( builder, output ) || '';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
builder.removeChain( this );
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
getSerializeChildren() {
|
||||
|
||||
return getNodeChildren( this );
|
||||
|
||||
}
|
||||
|
||||
serialize( json ) {
|
||||
|
||||
const nodeChildren = this.getSerializeChildren();
|
||||
|
||||
const inputNodes = {};
|
||||
|
||||
for ( const { property, index, childNode } of nodeChildren ) {
|
||||
|
||||
if ( index !== undefined ) {
|
||||
|
||||
if ( inputNodes[ property ] === undefined ) {
|
||||
|
||||
inputNodes[ property ] = Number.isInteger( index ) ? [] : {};
|
||||
|
||||
}
|
||||
|
||||
inputNodes[ property ][ index ] = childNode.toJSON( json.meta ).uuid;
|
||||
|
||||
} else {
|
||||
|
||||
inputNodes[ property ] = childNode.toJSON( json.meta ).uuid;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( Object.keys( inputNodes ).length > 0 ) {
|
||||
|
||||
json.inputNodes = inputNodes;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
deserialize( json ) {
|
||||
|
||||
if ( json.inputNodes !== undefined ) {
|
||||
|
||||
const nodes = json.meta.nodes;
|
||||
|
||||
for ( const property in json.inputNodes ) {
|
||||
|
||||
if ( Array.isArray( json.inputNodes[ property ] ) ) {
|
||||
|
||||
const inputArray = [];
|
||||
|
||||
for ( const uuid of json.inputNodes[ property ] ) {
|
||||
|
||||
inputArray.push( nodes[ uuid ] );
|
||||
|
||||
}
|
||||
|
||||
this[ property ] = inputArray;
|
||||
|
||||
} else if ( typeof json.inputNodes[ property ] === 'object' ) {
|
||||
|
||||
const inputObject = {};
|
||||
|
||||
for ( const subProperty in json.inputNodes[ property ] ) {
|
||||
|
||||
const uuid = json.inputNodes[ property ][ subProperty ];
|
||||
|
||||
inputObject[ subProperty ] = nodes[ uuid ];
|
||||
|
||||
}
|
||||
|
||||
this[ property ] = inputObject;
|
||||
|
||||
} else {
|
||||
|
||||
const uuid = json.inputNodes[ property ];
|
||||
|
||||
this[ property ] = nodes[ uuid ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
toJSON( meta ) {
|
||||
|
||||
const { uuid, type } = this;
|
||||
const isRoot = ( meta === undefined || typeof meta === 'string' );
|
||||
|
||||
if ( isRoot ) {
|
||||
|
||||
meta = {
|
||||
textures: {},
|
||||
images: {},
|
||||
nodes: {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// serialize
|
||||
|
||||
let data = meta.nodes[ uuid ];
|
||||
|
||||
if ( data === undefined ) {
|
||||
|
||||
data = {
|
||||
uuid,
|
||||
type,
|
||||
meta,
|
||||
metadata: {
|
||||
version: 4.6,
|
||||
type: 'Node',
|
||||
generator: 'Node.toJSON'
|
||||
}
|
||||
};
|
||||
|
||||
if ( isRoot !== true ) meta.nodes[ data.uuid ] = data;
|
||||
|
||||
this.serialize( data );
|
||||
|
||||
delete data.meta;
|
||||
|
||||
}
|
||||
|
||||
// TODO: Copied from Object3D.toJSON
|
||||
|
||||
function extractFromCache( cache ) {
|
||||
|
||||
const values = [];
|
||||
|
||||
for ( const key in cache ) {
|
||||
|
||||
const data = cache[ key ];
|
||||
delete data.metadata;
|
||||
values.push( data );
|
||||
|
||||
}
|
||||
|
||||
return values;
|
||||
|
||||
}
|
||||
|
||||
if ( isRoot ) {
|
||||
|
||||
const textures = extractFromCache( meta.textures );
|
||||
const images = extractFromCache( meta.images );
|
||||
const nodes = extractFromCache( meta.nodes );
|
||||
|
||||
if ( textures.length > 0 ) data.textures = textures;
|
||||
if ( images.length > 0 ) data.images = images;
|
||||
if ( nodes.length > 0 ) data.nodes = nodes;
|
||||
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Node;
|
||||
|
||||
export function addNodeClass( type, nodeClass ) {
|
||||
|
||||
if ( typeof nodeClass !== 'function' || ! type ) throw new Error( `Node class ${ type } is not a class` );
|
||||
if ( NodeClasses.has( type ) ) {
|
||||
|
||||
console.warn( `Redefinition of node class ${ type }` );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
NodeClasses.set( type, nodeClass );
|
||||
nodeClass.type = type;
|
||||
|
||||
}
|
||||
|
||||
export function createNodeFromType( type ) {
|
||||
|
||||
const Class = NodeClasses.get( type );
|
||||
|
||||
if ( Class !== undefined ) {
|
||||
|
||||
return new Class();
|
||||
|
||||
}
|
||||
|
||||
}
|
15
static/sdk/three/jsm/nodes/core/NodeAttribute.js
Normal file
15
static/sdk/three/jsm/nodes/core/NodeAttribute.js
Normal file
@ -0,0 +1,15 @@
|
||||
class NodeAttribute {
|
||||
|
||||
constructor( name, type, node = null ) {
|
||||
|
||||
this.isNodeAttribute = true;
|
||||
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.node = node;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeAttribute;
|
1251
static/sdk/three/jsm/nodes/core/NodeBuilder.js
Normal file
1251
static/sdk/three/jsm/nodes/core/NodeBuilder.js
Normal file
File diff suppressed because it is too large
Load Diff
26
static/sdk/three/jsm/nodes/core/NodeCache.js
Normal file
26
static/sdk/three/jsm/nodes/core/NodeCache.js
Normal file
@ -0,0 +1,26 @@
|
||||
let id = 0;
|
||||
|
||||
class NodeCache {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.id = id ++;
|
||||
this.nodesData = new WeakMap();
|
||||
|
||||
}
|
||||
|
||||
getNodeData( node ) {
|
||||
|
||||
return this.nodesData.get( node );
|
||||
|
||||
}
|
||||
|
||||
setNodeData( node, data ) {
|
||||
|
||||
this.nodesData.set( node, data );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeCache;
|
15
static/sdk/three/jsm/nodes/core/NodeCode.js
Normal file
15
static/sdk/three/jsm/nodes/core/NodeCode.js
Normal file
@ -0,0 +1,15 @@
|
||||
class NodeCode {
|
||||
|
||||
constructor( name, type, code = '' ) {
|
||||
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.code = code;
|
||||
|
||||
Object.defineProperty( this, 'isNodeCode', { value: true } );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeCode;
|
143
static/sdk/three/jsm/nodes/core/NodeFrame.js
Normal file
143
static/sdk/three/jsm/nodes/core/NodeFrame.js
Normal file
@ -0,0 +1,143 @@
|
||||
import { NodeUpdateType } from './constants.js';
|
||||
|
||||
class NodeFrame {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.time = 0;
|
||||
this.deltaTime = 0;
|
||||
|
||||
this.frameId = 0;
|
||||
this.renderId = 0;
|
||||
|
||||
this.startTime = null;
|
||||
|
||||
this.updateMap = new WeakMap();
|
||||
this.updateBeforeMap = new WeakMap();
|
||||
|
||||
this.renderer = null;
|
||||
this.material = null;
|
||||
this.camera = null;
|
||||
this.object = null;
|
||||
this.scene = null;
|
||||
|
||||
}
|
||||
|
||||
_getMaps( referenceMap, nodeRef ) {
|
||||
|
||||
let maps = referenceMap.get( nodeRef );
|
||||
|
||||
if ( maps === undefined ) {
|
||||
|
||||
maps = {
|
||||
renderMap: new WeakMap(),
|
||||
frameMap: new WeakMap()
|
||||
};
|
||||
|
||||
referenceMap.set( nodeRef, maps );
|
||||
|
||||
}
|
||||
|
||||
return maps;
|
||||
|
||||
}
|
||||
|
||||
updateBeforeNode( node ) {
|
||||
|
||||
const updateType = node.getUpdateBeforeType();
|
||||
const reference = node.updateReference( this );
|
||||
|
||||
if ( updateType === NodeUpdateType.FRAME ) {
|
||||
|
||||
const { frameMap } = this._getMaps( this.updateBeforeMap, reference );
|
||||
|
||||
if ( frameMap.get( reference ) !== this.frameId ) {
|
||||
|
||||
if ( node.updateBefore( this ) !== false ) {
|
||||
|
||||
frameMap.set( reference, this.frameId );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( updateType === NodeUpdateType.RENDER ) {
|
||||
|
||||
const { renderMap } = this._getMaps( this.updateBeforeMap, reference );
|
||||
|
||||
if ( renderMap.get( reference ) !== this.renderId ) {
|
||||
|
||||
if ( node.updateBefore( this ) !== false ) {
|
||||
|
||||
renderMap.set( reference, this.renderId );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( updateType === NodeUpdateType.OBJECT ) {
|
||||
|
||||
node.updateBefore( this );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateNode( node ) {
|
||||
|
||||
const updateType = node.getUpdateType();
|
||||
const reference = node.updateReference( this );
|
||||
|
||||
if ( updateType === NodeUpdateType.FRAME ) {
|
||||
|
||||
const { frameMap } = this._getMaps( this.updateMap, reference );
|
||||
|
||||
if ( frameMap.get( reference ) !== this.frameId ) {
|
||||
|
||||
if ( node.update( this ) !== false ) {
|
||||
|
||||
frameMap.set( reference, this.frameId );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( updateType === NodeUpdateType.RENDER ) {
|
||||
|
||||
const { renderMap } = this._getMaps( this.updateMap, reference );
|
||||
|
||||
if ( renderMap.get( reference ) !== this.renderId ) {
|
||||
|
||||
if ( node.update( this ) !== false ) {
|
||||
|
||||
renderMap.set( reference, this.renderId );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( updateType === NodeUpdateType.OBJECT ) {
|
||||
|
||||
node.update( this );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
this.frameId ++;
|
||||
|
||||
if ( this.lastTime === undefined ) this.lastTime = performance.now();
|
||||
|
||||
this.deltaTime = ( performance.now() - this.lastTime ) / 1000;
|
||||
|
||||
this.lastTime = performance.now();
|
||||
|
||||
this.time += this.deltaTime;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeFrame;
|
22
static/sdk/three/jsm/nodes/core/NodeFunction.js
Normal file
22
static/sdk/three/jsm/nodes/core/NodeFunction.js
Normal file
@ -0,0 +1,22 @@
|
||||
class NodeFunction {
|
||||
|
||||
constructor( type, inputs, name = '', presicion = '' ) {
|
||||
|
||||
this.type = type;
|
||||
this.inputs = inputs;
|
||||
this.name = name;
|
||||
this.presicion = presicion;
|
||||
|
||||
}
|
||||
|
||||
getCode( /*name = this.name*/ ) {
|
||||
|
||||
console.warn( 'Abstract function.' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NodeFunction.isNodeFunction = true;
|
||||
|
||||
export default NodeFunction;
|
17
static/sdk/three/jsm/nodes/core/NodeFunctionInput.js
Normal file
17
static/sdk/three/jsm/nodes/core/NodeFunctionInput.js
Normal file
@ -0,0 +1,17 @@
|
||||
class NodeFunctionInput {
|
||||
|
||||
constructor( type, name, count = null, qualifier = '', isConst = false ) {
|
||||
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.count = count;
|
||||
this.qualifier = qualifier;
|
||||
this.isConst = isConst;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NodeFunctionInput.isNodeFunctionInput = true;
|
||||
|
||||
export default NodeFunctionInput;
|
80
static/sdk/three/jsm/nodes/core/NodeKeywords.js
Normal file
80
static/sdk/three/jsm/nodes/core/NodeKeywords.js
Normal file
@ -0,0 +1,80 @@
|
||||
class NodeKeywords {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.keywords = [];
|
||||
this.nodes = [];
|
||||
this.keywordsCallback = {};
|
||||
|
||||
}
|
||||
|
||||
getNode( name ) {
|
||||
|
||||
let node = this.nodes[ name ];
|
||||
|
||||
if ( node === undefined && this.keywordsCallback[ name ] !== undefined ) {
|
||||
|
||||
node = this.keywordsCallback[ name ]( name );
|
||||
|
||||
this.nodes[ name ] = node;
|
||||
|
||||
}
|
||||
|
||||
return node;
|
||||
|
||||
}
|
||||
|
||||
addKeyword( name, callback ) {
|
||||
|
||||
this.keywords.push( name );
|
||||
this.keywordsCallback[ name ] = callback;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
parse( code ) {
|
||||
|
||||
const keywordNames = this.keywords;
|
||||
|
||||
const regExp = new RegExp( `\\b${keywordNames.join( '\\b|\\b' )}\\b`, 'g' );
|
||||
|
||||
const codeKeywords = code.match( regExp );
|
||||
|
||||
const keywordNodes = [];
|
||||
|
||||
if ( codeKeywords !== null ) {
|
||||
|
||||
for ( const keyword of codeKeywords ) {
|
||||
|
||||
const node = this.getNode( keyword );
|
||||
|
||||
if ( node !== undefined && keywordNodes.indexOf( node ) === - 1 ) {
|
||||
|
||||
keywordNodes.push( node );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return keywordNodes;
|
||||
|
||||
}
|
||||
|
||||
include( builder, code ) {
|
||||
|
||||
const keywordNodes = this.parse( code );
|
||||
|
||||
for ( const keywordNode of keywordNodes ) {
|
||||
|
||||
keywordNode.build( builder );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeKeywords;
|
11
static/sdk/three/jsm/nodes/core/NodeParser.js
Normal file
11
static/sdk/three/jsm/nodes/core/NodeParser.js
Normal file
@ -0,0 +1,11 @@
|
||||
class NodeParser {
|
||||
|
||||
parseFunction( /*source*/ ) {
|
||||
|
||||
console.warn( 'Abstract function.' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeParser;
|
40
static/sdk/three/jsm/nodes/core/NodeUniform.js
Normal file
40
static/sdk/three/jsm/nodes/core/NodeUniform.js
Normal file
@ -0,0 +1,40 @@
|
||||
class NodeUniform {
|
||||
|
||||
constructor( name, type, node, needsUpdate = undefined ) {
|
||||
|
||||
this.isNodeUniform = true;
|
||||
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.node = node.getSelf();
|
||||
this.needsUpdate = needsUpdate;
|
||||
|
||||
}
|
||||
|
||||
get value() {
|
||||
|
||||
return this.node.value;
|
||||
|
||||
}
|
||||
|
||||
set value( val ) {
|
||||
|
||||
this.node.value = val;
|
||||
|
||||
}
|
||||
|
||||
get id() {
|
||||
|
||||
return this.node.id;
|
||||
|
||||
}
|
||||
|
||||
get groupNode() {
|
||||
|
||||
return this.node.groupNode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeUniform;
|
210
static/sdk/three/jsm/nodes/core/NodeUtils.js
Normal file
210
static/sdk/three/jsm/nodes/core/NodeUtils.js
Normal file
@ -0,0 +1,210 @@
|
||||
import { Color, Matrix3, Matrix4, Vector2, Vector3, Vector4 } from 'three';
|
||||
|
||||
export function getCacheKey( object, force = false ) {
|
||||
|
||||
let cacheKey = '{';
|
||||
|
||||
if ( object.isNode === true ) {
|
||||
|
||||
cacheKey += object.id;
|
||||
|
||||
}
|
||||
|
||||
for ( const { property, childNode } of getNodeChildren( object ) ) {
|
||||
|
||||
cacheKey += ',' + property.slice( 0, - 4 ) + ':' + childNode.getCacheKey( force );
|
||||
|
||||
}
|
||||
|
||||
cacheKey += '}';
|
||||
|
||||
return cacheKey;
|
||||
|
||||
}
|
||||
|
||||
export function* getNodeChildren( node, toJSON = false ) {
|
||||
|
||||
for ( const property in node ) {
|
||||
|
||||
// Ignore private properties.
|
||||
if ( property.startsWith( '_' ) === true ) continue;
|
||||
|
||||
const object = node[ property ];
|
||||
|
||||
if ( Array.isArray( object ) === true ) {
|
||||
|
||||
for ( let i = 0; i < object.length; i ++ ) {
|
||||
|
||||
const child = object[ i ];
|
||||
|
||||
if ( child && ( child.isNode === true || toJSON && typeof child.toJSON === 'function' ) ) {
|
||||
|
||||
yield { property, index: i, childNode: child };
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( object && object.isNode === true ) {
|
||||
|
||||
yield { property, childNode: object };
|
||||
|
||||
} else if ( typeof object === 'object' ) {
|
||||
|
||||
for ( const subProperty in object ) {
|
||||
|
||||
const child = object[ subProperty ];
|
||||
|
||||
if ( child && ( child.isNode === true || toJSON && typeof child.toJSON === 'function' ) ) {
|
||||
|
||||
yield { property, index: subProperty, childNode: child };
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function getValueType( value ) {
|
||||
|
||||
if ( value === undefined || value === null ) return null;
|
||||
|
||||
const typeOf = typeof value;
|
||||
|
||||
if ( value.isNode === true ) {
|
||||
|
||||
return 'node';
|
||||
|
||||
} else if ( typeOf === 'number' ) {
|
||||
|
||||
return 'float';
|
||||
|
||||
} else if ( typeOf === 'boolean' ) {
|
||||
|
||||
return 'bool';
|
||||
|
||||
} else if ( typeOf === 'string' ) {
|
||||
|
||||
return 'string';
|
||||
|
||||
} else if ( typeOf === 'function' ) {
|
||||
|
||||
return 'shader';
|
||||
|
||||
} else if ( value.isVector2 === true ) {
|
||||
|
||||
return 'vec2';
|
||||
|
||||
} else if ( value.isVector3 === true ) {
|
||||
|
||||
return 'vec3';
|
||||
|
||||
} else if ( value.isVector4 === true ) {
|
||||
|
||||
return 'vec4';
|
||||
|
||||
} else if ( value.isMatrix3 === true ) {
|
||||
|
||||
return 'mat3';
|
||||
|
||||
} else if ( value.isMatrix4 === true ) {
|
||||
|
||||
return 'mat4';
|
||||
|
||||
} else if ( value.isColor === true ) {
|
||||
|
||||
return 'color';
|
||||
|
||||
} else if ( value instanceof ArrayBuffer ) {
|
||||
|
||||
return 'ArrayBuffer';
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
export function getValueFromType( type, ...params ) {
|
||||
|
||||
const last4 = type ? type.slice( - 4 ) : undefined;
|
||||
|
||||
if ( params.length === 1 ) { // ensure same behaviour as in NodeBuilder.format()
|
||||
|
||||
if ( last4 === 'vec2' ) params = [ params[ 0 ], params[ 0 ] ];
|
||||
else if ( last4 === 'vec3' ) params = [ params[ 0 ], params[ 0 ], params[ 0 ] ];
|
||||
else if ( last4 === 'vec4' ) params = [ params[ 0 ], params[ 0 ], params[ 0 ], params[ 0 ] ];
|
||||
|
||||
}
|
||||
|
||||
if ( type === 'color' ) {
|
||||
|
||||
return new Color( ...params );
|
||||
|
||||
} else if ( last4 === 'vec2' ) {
|
||||
|
||||
return new Vector2( ...params );
|
||||
|
||||
} else if ( last4 === 'vec3' ) {
|
||||
|
||||
return new Vector3( ...params );
|
||||
|
||||
} else if ( last4 === 'vec4' ) {
|
||||
|
||||
return new Vector4( ...params );
|
||||
|
||||
} else if ( last4 === 'mat3' ) {
|
||||
|
||||
return new Matrix3( ...params );
|
||||
|
||||
} else if ( last4 === 'mat4' ) {
|
||||
|
||||
return new Matrix4( ...params );
|
||||
|
||||
} else if ( type === 'bool' ) {
|
||||
|
||||
return params[ 0 ] || false;
|
||||
|
||||
} else if ( ( type === 'float' ) || ( type === 'int' ) || ( type === 'uint' ) ) {
|
||||
|
||||
return params[ 0 ] || 0;
|
||||
|
||||
} else if ( type === 'string' ) {
|
||||
|
||||
return params[ 0 ] || '';
|
||||
|
||||
} else if ( type === 'ArrayBuffer' ) {
|
||||
|
||||
return base64ToArrayBuffer( params[ 0 ] );
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
export function arrayBufferToBase64( arrayBuffer ) {
|
||||
|
||||
let chars = '';
|
||||
|
||||
const array = new Uint8Array( arrayBuffer );
|
||||
|
||||
for ( let i = 0; i < array.length; i ++ ) {
|
||||
|
||||
chars += String.fromCharCode( array[ i ] );
|
||||
|
||||
}
|
||||
|
||||
return btoa( chars );
|
||||
|
||||
}
|
||||
|
||||
export function base64ToArrayBuffer( base64 ) {
|
||||
|
||||
return Uint8Array.from( atob( base64 ), c => c.charCodeAt( 0 ) ).buffer;
|
||||
|
||||
}
|
14
static/sdk/three/jsm/nodes/core/NodeVar.js
Normal file
14
static/sdk/three/jsm/nodes/core/NodeVar.js
Normal file
@ -0,0 +1,14 @@
|
||||
class NodeVar {
|
||||
|
||||
constructor( name, type ) {
|
||||
|
||||
this.isNodeVar = true;
|
||||
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeVar;
|
17
static/sdk/three/jsm/nodes/core/NodeVarying.js
Normal file
17
static/sdk/three/jsm/nodes/core/NodeVarying.js
Normal file
@ -0,0 +1,17 @@
|
||||
import NodeVar from './NodeVar.js';
|
||||
|
||||
class NodeVarying extends NodeVar {
|
||||
|
||||
constructor( name, type ) {
|
||||
|
||||
super( name, type );
|
||||
|
||||
this.needsInterpolation = false;
|
||||
|
||||
this.isNodeVarying = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeVarying;
|
63
static/sdk/three/jsm/nodes/core/OutputStructNode.js
Normal file
63
static/sdk/three/jsm/nodes/core/OutputStructNode.js
Normal file
@ -0,0 +1,63 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import StructTypeNode from './StructTypeNode.js';
|
||||
import { nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class OutputStructNode extends Node {
|
||||
|
||||
constructor( ...members ) {
|
||||
|
||||
super();
|
||||
|
||||
this.members = members;
|
||||
|
||||
this.isOutputStructNode = true;
|
||||
|
||||
}
|
||||
|
||||
setup( builder ) {
|
||||
|
||||
super.setup( builder );
|
||||
|
||||
const members = this.members;
|
||||
const types = [];
|
||||
|
||||
for ( let i = 0; i < members.length; i ++ ) {
|
||||
|
||||
types.push( members[ i ].getNodeType( builder ) );
|
||||
|
||||
}
|
||||
|
||||
this.nodeType = builder.getStructTypeFromNode( new StructTypeNode( types ) ).name;
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
const nodeVar = builder.getVarFromNode( this );
|
||||
nodeVar.isOutputStructVar = true;
|
||||
|
||||
const propertyName = builder.getPropertyName( nodeVar );
|
||||
|
||||
const members = this.members;
|
||||
|
||||
const structPrefix = propertyName !== '' ? propertyName + '.' : '';
|
||||
|
||||
for ( let i = 0; i < members.length; i ++ ) {
|
||||
|
||||
const snippet = members[ i ].build( builder, output );
|
||||
|
||||
builder.addLineFlowCode( `${ structPrefix }m${ i } = ${ snippet }` );
|
||||
|
||||
}
|
||||
|
||||
return propertyName;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default OutputStructNode;
|
||||
|
||||
export const outputStruct = nodeProxy( OutputStructNode );
|
||||
|
||||
addNodeClass( 'OutputStructNode', OutputStructNode );
|
33
static/sdk/three/jsm/nodes/core/ParameterNode.js
Normal file
33
static/sdk/three/jsm/nodes/core/ParameterNode.js
Normal file
@ -0,0 +1,33 @@
|
||||
import { addNodeClass } from './Node.js';
|
||||
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||||
import PropertyNode from './PropertyNode.js';
|
||||
|
||||
class ParameterNode extends PropertyNode {
|
||||
|
||||
constructor( nodeType, name = null ) {
|
||||
|
||||
super( nodeType, name );
|
||||
|
||||
this.isParameterNode = true;
|
||||
|
||||
}
|
||||
|
||||
getHash() {
|
||||
|
||||
return this.uuid;
|
||||
|
||||
}
|
||||
|
||||
generate() {
|
||||
|
||||
return this.name;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ParameterNode;
|
||||
|
||||
export const parameter = ( type, name ) => nodeObject( new ParameterNode( type, name ) );
|
||||
|
||||
addNodeClass( 'ParameterNode', ParameterNode );
|
82
static/sdk/three/jsm/nodes/core/PropertyNode.js
Normal file
82
static/sdk/three/jsm/nodes/core/PropertyNode.js
Normal file
@ -0,0 +1,82 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { nodeImmutable, nodeObject } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class PropertyNode extends Node {
|
||||
|
||||
constructor( nodeType, name = null, varying = false ) {
|
||||
|
||||
super( nodeType );
|
||||
|
||||
this.name = name;
|
||||
this.varying = varying;
|
||||
|
||||
this.isPropertyNode = true;
|
||||
|
||||
}
|
||||
|
||||
getHash( builder ) {
|
||||
|
||||
return this.name || super.getHash( builder );
|
||||
|
||||
}
|
||||
|
||||
isGlobal( /*builder*/ ) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
let nodeVar;
|
||||
|
||||
if ( this.varying === true ) {
|
||||
|
||||
nodeVar = builder.getVaryingFromNode( this, this.name );
|
||||
nodeVar.needsInterpolation = true;
|
||||
|
||||
} else {
|
||||
|
||||
nodeVar = builder.getVarFromNode( this, this.name );
|
||||
|
||||
}
|
||||
|
||||
return builder.getPropertyName( nodeVar );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default PropertyNode;
|
||||
|
||||
export const property = ( type, name ) => nodeObject( new PropertyNode( type, name ) );
|
||||
export const varyingProperty = ( type, name ) => nodeObject( new PropertyNode( type, name, true ) );
|
||||
|
||||
export const diffuseColor = nodeImmutable( PropertyNode, 'vec4', 'DiffuseColor' );
|
||||
export const roughness = nodeImmutable( PropertyNode, 'float', 'Roughness' );
|
||||
export const metalness = nodeImmutable( PropertyNode, 'float', 'Metalness' );
|
||||
export const clearcoat = nodeImmutable( PropertyNode, 'float', 'Clearcoat' );
|
||||
export const clearcoatRoughness = nodeImmutable( PropertyNode, 'float', 'ClearcoatRoughness' );
|
||||
export const sheen = nodeImmutable( PropertyNode, 'vec3', 'Sheen' );
|
||||
export const sheenRoughness = nodeImmutable( PropertyNode, 'float', 'SheenRoughness' );
|
||||
export const iridescence = nodeImmutable( PropertyNode, 'float', 'Iridescence' );
|
||||
export const iridescenceIOR = nodeImmutable( PropertyNode, 'float', 'IridescenceIOR' );
|
||||
export const iridescenceThickness = nodeImmutable( PropertyNode, 'float', 'IridescenceThickness' );
|
||||
export const alphaT = nodeImmutable( PropertyNode, 'float', 'AlphaT' );
|
||||
export const anisotropy = nodeImmutable( PropertyNode, 'float', 'Anisotropy' );
|
||||
export const anisotropyT = nodeImmutable( PropertyNode, 'vec3', 'AnisotropyT' );
|
||||
export const anisotropyB = nodeImmutable( PropertyNode, 'vec3', 'AnisotropyB' );
|
||||
export const specularColor = nodeImmutable( PropertyNode, 'color', 'SpecularColor' );
|
||||
export const specularF90 = nodeImmutable( PropertyNode, 'float', 'SpecularF90' );
|
||||
export const shininess = nodeImmutable( PropertyNode, 'float', 'Shininess' );
|
||||
export const output = nodeImmutable( PropertyNode, 'vec4', 'Output' );
|
||||
export const dashSize = nodeImmutable( PropertyNode, 'float', 'dashSize' );
|
||||
export const gapSize = nodeImmutable( PropertyNode, 'float', 'gapSize' );
|
||||
export const pointWidth = nodeImmutable( PropertyNode, 'float', 'pointWidth' );
|
||||
export const ior = nodeImmutable( PropertyNode, 'float', 'IOR' );
|
||||
export const transmission = nodeImmutable( PropertyNode, 'float', 'Transmission' );
|
||||
export const thickness = nodeImmutable( PropertyNode, 'float', 'Thickness' );
|
||||
export const attenuationDistance = nodeImmutable( PropertyNode, 'float', 'AttenuationDistance' );
|
||||
export const attenuationColor = nodeImmutable( PropertyNode, 'color', 'AttenuationColor' );
|
||||
|
||||
addNodeClass( 'PropertyNode', PropertyNode );
|
89
static/sdk/three/jsm/nodes/core/StackNode.js
Normal file
89
static/sdk/three/jsm/nodes/core/StackNode.js
Normal file
@ -0,0 +1,89 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { cond } from '../math/CondNode.js';
|
||||
import { ShaderNode, nodeProxy, getCurrentStack, setCurrentStack } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class StackNode extends Node {
|
||||
|
||||
constructor( parent = null ) {
|
||||
|
||||
super();
|
||||
|
||||
this.nodes = [];
|
||||
this.outputNode = null;
|
||||
|
||||
this.parent = parent;
|
||||
|
||||
this._currentCond = null;
|
||||
|
||||
this.isStackNode = true;
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
return this.outputNode ? this.outputNode.getNodeType( builder ) : 'void';
|
||||
|
||||
}
|
||||
|
||||
add( node ) {
|
||||
|
||||
this.nodes.push( node );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
if( boolNode, method ) {
|
||||
|
||||
const methodNode = new ShaderNode( method );
|
||||
this._currentCond = cond( boolNode, methodNode );
|
||||
|
||||
return this.add( this._currentCond );
|
||||
|
||||
}
|
||||
|
||||
elseif( boolNode, method ) {
|
||||
|
||||
const methodNode = new ShaderNode( method );
|
||||
const ifNode = cond( boolNode, methodNode );
|
||||
|
||||
this._currentCond.elseNode = ifNode;
|
||||
this._currentCond = ifNode;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
else( method ) {
|
||||
|
||||
this._currentCond.elseNode = new ShaderNode( method );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
build( builder, ...params ) {
|
||||
|
||||
const previousStack = getCurrentStack();
|
||||
|
||||
setCurrentStack( this );
|
||||
|
||||
for ( const node of this.nodes ) {
|
||||
|
||||
node.build( builder, 'void' );
|
||||
|
||||
}
|
||||
|
||||
setCurrentStack( previousStack );
|
||||
|
||||
return this.outputNode ? this.outputNode.build( builder, ...params ) : super.build( builder, ...params );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default StackNode;
|
||||
|
||||
export const stack = nodeProxy( StackNode );
|
||||
|
||||
addNodeClass( 'StackNode', StackNode );
|
24
static/sdk/three/jsm/nodes/core/StructTypeNode.js
Normal file
24
static/sdk/three/jsm/nodes/core/StructTypeNode.js
Normal file
@ -0,0 +1,24 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
|
||||
class StructTypeNode extends Node {
|
||||
|
||||
constructor( types ) {
|
||||
|
||||
super();
|
||||
|
||||
this.types = types;
|
||||
this.isStructTypeNode = true;
|
||||
|
||||
}
|
||||
|
||||
getMemberTypes() {
|
||||
|
||||
return this.types;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default StructTypeNode;
|
||||
|
||||
addNodeClass( 'StructTypeNode', StructTypeNode );
|
58
static/sdk/three/jsm/nodes/core/TempNode.js
Normal file
58
static/sdk/three/jsm/nodes/core/TempNode.js
Normal file
@ -0,0 +1,58 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
|
||||
class TempNode extends Node {
|
||||
|
||||
constructor( type ) {
|
||||
|
||||
super( type );
|
||||
|
||||
this.isTempNode = true;
|
||||
|
||||
}
|
||||
|
||||
hasDependencies( builder ) {
|
||||
|
||||
return builder.getDataFromNode( this ).usageCount > 1;
|
||||
|
||||
}
|
||||
|
||||
build( builder, output ) {
|
||||
|
||||
const buildStage = builder.getBuildStage();
|
||||
|
||||
if ( buildStage === 'generate' ) {
|
||||
|
||||
const type = builder.getVectorType( this.getNodeType( builder, output ) );
|
||||
const nodeData = builder.getDataFromNode( this );
|
||||
|
||||
if ( builder.context.tempRead !== false && nodeData.propertyName !== undefined ) {
|
||||
|
||||
return builder.format( nodeData.propertyName, type, output );
|
||||
|
||||
} else if ( builder.context.tempWrite !== false && type !== 'void' && output !== 'void' && this.hasDependencies( builder ) ) {
|
||||
|
||||
const snippet = super.build( builder, type );
|
||||
|
||||
const nodeVar = builder.getVarFromNode( this, null, type );
|
||||
const propertyName = builder.getPropertyName( nodeVar );
|
||||
|
||||
builder.addLineFlowCode( `${propertyName} = ${snippet}` );
|
||||
|
||||
nodeData.snippet = snippet;
|
||||
nodeData.propertyName = propertyName;
|
||||
|
||||
return builder.format( nodeData.propertyName, type, output );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return super.build( builder, output );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default TempNode;
|
||||
|
||||
addNodeClass( 'TempNode', TempNode );
|
13
static/sdk/three/jsm/nodes/core/UniformGroup.js
Normal file
13
static/sdk/three/jsm/nodes/core/UniformGroup.js
Normal file
@ -0,0 +1,13 @@
|
||||
class UniformGroup {
|
||||
|
||||
constructor( name ) {
|
||||
|
||||
this.name = name;
|
||||
|
||||
this.isUniformGroup = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default UniformGroup;
|
36
static/sdk/three/jsm/nodes/core/UniformGroupNode.js
Normal file
36
static/sdk/three/jsm/nodes/core/UniformGroupNode.js
Normal file
@ -0,0 +1,36 @@
|
||||
import Node from './Node.js';
|
||||
import { addNodeClass } from './Node.js';
|
||||
|
||||
class UniformGroupNode extends Node {
|
||||
|
||||
constructor( name, shared = false ) {
|
||||
|
||||
super( 'string' );
|
||||
|
||||
this.name = name;
|
||||
this.version = 0;
|
||||
|
||||
this.shared = shared;
|
||||
|
||||
this.isUniformGroup = true;
|
||||
|
||||
}
|
||||
|
||||
set needsUpdate( value ) {
|
||||
|
||||
if ( value === true ) this.version ++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const uniformGroup = ( name ) => new UniformGroupNode( name );
|
||||
export const sharedUniformGroup = ( name ) => new UniformGroupNode( name, true );
|
||||
|
||||
export const frameGroup = sharedUniformGroup( 'frame' );
|
||||
export const renderGroup = sharedUniformGroup( 'render' );
|
||||
export const objectGroup = uniformGroup( 'object' );
|
||||
|
||||
export default UniformGroupNode;
|
||||
|
||||
addNodeClass( 'UniformGroupNode', UniformGroupNode );
|
100
static/sdk/three/jsm/nodes/core/UniformNode.js
Normal file
100
static/sdk/three/jsm/nodes/core/UniformNode.js
Normal file
@ -0,0 +1,100 @@
|
||||
import InputNode from './InputNode.js';
|
||||
import { objectGroup } from './UniformGroupNode.js';
|
||||
import { addNodeClass } from './Node.js';
|
||||
import { nodeObject, getConstNodeType } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class UniformNode extends InputNode {
|
||||
|
||||
constructor( value, nodeType = null ) {
|
||||
|
||||
super( value, nodeType );
|
||||
|
||||
this.isUniformNode = true;
|
||||
|
||||
this.groupNode = objectGroup;
|
||||
|
||||
}
|
||||
|
||||
setGroup( group ) {
|
||||
|
||||
this.groupNode = group;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getGroup() {
|
||||
|
||||
return this.groupNode;
|
||||
|
||||
}
|
||||
|
||||
getUniformHash( builder ) {
|
||||
|
||||
return this.getHash( builder );
|
||||
|
||||
}
|
||||
|
||||
onUpdate( callback, updateType ) {
|
||||
|
||||
const self = this.getSelf();
|
||||
|
||||
callback = callback.bind( self );
|
||||
|
||||
return super.onUpdate( ( frame ) => {
|
||||
|
||||
const value = callback( frame, self );
|
||||
|
||||
if ( value !== undefined ) {
|
||||
|
||||
this.value = value;
|
||||
|
||||
}
|
||||
|
||||
}, updateType );
|
||||
|
||||
}
|
||||
|
||||
generate( builder, output ) {
|
||||
|
||||
const type = this.getNodeType( builder );
|
||||
|
||||
const hash = this.getUniformHash( builder );
|
||||
|
||||
let sharedNode = builder.getNodeFromHash( hash );
|
||||
|
||||
if ( sharedNode === undefined ) {
|
||||
|
||||
builder.setHashNode( this, hash );
|
||||
|
||||
sharedNode = this;
|
||||
|
||||
}
|
||||
|
||||
const sharedNodeType = sharedNode.getInputType( builder );
|
||||
|
||||
const nodeUniform = builder.getUniformFromNode( sharedNode, sharedNodeType, builder.shaderStage, builder.context.label );
|
||||
const propertyName = builder.getPropertyName( nodeUniform );
|
||||
|
||||
if ( builder.context.label !== undefined ) delete builder.context.label;
|
||||
|
||||
return builder.format( propertyName, type, output );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default UniformNode;
|
||||
|
||||
export const uniform = ( arg1, arg2 ) => {
|
||||
|
||||
const nodeType = getConstNodeType( arg2 || arg1 );
|
||||
|
||||
// @TODO: get ConstNode from .traverse() in the future
|
||||
const value = ( arg1 && arg1.isNode === true ) ? ( arg1.node && arg1.node.value ) || arg1.value : arg1;
|
||||
|
||||
return nodeObject( new UniformNode( value, nodeType ) );
|
||||
|
||||
};
|
||||
|
||||
addNodeClass( 'UniformNode', UniformNode );
|
60
static/sdk/three/jsm/nodes/core/VarNode.js
Normal file
60
static/sdk/three/jsm/nodes/core/VarNode.js
Normal file
@ -0,0 +1,60 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class VarNode extends Node {
|
||||
|
||||
constructor( node, name = null ) {
|
||||
|
||||
super();
|
||||
|
||||
this.node = node;
|
||||
this.name = name;
|
||||
|
||||
this.isVarNode = true;
|
||||
|
||||
}
|
||||
|
||||
isGlobal() {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
getHash( builder ) {
|
||||
|
||||
return this.name || super.getHash( builder );
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
return this.node.getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const { node, name } = this;
|
||||
|
||||
const nodeVar = builder.getVarFromNode( this, name, builder.getVectorType( this.getNodeType( builder ) ) );
|
||||
|
||||
const propertyName = builder.getPropertyName( nodeVar );
|
||||
|
||||
const snippet = node.build( builder, nodeVar.type );
|
||||
|
||||
builder.addLineFlowCode( `${propertyName} = ${snippet}` );
|
||||
|
||||
return propertyName;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default VarNode;
|
||||
|
||||
export const temp = nodeProxy( VarNode );
|
||||
|
||||
addNodeElement( 'temp', temp ); // @TODO: Will be removed in the future
|
||||
addNodeElement( 'toVar', ( ...params ) => temp( ...params ).append() );
|
||||
|
||||
addNodeClass( 'VarNode', VarNode );
|
65
static/sdk/three/jsm/nodes/core/VaryingNode.js
Normal file
65
static/sdk/three/jsm/nodes/core/VaryingNode.js
Normal file
@ -0,0 +1,65 @@
|
||||
import Node, { addNodeClass } from './Node.js';
|
||||
import { NodeShaderStage } from './constants.js';
|
||||
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
|
||||
|
||||
class VaryingNode extends Node {
|
||||
|
||||
constructor( node, name = null ) {
|
||||
|
||||
super();
|
||||
|
||||
this.node = node;
|
||||
this.name = name;
|
||||
|
||||
this.isVaryingNode = true;
|
||||
|
||||
}
|
||||
|
||||
isGlobal() {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
getHash( builder ) {
|
||||
|
||||
return this.name || super.getHash( builder );
|
||||
|
||||
}
|
||||
|
||||
getNodeType( builder ) {
|
||||
|
||||
// VaryingNode is auto type
|
||||
|
||||
return this.node.getNodeType( builder );
|
||||
|
||||
}
|
||||
|
||||
generate( builder ) {
|
||||
|
||||
const { name, node } = this;
|
||||
const type = this.getNodeType( builder );
|
||||
|
||||
const nodeVarying = builder.getVaryingFromNode( this, name, type );
|
||||
|
||||
// this property can be used to check if the varying can be optimized for a var
|
||||
nodeVarying.needsInterpolation || ( nodeVarying.needsInterpolation = ( builder.shaderStage === 'fragment' ) );
|
||||
|
||||
const propertyName = builder.getPropertyName( nodeVarying, NodeShaderStage.VERTEX );
|
||||
|
||||
// force node run in vertex stage
|
||||
builder.flowNodeFromShaderStage( NodeShaderStage.VERTEX, node, type, propertyName );
|
||||
|
||||
return builder.getPropertyName( nodeVarying );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default VaryingNode;
|
||||
|
||||
export const varying = nodeProxy( VaryingNode );
|
||||
|
||||
addNodeElement( 'varying', varying );
|
||||
|
||||
addNodeClass( 'VaryingNode', VaryingNode );
|
28
static/sdk/three/jsm/nodes/core/constants.js
Normal file
28
static/sdk/three/jsm/nodes/core/constants.js
Normal file
@ -0,0 +1,28 @@
|
||||
export const NodeShaderStage = {
|
||||
VERTEX: 'vertex',
|
||||
FRAGMENT: 'fragment'
|
||||
};
|
||||
|
||||
export const NodeUpdateType = {
|
||||
NONE: 'none',
|
||||
FRAME: 'frame',
|
||||
RENDER: 'render',
|
||||
OBJECT: 'object'
|
||||
};
|
||||
|
||||
export const NodeType = {
|
||||
BOOLEAN: 'bool',
|
||||
INTEGER: 'int',
|
||||
FLOAT: 'float',
|
||||
VECTOR2: 'vec2',
|
||||
VECTOR3: 'vec3',
|
||||
VECTOR4: 'vec4',
|
||||
MATRIX2: 'mat2',
|
||||
MATRIX3: 'mat3',
|
||||
MATRIX4: 'mat4'
|
||||
};
|
||||
|
||||
export const defaultShaderStages = [ 'fragment', 'vertex' ];
|
||||
export const defaultBuildStages = [ 'setup', 'analyze', 'generate' ];
|
||||
export const shaderStages = [ ...defaultShaderStages, 'compute' ];
|
||||
export const vectorComponents = [ 'x', 'y', 'z', 'w' ];
|
Reference in New Issue
Block a user