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"); }
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); } } } }
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); }
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"); }
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; } } }
public IReadOnlyList <StreamedFrame> GenerateFrames(Version version, Platform platform, TransferInstructionFlags flags) { List <StreamedFrame> frames = new List <StreamedFrame>(); byte[] memStreamBuffer = new byte[Data.Length * sizeof(uint)]; Buffer.BlockCopy(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); }
public IReadOnlyList <StreamedFrame> GenerateFrames(AssetLayout layout) { List <StreamedFrame> frames = new List <StreamedFrame>(); byte[] memStreamBuffer = new byte[Data.Length * sizeof(uint)]; Buffer.BlockCopy(Data, 0, memStreamBuffer, 0, memStreamBuffer.Length); using (MemoryStream stream = new MemoryStream(memStreamBuffer)) { using (AssetReader reader = new AssetReader(stream, EndianType.LittleEndian, layout)) { while (reader.BaseStream.Position < reader.BaseStream.Length) { StreamedFrame frame = new StreamedFrame(); frame.Read(reader); frames.Add(frame); } } } return(frames); }