66 lines
3.6 KiB
JavaScript
66 lines
3.6 KiB
JavaScript
import { describe, expect, it } from "vitest";
|
||
import { Document, NodeIO } from "@gltf-transform/core";
|
||
import { KHRTextureTransform } from "@gltf-transform/extensions";
|
||
import { dedup, prune } from "@gltf-transform/functions";
|
||
import sharp from "sharp";
|
||
import { EXT_MATERIALS_BUMP, EXTMaterialsBump } from "../tools/assets/bumpExtension.mjs";
|
||
|
||
/** 8 × 8 px mit wechselnden Werten — prune() ersetzt einfarbige Texturen sonst durch Faktoren. */
|
||
function pattern() {
|
||
const data = Buffer.alloc(8 * 8 * 3);
|
||
for (let i = 0; i < data.length; i++) data[i] = (i * 37) & 0xff;
|
||
return sharp(data, { raw: { width: 8, height: 8, channels: 3 } }).png().toBuffer();
|
||
}
|
||
|
||
/** Ein Dreieck mit dem Material cont_a_side, Bump-Stärke 2,2 und Wellenteilung [3.2, 1]. */
|
||
async function bumpDocument() {
|
||
const document = new Document();
|
||
document.createBuffer();
|
||
const bumpExtension = document.createExtension(EXTMaterialsBump);
|
||
const transformExtension = document.createExtension(KHRTextureTransform);
|
||
const texture = document.createTexture("wellblech").setImage(await pattern()).setMimeType("image/png");
|
||
const bump = bumpExtension.createBump().setBumpFactor(2.2).setBumpTexture(texture);
|
||
bump.getBumpTextureInfo().setExtension("KHR_texture_transform", transformExtension.createTransform().setScale([3.2, 1]));
|
||
const material = document.createMaterial("cont_a_side").setExtension(EXT_MATERIALS_BUMP, bump);
|
||
const positions = document.createAccessor().setType("VEC3").setArray(new Float32Array([0, 0, 0, 1, 0, 0, 0, 1, 0]));
|
||
const primitive = document.createPrimitive().setMaterial(material).setAttribute("POSITION", positions);
|
||
document.createScene().addChild(document.createNode().setMesh(document.createMesh().addPrimitive(primitive)));
|
||
return document;
|
||
}
|
||
|
||
/** JSON-Teil einer .glb: 12 Byte Kopf, dann Länge und Typ des ersten Blocks, dann das JSON. */
|
||
function glbJson(glb) {
|
||
const view = new DataView(glb.buffer, glb.byteOffset, glb.byteLength);
|
||
return JSON.parse(new TextDecoder().decode(glb.subarray(20, 20 + view.getUint32(12, true))));
|
||
}
|
||
|
||
describe("EXT_materials_bump", () => {
|
||
const io = () => new NodeIO().registerExtensions([EXTMaterialsBump, KHRTextureTransform]);
|
||
|
||
// Bruch: @gltf-transform verwirft die Erweiterung (Wellblech flach), prune entfernt die Textur als
|
||
// unbenutzt, oder die Wellenteilung an der bumpTexture geht verloren (Wellen 3,2-mal zu breit).
|
||
it("übersteht dedup, prune, Schreiben und Einlesen mit Stärke, Textur und Teilung", async () => {
|
||
const document = await bumpDocument();
|
||
await document.transform(dedup(), prune());
|
||
|
||
const read = await io().readBinary(await io().writeBinary(document));
|
||
|
||
const bump = read.getRoot().listMaterials()[0].getExtension(EXT_MATERIALS_BUMP);
|
||
expect(bump.getBumpFactor()).toBe(2.2);
|
||
expect(bump.getBumpTexture().getSize()).toEqual([8, 8]);
|
||
expect(bump.getBumpTextureInfo().getExtension("KHR_texture_transform").getScale()).toEqual([3.2, 1]);
|
||
});
|
||
|
||
// Bruch: Feldnamen oder Aufbau weichen von der Spezifikation ab — three.js (GLTFLoader) liest
|
||
// genau materials[i].extensions.EXT_materials_bump.bumpFactor und .bumpTexture.index.
|
||
it("schreibt das JSON so, wie three.js es liest", async () => {
|
||
const json = glbJson(await io().writeBinary(await bumpDocument()));
|
||
|
||
expect(json.extensionsUsed).toContain(EXT_MATERIALS_BUMP);
|
||
const def = json.materials[0].extensions[EXT_MATERIALS_BUMP];
|
||
expect(def.bumpFactor).toBe(2.2);
|
||
expect(json.textures[def.bumpTexture.index]).toBeDefined();
|
||
expect(def.bumpTexture.extensions.KHR_texture_transform.scale).toEqual([3.2, 1]);
|
||
});
|
||
});
|