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); }
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); }
public AnimationCurveTpl(KeyframeTpl <T> keyframe1, KeyframeTpl <T> keyframe2) : this(false) { Curve = new KeyframeTpl <T> [2]; Curve[0] = keyframe1; Curve[1] = keyframe2; }
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); }
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); }
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]; } }
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)); }
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)); }
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]; } }
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)); }
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(); }
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)); }
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()); } }
public AnimationCurveTpl(KeyframeTpl <T> keyframe) : this(false) { Curve = new KeyframeTpl <T> [1]; Curve[0] = keyframe; }