@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
136 lines (101 loc) • 3.86 kB
JavaScript
import { logger } from "../../logging/GlobalLogger.js";
import { AnimationCurve } from "../curve/AnimationCurve.js";
import { AnimationClip } from "./AnimationClip.js";
import { AnimationClipBinding } from "./AnimationClipBinding.js";
import { AnimationInterpolationKind } from "./AnimationInterpolationKind.js";
import { AnimationTrack } from "./AnimationTrack.js";
import { AnimationTrackBinding } from "./AnimationTrackBinding.js";
import { bind_property_writer } from "./bind_property_writer.js";
import { curve_from_track_data } from "./curve_from_track_data.js";
/**
*
* @param {THREE.KeyframeTrack} track
*/
function track_to_interpolation(track) {
const name = track.createInterpolant.name;
switch (name) {
case "InterpolantFactoryMethodDiscrete":
return AnimationInterpolationKind.Discrete;
case "InterpolantFactoryMethodLinear":
return AnimationInterpolationKind.Linear;
case "InterpolantFactoryMethodGLTFCubicSpline":
return AnimationInterpolationKind.CubicTangents;
default:
if (track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true) {
// second attempt
return AnimationInterpolationKind.CubicTangents;
}
// unsupported, default to linear
console.warn(`Unsupported interpolation type, defaulting to linear`);
return AnimationInterpolationKind.Linear;
}
}
/**
*
* @param {THREE.KeyframeTrack} track
* @returns {AnimationCurve[]}
*/
function convert_three_track_to_curves(track) {
const values = track.values;
const times = track.times;
const key_count = times.length;
/**
*
* @type {AnimationCurve[]}
*/
const curves = [];
// figure out interpolation type
const interpolation = track_to_interpolation(track);
const values_per_key = values.length / key_count;
const component_count = interpolation === AnimationInterpolationKind.CubicTangents ? values_per_key / 3 : values_per_key;
for (let component_index = 0; component_index < component_count; component_index++) {
const curve = new AnimationCurve();
curve_from_track_data(
curve,
interpolation,
values,
times,
component_count,
component_index
);
curves.push(curve);
}
return curves;
}
/**
*
* @param {THREE.KeyframeTrack} track
* @returns {AnimationTrack}
*/
function convert_three_track(track) {
const track_name = track.name;
// last part is the property
const curves = convert_three_track_to_curves(track);
return AnimationTrack.from(curves, track_name);
}
/**
* Three.js clip to internal representation
* @param {EntityNode} node
* @param {THREE.AnimationClip} clip
*/
export function convert_three_clip(node, clip) {
const three_tracks = clip.tracks;
const track_count = three_tracks.length;
const clip_binding = new AnimationClipBinding();
const meep_clip = new AnimationClip();
meep_clip.name = clip.name;
clip_binding.clip = meep_clip;
for (let i = 0; i < track_count; i++) {
try {
const three_track = three_tracks[i];
const meep_track = convert_three_track(three_track);
const property_path = three_track.name.split('.');
const writer = bind_property_writer(node, property_path);
meep_clip.tracks.push(meep_track);
clip_binding.tracks.push(AnimationTrackBinding.from(writer, meep_track));
} catch (e) {
logger.error(`Failed to parse track[${i}]: ${e}`);
}
}
return clip_binding;
}