48 lines
1.3 KiB
TypeScript
48 lines
1.3 KiB
TypeScript
import { ImageLoader } from 'three';
|
|
import { to1D } from '../../../common/convert';
|
|
import { WorldLoader } from '../../../common/world/WorldLoader';
|
|
|
|
const loader = new ImageLoader();
|
|
const worldPath = '/assets/terrain/region/';
|
|
|
|
export class ClientWorldLoader implements WorldLoader {
|
|
async loadHeightMap(
|
|
chunkX: number,
|
|
chunkY: number,
|
|
scale: number,
|
|
): Promise<number[]> {
|
|
return new Promise((resolve, reject) => {
|
|
loader.load(
|
|
`${worldPath}/height-${chunkX}-${chunkY}.png`,
|
|
(data) => resolve(ClientWorldLoader.heightFromImage(data, scale)),
|
|
undefined,
|
|
(err) => {
|
|
reject(err);
|
|
},
|
|
);
|
|
});
|
|
}
|
|
|
|
public static heightFromImage(
|
|
image: HTMLImageElement,
|
|
scale: number,
|
|
): number[] {
|
|
const array = new Array(image.width * image.height);
|
|
const ctx = document.createElement('canvas').getContext('2d');
|
|
ctx.canvas.width = image.width;
|
|
ctx.canvas.height = image.height;
|
|
ctx.drawImage(image, 0, 0, image.width, image.height);
|
|
|
|
// pixel data
|
|
const data = ctx.getImageData(0, 0, image.width, image.height);
|
|
for (let x = 0; x < image.width; x++) {
|
|
for (let y = 0; y < image.height; y++) {
|
|
const index = to1D(x, y, image.width);
|
|
array[index] = (data.data[index * 4] * scale) / 255;
|
|
}
|
|
}
|
|
|
|
return array;
|
|
}
|
|
}
|