BFRES : Add JSON/YAML converting with scene animations.
This commit is contained in:
parent
7936762ec9
commit
65aa3598a2
@ -85,12 +85,38 @@ namespace Bfres.Structs
|
||||
|
||||
public override void Export(string FileName)
|
||||
{
|
||||
SceneAnim.Export(FileName, ((BFRESGroupNode)Parent).GetResFile());
|
||||
string ext = Utils.GetExtension(FileName);
|
||||
|
||||
if (ext == ".bfscn")
|
||||
{
|
||||
SceneAnim.Export(FileName, ((BFRESGroupNode)Parent).GetResFile());
|
||||
}
|
||||
else if (ext == ".yaml")
|
||||
{
|
||||
System.IO.File.WriteAllText(FileName, YamlFscn.ToYaml(FileName, SceneAnim));
|
||||
}
|
||||
else if (ext == ".json")
|
||||
{
|
||||
System.IO.File.WriteAllText(FileName, YamlFscn.ToJson(FileName, SceneAnim));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void Replace(string FileName) {
|
||||
Replace(FileName, GetResFile(), GetResFileU());
|
||||
string ext = Utils.GetExtension(FileName);
|
||||
|
||||
if (ext == ".bfscn")
|
||||
{
|
||||
Replace(FileName, GetResFile(), GetResFileU());
|
||||
}
|
||||
else if (ext == ".yaml")
|
||||
{
|
||||
SceneAnim = YamlFscn.FromYaml(FileName);
|
||||
}
|
||||
else if (ext == ".json")
|
||||
{
|
||||
SceneAnim = YamlFscn.FromJson(FileName);
|
||||
}
|
||||
}
|
||||
|
||||
public void Replace(string FileName, ResFile resFileNX, ResU.ResFile resFileU)
|
||||
|
@ -1454,6 +1454,7 @@
|
||||
<Compile Include="YAML\YamlFmaa.cs" />
|
||||
<Compile Include="YAML\YamlFmat.cs" />
|
||||
<Compile Include="YAML\YamlFska.cs" />
|
||||
<Compile Include="YAML\YamlFscn.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
@ -141,6 +141,8 @@ namespace FirstPlugin
|
||||
|
||||
private void GetShapeTransform()
|
||||
{
|
||||
if (activeShape.boundingBoxes.Count == 0) return;
|
||||
|
||||
Vector3 translate = new Vector3(0);
|
||||
Vector3 scale = new Vector3(1);
|
||||
Vector4 rotate = new Vector4(0);
|
||||
|
@ -38,10 +38,10 @@ namespace FirstPlugin
|
||||
public static string FTXP = GetFilter(".bftxp", ".yaml", ".gif");
|
||||
public static string FMTV = GetFilter(".bfmvi");
|
||||
public static string FBNV = GetFilter(".bfbvi");
|
||||
public static string FSCN = GetFilter(".bfscn");
|
||||
public static string FSCN = GetFilter(".bfscn", ".yaml", ".json");
|
||||
public static string FSHA = GetFilter(".bfspa");
|
||||
|
||||
public static string CMDL = GetFilter(".dae");
|
||||
public static string CMDL = GetFilter(".dae", ".cmdl");
|
||||
|
||||
public static string NUTEXB = GetFilter(".dds",".png", ".bmp", ".tga", ".jpg", ".tiff", ".tif", ".gif");
|
||||
public static string XTX = GetFilter(".dds", ".png", ".bmp", ".tga", ".jpg", ".tiff", ".tif", ".gif");
|
||||
@ -61,6 +61,7 @@ namespace FirstPlugin
|
||||
else if (type == typeof(FTXP)) return FTXP;
|
||||
else if (type == typeof(FSHA)) return FSHA;
|
||||
else if (type == typeof(FTEX)) return FTEX;
|
||||
else if (type == typeof(FSCN)) return FSCN;
|
||||
else if (type == typeof(FSHU))
|
||||
{
|
||||
if (IsExporting)
|
||||
@ -137,6 +138,7 @@ namespace FirstPlugin
|
||||
case ".anim": filters.Add(ext, "Maya Animation"); break;
|
||||
case ".yaml": filters.Add(ext, "Yet Another Markup Language"); break;
|
||||
case ".gif": filters.Add(ext, "Graphics Interchange Format"); break;
|
||||
case ".cmdl": filters.Add(ext, "CTR Model"); break;
|
||||
default:
|
||||
filters.Add(ext, ""); break;
|
||||
}
|
||||
|
239
File_Format_Library/YAML/YamlFscn.cs
Normal file
239
File_Format_Library/YAML/YamlFscn.cs
Normal file
@ -0,0 +1,239 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SharpYaml;
|
||||
using SharpYaml.Events;
|
||||
using SharpYaml.Serialization;
|
||||
using SharpYaml.Serialization.Serializers;
|
||||
using Syroot.NintenTools.NSW.Bfres;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace FirstPlugin
|
||||
{
|
||||
public class YamlFscn
|
||||
{
|
||||
public static string ToJson(string Name, SceneAnim sceneAnim)
|
||||
{
|
||||
var config = new AnimConfig();
|
||||
config.ToYaml(sceneAnim);
|
||||
return JsonConvert.SerializeObject(config, Formatting.Indented);
|
||||
}
|
||||
|
||||
public static SceneAnim FromJson(string Name)
|
||||
{
|
||||
AnimConfig config = JsonConvert.DeserializeObject<AnimConfig>(
|
||||
System.IO.File.ReadAllText(Name));
|
||||
|
||||
return config.FromYaml();
|
||||
}
|
||||
|
||||
public static string ToYaml(string Name, SceneAnim sceneAnim)
|
||||
{
|
||||
var serializerSettings = new SerializerSettings()
|
||||
{
|
||||
// EmitTags = false
|
||||
};
|
||||
|
||||
serializerSettings.DefaultStyle = YamlStyle.Any;
|
||||
serializerSettings.ComparerForKeySorting = null;
|
||||
serializerSettings.RegisterTagMapping("AnimConfig", typeof(AnimConfig));
|
||||
|
||||
var config = new AnimConfig();
|
||||
config.ToYaml(sceneAnim);
|
||||
|
||||
var serializer = new Serializer(serializerSettings);
|
||||
string yaml = serializer.Serialize(config, typeof(AnimConfig));
|
||||
|
||||
return yaml;
|
||||
}
|
||||
|
||||
public static SceneAnim FromYaml(string Name)
|
||||
{
|
||||
var serializerSettings = new SerializerSettings()
|
||||
{
|
||||
// EmitTags = false
|
||||
};
|
||||
|
||||
serializerSettings.DefaultStyle = YamlStyle.Any;
|
||||
serializerSettings.ComparerForKeySorting = null;
|
||||
serializerSettings.RegisterTagMapping("AnimConfig", typeof(AnimConfig));
|
||||
|
||||
var serializer = new Serializer(serializerSettings);
|
||||
AnimConfig config = serializer.Deserialize<AnimConfig>(System.IO.File.ReadAllText(Name));
|
||||
|
||||
return config.FromYaml();
|
||||
}
|
||||
|
||||
public class AnimConfig
|
||||
{
|
||||
[JsonProperty(Order = 0)]
|
||||
public string Name { get; set; }
|
||||
[JsonProperty(Order = 1)]
|
||||
public string Path { get; set; }
|
||||
|
||||
[JsonProperty(Order = 2)]
|
||||
public List<CameraAnimConfig> CameraAnimations = new List<CameraAnimConfig>();
|
||||
|
||||
public void ToYaml(SceneAnim sceneAnim)
|
||||
{
|
||||
Name = sceneAnim.Name;
|
||||
Path = sceneAnim.Path;
|
||||
|
||||
foreach (var cameraAnim in sceneAnim.CameraAnims)
|
||||
CameraAnimations.Add(new CameraAnimConfig(cameraAnim));
|
||||
}
|
||||
|
||||
public SceneAnim FromYaml()
|
||||
{
|
||||
SceneAnim anim = new SceneAnim();
|
||||
anim.Name = Name;
|
||||
anim.Path = Path;
|
||||
foreach (var camera in CameraAnimations)
|
||||
{
|
||||
CameraAnim camAnim = new CameraAnim();
|
||||
camAnim.Name = camera.Name;
|
||||
camAnim.FrameCount = camera.FrameCount;
|
||||
camAnim.BaseData = camera.BaseData;
|
||||
if (camera.EulerZXY)
|
||||
camAnim.Flags |= CameraAnimFlags.EulerZXY;
|
||||
if (camera.Loop)
|
||||
camAnim.Flags |= CameraAnimFlags.Looping;
|
||||
if (camera.Perspective)
|
||||
camAnim.Flags |= CameraAnimFlags.Perspective;
|
||||
|
||||
foreach (var curve in camera.Curves) {
|
||||
AnimCurve animCurve = new AnimCurve();
|
||||
animCurve.AnimDataOffset = ConvertOffset(curve.Type);
|
||||
animCurve.Scale = 1;
|
||||
animCurve.CurveType = AnimCurveType.Linear;
|
||||
|
||||
int FrameCount = curve.KeyFrames.Count;
|
||||
animCurve.Frames = new float[FrameCount];
|
||||
animCurve.Keys = new float[FrameCount, 2];
|
||||
|
||||
var values = curve.KeyFrames.Values.ToList();
|
||||
for (int i = 0; i < curve.KeyFrames.Count; i++)
|
||||
{
|
||||
var KeyFrame = curve.KeyFrames.ElementAt(i);
|
||||
animCurve.Frames[i] = KeyFrame.Key;
|
||||
animCurve.Keys[i, 0] = KeyFrame.Value;
|
||||
|
||||
//Calculate delta
|
||||
float Delta = 0;
|
||||
if (i < values.Count - 1)
|
||||
Delta = values[i + 1] - values[i];
|
||||
|
||||
animCurve.Keys[i, 1] = Delta;
|
||||
}
|
||||
|
||||
animCurve.EndFrame = animCurve.Frames.Max();
|
||||
if (animCurve.Keys.Length > 1)
|
||||
animCurve.Delta = values[values.Count - 1] - values[0];
|
||||
|
||||
animCurve.KeyType = AnimCurveKeyType.Single;
|
||||
animCurve.FrameType = AnimCurveFrameType.Single;
|
||||
|
||||
|
||||
camAnim.Curves.Add(animCurve);
|
||||
}
|
||||
|
||||
anim.CameraAnims.Add(camAnim);
|
||||
anim.CameraAnimDict.Add(camAnim.Name);
|
||||
}
|
||||
|
||||
return anim;
|
||||
}
|
||||
|
||||
private static uint ConvertOffset(string type)
|
||||
{
|
||||
CameraOffsetType flags;
|
||||
bool isValid = Enum.TryParse(type, out flags);
|
||||
if (!isValid)
|
||||
throw new Exception($"Invalid camera curve type {type}!");
|
||||
|
||||
return (uint)flags;
|
||||
}
|
||||
}
|
||||
|
||||
public class CameraAnimConfig
|
||||
{
|
||||
[JsonProperty(Order = 0)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty(Order = 1)]
|
||||
public bool Loop { get; set; }
|
||||
|
||||
[JsonProperty(Order = 2)]
|
||||
public int FrameCount { get; set; }
|
||||
|
||||
[JsonProperty(Order = 3)]
|
||||
public bool EulerZXY { get; set; }
|
||||
|
||||
[JsonProperty(Order = 4)]
|
||||
public bool Perspective { get; set; }
|
||||
|
||||
[JsonProperty(Order = 5)]
|
||||
public CameraAnimData BaseData { get; set; }
|
||||
|
||||
[JsonProperty(Order = 6)]
|
||||
public List<CameraAnimCurve> Curves = new List<CameraAnimCurve>();
|
||||
|
||||
public CameraAnimConfig() { }
|
||||
|
||||
public CameraAnimConfig(CameraAnim camAnim)
|
||||
{
|
||||
Name = camAnim.Name;
|
||||
Loop = camAnim.Flags.HasFlag(CameraAnimFlags.Looping);
|
||||
EulerZXY = camAnim.Flags.HasFlag(CameraAnimFlags.EulerZXY);
|
||||
Perspective = camAnim.Flags.HasFlag(CameraAnimFlags.Perspective);
|
||||
|
||||
BaseData = camAnim.BaseData;
|
||||
|
||||
foreach (var curve in camAnim.Curves)
|
||||
Curves.Add(new CameraAnimCurve(curve));
|
||||
}
|
||||
}
|
||||
|
||||
public class CameraAnimCurve
|
||||
{
|
||||
[JsonProperty(Order = 0)]
|
||||
public string Type;
|
||||
|
||||
[JsonProperty(Order = 1)]
|
||||
public Dictionary<int, float> KeyFrames { get; set; }
|
||||
|
||||
public CameraAnimCurve() { }
|
||||
|
||||
public CameraAnimCurve(AnimCurve curve) {
|
||||
KeyFrames = new Dictionary<int, float>();
|
||||
|
||||
Type = ((CameraOffsetType)curve.AnimDataOffset).ToString();
|
||||
|
||||
for (int f = 0; f < curve.Frames.Length; f++)
|
||||
{
|
||||
int frame = (int)curve.Frames[f];
|
||||
float Value = curve.Offset + curve.Keys[f, 0] * curve.Scale;
|
||||
KeyFrames.Add(frame, Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Offsets to get data from "Values"
|
||||
public enum CameraOffsetType
|
||||
{
|
||||
ClipNear = 0,
|
||||
ClipFar = 4,
|
||||
AspectRatio = 8,
|
||||
FieldOFView = 12,
|
||||
PositionX = 16,
|
||||
PositionY = 20,
|
||||
PositionZ = 24,
|
||||
RotationX = 28,
|
||||
RotationY = 32,
|
||||
RotationZ = 36,
|
||||
Twist = 40,
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user