UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

136 lines (101 loc) 3.86 kB
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; }