41 lines
1.3 KiB
TypeScript
41 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/';
|
|
|
|
export class ClientWorldLoader implements WorldLoader {
|
|
async loadHeightMap(chunkX: number, chunkY: number): Promise<number[]> {
|
|
return new Promise((resolve, reject) => {
|
|
loader.load(
|
|
`${worldPath}/height-${chunkX}-${chunkY}.png`,
|
|
(data) => resolve(ClientWorldLoader.heightFromImage(data)),
|
|
undefined,
|
|
(err) => {
|
|
reject(err);
|
|
},
|
|
);
|
|
});
|
|
}
|
|
|
|
public static heightFromImage(image: HTMLImageElement): 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] * 32) / 255;
|
|
}
|
|
}
|
|
|
|
return array;
|
|
}
|
|
}
|