private void FindNextCurve(IReadOnlyList <StreamedFrame> streamFrames, int index, int currentFrameIndex, out int frameIndex, out int curveIndex)
        {
            for (frameIndex = currentFrameIndex + 1; frameIndex < streamFrames.Count; frameIndex++)
            {
                StreamedFrame frame = streamFrames[frameIndex];
                for (curveIndex = 0; curveIndex < frame.Curves.Count; curveIndex++)
                {
                    StreamedCurveKey curve = frame.Curves[curveIndex];
                    if (curve.Index == index)
                    {
                        return;
                    }
                }
            }

            // if there is no next curve, use current one
            frameIndex = currentFrameIndex;
            StreamedFrame currentFrame = streamFrames[currentFrameIndex];

            for (curveIndex = 0; curveIndex < currentFrame.Curves.Count; curveIndex++)
            {
                StreamedCurveKey curve = currentFrame.Curves[curveIndex];
                if (curve.Index == index)
                {
                    return;
                }
            }
            throw new Exception($"There is no curve with index {index} in any of current or next frames");
        }
        private void ProcessStreams(IReadOnlyList <StreamedFrame> streamFrames, AnimationClipBindingConstant bindings, IReadOnlyDictionary <uint, string> tos, float sampleRate)
        {
            float[] curveValues    = new float[4];
            float[] inSlopeValues  = new float[4];
            float[] outSlopeValues = new float[4];
            float   interval       = 1.0f / sampleRate;

            // first (index [0]) stream frame is for slope calculation for the first real frame (index [1])
            // last one (index [count - 1]) is +Infinity
            // it is made for slope processing, but we don't need them
            for (int frameIndex = 1; frameIndex < streamFrames.Count - 1; frameIndex++)
            {
                StreamedFrame frame = streamFrames[frameIndex];
                for (int curveIndex = 0; curveIndex < frame.Curves.Count;)
                {
                    StreamedCurveKey curve   = frame.Curves[curveIndex];
                    GenericBinding   binding = bindings.FindBinding(curve.Index);
                    GetPreviousFrame(streamFrames, curve.Index, frameIndex, out int prevFrameIndex, out int prevCurveIndex);

                    string path = GetCurvePath(tos, binding.Path);
                    if (binding.IsTransform)
                    {
                        int dimension = binding.TransformType.GetDimension();
                        for (int key = 0; key < dimension; key++)
                        {
                            StreamedCurveKey keyCurve     = frame.Curves[curveIndex];
                            StreamedFrame    prevFrame    = streamFrames[prevFrameIndex];
                            StreamedCurveKey prevKeyCurve = prevFrame.Curves[prevCurveIndex + key];
                            float            deltaTime    = frame.Time - prevFrame.Time;
                            curveValues[key]    = keyCurve.Value;
                            inSlopeValues[key]  = prevKeyCurve.CalculateNextInSlope(deltaTime, keyCurve.Value);
                            outSlopeValues[key] = keyCurve.OutSlope;
                            curveIndex          = GetNextCurve(frame, curveIndex);
                        }

                        AddTransformCurve(frame.Time, binding.TransformType, curveValues, inSlopeValues, outSlopeValues, 0, path);
                    }
                    else if (binding.CustomType == BindingCustomType.None)
                    {
                        AddDefaultCurve(binding, path, frame.Time, frame.Curves[curveIndex].Value);
                        curveIndex = GetNextCurve(frame, curveIndex);
                    }
                    else
                    {
                        AddCustomCurve(bindings, binding, path, frame.Time, frame.Curves[curveIndex].Value);
                        curveIndex = GetNextCurve(frame, curveIndex);
                    }
                }
            }
        }
        private int GetNextCurve(StreamedFrame frame, int currentCurve)
        {
            StreamedCurveKey curve = frame.Curves[currentCurve];
            int i = currentCurve + 1;

            for (; i < frame.Curves.Count; i++)
            {
                if (frame.Curves[i].Index != curve.Index)
                {
                    return(i);
                }
            }
            return(i);
        }
 private void GetPreviousFrame(IReadOnlyList <StreamedFrame> streamFrames, int curveID, int currentFrame, out int frameIndex, out int curveIndex)
 {
     for (frameIndex = currentFrame - 1; frameIndex >= 0; frameIndex--)
     {
         StreamedFrame frame = streamFrames[frameIndex];
         for (curveIndex = 0; curveIndex < frame.Curves.Count; curveIndex++)
         {
             StreamedCurveKey curve = frame.Curves[curveIndex];
             if (curve.Index == curveID)
             {
                 return;
             }
         }
     }
     throw new Exception($"There is no curve with index {curveID} in any of previous frames");
 }
        private void ProcessStreams(IReadOnlyList <StreamedFrame> streamFrames, AnimationClipBindingConstant bindings, IReadOnlyDictionary <uint, string> tos)
        {
            float[] curveValues    = new float[4];
            float[] inSlopeValues  = new float[4];
            float[] outSlopeValues = new float[4];

            // first (index [0]) stream frame is for slope calculation for the first real frame (index [1])
            // last one (index [count - 1]) is +Infinity
            // it is made for slope processing, but we don't need them
            for (int frameIndex = 1; frameIndex < streamFrames.Count - 1; frameIndex++)
            {
                StreamedFrame frame = streamFrames[frameIndex];
                for (int curveIndex = 0; curveIndex < frame.Curves.Count;)
                {
                    StreamedCurveKey curve = frame.Curves[curveIndex];
                    if (!GetGenericBinding(bindings, curve.Index, out GenericBinding binding))
                    {
                        curveIndex++;
                        continue;
                    }

                    //FindPreviousCurve(streamFrames, curve.Index, frameIndex, out int prevFrameIndex, out int prevCurveIndex);
                    //FindNextCurve(streamFrames, curve.Index, frameIndex, out int nextFrameIndex, out int nextCurveIndex);

                    string path      = GetCurvePath(tos, binding.Path);
                    int    dimension = binding.BindingType.GetDimension();
                    for (int key = 0; key < dimension; key++)
                    {
                        StreamedCurveKey keyCurve = frame.Curves[curveIndex + key];
                        //StreamedFrame prevFrame = streamFrames[prevFrameIndex];
                        //StreamedFrame nextFrame = streamFrames[nextFrameIndex];
                        //StreamedCurveKey prevKeyCurve = prevFrame.Curves[prevCurveIndex + key];
                        //StreamedCurveKey nextKeyCurve = nextFrame.Curves[nextCurveIndex + key];
                        curveValues[key] = keyCurve.Value;
#warning TODO: TCB to in/out slope
                        //inSlopeValues[key] = prevKeyCurve.CalculateNextInTangent(keyCurve.Value, nextKeyCurve.Value);
                        //outSlopeValues[key] = keyCurve.CalculateOutTangent(prevKeyCurve.Value, nextKeyCurve.Value);
                    }

                    AddComplexCurve(frame.Time, binding.BindingType, curveValues, inSlopeValues, outSlopeValues, 0, path);
                    curveIndex += dimension;
                }
            }
        }
