Skip to content

Commit 11cab9d

Browse files
committed
add new model and refactor
1 parent 34f35a5 commit 11cab9d

File tree

6 files changed

+443
-240
lines changed

6 files changed

+443
-240
lines changed
2.93 MB
Binary file not shown.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import type { Animation } from './types.ts';
2+
import { lerp, type Quat, slerp, type Vec3 } from './math.ts';
3+
4+
export type NodeTransform = {
5+
translation?: Vec3;
6+
rotation?: Quat;
7+
scale?: Vec3;
8+
};
9+
10+
export const sampleAnimation = (
11+
animation: Animation,
12+
time: number,
13+
): Map<number, NodeTransform> => {
14+
const transforms = new Map<number, NodeTransform>();
15+
const loopedTime = time % animation.duration;
16+
17+
for (const channel of animation.channels) {
18+
const { input: times, output: values } =
19+
animation.samplers[channel.samplerIndex];
20+
const components = channel.targetPath === 'rotation' ? 4 : 3;
21+
22+
let i = 0;
23+
while (i < times.length - 2 && loopedTime >= times[i + 1]) {
24+
i++;
25+
}
26+
27+
const t0 = times[i];
28+
const t1 = times[i + 1];
29+
const alpha = t1 > t0
30+
? Math.max(0, Math.min(1, (loopedTime - t0) / (t1 - t0)))
31+
: 0;
32+
33+
const start = i * components;
34+
const end = (i + 1) * components;
35+
const v0 = Array.from(values.slice(start, start + components));
36+
const v1 = Array.from(values.slice(end, end + components));
37+
38+
const result = channel.targetPath === 'rotation'
39+
? slerp(v0 as Quat, v1 as Quat, alpha)
40+
: lerp(v0, v1, alpha);
41+
42+
if (!transforms.has(channel.targetNode)) {
43+
transforms.set(channel.targetNode, {});
44+
}
45+
const t = transforms.get(channel.targetNode);
46+
if (!t) {
47+
continue;
48+
}
49+
if (channel.targetPath === 'rotation') {
50+
t.rotation = result as Quat;
51+
} else if (channel.targetPath === 'translation') {
52+
t.translation = result as Vec3;
53+
} else {
54+
t.scale = result as Vec3;
55+
}
56+
}
57+
58+
return transforms;
59+
};

0 commit comments

Comments
 (0)