// luma.gl // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors import { assert, checkProps } from '@luma.gl/core'; import { GL } from '@luma.gl/constants'; import { getTypedArrayFromGLType } from "./typed-array-utils.js"; const DEFAULT_ACCESSOR_VALUES = { offset: 0, stride: 0, type: 5126, size: 1, divisor: 0, normalized: false, integer: false }; const PROP_CHECKS = { deprecatedProps: { instanced: 'divisor', isInstanced: 'divisor' } }; export class Accessor { offset; stride; type; size; divisor; normalized; integer; buffer; index; static getBytesPerElement(accessor) { // TODO: using `FLOAT` when type is not specified, // ensure this assumption is valid or force API to specify type. const ArrayType = getTypedArrayFromGLType(accessor.type || 5126); return ArrayType.BYTES_PER_ELEMENT; } static getBytesPerVertex(accessor) { assert(accessor.size); // TODO: using `FLOAT` when type is not specified, // ensure this assumption is valid or force API to specify type. const ArrayType = getTypedArrayFromGLType(accessor.type || 5126); return ArrayType.BYTES_PER_ELEMENT * accessor.size; } // Combines (merges) a list of accessors. On top of default values // Usually [programAccessor, bufferAccessor, appAccessor] // All props will be set in the returned object. // TODO check for conflicts between values in the supplied accessors static resolve(...accessors) { return new Accessor(...[DEFAULT_ACCESSOR_VALUES, ...accessors]); // Default values } constructor(...accessors) { accessors.forEach(accessor => this._assign(accessor)); // Merge in sequence Object.freeze(this); } toString() { return JSON.stringify(this); } // ACCESSORS // TODO - remove> get BYTES_PER_ELEMENT() { return Accessor.getBytesPerElement(this); } get BYTES_PER_VERTEX() { return Accessor.getBytesPerVertex(this); } // PRIVATE // eslint-disable-next-line complexity, max-statements _assign(props = {}) { props = checkProps('Accessor', props, PROP_CHECKS); if (props.type !== undefined) { this.type = props.type; // Auto-deduce integer type? if (props.type === 5124 || props.type === 5125) { this.integer = true; } } if (props.size !== undefined) { this.size = props.size; } if (props.offset !== undefined) { this.offset = props.offset; } if (props.stride !== undefined) { this.stride = props.stride; } // @ts-expect-error if (props.normalize !== undefined) { // @ts-expect-error this.normalized = props.normalize; } if (props.normalized !== undefined) { this.normalized = props.normalized; } if (props.integer !== undefined) { this.integer = props.integer; } // INSTANCE DIVISOR if (props.divisor !== undefined) { this.divisor = props.divisor; } // Buffer is optional if (props.buffer !== undefined) { this.buffer = props.buffer; } // The binding index (for binding e.g. Transform feedbacks and Uniform buffers) // TODO - should this be part of accessor? if (props.index !== undefined) { if (typeof props.index === 'boolean') { this.index = props.index ? 1 : 0; } else { this.index = props.index; } } // DEPRECATED // @ts-expect-error if (props.instanced !== undefined) { // @ts-expect-error this.divisor = props.instanced ? 1 : 0; } // @ts-expect-error if (props.isInstanced !== undefined) { // @ts-expect-error this.divisor = props.isInstanced ? 1 : 0; } if (this.offset === undefined) delete this.offset; if (this.stride === undefined) delete this.stride; if (this.type === undefined) delete this.type; if (this.size === undefined) delete this.size; if (this.divisor === undefined) delete this.divisor; if (this.normalized === undefined) delete this.normalized; if (this.integer === undefined) delete this.integer; if (this.buffer === undefined) delete this.buffer; if (this.index === undefined) delete this.index; return this; } } // TEST EXPORTS export { DEFAULT_ACCESSOR_VALUES };