123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- import InputNode from '../core/InputNode.js';
- import { addNodeClass } from '../core/Node.js';
- import { varying } from '../core/VaryingNode.js';
- import { nodeObject, addNodeElement } from '../shadernode/ShaderNode.js';
- import { InterleavedBufferAttribute, InterleavedBuffer, StaticDrawUsage, DynamicDrawUsage } from 'three';
- class BufferAttributeNode extends InputNode {
- constructor( value, bufferType = null, bufferStride = 0, bufferOffset = 0 ) {
- super( value, bufferType );
- this.isBufferNode = true;
- this.bufferType = bufferType;
- this.bufferStride = bufferStride;
- this.bufferOffset = bufferOffset;
- this.usage = StaticDrawUsage;
- this.instanced = false;
- this.attribute = null;
- this.global = true;
- if ( value && value.isBufferAttribute === true ) {
- this.attribute = value;
- this.usage = value.usage;
- this.instanced = value.isInstancedBufferAttribute;
- }
- }
- getHash( builder ) {
- if ( this.bufferStride === 0 && this.bufferOffset === 0 ) {
- let bufferData = builder.globalCache.getData( this.value );
- if ( bufferData === undefined ) {
- bufferData = {
- node: this
- };
- builder.globalCache.setData( this.value, bufferData );
- }
- return bufferData.node.uuid;
- }
- return this.uuid;
- }
- getNodeType( builder ) {
- if ( this.bufferType === null ) {
- this.bufferType = builder.getTypeFromAttribute( this.attribute );
- }
- return this.bufferType;
- }
- setup( builder ) {
- if ( this.attribute !== null ) return;
- const type = this.getNodeType( builder );
- const array = this.value;
- const itemSize = builder.getTypeLength( type );
- const stride = this.bufferStride || itemSize;
- const offset = this.bufferOffset;
- const buffer = array.isInterleavedBuffer === true ? array : new InterleavedBuffer( array, stride );
- const bufferAttribute = new InterleavedBufferAttribute( buffer, itemSize, offset );
- buffer.setUsage( this.usage );
- this.attribute = bufferAttribute;
- this.attribute.isInstancedBufferAttribute = this.instanced; // @TODO: Add a possible: InstancedInterleavedBufferAttribute
- }
- generate( builder ) {
- const nodeType = this.getNodeType( builder );
- const nodeAttribute = builder.getBufferAttributeFromNode( this, nodeType );
- const propertyName = builder.getPropertyName( nodeAttribute );
- let output = null;
- if ( builder.shaderStage === 'vertex' || builder.shaderStage === 'compute' ) {
- this.name = propertyName;
- output = propertyName;
- } else {
- const nodeVarying = varying( this );
- output = nodeVarying.build( builder, nodeType );
- }
- return output;
- }
- getInputType( /*builder*/ ) {
- return 'bufferAttribute';
- }
- setUsage( value ) {
- this.usage = value;
- if ( this.attribute && this.attribute.isBufferAttribute === true ) {
- this.attribute.usage = value;
- }
- return this;
- }
- setInstanced( value ) {
- this.instanced = value;
- return this;
- }
- }
- export default BufferAttributeNode;
- export const bufferAttribute = ( array, type, stride, offset ) => nodeObject( new BufferAttributeNode( array, type, stride, offset ) );
- export const dynamicBufferAttribute = ( array, type, stride, offset ) => bufferAttribute( array, type, stride, offset ).setUsage( DynamicDrawUsage );
- export const instancedBufferAttribute = ( array, type, stride, offset ) => bufferAttribute( array, type, stride, offset ).setInstanced( true );
- export const instancedDynamicBufferAttribute = ( array, type, stride, offset ) => dynamicBufferAttribute( array, type, stride, offset ).setInstanced( true );
- addNodeElement( 'toAttribute', ( bufferNode ) => bufferAttribute( bufferNode.value ) );
- addNodeClass( 'BufferAttributeNode', BufferAttributeNode );
|