Skip to content

Commit

Permalink
Add support for importing/exporting bone order
Browse files Browse the repository at this point in the history
  • Loading branch information
Norbyte committed Aug 12, 2023
1 parent 9c88b30 commit e5d90a3
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 12 deletions.
2 changes: 1 addition & 1 deletion LSLib/Granny/Model/ColladaExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ private skin ExportSkin(Mesh mesh, List<Bone> bones, Dictionary<string, Bone> na

private node ExportBone(Skeleton skeleton, string name, int index, Bone bone)
{
var node = bone.MakeCollada(name);
var node = bone.MakeCollada(Xml);
var children = new List<node>();
for (int i = 0; i < skeleton.Bones.Count; i++)
{
Expand Down
10 changes: 7 additions & 3 deletions LSLib/Granny/Model/ColladaImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,12 @@ private void FindRootBones(List<node> parents, node node, List<RootBoneInfo> roo
{
if (node.type == NodeType.JOINT)
{
rootBones.Add(new RootBoneInfo
var root = new RootBoneInfo
{
Bone = node,
Parents = parents.Select(a => a).ToList()
});
};
rootBones.Add(root);
}
else if (node.type == NodeType.NODE)
{
Expand All @@ -279,7 +280,7 @@ private void FindRootBones(List<node> parents, node node, List<RootBoneInfo> roo
}
}

private technique FindExporterExtraData(extra[] extras)
public static technique FindExporterExtraData(extra[] extras)
{
if (extras != null)
{
Expand Down Expand Up @@ -942,6 +943,7 @@ public Root Import(string inputPath)

var collGeometries = new List<geometry>();
var collSkins = new List<skin>();
var collNodes = new List<node>();
var collAnimations = new List<animation>();
var rootBones = new List<RootBoneInfo>();

Expand Down Expand Up @@ -979,6 +981,7 @@ public Root Import(string inputPath)
{
foreach (var node in scene.node)
{
collNodes.Add(node);
FindRootBones(new List<node>(), node, rootBones);
}
}
Expand Down Expand Up @@ -1022,6 +1025,7 @@ public Root Import(string inputPath)
var skeleton = Skeleton.FromCollada(bone.Bone);
var rootTransform = NodeHelpers.GetTransformHierarchy(bone.Parents);
skeleton.TransformRoots(rootTransform.Inverted());
skeleton.ReorderBones();
root.Skeletons.Add(skeleton);
}

Expand Down
7 changes: 1 addition & 6 deletions LSLib/Granny/Model/Root.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,7 @@ public void PostLoad(UInt32 tag)

foreach (var skeleton in Skeletons ?? Enumerable.Empty<Skeleton>())
{
var hasSkinnedMeshes = Models.Any((model) => model.Skeleton == skeleton);
if (!hasSkinnedMeshes || skeleton.Bones.Count == 1)
{
skeleton.IsDummy = true;
Utils.Info(String.Format("Skeleton '{0}' marked as dummy", skeleton.Name));
}
skeleton.PostLoad(this);
}

// Upgrade legacy animation formats
Expand Down
92 changes: 91 additions & 1 deletion LSLib/Granny/Model/Skeleton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
using System.Linq;
using OpenTK;
using LSLib.Granny.GR2;
using System.Xml;
using LSLib.LS.Story;
using System.Reflection;

namespace LSLib.Granny.Model
{
Expand All @@ -29,6 +32,8 @@ public class Bone
public Matrix4 OriginalTransform;
[Serialization(Kind = SerializationKind.None)]
public Matrix4 WorldTransform;
[Serialization(Kind = SerializationKind.None)]
public int ExportIndex = -1;

public bool IsRoot { get { return ParentIndex == -1; } }

Expand All @@ -54,6 +59,27 @@ public void UpdateWorldTransforms(List<Bone> bones)
};
}

private void ImportLSLibProfile(node node)
{
var extraData = ColladaImporter.FindExporterExtraData(node.extra);
if (extraData != null && extraData.Any != null)
{
foreach (var setting in extraData.Any)
{
switch (setting.LocalName)
{
case "BoneIndex":
ExportIndex = Int32.Parse(setting.InnerText.Trim());
break;

default:
Utils.Warn($"Unrecognized LSLib bone attribute: {setting.LocalName}");
break;
}
}
}
}

public static Bone FromCollada(node bone, int parentIndex, List<Bone> bones, Dictionary<string, Bone> boneSIDs, Dictionary<string, Bone> boneIDs)
{
var transMat = ColladaHelpers.TransformFromNode(bone);
Expand All @@ -73,6 +99,7 @@ public static Bone FromCollada(node bone, int parentIndex, List<Bone> bones, Dic
colladaBone.OriginalTransform = transMat.transform;
colladaBone.Transform = Transform.FromMatrix4(transMat.transform);
colladaBone.UpdateWorldTransforms(bones);
colladaBone.ImportLSLibProfile(bone);

if (bone.node1 != null)
{
Expand All @@ -87,8 +114,22 @@ public static Bone FromCollada(node bone, int parentIndex, List<Bone> bones, Dic

return colladaBone;
}
private technique ExportLSLibProfile(XmlDocument Xml)
{
var profile = new technique()
{
profile = "LSTools"
};

public node MakeCollada(string parentName)
var props = new List<XmlElement>();
var prop = Xml.CreateElement("BoneIndex");
prop.InnerText = ExportIndex.ToString();
props.Add(prop);
profile.Any = props.ToArray();
return profile;
}

public node MakeCollada(XmlDocument Xml)
{
var node = new node();
node.id = "Bone_" + Name.Replace(' ', '_');
Expand All @@ -114,6 +155,18 @@ public node MakeCollada(string parentName)

node.Items = transforms.ToArray();
node.ItemsElementName = transformTypes.ToArray();

node.extra = new extra[]
{
new extra
{
technique = new technique[]
{
ExportLSLibProfile(Xml)
}
}
};

return node;
}
}
Expand Down Expand Up @@ -191,5 +244,42 @@ public void UpdateWorldTransforms()
bone.UpdateWorldTransforms(Bones);
}
}

public void ReorderBones()
{
// Reorder bones based on their ExportOrder
if (Bones.Any(m => m.ExportIndex > -1))
{
var newBones = Bones.ToList();
newBones.Sort((a, b) => a.ExportIndex - b.ExportIndex);

// Fix up parent indices
foreach (var bone in newBones)
{
if (bone.ParentIndex != -1)
{
var parent = Bones[bone.ParentIndex];
bone.ParentIndex = newBones.IndexOf(parent);
}
}

Bones = newBones;
}
}

public void PostLoad(Root root)
{
var hasSkinnedMeshes = root.Models.Any((model) => model.Skeleton == this);
if (!hasSkinnedMeshes || Bones.Count == 1)
{
IsDummy = true;
Utils.Info(String.Format("Skeleton '{0}' marked as dummy", this.Name));
}

for (var i = 0; i < Bones.Count; i++)
{
Bones[i].ExportIndex = i;
}
}
}
}
2 changes: 1 addition & 1 deletion LSLib/LS/Common.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public static class Common
public const int PatchVersion = 3;

// Version of LSTools profile data in generated DAE files
public const int ColladaMetadataVersion = 2;
public const int ColladaMetadataVersion = 3;

/// <summary>
/// Returns the version number of the LSLib library
Expand Down

0 comments on commit e5d90a3

Please sign in to comment.