@spearwolf/twopoint5d
Version:
a library to create 2.5d realtime graphics and pixelart with three.js
130 lines • 4.78 kB
JavaScript
import { BufferAttribute, BufferGeometry, InterleavedBuffer, InterleavedBufferAttribute } from 'three';
import { VOBufferPool } from './VOBufferPool.js';
import { VertexObjectDescriptor } from './VertexObjectDescriptor.js';
import { initializeAttributes } from './initializeAttributes.js';
import { selectAttributes } from './selectAttributes.js';
import { selectBuffers } from './selectBuffers.js';
import { updateUpdateRange } from './updateUpdateRange.js';
export class VOBufferGeometry extends BufferGeometry {
constructor(source, capacity) {
super();
this.buffers = new Map();
this.bufferSerials = new Map();
this.#serials = new Map();
this.#updateAttributes = new Map();
this.#firstAutoTouch = true;
this.pool = source instanceof VOBufferPool ? source : new VOBufferPool(source, capacity);
this.name = 'VOBufferGeometry';
initializeAttributes(this, this.pool, this.buffers, this.bufferSerials);
}
dispose() {
this.pool.clear();
super.dispose();
}
touchAttributes(...attrNames) {
selectAttributes(this.pool, this.buffers, attrNames).forEach((buffer) => {
buffer.needsUpdate = true;
});
}
touchBuffers(bufferTypes) {
selectBuffers(this.buffers, bufferTypes).forEach((buffer) => {
buffer.needsUpdate = true;
});
}
touch(...args) {
const attrNames = [];
let buffers = undefined;
args.forEach((arg) => {
if (typeof arg === 'string') {
attrNames.push(arg);
}
else {
buffers = { ...buffers, ...arg };
}
});
if (attrNames.length) {
this.touchAttributes(...attrNames);
}
if (buffers) {
this.touchBuffers(buffers);
}
}
update() {
this.#updateDrawRange();
this.#checkBufferSerials();
this.#autoTouchAttributes();
this.#updateBuffersUpdateRange();
this.#syncAttributeArrays();
}
#serials;
#updateAttributes;
#syncAttributeArrays() {
this.#updateAttributes.clear();
for (const [attrName, attr] of Object.entries(this.attributes)) {
const bufAttr = attr.isInterleavedBufferAttribute
? attr.data
: attr;
const version = bufAttr.version;
if (this.#serials.has(attrName)) {
if (this.#serials.get(attrName) !== version) {
this.#updateAttributes.set(attrName, bufAttr);
this.#serials.set(attrName, version);
}
}
else {
this.#updateAttributes.set(attrName, bufAttr);
this.#serials.set(attrName, version);
}
}
for (const [attrName, bufAttr] of this.#updateAttributes) {
const poolBufInfo = this.pool.buffer.bufferAttributes.get(attrName);
if (poolBufInfo) {
const poolBuf = this.pool.buffer.buffers.get(poolBufInfo.bufferName);
if (poolBuf) {
bufAttr.array = poolBuf.typedArray;
}
}
}
}
#checkBufferSerials() {
for (const [bufferName, buffer] of this.buffers) {
const serial = this.bufferSerials.get(bufferName);
const bufSerial = this.pool.buffer.buffers.get(bufferName).serial;
if (serial !== bufSerial) {
buffer.needsUpdate = true;
this.bufferSerials.set(bufferName, bufSerial);
}
}
}
#updateBuffersUpdateRange() {
updateUpdateRange(this.pool, this.buffers);
}
#updateDrawRange() {
this.setDrawRange(0, this.pool.descriptor.hasIndices
? this.pool.usedCount * this.pool.descriptor.indices.length
: this.pool.usedCount * this.pool.descriptor.vertexCount);
}
#firstAutoTouch;
#autoTouchAttributes() {
if (this.pool.usedCount === 0)
return;
if (this.#firstAutoTouch) {
this.touchBuffers({ static: true });
this.#firstAutoTouch = false;
}
const autoTouchAttrs = this.#getAutoTouchAttributeNames();
if (autoTouchAttrs.length) {
this.touchAttributes(...autoTouchAttrs);
}
}
#autoTouchAttrNames;
#getAutoTouchAttributeNames() {
if (!this.#autoTouchAttrNames) {
this.#autoTouchAttrNames = Array.from(this.pool.descriptor.attributes.values())
.filter((attr) => attr.autoTouch)
.map((attr) => attr.name);
}
return this.#autoTouchAttrNames;
}
}
//# sourceMappingURL=VOBufferGeometry.js.map