UNPKG

@pixi/core

Version:
200 lines (195 loc) 6.5 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var constants = require('@pixi/constants'); var runner = require('@pixi/runner'); var utils = require('@pixi/utils'); var Attribute = require('./Attribute.js'); var Buffer = require('./Buffer.js'); var interleaveTypedArrays = require('./utils/interleaveTypedArrays.js'); const byteSizeMap = { 5126: 4, 5123: 2, 5121: 1 }; let UID = 0; const map = { Float32Array, Uint32Array, Int32Array, Uint8Array, Uint16Array }; class Geometry { constructor(buffers = [], attributes = {}) { this.buffers = buffers; this.indexBuffer = null; this.attributes = attributes; this.glVertexArrayObjects = {}; this.id = UID++; this.instanced = false; this.instanceCount = 1; this.disposeRunner = new runner.Runner("disposeGeometry"); this.refCount = 0; } addAttribute(id, buffer, size = 0, normalized = false, type, stride, start, instance = false) { if (!buffer) { throw new Error("You must pass a buffer when creating an attribute"); } if (!(buffer instanceof Buffer.Buffer)) { if (buffer instanceof Array) { buffer = new Float32Array(buffer); } buffer = new Buffer.Buffer(buffer); } const ids = id.split("|"); if (ids.length > 1) { for (let i = 0; i < ids.length; i++) { this.addAttribute(ids[i], buffer, size, normalized, type); } return this; } let bufferIndex = this.buffers.indexOf(buffer); if (bufferIndex === -1) { this.buffers.push(buffer); bufferIndex = this.buffers.length - 1; } this.attributes[id] = new Attribute.Attribute(bufferIndex, size, normalized, type, stride, start, instance); this.instanced = this.instanced || instance; return this; } getAttribute(id) { return this.attributes[id]; } getBuffer(id) { return this.buffers[this.getAttribute(id).buffer]; } addIndex(buffer) { if (!(buffer instanceof Buffer.Buffer)) { if (buffer instanceof Array) { buffer = new Uint16Array(buffer); } buffer = new Buffer.Buffer(buffer); } buffer.type = constants.BUFFER_TYPE.ELEMENT_ARRAY_BUFFER; this.indexBuffer = buffer; if (!this.buffers.includes(buffer)) { this.buffers.push(buffer); } return this; } getIndex() { return this.indexBuffer; } interleave() { if (this.buffers.length === 1 || this.buffers.length === 2 && this.indexBuffer) return this; const arrays = []; const sizes = []; const interleavedBuffer = new Buffer.Buffer(); let i; for (i in this.attributes) { const attribute = this.attributes[i]; const buffer = this.buffers[attribute.buffer]; arrays.push(buffer.data); sizes.push(attribute.size * byteSizeMap[attribute.type] / 4); attribute.buffer = 0; } interleavedBuffer.data = interleaveTypedArrays.interleaveTypedArrays(arrays, sizes); for (i = 0; i < this.buffers.length; i++) { if (this.buffers[i] !== this.indexBuffer) { this.buffers[i].destroy(); } } this.buffers = [interleavedBuffer]; if (this.indexBuffer) { this.buffers.push(this.indexBuffer); } return this; } getSize() { for (const i in this.attributes) { const attribute = this.attributes[i]; const buffer = this.buffers[attribute.buffer]; return buffer.data.length / (attribute.stride / 4 || attribute.size); } return 0; } dispose() { this.disposeRunner.emit(this, false); } destroy() { this.dispose(); this.buffers = null; this.indexBuffer = null; this.attributes = null; } clone() { const geometry = new Geometry(); for (let i = 0; i < this.buffers.length; i++) { geometry.buffers[i] = new Buffer.Buffer(this.buffers[i].data.slice(0)); } for (const i in this.attributes) { const attrib = this.attributes[i]; geometry.attributes[i] = new Attribute.Attribute(attrib.buffer, attrib.size, attrib.normalized, attrib.type, attrib.stride, attrib.start, attrib.instance); } if (this.indexBuffer) { geometry.indexBuffer = geometry.buffers[this.buffers.indexOf(this.indexBuffer)]; geometry.indexBuffer.type = constants.BUFFER_TYPE.ELEMENT_ARRAY_BUFFER; } return geometry; } static merge(geometries) { const geometryOut = new Geometry(); const arrays = []; const sizes = []; const offsets = []; let geometry; for (let i = 0; i < geometries.length; i++) { geometry = geometries[i]; for (let j = 0; j < geometry.buffers.length; j++) { sizes[j] = sizes[j] || 0; sizes[j] += geometry.buffers[j].data.length; offsets[j] = 0; } } for (let i = 0; i < geometry.buffers.length; i++) { arrays[i] = new map[utils.getBufferType(geometry.buffers[i].data)](sizes[i]); geometryOut.buffers[i] = new Buffer.Buffer(arrays[i]); } for (let i = 0; i < geometries.length; i++) { geometry = geometries[i]; for (let j = 0; j < geometry.buffers.length; j++) { arrays[j].set(geometry.buffers[j].data, offsets[j]); offsets[j] += geometry.buffers[j].data.length; } } geometryOut.attributes = geometry.attributes; if (geometry.indexBuffer) { geometryOut.indexBuffer = geometryOut.buffers[geometry.buffers.indexOf(geometry.indexBuffer)]; geometryOut.indexBuffer.type = constants.BUFFER_TYPE.ELEMENT_ARRAY_BUFFER; let offset = 0; let stride = 0; let offset2 = 0; let bufferIndexToCount = 0; for (let i = 0; i < geometry.buffers.length; i++) { if (geometry.buffers[i] !== geometry.indexBuffer) { bufferIndexToCount = i; break; } } for (const i in geometry.attributes) { const attribute = geometry.attributes[i]; if ((attribute.buffer | 0) === bufferIndexToCount) { stride += attribute.size * byteSizeMap[attribute.type] / 4; } } for (let i = 0; i < geometries.length; i++) { const indexBufferData = geometries[i].indexBuffer.data; for (let j = 0; j < indexBufferData.length; j++) { geometryOut.indexBuffer.data[j + offset2] += offset; } offset += geometries[i].buffers[bufferIndexToCount].data.length / stride; offset2 += indexBufferData.length; } } return geometryOut; } } exports.Geometry = Geometry; //# sourceMappingURL=Geometry.js.map