private void ProcessDenses(Clip clip, AnimationClipBindingConstant bindings, IReadOnlyDictionary <uint, string> tos) { DenseClip dense = clip.DenseClip; int streamCount = clip.StreamedClip.CurveCount; float[] slopeValues = new float[4]; // no slopes - 0 values for (int frameIndex = 0; frameIndex < dense.FrameCount; frameIndex++) { float time = frameIndex / dense.SampleRate; int frameOffset = frameIndex * dense.CurveCount; for (int curveIndex = 0; curveIndex < dense.CurveCount;) { int index = streamCount + curveIndex; GenericBinding binding = bindings.FindBinding(index); string path = GetCurvePath(tos, binding.Path); int framePosition = frameOffset + curveIndex; if (binding.IsTransform) { AddTransformCurve(time, binding.TransformType, dense.SampleArray, slopeValues, slopeValues, framePosition, path); curveIndex += binding.TransformType.GetDimension(); } else if (binding.CustomType == BindingCustomType.None) { AddDefaultCurve(binding, path, time, dense.SampleArray[framePosition]); curveIndex++; } else { AddCustomCurve(bindings, binding, path, time, dense.SampleArray[framePosition]); curveIndex++; } } } }
private void ProcessConstant(Clip clip, AnimationClipBindingConstant bindings, IReadOnlyDictionary <uint, string> tos, float lastFrame) { ConstantClip constant = clip.ConstantClip; int streamCount = clip.StreamedClip.CurveCount; int denseCount = clip.DenseClip.CurveCount; float[] slopeValues = new float[4]; // no slopes - 0 values // only first and last frames float time = 0.0f; for (int i = 0; i < 2; i++, time += lastFrame) { for (int curveIndex = 0; curveIndex < constant.Constants.Count;) { int index = streamCount + denseCount + curveIndex; if (!GetGenericBinding(bindings, index, out GenericBinding binding)) { curveIndex++; continue; } string path = GetCurvePath(tos, binding.Path); AddComplexCurve(time, binding.BindingType, constant.Constants, slopeValues, slopeValues, curveIndex, path); curveIndex += binding.BindingType.GetDimension(); } } }
private void ProcessDenses(Clip clip, AnimationClipBindingConstant bindings, IReadOnlyDictionary <uint, string> tos) { DenseClip dense = clip.DenseClip; int streamCount = clip.StreamedClip.CurveCount; float[] slopeValues = new float[4]; // no slopes - 0 values for (int frameIndex = 0; frameIndex < dense.FrameCount; frameIndex++) { float time = frameIndex / dense.SampleRate; int frameOffset = frameIndex * dense.CurveCount; for (int curveIndex = 0; curveIndex < dense.CurveCount;) { int index = streamCount + curveIndex; if (!GetGenericBinding(bindings, index, out GenericBinding binding)) { curveIndex++; continue; } string path = GetCurvePath(tos, binding.Path); AddComplexCurve(time, binding.BindingType, dense.SampleArray, slopeValues, slopeValues, frameOffset + curveIndex, path); curveIndex += binding.BindingType.GetDimension(); } } }
private static bool GetGenericBinding(AnimationClipBindingConstant bindings, int index, out GenericBinding binding) { binding = bindings.FindBinding(index); if (binding.ClassID == ClassIDType.Transform) { return(true); } #warning TODO: humanoid return(false); }
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 void AddPPtrKeyframe(PPtrCurve curve, AnimationClipBindingConstant bindings, float time, int index) { if (!m_pptrs.TryGetValue(curve, out List <PPtrKeyframe> pptrCurve)) { pptrCurve = new List <PPtrKeyframe>(); m_pptrs.Add(curve, pptrCurve); AddPPtrKeyframe(curve, bindings, 0.0f, index - 1); } PPtr <Object> value = bindings.PptrCurveMapping[index]; PPtrKeyframe pptrKey = new PPtrKeyframe(time, value); pptrCurve.Add(pptrKey); }
public void Process(Clip clip, AnimationClipBindingConstant bindings, IReadOnlyDictionary <uint, string> tos) { IReadOnlyList <StreamedFrame> streamedFrames = clip.StreamedClip.GenerateFrames(m_version, m_platform, m_flags); float lastDenseFrame = clip.DenseClip.FrameCount / clip.DenseClip.SampleRate; float lastSampleFrame = streamedFrames.Count > 1 ? streamedFrames[streamedFrames.Count - 2].Time : 0.0f; float lastFrame = Math.Max(lastDenseFrame, lastSampleFrame); Clear(); ProcessStreams(streamedFrames, bindings, tos); ProcessDenses(clip, bindings, tos); if (Clip.IsReadConstantClip(m_version)) { ProcessConstant(clip, bindings, tos, lastFrame); } CreateCurves(); }
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; } } }
private void ProcessInner() { Clip clip = m_clip.MuscleClip.Clip; AnimationClipBindingConstant bindings = m_clip.ClipBindingConstant; IReadOnlyDictionary <uint, string> tos = m_clip.FindTOS(); IReadOnlyList <StreamedFrame> streamedFrames = clip.StreamedClip.GenerateFrames(Version, Platform, Flags); float lastDenseFrame = clip.DenseClip.FrameCount / clip.DenseClip.SampleRate; float lastSampleFrame = streamedFrames.Count > 1 ? streamedFrames[streamedFrames.Count - 2].Time : 0.0f; float lastFrame = Math.Max(lastDenseFrame, lastSampleFrame); ProcessStreams(streamedFrames, bindings, tos, clip.DenseClip.SampleRate); ProcessDenses(clip, bindings, tos); if (Clip.IsReadConstantClip(Version)) { ProcessConstant(clip, bindings, tos, lastFrame); } CreateCurves(); }
private void AddCustomCurve(AnimationClipBindingConstant bindings, GenericBinding binding, string path, float time, float value) { switch (binding.CustomType) { case BindingCustomType.AnimatorMuscle: AddAnimatorMuscleCurve(binding, path, time, value); break; default: string attribute = m_customCurveResolver.ToAttributeName(binding.CustomType, binding.Attribute, path); if (binding.IsPPtrCurve) { PPtrCurve curve = new PPtrCurve(path, attribute, binding.ClassID, binding.Script.CastTo <MonoScript>()); AddPPtrKeyframe(curve, bindings, time, (int)value); } else { FloatCurve curve = new FloatCurve(path, attribute, binding.ClassID, binding.Script.CastTo <MonoScript>()); AddFloatKeyframe(curve, time, value); } break; } }
private void ProcessConstant(Clip clip, AnimationClipBindingConstant bindings, IReadOnlyDictionary <uint, string> tos, float lastFrame) { ConstantClip constant = clip.ConstantClip; int streamCount = clip.StreamedClip.CurveCount; int denseCount = clip.DenseClip.CurveCount; float[] slopeValues = new float[4]; // no slopes - 0 values // only first and last frames float time = 0.0f; for (int i = 0; i < 2; i++, time += lastFrame) { for (int curveIndex = 0; curveIndex < constant.Constants.Count;) { int index = streamCount + denseCount + curveIndex; GenericBinding binding = bindings.FindBinding(index); string path = GetCurvePath(tos, binding.Path); if (binding.IsTransform) { AddTransformCurve(time, binding.TransformType, constant.Constants, slopeValues, slopeValues, curveIndex, path); curveIndex += binding.TransformType.GetDimension(); } else if (binding.CustomType == BindingCustomType.None) { AddDefaultCurve(binding, path, time, constant.Constants[curveIndex]); curveIndex++; } else { AddCustomCurve(bindings, binding, path, time, constant.Constants[curveIndex]); curveIndex++; } } } }