예제 #1
0
 private void Parse(Stream s, CurveDataInfo info, IList <float> floats)
 {
     for (int i = 0; i < info.FrameCount; i++)
     {
         ((IList <Frame>) this).Add(new Frame(0, this.handler, s, info, floats));
     }
 }
예제 #2
0
파일: Frame.cs 프로젝트: yalaier/Sims4Tools
        public void Parse(Stream s, CurveDataInfo info, IList <float> indexedFloats)
        {
            var br = new BinaryReader(s);

            mFrameIndex = br.ReadUInt16();
            ushort flags = br.ReadUInt16();

            mFlags = (UInt16)(flags >> 4);

            switch (info.Flags.Format)
            {
            case CurveDataFormat.Indexed:

                for (int floatsRead = 0; floatsRead < Curve.GetFloatCount(DataType); floatsRead++)
                {
                    float val = indexedFloats[br.ReadUInt16()];
                    if ((flags & 1 << floatsRead) != 0 ? true : false)
                    {
                        val *= -1;
                    }
                    mData[floatsRead] = Unpack(val, info.Offset, info.Scale);
                }
                break;

            case CurveDataFormat.Packed:
                for (int packedRead = 0; packedRead < Curve.GetPackedCount(DataType); packedRead++)
                {
                    ulong packed;
                    switch (DataType)
                    {
                    case CurveDataType.Float4:
                    case CurveDataType.Float1:
                        packed = br.ReadUInt16();
                        break;

                    case CurveDataType.Float3:
                        packed = br.ReadUInt32();
                        break;

                    default:
                        packed = br.ReadUInt16();
                        break;
                    }
                    for (int packedIndex = 0; packedIndex < Curve.GetFloatCount(DataType) / Curve.GetPackedCount(DataType); packedIndex++)
                    {
                        int   floatIndex   = packedIndex + packedRead;
                        int   bitsPerFloat = Curve.GetBitsPerFloat(DataType);
                        var   maxPackedVal = (ulong)(Math.Pow(2, bitsPerFloat) - 1);
                        ulong mask         = (maxPackedVal << (packedIndex * bitsPerFloat));
                        float val          = ((packed & mask) >> (packedIndex * bitsPerFloat)) / (float)maxPackedVal;
                        if ((flags & 1 << floatIndex) != 0 ? true : false)
                        {
                            val *= -1;
                        }
                        mData[floatIndex] = Unpack(val, info.Offset, info.Scale);
                    }
                }
                break;
            }
        }
예제 #3
0
 public void UnParse(Stream s, CurveDataInfo info, IList <float> floats)
 {
     info.FrameDataOffset = (uint)s.Position;
     info.FrameCount      = Count;
     for (int i = 0; i < Count; i++)
     {
         this[i].UnParse(s, info, floats);
     }
 }
예제 #4
0
파일: Frame.cs 프로젝트: yalaier/Sims4Tools
 public Frame(int apiVersion, EventHandler handler, Stream s, CurveDataInfo info, IList <float> indexedFloats)
     : this(apiVersion, handler, info.Flags.Type)
 {
     Parse(s, info, indexedFloats);
 }
예제 #5
0
파일: Frame.cs 프로젝트: yalaier/Sims4Tools
        public virtual void UnParse(Stream s, CurveDataInfo info, IList <float> indexedFloats)
        {
            var bw = new BinaryWriter(s);

            bw.Write(mFrameIndex);
            int flags = mFlags << 4;

            UInt16[] indices    = null;
            ulong[]  packedVals = null;
            switch (info.Flags.Format)
            {
            case CurveDataFormat.Indexed:
                indices = new ushort[Curve.GetFloatCount(DataType)];
                for (int i = 0; i < Curve.GetFloatCount(DataType); i++)
                {
                    float packedIndex = Pack(mData[i], info.Offset, info.Scale);
                    if (packedIndex < 0)
                    {
                        flags |= (1 << i);
                    }
                    packedIndex = Math.Abs(packedIndex);
                    if (!indexedFloats.Contains(packedIndex))
                    {
                        indexedFloats.Add(packedIndex);
                    }
                    indices[i] = (UInt16)indexedFloats.IndexOf(packedIndex);
                }
                break;

            case CurveDataFormat.Packed:
                packedVals = new ulong[Curve.GetPackedCount(DataType)];
                for (int packedWritten = 0; packedWritten < packedVals.Length; packedWritten++)
                {
                    ulong packed = 0;
                    for (int packedIndex = 0; packedIndex < Curve.GetFloatCount(DataType) / packedVals.Length; packedIndex++)
                    {
                        int    floatIndex   = packedWritten + packedIndex;
                        double maxPackedVal = Math.Pow(2, Curve.GetBitsPerFloat(DataType)) - 1;
                        float  val          = (mData[floatIndex] - info.Offset) / info.Scale;
                        if (val < 0)
                        {
                            flags |= (1 << floatIndex);
                        }
                        val     = Math.Abs(val);
                        packed |= (ulong)Math.Floor(val * maxPackedVal) << (packedIndex * Curve.GetBitsPerFloat(DataType));
                    }
                    packedVals[packedWritten] = packed;
                }
                break;
            }
            bw.Write((UInt16)flags);
            switch (info.Flags.Format)
            {
            case CurveDataFormat.Indexed:
                for (int i = 0; i < indices.Length; i++)
                {
                    bw.Write(indices[i]);
                }
                break;

            case CurveDataFormat.Packed:
                for (int i = 0; i < packedVals.Length; i++)
                {
                    Debug.WriteLine("broken");    //WritePacked(s, packedVals[i]);
                }
                break;
            }
        }