예제 #6
0
        public IReadOnlyList <StreamedFrame> GenerateFrames(Version version, Platform platform, TransferInstructionFlags flags)
        {
            List <StreamedFrame> frames = new List <StreamedFrame>();

            byte[] memStreamBuffer = new byte[Data.Length * sizeof(uint)];
            Buffer.BlockCopy(Data, 0, memStreamBuffer, 0, memStreamBuffer.Length);
            using (MemoryStream stream = new MemoryStream(memStreamBuffer))
            {
                using (AssetReader reader = new AssetReader(stream, version, platform, flags))
                {
                    while (reader.BaseStream.Position < reader.BaseStream.Length)
                    {
                        StreamedFrame frame = new StreamedFrame();
                        frame.Read(reader);
                        frames.Add(frame);
                    }
                }
            }
            return(frames);
        }
예제 #7
0
        public IReadOnlyList <StreamedFrame> GenerateFrames(AssetLayout layout)
        {
            List <StreamedFrame> frames = new List <StreamedFrame>();

            byte[] memStreamBuffer = new byte[Data.Length * sizeof(uint)];
            Buffer.BlockCopy(Data, 0, memStreamBuffer, 0, memStreamBuffer.Length);
            using (MemoryStream stream = new MemoryStream(memStreamBuffer))
            {
                using (AssetReader reader = new AssetReader(stream, EndianType.LittleEndian, layout))
                {
                    while (reader.BaseStream.Position < reader.BaseStream.Length)
                    {
                        StreamedFrame frame = new StreamedFrame();
                        frame.Read(reader);
                        frames.Add(frame);
                    }
                }
            }
            return(frames);
        }