UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

191 lines (170 loc) 6.76 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.instance = exports.default = void 0; var _Node = _interopRequireDefault(require("../core/Node.js")); var _PropertyNode = require("../core/PropertyNode.js"); var _BufferAttributeNode = require("./BufferAttributeNode.js"); var _Normal = require("./Normal.js"); var _Position = require("./Position.js"); var _TSLBase = require("../tsl/TSLBase.js"); var _constants = require("../core/constants.js"); var _BufferNode = require("../accessors/BufferNode.js"); var _IndexNode = require("../core/IndexNode.js"); var _InstancedInterleavedBuffer = require("../../core/InstancedInterleavedBuffer.js"); var _InstancedBufferAttribute = require("../../core/InstancedBufferAttribute.js"); var _constants2 = require("../../constants.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * This node implements the vertex shader logic which is required * when rendering 3D objects via instancing. The code makes sure * vertex positions, normals and colors can be modified via instanced * data. * * @augments Node */ class InstanceNode extends _Node.default { static get type() { return 'InstanceNode'; } /** * Constructs a new instance node. * * @param {number} count - The number of instances. * @param {InstancedBufferAttribute} instanceMatrix - Instanced buffer attribute representing the instance transformations. * @param {InstancedBufferAttribute} instanceColor - Instanced buffer attribute representing the instance colors. */ constructor(count, instanceMatrix, instanceColor) { super('void'); /** * The number of instances. * * @type {number} */ this.count = count; /** * Instanced buffer attribute representing the transformation of instances. * * @type {InstancedBufferAttribute} */ this.instanceMatrix = instanceMatrix; /** * Instanced buffer attribute representing the color of instances. * * @type {InstancedBufferAttribute} */ this.instanceColor = instanceColor; /** * The node that represents the instance matrix data. * * @type {?Node} */ this.instanceMatrixNode = null; /** * The node that represents the instance color data. * * @type {?Node} */ this.instanceColorNode = null; /** * The update type is set to `frame` since an update * of instanced buffer data must be checked per frame. * * @type {string} * @default 'frame' */ this.updateType = _constants.NodeUpdateType.FRAME; /** * A reference to a buffer that is used by `instanceMatrixNode`. * * @type {?InstancedInterleavedBuffer} */ this.buffer = null; /** * A reference to a buffer that is used by `instanceColorNode`. * * @type {?InstancedBufferAttribute} */ this.bufferColor = null; } /** * Setups the internal buffers and nodes and assigns the transformed vertex data * to predefined node variables for accumulation. That follows the same patterns * like with morph and skinning nodes. * * @param {NodeBuilder} builder - The current node builder. */ setup(builder) { const { count, instanceMatrix, instanceColor } = this; let { instanceMatrixNode, instanceColorNode } = this; if (instanceMatrixNode === null) { // Both WebGPU and WebGL backends have UBO max limited to 64kb. Matrix count number bigger than 1000 ( 16 * 4 * 1000 = 64kb ) will fallback to attribute. if (count <= 1000) { instanceMatrixNode = (0, _BufferNode.buffer)(instanceMatrix.array, 'mat4', Math.max(count, 1)).element(_IndexNode.instanceIndex); } else { const buffer = new _InstancedInterleavedBuffer.InstancedInterleavedBuffer(instanceMatrix.array, 16, 1); this.buffer = buffer; const bufferFn = instanceMatrix.usage === _constants2.DynamicDrawUsage ? _BufferAttributeNode.instancedDynamicBufferAttribute : _BufferAttributeNode.instancedBufferAttribute; const instanceBuffers = [ // F.Signature -> bufferAttribute( array, type, stride, offset ) bufferFn(buffer, 'vec4', 16, 0), bufferFn(buffer, 'vec4', 16, 4), bufferFn(buffer, 'vec4', 16, 8), bufferFn(buffer, 'vec4', 16, 12)]; instanceMatrixNode = (0, _TSLBase.mat4)(...instanceBuffers); } this.instanceMatrixNode = instanceMatrixNode; } if (instanceColor && instanceColorNode === null) { const buffer = new _InstancedBufferAttribute.InstancedBufferAttribute(instanceColor.array, 3); const bufferFn = instanceColor.usage === _constants2.DynamicDrawUsage ? _BufferAttributeNode.instancedDynamicBufferAttribute : _BufferAttributeNode.instancedBufferAttribute; this.bufferColor = buffer; instanceColorNode = (0, _TSLBase.vec3)(bufferFn(buffer, 'vec3', 3, 0)); this.instanceColorNode = instanceColorNode; } // POSITION const instancePosition = instanceMatrixNode.mul(_Position.positionLocal).xyz; _Position.positionLocal.assign(instancePosition); // NORMAL if (builder.hasGeometryAttribute('normal')) { const instanceNormal = (0, _Normal.transformNormal)(_Normal.normalLocal, instanceMatrixNode); // ASSIGNS _Normal.normalLocal.assign(instanceNormal); } // COLOR if (this.instanceColorNode !== null) { (0, _PropertyNode.varyingProperty)('vec3', 'vInstanceColor').assign(this.instanceColorNode); } } /** * Checks if the internal buffers required an update. * * @param {NodeFrame} frame - The current node frame. */ update( /*frame*/ ) { if (this.instanceMatrix.usage !== _constants2.DynamicDrawUsage && this.buffer !== null && this.instanceMatrix.version !== this.buffer.version) { this.buffer.version = this.instanceMatrix.version; } if (this.instanceColor && this.instanceColor.usage !== _constants2.DynamicDrawUsage && this.bufferColor !== null && this.instanceColor.version !== this.bufferColor.version) { this.bufferColor.version = this.instanceColor.version; } } } var _default = exports.default = InstanceNode; /** * TSL function for creating an instance node. * * @tsl * @function * @param {number} count - The number of instances. * @param {InstancedBufferAttribute} instanceMatrix - Instanced buffer attribute representing the instance transformations. * @param {InstancedBufferAttribute} instanceColor - Instanced buffer attribute representing the instance colors. * @returns {InstanceNode} */ const instance = exports.instance = /*@__PURE__*/(0, _TSLBase.nodeProxy)(InstanceNode).setParameterLength(3);