donmccurdy / donmccurdy/glTF-Transform

dedup: animation samplers

Open
#1,722 1 comment 1 reaction 0 assignees View on GitHub
feature package:functions
Dominant language
TypeScript
Stars
2k
Forks
206
Avg merge
2d 2h
Merged PRs (30d)
16

Description

**Is your feature request related to a problem? Please describe.**
Currently [dedup](https://github.com/donmccurdy/glTF-Transform/blob/main/packages/functions/src/dedup.ts) is only available for accessors, meshes, images, materials, and skins, but in gltf [spec](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#animations), samplers are defined to be able to be reused, this should help in case of models with duplicates in samplers.

**Describe the solution you'd like**
Add a `PropertyType.ANIMATION_SAMPLER` to `options.propertyTypes` of `dedup`, that enables animation sampler deduplication inside every gltf animation.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.
Attach some code here

```typescript

function hashAnimationSampler(sampler: AnimationSampler): string {
const hashKeys: (string | number | boolean)[] = [sampler.getInterpolation()];
const input = sampler.getInput();
if (input) {
hashKeys.push(
input.getCount(),
input.getType(),
input.getComponentType(),
input.getNormalized(),
input.getSparse(),
);
}
const output = sampler.getOutput();
if (output) {
hashKeys.push(
output.getCount(),
output.getType(),
output.getComponentType(),
output.getNormalized(),
output.getSparse(),
);
}
return hashKeys.join(':');
}

function dedupAnimationSamplers(document: Document): void {
const logger = document.getLogger();
const root = document.getRoot();
const animations = root.listAnimations();
const samplerMap = new Map();
const duplicates = new Map();
let duplicateCount = 0, totalCount = 0;
for (let i = 0, length = animations.length; i < length; i++) {
const animation = animations[i];
const samplers = animation.listSamplers();
totalCount += samplers.length;
for (let j = 0, samplersLength = samplers.length; j < samplersLength; j++) {
const sampler = samplers[j];
if (duplicates.has(sampler)) continue;
const hashKey = hashAnimationSampler(sampler);
const values = samplerMap.get(hashKey);
if (!values) {
samplerMap.set(hashKey, [sampler]);
continue;
}
let isDuplicate = false;
for (let k = 0, valueCount = values.length; k < valueCount; k++) {
const value = values[k];
// Instead of equals(), only do shallow compare here
// For a deep compare, dedup accessors before this
if (sampler.getInterpolation() === value.getInterpolation() &&
sampler.getInput() === value.getInput() &&
sampler.getOutput() === value.getOutput()) {
duplicates.set(sampler, value);
isDuplicate = true;
break;
}
}
if (!isDuplicate) {
values.push(sampler);
}

}
duplicateCount += duplicates.size;
duplicates.forEach((dst, src) => {
src.listParents().forEach((property) => {
if (!(property instanceof Root)) property.swap(src, dst);
});
src.dispose();
});
samplerMap.clear();
duplicates.clear();
}

logger.debug(`${NAME}: Merged ${duplicateCount} of ${totalCount} animation samplers.`);

}

```


Contributor guide

Open the contributing guide

Research direction

Start in packages/functions/src/dedup.ts and trace how options.propertyTypes selects the resource types handled by dedup. Confirm how animation samplers are represented and referenced, then implement the requested option so duplicate samplers are merged within each glTF animation while preserving existing deduplication behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
tooling
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.