/// <summary> /// /// </summary> /// <param name="node"></param> /// <param name="type"></param> /// <param name="keys"></param> /// <param name="defaultValue"></param> private void CreateTrack(FigaTreeNode node, JointTrackType type, List <FOBJKey> keys, float defaultValue) { // empty track if (keys.Count == 0) { return; } // skip constant tracks if (keys.Count == 1 && Math.Abs(keys[0].Value - defaultValue) < 0.001f) { return; } // skip constant tracks if (keys.Count == 2 && Math.Abs(keys[0].Value - defaultValue) < 0.001f) { return; } HSD_FOBJ fobj = new HSD_FOBJ(); fobj.SetKeys(keys, type); HSD_Track track = new HSD_Track(); track.FromFOBJ(fobj); node.Tracks.Add(track); }
/// <summary> /// /// </summary> /// <returns></returns> public HSD_FigaTree ToFigaTree() { List <FigaTreeNode> nodes = new List <FigaTreeNode>(); foreach (var v in jobjToTrack) { FigaTreeNode node = new FigaTreeNode(); CreateTrack(node, JointTrackType.HSD_A_J_TRAX, v.Value.X.Keys, v.Key.TX); CreateTrack(node, JointTrackType.HSD_A_J_TRAY, v.Value.Y.Keys, v.Key.TY); CreateTrack(node, JointTrackType.HSD_A_J_TRAZ, v.Value.Z.Keys, v.Key.TZ); CreateTrack(node, JointTrackType.HSD_A_J_ROTX, v.Value.RX.Keys, v.Key.RX); CreateTrack(node, JointTrackType.HSD_A_J_ROTY, v.Value.RY.Keys, v.Key.RY); CreateTrack(node, JointTrackType.HSD_A_J_ROTZ, v.Value.RZ.Keys, v.Key.RZ); CreateTrack(node, JointTrackType.HSD_A_J_SCAX, v.Value.SX.Keys, v.Key.SX); CreateTrack(node, JointTrackType.HSD_A_J_SCAY, v.Value.SY.Keys, v.Key.SY); CreateTrack(node, JointTrackType.HSD_A_J_SCAZ, v.Value.SZ.Keys, v.Key.SZ); nodes.Add(node); } HSD_FigaTree tree = new HSD_FigaTree(); tree.Type = 1; tree.FrameCount = FrameCount; tree.Nodes = nodes; return(tree); }
/// <summary> /// /// </summary> /// <param name="figatree"></param> /// <param name="jobjFrom"></param> /// <param name="jobjTo"></param> /// <param name="bmFrom"></param> /// <param name="bmTo"></param> /// <returns></returns> public static HSD_FigaTree Port(HSD_FigaTree figatree, HSD_JOBJ jobjFrom, HSD_JOBJ jobjTo, BoneMap bmFrom, BoneMap bmTo) { AnimationPlayer sourceAnim = new AnimationPlayer(jobjFrom, figatree); AnimationPlayer targetAnim = new AnimationPlayer(jobjTo, figatree.FrameCount); int jobjIndex = 0; foreach (var to in jobjTo.BreathFirstList) { var name = bmTo.GetName(jobjIndex); var index = bmFrom.GetIndex(name); FigaTreeNode node = new FigaTreeNode(); if (index != -1) { var jfrom = jobjFrom.BreathFirstList[index]; if (targetAnim.PortBoneTo(to, sourceAnim, jfrom)) { Debug.WriteLine($"Retargeting {name}"); } } jobjIndex++; } return(targetAnim.ToFigaTree());; }
/// <summary> /// /// </summary> /// <param name="nodes"></param> /// <param name="frameCount"></param> /// <returns></returns> public HSD_FigaTree ToFigaTree(float error = 0.0001f) { HSD_FigaTree tree = new HSD_FigaTree(); tree.FrameCount = FrameCount; tree.Type = 1; tree.Nodes = Nodes.Select(e => { var fn = new FigaTreeNode(); foreach (var t in e.Tracks) { HSD_Track track = new HSD_Track(); HSD_FOBJ fobj = t.ToFobj(error); track.FromFOBJ(fobj); fn.Tracks.Add(track); } return(fn); }).ToList(); return(tree); }
/// <summary> /// /// </summary> /// <param name="nodes"></param> /// <param name="frameCount"></param> /// <returns></returns> public HSD_FigaTree ToFigaTree() { HSD_FigaTree tree = new HSD_FigaTree(); tree.FrameCount = FrameCount; tree.Type = 1; tree.Nodes = Nodes.Select(e => { var fn = new FigaTreeNode(); foreach (var t in e.Tracks) { HSD_Track track = new HSD_Track(); HSD_FOBJ fobj = new HSD_FOBJ(); fobj.SetKeys(t.Keys, t.JointTrackType); track.FOBJ = fobj; fn.Tracks.Add(track); } return(fn); }).ToList(); return(tree); }
public static HSD_FigaTree RemapFigatree(RemapSettings settings, HSD_FigaTree from, int newBoneCount, JointMap mapFrom, JointMap mapTo) { var sourceNodes = from.Nodes; var targetNodes = new List <FigaTreeNode>(); for (int i = 0; i < newBoneCount; i++) { FigaTreeNode node = new FigaTreeNode(); targetNodes.Add(node); var remapIndex = mapFrom.IndexOf(mapTo[i]); if (remapIndex != -1) { // port tracks node.Tracks.AddRange(sourceNodes[remapIndex].Tracks); if (settings.IgnoreTranslation) { node.Tracks.RemoveAll( e => e.JointTrackType == JointTrackType.HSD_A_J_TRAX || e.JointTrackType == JointTrackType.HSD_A_J_TRAY || e.JointTrackType == JointTrackType.HSD_A_J_TRAZ); } } } var newft = new HSD_FigaTree(); newft.Type = 1; newft.FrameCount = from.FrameCount; newft.Nodes = targetNodes; return(newft); }
/// <summary> /// /// </summary> /// <param name="FileName"></param> /// <param name="animation"></param> /// <param name="skeleton"></param> private void ExportFigaTree(string FileName, SBAnimation animation, SBSkeleton skeleton) { HSDRawFile file = new HSDRawFile(); HSDRootNode root = new HSDRootNode(); if (HSDSettings.RootName == "" || HSDSettings.RootName == null) { HSDSettings.RootName = System.IO.Path.GetFileNameWithoutExtension(FileName); } if (HSDSettings.RootName == "" || HSDSettings.RootName == null) { HSDSettings.RootName = animation.Name; } root.Name = HSDSettings.RootName; if (root.Name == null || !root.Name.EndsWith("_figatree")) { System.Windows.Forms.MessageBox.Show($"Warning, the root name does not end with \"_figatree\"\n{root.Name}"); } file.Roots.Add(root); var nodes = new List <FigaTreeNode>(); int boneIndex = -1; foreach (var skelnode in skeleton.Bones) { FigaTreeNode animNode = new FigaTreeNode(); nodes.Add(animNode); boneIndex++; // skip trans n and rotn tracks if (boneIndex == 0) { continue; } var node = animation.TransformNodes.Find(e => e.Name == skelnode.Name); if (node == null) { continue; } foreach (var track in node.Tracks) { HSD_Track animTrack = new HSD_Track(); animTrack.FOBJ = EncodeFOBJ(track); animTrack.DataLength = (short)animTrack.FOBJ.Buffer.Length; animNode.Tracks.Add(animTrack); } } HSD_FigaTree tree = new HSD_FigaTree(); tree.FrameCount = animation.FrameCount; tree.Type = 1; tree.Nodes = nodes; root.Data = tree; file.Save(FileName); }