fix(props): Straßenlaternen auf glaubwürdige Höhe skaliert, Fuß auf den Boden gehoben
street_lamp_02.glb ist nur 1,657 m hoch (per gltf-transform inspect gemessen:
bboxMax.y 1.26478 - bboxMin.y -0.39258) und ihr Fuß liegt unter dem Ursprung.
#buildLamps setzte das Modell bisher unskaliert auf y=0 — der Fuß steckt im Boden,
und 1,66 m ist ohnehin zu klein neben 10-18 m hohen Palmen und 10-28 m breiten
Straßen dieser Karte. Poly Havens eigene Angabe ("1.7m tall") bestätigt, dass die
Rohgröße korrekt gemessen ist — der Fehler liegt in der Verwendung dieser Rohgröße
in diesem Maßstab, nicht in der Messung selbst.
lampFit(minY, maxY, targetHeight) leitet Skalierung und Fuß-Anhebung aus der
gemessenen bbox her; STREET_LAMP_HEIGHT = 4.0 m als benannte Zielgröße (Mitte des
für dekorative Straßenlaternen üblichen 3-6-m-Bereichs). load() wendet beides auf
die Modellwurzel an, bevor die Teil-Matrizen (Mast, Glas) eingesammelt werden, damit
#buildLamps() unverändert bleiben kann.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b273bb09cc
commit
ad9bf63b36
2 files changed
+82
-5
No files matched your search
+43
-1
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { lampPoints, palmTransforms, pointInPolygon, vergeLampPoints } from "../src/world/props.js";
|
||||
import { STREET_LAMP_HEIGHT, lampFit, lampPoints, palmTransforms, pointInPolygon, vergeLampPoints } from "../src/world/props.js";
|
||||
|
||||
describe("props", () => {
|
||||
it("setzt Laternen im gewünschten Abstand entlang der Linie", () => {
|
||||
@@ -105,3 +105,45 @@ describe("vergeLampPoints", () => {
|
||||
expect(out[0].z).toBeCloseTo(6);
|
||||
});
|
||||
});
|
||||
|
||||
// Fix-Runde 3, Befund B: street_lamp_02.glb ist mit `npx @gltf-transform/cli@4.5.0 inspect`
|
||||
// vermessen bboxMin.y=-0.39258 / bboxMax.y=1.26478 (Modellhöhe 1,65736 m) — der Fuß liegt
|
||||
// unter dem Ursprung, #buildLamps setzte das Modell bisher unskaliert auf y=0, der Fuß steckt
|
||||
// also im Boden, und 1,66 m ist ohnehin zu klein für eine Straßenlaterne (s. Bericht).
|
||||
// lampFit() ist rein: sie bekommt die gemessene bbox und die Zielhöhe hinein, keine
|
||||
// Seiteneffekte, kein GLTFLoader — PropLayer.load() ist der einzige Aufrufer.
|
||||
describe("lampFit", () => {
|
||||
const BBOX_MIN_Y = -0.39258;
|
||||
const BBOX_MAX_Y = 1.26478;
|
||||
|
||||
it("skaliert die gemessene Modellhöhe exakt auf die Zielhöhe", () => {
|
||||
const { scale } = lampFit(BBOX_MIN_Y, BBOX_MAX_Y, STREET_LAMP_HEIGHT);
|
||||
const modelHeight = BBOX_MAX_Y - BBOX_MIN_Y;
|
||||
expect(scale * modelHeight).toBeCloseTo(STREET_LAMP_HEIGHT, 5);
|
||||
});
|
||||
|
||||
it("hebt das skalierte Modell so an, dass sein Fuß (bboxMin.y) auf y = 0 zu stehen kommt", () => {
|
||||
const { scale, liftY } = lampFit(BBOX_MIN_Y, BBOX_MAX_Y, STREET_LAMP_HEIGHT);
|
||||
expect(BBOX_MIN_Y * scale + liftY).toBeCloseTo(0, 5);
|
||||
});
|
||||
|
||||
it("STREET_LAMP_HEIGHT ist eine glaubwürdige Straßenlaternenhöhe, keine 1,66 m", () => {
|
||||
// 3-6 m ist der in Quellen genannte Bereich für dekorative/ornamentale Straßen- und
|
||||
// Parklaternen (s. Bericht); das Modell selbst ist mit 1,66 m unstrittig zu klein.
|
||||
expect(STREET_LAMP_HEIGHT).toBeGreaterThanOrEqual(3);
|
||||
expect(STREET_LAMP_HEIGHT).toBeLessThanOrEqual(6);
|
||||
});
|
||||
|
||||
it("leitet den Skalierungsfaktor aus der übergebenen Zielhöhe her, statt eine Zahl zu raten", () => {
|
||||
expect(lampFit(0, 2, 4).scale).toBeCloseTo(2);
|
||||
expect(lampFit(0, 4, 4).scale).toBeCloseTo(1);
|
||||
expect(lampFit(0, 1, 4).scale).toBeCloseTo(4);
|
||||
});
|
||||
|
||||
it("liefert scale 1 und hebt nur um |bboxMin.y| an, wenn keine Zielhöhe übergeben wird und die Modellhöhe 0 ist (Randfall)", () => {
|
||||
// Entartete bbox (maxY === minY) darf nicht durch 0 teilen.
|
||||
const { scale, liftY } = lampFit(2, 2, STREET_LAMP_HEIGHT);
|
||||
expect(scale).toBe(1);
|
||||
expect(liftY).toBeCloseTo(-2);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user