Skip to content

Commit

Permalink
fix(functions): Make instance() skip existing instances (#1507)
Browse files Browse the repository at this point in the history
  • Loading branch information
donmccurdy committed Sep 22, 2024
1 parent 1443768 commit 6f44294
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
1 change: 1 addition & 0 deletions packages/functions/src/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export function instance(_options: InstanceOptions = INSTANCE_DEFAULTS): Transfo
scene.traverse((node) => {
const mesh = node.getMesh();
if (!mesh) return;
if (node.getExtension('EXT_mesh_gpu_instancing')) return;
meshInstances.set(mesh, (meshInstances.get(mesh) || new Set<Node>()).add(node));
});

Expand Down
31 changes: 30 additions & 1 deletion packages/functions/test/instance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import test from 'ava';
import { Document } from '@gltf-transform/core';
import { InstancedMesh, EXTMeshGPUInstancing } from '@gltf-transform/extensions';
import { instance } from '@gltf-transform/functions';
import { logger } from '@gltf-transform/test-utils';
import { logger, createTorusKnotPrimitive } from '@gltf-transform/test-utils';

test('translation', async (t) => {
const doc = new Document().setLogger(logger);
Expand Down Expand Up @@ -128,6 +128,35 @@ test('skip distinct meshes', async (t) => {
t.falsy(batch, 'does not create batch');
});

test('skip existing instances', async (t) => {
const document = new Document().setLogger(logger);
const root = document.getRoot();

const batchExtension = document.createExtension(EXTMeshGPUInstancing);
const batch = batchExtension.createInstancedMesh();

const prim = createTorusKnotPrimitive(document, { radialSegments: 4, tubularSegments: 6 });
const mesh = document.createMesh().addPrimitive(prim);
const node1 = document.createNode().setMesh(mesh).setExtension('EXT_mesh_gpu_instancing', batch);
const node2 = document.createNode().setMesh(mesh).setTranslation([0, 0, 0]);
const node3 = document.createNode().setMesh(mesh).setTranslation([10, 0, 0]);

document.createScene().addChild(node1).addChild(node2).addChild(node3);

await document.transform(instance({ min: 2 }));

t.is(root.listNodes().length, 2, 'keeps 2/3 nodes');

const [batch1, batch2] = root
.listNodes()
.map((node) => node.getExtension<InstancedMesh>('EXT_mesh_gpu_instancing'));

t.is(batch, batch1, 'keeps batch 1');
t.truthy(batch2, 'creates batch 2');
t.not(batch1, batch2, 'batches are not merged');
t.is(batch2.getAttribute('TRANSLATION').getCount(), 2, 'batch 2 has 2 instances');
});

test('idempotence', async (t) => {
const doc = new Document().setLogger(logger);

Expand Down

0 comments on commit 6f44294

Please sign in to comment.