Release Healer Man 0.1.26

This commit is contained in:
phenom committed 2026-09-09 22:18:15 -04:00
1 parent e7cc588bfc
commit 147c2804d4
27 files changed
+1010 -55

No files matched your search

+49 -2
View File
@@ -1,4 +1,4 @@
import { describe, expect, it } from "vitest";
import { describe, expect, it, vi } from "vitest";
import {
BoxGeometry,
Group,
@@ -8,7 +8,7 @@ import {
MeshBasicMaterial,
Vector3,
} from "three";
import { instanceRepeatedStaticMeshes } from "./staticSceneInstancing";
import { cacheStaticMatrices, instanceRepeatedStaticMeshes } from "./staticSceneInstancing";
function batchIn(root: Group): InstancedMesh {
let result: InstancedMesh | null = null;
@@ -28,6 +28,33 @@ function batchesIn(root: Group): readonly InstancedMesh[] {
}
describe("static scene instancing", () => {
it("caches local transforms without freezing dungeon placement or imported matrices", () => {
const parent = new Group();
const root = new Group();
const mesh = new Mesh(new BoxGeometry(), new MeshBasicMaterial());
mesh.matrixAutoUpdate = false;
mesh.matrix.makeTranslation(3, 0, 0);
parent.add(root);
root.add(mesh);
const updateChild = vi.spyOn(mesh, "updateMatrixWorld");
cacheStaticMatrices(root);
root.position.x = 10;
parent.position.x = 20;
parent.updateMatrixWorld(true);
expect(new Vector3().setFromMatrixPosition(mesh.matrixWorld).x).toBe(33);
parent.updateMatrixWorld(true);
expect(updateChild).toHaveBeenCalledTimes(1);
root.position.x = 15;
parent.updateMatrixWorld(true);
expect(new Vector3().setFromMatrixPosition(mesh.matrixWorld).x).toBe(38);
parent.position.x = 30;
parent.updateMatrixWorld(true);
expect(new Vector3().setFromMatrixPosition(mesh.matrixWorld).x).toBe(48);
expect(updateChild).toHaveBeenCalledTimes(3);
expect(root.matrixAutoUpdate).toBe(true);
expect(mesh.matrixWorldAutoUpdate).toBe(true);
});
it("batches repeated meshes while retaining their world transforms", () => {
const root = new Group();
root.position.set(10, 0, 0);
@@ -72,6 +99,26 @@ describe("static scene instancing", () => {
expect(root.children).toContain(existing);
});
it("removes containers emptied by batching while preserving authored empty nodes", () => {
const root = new Group();
const geometry = new BoxGeometry();
const material = new MeshBasicMaterial();
const authoredMarker = new Group();
authoredMarker.name = "authored-marker";
root.add(authoredMarker);
for (let index = 0; index < 3; index += 1) {
const outer = new Group();
const inner = new Group();
outer.add(inner);
inner.add(new Mesh(geometry, material));
root.add(outer);
}
instanceRepeatedStaticMeshes(root);
expect(root.children).toHaveLength(2);
expect(root.children).toContain(authoredMarker);
expect(batchIn(root).count).toBe(3);
});
it("does not combine meshes whose render state differs", () => {
const root = new Group();
const geometry = new BoxGeometry();