UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

294 lines (274 loc) 9.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.instancedDynamicBufferAttribute = exports.instancedBufferAttribute = exports.dynamicBufferAttribute = exports.default = exports.bufferAttribute = void 0; var _InputNode = _interopRequireDefault(require("../core/InputNode.js")); var _TSLCore = require("../tsl/TSLCore.js"); var _VaryingNode = require("../core/VaryingNode.js"); var _InterleavedBufferAttribute = require("../../core/InterleavedBufferAttribute.js"); var _InterleavedBuffer = require("../../core/InterleavedBuffer.js"); var _constants = require("../../constants.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * In earlier `three.js` versions it was only possible to define attribute data * on geometry level. With `BufferAttributeNode`, it is also possible to do this * on the node level. * ```js * const geometry = new THREE.PlaneGeometry(); * const positionAttribute = geometry.getAttribute( 'position' ); * * const colors = []; * for ( let i = 0; i < position.count; i ++ ) { * colors.push( 1, 0, 0 ); * } * * material.colorNode = bufferAttribute( new THREE.Float32BufferAttribute( colors, 3 ) ); * ``` * This new approach is especially interesting when geometry data are generated via * compute shaders. The below line converts a storage buffer into an attribute node. * ```js * material.positionNode = positionBuffer.toAttribute(); * ``` * @augments InputNode */ class BufferAttributeNode extends _InputNode.default { static get type() { return 'BufferAttributeNode'; } /** * Constructs a new buffer attribute node. * * @param {BufferAttribute|InterleavedBuffer|TypedArray} value - The attribute data. * @param {?string} [bufferType=null] - The buffer type (e.g. `'vec3'`). * @param {number} [bufferStride=0] - The buffer stride. * @param {number} [bufferOffset=0] - The buffer offset. */ constructor(value, bufferType = null, bufferStride = 0, bufferOffset = 0) { super(value, bufferType); /** * This flag can be used for type testing. * * @type {boolean} * @readonly * @default true */ this.isBufferNode = true; /** * The buffer type (e.g. `'vec3'`). * * @type {?string} * @default null */ this.bufferType = bufferType; /** * The buffer stride. * * @type {number} * @default 0 */ this.bufferStride = bufferStride; /** * The buffer offset. * * @type {number} * @default 0 */ this.bufferOffset = bufferOffset; /** * The usage property. Set this to `THREE.DynamicDrawUsage` via `.setUsage()`, * if you are planning to update the attribute data per frame. * * @type {number} * @default StaticDrawUsage */ this.usage = _constants.StaticDrawUsage; /** * Whether the attribute is instanced or not. * * @type {boolean} * @default false */ this.instanced = false; /** * A reference to the buffer attribute. * * @type {?BufferAttribute} * @default null */ this.attribute = null; /** * `BufferAttributeNode` sets this property to `true` by default. * * @type {boolean} * @default true */ this.global = true; if (value && value.isBufferAttribute === true) { this.attribute = value; this.usage = value.usage; this.instanced = value.isInstancedBufferAttribute; } } /** * This method is overwritten since the attribute data might be shared * and thus the hash should be shared as well. * * @param {NodeBuilder} builder - The current node builder. * @return {string} The hash. */ 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; } /** * This method is overwritten since the node type is inferred from * the buffer attribute. * * @param {NodeBuilder} builder - The current node builder. * @return {string} The node type. */ getNodeType(builder) { if (this.bufferType === null) { this.bufferType = builder.getTypeFromAttribute(this.attribute); } return this.bufferType; } /** * Depending on which value was passed to the node, `setup()` behaves * differently. If no instance of `BufferAttribute` was passed, the method * creates an internal attribute and configures it respectively. * * @param {NodeBuilder} builder - The current node builder. */ 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.InterleavedBuffer(array, stride); const bufferAttribute = new _InterleavedBufferAttribute.InterleavedBufferAttribute(buffer, itemSize, offset); buffer.setUsage(this.usage); this.attribute = bufferAttribute; this.attribute.isInstancedBufferAttribute = this.instanced; // @TODO: Add a possible: InstancedInterleavedBufferAttribute } /** * Generates the code snippet of the buffer attribute node. * * @param {NodeBuilder} builder - The current node builder. * @return {string} The generated code snippet. */ 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 = (0, _VaryingNode.varying)(this); output = nodeVarying.build(builder, nodeType); } return output; } /** * Overwrites the default implementation to return a fixed value `'bufferAttribute'`. * * @param {NodeBuilder} builder - The current node builder. * @return {string} The input type. */ getInputType( /*builder*/ ) { return 'bufferAttribute'; } /** * Sets the `usage` property to the given value. * * @param {number} value - The usage to set. * @return {BufferAttributeNode} A reference to this node. */ setUsage(value) { this.usage = value; if (this.attribute && this.attribute.isBufferAttribute === true) { this.attribute.usage = value; } return this; } /** * Sets the `instanced` property to the given value. * * @param {boolean} value - The value to set. * @return {BufferAttributeNode} A reference to this node. */ setInstanced(value) { this.instanced = value; return this; } } var _default = exports.default = BufferAttributeNode; /** * TSL function for creating a buffer attribute node. * * @tsl * @function * @param {BufferAttribute|InterleavedBuffer|TypedArray} array - The attribute data. * @param {?string} [type=null] - The buffer type (e.g. `'vec3'`). * @param {number} [stride=0] - The buffer stride. * @param {number} [offset=0] - The buffer offset. * @returns {BufferAttributeNode} */ const bufferAttribute = (array, type = null, stride = 0, offset = 0) => (0, _TSLCore.nodeObject)(new BufferAttributeNode(array, type, stride, offset)); /** * TSL function for creating a buffer attribute node but with dynamic draw usage. * Use this function if attribute data are updated per frame. * * @tsl * @function * @param {BufferAttribute|InterleavedBuffer|TypedArray} array - The attribute data. * @param {?string} [type=null] - The buffer type (e.g. `'vec3'`). * @param {number} [stride=0] - The buffer stride. * @param {number} [offset=0] - The buffer offset. * @returns {BufferAttributeNode} */ exports.bufferAttribute = bufferAttribute; const dynamicBufferAttribute = (array, type = null, stride = 0, offset = 0) => bufferAttribute(array, type, stride, offset).setUsage(_constants.DynamicDrawUsage); /** * TSL function for creating a buffer attribute node but with enabled instancing * * @tsl * @function * @param {BufferAttribute|InterleavedBuffer|TypedArray} array - The attribute data. * @param {?string} [type=null] - The buffer type (e.g. `'vec3'`). * @param {number} [stride=0] - The buffer stride. * @param {number} [offset=0] - The buffer offset. * @returns {BufferAttributeNode} */ exports.dynamicBufferAttribute = dynamicBufferAttribute; const instancedBufferAttribute = (array, type = null, stride = 0, offset = 0) => bufferAttribute(array, type, stride, offset).setInstanced(true); /** * TSL function for creating a buffer attribute node but with dynamic draw usage and enabled instancing * * @tsl * @function * @param {BufferAttribute|InterleavedBuffer|TypedArray} array - The attribute data. * @param {?string} [type=null] - The buffer type (e.g. `'vec3'`). * @param {number} [stride=0] - The buffer stride. * @param {number} [offset=0] - The buffer offset. * @returns {BufferAttributeNode} */ exports.instancedBufferAttribute = instancedBufferAttribute; const instancedDynamicBufferAttribute = (array, type = null, stride = 0, offset = 0) => dynamicBufferAttribute(array, type, stride, offset).setInstanced(true); exports.instancedDynamicBufferAttribute = instancedDynamicBufferAttribute; (0, _TSLCore.addMethodChaining)('toAttribute', bufferNode => bufferAttribute(bufferNode.value));