using System; using System.Collections.Generic; using LibMMD.Model; using LibMMD.Util; namespace LibMMD.Motion { internal sealed class MmdMorphWeightCalculator { private readonly MmdMotion _motion; private readonly List> _morphs = new List>(); internal MmdMorphWeightCalculator(MmdMotion motion, IEnumerable> morphs) { _motion = motion; _morphs.AddRange(morphs); } internal void Calculate(MmdModel model, double time, float[] output) { if (output.Length != model.Morphs.Length) throw new ArgumentException("model morph count not equals to output array length"); Array.Clear(output, 0, output.Length); foreach (var entry in _morphs) { var pose = _motion.GetMorphPose(entry.Key, time); Accumulate(model, entry.Value, pose.Weight, output); } } private static void Accumulate(MmdModel model, int index, float rate, float[] output) { if (rate < Tools.MmdMathConstEps) return; var morph = model.Morphs[index]; switch (morph.Type) { case Morph.MorphType.MorphTypeGroup: foreach (var morphData in morph.MorphDatas) { var data = (Morph.GroupMorph) morphData; Accumulate(model, data.MorphIndex, data.MorphRate * rate, output); } break; case Morph.MorphType.MorphTypeVertex: output[index] += rate; break; } } } }