@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
243 lines (166 loc) • 6.09 kB
JavaScript
import { assert } from "../../../../../core/assert.js";
import LabelView from "../../../../../view/common/LabelView.js";
import { CSS_ABSOLUTE_POSITIONING } from "../../../../../view/CSS_ABSOLUTE_POSITIONING.js";
import EmptyView from "../../../../../view/elements/EmptyView.js";
import { decompose_finger_print } from "../tile/decompose_finger_print.js";
import { tile_address_to_finger_print } from "../tile/tile_address_to_finger_print.js";
class TextureLODView extends EmptyView {
/**
*
* @type {View[]}
*/
#tiles = [];
#resolution = [1, 1];
constructor({
resolution = [1, 1],
tile_size = 8
}) {
super({ css: CSS_ABSOLUTE_POSITIONING });
this.css({
background: "rgba(255,255,255,0.05)"
});
this.#resolution = resolution;
const width = resolution[0];
const height = resolution[1];
assert.isNonNegativeInteger(width, 'width');
assert.isNonNegativeInteger(height, 'height');
for (let j = 0; j < height; j++) {
for (let i = 0; i < width; i++) {
const tileView = new EmptyView({ css: CSS_ABSOLUTE_POSITIONING });
// const flipped_y = height - j - 1;
tileView.position.set(i * tile_size, j * tile_size);
// tileView.position.set(i * tile_size, flipped_y * tile_size);
tileView.size.set(tile_size, tile_size);
this.clearTile(tileView);
this.#tiles.push(tileView)
this.addChild(tileView);
}
}
this.size.set(width * tile_size, height * tile_size);
const label = new LabelView(`${width} x ${height}`, {
css: {
...CSS_ABSOLUTE_POSITIONING,
color: '#FFFFFF',
textShadow: '0 0 2px black',
whiteSpace: "pre"
}
});
label.position.set(this.size.x + 4, (this.size.y - 20) * 0.5);
this.addChild(label);
}
clear() {
const resolution = this.#resolution;
const count = resolution[0] * resolution[1];
for (let i = 0; i < count; i++) {
const view = this.#tiles[i];
this.clearTile(view);
}
}
/**
*
* @param {View} view
*/
clearTile(view) {
view.css({
background: "none"
});
view.visible = false;
}
getTile(x, y) {
assert.isNonNegativeInteger(x, 'x');
assert.isNonNegativeInteger(y, 'y');
const resolution = this.#resolution;
// assert.lessThan(x, resolution[0]);
// assert.lessThan(y, resolution[1]);
const width = resolution[0];
const view = this.#tiles[x + width * y];
if (view === undefined) {
debugger
}
return view;
}
}
export class UsagePyramidDebugView extends EmptyView {
#levels = [];
#resolution = [1, 1];
#tile_size = 0;
#used_set = [];
#used_set_size = 0;
#image_url = null
setImageURL(url) {
this.#image_url = url;
this.#applyImageURL();
}
#applyImageURL() {
const background = {
backgroundImage: this.#image_url === null ? "none" : `url(${this.#image_url})`,
backgroundSize: "contain"
};
this.#levels.forEach(l => {
l.css(background);
});
}
setTextureParameters(resolution, tile_size) {
if (this.#resolution[0] === resolution && this.#resolution[1] === resolution && this.#tile_size === tile_size) {
return;
}
this.#tile_size = tile_size;
this.#resolution = [resolution, resolution];
this.#levels.splice(0, this.#levels.length);
this.removeAllChildren();
let size = resolution / tile_size;
assert.isNonNegativeInteger(size, 'size');
while (size > 0) {
const lod = new TextureLODView({
resolution: [size, size],
});
lod.css({
border: "1px solid rgba(0,0,0,0.7)"
});
this.#levels.push(lod);
this.addChild(lod);
size >>>= 1;
}
this.#levels.reverse();
let y = 0;
for (let i = 0; i < this.#levels.length; i++) {
const level = this.#levels[i];
level.position.set(2, y);
y += level.size.y + 4;
}
this.#applyImageURL();
}
/**
*
* @param {VirtualTextureUsage} usage
*/
set usage(usage) {
for (let i = 0; i < this.#used_set_size; i++) {
const finger_print = this.#used_set[i];
const { mip, x, y } = decompose_finger_print(finger_print);
const mipView = this.#levels[mip];
const tile = mipView.getTile(x, y);
mipView.clearTile(tile);
}
this.#used_set_size = 0;
const occupancy = usage.occupancy;
const occupancyCount = usage.occupancy_count;
for (let i = 0; i < occupancyCount; i++) {
const occupancy_index = occupancy[i];
const fingerPrint = tile_address_to_finger_print(occupancy_index);
const count = usage.getCountByFingerprint(fingerPrint);
if (count <= 0) {
continue;
}
const { mip, x, y } = decompose_finger_print(fingerPrint);
const mipView = this.#levels[mip];
const tile = mipView.getTile(x, y);
tile.css({
background: "rgba(255,0,0,0.8)"
});
tile.visible = true;
this.#used_set[this.#used_set_size] = fingerPrint;
this.#used_set_size++;
}
}
}