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 );
 |