public static HSD_FOBJ EncodeFrames(List <FOBJKey> Keys, byte TrackType) { HSD_FOBJ fobj = new HSD_FOBJ(); fobj.AnimationType = TrackType; // perform quantization FOBJQuantanizer valueQ = new FOBJQuantanizer(); FOBJQuantanizer tangentQ = new FOBJQuantanizer(); foreach (FOBJKey key in Keys) { valueQ.AddValue(key.Value); tangentQ.AddValue(key.Tan); } fobj.ValueScale = valueQ.GetValueScale(); fobj.ValueFormat = valueQ.GetDataFormat(); fobj.TanScale = tangentQ.GetValueScale(); fobj.TanFormat = tangentQ.GetDataFormat(); MemoryStream o = new MemoryStream(); using (HSDWriter Writer = new HSDWriter(o)) { Writer.BigEndian = false; int time = 0; for (int i = 0; i < Keys.Count;) { InterpolationType ip = Keys[i].InterpolationType; int j; for (j = 0; j < Keys.Count - i; j++) { if (Keys[i + j].InterpolationType != ip) { break; } } int flag = ((j - 1) << 4) | (int)ip; Writer.ExtendedByte(flag); for (int k = i; k < i + j; k++) { int DeltaTime = 0; if (k + 1 < Keys.Count) { DeltaTime = (int)(Keys[k + 1].Frame - Keys[k].Frame); } if (k == Keys.Count) { DeltaTime = 1; } switch (ip) { case InterpolationType.Step: valueQ.WriteValue(Writer, Keys[k].Value); Writer.ExtendedByte(DeltaTime); break; case InterpolationType.Linear: valueQ.WriteValue(Writer, Keys[k].Value); Writer.ExtendedByte(DeltaTime); break; case InterpolationType.HermiteValue: valueQ.WriteValue(Writer, Keys[k].Value); Writer.ExtendedByte(DeltaTime); break; case InterpolationType.Hermite: valueQ.WriteValue(Writer, Keys[k].Value); tangentQ.WriteValue(Writer, Keys[k].Tan); Writer.ExtendedByte(DeltaTime); break; case InterpolationType.HermiteCurve: tangentQ.WriteValue(Writer, Keys[k].Tan); break; case InterpolationType.Constant: valueQ.WriteValue(Writer, Keys[k].Value); break; default: throw new Exception("end"); } if (ip != InterpolationType.HermiteCurve) { time = (int)Keys[k].Frame; } } i += j; } } fobj.Data = o.ToArray(); o.Close(); o.Dispose(); return(fobj); }