Skip to content

Commit

Permalink
perf(functions): Shallow clone accessors where possible
Browse files Browse the repository at this point in the history
  • Loading branch information
donmccurdy committed Jan 22, 2024
1 parent bd24016 commit e3eee42
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 24 deletions.
22 changes: 8 additions & 14 deletions packages/functions/src/join-primitives.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Document, Primitive, ComponentTypeToTypedArray } from '@gltf-transform/core';
import { createIndices, createPrimGroupKey } from './utils.js';
import { createIndices, createPrimGroupKey, shallowCloneAccessor } from './utils.js';

interface JoinPrimitiveOptions {
skipValidation?: boolean;
Expand Down Expand Up @@ -74,23 +74,17 @@ export function joinPrimitives(prims: Primitive[], options: JoinPrimitiveOptions
for (const semantic of templatePrim.listSemantics()) {
const tplAttribute = templatePrim.getAttribute(semantic)!;
const AttributeArray = ComponentTypeToTypedArray[tplAttribute.getComponentType()];
const dstAttribute = document
.createAccessor()
.setType(tplAttribute.getType())
.setBuffer(tplAttribute.getBuffer())
.setNormalized(tplAttribute.getNormalized())
.setArray(new AttributeArray(dstVertexCount * tplAttribute.getElementSize()));
const dstAttribute = shallowCloneAccessor(document, tplAttribute).setArray(
new AttributeArray(dstVertexCount * tplAttribute.getElementSize()),
);
dstPrim.setAttribute(semantic, dstAttribute);
}

// (4) Allocate joined indices.
const dstIndicesArray = templatePrim.getIndices() ? createIndices(dstVertexCount) : null;
const dstIndices =
dstIndicesArray &&
document
.createAccessor()
.setBuffer(templatePrim.getIndices()!.getBuffer())
.setArray(createIndices(dstIndicesCount, dstVertexCount));
const srcIndices = templatePrim.getIndices();
const dstIndices = srcIndices
? shallowCloneAccessor(document, srcIndices).setArray(createIndices(dstIndicesCount, dstVertexCount))
: null;
dstPrim.setIndices(dstIndices);

// (5) Remap attributes into joined Primitive.
Expand Down
18 changes: 10 additions & 8 deletions packages/functions/src/reorder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Accessor, Document, GLTF, Primitive, PropertyType, Transform } from '@gltf-transform/core';
import { prune } from './prune.js';
import { createTransform, deepListAttributes, remapAttribute, SetMap } from './utils.js';
import { createTransform, deepListAttributes, remapAttribute, SetMap, shallowCloneAccessor } from './utils.js';
import type { MeshoptEncoder } from 'meshoptimizer';

const NAME = 'reorder';
Expand Down Expand Up @@ -48,18 +48,19 @@ export function reorder(_options: ReorderOptions): Transform {
throw new Error(`${NAME}: encoder dependency required — install "meshoptimizer".`);
}

return createTransform(NAME, async (doc: Document): Promise<void> => {
const logger = doc.getLogger();
return createTransform(NAME, async (document: Document): Promise<void> => {
const logger = document.getLogger();

await encoder.ready;

const plan = createLayoutPlan(doc);
const plan = createLayoutPlan(document);

for (const srcIndices of plan.indicesToAttributes.keys()) {
const dstIndices = srcIndices.clone();
let indicesArray = dstIndices.getArray()!.slice();
let indicesArray = srcIndices.getArray()!;
if (!(indicesArray instanceof Uint32Array)) {
indicesArray = new Uint32Array(indicesArray);
} else {
indicesArray = indicesArray.slice();
}

// Compute optimal order.
Expand All @@ -69,11 +70,12 @@ export function reorder(_options: ReorderOptions): Transform {
options.target === 'size',
);

const dstIndices = shallowCloneAccessor(document, srcIndices);
dstIndices.setArray(unique <= 65534 ? new Uint16Array(indicesArray) : indicesArray);

// Update affected primitives.
for (const srcAttribute of plan.indicesToAttributes.get(srcIndices)) {
const dstAttribute = srcAttribute.clone();
const dstAttribute = shallowCloneAccessor(document, srcAttribute);
remapAttribute(dstAttribute, remap, unique);
for (const prim of plan.attributesToPrimitives.get(srcAttribute)) {
if (prim.getIndices() === srcIndices) {
Expand All @@ -90,7 +92,7 @@ export function reorder(_options: ReorderOptions): Transform {
}

// Clean up any attributes left unused by earlier cloning.
await doc.transform(
await document.transform(
prune({
propertyTypes: [PropertyType.ACCESSOR],
keepAttributes: true,
Expand Down
5 changes: 3 additions & 2 deletions packages/functions/src/simplify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
remapAttribute,
deepSwapAttribute,
isTransformPending,
shallowCloneAccessor,
} from './utils.js';
import { weld } from './weld.js';
import type { MeshoptSimplifier } from 'meshoptimizer';
Expand Down Expand Up @@ -175,15 +176,15 @@ export function simplifyPrimitive(document: Document, prim: Primitive, _options:
// (3) Write vertex attributes.

for (const srcAttribute of deepListAttributes(prim)) {
const dstAttribute = srcAttribute.clone();
const dstAttribute = shallowCloneAccessor(document, srcAttribute);
remapAttribute(dstAttribute, remap, unique);
deepSwapAttribute(prim, srcAttribute, dstAttribute);
if (srcAttribute.listParents().length === 1) srcAttribute.dispose();
}

// (4) Write indices.

const dstIndices = srcIndices.clone();
const dstIndices = shallowCloneAccessor(document, srcIndices);
dstIndices.setArray(srcVertexCount <= 65534 ? new Uint16Array(dstIndicesArray) : dstIndicesArray);
prim.setIndices(dstIndices);
if (srcIndices.listParents().length === 1) srcIndices.dispose();
Expand Down

0 comments on commit e3eee42

Please sign in to comment.