@spearwolf/twopoint5d
Version:
a library to create 2.5d realtime graphics and pixelart with three.js
129 lines • 4.64 kB
JavaScript
import { Box3, Box3Helper, Color, Object3D, Vector2, Vector3 } from 'three';
import { AABB2 } from './AABB2.js';
import { HelpersManager } from './HelpersManager.js';
import { Map2DTile } from './Map2DTile.js';
import { Map2DTileCoordsUtil } from './Map2DTileCoordsUtil.js';
export class RectangularVisibilityArea {
#width;
#height;
#viewRect;
#tileCreated;
#showHelpers;
#helpers;
constructor(width = 320, height = 240) {
this.#width = 0;
this.#height = 0;
this.needsUpdate = true;
this.viewRectHelperHeight = 20;
this.viewRectHelperColor = new Color(0xfff066);
this.#viewRect = undefined;
this.#showHelpers = false;
this.#helpers = new HelpersManager();
this.width = width;
this.height = height;
}
get width() {
return this.#width;
}
set width(width) {
if (this.#width !== width) {
this.#width = width;
this.needsUpdate = true;
}
}
get height() {
return this.#height;
}
set height(height) {
if (this.#height !== height) {
this.#height = height;
this.needsUpdate = true;
}
}
computeVisibleTiles(previousTiles, [centerX, centerY], map2dTileCoords, node) {
if (this.width === 0 || this.height === 0) {
return undefined;
}
const { width, height } = this;
const halfWidth = width / 2;
const halfHeight = height / 2;
const left = centerX - halfWidth;
const top = centerY - halfHeight;
const viewRectHelperHalfHeight = this.viewRectHelperHeight / 2;
this.#viewRect = new Box3(new Vector3(-halfWidth, -viewRectHelperHalfHeight, -halfHeight), new Vector3(halfWidth, viewRectHelperHalfHeight, halfHeight));
const tileCoords = map2dTileCoords.computeTilesWithinCoords(left, top, width, height);
const fullViewArea = AABB2.from(tileCoords);
const removeTiles = [];
const reuseTiles = [];
const tilesLength = tileCoords.rows * tileCoords.columns;
let tileCreated = this.#tileCreated;
if (tileCreated == null || tileCreated.length < tilesLength) {
this.#tileCreated = new Uint8Array(tilesLength);
tileCreated = this.#tileCreated;
}
else {
tileCreated.fill(0);
}
previousTiles.forEach((tile) => {
if (fullViewArea.isIntersecting(tile.view)) {
reuseTiles.push(tile);
const tx = tile.x - tileCoords.tileLeft;
const ty = tile.y - tileCoords.tileTop;
tileCreated[ty * tileCoords.columns + tx] = 1;
}
else {
removeTiles.push(tile);
}
});
const createTiles = [];
for (let ty = 0; ty < tileCoords.rows; ty++) {
for (let tx = 0; tx < tileCoords.columns; tx++) {
if (tileCreated[ty * tileCoords.columns + tx] === 0) {
const tileX = tx + tileCoords.tileLeft;
const tileY = ty + tileCoords.tileTop;
const tile = new Map2DTile(tileX, tileY, new AABB2(tileX * tileCoords.tileWidth, tileY * tileCoords.tileHeight, tileCoords.tileWidth, tileCoords.tileHeight));
createTiles.push(tile);
}
}
}
if (this.showHelpers) {
this.updateHelpers();
}
const offset = new Vector2(map2dTileCoords.xOffset - centerX, map2dTileCoords.yOffset - centerY);
const translate = new Vector3().setFromMatrixPosition(node.matrixWorld);
return {
tiles: reuseTiles.concat(createTiles),
offset,
translate,
removeTiles,
createTiles,
reuseTiles,
};
}
get showHelpers() {
return this.#showHelpers;
}
set showHelpers(showHelpers) {
if (this.#showHelpers && !showHelpers) {
this.#helpers.remove();
}
else if (!this.#showHelpers && showHelpers) {
this.updateHelpers();
}
this.#showHelpers = showHelpers;
}
addToScene(scene) {
this.#helpers.scene = scene;
}
removeFromScene(scene) {
this.#helpers.removeFromScene(scene);
}
updateHelpers() {
this.#helpers.remove();
if (this.#viewRect) {
const helper = new Box3Helper(this.#viewRect, this.viewRectHelperColor);
this.#helpers.add(helper);
}
}
}
//# sourceMappingURL=RectangularVisibilityArea.js.map