Files

41 lines
2.5 KiB
TypeScript

import "@babylonjs/loaders/glTF";
import { Animation } from "@babylonjs/core/Animations/animation.js";
import { AnimationPropertyInfo } from "@babylonjs/loaders/glTF/2.0/glTFLoaderAnimation.js";
import { SetInterpolationForKey } from "@babylonjs/loaders/glTF/2.0/Extensions/objectModelMapping.js";
// Babylon 9.25.0 registers metallicFactor twice and omits roughnessFactor.
// Its metallic-roughness texture pointer paths also omit KHR_texture_transform.
// Keep these corrections covered by actual glTF animation playback tests.
class MaterialProperty extends AnimationPropertyInfo {
buildAnimations(target: any, name: string, fps: number, keys: any[]) {
return Object.values(target._data || {}).map((data: any) => ({
babylonAnimatable: data.babylonMaterial,
babylonAnimation: this._buildAnimation(name, fps, keys),
}));
}
}
const scalar = (property: string, index = 0, stride = 1) => new MaterialProperty(
Animation.ANIMATIONTYPE_FLOAT, property,
(_target, source, offset, scale) => source[offset + index] * scale,
() => stride,
);
SetInterpolationForKey("/materials/{}/pbrMetallicRoughness/metallicFactor", [scalar("metallic")]);
SetInterpolationForKey("/materials/{}/pbrMetallicRoughness/roughnessFactor", [scalar("roughness")]);
const texturePath = "/materials/{}/pbrMetallicRoughness/metallicRoughnessTexture/extensions/KHR_texture_transform/";
SetInterpolationForKey(texturePath + "offset", [scalar("metallicTexture.uOffset", 0, 2), scalar("metallicTexture.vOffset", 1, 2)]);
SetInterpolationForKey(texturePath + "scale", [scalar("metallicTexture.uScale", 0, 2), scalar("metallicTexture.vScale", 1, 2)]);
SetInterpolationForKey(texturePath + "rotation", [new MaterialProperty(Animation.ANIMATIONTYPE_FLOAT, "metallicTexture.wAng", (_t, s, o, scale) => -s[o] * scale, () => 1)]);
// xmag/ymag are scalar half-extents; both sides use the same sample.
class CameraProperty extends AnimationPropertyInfo {
buildAnimations(target: any, name: string, fps: number, keys: any[]) {
return [{ babylonAnimatable: target._babylonCamera, babylonAnimation: this._buildAnimation(name, fps, keys) }];
}
}
for (const [axis, negative, positive] of [["xmag", "orthoLeft", "orthoRight"], ["ymag", "orthoBottom", "orthoTop"]]) {
SetInterpolationForKey(`/cameras/{}/orthographic/${axis}`, [
new CameraProperty(Animation.ANIMATIONTYPE_FLOAT, negative, (_t, s, o, scale) => -s[o] * scale, () => 1),
new CameraProperty(Animation.ANIMATIONTYPE_FLOAT, positive, (_t, s, o, scale) => s[o] * scale, () => 1),
]);
}