tests/CitizenAnimationSetup/SmartPortGraphLayoutTests.cs
using HumanoidRetargeter.Target;
using Xunit;
namespace HumanoidRetargeter.Tests.Target;
public class SmartPortGraphLayoutTests
{
static string Graph => VmdlWriter.Kv3Header + """
{ _class = "CAnimationGraph"
m_nodeManager = { m_nodes = [
{ key = { m_id = 1 } value = { _class = "CSequenceAnimNode" m_nNodeID = { m_id = 1 }
m_vecPosition = [-725.25, 113.125] m_sequenceName = "idle" m_bone = "hand_r" } },
{ key = { m_id = 2 } value = { _class = "CRootAnimNode" m_nNodeID = { m_id = 2 }
m_vecPosition = [1500, -30.5]
m_inputConnection = { m_nodeID = { m_id = 1 } m_outputID = { m_id = 4294967295 } } } }
] m_nodeGroups = [{ name = "Weapon poses" position = [-800, -200] size = [2500, 600] }] }
}
""";
static KvObject Manager(string text) => (KvObject)((KvObject)Kv3.Parse(text).Root)["m_nodeManager"];
static KvObject[] Nodes(KvObject manager) => ((KvArray)manager["m_nodes"]).Items.Cast<KvObject>()
.Select(n => (KvObject)n["value"]).ToArray();
[Fact]
public void CopyAndBoneRebaseKeepNodePositionsAndGroups()
{
var copied = StockAnimationGraph.CopyForModel(SmartPortSetup.Rebase(Graph,
new Dictionary<string, string> { ["hand_r"] = "hand_R" }), "custom.vmdl");
var before = Manager(Graph);
var after = Manager(copied);
for (var i = 0; i < Nodes(before).Length; i++)
Assert.True(KvValue.DeepEquals(Nodes(before)[i]["m_vecPosition"], Nodes(after)[i]["m_vecPosition"]));
Assert.True(KvValue.DeepEquals(before["m_nodeGroups"], after["m_nodeGroups"]));
Assert.Equal("hand_R", Nodes(after)[0].GetString("m_bone"));
}
[Fact]
public void ExtendingKeepsExistingLayoutAndSeparatesAddedNodes()
{
var clips = Enumerable.Range(0, 12).Select(i => new SmartPortClip("clip_" + i, true, i % 2 == 0, false)).ToArray();
var output = SmartPortExtension.ExtendGraph(Graph, "custom.vmdl", clips, out _);
var before = Manager(Graph);
var after = Manager(output);
Assert.True(KvValue.DeepEquals(before["m_nodeGroups"], after["m_nodeGroups"]));
for (var i = 0; i < Nodes(before).Length; i++)
Assert.True(KvValue.DeepEquals(Nodes(before)[i]["m_vecPosition"], Nodes(after)[i]["m_vecPosition"]));
var positions = Nodes(after).Skip(2).Select(n => (KvArray)n["m_vecPosition"]).ToArray();
Assert.All(positions, p => Assert.True(((KvDouble)p.Items[0]).Value >= 2000));
Assert.Equal(positions.Length, positions.Select(p => (((KvDouble)p.Items[0]).Value, ((KvDouble)p.Items[1]).Value)).Distinct().Count());
}
}