161 lines
2.9 KiB
JavaScript
161 lines
2.9 KiB
JavaScript
|
import Node, { addNodeClass } from '../core/Node.js';
|
||
|
import { NodeUpdateType } from '../core/constants.js';
|
||
|
import { uniform } from '../core/UniformNode.js';
|
||
|
import { texture } from './TextureNode.js';
|
||
|
import { buffer } from './BufferNode.js';
|
||
|
import { nodeObject } from '../shadernode/ShaderNode.js';
|
||
|
import { uniforms } from './UniformsNode.js';
|
||
|
import ArrayElementNode from '../utils/ArrayElementNode.js';
|
||
|
|
||
|
class ReferenceElementNode extends ArrayElementNode {
|
||
|
|
||
|
constructor( referenceNode, indexNode ) {
|
||
|
|
||
|
super( referenceNode, indexNode );
|
||
|
|
||
|
this.referenceNode = referenceNode;
|
||
|
|
||
|
this.isReferenceElementNode = true;
|
||
|
|
||
|
}
|
||
|
|
||
|
getNodeType() {
|
||
|
|
||
|
return this.referenceNode.uniformType;
|
||
|
|
||
|
}
|
||
|
|
||
|
generate( builder ) {
|
||
|
|
||
|
const snippet = super.generate( builder );
|
||
|
const arrayType = this.referenceNode.getNodeType();
|
||
|
const elementType = this.getNodeType();
|
||
|
|
||
|
return builder.format( snippet, arrayType, elementType );
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
class ReferenceNode extends Node {
|
||
|
|
||
|
constructor( property, uniformType, object = null, count = null ) {
|
||
|
|
||
|
super();
|
||
|
|
||
|
this.property = property;
|
||
|
this.uniformType = uniformType;
|
||
|
this.object = object;
|
||
|
this.count = count;
|
||
|
|
||
|
this.properties = property.split( '.' );
|
||
|
this.reference = null;
|
||
|
this.node = null;
|
||
|
|
||
|
this.updateType = NodeUpdateType.OBJECT;
|
||
|
|
||
|
}
|
||
|
|
||
|
element( indexNode ) {
|
||
|
|
||
|
return nodeObject( new ReferenceElementNode( this, nodeObject( indexNode ) ) );
|
||
|
|
||
|
}
|
||
|
|
||
|
setNodeType( uniformType ) {
|
||
|
|
||
|
let node = null;
|
||
|
|
||
|
if ( this.count !== null ) {
|
||
|
|
||
|
node = buffer( null, uniformType, this.count );
|
||
|
|
||
|
} else if ( Array.isArray( this.getValueFromReference() ) ) {
|
||
|
|
||
|
node = uniforms( null, uniformType );
|
||
|
|
||
|
} else if ( uniformType === 'texture' ) {
|
||
|
|
||
|
node = texture( null );
|
||
|
|
||
|
} else {
|
||
|
|
||
|
node = uniform( null, uniformType );
|
||
|
|
||
|
}
|
||
|
|
||
|
this.node = node;
|
||
|
|
||
|
}
|
||
|
|
||
|
getNodeType( builder ) {
|
||
|
|
||
|
return this.node.getNodeType( builder );
|
||
|
|
||
|
}
|
||
|
|
||
|
getValueFromReference( object = this.reference ) {
|
||
|
|
||
|
const { properties } = this;
|
||
|
|
||
|
let value = object[ properties[ 0 ] ];
|
||
|
|
||
|
for ( let i = 1; i < properties.length; i ++ ) {
|
||
|
|
||
|
value = value[ properties[ i ] ];
|
||
|
|
||
|
}
|
||
|
|
||
|
return value;
|
||
|
|
||
|
}
|
||
|
|
||
|
updateReference( state ) {
|
||
|
|
||
|
this.reference = this.object !== null ? this.object : state.object;
|
||
|
|
||
|
return this.reference;
|
||
|
|
||
|
}
|
||
|
|
||
|
setup() {
|
||
|
|
||
|
this.updateValue();
|
||
|
|
||
|
return this.node;
|
||
|
|
||
|
}
|
||
|
|
||
|
update( /*frame*/ ) {
|
||
|
|
||
|
this.updateValue();
|
||
|
|
||
|
}
|
||
|
|
||
|
updateValue() {
|
||
|
|
||
|
if ( this.node === null ) this.setNodeType( this.uniformType );
|
||
|
|
||
|
const value = this.getValueFromReference();
|
||
|
|
||
|
if ( Array.isArray( value ) ) {
|
||
|
|
||
|
this.node.array = value;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
this.node.value = value;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export default ReferenceNode;
|
||
|
|
||
|
export const reference = ( name, type, object ) => nodeObject( new ReferenceNode( name, type, object ) );
|
||
|
export const referenceBuffer = ( name, type, count, object ) => nodeObject( new ReferenceNode( name, type, object, count ) );
|
||
|
|
||
|
addNodeClass( 'ReferenceNode', ReferenceNode );
|