UNPKG

@spearwolf/twopoint5d

Version:

Create 2.5D realtime graphics and pixelart with WebGL and three.js

115 lines 3.87 kB
import { VOBufferPool } from './VOBufferPool.js'; import { VOUtils } from './VOUtils.js'; import { VertexObjectBuffer } from './VertexObjectBuffer.js'; import { createVertexObject } from './createVertexObject.js'; import { voBuffer } from './constants.js'; export class VertexObjectPool extends VOBufferPool { #voIndex; constructor(descriptor, capacityOrData) { super(descriptor, capacityOrData); this.#voIndex = new Array(this.capacity); } resize(capacity) { if (capacity < 0 || !Number.isInteger(capacity)) { throw new Error('Capacity must be a non-negative integer'); } if (capacity === this.capacity) return; const newBuffer = new VertexObjectBuffer(this.descriptor, capacity); const copyCount = Math.min(this.usedCount, capacity); if (copyCount > 0) { const { vertexCount } = this.descriptor; for (const [bufferName, oldBuf] of this.buffer.buffers) { const newBuf = newBuffer.buffers.get(bufferName); const copyLength = copyCount * vertexCount * oldBuf.itemSize; newBuf.typedArray.set(oldBuf.typedArray.subarray(0, copyLength)); newBuf.serial++; } } this.buffer = newBuffer; const newVoIndex = new Array(capacity); for (let i = 0; i < copyCount; i++) { const vo = this.#voIndex[i]; if (vo != null) { vo[voBuffer] = newBuffer; newVoIndex[i] = vo; } } this.#voIndex = newVoIndex; Object.defineProperty(this, 'capacity', { value: capacity, writable: false, enumerable: true, configurable: true, }); this.usedCount = Math.min(this.usedCount, capacity); } createVO() { if (this.usedCount < this.capacity) { const idx = this.usedCount++; const vo = this.#createVO(idx); this.#voIndex[idx] = vo; return vo; } return undefined; } containsVO(vo) { return VOUtils.isBuffer(vo, this.buffer); } dispose() { if (this.isDisposed) return; for (let i = 0; i < this.#voIndex.length; i++) { const vo = this.#voIndex[i]; if (vo != null) { if (this.onDestroyVO != null) { this.onDestroyVO(vo); } VOUtils.clearBuffer(vo); } } this.#voIndex.length = 0; super.dispose(); } freeVO(vo) { if (!this.containsVO(vo)) return; const idx = VOUtils.getIndex(vo); const lastUsedIdx = this.usedCount - 1; if (idx === lastUsedIdx) { this.#destroyVO(idx); } else { this.buffer.copyWithin(idx, lastUsedIdx, lastUsedIdx + 1); const lastUsedVO = this.#voIndex[lastUsedIdx]; VOUtils.setIndex(lastUsedVO, idx); this.#voIndex[idx] = lastUsedVO; } this.usedCount--; VOUtils.clearBuffer(vo); } getVO(idx) { let vo = this.#voIndex[idx]; if (vo == null && idx < this.usedCount) { vo = this.#createVO(idx); this.#voIndex[idx] = vo; } return vo; } #destroyVO(idx) { const vo = this.#voIndex[idx]; if (vo != null && this.onDestroyVO != null) { this.onDestroyVO(vo); } this.#voIndex[idx] = undefined; } #createVO(idx) { const vo = createVertexObject(this.descriptor, this.buffer, idx); this.buffer.touch(); if (this.onCreateVO != null) { return this.onCreateVO(vo) ?? vo; } return vo; } } //# sourceMappingURL=VertexObjectPool.js.map