예제 #6
0
        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;
        }
예제 #7
0
        protected void Parse(Stream s)
        {
            var br = new BinaryReader(s);
            string foo = FOURCC(br.ReadUInt64());
            if (foo != "_pilC3S_")
                throw new Exception("Bad clip header: Expected \"_S3Clip_\"");
            mVersion = br.ReadUInt32();
            mUnknown01 = br.ReadUInt32();
            mFrameDuration = br.ReadSingle();
            mMaxFrameCount = br.ReadUInt16();
            mUnknown02 = br.ReadUInt16();

            uint curveCount = br.ReadUInt32();
            uint indexedFloatCount = br.ReadUInt32();
            uint curveDataOffset = br.ReadUInt32();
            uint frameDataOffset = br.ReadUInt32();
            uint animNameOffset = br.ReadUInt32();
            uint srcNameOffset = br.ReadUInt32();

            if (checking && s.Position != curveDataOffset)
                throw new InvalidDataException("Bad Curve Data Offset");

            var curveDataInfos = new List<CurveDataInfo>();
            for (int i = 0; i < curveCount; i++)
            {
                var p = new CurveDataInfo();
                p.FrameDataOffset = br.ReadUInt32();
                p.TrackKey = br.ReadUInt32();
                p.Offset = br.ReadSingle();
                p.Scale = br.ReadSingle();
                p.FrameCount = br.ReadUInt16();
                p.Flags = new CurveDataFlags(br.ReadByte());
                p.Type = (CurveType)br.ReadByte();
                curveDataInfos.Add(p);
            }

            if (checking && s.Position != animNameOffset)
                throw new InvalidDataException("Bad Name Offset");
            mAnimName = br.ReadZString();
            if (checking && s.Position != srcNameOffset)
                throw new InvalidDataException("Bad SourceName Offset");
            mSrcName = br.ReadZString();

            if (checking && s.Position != frameDataOffset)
                throw new InvalidDataException("Bad Indexed Floats Offset");
            var indexedFloats = new List<float>();
            for (int i = 0; i < indexedFloatCount; i++)
            {
                indexedFloats.Add(br.ReadSingle());
            }

            var trackMap = new Dictionary<uint, List<Curve>>();
            var test = curveDataInfos.Where(x => x.Type != CurveType.Position && x.Type != CurveType.Orientation).ToArray();
            for (int i = 0; i < curveDataInfos.Count; i++)
            {
                    CurveDataInfo curveDataInfo = curveDataInfos[i];
                try
                {

                    if (checking && s.Position != curveDataInfo.FrameDataOffset)
                        throw new InvalidDataException("Bad FrameData offset.");
                    Curve curve;

                    curve = new Curve(0, handler, curveDataInfo.Type, curveDataInfo.Flags.Type, s, curveDataInfo, indexedFloats);

                    if (!trackMap.ContainsKey(curveDataInfo.TrackKey))
                    {
                        trackMap[curveDataInfo.TrackKey] = new List<Curve>();
                    }
                    trackMap[curveDataInfo.TrackKey].Add(curve);
                }
                catch (Exception)
                {
                    Debug.WriteLine("Can't load channel with type: " + curveDataInfo.Type);
                }

            }

            var tracks = new List<Track>();
            foreach (uint k in trackMap.Keys)
            {
                tracks.Add(new Track(0, handler, k, trackMap[k]));
            }
            mTracks = new TrackList(handler, tracks);

            if (checking && s.Position != s.Length)
                throw new InvalidDataException("Unexpected End of Clip.");
        }
예제 #8
0
 public Curve(int apiVersion, EventHandler handler, CurveType type, CurveDataType dataType, Stream s, CurveDataInfo info, IList <float> indexedFloats)
     : this(apiVersion, handler, type, dataType)
 {
     Parse(s, info, indexedFloats);
 }
