Skip to content

Commit

Permalink
Cleaned up Dat keyframes by aligning with how HSDRaw interpolates and…
Browse files Browse the repository at this point in the history
… set up animation names.
  • Loading branch information
MeltyPlayer committed Nov 5, 2023
1 parent 2136b12 commit 753a998
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 11 deletions.
5 changes: 5 additions & 0 deletions FinModelUtility/Fin/Fin/src/util/strings/StringUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,10 @@ public static string SubstringUpTo(this string str, string substr) {
var indexTo = str.IndexOf(substr);
return indexTo >= 0 ? str[..indexTo] : str;
}

public static string SubstringAfter(this string str, string substr) {
var indexTo = str.IndexOf(substr);
return indexTo >= 0 ? str[(indexTo + substr.Length)..] : str;
}
}
}
7 changes: 5 additions & 2 deletions FinModelUtility/Formats/Dat/Dat/src/api/DatModelImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using fin.model.io.importers;
using fin.util.enums;
using fin.util.hex;
using fin.util.strings;

using gx;

Expand Down Expand Up @@ -94,9 +95,11 @@ public unsafe IModel ImportModel(DatModelFileBundle modelFileBundle) {

var i = 0;
foreach (var animationDatSubfile in animationDat.Subfiles) {
foreach (var figaTree in animationDatSubfile
.GetRootNodesOfType<FigaTree>()) {
foreach (var (figaTree, figaTreeName) in animationDatSubfile
.GetRootNodesWithNamesOfType<FigaTree>()) {
var finAnimation = lazyFinAnimations[i++];
finAnimation.Name = figaTreeName.SubstringAfter("Share_ACTION_")
.SubstringUpTo("_figatree");
finAnimation.FrameCount = (int) figaTree.FrameCount;

foreach (var (jObj, trackNode) in primaryDatSubfile.JObjs.Zip(
Expand Down
44 changes: 38 additions & 6 deletions FinModelUtility/Formats/Dat/Dat/src/schema/DatSubfile.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using dat.schema.animation;
using System.Linq;

using dat.schema.animation;

using fin.data.queues;
using fin.io.bundles;
using fin.util.linq;

using schema.binary;
Expand All @@ -23,12 +26,36 @@ public class DatSubfile : IBinaryDeserializable {

public uint FileSize { get; set; }

public List<IDatNode> RootNodes { get; } = new();
public LinkedList<(IDatNode, string)> RootNodesWithNames { get; } = new();

public IEnumerable<IDatNode> RootNodes
=> this.RootNodesWithNames.Select(
rootNodeAndName => rootNodeAndName.Item1);

public IEnumerable<TNode> GetRootNodesOfType<TNode>()
where TNode : IDatNode
=> this.RootNodes.WhereIs<IDatNode, TNode>();

public IEnumerable<(TNode, string)> GetRootNodesWithNamesOfType<TNode>()
where TNode : IDatNode
=> this.RootNodesWithNames
.SelectWhere<(IDatNode, string), (TNode, string)>(IsOfType_);

private static bool IsOfType_<TNode>(
(IDatNode, string) nodeWithName,
out (TNode, string) outNodeWithName)
where TNode : IDatNode {
var (node, name) = nodeWithName;
if (node is TNode datNode) {
outNodeWithName = (datNode, name);
return true;
}

outNodeWithName = default;
return false;
}


public IEnumerable<JObj> RootJObjs => this.GetRootNodesOfType<JObj>();

private readonly Dictionary<uint, JObj> jObjByOffset_ = new();
Expand Down Expand Up @@ -97,28 +124,33 @@ private void ReadRootNodeObjects_(IBinaryReader br) {

var jObjQueue = new FinTuple2Queue<uint, JObj>();

this.RootNodes.Clear();
this.RootNodesWithNames.Clear();
foreach (var rootNode in this.rootNodes_) {
var rootNodeOffset = rootNode.Data.DataOffset;
br.Position = rootNodeOffset;

IDatNode? node = null;
switch (rootNode.Type) {
case RootNodeType.JOBJ: {
var jObj = br.ReadNew<JObj>();
this.RootNodes.Add(jObj);
node = jObj;

jObjQueue.Enqueue((rootNodeOffset, jObj));
break;
}
case RootNodeType.MATANIM_JOINT: {
this.RootNodes.Add(br.ReadNew<MatAnimJoint>());
node = br.ReadNew<MatAnimJoint>();
break;
}
case RootNodeType.FIGATREE: {
this.RootNodes.Add(br.ReadNew<FigaTree>());
node = br.ReadNew<FigaTree>();
break;
}
}

if (node != null) {
this.RootNodesWithNames.AddLast((node, rootNode.Name));
}
}

br.PopLocalSpace();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public static class DatKeyframesUtil {
/// <summary>
/// Shamelessly stolen from:
/// https://github.com/Ploaj/HSDLib/blob/93a906444f34951c6eed4d8c6172bba43d4ada98/HSDRaw/Tools/FOBJ_Decoder.cs#L22
/// https://github.com/Ploaj/HSDLib/blob/93a906444f34951c6eed4d8c6172bba43d4ada98/HSDRaw/Tools/FOBJ_Player.cs#L162
/// </summary>
public static void ReadKeyframes(
IBinaryReader br,
Expand Down Expand Up @@ -41,21 +42,30 @@ public static void ReadKeyframes(
break;
}

var previousInterpolationType = GxInterpolationType.Constant;
float value = 0;
float tangent = 0;
int time = 0;

for (int i = 0; i < numOfKey; i++) {
float value = 0;
float? tangent = null;
int time = 1;
switch (interpolation) {
case GxInterpolationType.Constant:
value = ParseFloat_(sbr, valueFormat, valueScale);
if (previousInterpolationType != GxInterpolationType.Slp) {
tangent = 0;
}
time = ReadPacked_(sbr);
break;
case GxInterpolationType.Linear:
value = ParseFloat_(sbr, valueFormat, valueScale);
if (previousInterpolationType != GxInterpolationType.Slp) {
tangent = 0;
}
time = ReadPacked_(sbr);
break;
case GxInterpolationType.Spl0:
value = ParseFloat_(sbr, valueFormat, valueScale);
tangent = 0;
time = ReadPacked_(sbr);
break;
case GxInterpolationType.Spl:
Expand All @@ -65,9 +75,11 @@ public static void ReadKeyframes(
break;
case GxInterpolationType.Slp:
tangent = ParseFloat_(sbr, tangentFormat, tangentScale);
time = 0;
break;
case GxInterpolationType.Key:
value = ParseFloat_(sbr, valueFormat, valueScale);
time = 0;
break;
default:
throw new Exception("Unknown Interpolation Type " +
Expand All @@ -78,6 +90,8 @@ public static void ReadKeyframes(
keyframes.AddLast((frame, value, tangent));
}
frame += time;

previousInterpolationType = interpolation;
}
}
});
Expand Down

0 comments on commit 753a998

Please sign in to comment.