@tolokoban/tgd
Version:
ToloGameDev library for WebGL2
397 lines • 32.6 kB
JavaScript
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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