76 lines
2.0 KiB
TypeScript
76 lines
2.0 KiB
TypeScript
import {
|
|
BufferGeometry,
|
|
Float32BufferAttribute,
|
|
Material,
|
|
Mesh,
|
|
Vector3,
|
|
} from 'three';
|
|
import { WorldChunk } from '../../../common/world/WorldChunk';
|
|
|
|
export class ClientWorldMesher {
|
|
public createGeometry(
|
|
chunk: WorldChunk,
|
|
getHeight: (x: number, y: number) => number,
|
|
getNormal: (x: number, y: number) => Vector3,
|
|
): BufferGeometry {
|
|
const geometry = new BufferGeometry();
|
|
const vertices = [];
|
|
const normals = [];
|
|
const indices = [];
|
|
const uvs = [];
|
|
for (let x = 0; x < chunk.size; x++) {
|
|
for (let y = 0; y < chunk.size; y++) {
|
|
const normal = getNormal(y, x);
|
|
vertices.push(
|
|
(y / chunk.size - 1) * chunk.size,
|
|
getHeight(y, x),
|
|
(x / chunk.size - 1) * chunk.size,
|
|
);
|
|
normals.push(normal.x, normal.y, normal.z);
|
|
uvs.push(y / (chunk.size - 1), x / (chunk.size - 1));
|
|
}
|
|
}
|
|
|
|
for (let x = 0; x < chunk.size - 1; x++) {
|
|
for (let y = 0; y < chunk.size - 1; y++) {
|
|
const topLeft = x * chunk.size + y;
|
|
const topRight = topLeft + 1;
|
|
const bottomLeft = (x + 1) * chunk.size + y;
|
|
const bottomRight = bottomLeft + 1;
|
|
indices.push(
|
|
topLeft,
|
|
bottomLeft,
|
|
topRight,
|
|
topRight,
|
|
bottomLeft,
|
|
bottomRight,
|
|
);
|
|
}
|
|
}
|
|
|
|
geometry.setIndex(indices);
|
|
geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
|
|
geometry.setAttribute('normal', new Float32BufferAttribute(normals, 3));
|
|
geometry.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
|
|
|
|
return geometry;
|
|
}
|
|
|
|
public createTerrainMesh(
|
|
chunk: WorldChunk,
|
|
material: Material,
|
|
getHeight: (x: number, y: number) => number,
|
|
getNormal: (x: number, y: number) => Vector3,
|
|
): Mesh {
|
|
const geometry = this.createGeometry(chunk, getHeight, getNormal);
|
|
const mesh = new Mesh(geometry, material);
|
|
mesh.position.set(
|
|
chunk.size * (chunk.x + 1),
|
|
0,
|
|
chunk.size * (chunk.y + 1),
|
|
);
|
|
|
|
return mesh;
|
|
}
|
|
}
|