Пример #1
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));
        }
Пример #2
0
 public Quaternionf(Quaternionf copy) :
     this(copy.X, copy.Y, copy.Z, copy.W)
 {
 }