UNPKG

@tolokoban/tgd

Version:

ToloGameDev library for WebGL2

397 lines 32.6 kB
import { TgdDataset } from "./../../dataset/index.js"; import { TgdConsole } from "./../../debug/index.js"; import { TgdMat4, TgdTransfo, TgdVec2 } from "./../../math/index.js"; import { TgdProgram } from "./../../program/index.js"; import { TgdShaderFragment, TgdShaderVertex, } from "./../../shader/index.js"; import { isNumber } from "./../../types/guards.js"; import { TgdVertexArray } from "./../../vao/index.js"; import { AccessorProxy } from "./accessor.js"; import { TgdPainterSpritesAbstract } from "./sprites-abstract.js"; const DEBUG_COL_SIZE = 8; export class TgdPainterSprites extends TgdPainterSpritesAbstract { constructor(context, options) { super(); this.context = context; this.options = options; this.transfo = new TgdTransfo(); /** * Number of actual sprites. * * The capacity can be get with `this.dataset.count`. */ this._count = 0; this.sprites = []; /** * Map[id] = index in array `sprites` */ this.spriteIndexes = new Map(); this.attPosition = new AccessorProxy("attPosition"); this.attCos = new AccessorProxy("attCos"); this.attSin = new AccessorProxy("attSin"); this.attScale = new AccessorProxy("attScale"); this.attUV = new AccessorProxy("attUV"); this.attSize = new AccessorProxy("attSize"); this.attOrigin = new AccessorProxy("attOrigin"); this.attributes = {}; this.uniAtlasRatio = new TgdVec2(1, 1); this.dirty = true; this.uniFaceCamera = new TgdMat4(); this.name = `Sprites/${this.name}`; for (const attribName of Object.keys(options.attributes ?? {})) { this.attributes[attribName] = new AccessorProxy(attribName); } const { texture } = options; this.texture = texture; if (texture.width > texture.height) { this.uniAtlasRatio.x = texture.width / texture.height; this.uniAtlasRatio.y = 1; } else { this.uniAtlasRatio.x = 1; this.uniAtlasRatio.y = texture.height / texture.width; } this.uniAtlasRatio.scale(options.atlasUnit ?? 1); const uniforms = { uniTransfoMatrix: "mat4", uniModelViewMatrix: "mat4", uniProjectionMatrix: "mat4", uniAtlasRatio: "vec2", }; if (options.faceCamera) { uniforms.uniFaceCamera = "mat4"; } const prg = new TgdProgram(context.gl, { vert: new TgdShaderVertex({ uniforms, attributes: { ...options.attributes, attPosition: "vec3", attCos: "float", attSin: "float", attScale: "vec2", attUV: "vec3", attSize: "vec2", attOrigin: "vec2", attCorners: "vec4", }, varying: { ...options.varyings, varUV: "vec2", }, functions: extract(options.vert?.functions), mainCode: [ "varUV = attUV.xy + attSize * attCorners.zw;", "vec4 position = vec4((attCorners.xy - attOrigin) * attScale * attSize * uniAtlasRatio, 0.0, 1.0);", "mat4 rotation = mat4(", ["attCos, attSin, 0, 0,", "-attSin, attCos, 0, 0,", "0, 0, 1, 0,", "0, 0, 0, 1"], ");", "position = rotation * position;", ...(options.faceCamera ? ["position = uniFaceCamera * position;"] : []), "position += vec4(attPosition, 0.0);", "gl_Position = uniProjectionMatrix * uniModelViewMatrix * uniTransfoMatrix * position;", extract(options.vert?.code) ?? "", ], }).code, frag: new TgdShaderFragment({ uniforms: { uniTexture: "sampler2D", }, functions: extract(options.frag?.functions), varying: { ...options.varyings, varUV: "vec2", }, outputs: { FragColor: "vec4", }, mainCode: [ "vec4 color = texture(uniTexture, varUV);", `if (color.a < ${1 / 0xff}) discard;`, extract(options.frag?.code) ?? "", "FragColor = color;", ], }).code, }); this.prg = prg; const datasetFrame = new TgdDataset({ /** * (x, y, u, v) */ attCorners: "vec4", }); // prettier-ignore datasetFrame.set("attCorners", new Float32Array([ -1, -1, 0, 1, +1, -1, 1, 1, -1, +1, 0, 0, +1, +1, 1, 0, ])); const datasetInstances = new TgdDataset({ ...options.attributes, attPosition: "vec3", attScale: "vec2", attUV: "vec3", attSize: "vec2", attOrigin: "vec2", attCos: "float", attSin: "float", }, { divisor: 1, usage: "DYNAMIC_DRAW", }); datasetInstances.count = options.initialCapacity ?? 1; this.datasetInstances = datasetInstances; const vao = new TgdVertexArray(context.gl, prg, [datasetInstances, datasetFrame]); this.vao = vao; this.updateAccessors(); } list() { return [...this.sprites]; } forEach(callback) { for (const sprite of this.sprites) callback(sprite); } filter(test) { return this.sprites.filter(test); } get count() { return this._count; } set count(value) { this._count = value; while (value > this.capacity) { this.capacity = 2 * Math.max(1, this.capacity); this.updateAccessors(); } } get capacity() { return this.datasetInstances.count; } set capacity(value) { if (this.datasetInstances.count === value) return; this.datasetInstances.count = value; } /** * Delete all sprites. */ clear() { this.count = 0; this.sprites.splice(0); this.spriteIndexes.clear(); } add(data) { const offset = this.count; this.count++; const info = { id: TgdPainterSprites.id++, index: 0, x: 0, y: 0, z: 0, angle: 0, scaleX: 1, scaleY: 1, ...data, }; const props = { id: info.id, offset, atlas: this.options.atlas, }; const sprite = new Proxy(info, { set: (obj, key, value) => { if (key === "_offset") { props.offset = value; this.dirty = true; return true; } this.interceptSetter(key, value, props); obj[key] = value; this.dirty = true; return true; }, get: (obj, prop) => { if (prop === "_offset") return props.offset; return obj[prop]; }, }); this.initialize(sprite, info); this.sprites[offset] = sprite; this.spriteIndexes.set(sprite.id, offset); this.context.paint(); return sprite; } initialize(sprite, info) { sprite.angle = info.angle; sprite.index = info.index; sprite.scaleX = info.scaleX; sprite.scaleY = info.scaleY; sprite.x = info.x; sprite.y = info.y; sprite.z = info.z; } interceptSetter(key, value, { offset, atlas }) { switch (key) { case "index": { const item = atlas[value]; if (!item) return false; this.attUV.set(item.x, offset, 0); this.attUV.set(item.y, offset, 1); this.attUV.set(item.z ?? 0, offset, 2); this.attSize.set(item.width, offset, 0); this.attSize.set(item.height, offset, 1); this.attOrigin.set(item.originX ?? 0, offset, 0); this.attOrigin.set(item.originY ?? 0, offset, 1); return true; } case "x": this.attPosition.set(value, offset, 0); return true; case "y": this.attPosition.set(value, offset, 1); return true; case "z": this.attPosition.set(value, offset, 2); return true; case "angle": { const angle = value; this.attCos.set(Math.cos(angle), offset); this.attSin.set(Math.sin(angle), offset); return true; } case "scaleX": this.attScale.set(value, offset, 0); return true; case "scaleY": this.attScale.set(value, offset, 1); return true; } return this.options.attributesSetter?.(this.attributes, key, value, offset) ?? false; } remove(sprite) { const index = this.spriteIndexes.get(sprite.id); if (!isNumber(index)) return false; const lastIndex = this.sprites.length - 1; if (lastIndex !== index) { // We need to fill the hole of this deleted sprite // with the last sprite of the list. const lastSprite = this.sprites[lastIndex]; if (!lastSprite) { throw new Error("[TgdPainterSprites.spriteDelete] There is no last sprite!"); } this.datasetInstances.copyAttributes({ fromIndex: lastIndex, toIndex: index, }); this.spriteIndexes.set(lastSprite.id, index); this.sprites[index] = lastSprite; lastSprite._offset = index; } this.sprites.pop(); this.count--; this.spriteIndexes.delete(sprite.id); this.dirty = true; this.context.paint(); return true; } delete() { this.prg.delete(); this.vao.delete(); } paint() { const { context, datasetInstances, vao, prg, transfo, texture, count, uniFaceCamera, options } = this; if (this.dirty) { this.dirty = false; vao.updateDataset(datasetInstances); } const { gl, camera } = context; prg.use(); texture.activate(0, prg, "uniTexture"); prg.uniform2fv("uniAtlasRatio", this.uniAtlasRatio); prg.uniformMatrix4fv("uniTransfoMatrix", transfo.matrix); prg.uniformMatrix4fv("uniModelViewMatrix", camera.matrixModelView); prg.uniformMatrix4fv("uniProjectionMatrix", camera.matrixProjection); if (options.faceCamera) { camera.transfo.orientation.toMatrix(uniFaceCamera); prg.uniformMatrix4fv("uniFaceCamera", uniFaceCamera); } vao.bind(); gl.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, count); vao.unbind(); } debug(caption) { this.transfo.debug("Transfo"); const out = new TgdConsole({ text: caption ?? this.name, bold: true }); out.nl(); out.add("count: ").add(`${this.count}`, { color: "yellow" }).nl(); out.add("capacity: ").add(`${this.capacity}`, { color: "yellow" }).nl(); const spc = " ".repeat(DEBUG_COL_SIZE); const head = (value) => value.slice(0, DEBUG_COL_SIZE).padStart(DEBUG_COL_SIZE, " "); const fields = { position: [this.attPosition, 3], scale: [this.attScale, 2], uv: [this.attUV, 3], size: [this.attSize, 2], origin: [this.attOrigin, 2], cos: [this.attCos, 1], sin: [this.attSin, 1], }; const columns = Object.keys(fields); const hr = `${columns.map(() => "-".repeat(DEBUG_COL_SIZE)).join("|")}|\n`; if (this.count > 0) { out.add(hr) .add(columns.map(head).join("|"), { bold: true, }) .add("|") .nl() .add(hr); for (let index = 0; index < this.count; index++) { for (let dim = 0; dim < 3; dim++) { for (const [accessor, maxDim] of Object.values(fields)) { if (dim < maxDim) { out.add(pad(accessor, index, dim)); } else { out.add(spc); } out.add("|"); } out.nl(); } out.add(hr); } } out.debug(); } updateAccessors() { const { datasetInstances } = this; this.attPosition.dataset = datasetInstances; this.attCos.dataset = datasetInstances; this.attSin.dataset = datasetInstances; this.attScale.dataset = datasetInstances; this.attUV.dataset = datasetInstances; this.attSize.dataset = datasetInstances; this.attOrigin.dataset = datasetInstances; for (const attribute of Object.values(this.attributes)) { attribute.dataset = datasetInstances; } } } TgdPainterSprites.id = 1; function pad(accessor, index, dimension = 0) { return `${accessor.get(index, dimension)}`.slice(0, DEBUG_COL_SIZE).padStart(DEBUG_COL_SIZE, " "); } function extract(arg) { if (arg === null || arg === undefined) return undefined; if (typeof arg !== "function") return arg; return arg(); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3ByaXRlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9wYWludGVyL3Nwcml0ZXMvc3ByaXRlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsVUFBVSxFQUE2QixNQUFNLGNBQWMsQ0FBQTtBQUNwRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBQ3ZDLE9BQU8sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUN4RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBQ3pDLE9BQU8sRUFJSCxpQkFBaUIsRUFDakIsZUFBZSxHQUNsQixNQUFNLGFBQWEsQ0FBQTtBQUdwQixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDNUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUN6QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBQzFDLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLG9CQUFvQixDQUFBO0FBNEM5RCxNQUFNLGNBQWMsR0FBRyxDQUFDLENBQUE7QUFJeEIsTUFBTSxPQUFPLGlCQUFtRCxTQUFRLHlCQUF1QztJQWdDM0csWUFDdUIsT0FBbUIsRUFDbkIsT0FBaUM7UUFFcEQsS0FBSyxFQUFFLENBQUE7UUFIWSxZQUFPLEdBQVAsT0FBTyxDQUFZO1FBQ25CLFlBQU8sR0FBUCxPQUFPLENBQTBCO1FBakN4QyxZQUFPLEdBQUcsSUFBSSxVQUFVLEVBQUUsQ0FBQTtRQU0xQzs7OztXQUlHO1FBQ08sV0FBTSxHQUFHLENBQUMsQ0FBQTtRQUNELFlBQU8sR0FBZ0IsRUFBRSxDQUFBO1FBQzVDOztXQUVHO1FBQ2dCLGtCQUFhLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUE7UUFDekMsZ0JBQVcsR0FBRyxJQUFJLGFBQWEsQ0FBQyxhQUFhLENBQUMs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