bd13495923
Gebaeude-Footprints (swisstopo vec25) werden jetzt zu Volumen extrudiert (z=0 bis Hoehe; Hoehe aus OSM height/building:levels, sonst 9 m; Deckel/ Boden via Delaunay, konkave Grundrisse) und als importedMesh gerendert — der flache Footprint-contourSet bleibt fuer den 2D-Plan erhalten. Neuer Terrain-Abruf (swissALTI3D ueber den CORS-faehigen profile.json-Dienst, zeilenweise parallel) liefert ein N-Raster, das terrainMeshFromGrid trianguliert; Hoehen aufs Zentrum bezogen, lagerichtig zu den Gebaeuden. Neue Quelle 'Swisstopo-Gelaende' im Import-Dialog. Viewport3D unveraendert (bestehender importedMesh/terrainMesh-Pfad). 8 neue Tests.
57 lines
1.6 KiB
TypeScript
57 lines
1.6 KiB
TypeScript
// Tests für den Terrain-Mesh-Aufbau aus einem regulären Höhenraster
|
||
// (swisstopo-DTM-Profilraster → terrainMeshFromGrid).
|
||
|
||
import { describe, it, expect } from "vitest";
|
||
import { terrainMeshFromGrid } from "./terrain";
|
||
import type { TerrainGrid } from "./terrain";
|
||
|
||
describe("terrainMeshFromGrid", () => {
|
||
it("baut ein vollständiges Quad-Gitter (3×3 → 8 Dreiecke)", () => {
|
||
const grid: TerrainGrid = {
|
||
xs: [0, 10, 20],
|
||
ys: [0, 10, 20],
|
||
z: [
|
||
[1, 2, 3],
|
||
[2, 3, 4],
|
||
[3, 4, 5],
|
||
],
|
||
};
|
||
const mesh = terrainMeshFromGrid(grid);
|
||
expect(mesh.type).toBe("terrainMesh");
|
||
// 9 Vertices × 3 Komponenten.
|
||
expect(mesh.positions.length).toBe(9 * 3);
|
||
// 2×2 Zellen × 2 Dreiecke × 3 Indizes.
|
||
expect(mesh.indices.length).toBe(2 * 2 * 2 * 3);
|
||
});
|
||
|
||
it("lässt Zellen mit fehlender (null) Ecke aus", () => {
|
||
const grid: TerrainGrid = {
|
||
xs: [0, 10, 20],
|
||
ys: [0, 10, 20],
|
||
z: [
|
||
[1, 2, 3],
|
||
[2, null, 4],
|
||
[3, 4, 5],
|
||
],
|
||
};
|
||
const mesh = terrainMeshFromGrid(grid);
|
||
// Die fehlende Mitte gehört zu allen 4 Zellen → keine Faces übrig.
|
||
expect(mesh.indices.length).toBe(0);
|
||
});
|
||
|
||
it("überträgt die Höhen als Z-Koordinate (Modell x,y,z)", () => {
|
||
const grid: TerrainGrid = {
|
||
xs: [0, 10],
|
||
ys: [0, 10],
|
||
z: [
|
||
[5, 7],
|
||
[9, 11],
|
||
],
|
||
};
|
||
const mesh = terrainMeshFromGrid(grid);
|
||
const zs: number[] = [];
|
||
for (let i = 2; i < mesh.positions.length; i += 3) zs.push(mesh.positions[i]);
|
||
expect(zs.sort((a, b) => a - b)).toEqual([5, 7, 9, 11]);
|
||
});
|
||
});
|