diff --git a/.vs/Switch_Toolbox/v15/.suo b/.vs/Switch_Toolbox/v15/.suo index 7c68f003..6d910341 100644 Binary files a/.vs/Switch_Toolbox/v15/.suo and b/.vs/Switch_Toolbox/v15/.suo differ diff --git a/.vs/Switch_Toolbox/v15/Browse.VC.db b/.vs/Switch_Toolbox/v15/Browse.VC.db index 4b32e290..dc8fbdc7 100644 Binary files a/.vs/Switch_Toolbox/v15/Browse.VC.db and b/.vs/Switch_Toolbox/v15/Browse.VC.db differ diff --git a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide index 2e25ff64..b95dbd35 100644 Binary files a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide and b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide differ diff --git a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-shm b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-shm index b1203dc6..a3c52954 100644 Binary files a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-shm and b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-shm differ diff --git a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-wal b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-wal index 6baca446..5bfab2ff 100644 Binary files a/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-wal and b/.vs/Switch_Toolbox/v15/Server/sqlite3/storage.ide-wal differ diff --git a/BrawlboxHelper/BrawlboxHelper.cs b/BrawlboxHelper/BrawlboxHelper.cs new file mode 100644 index 00000000..38b77dd9 --- /dev/null +++ b/BrawlboxHelper/BrawlboxHelper.cs @@ -0,0 +1,552 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Syroot.NintenTools.NSW.Bfres; +using ResU = Syroot.NintenTools.Bfres; +using System.Windows; +using Syroot.Maths; +using BrawlLib.SSBB.ResourceNodes; + +namespace BrawlboxHelper +{ + public class FSHUConverter + { + public static ResU.ShaderParamAnim Clr02Fshu(string FileName) + { + CLR0Node clr0 = NodeFactory.FromFile(null, FileName) as CLR0Node; + + ResU.ShaderParamAnim fshu = new ResU.ShaderParamAnim(); + fshu.FrameCount = clr0.FrameCount; + fshu.Name = clr0.Name; + fshu.Path = clr0.OriginalPath; + fshu.UserData = new ResU.ResDict(); + + //Set flags + if (clr0.Loop) + fshu.Flags |= ResU.ShaderParamAnimFlags.Looping; + + //Set mat anims and then calculate data after + foreach (var entry in clr0.Children) + fshu.ShaderParamMatAnims.Add(Clr0Entry2ShaderMatAnim(clr0, (CLR0MaterialNode)entry)); + + fshu.BakedSize = CalculateBakeSize(fshu); + fshu.BindIndices = SetIndices(fshu); + + return fshu; + } + + public static ResU.ShaderParamMatAnim Clr0Entry2ShaderMatAnim(CLR0Node clr0, CLR0MaterialNode clrMaterial) + { + ResU.ShaderParamMatAnim matAnim = new ResU.ShaderParamMatAnim(); + matAnim.Name = clrMaterial.Name; + foreach (var entry in clrMaterial.Children) + { + ushort curveIndex = 0; + ushort constantIndex = 0; + + CLR0MaterialEntryNode ParamEntry = (CLR0MaterialEntryNode)entry; + + //Add constants for RGBA if constant + if (ParamEntry.Constant) + { + //Red + matAnim.Constants.Add(new ResU.AnimConstant() + { + AnimDataOffset = 0, + Value = (float)ParamEntry.Colors[0].R / 255f, + }); + + //Green + matAnim.Constants.Add(new ResU.AnimConstant() + { + AnimDataOffset = 4, + Value = (float)ParamEntry.Colors[0].G / 255f, + }); + + //Blue + matAnim.Constants.Add(new ResU.AnimConstant() + { + AnimDataOffset = 8, + Value = (float)ParamEntry.Colors[0].B / 255f, + }); + + //Alpha + matAnim.Constants.Add(new ResU.AnimConstant() + { + AnimDataOffset = 12, + Value = (float)ParamEntry.Colors[0].A / 255f, + }); + } + + var RedCurve = GenerateCurve(0, clr0, ParamEntry); + var GreenCurve = GenerateCurve(4, clr0, ParamEntry); + var BlueCurve = GenerateCurve(8, clr0, ParamEntry); + var AlphaCurve = GenerateCurve(12, clr0, ParamEntry); + + if (RedCurve != null) + matAnim.Curves.Add(RedCurve); + if (GreenCurve != null) + matAnim.Curves.Add(GreenCurve); + if (BlueCurve != null) + matAnim.Curves.Add(BlueCurve); + if (AlphaCurve != null) + matAnim.Curves.Add(AlphaCurve); + + matAnim.ParamAnimInfos.Add(new ResU.ParamAnimInfo() + { + Name = entry.Name, + BeginCurve = matAnim.Curves.Count > 0 ? curveIndex : ushort.MaxValue, + FloatCurveCount = (ushort)matAnim.Curves.Count, + SubBindIndex = ushort.MaxValue, + ConstantCount = (ushort)matAnim.Constants.Count, + BeginConstant = matAnim.Constants.Count > 0 ? constantIndex : ushort.MaxValue, + }); + + constantIndex += (ushort)matAnim.Constants.Count; + curveIndex += (ushort)matAnim.Curves.Count; + } + + return matAnim; + } + + + private static ResU.AnimCurve GenerateCurve(uint AnimOffset, CLR0Node anim, CLR0MaterialEntryNode entry) + { + ResU.AnimCurve curve = new ResU.AnimCurve(); + curve.AnimDataOffset = AnimOffset; + curve.StartFrame = 0; + curve.Offset = 0; + curve.Scale = 1; + curve.FrameType = ResU.AnimCurveFrameType.Single; + curve.KeyType = ResU.AnimCurveKeyType.Single; + curve.CurveType = ResU.AnimCurveType.Linear; + + List Frames = new List(); + List Keys = new List(); + + for (int c = 0; c < entry.Colors.Count; c++) + { + Frames.Add(c); + //Max of 4 values. Cubic using 4, linear using 2, and step using 1 + float[] KeyValues = new float[4]; + + switch (AnimOffset) + { + case 0: //Red + Keys.Add((float)entry.Colors[c].R / 255f); + break; + case 4: //Green + Keys.Add((float)entry.Colors[c].G / 255f); + break; + case 8: //Blue + Keys.Add((float)entry.Colors[c].B / 255f); + break; + case 12: //Alpha + Keys.Add((float)entry.Colors[c].A / 255f); + break; + default: + throw new Exception("Invalid animation offset set!"); + } + } + + //Max value in frames is our end frame + curve.EndFrame = Frames.Max(); + curve.Frames = Frames.ToArray(); + + //If a curve only has one frame we don't need to interpolate or add keys to a curve as it's constant + if (curve.Frames.Length <= 1) + return null; + + switch (curve.CurveType) + { + case ResU.AnimCurveType.Cubic: + curve.Keys = new float[Keys.Count, 4]; + for (int frame = 0; frame < Keys.Count; frame++) + { + float Delta = 0; + + if (frame < Keys.Count - 1) + Delta = Keys[frame + 1] - Keys[frame]; + + float value = Keys[frame]; + float Slope = 0; + float Slope2 = 0; + + curve.Keys[frame, 0] = value; + curve.Keys[frame, 1] = Slope; + curve.Keys[frame, 2] = Slope2; + curve.Keys[frame, 3] = Delta; + } + break; + case ResU.AnimCurveType.StepInt: + //Step requires no interpolation + curve.Keys = new float[Keys.Count, 1]; + for (int frame = 0; frame < Keys.Count; frame++) + { + curve.Keys[frame, 0] = 0; + } + break; + case ResU.AnimCurveType.Linear: + curve.Keys = new float[Keys.Count, 2]; + for (int frame = 0; frame < Keys.Count; frame++) + { + //Delta for second value used in linear curves + float time = curve.Frames[frame]; + float Delta = 0; + + if (frame < Keys.Count - 1) + Delta = Keys[frame + 1] - Keys[frame]; + + curve.Keys[frame, 0] = Keys[frame]; + curve.Keys[frame, 1] = Delta; + } + break; + } + + return curve; + } + + private static ushort[] SetIndices(ResU.ShaderParamAnim fshu) + { + List indces = new List(); + foreach (var matAnim in fshu.ShaderParamMatAnims) + indces.Add(65535); + + return indces.ToArray(); + } + private static uint CalculateBakeSize(ResU.ShaderParamAnim fshu) + { + return 0; + } + } + + public class FSKAConverter + { + static float Deg2Rad = (float)(Math.PI / 180f); + + public static SkeletalAnim Chr02Fska(string FileName) + { + CHR0Node chr0 = CHR0Node.FromFile(FileName); + + SkeletalAnim fska = new SkeletalAnim(); + fska.FrameCount = chr0.FrameCount; + fska.Name = chr0.Name; + fska.Path = chr0.OriginalPath; + fska.UserDatas = new List(); + fska.UserDataDict = new ResDict(); + + //Set flags + if (chr0.Loop) + fska.FlagsAnimSettings |= SkeletalAnimFlags.Looping; + fska.FlagsRotate = SkeletalAnimFlagsRotate.EulerXYZ; + fska.FlagsScale = SkeletalAnimFlagsScale.Maya; + + //Set bone anims and then calculate data after + foreach (var entry in chr0.Children) + fska.BoneAnims.Add(Chr0Entry2BoneAnim((CHR0EntryNode)entry)); + + fska.BakedSize = CalculateBakeSize(fska); + fska.BindIndices = SetIndices(fska); + + return fska; + } + + private static BoneAnim Chr0Entry2BoneAnim(CHR0EntryNode entry) + { + BoneAnim boneAnim = new BoneAnim(); + boneAnim.Name = entry.Name; + + if (entry.UseModelTranslate) + boneAnim.FlagsBase |= BoneAnimFlagsBase.Translate; + if (entry.UseModelRotate) + boneAnim.FlagsBase |= BoneAnimFlagsBase.Rotate; + if (entry.UseModelScale) + boneAnim.FlagsBase |= BoneAnimFlagsBase.Scale; + + var FirstFrame = entry.GetAnimFrame(0); + + float xRadian = FirstFrame.Rotation._x * Deg2Rad; + float yRadian = FirstFrame.Rotation._y * Deg2Rad; + float zRadian = FirstFrame.Rotation._z * Deg2Rad; + + var baseData = new BoneAnimData(); + baseData.Translate = new Vector3F(FirstFrame.Translation._x, FirstFrame.Translation._y, FirstFrame.Translation._z); + baseData.Rotate = new Vector4F(xRadian, yRadian, zRadian, 1); + baseData.Scale = new Vector3F(FirstFrame.Scale._x, FirstFrame.Scale._y, FirstFrame.Scale._z); + baseData.Flags = 0; + boneAnim.BaseData = baseData; + + boneAnim.FlagsBase |= BoneAnimFlagsBase.Translate; + boneAnim.FlagsBase |= BoneAnimFlagsBase.Scale; + boneAnim.FlagsBase |= BoneAnimFlagsBase.Rotate; + + if (baseData.Rotate == new Vector4F(0, 0, 0, 1)) + boneAnim.FlagsTransform |= BoneAnimFlagsTransform.RotateZero; + if (baseData.Translate == new Vector3F(0, 0, 0)) + boneAnim.FlagsTransform |= BoneAnimFlagsTransform.TranslateZero; + if (baseData.Scale == new Vector3F(1, 1, 1)) + boneAnim.FlagsTransform |= BoneAnimFlagsTransform.ScaleOne; + if (IsUniform(baseData.Scale)) + boneAnim.FlagsTransform |= BoneAnimFlagsTransform.ScaleUniform; + if (!IsRoot(boneAnim)) + boneAnim.FlagsTransform |= BoneAnimFlagsTransform.SegmentScaleCompensate; + + boneAnim.BeginTranslate = 6; + boneAnim.BeginRotate = 3; + + if (FirstFrame.HasKeys) + { + var AnimFrame = entry.GetAnimFrame(0); + if (AnimFrame.hasTx) + { + boneAnim.FlagsCurve |= BoneAnimFlagsCurve.TranslateX; + var curve = GenerateCurve(0x10, entry); + if (curve != null) + boneAnim.Curves.Add(curve); + } + if (AnimFrame.hasTy) + { + boneAnim.FlagsCurve |= BoneAnimFlagsCurve.TranslateY; + var curve = GenerateCurve(0x14, entry); + if (curve != null) + boneAnim.Curves.Add(curve); + } + if (AnimFrame.hasTz) + { + boneAnim.FlagsCurve |= BoneAnimFlagsCurve.TranslateZ; + var curve = GenerateCurve(0x18, entry); + if (curve != null) + boneAnim.Curves.Add(curve); + } + if (AnimFrame.hasRx) + { + boneAnim.FlagsCurve |= BoneAnimFlagsCurve.RotateX; + var curve = GenerateCurve(0x20, entry); + if (curve != null) + boneAnim.Curves.Add(curve); + } + if (AnimFrame.hasRy) + { + boneAnim.FlagsCurve |= BoneAnimFlagsCurve.RotateY; + var curve = GenerateCurve(0x24, entry); + if (curve != null) + boneAnim.Curves.Add(curve); + } + if (AnimFrame.hasRz) + { + boneAnim.FlagsCurve |= BoneAnimFlagsCurve.RotateZ; + var curve = GenerateCurve(0x28, entry); + if (curve != null) + boneAnim.Curves.Add(curve); + } + if (AnimFrame.hasSx) + { + boneAnim.FlagsCurve |= BoneAnimFlagsCurve.ScaleX; + var curve = GenerateCurve(0x4, entry); + if (curve != null) + boneAnim.Curves.Add(curve); + } + if (AnimFrame.hasSy) + { + boneAnim.FlagsCurve |= BoneAnimFlagsCurve.ScaleY; + var curve = GenerateCurve(0x8, entry); + if (curve != null) + boneAnim.Curves.Add(curve); + } + if (AnimFrame.hasSz) + { + boneAnim.FlagsCurve |= BoneAnimFlagsCurve.ScaleZ; + var curve = GenerateCurve(0xC, entry); + if (curve != null) + boneAnim.Curves.Add(curve); + } + } + + return boneAnim; + } + + private static bool IsRoot(BoneAnim boneAnim) + { + if (boneAnim.Name.Contains("root") || boneAnim.Name.Contains("center")) + return true; + + return false; + } + + private static bool IsUniform(Vector3F value) + { + return value.X == value.Y && value.X == value.Z; + } + + private static bool HasKeyFrames(CHR0EntryNode entry) + { + for (int frame = 0; frame < entry.FrameCount; frame++) + { + var AnimFrame = entry.GetAnimFrame(frame); + if (frame > 0) + { + if (AnimFrame.hasTx) return true; + if (AnimFrame.hasTy) return true; + if (AnimFrame.hasTz) return true; + if (AnimFrame.hasRx) return true; + if (AnimFrame.hasRy) return true; + if (AnimFrame.hasRz) return true; + if (AnimFrame.hasSx) return true; + if (AnimFrame.hasSy) return true; + if (AnimFrame.hasSz) return true; + } + } + return false; + } + + private static AnimCurve GenerateCurve(uint AnimOffset, CHR0EntryNode entry) + { + AnimCurve curve = new AnimCurve(); + curve.AnimDataOffset = AnimOffset; + curve.StartFrame = 0; + curve.Offset = 0; + curve.Scale = 1; + curve.FrameType = AnimCurveFrameType.Single; + curve.KeyType = AnimCurveKeyType.Single; + curve.CurveType = AnimCurveType.Cubic; + + List Frames = new List(); + List Keys = new List(); + + for (int frame = 0; frame < entry.FrameCount; frame++) + { + //Max of 4 values. Cubic using 4, linear using 2, and step using 1 + float[] KeyValues = new float[4]; + + //Set the main values to the curve based on offset for encoding later + var AnimFrame = entry.GetAnimFrame(frame); + if (AnimFrame.hasTx && AnimOffset == 0x10) + { + Frames.Add(frame); + KeyValues[0] = AnimFrame.Translation._x; + Keys.Add(KeyValues); + } + if (AnimFrame.hasTy && AnimOffset == 0x14) + { + Frames.Add(frame); + KeyValues[0] = AnimFrame.Translation._y; + Keys.Add(KeyValues); + } + if (AnimFrame.hasTz && AnimOffset == 0x18) + { + Frames.Add(frame); + KeyValues[0] = AnimFrame.Translation._z; + Keys.Add(KeyValues); + } + if (AnimFrame.hasRx && AnimOffset == 0x20) + { + Frames.Add(frame); + float xRadian = AnimFrame.Rotation._x * Deg2Rad; + KeyValues[0] = xRadian; + Keys.Add(KeyValues); + } + if (AnimFrame.hasRy && AnimOffset == 0x24) + { + Frames.Add(frame); + float yRadian = AnimFrame.Rotation._y * Deg2Rad; + KeyValues[0] = yRadian; + Keys.Add(KeyValues); + } + if (AnimFrame.hasRz && AnimOffset == 0x28) + { + Frames.Add(frame); + float zRadian = AnimFrame.Rotation._z * Deg2Rad; + KeyValues[0] = zRadian; + Keys.Add(KeyValues); + } + if (AnimFrame.hasSx && AnimOffset == 0x04) + { + Frames.Add(frame); + KeyValues[0] = AnimFrame.Scale._x; + Keys.Add(KeyValues); + } + if (AnimFrame.hasSy && AnimOffset == 0x08) + { + Frames.Add(frame); + KeyValues[0] = AnimFrame.Scale._y; + Keys.Add(KeyValues); + } + if (AnimFrame.hasSz && AnimOffset == 0x0C) + { + Frames.Add(frame); + KeyValues[0] = AnimFrame.Scale._z; + Keys.Add(KeyValues); + } + } + + //Max value in frames is our end frame + curve.EndFrame = Frames.Max(); + curve.Frames = Frames.ToArray(); + + //If a curve only has one frame we don't need to interpolate or add keys to a curve as it's constant + if (curve.Frames.Length <= 1) + return null; + + switch (curve.CurveType) + { + case AnimCurveType.Cubic: + curve.Keys = new float[Keys.Count, 4]; + for (int frame = 0; frame < Keys.Count; frame++) + { + float Delta = 0; + + if (frame < Keys.Count - 1) + Delta = Keys[frame + 1][0] - Keys[frame][0]; + + float value = Keys[frame][0]; + float Slope = Keys[frame][1]; + float Slope2 = Keys[frame][2]; + + curve.Keys[frame, 0] = value; + curve.Keys[frame, 1] = Slope; + curve.Keys[frame, 2] = Slope2; + curve.Keys[frame, 3] = Delta; + } + break; + case AnimCurveType.StepInt: + //Step requires no interpolation + curve.Keys = new float[Keys.Count, 1]; + for (int frame = 0; frame < Keys.Count; frame++) + { + curve.Keys[frame, 0] = Keys[frame][0]; + } + break; + case AnimCurveType.Linear: + curve.Keys = new float[Keys.Count, 2]; + for (int frame = 0; frame < Keys.Count; frame++) + { + //Delta for second value used in linear curves + float time = curve.Frames[frame]; + float Delta = 0; + + if (frame < Keys.Count - 1) + Delta = Keys[frame + 1][0] - Keys[frame][0]; + + curve.Keys[frame, 0] = Keys[frame][0]; + curve.Keys[frame, 1] = Delta; + } + break; + } + + return curve; + } + + private static ushort[] SetIndices(SkeletalAnim fska) + { + List indces = new List(); + foreach (var boneAnim in fska.BoneAnims) + indces.Add(65535); + + return indces.ToArray(); + } + private static uint CalculateBakeSize(SkeletalAnim fska) + { + return 0; + } + } +} diff --git a/BrawlboxHelper/BrawlboxHelper.csproj b/BrawlboxHelper/BrawlboxHelper.csproj new file mode 100644 index 00000000..e80b1f4c --- /dev/null +++ b/BrawlboxHelper/BrawlboxHelper.csproj @@ -0,0 +1,69 @@ + + + + + Debug + AnyCPU + {FA690685-3370-44D5-B138-F538C8D4C2A3} + Library + Properties + BrawlboxHelper + BrawlboxHelper + v4.6.2 + 512 + true + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + ..\Toolbox\bin\Release\Lib\ + TRACE + prompt + 4 + + + + ..\Toolbox\Lib\BrawlLib.dll + False + + + ..\Toolbox\Lib\Syroot.BinaryData.dll + False + + + ..\Toolbox\Lib\Syroot.Maths.dll + False + + + ..\Toolbox\Lib\Syroot.NintenTools.Bfres.dll + False + + + False + ..\Toolbox\Lib\Syroot.NintenTools.NSW.Bfres.dll + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BrawlboxHelper/Properties/AssemblyInfo.cs b/BrawlboxHelper/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..9f4fbc0d --- /dev/null +++ b/BrawlboxHelper/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BrawlboxHelper")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("BrawlboxHelper")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("fa690685-3370-44d5-b138-f538c8d4c2a3")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/README.md b/README.md index f86e30d5..6abcc219 100644 --- a/README.md +++ b/README.md @@ -78,12 +78,14 @@ In the event that the tool cannot compile, check references. All the libraries a - GDKChan for PICA shaders stuff used with bcres, structs for bcres, and some DDS decode methods - AboodXD for some foundation stuff with exelix's SARC library, Wii U (GPU7) and Switch (Tegra X1) textures swizzling, reading/converting uncompressed types for DDS, and documentation for GTX, XTX, and BNTX - MelonSpeedruns for logo. +- BrawlBox team for brawl libaries used for brres parsing. Resources - [Treeview Icons by icons8](https://icons8.com/) - Smash Forge (Currently placeholders) Libraries +- [Brawl Lib (for brres section conversion)](https://github.com/libertyernie/brawltools) - [Exelix (Sarc, kcl, and byml libraries)](https://github.com/exelix11/EditorCore/tree/master/FileFormatPlugins) - [ZstdNet (Compression)](https://github.com/skbkontur/ZstdNet) - [Be.HexEditor by Bernhard Elbl](https://sourceforge.net/projects/hexbox/) diff --git a/Switch_FileFormatsMain/FileFormats/BCRES/Wrappers/CMDL/MTOBWrapper.cs b/Switch_FileFormatsMain/FileFormats/BCRES/Wrappers/CMDL/MTOBWrapper.cs index ab354de1..20caaf4b 100644 --- a/Switch_FileFormatsMain/FileFormats/BCRES/Wrappers/CMDL/MTOBWrapper.cs +++ b/Switch_FileFormatsMain/FileFormats/BCRES/Wrappers/CMDL/MTOBWrapper.cs @@ -65,61 +65,68 @@ namespace FirstPlugin int textureUnit = 1; if (material.TextureMapInfo1 != null) + Nodes.Add(CreateGenericMatTexture(textureUnit, bcres, material.TextureMapInfo1)); + if (material.TextureMapInfo2 != null) + Nodes.Add(CreateGenericMatTexture(textureUnit, bcres, material.TextureMapInfo2)); + if (material.TextureMapInfo3 != null) + Nodes.Add(CreateGenericMatTexture(textureUnit, bcres, material.TextureMapInfo3)); + } + + private BcresTextureMapWrapper CreateGenericMatTexture(int textureUnit, BCRES bcres, TextureMapInfo TextureMapInfo) + { + STGenericMatTexture tex1 = new STGenericMatTexture(); + var TexRef = TextureMapInfo.TextureRef; + var Sampler = TextureMapInfo.Sampler; + + tex1.textureUnit = textureUnit++; + tex1.Name = TexRef.Reference.Name; + tex1.Type = STGenericMatTexture.TextureType.Diffuse; + TextureMaps.Add(tex1); + + switch (TextureMapInfo.WrapU) { - STGenericMatTexture tex1 = new STGenericMatTexture(); - var TexRef = material.TextureMapInfo1.TextureRef; - var Sampler = material.TextureMapInfo1.Sampler; - - tex1.textureUnit = textureUnit++; - tex1.Name = TexRef.Reference.Name; - tex1.Type = STGenericMatTexture.TextureType.Diffuse; - TextureMaps.Add(tex1); - - switch (material.TextureMapInfo1.WrapU) - { - case PICATextureWrap.Repeat: tex1.wrapModeS = 0; break; - case PICATextureWrap.Mirror: tex1.wrapModeS = 1; break; - case PICATextureWrap.ClampToEdge: tex1.wrapModeS = 2; break; - case PICATextureWrap.ClampToBorder: tex1.wrapModeS = 2; break; - } - switch (material.TextureMapInfo1.WrapV) - { - case PICATextureWrap.Repeat: tex1.wrapModeT = 0; break; - case PICATextureWrap.Mirror: tex1.wrapModeT = 1; break; - case PICATextureWrap.ClampToEdge: tex1.wrapModeT = 2; break; - case PICATextureWrap.ClampToBorder: tex1.wrapModeT = 2; break; - } - - switch (material.TextureMapInfo1.MagFilter) - { - case PICATextureFilter.Linear: tex1.magFilter = 0; break; - case PICATextureFilter.Nearest: tex1.magFilter = 1; break; - } - - switch (material.TextureMapInfo1.MinFilter) - { - case PICATextureFilter.Linear: tex1.minFilter = 0; break; - case PICATextureFilter.Nearest: tex1.minFilter = 1; break; - } - - switch (material.TextureMapInfo1.MipFilter) - { - case PICATextureFilter.Linear: tex1.mipDetail = 0; break; - case PICATextureFilter.Nearest: tex1.mipDetail = 1; break; - } - - switch (material.TextureMapInfo1.WrapV) - { - case PICATextureWrap.Repeat: tex1.wrapModeT = 0; break; - case PICATextureWrap.Mirror: tex1.wrapModeT = 1; break; - case PICATextureWrap.ClampToEdge: tex1.wrapModeT = 2; break; - case PICATextureWrap.ClampToBorder: tex1.wrapModeT = 2; break; - } - - - var wrapperTexMap = new BcresTextureMapWrapper(bcres, material.TextureMapInfo1, tex1); - Nodes.Add(wrapperTexMap); + case PICATextureWrap.Repeat: tex1.wrapModeS = 0; break; + case PICATextureWrap.Mirror: tex1.wrapModeS = 1; break; + case PICATextureWrap.ClampToEdge: tex1.wrapModeS = 2; break; + case PICATextureWrap.ClampToBorder: tex1.wrapModeS = 2; break; } + switch (TextureMapInfo.WrapV) + { + case PICATextureWrap.Repeat: tex1.wrapModeT = 0; break; + case PICATextureWrap.Mirror: tex1.wrapModeT = 1; break; + case PICATextureWrap.ClampToEdge: tex1.wrapModeT = 2; break; + case PICATextureWrap.ClampToBorder: tex1.wrapModeT = 2; break; + } + + switch (TextureMapInfo.MagFilter) + { + case PICATextureFilter.Linear: tex1.magFilter = 0; break; + case PICATextureFilter.Nearest: tex1.magFilter = 1; break; + } + + switch (TextureMapInfo.MinFilter) + { + case PICATextureFilter.Linear: tex1.minFilter = 0; break; + case PICATextureFilter.Nearest: tex1.minFilter = 1; break; + } + + switch (TextureMapInfo.MipFilter) + { + case PICATextureFilter.Linear: tex1.mipDetail = 0; break; + case PICATextureFilter.Nearest: tex1.mipDetail = 1; break; + } + + switch (TextureMapInfo.WrapV) + { + case PICATextureWrap.Repeat: tex1.wrapModeT = 0; break; + case PICATextureWrap.Mirror: tex1.wrapModeT = 1; break; + case PICATextureWrap.ClampToEdge: tex1.wrapModeT = 2; break; + case PICATextureWrap.ClampToBorder: tex1.wrapModeT = 2; break; + } + + + var wrapperTexMap = new BcresTextureMapWrapper(bcres, TextureMapInfo, tex1); + return wrapperTexMap; } } } diff --git a/Switch_FileFormatsMain/FileFormats/BFRES/BFRESAnimFolder.cs b/Switch_FileFormatsMain/FileFormats/BFRES/BFRESAnimFolder.cs index 2285a1c2..e542ae61 100644 --- a/Switch_FileFormatsMain/FileFormats/BFRES/BFRESAnimFolder.cs +++ b/Switch_FileFormatsMain/FileFormats/BFRES/BFRESAnimFolder.cs @@ -104,6 +104,9 @@ namespace Bfres.Structs public void ImportSkeletalAnim() { OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = FileFilters.FSKA_REPLACE; + ofd.Multiselect = true; + if (ofd.ShowDialog() != DialogResult.OK) return; @@ -115,10 +118,15 @@ namespace Bfres.Structs public void ImportShaderParamAnim() { OpenFileDialog ofd = new OpenFileDialog(); + if (IsWiiU) + ofd.Filter = FileFilters.FSHU_REPLACE; + else + ofd.Filter = FileFilters.FMAA; + ofd.Multiselect = true; + if (ofd.ShowDialog() != DialogResult.OK) return; - BFRESGroupNode group = null; if (IsWiiU) group = GetOrCreateFolder(MaterialAnimation.AnimationType.ShaderParam); @@ -132,6 +140,12 @@ namespace Bfres.Structs public void ImportColorAnim() { OpenFileDialog ofd = new OpenFileDialog(); + if (IsWiiU) + ofd.Filter = FileFilters.FSHU_REPLACE; + else + ofd.Filter = FileFilters.FMAA; + ofd.Multiselect = true; + if (ofd.ShowDialog() != DialogResult.OK) return; @@ -148,6 +162,12 @@ namespace Bfres.Structs public void ImportTexSrtAnim() { OpenFileDialog ofd = new OpenFileDialog(); + if (IsWiiU) + ofd.Filter = FileFilters.FSHU_REPLACE; + else + ofd.Filter = FileFilters.FMAA; + ofd.Multiselect = true; + if (ofd.ShowDialog() != DialogResult.OK) return; @@ -164,6 +184,12 @@ namespace Bfres.Structs public void ImportTexPatAnim() { OpenFileDialog ofd = new OpenFileDialog(); + if (IsWiiU) + ofd.Filter = FileFilters.FTXP; + else + ofd.Filter = FileFilters.FMAA; + ofd.Multiselect = true; + if (ofd.ShowDialog() != DialogResult.OK) return; @@ -180,6 +206,9 @@ namespace Bfres.Structs public void ImportBoneVisAnim() { OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = FileFilters.FBNV; + ofd.Multiselect = true; + if (ofd.ShowDialog() != DialogResult.OK) return; @@ -191,6 +220,9 @@ namespace Bfres.Structs public void ImportMatVisAnim() { OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = FileFilters.FBNV; + ofd.Multiselect = true; + if (ofd.ShowDialog() != DialogResult.OK) return; @@ -207,6 +239,9 @@ namespace Bfres.Structs public void ImportSceneAnim() { OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = FileFilters.FSCN; + ofd.Multiselect = true; + if (ofd.ShowDialog() != DialogResult.OK) return; @@ -218,6 +253,9 @@ namespace Bfres.Structs public void ImportShapeAnim() { OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = FileFilters.FSHA; + ofd.Multiselect = true; + if (ofd.ShowDialog() != DialogResult.OK) return; @@ -393,7 +431,7 @@ namespace Bfres.Structs public BFRESGroupNode GetOrCreateFolder(object CheckAnimEffect = null) where T : STGenericWrapper { - BFRESGroupNode group = new BFRESGroupNode(); + BFRESGroupNode group = new BFRESGroupNode(IsWiiU); if (typeof(T) == typeof(FSKA)) { group.Type = BRESGroupType.SkeletalAnim; } if (typeof(T) == typeof(FMAA)) { group.Type = BRESGroupType.MaterialAnim; } diff --git a/Switch_FileFormatsMain/FileFormats/BFRES/BFRESGroupNode.cs b/Switch_FileFormatsMain/FileFormats/BFRES/BFRESGroupNode.cs index 65cf9c03..87df767d 100644 --- a/Switch_FileFormatsMain/FileFormats/BFRES/BFRESGroupNode.cs +++ b/Switch_FileFormatsMain/FileFormats/BFRES/BFRESGroupNode.cs @@ -38,18 +38,7 @@ namespace Bfres.Structs get { return ContextMenuStrip.Items[0].Visible; } } - public bool IsWiiU - { - get - { - if (Parent is BFRES) - return ((BFRES)Parent).IsWiiU; - else if (Parent.Parent is BFRES) - return ((BFRES)Parent.Parent).IsWiiU; - else - return ((BFRES)Parent.Parent.Parent).IsWiiU; - } - } + public bool IsWiiU; public override void OnClick(TreeView treeview) { @@ -62,10 +51,11 @@ namespace Bfres.Structs } } - public BFRESGroupNode() : base() + public BFRESGroupNode(bool isWiiU) : base() { ImageKey = "folder"; + IsWiiU = isWiiU; LoadContextMenus(); } diff --git a/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/CurveHelper.cs b/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/CurveHelper.cs index a04697d8..2ddcf088 100644 --- a/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/CurveHelper.cs +++ b/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/CurveHelper.cs @@ -55,9 +55,9 @@ namespace Bfres.Structs InterType = InterpolationType.HERMITE, Frame = (int)animCurve.Frames[i], Value = animCurve.Offset + (animCurve.Keys[i, 0] * animCurve.Scale), - Value2 = animCurve.Offset + (animCurve.Keys[i, 1] * animCurve.Scale), - Value3 = animCurve.Offset + (animCurve.Keys[i, 2] * animCurve.Scale), - Value4 = animCurve.Offset + (animCurve.Keys[i, 3] * animCurve.Scale), + Slope1 = animCurve.Offset + (animCurve.Keys[i, 1] * animCurve.Scale), + Slope2 = animCurve.Offset + (animCurve.Keys[i, 2] * animCurve.Scale), + Delta = animCurve.Offset + (animCurve.Keys[i, 3] * animCurve.Scale), }); break; case ResU.AnimCurveType.Linear: //2 elements are stored for linear @@ -68,7 +68,7 @@ namespace Bfres.Structs InterType = InterpolationType.LINEAR, Frame = (int)animCurve.Frames[i], Value = animCurve.Offset + (animCurve.Keys[i, 0] * animCurve.Scale), - Value2 = animCurve.Offset + (animCurve.Keys[i, 1] * animCurve.Scale), + Delta = animCurve.Offset + (animCurve.Keys[i, 1] * animCurve.Scale), }); break; case ResU.AnimCurveType.StepInt: //1 element are stored for step @@ -182,9 +182,9 @@ namespace Bfres.Structs Value = animCurve.Offset + (animCurve.Keys[i, 0] * animCurve.Scale), Value1 = animCurve.Offset + (animCurve.Keys[i, 0] * animCurve.Scale), - Value2 = animCurve.Offset + (animCurve.Keys[i, 1] * animCurve.Scale), - Value3 = animCurve.Offset + (animCurve.Keys[i, 2] * animCurve.Scale), - Value4 = animCurve.Offset + (animCurve.Keys[i, 3] * animCurve.Scale), + Slope1 = animCurve.Offset + (animCurve.Keys[i, 1] * animCurve.Scale), + Slope2 = animCurve.Offset + (animCurve.Keys[i, 2] * animCurve.Scale), + Delta = animCurve.Offset + (animCurve.Keys[i, 3] * animCurve.Scale), }); break; case AnimCurveType.Linear: //2 elements are stored for linear @@ -197,7 +197,7 @@ namespace Bfres.Structs Value = animCurve.Offset + (animCurve.Keys[i, 0] * animCurve.Scale), Value1 = animCurve.Offset + (animCurve.Keys[i, 0] * animCurve.Scale), - Value2 = animCurve.Offset + (animCurve.Keys[i, 1] * animCurve.Scale), + Delta = animCurve.Offset + (animCurve.Keys[i, 1] * animCurve.Scale), }); break; case AnimCurveType.StepInt: //1 element are stored for step diff --git a/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/SubFiles/FMDL.cs b/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/SubFiles/FMDL.cs index a6fee2d6..88775dba 100644 --- a/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/SubFiles/FMDL.cs +++ b/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/SubFiles/FMDL.cs @@ -465,7 +465,14 @@ namespace Bfres.Structs break; default: AssimpSaver assimp = new AssimpSaver(); - assimp.SaveFromModel(this, FileName, GetTextures(), Skeleton, Skeleton.Node_Array.ToList()); + ExportModelSettings settings = new ExportModelSettings(); + if (settings.ShowDialog() == DialogResult.OK) + { + if (settings.ExportTextures) + assimp.SaveFromModel(this, FileName, GetTextures(), Skeleton, Skeleton.Node_Array.ToList()); + else + assimp.SaveFromModel(this, FileName, new List(), Skeleton, Skeleton.Node_Array.ToList()); + } break; } } diff --git a/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/SubFiles/FSHU.cs b/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/SubFiles/FSHU.cs index fb89c55b..29805169 100644 --- a/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/SubFiles/FSHU.cs +++ b/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/SubFiles/FSHU.cs @@ -32,6 +32,9 @@ namespace Bfres.Structs Materials.Add(mat); } + public override string ExportFilter => FileFilters.FSHU_EXPORT; + public override string ReplaceFilter => FileFilters.FSHU_REPLACE; + public override void OnClick(TreeView treeView) => UpdateEditor(); public void UpdateEditor(){ @@ -66,6 +69,11 @@ namespace Bfres.Structs ShaderParamAnim.Import(FileName, resFile, ShaderParamAnimType.TextureSRT); LoadAnim(ShaderParamAnim, AnimationType.TexturePattern); } + if (ext == ".clr0") + { + ShaderParamAnim = BrawlboxHelper.FSHUConverter.Clr02Fshu(FileName); + LoadAnim(ShaderParamAnim, AnimationType.Color); + } ShaderParamAnim.Name = Text; } diff --git a/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/SubFiles/FSKA.cs b/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/SubFiles/FSKA.cs index 4c8f265e..c879870f 100644 --- a/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/SubFiles/FSKA.cs +++ b/Switch_FileFormatsMain/FileFormats/BFRES/Bfres Structs/SubFiles/FSKA.cs @@ -186,25 +186,183 @@ namespace Bfres.Structs string ext = Utils.GetExtension(FileName); if (ext == ".bfska") { + bool IsSwitch = BfresUtilies.IsSubSectionSwitch(FileName); + MessageBox.Show(IsSwitch.ToString()); + if (resFileU != null) { - SkeletalAnimU.Import(FileName, resFileU); - SkeletalAnimU.Name = Text; - LoadAnim(SkeletalAnimU); + //If it's a switch animation try to conver it to wii u + if (IsSwitch) + { + var ska = new SkeletalAnim(); + ska.Import(FileName); + SkeletalAnimU = ConvertSwitchToWiiU(ska); + SkeletalAnimU.Name = Text; + LoadAnim(SkeletalAnimU); + } + else + { + SkeletalAnimU.Import(FileName, resFileU); + SkeletalAnimU.Name = Text; + LoadAnim(SkeletalAnimU); + } } else { - SkeletalAnim.Import(FileName); - SkeletalAnim.Name = Text; - LoadAnim(SkeletalAnim); + if (IsSwitch) + { + SkeletalAnim.Import(FileName); + SkeletalAnim.Name = Text; + LoadAnim(SkeletalAnim); + } + else + { + //Create a new wii u skeletal anim and try to convert it instead + var ska = new ResU.SkeletalAnim(); + ska.Import(FileName, new ResU.ResFile()); + SkeletalAnim = ConvertWiiUToSwitch(ska); + SkeletalAnim.Name = Text; + LoadAnim(SkeletalAnim); + } } } else if (ext == ".seanim") { FromSeanim(FileName); } + else if (ext == ".chr0") + { + FromChr0(FileName); + } } + public static SkeletalAnim ConvertWiiUToSwitch(ResU.SkeletalAnim skeletalAnimU) + { + SkeletalAnim ska = new SkeletalAnim(); + ska.Name = skeletalAnimU.Name; + ska.Path = skeletalAnimU.Path; + ska.FrameCount = skeletalAnimU.FrameCount; + ska.FlagsScale = SkeletalAnimFlagsScale.None; + + if (skeletalAnimU.FlagsScale.HasFlag(ResU.SkeletalAnimFlagsScale.Maya)) + ska.FlagsScale = SkeletalAnimFlagsScale.Maya; + if (skeletalAnimU.FlagsScale.HasFlag(ResU.SkeletalAnimFlagsScale.Softimage)) + ska.FlagsScale = SkeletalAnimFlagsScale.Softimage; + if (skeletalAnimU.FlagsScale.HasFlag(ResU.SkeletalAnimFlagsScale.Standard)) + ska.FlagsScale = SkeletalAnimFlagsScale.Standard; + + ska.FrameCount = skeletalAnimU.FrameCount; + ska.BindIndices = skeletalAnimU.BindIndices; + ska.BakedSize = skeletalAnimU.BakedSize; + ska.Loop = skeletalAnimU.Loop; + ska.Baked = skeletalAnimU.Baked; + foreach (var boneAnimU in skeletalAnimU.BoneAnims) + { + var boneAnim = new BoneAnim(); + ska.BoneAnims.Add(boneAnim); + boneAnim.Name = boneAnimU.Name; + boneAnim.BeginRotate = boneAnimU.BeginRotate; + boneAnim.BeginTranslate = boneAnimU.BeginTranslate; + boneAnim.BeginBaseTranslate = boneAnimU.BeginBaseTranslate; + var baseData = new BoneAnimData(); + baseData.Translate = boneAnimU.BaseData.Translate; + baseData.Scale = boneAnimU.BaseData.Scale; + baseData.Rotate = boneAnimU.BaseData.Rotate; + baseData.Flags = boneAnimU.BaseData.Flags; + boneAnim.BaseData = baseData; + boneAnim.FlagsBase = (BoneAnimFlagsBase)boneAnimU.FlagsBase; + boneAnim.FlagsCurve = (BoneAnimFlagsCurve)boneAnimU.FlagsCurve; + boneAnim.FlagsTransform = (BoneAnimFlagsTransform)boneAnimU.FlagsTransform; + + foreach (var curveU in boneAnimU.Curves) + { + AnimCurve curve = new AnimCurve(); + curve.AnimDataOffset = curveU.AnimDataOffset; + curve.CurveType = (AnimCurveType)curveU.CurveType; + curve.Delta = curveU.Delta; + curve.EndFrame = curveU.EndFrame; + curve.Frames = curveU.Frames; + curve.Keys = curveU.Keys; + curve.KeyStepBoolData = curveU.KeyStepBoolData; + curve.KeyType = (AnimCurveKeyType)curveU.KeyType; + curve.FrameType = (AnimCurveFrameType)curveU.FrameType; + curve.StartFrame = curveU.StartFrame; + curve.Scale = curveU.Scale; + if (curve.Offset.GetType() == typeof(float)) + curve.Offset = (float)curveU.Offset; + if (curve.Offset.GetType() == typeof(uint)) + curve.Offset = (uint)curveU.Offset; + if (curve.Offset.GetType() == typeof(int)) + curve.Offset = (int)curveU.Offset; + + boneAnim.Curves.Add(curve); + } + } + + return ska; + } + + public static ResU.SkeletalAnim ConvertSwitchToWiiU(SkeletalAnim skeletalAnimNX) + { + ResU.SkeletalAnim ska = new ResU.SkeletalAnim(); + ska.Name = skeletalAnimNX.Name; + ska.Path = skeletalAnimNX.Path; + ska.FrameCount = skeletalAnimNX.FrameCount; + ska.FlagsScale = ResU.SkeletalAnimFlagsScale.None; + + if (skeletalAnimNX.FlagsScale.HasFlag(SkeletalAnimFlagsScale.Maya)) + ska.FlagsScale = ResU.SkeletalAnimFlagsScale.Maya; + if (skeletalAnimNX.FlagsScale.HasFlag(SkeletalAnimFlagsScale.Softimage)) + ska.FlagsScale = ResU.SkeletalAnimFlagsScale.Softimage; + if (skeletalAnimNX.FlagsScale.HasFlag(SkeletalAnimFlagsScale.Standard)) + ska.FlagsScale = ResU.SkeletalAnimFlagsScale.Standard; + + ska.FrameCount = skeletalAnimNX.FrameCount; + ska.BindIndices = skeletalAnimNX.BindIndices; + ska.BakedSize = skeletalAnimNX.BakedSize; + ska.Loop = skeletalAnimNX.Loop; + ska.Baked = skeletalAnimNX.Baked; + foreach (var boneAnimNX in skeletalAnimNX.BoneAnims) + { + var boneAnimU = new ResU.BoneAnim(); + ska.BoneAnims.Add(boneAnimU); + boneAnimU.Name = boneAnimNX.Name; + boneAnimU.BeginRotate = boneAnimNX.BeginRotate; + boneAnimU.BeginTranslate = boneAnimNX.BeginTranslate; + boneAnimU.BeginBaseTranslate = boneAnimNX.BeginBaseTranslate; + var baseData = new ResU.BoneAnimData(); + baseData.Translate = boneAnimNX.BaseData.Translate; + baseData.Scale = boneAnimNX.BaseData.Scale; + baseData.Rotate = boneAnimNX.BaseData.Rotate; + baseData.Flags = boneAnimNX.BaseData.Flags; + boneAnimU.BaseData = baseData; + boneAnimU.FlagsBase = (ResU.BoneAnimFlagsBase)boneAnimNX.FlagsBase; + boneAnimU.FlagsCurve = (ResU.BoneAnimFlagsCurve)boneAnimNX.FlagsCurve; + boneAnimU.FlagsTransform = (ResU.BoneAnimFlagsTransform)boneAnimNX.FlagsTransform; + + foreach (var curveNX in boneAnimU.Curves) + { + ResU.AnimCurve curve = new ResU.AnimCurve(); + curve.AnimDataOffset = curveNX.AnimDataOffset; + curve.CurveType = curveNX.CurveType; + curve.Delta = curveNX.Delta; + curve.EndFrame = curveNX.EndFrame; + curve.Frames = curveNX.Frames; + curve.Keys = curveNX.Keys; + curve.KeyStepBoolData = curveNX.KeyStepBoolData; + curve.KeyType = curveNX.KeyType; + curve.FrameType = curveNX.FrameType; + curve.StartFrame = curveNX.StartFrame; + curve.Scale = curveNX.Scale; + curve.Offset = curveNX.Offset; + boneAnimU.Curves.Add(curve); + } + } + + return ska; + } + + public FSKA(ResU.SkeletalAnim ska) { LoadAnim(ska); } public FSKA(SkeletalAnim ska) { LoadAnim(ska); } @@ -363,6 +521,23 @@ namespace Bfres.Structs Initialize(); } + public void FromChr0(string FileName) + { + if (SkeletalAnimU != null) + { + var SkeletalAnimNX = BrawlboxHelper.FSKAConverter.Chr02Fska(FileName); + SkeletalAnimU = ConvertSwitchToWiiU(SkeletalAnimNX); + SkeletalAnimU.Name = Text; + LoadAnim(SkeletalAnimU); + } + else + { + SkeletalAnim = BrawlboxHelper.FSKAConverter.Chr02Fska(FileName); + SkeletalAnim.Name = Text; + LoadAnim(SkeletalAnim); + } + } + public void FromSeanim(string FileName) { SEAnim anim = SEAnim.Read(FileName); diff --git a/Switch_FileFormatsMain/FileFormats/BFRES/BfresUtilies.cs b/Switch_FileFormatsMain/FileFormats/BFRES/BfresUtilies.cs new file mode 100644 index 00000000..b9ab43ae --- /dev/null +++ b/Switch_FileFormatsMain/FileFormats/BFRES/BfresUtilies.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Switch_Toolbox.Library.IO; + +namespace FirstPlugin +{ + public class BfresUtilies + { + public static bool IsSubSectionSwitch(string FileName) + { + using (var reader = new FileReader(FileName)) + { + reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian; + + reader.Seek(24, System.IO.SeekOrigin.Begin); + return reader.ReadUInt32() == 1; + } + } + } +} diff --git a/Switch_FileFormatsMain/FileFormats/Texture/GTXFile.cs b/Switch_FileFormatsMain/FileFormats/Texture/GTXFile.cs index a270c523..b70253d7 100644 --- a/Switch_FileFormatsMain/FileFormats/Texture/GTXFile.cs +++ b/Switch_FileFormatsMain/FileFormats/Texture/GTXFile.cs @@ -576,7 +576,9 @@ namespace FirstPlugin LibraryGUI.Instance.LoadEditor(editor); } editor.Text = Text; - editor.LoadProperties(FTEX.FromGx2Surface(surface, Text)); + var tex = FTEX.FromGx2Surface(surface, Text); + tex.MipCount = MipCount; + editor.LoadProperties(tex); editor.LoadImage(this); } } diff --git a/Switch_FileFormatsMain/GUI/BFRES/AnimKeyViewer.cs b/Switch_FileFormatsMain/GUI/BFRES/AnimKeyViewer.cs index 4f5a7205..b71a2322 100644 --- a/Switch_FileFormatsMain/GUI/BFRES/AnimKeyViewer.cs +++ b/Switch_FileFormatsMain/GUI/BFRES/AnimKeyViewer.cs @@ -47,9 +47,9 @@ namespace FirstPlugin.Forms stLabel1.Text = $"key Frame {keyFrame.Frame}"; numericUpDownFloat1.Value = (decimal)keyFrame.Value1; - numericUpDownFloat2.Value = (decimal)keyFrame.Value2; - numericUpDownFloat3.Value = (decimal)keyFrame.Value3; - numericUpDownFloat4.Value = (decimal)keyFrame.Value4; + numericUpDownFloat2.Value = (decimal)keyFrame.Slope1; + numericUpDownFloat3.Value = (decimal)keyFrame.Slope2; + numericUpDownFloat4.Value = (decimal)keyFrame.Delta; } else { diff --git a/Switch_FileFormatsMain/NodeWrappers/Archives/BFRESWrapper.cs b/Switch_FileFormatsMain/NodeWrappers/Archives/BFRESWrapper.cs index c5ad92d0..aa06e8d0 100644 --- a/Switch_FileFormatsMain/NodeWrappers/Archives/BFRESWrapper.cs +++ b/Switch_FileFormatsMain/NodeWrappers/Archives/BFRESWrapper.cs @@ -45,7 +45,7 @@ namespace FirstPlugin.NodeWrappers if (ofd.ShowDialog() != DialogResult.OK) return; - BFRESGroupNode group = new BFRESGroupNode(); + BFRESGroupNode group = new BFRESGroupNode(IsWiiU); group.Import(ofd.FileNames); } @@ -55,13 +55,13 @@ namespace FirstPlugin.NodeWrappers if (ofd.ShowDialog() != DialogResult.OK) return; - BFRESGroupNode group = new BFRESGroupNode(); + BFRESGroupNode group = new BFRESGroupNode(IsWiiU); group.Import(ofd.FileNames); } public void NewModel() { - BFRESGroupNode group = new BFRESGroupNode(); + BFRESGroupNode group = new BFRESGroupNode(IsWiiU); FMDL anim = new FMDL(); if (IsWiiU) @@ -80,7 +80,7 @@ namespace FirstPlugin.NodeWrappers public void NewEmbeddedFile() { - BFRESGroupNode group = new BFRESGroupNode(); + BFRESGroupNode group = new BFRESGroupNode(IsWiiU); ExternalFileData fshu = new ExternalFileData("NewFile", new byte[0]); group.AddNode(fshu, "NewFile"); SetupAddedNode(group, fshu); diff --git a/Switch_FileFormatsMain/NodeWrappers/BfresFilters.cs b/Switch_FileFormatsMain/NodeWrappers/BfresFilters.cs index 60b926ab..db6ba497 100644 --- a/Switch_FileFormatsMain/NodeWrappers/BfresFilters.cs +++ b/Switch_FileFormatsMain/NodeWrappers/BfresFilters.cs @@ -21,9 +21,12 @@ namespace FirstPlugin public static string BONE = GetFilter(".bfbon"); public static string FMAT = GetFilter(".bfmat"); - public static string FSKA = GetFilter(".bfska", ".seanim", ".smd"); + public static string FSKA_EXPORT = GetFilter(".bfska", ".seanim", ".smd"); + public static string FSKA_REPLACE = GetFilter(".bfska", ".chr0"); + public static string FMAA = GetFilter(".bfmaa", ".gif"); - public static string FSHU = GetFilter(".bfshu"); + public static string FSHU_REPLACE = GetFilter(".bfshu", "clr0"); + public static string FSHU_EXPORT = GetFilter(".bfshu"); public static string FCLH = GetFilter(".bfcsh"); public static string FSTH = GetFilter(".bfsth"); @@ -45,7 +48,8 @@ namespace FirstPlugin else if (type == typeof(FMAT)) return FMAT; else if (type == typeof(FSKL)) return FSKL; else if (type == typeof(BfresBone)) return BONE; - else if (type == typeof(FSKA)) return FSKA; + else if (type == typeof(FMAA) && IsExporting) return FSKA_EXPORT; + else if (type == typeof(FSKA)) return FSKA_REPLACE; else if (type == typeof(FMAA)) return FMAA; else if (type == typeof(FTXP)) return FTXP; else if (type == typeof(FSHA)) return FSHA; @@ -67,7 +71,11 @@ namespace FirstPlugin if (animType == VisibiltyAnimType.Material) return FMTV; else return FBNV; } - return FSHU; + + if (IsExporting) + return FSHU_EXPORT; + else + return FSHU_REPLACE; } else if (type == typeof(FVIS)) { diff --git a/Switch_FileFormatsMain/Switch_FileFormatsMain.csproj b/Switch_FileFormatsMain/Switch_FileFormatsMain.csproj index 252e82f7..4cabd85d 100644 --- a/Switch_FileFormatsMain/Switch_FileFormatsMain.csproj +++ b/Switch_FileFormatsMain/Switch_FileFormatsMain.csproj @@ -217,6 +217,7 @@ + @@ -1159,6 +1160,11 @@ + + {fa690685-3370-44d5-b138-f538c8d4c2a3} + BrawlboxHelper + False + {96820047-2a39-4e5a-bfa4-e84fff5c66cf} Switch_Toolbox_Library diff --git a/Switch_FileFormatsMain/obj/Release/AxInterop.WMPLib.dll b/Switch_FileFormatsMain/obj/Release/AxInterop.WMPLib.dll index c009c822..3c818859 100644 Binary files a/Switch_FileFormatsMain/obj/Release/AxInterop.WMPLib.dll and b/Switch_FileFormatsMain/obj/Release/AxInterop.WMPLib.dll differ diff --git a/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferences.cache b/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferences.cache index bac4bb97..9f50fead 100644 Binary files a/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferences.cache and b/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferences.cache differ diff --git a/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache b/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache index eb97bdf7..08af96c0 100644 Binary files a/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache and b/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache differ diff --git a/Switch_FileFormatsMain/obj/Release/Interop.WMPLib.dll b/Switch_FileFormatsMain/obj/Release/Interop.WMPLib.dll index 2fa12fb4..de59ae1b 100644 Binary files a/Switch_FileFormatsMain/obj/Release/Interop.WMPLib.dll and b/Switch_FileFormatsMain/obj/Release/Interop.WMPLib.dll differ diff --git a/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csproj.CoreCompileInputs.cache b/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csproj.CoreCompileInputs.cache index 39aa351b..c991c147 100644 --- a/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csproj.CoreCompileInputs.cache +++ b/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -f3116c416a062081738ca7e7aee034e76dab7162 +b1cc2c6fe1714d994e4d77917f9fc78ba61787cc diff --git a/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csprojAssemblyReference.cache b/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csprojAssemblyReference.cache index d0fc217e..0b3eabbf 100644 Binary files a/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csprojAssemblyReference.cache and b/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csprojAssemblyReference.cache differ diff --git a/Switch_Toolbox.sln b/Switch_Toolbox.sln index deca1148..6ddc3624 100644 --- a/Switch_Toolbox.sln +++ b/Switch_Toolbox.sln @@ -11,6 +11,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Updater", "Updater\Updater. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Toolbox", "Toolbox\Toolbox.csproj", "{5E55CA2B-F181-4681-AAFA-A20FEBCF7387}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BrawlboxHelper", "BrawlboxHelper\BrawlboxHelper.csproj", "{FA690685-3370-44D5-B138-F538C8D4C2A3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -52,14 +53,14 @@ Global {5E55CA2B-F181-4681-AAFA-A20FEBCF7387}.Release|Any CPU.Build.0 = Release|Any CPU {5E55CA2B-F181-4681-AAFA-A20FEBCF7387}.Release|x64.ActiveCfg = Release|Any CPU {5E55CA2B-F181-4681-AAFA-A20FEBCF7387}.Release|x64.Build.0 = Release|Any CPU - {860B49C9-54E3-4E10-830D-6497B845ED11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {860B49C9-54E3-4E10-830D-6497B845ED11}.Debug|Any CPU.Build.0 = Debug|Any CPU - {860B49C9-54E3-4E10-830D-6497B845ED11}.Debug|x64.ActiveCfg = Debug|Any CPU - {860B49C9-54E3-4E10-830D-6497B845ED11}.Debug|x64.Build.0 = Debug|Any CPU - {860B49C9-54E3-4E10-830D-6497B845ED11}.Release|Any CPU.ActiveCfg = Release|Any CPU - {860B49C9-54E3-4E10-830D-6497B845ED11}.Release|Any CPU.Build.0 = Release|Any CPU - {860B49C9-54E3-4E10-830D-6497B845ED11}.Release|x64.ActiveCfg = Release|Any CPU - {860B49C9-54E3-4E10-830D-6497B845ED11}.Release|x64.Build.0 = Release|Any CPU + {FA690685-3370-44D5-B138-F538C8D4C2A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA690685-3370-44D5-B138-F538C8D4C2A3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA690685-3370-44D5-B138-F538C8D4C2A3}.Debug|x64.ActiveCfg = Debug|Any CPU + {FA690685-3370-44D5-B138-F538C8D4C2A3}.Debug|x64.Build.0 = Debug|Any CPU + {FA690685-3370-44D5-B138-F538C8D4C2A3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA690685-3370-44D5-B138-F538C8D4C2A3}.Release|Any CPU.Build.0 = Release|Any CPU + {FA690685-3370-44D5-B138-F538C8D4C2A3}.Release|x64.ActiveCfg = Release|Any CPU + {FA690685-3370-44D5-B138-F538C8D4C2A3}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Switch_Toolbox_Library/Animations/Animation.cs b/Switch_Toolbox_Library/Animations/Animation.cs index f4c3eb03..6d2958eb 100644 --- a/Switch_Toolbox_Library/Animations/Animation.cs +++ b/Switch_Toolbox_Library/Animations/Animation.cs @@ -453,7 +453,10 @@ namespace Switch_Toolbox.Library.Animations { public bool IsKeyed = false; - public float Value1, Value2, Value3, Value4; + public float Value1, Delta; + + public float Slope1; + public float Slope2; public float Value { @@ -468,7 +471,11 @@ namespace Switch_Toolbox.Library.Animations } public String Text; public float _frame; - public float In = 0, Out = -1; + + public float In = 0; + public float Out = -1; + + // public float In = 0, Out = -1; public bool Weighted = false; public bool Degrees = false; // Use Degrees public InterpolationType InterType = InterpolationType.LINEAR; diff --git a/Switch_Toolbox_Library/FileFormats/Assimp/AssimpSaver.cs b/Switch_Toolbox_Library/FileFormats/Assimp/AssimpSaver.cs index 569216ff..218c33f3 100644 --- a/Switch_Toolbox_Library/FileFormats/Assimp/AssimpSaver.cs +++ b/Switch_Toolbox_Library/FileFormats/Assimp/AssimpSaver.cs @@ -11,17 +11,42 @@ namespace Switch_Toolbox.Library { public class AssimpSaver { + private List ExtractedTextures = new List(); + public List BoneNames = new List(); + STProgressBar progressBar; + public void SaveFromModel(STGenericModel model, string FileName, List Textures, STSkeleton skeleton = null, List NodeArray = null) { + ExtractedTextures.Clear(); + Scene scene = new Scene(); scene.RootNode = new Node("RootNode"); + progressBar = new STProgressBar(); + progressBar.Task = "Exorting Skeleton..."; + progressBar.Value = 0; + progressBar.StartPosition = FormStartPosition.CenterScreen; + progressBar.Show(); + progressBar.Refresh(); + SaveSkeleton(skeleton, scene.RootNode); SaveMaterials(scene, model, FileName, Textures); + + progressBar.Task = "Exorting Meshes..."; + progressBar.Value = 50; + SaveMeshes(scene, model, skeleton, FileName, NodeArray); + + progressBar.Task = "Saving File..."; + progressBar.Value = 80; + SaveScene(FileName, scene); + + progressBar.Value = 100; + progressBar.Close(); + progressBar.Dispose(); } private void SaveScene(string FileName, Scene scene) @@ -150,15 +175,24 @@ namespace Switch_Toolbox.Library string TextureExtension = ".png"; string TexturePath = System.IO.Path.GetDirectoryName(FileName); - foreach (var tex in Textures) + for (int i = 0; i < Textures.Count; i++) { - string path = System.IO.Path.Combine(TexturePath, tex.Text + TextureExtension); + string path = System.IO.Path.Combine(TexturePath, Textures[i].Text + TextureExtension); - var bitmap = tex.GetBitmap(); - bitmap.Save(path); - bitmap.Dispose(); + if (!ExtractedTextures.Contains(path)) + { + ExtractedTextures.Add(path); - GC.Collect(); + progressBar.Task = $"Exorting Texture {Textures[i].Text}"; + progressBar.Value = ((i * 100) / Textures.Count); + progressBar.Refresh(); + + var bitmap = Textures[i].GetBitmap(); + bitmap.Save(path); + bitmap.Dispose(); + + GC.Collect(); + } } foreach (var mat in model.Nodes[1].Nodes) diff --git a/Switch_Toolbox_Library/Forms/BatchFormatExport.cs b/Switch_Toolbox_Library/Forms/BatchFormatExport.cs index 1388f9c0..d01fe77c 100644 --- a/Switch_Toolbox_Library/Forms/BatchFormatExport.cs +++ b/Switch_Toolbox_Library/Forms/BatchFormatExport.cs @@ -31,8 +31,8 @@ namespace Switch_Toolbox.Library string SelectedExt = comboBox1.GetSelectedText(); string output = GetSubstringByString("(",")", SelectedExt); - output = output.Replace('*', ' '); - output.Replace(" ", string.Empty); + output = output.Remove(0, 1); + output.Replace(" ", string.Empty); if (output == ".") output = ".raw"; diff --git a/Switch_Toolbox_Library/Forms/Dialogs/ExportModelSettings.Designer.cs b/Switch_Toolbox_Library/Forms/Dialogs/ExportModelSettings.Designer.cs new file mode 100644 index 00000000..5cc73f3d --- /dev/null +++ b/Switch_Toolbox_Library/Forms/Dialogs/ExportModelSettings.Designer.cs @@ -0,0 +1,100 @@ +namespace Switch_Toolbox.Library.Forms +{ + partial class ExportModelSettings + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.exportTexturesChkBox = new Switch_Toolbox.Library.Forms.STCheckBox(); + this.stButton1 = new Switch_Toolbox.Library.Forms.STButton(); + this.stButton2 = new Switch_Toolbox.Library.Forms.STButton(); + this.contentContainer.SuspendLayout(); + this.SuspendLayout(); + // + // contentContainer + // + this.contentContainer.Controls.Add(this.stButton2); + this.contentContainer.Controls.Add(this.stButton1); + this.contentContainer.Controls.Add(this.exportTexturesChkBox); + this.contentContainer.Size = new System.Drawing.Size(210, 156); + this.contentContainer.Controls.SetChildIndex(this.exportTexturesChkBox, 0); + this.contentContainer.Controls.SetChildIndex(this.stButton1, 0); + this.contentContainer.Controls.SetChildIndex(this.stButton2, 0); + // + // exportTexturesChkBox + // + this.exportTexturesChkBox.AutoSize = true; + this.exportTexturesChkBox.Checked = true; + this.exportTexturesChkBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.exportTexturesChkBox.Location = new System.Drawing.Point(23, 47); + this.exportTexturesChkBox.Name = "exportTexturesChkBox"; + this.exportTexturesChkBox.Size = new System.Drawing.Size(100, 17); + this.exportTexturesChkBox.TabIndex = 11; + this.exportTexturesChkBox.Text = "Export Textures"; + this.exportTexturesChkBox.UseVisualStyleBackColor = true; + // + // stButton1 + // + this.stButton1.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.stButton1.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.stButton1.Location = new System.Drawing.Point(126, 124); + this.stButton1.Name = "stButton1"; + this.stButton1.Size = new System.Drawing.Size(75, 23); + this.stButton1.TabIndex = 12; + this.stButton1.Text = "Cancel"; + this.stButton1.UseVisualStyleBackColor = false; + // + // stButton2 + // + this.stButton2.DialogResult = System.Windows.Forms.DialogResult.OK; + this.stButton2.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.stButton2.Location = new System.Drawing.Point(45, 124); + this.stButton2.Name = "stButton2"; + this.stButton2.Size = new System.Drawing.Size(75, 23); + this.stButton2.TabIndex = 13; + this.stButton2.Text = "Ok"; + this.stButton2.UseVisualStyleBackColor = false; + // + // ExportModelSettings + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(216, 161); + this.Name = "ExportModelSettings"; + this.Text = "Export Settings"; + this.contentContainer.ResumeLayout(false); + this.contentContainer.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private STCheckBox exportTexturesChkBox; + private STButton stButton2; + private STButton stButton1; + } +} \ No newline at end of file diff --git a/Switch_Toolbox_Library/Forms/Dialogs/ExportModelSettings.cs b/Switch_Toolbox_Library/Forms/Dialogs/ExportModelSettings.cs new file mode 100644 index 00000000..2e268191 --- /dev/null +++ b/Switch_Toolbox_Library/Forms/Dialogs/ExportModelSettings.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Switch_Toolbox.Library.Forms +{ + public partial class ExportModelSettings : STForm + { + public bool ExportTextures + { + get + { + return exportTexturesChkBox.Checked; + } + } + + public ExportModelSettings() + { + InitializeComponent(); + } + } +} diff --git a/Switch_Toolbox_Library/Forms/Dialogs/ExportModelSettings.resx b/Switch_Toolbox_Library/Forms/Dialogs/ExportModelSettings.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/Switch_Toolbox_Library/Forms/Dialogs/ExportModelSettings.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Switch_Toolbox_Library/Generics/STGenericWrapper.cs b/Switch_Toolbox_Library/Generics/STGenericWrapper.cs index 6b053c11..68abae6d 100644 --- a/Switch_Toolbox_Library/Generics/STGenericWrapper.cs +++ b/Switch_Toolbox_Library/Generics/STGenericWrapper.cs @@ -186,6 +186,7 @@ namespace Switch_Toolbox.Library.NodeWrappers if (form.ShowDialog() == DialogResult.OK) { string extension = form.GetSelectedExtension(); + extension.Replace(" ", string.Empty); foreach (TreeNode node in Nodes) { diff --git a/Switch_Toolbox_Library/Switch_Toolbox_Library.csproj b/Switch_Toolbox_Library/Switch_Toolbox_Library.csproj index 51f00fa6..0615f6b6 100644 --- a/Switch_Toolbox_Library/Switch_Toolbox_Library.csproj +++ b/Switch_Toolbox_Library/Switch_Toolbox_Library.csproj @@ -220,6 +220,12 @@ BatchFormatExport.cs + + Form + + + ExportModelSettings.cs + UserControl @@ -690,6 +696,9 @@ STTextBox.cs + + ExportModelSettings.cs + STOptionsDialog.cs diff --git a/Toolbox/Lib/BrawlLib.dll b/Toolbox/Lib/BrawlLib.dll new file mode 100644 index 00000000..46cd82e7 Binary files /dev/null and b/Toolbox/Lib/BrawlLib.dll differ diff --git a/Toolbox/Lib/BrawlLib.pdb b/Toolbox/Lib/BrawlLib.pdb new file mode 100644 index 00000000..0bcac6d3 Binary files /dev/null and b/Toolbox/Lib/BrawlLib.pdb differ diff --git a/Toolbox/Lib/BrawlboxHelper.dll b/Toolbox/Lib/BrawlboxHelper.dll new file mode 100644 index 00000000..4e4b4abd Binary files /dev/null and b/Toolbox/Lib/BrawlboxHelper.dll differ diff --git a/Toolbox/Lib/BrawlboxHelper.pdb b/Toolbox/Lib/BrawlboxHelper.pdb new file mode 100644 index 00000000..03303d1c Binary files /dev/null and b/Toolbox/Lib/BrawlboxHelper.pdb differ diff --git a/Toolbox/Toolbox.csproj b/Toolbox/Toolbox.csproj index 1715bca0..05de3122 100644 --- a/Toolbox/Toolbox.csproj +++ b/Toolbox/Toolbox.csproj @@ -310,6 +310,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest