Exemplo n.º 1
0
        private void ProcessStreams(IReadOnlyList <StreamedFrame> streamFrames, AnimationClipBindingConstant bindings, IReadOnlyDictionary <uint, string> tos)
        {
            float[] curveValues = new float[4];
            for (int frameIndex = 1; frameIndex < streamFrames.Count - 2; 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;
                    }

                    string path      = GetCurvePath(tos, binding.Path);
                    int    dimension = binding.BindingType.GetDimension();
                    for (int key = 0; key < dimension; key++)
                    {
                        curveValues[key] = frame.Curves[curveIndex + key].Value;
                    }

                    AddComplexCurve(frame.Time, binding.BindingType, curveValues, 0, path);
                    curveIndex += dimension;
                }
            }
        }
Exemplo n.º 2
0
        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");
        }
Exemplo n.º 3
0
        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.Length;)
                {
                    StreamedCurveKey curve   = frame.Curves[curveIndex];
                    GenericBinding   binding = bindings.FindBinding(curve.Index);

                    string path = GetCurvePath(tos, binding.Path);
                    if (binding.IsTransform)
                    {
                        GetPreviousFrame(streamFrames, curve.Index, frameIndex, out int prevFrameIndex, out int prevCurveIndex);
                        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);
                    }
                }
            }
        }
Exemplo n.º 4
0
        private int GetNextCurve(StreamedFrame frame, int currentCurve)
        {
            StreamedCurveKey curve = frame.Curves[currentCurve];
            int i = currentCurve + 1;

            for (; i < frame.Curves.Length; i++)
            {
                if (frame.Curves[i].Index != curve.Index)
                {
                    return(i);
                }
            }
            return(i);
        }
Exemplo n.º 5
0
 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.Length; 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");
 }
Exemplo n.º 6
0
        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;
                }
            }
        }
Exemplo n.º 7
0
        public IReadOnlyList <StreamedFrame> GenerateFrames(Version version, Platform platform, TransferInstructionFlags flags)
        {
            List <StreamedFrame> frames = new List <StreamedFrame>();

            byte[] memStreamBuffer = new byte[m_data.Length * sizeof(uint)];
            Buffer.BlockCopy(m_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);
        }
Exemplo n.º 8
0
        public IReadOnlyList <StreamedFrame> GenerateFrames(IAssetsExporter exporter)
        {
            List <StreamedFrame> frames = new List <StreamedFrame>();

            byte[] memStreamBuffer = new byte[m_data.Length * sizeof(uint)];
            Buffer.BlockCopy(m_data, 0, memStreamBuffer, 0, memStreamBuffer.Length);
            using (MemoryStream memStream = new MemoryStream(memStreamBuffer))
            {
                using (AssetStream stream = new AssetStream(memStream, exporter.Version, exporter.Platform))
                {
                    while (stream.BaseStream.Position < stream.BaseStream.Length)
                    {
                        StreamedFrame frame = new StreamedFrame();
                        frame.Read(stream);
                        frames.Add(frame);
                    }
                }
            }
            return(frames);
        }
Exemplo n.º 9
0
        public IReadOnlyList <StreamedFrame> GenerateFrames()
        {
            List <StreamedFrame> frames = new List <StreamedFrame>();

            byte[] memStreamBuffer = new byte[m_data.Length * sizeof(uint)];
            Buffer.BlockCopy(m_data, 0, memStreamBuffer, 0, memStreamBuffer.Length);
            using (MemoryStream memStream = new MemoryStream(memStreamBuffer))
            {
                using (EndianStream stream = new EndianStream(memStream, EndianType.LittleEndian))
                {
                    while (stream.BaseStream.Position < stream.BaseStream.Length)
                    {
                        StreamedFrame frame = new StreamedFrame();
                        frame.Read(stream);
                        frames.Add(frame);
                    }
                }
            }
            return(frames);
        }
Exemplo n.º 10
0
        public void ExportGenericData(IExportContainer container, YAMLMappingNode node, IReadOnlyDictionary <uint, string> tos)
        {
            StreamedClip streamedClip = MuscleClip.Clip.StreamedClip;
            DenseClip    denseClip    = MuscleClip.Clip.DenseClip;
            ConstantClip constantClip = MuscleClip.Clip.ConstantClip;

            IReadOnlyList <StreamedFrame>      streamedFrames = streamedClip.GenerateFrames(container);
            Dictionary <uint, Vector3Curve>    translations   = new Dictionary <uint, Vector3Curve>();
            Dictionary <uint, QuaternionCurve> rotations      = new Dictionary <uint, QuaternionCurve>();
            Dictionary <uint, Vector3Curve>    scales         = new Dictionary <uint, Vector3Curve>();
            Dictionary <uint, Vector3Curve>    eulers         = new Dictionary <uint, Vector3Curve>();
            Dictionary <uint, FloatCurve>      floats         = new Dictionary <uint, FloatCurve>();

            int frameCount = Math.Max(denseClip.FrameCount - 1, streamedFrames.Count - 2);

            float[] frameCurvesValue = new float[streamedClip.CurveCount];
            for (int frame = 0, streamFrame = 1; frame < frameCount; frame++, streamFrame++)
            {
                bool          isAdd = true;
                float         time;
                StreamedFrame streamedFrame = new StreamedFrame();
                if (streamFrame < streamedFrames.Count)
                {
                    streamedFrame = streamedFrames[streamFrame];
                    time          = streamedFrame.Time;
                }
                else
                {
                    time = (float)frame / SampleRate;
                }

                bool isStreamFrame = streamFrame < (streamedFrames.Count - 1);
                bool isDenseFrame  = frame < (denseClip.FrameCount - 1);

                // number of stream curves which has key in current frame
                int streamFrameCurveCount = isStreamFrame ? streamedFrame.Curves.Count : 0;
                int denseFrameCurveCount  = (int)denseClip.CurveCount;
                // total amount of curves which has key in current frame
                int frameCurveCount = streamFrameCurveCount + denseFrameCurveCount + constantClip.Constants.Count;
                int streamOffset    = (int)streamedClip.CurveCount - streamFrameCurveCount;
                for (int curve = 0; curve < frameCurveCount;)
                {
                    int curveIndex;
                    IReadOnlyList <float> curvesValue;
                    int offset;

                    if (isStreamFrame && curve < streamedFrame.Curves.Count)
                    {
#warning TODO: read TCB and convert to in/out slope
                        for (int key = curve; key < Math.Min(curve + 5, streamedFrame.Curves.Count); key++)
                        {
                            frameCurvesValue[key] = streamedFrame.Curves[key].Value;
                        }
                        curveIndex  = streamedFrame.Curves[curve].Index;
                        curvesValue = frameCurvesValue;
                        offset      = 0;
                    }
                    else if (isDenseFrame && curve < streamFrameCurveCount + denseFrameCurveCount)
                    {
                        curveIndex  = curve + streamOffset;
                        curvesValue = denseClip.SampleArray;
                        offset      = streamFrameCurveCount - frame * denseFrameCurveCount;
                    }
                    else if (!isDenseFrame && curve < streamFrameCurveCount + denseFrameCurveCount)
                    {
                        curve += denseFrameCurveCount;

                        curveIndex  = curve + streamOffset;
                        curvesValue = constantClip.Constants;
                        offset      = streamFrameCurveCount + denseFrameCurveCount;
                        isAdd       = frame == 0 || frame == frameCount - 1;
                    }
                    else
                    {
                        curveIndex  = curve + streamOffset;
                        curvesValue = constantClip.Constants;
                        offset      = streamFrameCurveCount + denseFrameCurveCount;
                        isAdd       = frame == 0 || frame == frameCount - 1;
                    }

                    GenericBinding binding  = ClipBindingConstant.FindBinding(curveIndex);
                    uint           pathHash = binding.Path;

                    if (pathHash == 0)
                    {
                        curve++;
                        continue;
                    }
                    if (!tos.TryGetValue(pathHash, out string path))
                    {
                        path = "dummy" + pathHash;
                        //Logger.Log(LogType.Debug, LogCategory.Export, $"Can't find path '{binding.Path}' in TOS for {ToLogString()}");
                    }

                    switch (binding.BindingType)
                    {
                    case BindingType.Translation:
                        // HACK: TEMP:
                        if (curve + 3 > curvesValue.Count)
                        {
                            curve += 3;
                            break;
                        }

                        float x = curvesValue[curve++ - offset];
                        float y = curvesValue[curve++ - offset];
                        float z = curvesValue[curve++ - offset];
                        float w = 0;
                        if (isAdd)
                        {
                            Vector3f trans = new Vector3f(x, y, z);
                            if (!translations.TryGetValue(pathHash, out Vector3Curve transCurve))
                            {
                                transCurve             = new Vector3Curve(path);
                                translations[pathHash] = transCurve;
                            }

                            Vector3f defWeight = new Vector3f(1.0f / 3.0f);
                            KeyframeTpl <Vector3f> transKey = new KeyframeTpl <Vector3f>(time, trans, defWeight);
                            transCurve.Curve.Curve.Add(transKey);
                        }
                        break;

                    case BindingType.Rotation:
                        // HACK: TEMP:
                        if (curve + 4 > curvesValue.Count)
                        {
                            curve += 4;
                            break;
                        }

                        x = curvesValue[curve++ - offset];
                        y = curvesValue[curve++ - offset];
                        z = curvesValue[curve++ - offset];
                        w = curvesValue[curve++ - offset];
                        if (isAdd)
                        {
                            Quaternionf rot = new Quaternionf(x, y, z, w);
                            if (!rotations.TryGetValue(pathHash, out QuaternionCurve rotCurve))
                            {
                                rotCurve            = new QuaternionCurve(path);
                                rotations[pathHash] = rotCurve;
                            }

                            Quaternionf defWeight            = new Quaternionf(1.0f / 3.0f);
                            KeyframeTpl <Quaternionf> rotKey = new KeyframeTpl <Quaternionf>(time, rot, defWeight);
                            rotCurve.Curve.Curve.Add(rotKey);
                        }
                        break;

                    case BindingType.Scaling:
                        // HACK: TEMP:
                        if (curve + 3 > curvesValue.Count)
                        {
                            curve += 3;
                            break;
                        }

                        x = curvesValue[curve++ - offset];
                        y = curvesValue[curve++ - offset];
                        z = curvesValue[curve++ - offset];
                        if (isAdd)
                        {
                            Vector3f scale = new Vector3f(x, y, z);
                            if (!scales.TryGetValue(pathHash, out Vector3Curve scaleCurve))
                            {
                                scaleCurve       = new Vector3Curve(path);
                                scales[pathHash] = scaleCurve;
                            }

                            Vector3f defWeight = new Vector3f(1.0f / 3.0f);
                            KeyframeTpl <Vector3f> scaleKey = new KeyframeTpl <Vector3f>(time, scale, defWeight);
                            scaleCurve.Curve.Curve.Add(scaleKey);
                        }
                        break;

                    case BindingType.EulerRotation:
                        // HACK: TEMP:
                        if (curve + 3 > curvesValue.Count)
                        {
                            curve += 3;
                            break;
                        }

                        x = curvesValue[curve++ - offset];
                        y = curvesValue[curve++ - offset];
                        z = curvesValue[curve++ - offset];
                        if (isAdd)
                        {
                            Vector3f euler = new Vector3f(x, y, z);
                            if (!eulers.TryGetValue(pathHash, out Vector3Curve eulerCurve))
                            {
                                eulerCurve       = new Vector3Curve(path);
                                eulers[pathHash] = eulerCurve;
                            }

                            Vector3f defWeight = new Vector3f(1.0f / 3.0f);
                            KeyframeTpl <Vector3f> eulerKey = new KeyframeTpl <Vector3f>(time, euler, defWeight);
                            eulerCurve.Curve.Curve.Add(eulerKey);
                        }
                        break;

                    case BindingType.Floats:
                        float value = curvesValue[curve++ - offset];
                        if (isAdd)
                        {
                            Float @float = new Float(value);
                            if (!floats.TryGetValue(pathHash, out FloatCurve floatCurve))
                            {
                                floatCurve       = new FloatCurve(path);
                                floats[pathHash] = floatCurve;
                            }

                            Float defWeight = new Float(1.0f / 3.0f);
                            KeyframeTpl <Float> floatKey = new KeyframeTpl <Float>(time, @float, defWeight);
                            floatCurve.Curve.Curve.Add(floatKey);
                        }
                        break;

                    default:
#warning TODO: ???
                        curve++;
                        //throw new NotImplementedException(binding.BindingType.ToString());
                        break;
                    }
                }
            }

            node.Add("m_RotationCurves", rotations.Values.ExportYAML(container));
            node.Add("m_CompressedRotationCurves", YAMLSequenceNode.Empty);
            node.Add("m_EulerCurves", eulers.Values.ExportYAML(container));
            node.Add("m_PositionCurves", translations.Values.ExportYAML(container));
            node.Add("m_ScaleCurves", scales.Values.ExportYAML(container));
            node.Add("m_FloatCurves", floats.Values.ExportYAML(container));
        }