public void UnParse(Stream s) { var bw = new BinaryWriter(s); bw.Write(Encoding.ASCII.GetBytes("_pilC3S_")); bw.Write(mVersion); bw.Write(mUnknown01); bw.Write(mFrameDuration); bw.Write(mMaxFrameCount); bw.Write(Unknown02); var indexedFloats = new List<float>(); var curveDataInfos = new List<CurveDataInfo>(); UInt32 curveCount = 0; byte[] frameData; using (var frameStream = new MemoryStream()) { foreach (Track track in Tracks) { foreach (Curve curve in track.Curves) { curveCount++; Single scale = 1f; Single offset = 0f; IEnumerable<float> values = curve.SelectFloats(); if (values.Any()) { float min = values.Min(); float max = values.Max(); offset = (min + max) / 2f; scale = (min - max) / 2f; } //not sure what really determines whether to index or not Boolean isIndexed = curve.Frames.Count == 0 ? true : curve.Type == CurveType.Position ? IsIndexed(curve.Frames.Cast<Frame>()) : false; var flags = new CurveDataFlags(); flags.Format = isIndexed ? CurveDataFormat.Indexed : CurveDataFormat.Packed; flags.Type = curve.Frames.DataType; flags.Static = curve.Frames.Count == 0; var curveDataInfo = new CurveDataInfo { Offset = offset, Flags = flags, FrameCount = curve.Frames.Count, FrameDataOffset = (UInt32)frameStream.Position, Scale = scale, TrackKey = track.TrackKey, Type = curve.Type }; curve.UnParse(frameStream, curveDataInfo, indexedFloats); curveDataInfos.Add(curveDataInfo); } } frameData = frameStream.ToArray(); } bw.Write(curveCount); bw.Write(indexedFloats.Count); long offsets = s.Position; uint curveDataOffset = 0; uint frameDataOffset = 0; uint animNameOffset = 0; uint srcNameOffset = 0; s.Seek(4 * sizeof(UInt32), SeekOrigin.Current); curveDataOffset = (uint)s.Position; var frameOffset = (uint)(curveDataOffset + (20 * curveDataInfos.Count) + mAnimName.Length + mSrcName.Length + 2 + (sizeof(Single) * indexedFloats.Count)); foreach (CurveDataInfo curveDataInfo in curveDataInfos) { bw.Write((curveDataInfo.FrameDataOffset + frameOffset)); bw.Write(curveDataInfo.TrackKey); bw.Write(curveDataInfo.Offset); bw.Write(curveDataInfo.Scale); bw.Write((UInt16)curveDataInfo.FrameCount); bw.Write(curveDataInfo.Flags.Raw); bw.Write((Byte)curveDataInfo.Type); } animNameOffset = (uint)s.Position; bw.WriteZString( AnimName); srcNameOffset = (uint)s.Position; bw.WriteZString(SrcName); frameDataOffset = (uint)s.Position; foreach (float f in indexedFloats) bw.Write(f); bw.Write(frameData); s.Seek(offsets, SeekOrigin.Begin); bw.Write(curveDataOffset); bw.Write(frameDataOffset); bw.Write(animNameOffset); bw.Write(srcNameOffset); s.Position = s.Length; }
public void UnParse(Stream s) { var bw = new BinaryWriter(s); bw.Write(Encoding.ASCII.GetBytes("_pilC3S_")); bw.Write(mVersion); bw.Write(mUnknown01); bw.Write(mFrameDuration); bw.Write(mMaxFrameCount); bw.Write(Unknown02); var indexedFloats = new List <float>(); var curveDataInfos = new List <CurveDataInfo>(); UInt32 curveCount = 0; byte[] frameData; using (var frameStream = new MemoryStream()) { foreach (Track track in Tracks) { foreach (Curve curve in track.Curves) { curveCount++; Single scale = 1f; Single offset = 0f; IEnumerable <float> values = curve.SelectFloats(); if (values.Any()) { float min = values.Min(); float max = values.Max(); offset = (min + max) / 2f; scale = (min - max) / 2f; } //not sure what really determines whether to index or not Boolean isIndexed = curve.Frames.Count == 0 ? true : curve.Type == CurveType.Position ? IsIndexed(curve.Frames.Cast <Frame>()) : false; var flags = new CurveDataFlags(); flags.Format = isIndexed ? CurveDataFormat.Indexed : CurveDataFormat.Packed; flags.Type = curve.Frames.DataType; flags.Static = curve.Frames.Count == 0; var curveDataInfo = new CurveDataInfo { Offset = offset, Flags = flags, FrameCount = curve.Frames.Count, FrameDataOffset = (UInt32)frameStream.Position, Scale = scale, TrackKey = track.TrackKey, Type = curve.Type }; curve.UnParse(frameStream, curveDataInfo, indexedFloats); curveDataInfos.Add(curveDataInfo); } } frameData = frameStream.ToArray(); } bw.Write(curveCount); bw.Write(indexedFloats.Count); long offsets = s.Position; uint curveDataOffset = 0; uint frameDataOffset = 0; uint animNameOffset = 0; uint srcNameOffset = 0; s.Seek(4 * sizeof(UInt32), SeekOrigin.Current); curveDataOffset = (uint)s.Position; var frameOffset = (uint)(curveDataOffset + (20 * curveDataInfos.Count) + mAnimName.Length + mSrcName.Length + 2 + (sizeof(Single) * indexedFloats.Count)); foreach (CurveDataInfo curveDataInfo in curveDataInfos) { bw.Write((curveDataInfo.FrameDataOffset + frameOffset)); bw.Write(curveDataInfo.TrackKey); bw.Write(curveDataInfo.Offset); bw.Write(curveDataInfo.Scale); bw.Write((UInt16)curveDataInfo.FrameCount); bw.Write(curveDataInfo.Flags.Raw); bw.Write((Byte)curveDataInfo.Type); } animNameOffset = (uint)s.Position; bw.WriteZString(AnimName); srcNameOffset = (uint)s.Position; bw.WriteZString(SrcName); frameDataOffset = (uint)s.Position; foreach (float f in indexedFloats) { bw.Write(f); } bw.Write(frameData); s.Seek(offsets, SeekOrigin.Begin); bw.Write(curveDataOffset); bw.Write(frameDataOffset); bw.Write(animNameOffset); bw.Write(srcNameOffset); s.Position = s.Length; }