コード例 #1
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");
        }
コード例 #2
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);
        }
コード例 #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.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);
                    }
                }
            }
        }
コード例 #4
0
        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);
        }
コード例 #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.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");
 }
コード例 #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;
                }
            }
        }