Пример #1
0
        public static StreamedCurveKey CalculateStreamedFrame(AnimationCurveTpl <Float> curve, int lhsIndex, int rhsIndex, float timeOffset)
        {
            IReadOnlyList <KeyframeTpl <Float> > keyframes = curve.Curve;
            KeyframeTpl <Float> lhs = keyframes[lhsIndex];
            int curveKeyIndex       = lhsIndex;
            KeyframeTpl <Float> rhs = keyframes[rhsIndex];
            float frameTime         = lhs.Time + timeOffset;
            //TimeEnd = rhs.Time + timeOffset;
            float deltaTime = rhs.Time - lhs.Time;

            if (deltaTime < 0.00009999999747378752)
            {
                deltaTime = 0.000099999997f;
            }
            float deltaValue    = rhs.Value.Value - lhs.Value.Value;
            float inverseTime   = 1.0f / (deltaTime * deltaTime);
            float outTangent    = lhs.OutSlope.Value * deltaTime;
            float inTangent     = rhs.InSlope.Value * deltaTime;
            float curveKeyCoefX = (inTangent + outTangent - deltaValue - deltaValue) * inverseTime / deltaTime;
            float curveKeyCoefY = inverseTime * (deltaValue + deltaValue + deltaValue - outTangent - outTangent - inTangent);
            float curveKeyCoefZ = lhs.OutSlope.Value;
            float curveKeyValue = lhs.Value.Value;

            if (lhs.OutSlope.Value == float.PositiveInfinity || rhs.InSlope.Value == float.PositiveInfinity)
            {
                curveKeyCoefX = 0.0f;
                curveKeyCoefY = 0.0f;
                curveKeyCoefZ = 0.0f;
                curveKeyValue = lhs.Value.Value;
            }
            Vector3f         curveKeyCoef = new Vector3f(curveKeyCoefX, curveKeyCoefY, curveKeyCoefZ);
            StreamedCurveKey curveKey     = new StreamedCurveKey(curveKeyIndex, curveKeyValue, curveKeyCoef);

            return(curveKey);
        }
Пример #2
0
 public AnimationCurveTpl(T value1, T inSlope1, T outSlope1, T value2, T inSlope2, T outSlope2, T defaultWeight) :
     this(false)
 {
     Curve    = new KeyframeTpl <T> [2];
     Curve[0] = new KeyframeTpl <T>(0.0f, value1, inSlope1, outSlope1, defaultWeight);
     Curve[1] = new KeyframeTpl <T>(1.0f, value2, inSlope2, outSlope2, defaultWeight);
 }
Пример #3
0
 public AnimationCurveTpl(KeyframeTpl <T> keyframe1, KeyframeTpl <T> keyframe2) :
     this(false)
 {
     Curve    = new KeyframeTpl <T> [2];
     Curve[0] = keyframe1;
     Curve[1] = keyframe2;
 }
Пример #4
0
 public AnimationCurveTpl(T defaultValue, T defaultWeight) :
     this(false)
 {
     Curve    = new KeyframeTpl <T> [2];
     Curve[0] = new KeyframeTpl <T>(0.0f, defaultValue, defaultWeight);
     Curve[1] = new KeyframeTpl <T>(1.0f, defaultValue, defaultWeight);
 }
Пример #5
0
        public static KeyframeTpl <T> Convert <T>(IExportContainer container, ref KeyframeTpl <T> origin)
            where T : struct, IAsset
        {
            KeyframeTpl <T> instance = origin;

            instance.TangentMode = origin.GetTangentMode(container.Version).ToTangent(container.ExportVersion);
            return(instance);
        }
Пример #6
0
 public AnimationCurveTpl(IReadOnlyList <KeyframeTpl <T> > keyframes) :
     this(false)
 {
     Curve = new KeyframeTpl <T> [keyframes.Count];
     for (int i = 0; i < keyframes.Count; i++)
     {
         Curve[i] = keyframes[i];
     }
 }
Пример #7
0
        private AnimationCurveTpl <Float> GetReverbZoneMixCustomCurve(Version version)
        {
            if (IsReadReverbZoneMixCustomCurve(version))
            {
                return(ReverbZoneMixCustomCurve);
            }

            KeyframeTpl <Float> frame = new KeyframeTpl <Float>(0.0f, 1.0f, 1.0f / 3.0f);

            return(new AnimationCurveTpl <Float>(frame));
        }
