Files
workinf_Blender_Wasm/tools/web/check-physics-main-reader.mjs
2026-08-12 17:14:27 -04:00

70 lines
3.1 KiB
JavaScript

import assert from "node:assert/strict";
import crypto from "node:crypto";
import fs from "node:fs";
import factory from "../../web/app/src/vendor/blender/web_engine.js";
const root = new URL("../../", import.meta.url);
const wasmBinary = fs.readFileSync(new URL("web/app/src/vendor/blender/web_engine.wasm", root));
const fixture = fs.readFileSync(new URL("tests/files/web/modifier_physics_scene.blend", root));
function open(engine, handle, bytes) {
const pointer = engine._malloc(bytes.byteLength);
try {
engine.HEAPU8.set(bytes, pointer);
assert.equal(engine._web_engine_open_blend(handle, pointer, bytes.byteLength), 0,
engine.UTF8ToString(engine._web_engine_last_error_message()));
}
finally { engine._free(pointer); }
}
function output(engine, handle, fn, owned = false) {
const dataOut = engine._malloc(4);
const lengthOut = engine._malloc(4);
try {
assert.equal(fn(handle, dataOut, lengthOut), 0, engine.UTF8ToString(engine._web_engine_last_error_message()));
const pointer = engine.HEAPU32[dataOut >>> 2];
const length = engine.HEAPU32[lengthOut >>> 2];
const bytes = engine.HEAPU8.slice(pointer, pointer + length);
if (owned) engine._web_engine_free_buffer(pointer);
return bytes;
}
finally { engine._free(dataOut); engine._free(lengthOut); }
}
function snapshot(engine, handle) {
return JSON.parse(new TextDecoder().decode(output(engine, handle, engine._web_engine_get_scene_snapshot)));
}
function assertManifest(scene) {
const manifest = scene.physicsSimulation;
assert.equal(manifest?.schemaVersion, 1);
assert.deepEqual(manifest.systems.map((system) => system.family).sort(), ["CLOTH", "SOFT_BODY"]);
for (const system of manifest.systems) {
assert.match(system.id, /^physics:/);
assert.match(system.ownerObjectId, /^object:/);
assert.deepEqual(system.settingsHash, crypto.createHash("sha256").update(JSON.stringify(system.settings)).digest("hex"));
assert.equal(system.cache, undefined);
}
const collisionId = "object:PhysicsCollisionDisabled";
assert.ok(manifest.systems.every((system) => system.dependencyIds.includes(collisionId)));
const cloth = manifest.systems.find((system) => system.family === "CLOTH");
const soft = manifest.systems.find((system) => system.family === "SOFT_BODY");
assert.equal(cloth.settings.name, "Cloth Disabled");
assert.equal(cloth.settings.enabled, false);
assert.equal(soft.ownerObjectId, "object:PhysicsSoftBodyDisabled");
assert.equal(typeof soft.settings.nodeMass, "number");
}
const engine = await factory({ wasmBinary: wasmBinary.slice() });
const handle = engine._web_engine_create();
open(engine, handle, fixture);
assertManifest(snapshot(engine, handle));
const saved = output(engine, handle, engine._web_engine_save_blend, true);
engine._web_engine_destroy(handle);
const reopened = engine._web_engine_create();
open(engine, reopened, saved);
assertManifest(snapshot(engine, reopened));
engine._web_engine_destroy(reopened);
process.stdout.write("physics-main-reader-ok families=CLOTH,SOFT_BODY dependencies=COLLISION settings-sha256=passed save-reopen=passed playback=BLOCKED solver=BLOCKED\n");