forked from phenom/healer-man
Release Healer Man 0.1.7
This commit is contained in:
1 parent
b12fb84859
commit
eca6b5db9b
99 files changed
+1931
-150
No files matched your search
@@ -0,0 +1,109 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
BoxGeometry,
|
||||
Group,
|
||||
InstancedMesh,
|
||||
Matrix4,
|
||||
Mesh,
|
||||
MeshBasicMaterial,
|
||||
Vector3,
|
||||
} from "three";
|
||||
import { instanceRepeatedStaticMeshes } from "./staticSceneInstancing";
|
||||
|
||||
function batchIn(root: Group): InstancedMesh {
|
||||
let result: InstancedMesh | null = null;
|
||||
root.traverse((node) => {
|
||||
if ((node as InstancedMesh).isInstancedMesh) result = node as InstancedMesh;
|
||||
});
|
||||
if (!result) throw new Error("Expected an instanced mesh batch.");
|
||||
return result;
|
||||
}
|
||||
|
||||
function batchesIn(root: Group): readonly InstancedMesh[] {
|
||||
const result: InstancedMesh[] = [];
|
||||
root.traverse((node) => {
|
||||
if ((node as InstancedMesh).isInstancedMesh) result.push(node as InstancedMesh);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
describe("static scene instancing", () => {
|
||||
it("batches repeated meshes while retaining their world transforms", () => {
|
||||
const root = new Group();
|
||||
root.position.set(10, 0, 0);
|
||||
const geometry = new BoxGeometry();
|
||||
const material = new MeshBasicMaterial();
|
||||
for (const x of [1, 3, 7]) {
|
||||
const mesh = new Mesh(geometry, material);
|
||||
mesh.position.x = x;
|
||||
root.add(mesh);
|
||||
}
|
||||
|
||||
expect(instanceRepeatedStaticMeshes(root)).toEqual({
|
||||
batches: 1,
|
||||
instances: 3,
|
||||
removedMeshes: 3,
|
||||
});
|
||||
const batch = batchIn(root);
|
||||
const matrix = new Matrix4();
|
||||
const position = new Vector3();
|
||||
const positions = Array.from({ length: batch.count }, (_, index) => {
|
||||
batch.getMatrixAt(index, matrix);
|
||||
position.setFromMatrixPosition(matrix);
|
||||
return position.x;
|
||||
});
|
||||
expect(positions).toEqual([1, 3, 7]);
|
||||
});
|
||||
|
||||
it("leaves small groups and existing instance batches unchanged", () => {
|
||||
const root = new Group();
|
||||
const geometry = new BoxGeometry();
|
||||
const material = new MeshBasicMaterial();
|
||||
root.add(new Mesh(geometry, material), new Mesh(geometry, material));
|
||||
const existing = new InstancedMesh(geometry, material, 4);
|
||||
root.add(existing);
|
||||
|
||||
expect(instanceRepeatedStaticMeshes(root)).toEqual({
|
||||
batches: 0,
|
||||
instances: 0,
|
||||
removedMeshes: 0,
|
||||
});
|
||||
expect(root.children).toHaveLength(3);
|
||||
expect(root.children).toContain(existing);
|
||||
});
|
||||
|
||||
it("does not combine meshes whose render state differs", () => {
|
||||
const root = new Group();
|
||||
const geometry = new BoxGeometry();
|
||||
const material = new MeshBasicMaterial();
|
||||
for (let index = 0; index < 3; index += 1) {
|
||||
const mesh = new Mesh(geometry, material);
|
||||
mesh.receiveShadow = index !== 2;
|
||||
root.add(mesh);
|
||||
}
|
||||
|
||||
expect(instanceRepeatedStaticMeshes(root)).toEqual({
|
||||
batches: 0,
|
||||
instances: 0,
|
||||
removedMeshes: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps distant repetitions in separate cullable spatial batches", () => {
|
||||
const root = new Group();
|
||||
const geometry = new BoxGeometry();
|
||||
const material = new MeshBasicMaterial();
|
||||
for (const x of [1, 2, 3, 385, 386, 387]) {
|
||||
const mesh = new Mesh(geometry, material);
|
||||
mesh.position.x = x;
|
||||
root.add(mesh);
|
||||
}
|
||||
|
||||
expect(instanceRepeatedStaticMeshes(root)).toEqual({
|
||||
batches: 2,
|
||||
instances: 6,
|
||||
removedMeshes: 6,
|
||||
});
|
||||
expect(batchesIn(root).map((batch) => batch.count)).toEqual([3, 3]);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user