Пример #8
0
        private AnimationCurveTpl <Float> GetSpreadCustomCurve(Version version)
        {
            if (IsReadRolloffCustomCurve(version))
            {
                return(SpreadCustomCurve);
            }

            KeyframeTpl <Float> frame = new KeyframeTpl <Float>(0.0f, 0.0f, 1.0f / 3.0f);

            return(new AnimationCurveTpl <Float>(frame));
        }
Пример #9
0
 public AnimationCurveTpl(IReadOnlyList <KeyframeTpl <T> > keyframes, CurveLoopTypes preInfinity, CurveLoopTypes postInfinity)
 {
     PreInfinity   = preInfinity;
     PostInfinity  = postInfinity;
     RotationOrder = RotationOrder.OrderZXY;
     Curve         = new KeyframeTpl <T> [keyframes.Count];
     for (int i = 0; i < keyframes.Count; i++)
     {
         Curve[i] = keyframes[i];
     }
 }
Пример #10
0
        private AnimationCurveTpl <Float> GetPanLevelCustomCurve(Version version)
        {
            if (HasRolloffCustomCurve(version))
            {
                return(PanLevelCustomCurve);
            }

            KeyframeTpl <Float> frame = new KeyframeTpl <Float>(0.0f, 0.0f, 1.0f / 3.0f);

            return(new AnimationCurveTpl <Float>(frame));
        }
Пример #11
0
        private void AddFloatKeyframe(FloatCurve curve, float time, float value)
        {
            if (!m_floats.TryGetValue(curve, out List <KeyframeTpl <Float> > floatCurve))
            {
                floatCurve = new List <KeyframeTpl <Float> >();
                m_floats.Add(curve, floatCurve);
            }

            KeyframeTpl <Float> floatKey = new KeyframeTpl <Float>(time, value, KeyframeTpl <Float> .DefaultFloatWeight);

            floatCurve.Add(floatKey);
        }
        public static void GenerateTypeTree(TypeTreeContext context, string name, TypeTreeGenerator generator)
        {
            context.AddNode(TypeTreeUtils.AnimationCurveName, name, 0, ToSerializedVersion(context.Version));
            context.BeginChildren();
            context.BeginArray(CurveName, TransferMetaFlags.AlignBytesFlag);
            KeyframeTpl <T> .GenerateTypeTree(context, TypeTreeUtils.DataName, generator);

            context.EndArray();
            context.AddInt32(PreInfinityName);
            context.AddInt32(PostInfinityName);
            if (HasRotationOrder(context.Version))
            {
                context.AddInt32(RotationOrderName);
            }
            context.EndChildren();
        }
Пример #13
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));
        }
