41 lines
2.5 KiB
TypeScript
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),
|
|
]);
|
|
}
|