Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public static void DisplayMultipleItems(UILabel label, Dictionary<RegularItem, I
Int32 columnIndex = 0;
IEnumerable<KeyValuePair<RegularItem, Int32>> enumerator = items;
if (items.Count == 1 && items.First().Value == 2)
enumerator = new List<KeyValuePair<RegularItem, Int32>>([new(items.First().Key, 1), new(items.First().Key, 1)]);
enumerator = new List<KeyValuePair<RegularItem, Int32>>() { new(items.First().Key, 1), new(items.First().Key, 1) };
foreach (KeyValuePair<RegularItem, Int32> kvp in enumerator)
{
if (kvp.Key == RegularItem.NoItem || kvp.Value <= 0)
Expand Down
97 changes: 96 additions & 1 deletion Assembly-CSharp/Memoria/Assets/3DModel/AnimationClipReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,17 @@ private static AnimationClip ReadAnimationClip_JSON(String filecontent, out Anim
List<Keyframe> keys_y = new List<Keyframe>();
List<Keyframe> keys_z = new List<Keyframe>();
List<Keyframe> keys_w = new List<Keyframe>();

List<Keyframe> keys_xIT = new List<Keyframe>();
List<Keyframe> keys_yIT = new List<Keyframe>();
List<Keyframe> keys_zIT = new List<Keyframe>();
List<Keyframe> keys_wIT = new List<Keyframe>();

List<Keyframe> keys_xOT = new List<Keyframe>();
List<Keyframe> keys_yOT = new List<Keyframe>();
List<Keyframe> keys_zOT = new List<Keyframe>();
List<Keyframe> keys_wOT = new List<Keyframe>();

ta.transformType = localType;
foreach (JSONNode frameNode in rotArray.Childs)
{
Expand Down Expand Up @@ -216,7 +227,48 @@ private static AnimationClip ReadAnimationClip_JSON(String filecontent, out Anim
fa.pos.w = keyNode.AsFloat;
keys_w.Add(new Keyframe(time, fa.pos.w));
}
// TODO: read inward/outward tangent (with keys "xInnerTangent", "xOuterTangent", etc.)

if (frameClass.Dict.TryGetValue("xInnerTangent", out keyNode))
{
fa.posInnerTangent.x = keyNode.AsFloat;
keys_xIT.Add(new Keyframe(time, fa.posInnerTangent.x));
}
if (frameClass.Dict.TryGetValue("yInnerTangent", out keyNode))
{
fa.posInnerTangent.y = keyNode.AsFloat;
keys_yIT.Add(new Keyframe(time, fa.posInnerTangent.y));
}
if (frameClass.Dict.TryGetValue("zInnerTangent", out keyNode))
{
fa.posInnerTangent.z = keyNode.AsFloat;
keys_zIT.Add(new Keyframe(time, fa.posInnerTangent.z));
}
if (frameClass.Dict.TryGetValue("wInnerTangent", out keyNode))
{
fa.posInnerTangent.w = keyNode.AsFloat;
keys_wIT.Add(new Keyframe(time, fa.posInnerTangent.w));
}

if (frameClass.Dict.TryGetValue("xOuterTangent", out keyNode))
{
fa.posOuterTangent.x = keyNode.AsFloat;
keys_xOT.Add(new Keyframe(time, fa.posOuterTangent.x));
}
if (frameClass.Dict.TryGetValue("yOuterTangent", out keyNode))
{
fa.posOuterTangent.y = keyNode.AsFloat;
keys_yOT.Add(new Keyframe(time, fa.posOuterTangent.y));
}
if (frameClass.Dict.TryGetValue("zOuterTangent", out keyNode))
{
fa.posOuterTangent.z = keyNode.AsFloat;
keys_zOT.Add(new Keyframe(time, fa.posOuterTangent.z));
}
if (frameClass.Dict.TryGetValue("wOuterTangent", out keyNode))
{
fa.posOuterTangent.w = keyNode.AsFloat;
keys_wOT.Add(new Keyframe(time, fa.posOuterTangent.w));
}
}
if (!keys_x.IsNullOrEmpty())
{
Expand All @@ -238,6 +290,49 @@ private static AnimationClip ReadAnimationClip_JSON(String filecontent, out Anim
animCurve = new AnimationCurve(keys_w.ToArray());
clip.SetCurve(boneName, typeof(Transform), localType + ".w", animCurve);
}

if (!keys_xIT.IsNullOrEmpty())
{
animCurve = new AnimationCurve(keys_xIT.ToArray());
clip.SetCurve(boneName, typeof(Transform), localType + ".xInnerTangent", animCurve);
}
if (!keys_yIT.IsNullOrEmpty())
{
animCurve = new AnimationCurve(keys_yIT.ToArray());
clip.SetCurve(boneName, typeof(Transform), localType + ".yInnerTangent", animCurve);
}
if (!keys_zIT.IsNullOrEmpty())
{
animCurve = new AnimationCurve(keys_zIT.ToArray());
clip.SetCurve(boneName, typeof(Transform), localType + ".zInnerTangent", animCurve);
}
if (!keys_wIT.IsNullOrEmpty())
{
animCurve = new AnimationCurve(keys_wIT.ToArray());
clip.SetCurve(boneName, typeof(Transform), localType + ".wInnerTangent", animCurve);
}

if (!keys_xOT.IsNullOrEmpty())
{
animCurve = new AnimationCurve(keys_xOT.ToArray());
clip.SetCurve(boneName, typeof(Transform), localType + ".xOuterTangent", animCurve);
}
if (!keys_yOT.IsNullOrEmpty())
{
animCurve = new AnimationCurve(keys_yOT.ToArray());
clip.SetCurve(boneName, typeof(Transform), localType + ".yOuterTangent", animCurve);
}
if (!keys_zOT.IsNullOrEmpty())
{
animCurve = new AnimationCurve(keys_zOT.ToArray());
clip.SetCurve(boneName, typeof(Transform), localType + ".zOuterTangent", animCurve);
}
if (!keys_wOT.IsNullOrEmpty())
{
animCurve = new AnimationCurve(keys_wOT.ToArray());
clip.SetCurve(boneName, typeof(Transform), localType + ".wOuterTangent", animCurve);
}

ta.frameAnimList.AddRange(faDict.Values);
ba.transformAnimList.Add(ta);
}
Expand Down
3 changes: 2 additions & 1 deletion Assembly-CSharp/Memoria/Assets/3DModel/FbxBinary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ static void Encrypt(byte[] a, byte[] b)

const string timePath1 = "FBXHeaderExtension";
const string timePath2 = "CreationTimeStamp";
static readonly Stack<string> timePath = new Stack<string>([timePath1, timePath2]);
static string[] timePaths = [ timePath1, timePath2 ];
static readonly Stack<string> timePath = new Stack<string>(timePaths);

// Gets a single timestamp component
static int GetTimestampVar(FbxNode timestamp, string element)
Expand Down
Loading