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; } } }
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"); }
public StreamedFrame(BinaryReader reader) { time = reader.ReadSingle(); int numKeys = reader.ReadInt32(); keyList = new StreamedCurveKey[numKeys]; for (int i = 0; i < numKeys; i++) { keyList[i] = new StreamedCurveKey(reader); } }
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); } } } }
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); }
public float CalculateNextInSlope(float dx, StreamedCurveKey rhs) { //Stepped if (coeff[0] == 0f && coeff[1] == 0f && coeff[2] == 0f) { return(float.PositiveInfinity); } dx = Math.Max(dx, 0.0001f); var dy = rhs.value - value; var length = 1.0f / (dx * dx); var d1 = outSlope * dx; var d2 = dy + dy + dy - d1 - d1 - coeff[1] / length; return(d2 / dx); }
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"); }
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; } } }