icy3dw/src/common/world/WorldChunk.ts

52 lines
1.6 KiB
TypeScript

import { Vector3, Vector2 } from 'three';
import { to1D } from '../convert';
import { barycentricPoint } from '../helper';
import { WorldManifestRegion } from './WorldManifest';
export class WorldChunk {
constructor(
public heightData: number[],
public x: number,
public y: number,
public size: number,
public region: WorldManifestRegion,
public scaledSize = size,
) {}
public getPoint(x: number, y: number): number {
return this.heightData[to1D(Math.floor(x), Math.floor(y), this.size)];
}
public getInterpolatedPoint(x: number, y: number): number {
const terrainX = x - this.x * this.size;
const terrainY = y - this.y * this.size;
const gridSquareSize = this.scaledSize / this.size;
const gridX = Math.floor(x / gridSquareSize);
const gridY = Math.floor(y / gridSquareSize);
if (gridX >= this.size || gridY >= this.size || gridX < 0 || gridY < 0) {
return 0;
}
const xCoord = (terrainX % gridSquareSize) / gridSquareSize;
const yCoord = (terrainY % gridSquareSize) / gridSquareSize;
let result: number;
if (xCoord <= 1 - yCoord) {
result = barycentricPoint(
new Vector3(0, this.getPoint(gridX, gridY), 0),
new Vector3(1, this.getPoint(gridX + 1, gridY), 0),
new Vector3(0, this.getPoint(gridX, gridY + 1), 1),
new Vector2(xCoord, yCoord),
);
} else {
result = barycentricPoint(
new Vector3(1, this.getPoint(gridX + 1, gridY), 0),
new Vector3(1, this.getPoint(gridX + 1, gridY + 1), 1),
new Vector3(0, this.getPoint(gridX, gridY + 1), 1),
new Vector2(xCoord, yCoord),
);
}
return result;
}
}