From 68fd3f6ba5b741acbd466deae4a9f37431d1be3d Mon Sep 17 00:00:00 2001 From: MeltyPlayer Date: Sat, 11 Nov 2023 18:28:31 -0600 Subject: [PATCH] Investigated what's going on with the Bnk keyframe values to try to figure out what might be going wrong. --- .../data/{lists => counters}/CounterArray.cs | 4 +- .../Fin/Fin/src/data/counters/CounterSet.cs | 20 +++++++ .../data/dictionaries/SortedSetDictionary.cs | 37 +++++++++++++ .../Visceral/Visceral/src/api/BnkReader.cs | 54 +++++++++++++++---- 4 files changed, 103 insertions(+), 12 deletions(-) rename FinModelUtility/Fin/Fin/src/data/{lists => counters}/CounterArray.cs (92%) create mode 100644 FinModelUtility/Fin/Fin/src/data/counters/CounterSet.cs create mode 100644 FinModelUtility/Fin/Fin/src/data/dictionaries/SortedSetDictionary.cs diff --git a/FinModelUtility/Fin/Fin/src/data/lists/CounterArray.cs b/FinModelUtility/Fin/Fin/src/data/counters/CounterArray.cs similarity index 92% rename from FinModelUtility/Fin/Fin/src/data/lists/CounterArray.cs rename to FinModelUtility/Fin/Fin/src/data/counters/CounterArray.cs index 8f2b73457..7f8cddb41 100644 --- a/FinModelUtility/Fin/Fin/src/data/lists/CounterArray.cs +++ b/FinModelUtility/Fin/Fin/src/data/counters/CounterArray.cs @@ -1,7 +1,9 @@ using System.Collections; using System.Collections.Generic; -namespace fin.data.lists { +using fin.data.lists; + +namespace fin.data.counters { public class CounterArray : IFinList { private readonly List impl_ = new(); diff --git a/FinModelUtility/Fin/Fin/src/data/counters/CounterSet.cs b/FinModelUtility/Fin/Fin/src/data/counters/CounterSet.cs new file mode 100644 index 000000000..b1a8793da --- /dev/null +++ b/FinModelUtility/Fin/Fin/src/data/counters/CounterSet.cs @@ -0,0 +1,20 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace fin.data.counters { + public class CounterSet { + private readonly Dictionary impl_ = new(); + + public int Increment(T key) { + if (this.impl_.TryGetValue(key, out var count)) { + count++; + } + + return this.impl_[key] = count; + } + + public void Clear() => this.impl_.Clear(); + public int Count => this.impl_.Count; + } +} \ No newline at end of file diff --git a/FinModelUtility/Fin/Fin/src/data/dictionaries/SortedSetDictionary.cs b/FinModelUtility/Fin/Fin/src/data/dictionaries/SortedSetDictionary.cs new file mode 100644 index 000000000..eac816365 --- /dev/null +++ b/FinModelUtility/Fin/Fin/src/data/dictionaries/SortedSetDictionary.cs @@ -0,0 +1,37 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace fin.data.dictionaries { + public class SortedSetDictionary + : IFinCollection<(TKey Key, SortedSet Value)> { + private readonly NullFriendlyDictionary> impl_ = + new(); + + public void Clear() => this.impl_.Clear(); + public void ClearSet(TKey key) => this.impl_.Remove(key); + + public int Count => this.impl_.Values.Select(list => list.Count).Sum(); + + public bool HasSet(TKey key) => this.impl_.ContainsKey(key); + + public void Add(TKey key, TValue value) { + SortedSet set; + if (!this.impl_.TryGetValue(key, out set)) { + this.impl_[key] = set = new SortedSet(); + } + + set.Add(value); + } + + public SortedSet this[TKey key] => this.impl_[key]; + + public bool TryGetSet(TKey key, out SortedSet? set) + => this.impl_.TryGetValue(key, out set); + + IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); + + public IEnumerator<(TKey Key, SortedSet Value)> GetEnumerator() + => this.impl_.GetEnumerator(); + } +} \ No newline at end of file diff --git a/FinModelUtility/Formats/Visceral/Visceral/src/api/BnkReader.cs b/FinModelUtility/Formats/Visceral/Visceral/src/api/BnkReader.cs index fff770dba..d806c8222 100644 --- a/FinModelUtility/Formats/Visceral/Visceral/src/api/BnkReader.cs +++ b/FinModelUtility/Formats/Visceral/Visceral/src/api/BnkReader.cs @@ -1,5 +1,7 @@ using System.Collections; +using fin.data.counters; +using fin.data.dictionaries; using fin.data.queues; using fin.io; using fin.math.floats; @@ -15,6 +17,16 @@ public enum MaybeBoneType { ANIMATED = 0x16, } + public enum AxisType : byte { + ROT_X, + ROT_Y, + ROT_Z, + UNKNOWN, + POS_X, + POS_Y, + POS_Z, + } + public enum KeyframeType : byte { ONLY_KEYFRAME = 0x0, KEYFRAME_AND_3_BYTES = 0x1, @@ -72,6 +84,10 @@ private void ReadIntoAnimation_(IBinaryReader bnkBr, var totalFrames = 1; var commands = new List(); + var countsOfAxesWithKeyframeType = + new CounterSet<(AxisType, KeyframeType)>(); + var valuesByAxesWithKeyframeType = + new SortedSetDictionary<(AxisType, KeyframeType), float>(); { var rootOffset = bnkBr.ReadUInt32(); @@ -132,25 +148,29 @@ private void ReadIntoAnimation_(IBinaryReader bnkBr, } var boneTracks = finAnimation.AddBoneTracks(bones[b]); - var rotations = boneTracks.UseQuaternionAxesRotationTrack(); + var rotations = boneTracks.UseEulerRadiansRotationTrack(); var positions = boneTracks.UseSeparatePositionAxesTrack(); for (var a = 0; a < 7; ++a) { + var axisType = (AxisType) a; + void SetKeyframe(int frame, float value) { totalFrames = Math.Max(totalFrames, frame); - switch (a) { - case 0: - case 1: - case 2: - case 3: { - rotations.Set(frame, a, value); + switch (axisType) { + case AxisType.ROT_X: + case AxisType.ROT_Y: + case AxisType.ROT_Z: { + rotations.Set(frame, axisType - AxisType.ROT_X, value); break; } - case 4: - case 5: - case 6: { - positions.Set(frame, a - 4, value); + case AxisType.POS_X: + case AxisType.POS_Y: + case AxisType.POS_Z: { + positions.Set(frame, axisType - AxisType.POS_X, value); + break; + } + case AxisType.UNKNOWN: { break; } default: throw new Exception(); @@ -166,6 +186,9 @@ void SetKeyframe(int frame, float value) { if (upper == standaloneCommandPrefix) { var keyframeType = (KeyframeType) lower; + countsOfAxesWithKeyframeType.Increment( + (axisType, keyframeType)); + bnkBr.Position -= 1; var frame = 0; @@ -175,6 +198,9 @@ void SetKeyframe(int frame, float value) { keyframeType, (int) standaloneCommandPrefix)) { SetKeyframe(frame++, keyframeValue); + valuesByAxesWithKeyframeType.Add( + (axisType, keyframeType), + keyframeValue); } } else if (lower == 5) { var keyframeCount = upper; @@ -188,6 +214,9 @@ void SetKeyframe(int frame, float value) { var keyframeType = (KeyframeType) (lengthAndKeyframeType & 0xF); + countsOfAxesWithKeyframeType.Increment( + (axisType, keyframeType)); + bnkBr.Position -= 1; var startingKeyframe = frame; @@ -197,6 +226,9 @@ void SetKeyframe(int frame, float value) { keyframeType, keyframeLength)) { SetKeyframe(frame++, keyframeValue); + valuesByAxesWithKeyframeType.Add( + (axisType, keyframeType), + keyframeValue); } frame = startingKeyframe + keyframeLength;