/// <summary> /// /// </summary> /// <param name="type"></param> /// <returns></returns> private static bool HasSlope(GXInterpolationType type) { switch (type) { case GXInterpolationType.HSD_A_OP_SLP: case GXInterpolationType.HSD_A_OP_SPL: return(true); default: return(false); } }
public List <FOBJKey> GetKeys(float startframe, float frame_count = -1) { List <FOBJKey> Keys = new List <FOBJKey>(); if (FOBJ.JointTrackType == JointTrackType.HSD_A_J_PTCL) { return(Keys); } float clock = startframe; Reader.Seek(0); while (Reader.Position < Reader.BaseStream.Length) { int type = Reader.ReadPacked(); GXInterpolationType interpolation = (GXInterpolationType)((type) & 0x0F); int numOfKey = ((type >> 4)) + 1; if (interpolation == 0) { break; } for (int i = 0; i < numOfKey; i++) { double value = 0; double tan = 0; int time = 0; switch (interpolation) { case GXInterpolationType.HSD_A_OP_CON: value = ParseFloat(Reader, FOBJ.ValueFormat, FOBJ.ValueScale); time = Reader.ReadPacked(); break; case GXInterpolationType.HSD_A_OP_LIN: value = ParseFloat(Reader, FOBJ.ValueFormat, FOBJ.ValueScale); time = Reader.ReadPacked(); break; case GXInterpolationType.HSD_A_OP_SPL0: value = ParseFloat(Reader, FOBJ.ValueFormat, FOBJ.ValueScale); time = Reader.ReadPacked(); break; case GXInterpolationType.HSD_A_OP_SPL: value = ParseFloat(Reader, FOBJ.ValueFormat, FOBJ.ValueScale); tan = ParseFloat(Reader, FOBJ.TanFormat, FOBJ.TanScale); time = Reader.ReadPacked(); break; case GXInterpolationType.HSD_A_OP_SLP: tan = ParseFloat(Reader, FOBJ.TanFormat, FOBJ.TanScale); break; case GXInterpolationType.HSD_A_OP_KEY: value = ParseFloat(Reader, FOBJ.ValueFormat, FOBJ.ValueScale); break; default: throw new Exception("Unknown Interpolation Type " + interpolation.ToString("X")); } FOBJKey kf = new FOBJKey(); kf.InterpolationType = interpolation; kf.Value = (float)value; kf.Frame = clock; kf.Tan = (float)tan; Keys.Add(kf); clock += time; } } // hack for animations that don't start on frame 0 if (Keys.Count > 0 && Keys[0].Frame != 0) { Keys.Insert(0, new FOBJKey() { Frame = 0, Value = Keys[0].Value, InterpolationType = GXInterpolationType.HSD_A_OP_CON }); } return(Keys); }
public static HSD_FOBJ EncodeFrames(List <FOBJKey> Keys, byte TrackType, float error = 0.0001f) { HSD_FOBJ fobj = new HSD_FOBJ(); fobj.JointTrackType = (JointTrackType)TrackType; if (fobj.JointTrackType == JointTrackType.HSD_A_J_PTCL) { return(fobj); } // automatically set single key interpolation type if (Keys.Count == 1) { Keys[0].InterpolationType = GXInterpolationType.HSD_A_OP_KEY; } // perform quantization FOBJQuantanizer valueQ = new FOBJQuantanizer(error); FOBJQuantanizer tangentQ = new FOBJQuantanizer(error); 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 (BinaryWriterExt Writer = new BinaryWriterExt(o)) { Writer.BigEndian = false; for (int i = 0; i < Keys.Count;) { GXInterpolationType ip = Keys[i].InterpolationType; int j; for (j = 0; j < Keys.Count - i; j++) { if (Keys[i + j].InterpolationType != ip) { break; } } if (j > 0x7FF) { j = 0x7FF; } int flag = ((j - 1) << 4) | (int)ip; Writer.WritePacked(flag); for (int k = i; k < i + j; k++) { int DeltaTime = 0; if (k + 1 < Keys.Count) { var nextKey = Keys.Find(e => e.Frame > Keys[k].Frame && e.InterpolationType != GXInterpolationType.HSD_A_OP_SLP); if (nextKey != null) { DeltaTime = (int)(nextKey.Frame - Keys[k].Frame); } } if (k == Keys.Count) { DeltaTime = 1; } switch (ip) { case GXInterpolationType.HSD_A_OP_CON: valueQ.WriteValue(Writer, Keys[k].Value); Writer.WritePacked(DeltaTime); break; case GXInterpolationType.HSD_A_OP_LIN: valueQ.WriteValue(Writer, Keys[k].Value); Writer.WritePacked(DeltaTime); break; case GXInterpolationType.HSD_A_OP_SPL0: valueQ.WriteValue(Writer, Keys[k].Value); Writer.WritePacked(DeltaTime); break; case GXInterpolationType.HSD_A_OP_SPL: valueQ.WriteValue(Writer, Keys[k].Value); tangentQ.WriteValue(Writer, Keys[k].Tan); Writer.WritePacked(DeltaTime); break; case GXInterpolationType.HSD_A_OP_SLP: tangentQ.WriteValue(Writer, Keys[k].Tan); break; case GXInterpolationType.HSD_A_OP_KEY: valueQ.WriteValue(Writer, Keys[k].Value); break; } } i += j; } } fobj.Buffer = o.ToArray(); o.Dispose(); return(fobj); }
public List <FOBJKey> GetKeys(float FrameCount = -1) { List <FOBJKey> Keys = new List <FOBJKey>(); int clock = 0; Reader.Seek(0); while (Reader.Position < Reader.BaseStream.Length) { int type = Reader.ReadPacked(); GXInterpolationType interpolation = (GXInterpolationType)((type) & 0x0F); int numOfKey = ((type >> 4)) + 1; if (interpolation == 0) { break; } for (int i = 0; i < numOfKey; i++) { double value = 0; double tan = 0; int time = 0; switch (interpolation) { case GXInterpolationType.HSD_A_OP_CON: value = ParseFloat(Reader, FOBJ.ValueFormat, FOBJ.ValueScale); time = Reader.ReadPacked(); break; case GXInterpolationType.HSD_A_OP_LIN: value = ParseFloat(Reader, FOBJ.ValueFormat, FOBJ.ValueScale); time = Reader.ReadPacked(); break; case GXInterpolationType.HSD_A_OP_SPL0: value = ParseFloat(Reader, FOBJ.ValueFormat, FOBJ.ValueScale); time = Reader.ReadPacked(); break; case GXInterpolationType.HSD_A_OP_SPL: value = ParseFloat(Reader, FOBJ.ValueFormat, FOBJ.ValueScale); tan = ParseFloat(Reader, FOBJ.TanFormat, FOBJ.TanScale); time = Reader.ReadPacked(); break; case GXInterpolationType.HSD_A_OP_SLP: tan = ParseFloat(Reader, FOBJ.TanFormat, FOBJ.TanScale); break; case GXInterpolationType.HSD_A_OP_KEY: value = ParseFloat(Reader, FOBJ.ValueFormat, FOBJ.ValueScale); break; default: throw new Exception("Unknown Interpolation Type " + interpolation.ToString("X")); } FOBJKey kf = new FOBJKey(); kf.InterpolationType = interpolation; kf.Value = (float)value; kf.Frame = clock; kf.Tan = (float)tan; Keys.Add(kf); clock += time; } } return(Keys); }
public List <FOBJKey> GetKeys(float startframe, float frame_count = -1) { List <FOBJKey> Keys = new List <FOBJKey>(); if (FOBJ.JointTrackType == JointTrackType.HSD_A_J_PTCL) { return(Keys); } float clock = 0;// startframe; Reader.Seek(0); while (Reader.Position < Reader.BaseStream.Length) { int type = Reader.ReadPacked(); GXInterpolationType interpolation = (GXInterpolationType)((type) & 0x0F); int numOfKey = ((type >> 4)) + 1; if (interpolation == 0) { break; } for (int i = 0; i < numOfKey; i++) { double value = 0; double tan = 0; int time = 0; switch (interpolation) { case GXInterpolationType.HSD_A_OP_CON: value = ParseFloat(Reader, FOBJ.ValueFormat, FOBJ.ValueScale); time = Reader.ReadPacked(); break; case GXInterpolationType.HSD_A_OP_LIN: value = ParseFloat(Reader, FOBJ.ValueFormat, FOBJ.ValueScale); time = Reader.ReadPacked(); break; case GXInterpolationType.HSD_A_OP_SPL0: value = ParseFloat(Reader, FOBJ.ValueFormat, FOBJ.ValueScale); time = Reader.ReadPacked(); break; case GXInterpolationType.HSD_A_OP_SPL: value = ParseFloat(Reader, FOBJ.ValueFormat, FOBJ.ValueScale); tan = ParseFloat(Reader, FOBJ.TanFormat, FOBJ.TanScale); time = Reader.ReadPacked(); break; case GXInterpolationType.HSD_A_OP_SLP: tan = ParseFloat(Reader, FOBJ.TanFormat, FOBJ.TanScale); break; case GXInterpolationType.HSD_A_OP_KEY: value = ParseFloat(Reader, FOBJ.ValueFormat, FOBJ.ValueScale); break; default: throw new Exception("Unknown Interpolation Type " + interpolation.ToString("X")); } FOBJKey kf = new FOBJKey(); kf.InterpolationType = interpolation; kf.Value = (float)value; kf.Frame = clock; kf.Tan = (float)tan; Keys.Add(kf); clock += time; } } // hack for animations that don't start on frame 0 if (startframe != 0) { // create a player in order to bake keys FOBJ_Player player = new FOBJ_Player(0, Keys); // move starting frame foreach (var k in Keys) { k.Frame -= startframe; } // remove all keys out of bounds Keys.RemoveAll(e => e.Frame < 0); // bake the keys from frame 0 to first key frame if (Keys.Count > 0 && Keys[0].Frame != 0) { var firstFrame = Keys[0].Frame; for (int i = 0; i < firstFrame; i++) { Keys.Insert(i, new FOBJKey() { Frame = i, Value = player.GetValue(i - startframe), InterpolationType = GXInterpolationType.HSD_A_OP_LIN }); } } } return(Keys); }
public float GetValue(float Frame) { // register float p0 = 0; float p1 = 0; float d0 = 0; float d1 = 0; float t0 = 0; float t1 = 0; GXInterpolationType op_intrp = GXInterpolationType.HSD_A_OP_CON; GXInterpolationType op = GXInterpolationType.HSD_A_OP_CON; // get current frame state for (int i = 0; i < Keys.Count; i++) { op_intrp = op; op = Keys[i].InterpolationType; switch (op) { case GXInterpolationType.HSD_A_OP_CON: p0 = p1; p1 = Keys[i].Value; if (op_intrp != GXInterpolationType.HSD_A_OP_SLP) { d0 = d1; d1 = 0; } t0 = t1; t1 = Keys[i].Frame; break; case GXInterpolationType.HSD_A_OP_LIN: p0 = p1; p1 = Keys[i].Value; if (op_intrp != GXInterpolationType.HSD_A_OP_SLP) { d0 = d1; d1 = 0; } t0 = t1; t1 = Keys[i].Frame; break; case GXInterpolationType.HSD_A_OP_SPL0: p0 = p1; d0 = d1; p1 = Keys[i].Value; d1 = 0; t0 = t1; t1 = Keys[i].Frame; break; case GXInterpolationType.HSD_A_OP_SPL: p0 = p1; p1 = Keys[i].Value; d0 = d1; d1 = Keys[i].Tan; t0 = t1; t1 = Keys[i].Frame; break; case GXInterpolationType.HSD_A_OP_SLP: d0 = d1; d1 = Keys[i].Tan; break; case GXInterpolationType.HSD_A_OP_KEY: p1 = Keys[i].Value; p0 = Keys[i].Value; break; } if (t1 > Frame && Keys[i].InterpolationType != GXInterpolationType.HSD_A_OP_SLP) { break; } op_intrp = Keys[i].InterpolationType; } if (t0 == t1 || op_intrp == GXInterpolationType.HSD_A_OP_CON || op_intrp == GXInterpolationType.HSD_A_OP_KEY) { return(p0); } float FrameDiff = Frame - t0; float Weight = FrameDiff / (t1 - t0); if (op_intrp == GXInterpolationType.HSD_A_OP_LIN) { return(AnimationHelperInterpolation.Lerp(p0, p1, Weight)); } if (op_intrp == GXInterpolationType.HSD_A_OP_SPL || op_intrp == GXInterpolationType.HSD_A_OP_SPL0 || op_intrp == GXInterpolationType.HSD_A_OP_SLP) { return(AnimationHelperInterpolation.Herp(p0, p1, d0, d1, FrameDiff, Weight)); } return(p0); }
public static AnimState GetState(float Frame, List <FOBJKey> Keys) { // register float p0 = 0; float p1 = 0; float d0 = 0; float d1 = 0; float t0 = 0; float t1 = 0; GXInterpolationType op_intrp = GXInterpolationType.HSD_A_OP_CON; GXInterpolationType op = GXInterpolationType.HSD_A_OP_CON; // get current frame state for (int i = 0; i < Keys.Count; i++) { op_intrp = op; op = Keys[i].InterpolationType; switch (op) { case GXInterpolationType.HSD_A_OP_CON: p0 = p1; p1 = Keys[i].Value; if (op_intrp != GXInterpolationType.HSD_A_OP_SLP) { d0 = d1; d1 = 0; } t0 = t1; t1 = Keys[i].Frame; break; case GXInterpolationType.HSD_A_OP_LIN: p0 = p1; p1 = Keys[i].Value; if (op_intrp != GXInterpolationType.HSD_A_OP_SLP) { d0 = d1; d1 = 0; } t0 = t1; t1 = Keys[i].Frame; break; case GXInterpolationType.HSD_A_OP_SPL0: p0 = p1; d0 = d1; p1 = Keys[i].Value; d1 = 0; t0 = t1; t1 = Keys[i].Frame; break; case GXInterpolationType.HSD_A_OP_SPL: p0 = p1; p1 = Keys[i].Value; d0 = d1; d1 = Keys[i].Tan; t0 = t1; t1 = Keys[i].Frame; break; case GXInterpolationType.HSD_A_OP_SLP: d0 = d1; d1 = Keys[i].Tan; break; case GXInterpolationType.HSD_A_OP_KEY: p1 = Keys[i].Value; p0 = Keys[i].Value; break; } if (t1 > Frame && Keys[i].InterpolationType != GXInterpolationType.HSD_A_OP_SLP) { break; } op_intrp = Keys[i].InterpolationType; } return(new AnimState() { t0 = t0, t1 = t1, p0 = p0, p1 = p1, d0 = d0, d1 = d1, op = op, op_intrp = op_intrp }); }
public static HSD_FOBJ EncodeFrames(List <FOBJKey> Keys, byte TrackType) { HSD_FOBJ fobj = new HSD_FOBJ(); fobj.AnimationType = (JointTrackType)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 (BinaryWriterExt Writer = new BinaryWriterExt(o)) { Writer.BigEndian = false; int time = 0; for (int i = 0; i < Keys.Count;) { GXInterpolationType 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 GXInterpolationType.HSD_A_OP_CON: valueQ.WriteValue(Writer, Keys[k].Value); Writer.ExtendedByte(DeltaTime); break; case GXInterpolationType.HSD_A_OP_LIN: valueQ.WriteValue(Writer, Keys[k].Value); Writer.ExtendedByte(DeltaTime); break; case GXInterpolationType.HSD_A_OP_SPL0: valueQ.WriteValue(Writer, Keys[k].Value); Writer.ExtendedByte(DeltaTime); break; case GXInterpolationType.HSD_A_OP_SPL: valueQ.WriteValue(Writer, Keys[k].Value); tangentQ.WriteValue(Writer, Keys[k].Tan); Writer.ExtendedByte(DeltaTime); break; case GXInterpolationType.HSD_A_OP_SLP: tangentQ.WriteValue(Writer, Keys[k].Tan); break; case GXInterpolationType.HSD_A_OP_KEY: valueQ.WriteValue(Writer, Keys[k].Value); break; } if (ip != GXInterpolationType.HSD_A_OP_SLP) { time = (int)Keys[k].Frame; } } i += j; } } fobj.Buffer = o.ToArray(); o.Dispose(); return(fobj); }