icy3dw/src/common/world/WorldManager.ts

87 lines
2.1 KiB
TypeScript

import { to1D } from '../convert';
import { WorldChunk } from './WorldChunk';
import { WorldLoader } from './WorldLoader';
import { WorldManifest } from './WorldManifest';
export class WorldManager {
protected _chunks!: WorldChunk[];
constructor(public loader: WorldLoader, public manifest: WorldManifest) {
this._chunks = new Array(this.worldWidth * this.worldHeight);
}
public get worldWidth() {
return this.manifest.worldWidth;
}
public get worldHeight() {
return this.manifest.worldHeight;
}
public get worldChunkSize() {
return this.manifest.worldChunkSize;
}
async loadHeightData(chunkX: number, chunkY: number) {
const heightData = await this.loader.loadHeightMap(
chunkX,
chunkY,
this.manifest.worldHeightScale,
);
this._chunks[to1D(chunkX, chunkY, this.worldWidth)] = new WorldChunk(
heightData,
chunkX,
chunkY,
this.worldChunkSize,
this.manifest.regionMap.find(({ x, y }) => x === chunkX && y === chunkY),
);
}
async loadWorld() {
for (let x = 0; x < this.worldWidth; x++) {
for (let y = 0; y < this.worldHeight; y++) {
await this.loadHeightData(x, y);
}
}
}
getPointHeight(x: number, y: number): number {
const chunkX = Math.floor(x / this.worldChunkSize);
const chunkY = Math.floor(y / this.worldChunkSize);
if (
chunkX >= this.worldWidth ||
chunkY >= this.worldHeight ||
x < 0 ||
y < 0
) {
return 0;
}
return this._chunks[to1D(chunkX, chunkY, this.worldWidth)].getPoint(
x - chunkX * this.worldChunkSize,
y - chunkY * this.worldChunkSize,
);
}
getHeight(x: number, y: number): number {
const chunkX = Math.floor(x / this.worldChunkSize);
const chunkY = Math.floor(y / this.worldChunkSize);
if (
chunkX >= this.worldWidth ||
chunkY >= this.worldHeight ||
x < 0 ||
y < 0
) {
return 0;
}
return this._chunks[
to1D(chunkX, chunkY, this.worldWidth)
].getInterpolatedPoint(
x - chunkX * this.worldChunkSize,
y - chunkY * this.worldChunkSize,
);
}
}