feat(assets): Hood Yard aufbereitet (653,6 MB -> 16,2 MB)
2,9 Mio. -> 658 000 Dreiecke, 542 -> 43 Primitive, 105 PNG in 2048 px -> 32 WebP in 1024 px und 37 in 512 px. EXT_materials_bump der Container erhalten. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
62dbbe41d2
commit
d923f1ba2f
2 files changed
+70
No files matched your search
@@ -0,0 +1,70 @@
|
||||
import { statSync } from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
import { NodeIO } from "@gltf-transform/core";
|
||||
import { ALL_EXTENSIONS } from "@gltf-transform/extensions";
|
||||
import { getBounds } from "@gltf-transform/functions";
|
||||
import { MeshoptDecoder } from "meshoptimizer";
|
||||
import { PLACES, SOLID_MATERIALS } from "../src/world/places.js";
|
||||
import { EXT_MATERIALS_BUMP, EXTMaterialsBump } from "../tools/assets/bumpExtension.mjs";
|
||||
|
||||
const place = PLACES.find((entry) => entry.id === "hood-yard");
|
||||
const file = fileURLToPath(new URL(`../public/${place.url.slice(2)}`, import.meta.url));
|
||||
const CONTAINERS = ["cont_a_side", "cont_a_end", "cont_b_side", "cont_b_end", "cont_c_side", "cont_c_end"];
|
||||
|
||||
describe("hood-yard.glb", () => {
|
||||
let document;
|
||||
beforeAll(async () => {
|
||||
await MeshoptDecoder.ready;
|
||||
const io = new NodeIO()
|
||||
.registerExtensions([...ALL_EXTENSIONS, EXTMaterialsBump])
|
||||
.registerDependencies({ "meshopt.decoder": MeshoptDecoder });
|
||||
document = await io.read(file);
|
||||
}, 30000);
|
||||
|
||||
// Bruch: Aufbereitung übersprungen oder falsch eingestellt — die Quelle hatte 653 MB.
|
||||
it("ist kleiner als 30 MB", () => {
|
||||
expect(statSync(file).size).toBeLessThan(30e6);
|
||||
});
|
||||
|
||||
// Bruch: das Wellblech ist weg, die Geometrie unkomprimiert, oder GPU-Instanzen, deren Matrizen die
|
||||
// Kollision des Controllers nicht liest.
|
||||
it("nutzt meshopt und WebP, behält EXT_materials_bump und hat keine Instanzen", () => {
|
||||
const used = document.getRoot().listExtensionsUsed().map((extension) => extension.extensionName);
|
||||
|
||||
expect(used).toEqual(expect.arrayContaining(["EXT_meshopt_compression", "EXT_texture_webp", EXT_MATERIALS_BUMP]));
|
||||
expect(used).not.toContain("EXT_mesh_gpu_instancing");
|
||||
});
|
||||
|
||||
it("hat nur WebP-Texturen bis 1024 px", () => {
|
||||
for (const texture of document.getRoot().listTextures()) {
|
||||
expect(texture.getMimeType()).toBe("image/webp");
|
||||
expect(Math.max(...texture.getSize())).toBeLessThanOrEqual(1024);
|
||||
}
|
||||
});
|
||||
|
||||
it("gibt allen sechs Container-Materialien ihre Bump-Textur", () => {
|
||||
const materials = new Map(document.getRoot().listMaterials().map((material) => [material.getName(), material]));
|
||||
for (const name of CONTAINERS) {
|
||||
expect(materials.get(name)?.getExtension(EXT_MATERIALS_BUMP)?.getBumpTexture()).toBeTruthy();
|
||||
}
|
||||
});
|
||||
|
||||
// Bruch: dedup oder ein neues Werkzeug benennt ein Material um — der Hof wäre dort ohne Warnung
|
||||
// durchlässig, weil die Kollision nach Namen auswählt.
|
||||
it("enthält jedes feste Material der Kollisionsliste", () => {
|
||||
const names = document.getRoot().listMaterials().map((material) => material.getName());
|
||||
expect(SOLID_MATERIALS.filter((name) => !names.includes(name))).toEqual([]);
|
||||
});
|
||||
|
||||
// Bruch: bounds in PLACES passt nicht mehr zur Datei — der Datentest prüfte dann die falsche Fläche.
|
||||
it("passt auf 5 cm zu den Außenmaßen in PLACES", () => {
|
||||
const { min, max } = getBounds(document.getRoot().listScenes()[0]);
|
||||
const { minX, maxX, minZ, maxZ } = place.bounds;
|
||||
|
||||
expect(Math.abs(min[0] - minX)).toBeLessThan(0.05);
|
||||
expect(Math.abs(max[0] - maxX)).toBeLessThan(0.05);
|
||||
expect(Math.abs(min[2] - minZ)).toBeLessThan(0.05);
|
||||
expect(Math.abs(max[2] - maxZ)).toBeLessThan(0.05);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user