예제 #9
0
 public virtual void UnParse(Stream s, CurveDataInfo info, IList <float> indexedFloats)
 {
     mFrames.UnParse(s, info, indexedFloats);
 }
예제 #10
0
 protected virtual void Parse(Stream s, CurveDataInfo info, IList <float> indexedFloats)
 {
     mFrames = new FrameList(handler, info.Flags.Type, s, info, indexedFloats);
 }
예제 #11
0
파일: Clip.cs 프로젝트: yalaier/Sims4Tools
        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;
        }
예제 #12
0
파일: Clip.cs 프로젝트: yalaier/Sims4Tools
        protected void Parse(Stream s)
        {
            var    br  = new BinaryReader(s);
            string foo = FOURCC(br.ReadUInt64());

            if (foo != "_pilC3S_")
            {
                throw new Exception("Bad clip header: Expected \"_S3Clip_\"");
            }
            mVersion       = br.ReadUInt32();
            mUnknown01     = br.ReadUInt32();
            mFrameDuration = br.ReadSingle();
            mMaxFrameCount = br.ReadUInt16();
            mUnknown02     = br.ReadUInt16();

            uint curveCount        = br.ReadUInt32();
            uint indexedFloatCount = br.ReadUInt32();
            uint curveDataOffset   = br.ReadUInt32();
            uint frameDataOffset   = br.ReadUInt32();
            uint animNameOffset    = br.ReadUInt32();
            uint srcNameOffset     = br.ReadUInt32();

            if (checking && s.Position != curveDataOffset)
            {
                throw new InvalidDataException("Bad Curve Data Offset");
            }

            var curveDataInfos = new List <CurveDataInfo>();

            for (int i = 0; i < curveCount; i++)
            {
                var p = new CurveDataInfo();
                p.FrameDataOffset = br.ReadUInt32();
                p.TrackKey        = br.ReadUInt32();
                p.Offset          = br.ReadSingle();
                p.Scale           = br.ReadSingle();
                p.FrameCount      = br.ReadUInt16();
                p.Flags           = new CurveDataFlags(br.ReadByte());
                p.Type            = (CurveType)br.ReadByte();
                curveDataInfos.Add(p);
            }

            if (checking && s.Position != animNameOffset)
            {
                throw new InvalidDataException("Bad Name Offset");
            }
            mAnimName = br.ReadZString();
            if (checking && s.Position != srcNameOffset)
            {
                throw new InvalidDataException("Bad SourceName Offset");
            }
            mSrcName = br.ReadZString();

            if (checking && s.Position != frameDataOffset)
            {
                throw new InvalidDataException("Bad Indexed Floats Offset");
            }
            var indexedFloats = new List <float>();

            for (int i = 0; i < indexedFloatCount; i++)
            {
                indexedFloats.Add(br.ReadSingle());
            }

            var trackMap = new Dictionary <uint, List <Curve> >();
            var test     = curveDataInfos.Where(x => x.Type != CurveType.Position && x.Type != CurveType.Orientation).ToArray();

            for (int i = 0; i < curveDataInfos.Count; i++)
            {
                CurveDataInfo curveDataInfo = curveDataInfos[i];
                try
                {
                    if (checking && s.Position != curveDataInfo.FrameDataOffset)
                    {
                        throw new InvalidDataException("Bad FrameData offset.");
                    }
                    Curve curve;

                    curve = new Curve(0, handler, curveDataInfo.Type, curveDataInfo.Flags.Type, s, curveDataInfo, indexedFloats);

                    if (!trackMap.ContainsKey(curveDataInfo.TrackKey))
                    {
                        trackMap[curveDataInfo.TrackKey] = new List <Curve>();
                    }
                    trackMap[curveDataInfo.TrackKey].Add(curve);
                }
                catch (Exception)
                {
                    Debug.WriteLine("Can't load channel with type: " + curveDataInfo.Type);
                }
            }

            var tracks = new List <Track>();

            foreach (uint k in trackMap.Keys)
            {
                tracks.Add(new Track(0, handler, k, trackMap[k]));
            }
            mTracks = new TrackList(handler, tracks);

            if (checking && s.Position != s.Length)
            {
                throw new InvalidDataException("Unexpected End of Clip.");
            }
        }
예제 #13
0
 protected virtual void WriteElement(Stream s, CurveDataInfo info, IList <float> floats, Frame element)
 {
     element.UnParse(s, info, floats);
 }
예제 #14
0
 protected virtual Frame CreateElement(Stream s, CurveDataInfo info, IList <float> floats)
 {
     return(new Frame(0, handler, s, info, floats));
 }
예제 #15
0
 public FrameList(EventHandler handler, CurveDataType type, Stream s, CurveDataInfo info, IList <float> floats)
     : base(handler)
 {
     mDataType = type;
     Parse(s, info, floats);
 }