using LibMMD.Model; namespace LibMMD.Motion { public class MotionPlayer { public MotionPlayer(MmdMotion motion, Poser poser) { _motion = motion; _poser = poser; var model = poser.Model; _translationScaler = new MmdMotionTranslationScaler(model); _bindings = new MmdMotionBindingMap(motion, model); _grooveFallback = new MmdGrooveFallback( motion, poser, _translationScaler, _bindings.GrooveFallbackCenterIndex); _morphWeightCalculator = new MmdMorphWeightCalculator(motion, _bindings.Morphs); poser.ResetIkEnabled(); } public void SeekFrame(int frame) { foreach (var entry in _bindings.Ik) _poser.SetIkEnabled(entry.Value, _motion.GetIkEnabled(entry.Key, frame)); foreach (var entry in _bindings.Morphs) { _poser.SetMorphPose(entry.Value, _motion.GetMorphPose(entry.Key, frame)); } foreach (var entry in _bindings.Bones) { _poser.SetBonePose(entry.Value, _translationScaler.Apply(entry.Value, _motion.GetBonePose(entry.Key, frame))); } _grooveFallback.ApplyFrame(frame); } public void SeekTime(double time) { var frame = time * 30.0; foreach (var entry in _bindings.Ik) _poser.SetIkEnabled(entry.Value, _motion.GetIkEnabled(entry.Key, frame)); foreach (var entry in _bindings.Morphs) { _poser.SetMorphPose(entry.Value, _motion.GetMorphPose(entry.Key, time)); } foreach (var entry in _bindings.Bones) { _poser.SetBonePose(entry.Value, _translationScaler.Apply(entry.Value, _motion.GetBonePose(entry.Key, time))); } _grooveFallback.ApplyTime(time); } // Effective weight per vertex-type morph (indexed by model.Morphs index), with group // morphs recursively expanded into their leaf vertex morphs. Used to drive Unity // BlendShape weights (SkinnedMeshRenderer.SetBlendShapeWeight) instead of rewriting // vertex positions directly. public void CalculateMorphWeights(MmdModel model, double time, float[] output) { _morphWeightCalculator.Calculate(model, time, output); } public double GetMotionTimeLength() { return _motion.Length * 30.0; } public int GetMotionFrameLength() { return _motion.Length; } private readonly MmdMotion _motion; private readonly Poser _poser; private readonly MmdMotionTranslationScaler _translationScaler; private readonly MmdMotionBindingMap _bindings; private readonly MmdGrooveFallback _grooveFallback; private readonly MmdMorphWeightCalculator _morphWeightCalculator; } }