Пример #14
0
        private void AddTransformCurve(float time, TransformType transType, IReadOnlyList <float> curveValues,
                                       IReadOnlyList <float> inSlopeValues, IReadOnlyList <float> outSlopeValues, int offset, string path)
        {
            switch (transType)
            {
            case TransformType.Translation:
            {
                Vector3Curve curve = new Vector3Curve(path);
                if (!m_translations.TryGetValue(curve, out List <KeyframeTpl <Vector3f> > transCurve))
                {
                    transCurve = new List <KeyframeTpl <Vector3f> >();
                    m_translations.Add(curve, transCurve);
                }

                float x = curveValues[offset + 0];
                float y = curveValues[offset + 1];
                float z = curveValues[offset + 2];

                float inX = inSlopeValues[0];
                float inY = inSlopeValues[1];
                float inZ = inSlopeValues[2];

                float outX = outSlopeValues[0];
                float outY = outSlopeValues[1];
                float outZ = outSlopeValues[2];

                Vector3f value    = new Vector3f(x, y, z);
                Vector3f inSlope  = new Vector3f(inX, inY, inZ);
                Vector3f outSlope = new Vector3f(outX, outY, outZ);
                KeyframeTpl <Vector3f> transKey = new KeyframeTpl <Vector3f>(time, value, inSlope, outSlope, KeyframeTpl <Vector3f> .DefaultVector3Weight);
                transCurve.Add(transKey);
            }
            break;

            case TransformType.Rotation:
            {
                QuaternionCurve curve = new QuaternionCurve(path);
                if (!m_rotations.TryGetValue(curve, out List <KeyframeTpl <Quaternionf> > rotCurve))
                {
                    rotCurve = new List <KeyframeTpl <Quaternionf> >();
                    m_rotations.Add(curve, rotCurve);
                }

                float x = curveValues[offset + 0];
                float y = curveValues[offset + 1];
                float z = curveValues[offset + 2];
                float w = curveValues[offset + 3];

                float inX = inSlopeValues[0];
                float inY = inSlopeValues[1];
                float inZ = inSlopeValues[2];
                float inW = inSlopeValues[3];

                float outX = outSlopeValues[0];
                float outY = outSlopeValues[1];
                float outZ = outSlopeValues[2];
                float outW = outSlopeValues[3];

                Quaternionf value                = new Quaternionf(x, y, z, w);
                Quaternionf inSlope              = new Quaternionf(inX, inY, inZ, inW);
                Quaternionf outSlope             = new Quaternionf(outX, outY, outZ, outW);
                KeyframeTpl <Quaternionf> rotKey = new KeyframeTpl <Quaternionf>(time, value, inSlope, outSlope, KeyframeTpl <Quaternionf> .DefaultQuaternionWeight);
                rotCurve.Add(rotKey);
            }
            break;

            case TransformType.Scaling:
            {
                Vector3Curve curve = new Vector3Curve(path);
                if (!m_scales.TryGetValue(curve, out List <KeyframeTpl <Vector3f> > scaleCurve))
                {
                    scaleCurve = new List <KeyframeTpl <Vector3f> >();
                    m_scales.Add(curve, scaleCurve);
                }

                float x = curveValues[offset + 0];
                float y = curveValues[offset + 1];
                float z = curveValues[offset + 2];

                float inX = inSlopeValues[0];
                float inY = inSlopeValues[1];
                float inZ = inSlopeValues[2];

                float outX = outSlopeValues[0];
                float outY = outSlopeValues[1];
                float outZ = outSlopeValues[2];

                Vector3f value    = new Vector3f(x, y, z);
                Vector3f inSlope  = new Vector3f(inX, inY, inZ);
                Vector3f outSlope = new Vector3f(outX, outY, outZ);
                KeyframeTpl <Vector3f> scaleKey = new KeyframeTpl <Vector3f>(time, value, inSlope, outSlope, KeyframeTpl <Vector3f> .DefaultVector3Weight);
                scaleCurve.Add(scaleKey);
            }
            break;

            case TransformType.EulerRotation:
            {
                Vector3Curve curve = new Vector3Curve(path);
                if (!m_eulers.TryGetValue(curve, out List <KeyframeTpl <Vector3f> > eulerCurve))
                {
                    eulerCurve = new List <KeyframeTpl <Vector3f> >();
                    m_eulers.Add(curve, eulerCurve);
                }

                float x = curveValues[offset + 0];
                float y = curveValues[offset + 1];
                float z = curveValues[offset + 2];

                float inX = inSlopeValues[0];
                float inY = inSlopeValues[1];
                float inZ = inSlopeValues[2];

                float outX = outSlopeValues[0];
                float outY = outSlopeValues[1];
                float outZ = outSlopeValues[2];

                Vector3f value    = new Vector3f(x, y, z);
                Vector3f inSlope  = new Vector3f(inX, inY, inZ);
                Vector3f outSlope = new Vector3f(outX, outY, outZ);
                KeyframeTpl <Vector3f> eulerKey = new KeyframeTpl <Vector3f>(time, value, inSlope, outSlope, KeyframeTpl <Vector3f> .DefaultVector3Weight);
                eulerCurve.Add(eulerKey);
            }
            break;

            default:
                throw new NotImplementedException(transType.ToString());
            }
        }
Пример #15
0
 public AnimationCurveTpl(KeyframeTpl <T> keyframe) :
     this(false)
 {
     Curve    = new KeyframeTpl <T> [1];
     Curve[0] = keyframe;
 }