diff --git a/BrawlboxHelper/Syroot.NintenTools.NSW.Bfres.dll b/BrawlboxHelper/Syroot.NintenTools.NSW.Bfres.dll index 038acd50..09d451a8 100644 Binary files a/BrawlboxHelper/Syroot.NintenTools.NSW.Bfres.dll and b/BrawlboxHelper/Syroot.NintenTools.NSW.Bfres.dll differ diff --git a/File_Format_Library/FileFormats/Archives/GFA.cs b/File_Format_Library/FileFormats/Archives/GFA.cs index fa726e15..725cbd6f 100644 --- a/File_Format_Library/FileFormats/Archives/GFA.cs +++ b/File_Format_Library/FileFormats/Archives/GFA.cs @@ -7,6 +7,8 @@ using Toolbox; using System.Windows.Forms; using Toolbox.Library; using Toolbox.Library.IO; +using System.IO; +using VGAudio.Utilities; namespace FirstPlugin { @@ -80,9 +82,24 @@ namespace FirstPlugin uint CompressionType = reader.ReadUInt32(); uint DecompressedSize = reader.ReadUInt32(); uint CompressedSize = reader.ReadUInt32(); + + byte[] input = reader.ReadBytes((int)CompressedSize); + if (CompressionType == 1) input = BPE.Decompress(input, DecompressedSize, CompressedSize); + if (CompressionType == 2) input = LZ77_WII.Decompress(input); + if (CompressionType == 3) input = LZ77_WII.Decompress(input); //same as 2 + + using (var r = new FileReader(input)) + { + for (int i = 0; i < FileCount; i++) + { + r.SeekBegin(files[i].Offset - DataOffset); + files[i].FileData = r.ReadBytes((int)files[i].Size); + } + } } } + public void Unload() { @@ -146,13 +163,15 @@ namespace FirstPlugin public class FileEntry : ArchiveFileInfo { public uint Hash { get; set; } + public uint Offset { get; set; } + public uint Size { get; set; } public void Read(FileReader reader) { Hash = reader.ReadUInt32(); FileName = GetName(reader); - uint Size = reader.ReadUInt32(); - uint Offset = reader.ReadUInt32(); + Size = reader.ReadUInt32(); + Offset = reader.ReadUInt32(); } } @@ -164,5 +183,114 @@ namespace FirstPlugin return reader.ReadZeroTerminatedString(); } } + + class BPE + { + //Decompiled from MasterF0X tool for BPE decompression + static int index = 0; + static bool end = false; + + public static byte[] Decompress(byte[] input, uint decompressedSize, uint cs) + { + char[] chArray1 = new char[16777215]; + char[] chArray2 = new char[16777215]; + char[] chArray3 = new char[16777215]; + + var mem = new MemoryStream(); + BinaryWriter binaryWriter = new BinaryWriter(mem); + label_26: + int num1; + int num2; + while (index < input.Length) + { + if (end) + { + binaryWriter.Close(); + end = false; + index = 0; + num1 = 0; + num2 = 0; + return mem.ToArray(); + } + for (int index = 0; index < 256; ++index) + chArray1[index] = (char)index; + int num3 = (int)getc(input, cs); + int index1 = 0; + while (true) + { + if (num3 > (int)sbyte.MaxValue) + { + index1 += num3 - (int)sbyte.MaxValue; + num3 = 0; + } + if (index1 != 256) + { + int num4 = 0; + while (num4 <= num3) + { + chArray1[index1] = getc(input, cs); + if (index1 != (int)chArray1[index1]) + chArray2[index1] = getc(input, cs); + ++num4; + ++index1; + } + if (index1 != 256) + num3 = (int)getc(input, cs); + else + break; + } + else + break; + } + int num5 = 256 * (int)getc(input, cs) + (int)getc(input, cs); + int num6 = 0; + while (true) + { + int index2; + if (num6 > 0) + index2 = (int)chArray3[--num6]; + else if (num5-- != 0) + index2 = (int)getc(input, cs); + else + goto label_26; + if (index2 == (int)chArray1[index2]) + { + binaryWriter.Write((byte)index2); + } + else + { + char[] chArray4 = chArray3; + int index3 = num6; + int num7 = index3 + 1; + int num8 = (int)chArray2[index2]; + chArray4[index3] = (char)num8; + char[] chArray5 = chArray3; + int index4 = num7; + num6 = index4 + 1; + int num9 = (int)chArray1[index2]; + chArray5[index4] = (char)num9; + } + } + } + binaryWriter.Close(); + end = false; + index = 0; + num1 = 0; + num2 = 0; + return mem.ToArray(); + } + + static char getc(byte[] input, uint uncompS) + { + if (index >= uncompS) + { + end = true; + return '0'; + } + char ch = (char)input[index]; + ++index; + return ch; + } + } } } diff --git a/File_Format_Library/FileFormats/BFRES/Bfres Structs/CurveHelper.cs b/File_Format_Library/FileFormats/BFRES/Bfres Structs/CurveHelper.cs index 73df2d7a..03709587 100644 --- a/File_Format_Library/FileFormats/BFRES/Bfres Structs/CurveHelper.cs +++ b/File_Format_Library/FileFormats/BFRES/Bfres Structs/CurveHelper.cs @@ -7,6 +7,8 @@ using Syroot.NintenTools.NSW.Bfres; using Toolbox.Library; using ResU = Syroot.NintenTools.Bfres; using Toolbox.Library.Animations; +using AampLibraryCSharp; +using static FirstPlugin.CSAB; namespace Bfres.Structs { @@ -26,76 +28,94 @@ namespace Bfres.Structs else return AnimCurveKeyType.Single; } - public static Animation.KeyGroup CreateTrackWiiU(ResU.AnimCurve animCurve) + public static Animation.KeyGroup CreateTrackWiiU(ResU.AnimCurve curve, bool valuesAsInts = false) { Animation.KeyGroup track = new Animation.KeyGroup(); - track.AnimDataOffset = animCurve.AnimDataOffset; - track.Scale = animCurve.Scale; - track.Offset = animCurve.Offset; - track.StartFrame = animCurve.StartFrame; - track.EndFrame = animCurve.EndFrame; - track.Delta = animCurve.Delta; + track.AnimDataOffset = curve.AnimDataOffset; + track.Scale = curve.Scale; + track.Offset = curve.Offset; + track.StartFrame = curve.StartFrame; + track.EndFrame = curve.EndFrame; + track.Delta = curve.Delta; - float tanscale = animCurve.Delta; + float tanscale = curve.Delta; if (tanscale == 0) tanscale = 1; - if (animCurve.Scale == 0) - animCurve.Scale = 1; + if (curve.Scale == 0) + curve.Scale = 1; - for (int i = 0; i < (ushort)animCurve.Frames.Length; i++) + float valueScale = curve.Scale > 0 ? curve.Scale : 1; + + for (int i = 0; i < curve.Frames.Length; i++) { - switch (animCurve.CurveType) + var frame = curve.Frames[i]; + if (frame == 0 && track.Keys.Any(x => x.Frame == 0)) + track.Keys.RemoveAt(0); + + switch (curve.CurveType) { - case ResU.AnimCurveType.Cubic: //4 elements are stored for cubic - track.InterpolationType = InterpolationType.HERMITE; - var coef0 = animCurve.Offset + (animCurve.Keys[i, 0] * animCurve.Scale); - var coef1 = animCurve.Offset + (animCurve.Keys[i, 1] * animCurve.Scale); - var coef2 = animCurve.Offset + (animCurve.Keys[i, 2] * animCurve.Scale); - var coef3 = animCurve.Offset + (animCurve.Keys[i, 3] * animCurve.Scale); - var slopes = GetSlopes(animCurve, i); + case ResU.AnimCurveType.Cubic: + { + track.InterpolationType = InterpolationType.HERMITE; + //Important to not offset the other 3 values, just the first one! + var value = curve.Keys[i, 0] * valueScale + curve.Offset; + var slopes = GetSlopes(curve, i); - track.Keys.Add(new Animation.KeyFrame() - { - IsKeyed = true, - InterType = InterpolationType.HERMITE, - Frame = (int)animCurve.Frames[i], - Value = coef0, - // Slope1 = slopes[0], - // Slope2 = slopes[1], - }); + track.Keys.Add(new Animation.KeyFrame() + { + Frame = frame, + Value = value, + In = slopes[0], + Out = slopes[1], + }); + } break; - case ResU.AnimCurveType.Linear: //2 elements are stored for linear - track.InterpolationType = InterpolationType.LINEAR; - track.Keys.Add(new Animation.KeyFrame() + case ResU.AnimCurveType.Linear: { - IsKeyed = true, - InterType = InterpolationType.LINEAR, - Frame = (int)animCurve.Frames[i], - Value = animCurve.Offset + (animCurve.Keys[i, 0] * animCurve.Scale), - Delta = animCurve.Offset + (animCurve.Keys[i, 1] * animCurve.Scale), - }); + track.InterpolationType = InterpolationType.LINEAR; + var value = curve.Keys[i, 0] * valueScale + curve.Offset; + var delta = curve.Keys[i, 1] * valueScale; + track.Keys.Add(new Animation.KeyFrame() + { + Frame = frame, + Value = value, + Delta = delta, + }); + } break; - case ResU.AnimCurveType.StepInt: //1 element are stored for step - track.InterpolationType = InterpolationType.STEP; - track.Keys.Add(new Animation.KeyFrame() + case ResU.AnimCurveType.StepBool: { - IsKeyed = true, - InterType = InterpolationType.STEP, - Frame = (int)animCurve.Frames[i], - Value = (int)animCurve.Offset + (int)animCurve.Keys[i, 0] * animCurve.Scale, - }); - - Console.WriteLine($"Frame {animCurve.Frames[i]} FrameINT {(int)animCurve.Frames[i]} Offset " + (int)animCurve.Offset + " " + ((int)animCurve.Offset + (int)animCurve.Keys[i, 0] * animCurve.Scale)); + track.InterpolationType = InterpolationType.STEP; + track.Keys.Add(new Animation.KeyFrame() + { + Frame = frame, + Value = curve.KeyStepBoolData[i] ? 1 : 0, + }); + } break; default: - throw new Exception("Unsupported anim type!"); + { + track.InterpolationType = InterpolationType.STEP; + var value = curve.Keys[i, 0] + curve.Offset; + if (valuesAsInts) + value = (int)curve.Keys[i, 0] + curve.Offset; + + track.Keys.Add(new Animation.KeyFrame() + { + Frame = frame, + Value = value, + }); + } + break; } } return track; } + //Method to extract the slopes from a cubic curve + //Need to get the time, delta, out and next in slope values public static float[] GetSlopes(AnimCurve curve, float index) { float[] slopes = new float[2]; @@ -106,9 +126,9 @@ namespace Bfres.Structs for (int i = 0; i < curve.Frames.Length; i++) { var coef0 = curve.Keys[i, 0] * curve.Scale + curve.Offset; - var coef1 = curve.Keys[i, 1] * curve.Scale + curve.Offset; - var coef2 = curve.Keys[i, 2] * curve.Scale + curve.Offset; - var coef3 = curve.Keys[i, 3] * curve.Scale + curve.Offset; + var coef1 = curve.Keys[i, 1] * curve.Scale; + var coef2 = curve.Keys[i, 2] * curve.Scale; + var coef3 = curve.Keys[i, 3] * curve.Scale; float time = 0; float delta = 0; if (i < curve.Frames.Length - 1) @@ -118,7 +138,7 @@ namespace Bfres.Structs time = curve.Frames[i + 1] - curve.Frames[i]; } - var slopeData = CurveInterpolationHelper.GetCubicSlopes(time, delta, + var slopeData = GetCubicSlopes(time, delta, new float[4] { coef0, coef1, coef2, coef3, }); if (index == i) @@ -135,6 +155,7 @@ namespace Bfres.Structs return slopes; } + public static float[] GetSlopes(ResU.AnimCurve curve, float index) { float[] slopes = new float[2]; @@ -145,9 +166,9 @@ namespace Bfres.Structs for (int i = 0; i < curve.Frames.Length; i++) { var coef0 = curve.Keys[i, 0] * curve.Scale + curve.Offset; - var coef1 = curve.Keys[i, 1] * curve.Scale + curve.Offset; - var coef2 = curve.Keys[i, 2] * curve.Scale + curve.Offset; - var coef3 = curve.Keys[i, 3] * curve.Scale + curve.Offset; + var coef1 = curve.Keys[i, 1] * curve.Scale; + var coef2 = curve.Keys[i, 2] * curve.Scale; + var coef3 = curve.Keys[i, 3] * curve.Scale; float time = 0; float delta = 0; if (i < curve.Frames.Length - 1) @@ -157,7 +178,7 @@ namespace Bfres.Structs time = curve.Frames[i + 1] - curve.Frames[i]; } - var slopeData = CurveInterpolationHelper.GetCubicSlopes(time, delta, + var slopeData = GetCubicSlopes(time, delta, new float[4] { coef0, coef1, coef2, coef3, }); if (index == i) @@ -174,6 +195,14 @@ namespace Bfres.Structs return slopes; } + public static float[] GetCubicSlopes(float time, float delta, float[] coef) + { + float outSlope = coef[1] / time; + float param = coef[3] - (-2 * delta); + float inSlope = param / time - outSlope; + return new float[2] { inSlope, coef[1] == 0 ? 0 : outSlope }; + } + public static BooleanKeyGroup CreateBooleanTrackWiiU(ResU.AnimCurve animCurve) { BooleanKeyGroup track = new BooleanKeyGroup(); @@ -235,75 +264,86 @@ namespace Bfres.Structs return track; } - public static Animation.KeyGroup CreateTrack(AnimCurve animCurve) + public static Animation.KeyGroup CreateTrack(AnimCurve curve, bool valuesAsInts = false) { Animation.KeyGroup track = new Animation.KeyGroup(); - track.AnimDataOffset = animCurve.AnimDataOffset; - track.Scale = animCurve.Scale; - track.Offset = animCurve.Offset; - track.StartFrame = animCurve.StartFrame; - track.EndFrame = animCurve.EndFrame; - track.Delta = animCurve.Delta; + track.AnimDataOffset = curve.AnimDataOffset; + track.Scale = curve.Scale; + track.Offset = curve.Offset; + track.StartFrame = curve.StartFrame; + track.EndFrame = curve.EndFrame; + track.Delta = curve.Delta; - float tanscale = animCurve.Delta; + float tanscale = curve.Delta; if (tanscale == 0) tanscale = 1; - if (animCurve.Scale == 0) - animCurve.Scale = 1; + if (curve.Scale == 0) + curve.Scale = 1; - for (int i = 0; i < (ushort)animCurve.Frames.Length; i++) + float valueScale = curve.Scale > 0 ? curve.Scale : 1; + + for (int i = 0; i < curve.Frames.Length; i++) { - switch (animCurve.CurveType) + var frame = curve.Frames[i]; + if (frame == 0 && track.Keys.Any(x => x.Frame == 0)) + track.Keys.RemoveAt(0); + + switch (curve.CurveType) { - case AnimCurveType.Cubic: //4 elements are stored for cubic - track.InterpolationType = InterpolationType.HERMITE; - var coef0 = animCurve.Offset + (animCurve.Keys[i, 0] * animCurve.Scale); - var coef1 = animCurve.Offset + (animCurve.Keys[i, 1] * animCurve.Scale); - var coef2 = animCurve.Offset + (animCurve.Keys[i, 2] * animCurve.Scale); - var coef3 = animCurve.Offset + (animCurve.Keys[i, 3] * animCurve.Scale); - var slopes = GetSlopes(animCurve, i); - - var inSlope = slopes[0] * animCurve.Scale + animCurve.Offset; - var outSlope = slopes[1] * animCurve.Scale + animCurve.Offset; - - track.Keys.Add(new Animation.KeyFrame() + case AnimCurveType.Cubic: { - IsKeyed = true, - InterType = InterpolationType.HERMITE, - Frame = (int)animCurve.Frames[i], - Value = coef0, - Slope1 = inSlope, - Slope2 = outSlope, - }); + track.InterpolationType = InterpolationType.HERMITE; + //Important to not offset the other 3 values, just the first one! + var value = curve.Keys[i, 0] * valueScale + curve.Offset; + var slopes = GetSlopes(curve, i); + + track.Keys.Add(new Animation.KeyFrame() + { + Frame = frame, + Value = value, + In = slopes[0], + Out = slopes[1], + }); + } break; - case AnimCurveType.Linear: //2 elements are stored for linear - track.InterpolationType = InterpolationType.LINEAR; - track.Keys.Add(new Animation.KeyFrame() + case AnimCurveType.Linear: { - IsKeyed = true, - InterType = InterpolationType.LINEAR, - Frame = (int)animCurve.Frames[i], - Value = animCurve.Offset + (animCurve.Keys[i, 0] * animCurve.Scale), - - Value1 = animCurve.Offset + (animCurve.Keys[i, 0] * animCurve.Scale), - Delta = animCurve.Offset + (animCurve.Keys[i, 1] * animCurve.Scale), - }); + track.InterpolationType = InterpolationType.LINEAR; + var value = curve.Keys[i, 0] * valueScale + curve.Offset; + var delta = curve.Keys[i, 1] * valueScale; + track.Keys.Add(new Animation.KeyFrame() + { + Frame = frame, + Value = value, + Delta = delta, + }); + } break; - case AnimCurveType.StepInt: //1 element are stored for step - track.InterpolationType = InterpolationType.STEP; - track.Keys.Add(new Animation.KeyFrame() + case AnimCurveType.StepBool: { - IsKeyed = true, - InterType = InterpolationType.STEP, - Frame = (int)animCurve.Frames[i], - Value = (int)animCurve.Offset + (int)animCurve.Keys[i, 0] * animCurve.Scale, - Value1 = (int)animCurve.Offset + (int)animCurve.Keys[i, 0] * animCurve.Scale, - - }); + track.InterpolationType = InterpolationType.STEP; + track.Keys.Add(new Animation.KeyFrame() + { + Frame = frame, + Value = curve.KeyStepBoolData[i] ? 1 : 0, + }); + } break; default: - throw new Exception("Unsupported anim type!"); + { + track.InterpolationType = InterpolationType.STEP; + var value = curve.Keys[i, 0] + curve.Offset; + if (valuesAsInts) + value = (int)curve.Keys[i, 0] + curve.Offset; + + track.Keys.Add(new Animation.KeyFrame() + { + Frame = frame, + Value = value, + }); + } + break; } } diff --git a/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FMAA.cs b/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FMAA.cs index 7bb8b97d..525e1257 100644 --- a/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FMAA.cs +++ b/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FMAA.cs @@ -431,7 +431,7 @@ namespace Bfres.Structs { int index = (int)SamplerInfo.CurveIndex; - Animation.KeyGroup keyGroup = CurveHelper.CreateTrack(matanim.Curves[index]); + Animation.KeyGroup keyGroup = CurveHelper.CreateTrack(matanim.Curves[index], true); sampler.AnimDataOffset = matanim.Curves[index].AnimDataOffset; sampler.Keys = keyGroup.Keys; diff --git a/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FMDL.cs b/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FMDL.cs index acaa600d..7c6a5651 100644 --- a/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FMDL.cs +++ b/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FMDL.cs @@ -610,6 +610,7 @@ namespace Bfres.Structs Dictionary> AttributeMatcher = new Dictionary>(); bool IsWiiU = (resFileU != null); + var boneMappings = Model != null ? Model.Skeleton.userIndices : new ushort[0]; int MatStartIndex = materials.Count; string ext = System.IO.Path.GetExtension(FileName); @@ -1365,6 +1366,9 @@ namespace Bfres.Structs if (IsEdited) UpdateVertexData(); + + if (Model != null) + Model.Skeleton.userIndices = boneMappings; } public FMAT GetMaterial(int index) diff --git a/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FSKA.cs b/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FSKA.cs index 4d1b0dcd..b911970d 100644 --- a/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FSKA.cs +++ b/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FSKA.cs @@ -11,6 +11,7 @@ using Toolbox.Library.Animations; using Toolbox.Library.Forms; using SELib; using FirstPlugin.Forms; +using static Toolbox.Library.Animations.Animation; namespace Bfres.Structs { @@ -748,16 +749,16 @@ namespace Bfres.Structs keyGroup.AnimDataOffset = bn.Curves[curve].AnimDataOffset; switch (keyGroup.AnimDataOffset) { - case (int)TrackType.XPOS: bone.XPOS.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.YPOS: bone.YPOS.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.ZPOS: bone.ZPOS.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.XROT: bone.XROT.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.YROT: bone.YROT.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.ZROT: bone.ZROT.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.WROT: bone.WROT.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.XSCA: bone.XSCA.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.YSCA: bone.YSCA.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.ZSCA: bone.ZSCA.Keys.AddRange(keyGroup.Keys); break; + case (int)TrackType.XPOS: bone.XPOS = keyGroup; break; + case (int)TrackType.YPOS: bone.YPOS = keyGroup; break; + case (int)TrackType.ZPOS: bone.ZPOS = keyGroup; break; + case (int)TrackType.XROT: bone.XROT = keyGroup; break; + case (int)TrackType.YROT: bone.YROT = keyGroup; break; + case (int)TrackType.ZROT: bone.ZROT = keyGroup; break; + case (int)TrackType.WROT: bone.WROT = keyGroup; break; + case (int)TrackType.XSCA: bone.XSCA = keyGroup; break; + case (int)TrackType.YSCA: bone.YSCA = keyGroup; break; + case (int)TrackType.ZSCA: bone.ZSCA = keyGroup; break; default: throw new Exception("Unknown Anim Offset " + keyGroup.AnimDataOffset); } } @@ -811,16 +812,16 @@ namespace Bfres.Structs keyGroup.AnimDataOffset = bn.Curves[curve].AnimDataOffset; switch (keyGroup.AnimDataOffset) { - case (int)TrackType.XPOS: bone.XPOS.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.YPOS: bone.YPOS.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.ZPOS: bone.ZPOS.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.XROT: bone.XROT.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.YROT: bone.YROT.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.ZROT: bone.ZROT.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.WROT: bone.WROT.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.XSCA: bone.XSCA.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.YSCA: bone.YSCA.Keys.AddRange(keyGroup.Keys); break; - case (int)TrackType.ZSCA: bone.ZSCA.Keys.AddRange(keyGroup.Keys); break; + case (int)TrackType.XPOS: bone.XPOS = keyGroup; break; + case (int)TrackType.YPOS: bone.YPOS = keyGroup; break; + case (int)TrackType.ZPOS: bone.ZPOS = keyGroup; break; + case (int)TrackType.XROT: bone.XROT = keyGroup; break; + case (int)TrackType.YROT: bone.YROT = keyGroup; break; + case (int)TrackType.ZROT: bone.ZROT = keyGroup; break; + case (int)TrackType.WROT: bone.WROT = keyGroup; break; + case (int)TrackType.XSCA: bone.XSCA = keyGroup; break; + case (int)TrackType.YSCA: bone.YSCA = keyGroup; break; + case (int)TrackType.ZSCA: bone.ZSCA = keyGroup; break; default: throw new Exception("Unknown Anim Offset " + keyGroup.AnimDataOffset); } } diff --git a/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FTXP.cs b/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FTXP.cs index 03bc3005..ca34132e 100644 --- a/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FTXP.cs +++ b/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FTXP.cs @@ -85,7 +85,7 @@ namespace Bfres.Structs { int index = (int)SamplerInfo.CurveIndex; - Animation.KeyGroup keyGroup = CurveHelper.CreateTrackWiiU(matanim.Curves[index]); + Animation.KeyGroup keyGroup = CurveHelper.CreateTrackWiiU(matanim.Curves[index], true); sampler.AnimDataOffset = matanim.Curves[index].AnimDataOffset; sampler.Keys = keyGroup.Keys; diff --git a/File_Format_Library/FileFormats/Texture/BNTX.cs b/File_Format_Library/FileFormats/Texture/BNTX.cs index 96714246..c9697a8c 100644 --- a/File_Format_Library/FileFormats/Texture/BNTX.cs +++ b/File_Format_Library/FileFormats/Texture/BNTX.cs @@ -1534,7 +1534,9 @@ namespace FirstPlugin //Max mip level will be set automatically unless overwritten //The tex format can be adjusted in the function if necessary. Will normally be set to format in settings - public void Replace(string FileName, uint MaxMipLevel = 0, uint ArrayIndex = 0, TEX_FORMAT DefaultFormat = TEX_FORMAT.BC1_UNORM_SRGB, SurfaceDim surfaceDim = SurfaceDim.Dim2D) + public void Replace(string FileName, uint MaxMipLevel = 0, uint ArrayIndex = 0, + TEX_FORMAT DefaultFormat = TEX_FORMAT.BC1_UNORM_SRGB, SurfaceDim surfaceDim = SurfaceDim.Dim2D, + int alignment = 512) { Console.WriteLine("surfaceDim" + surfaceDim); @@ -1545,6 +1547,9 @@ namespace FirstPlugin BinaryTextureImporterList importer = new BinaryTextureImporterList(); setting.SurfaceDim = surfaceDim; + setting.Alignment = alignment; + //Check if alignment is required for combining individual levels or not + setting.CombineMipLevel = alignment != 0 ? true : false; var ImageDataCached = new List>(); if (Texture != null && Texture.TextureData != null) diff --git a/File_Format_Library/FileFormats/Texture/TXTG.cs b/File_Format_Library/FileFormats/Texture/TXTG.cs index 77faed59..b2adf673 100644 --- a/File_Format_Library/FileFormats/Texture/TXTG.cs +++ b/File_Format_Library/FileFormats/Texture/TXTG.cs @@ -244,7 +244,7 @@ namespace FirstPlugin writer.Write((byte)mip); writer.Write((byte)1); - var surface = Zstb.SCompress(ImageList[array][mip]); + var surface = Zstb.SCompress(ImageList[array][mip], 20); surfaceSizes.Add((uint)surface.Length); surfaceData.Add(surface); @@ -293,7 +293,7 @@ namespace FirstPlugin { //Replace the data using an instance of a switch texture var tex = new TextureData(); - tex.Replace(FileName, MipCount, 0, Format); + tex.Replace(FileName, MipCount, 0, Format, Syroot.NintenTools.NSW.Bntx.GFX.SurfaceDim.Dim2D, 1); //Get swappable array level ImageEditorBase editor = (ImageEditorBase)LibraryGUI.GetActiveContent(typeof(ImageEditorBase)); @@ -310,6 +310,9 @@ namespace FirstPlugin if (tex.Texture == null) return; + for (int i = 0; i < ImageList[0].Count; i++) + Console.WriteLine($"SIZE 1 mip{i} {ImageList[0][i].Length}"); + //Ensure the format matches if image requires multiple surface levels if (ImageList.Count > 1 && this.Format != tex.Format) throw new Exception($"Imported texture must use the original format for surface injecting! Expected {this.Format} but got {tex.Format}! If you need ASTC, use an astc encoder with .astc file format."); @@ -326,6 +329,10 @@ namespace FirstPlugin ImageList.Add(surface); } + for (int i = 0; i < ImageList[0].Count; i++) + Console.WriteLine($"SIZE 2 mip{i} {ImageList[0][i].Length}"); + + Width = tex.Texture.Width; Height = tex.Texture.Height; MipCount = tex.Texture.MipCount; @@ -363,6 +370,7 @@ namespace FirstPlugin { 0x203, TEX_FORMAT.BC1_UNORM_SRGB }, { 0x302, TEX_FORMAT.BC1_UNORM }, { 0x606, TEX_FORMAT.BC4_UNORM }, + { 0x607, TEX_FORMAT.BC4_UNORM }, { 0x702, TEX_FORMAT.BC5_UNORM }, { 0x703, TEX_FORMAT.BC5_UNORM }, { 0x707, TEX_FORMAT.BC5_UNORM }, diff --git a/File_Format_Library/File_Format_Library.csproj b/File_Format_Library/File_Format_Library.csproj index 3d7e7e4f..d3f4d350 100644 --- a/File_Format_Library/File_Format_Library.csproj +++ b/File_Format_Library/File_Format_Library.csproj @@ -1557,6 +1557,7 @@ + diff --git a/File_Format_Library/GL/BFRES/BFRES_Render.cs b/File_Format_Library/GL/BFRES/BFRES_Render.cs index bd11f5d9..c3f24382 100644 --- a/File_Format_Library/GL/BFRES/BFRES_Render.cs +++ b/File_Format_Library/GL/BFRES/BFRES_Render.cs @@ -821,8 +821,8 @@ namespace FirstPlugin { if (mat.shaderassign.options.ContainsKey(propertyName)) { - float value = float.Parse(mat.shaderassign.options[propertyName]); - shader.SetFloat(propertyName, value); + //float value = float.Parse(mat.shaderassign.options[propertyName]); + //shader.SetFloat(propertyName, value); } Dictionary matParams = mat.matparam; diff --git a/File_Format_Library/GUI/BFRES/BfresModelImportSettings.Designer.cs b/File_Format_Library/GUI/BFRES/BfresModelImportSettings.Designer.cs index 8bd31fd6..97e333d1 100644 --- a/File_Format_Library/GUI/BFRES/BfresModelImportSettings.Designer.cs +++ b/File_Format_Library/GUI/BFRES/BfresModelImportSettings.Designer.cs @@ -61,6 +61,8 @@ this.chkBoxFlipUvsY = new Toolbox.Library.Forms.STCheckBox(); this.chkBoxImportBones = new Toolbox.Library.Forms.STCheckBox(); this.panel8 = new Toolbox.Library.Forms.STPanel(); + this.stLabel4 = new Toolbox.Library.Forms.STLabel(); + this.lodCountUD = new Toolbox.Library.Forms.NumericUpDownUint(); this.chkCreateDummyLODs = new Toolbox.Library.Forms.STCheckBox(); this.stLabel3 = new Toolbox.Library.Forms.STLabel(); this.gamePresetCB = new Toolbox.Library.Forms.STComboBox(); @@ -103,8 +105,6 @@ this.stCheckBox1 = new Toolbox.Library.Forms.STCheckBox(); this.chkMapOriginalMaterials = new Toolbox.Library.Forms.STCheckBox(); this.ogSkinCountChkBox = new Toolbox.Library.Forms.STCheckBox(); - this.lodCountUD = new Toolbox.Library.Forms.NumericUpDownUint(); - this.stLabel4 = new Toolbox.Library.Forms.STLabel(); this.contentContainer.SuspendLayout(); this.panel1.SuspendLayout(); this.panel2.SuspendLayout(); @@ -114,6 +114,7 @@ this.panel6.SuspendLayout(); this.panel7.SuspendLayout(); this.panel8.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.lodCountUD)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); this.panel9.SuspendLayout(); this.tabControl1.SuspendLayout(); @@ -121,7 +122,6 @@ this.tabPageAdvanced.SuspendLayout(); this.stPanel1.SuspendLayout(); this.tabPage1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.lodCountUD)).BeginInit(); this.SuspendLayout(); // // contentContainer @@ -492,6 +492,27 @@ this.panel8.Size = new System.Drawing.Size(524, 341); this.panel8.TabIndex = 11; // + // stLabel4 + // + this.stLabel4.AutoSize = true; + this.stLabel4.Location = new System.Drawing.Point(237, 291); + this.stLabel4.Name = "stLabel4"; + this.stLabel4.Size = new System.Drawing.Size(63, 13); + this.stLabel4.TabIndex = 39; + this.stLabel4.Text = "LOD Count:"; + // + // lodCountUD + // + this.lodCountUD.Location = new System.Drawing.Point(319, 289); + this.lodCountUD.Maximum = new decimal(new int[] { + 2147483647, + 0, + 0, + 0}); + this.lodCountUD.Name = "lodCountUD"; + this.lodCountUD.Size = new System.Drawing.Size(120, 20); + this.lodCountUD.TabIndex = 38; + // // chkCreateDummyLODs // this.chkCreateDummyLODs.AutoSize = true; @@ -582,6 +603,7 @@ this.chkBoxRotNegative90Y.Text = "Rotate -90 degrees"; this.chkBoxRotNegative90Y.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; this.chkBoxRotNegative90Y.UseVisualStyleBackColor = true; + this.chkBoxRotNegative90Y.CheckedChanged += new System.EventHandler(this.chkBoxSettings_CheckedChanged); // // textBoxMaterialPath // @@ -814,7 +836,7 @@ this.tabPageAdvanced.Location = new System.Drawing.Point(4, 25); this.tabPageAdvanced.Name = "tabPageAdvanced"; this.tabPageAdvanced.Padding = new System.Windows.Forms.Padding(3); - this.tabPageAdvanced.Size = new System.Drawing.Size(530, 333); + this.tabPageAdvanced.Size = new System.Drawing.Size(530, 347); this.tabPageAdvanced.TabIndex = 0; this.tabPageAdvanced.Text = "Advanced Settings"; // @@ -831,7 +853,7 @@ this.stPanel1.Dock = System.Windows.Forms.DockStyle.Fill; this.stPanel1.Location = new System.Drawing.Point(3, 3); this.stPanel1.Name = "stPanel1"; - this.stPanel1.Size = new System.Drawing.Size(524, 327); + this.stPanel1.Size = new System.Drawing.Size(524, 341); this.stPanel1.TabIndex = 17; // // tabPage1 @@ -848,7 +870,7 @@ this.tabPage1.Location = new System.Drawing.Point(4, 25); this.tabPage1.Name = "tabPage1"; this.tabPage1.Padding = new System.Windows.Forms.Padding(3); - this.tabPage1.Size = new System.Drawing.Size(530, 333); + this.tabPage1.Size = new System.Drawing.Size(530, 347); this.tabPage1.TabIndex = 2; this.tabPage1.Text = "Inject Mode"; this.tabPage1.UseVisualStyleBackColor = true; @@ -959,27 +981,6 @@ this.ogSkinCountChkBox.Text = "Keep Original Skin Count (can help crashes)"; this.ogSkinCountChkBox.UseVisualStyleBackColor = true; // - // lodCountUD - // - this.lodCountUD.Location = new System.Drawing.Point(319, 289); - this.lodCountUD.Maximum = new decimal(new int[] { - 2147483647, - 0, - 0, - 0}); - this.lodCountUD.Name = "lodCountUD"; - this.lodCountUD.Size = new System.Drawing.Size(120, 20); - this.lodCountUD.TabIndex = 38; - // - // stLabel4 - // - this.stLabel4.AutoSize = true; - this.stLabel4.Location = new System.Drawing.Point(237, 291); - this.stLabel4.Name = "stLabel4"; - this.stLabel4.Size = new System.Drawing.Size(63, 13); - this.stLabel4.TabIndex = 39; - this.stLabel4.Text = "LOD Count:"; - // // BfresModelImportSettings // this.ClientSize = new System.Drawing.Size(547, 412); @@ -1003,6 +1004,7 @@ this.panel7.PerformLayout(); this.panel8.ResumeLayout(false); this.panel8.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.lodCountUD)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); this.panel9.ResumeLayout(false); this.panel9.PerformLayout(); @@ -1012,7 +1014,6 @@ this.stPanel1.ResumeLayout(false); this.tabPage1.ResumeLayout(false); this.tabPage1.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.lodCountUD)).EndInit(); this.ResumeLayout(false); } diff --git a/File_Format_Library/GUI/BFRES/BfresModelImportSettings.cs b/File_Format_Library/GUI/BFRES/BfresModelImportSettings.cs index 9a972c2a..59c88052 100644 --- a/File_Format_Library/GUI/BFRES/BfresModelImportSettings.cs +++ b/File_Format_Library/GUI/BFRES/BfresModelImportSettings.cs @@ -492,10 +492,12 @@ namespace FirstPlugin int assimpIndex = assimpMeshListView.SelectedIndices[0]; - if (objectNameTB.Text == originalMeshListView.Items[assimpIndex].Text) - objectNameTB.BackColor = System.Drawing.Color.Green; - else - objectNameTB.BackColor = System.Drawing.Color.DarkRed; + objectNameTB.BackColor = System.Drawing.Color.DarkRed; + foreach (ListViewItem item in originalMeshListView.Items) + { + if (objectNameTB.Text == item.Text) + objectNameTB.BackColor = System.Drawing.Color.Green; + } NewMeshlist[assimpIndex].ObjectName = objectNameTB.Text; } diff --git a/File_Format_Library/GUI/BFRES/Materials/ShaderAssign/ShaderOptionsEditor.Designer.cs b/File_Format_Library/GUI/BFRES/Materials/ShaderAssign/ShaderOptionsEditor.Designer.cs index cd10f1cd..8001c8ff 100644 --- a/File_Format_Library/GUI/BFRES/Materials/ShaderAssign/ShaderOptionsEditor.Designer.cs +++ b/File_Format_Library/GUI/BFRES/Materials/ShaderAssign/ShaderOptionsEditor.Designer.cs @@ -28,17 +28,66 @@ /// private void InitializeComponent() { + this.chkFilterDefaults = new Toolbox.Library.Forms.STCheckBox(); + this.shaderOptionsListView = new Toolbox.Library.Forms.STListView(); + this.ovlColumn1 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); + this.ovlColumn2 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); this.btnScrolDown = new Toolbox.Library.Forms.STButton(); this.btnScrollUp = new Toolbox.Library.Forms.STButton(); this.btnEdit = new Toolbox.Library.Forms.STButton(); this.btnRemove = new Toolbox.Library.Forms.STButton(); this.btnAdd = new Toolbox.Library.Forms.STButton(); - this.shaderOptionsListView = new Toolbox.Library.Forms.STListView(); - this.ovlColumn1 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); - this.ovlColumn2 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn())); ((System.ComponentModel.ISupportInitialize)(this.shaderOptionsListView)).BeginInit(); this.SuspendLayout(); // + // chkFilterDefaults + // + this.chkFilterDefaults.AutoSize = true; + this.chkFilterDefaults.Checked = true; + this.chkFilterDefaults.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkFilterDefaults.Location = new System.Drawing.Point(165, 7); + this.chkFilterDefaults.Name = "chkFilterDefaults"; + this.chkFilterDefaults.Size = new System.Drawing.Size(120, 17); + this.chkFilterDefaults.TabIndex = 31; + this.chkFilterDefaults.Text = "Filter Default Values"; + this.chkFilterDefaults.UseVisualStyleBackColor = true; + this.chkFilterDefaults.CheckedChanged += new System.EventHandler(this.chkFilterDefaults_CheckedChanged); + // + // shaderOptionsListView + // + this.shaderOptionsListView.AllColumns.Add(this.ovlColumn1); + this.shaderOptionsListView.AllColumns.Add(this.ovlColumn2); + this.shaderOptionsListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.shaderOptionsListView.CellEditUseWholeCell = false; + this.shaderOptionsListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.ovlColumn1, + this.ovlColumn2}); + this.shaderOptionsListView.Cursor = System.Windows.Forms.Cursors.Default; + this.shaderOptionsListView.HideSelection = false; + this.shaderOptionsListView.Location = new System.Drawing.Point(3, 32); + this.shaderOptionsListView.Name = "shaderOptionsListView"; + this.shaderOptionsListView.ShowGroups = false; + this.shaderOptionsListView.Size = new System.Drawing.Size(449, 400); + this.shaderOptionsListView.TabIndex = 30; + this.shaderOptionsListView.UseCompatibleStateImageBehavior = false; + this.shaderOptionsListView.View = System.Windows.Forms.View.Details; + this.shaderOptionsListView.SelectedIndexChanged += new System.EventHandler(this.shaderOptionsListView_SelectedIndexChanged); + this.shaderOptionsListView.DoubleClick += new System.EventHandler(this.shaderOptionsListView_DoubleClick); + // + // ovlColumn1 + // + this.ovlColumn1.AspectName = "Name"; + this.ovlColumn1.Text = "Name"; + this.ovlColumn1.Width = 170; + // + // ovlColumn2 + // + this.ovlColumn2.AspectName = "Value"; + this.ovlColumn2.Text = "Value"; + this.ovlColumn2.Width = 385; + // // btnScrolDown // this.btnScrolDown.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); @@ -97,45 +146,11 @@ this.btnAdd.UseVisualStyleBackColor = true; this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click); // - // shaderOptionsListView - // - this.shaderOptionsListView.AllColumns.Add(this.ovlColumn1); - this.shaderOptionsListView.AllColumns.Add(this.ovlColumn2); - this.shaderOptionsListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.shaderOptionsListView.CellEditUseWholeCell = false; - this.shaderOptionsListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.ovlColumn1, - this.ovlColumn2}); - this.shaderOptionsListView.Cursor = System.Windows.Forms.Cursors.Default; - this.shaderOptionsListView.Location = new System.Drawing.Point(3, 32); - this.shaderOptionsListView.Name = "shaderOptionsListView"; - this.shaderOptionsListView.ShowGroups = false; - this.shaderOptionsListView.Size = new System.Drawing.Size(449, 400); - this.shaderOptionsListView.TabIndex = 30; - this.shaderOptionsListView.UseCompatibleStateImageBehavior = false; - this.shaderOptionsListView.View = System.Windows.Forms.View.Details; - this.shaderOptionsListView.SelectedIndexChanged += new System.EventHandler(this.shaderOptionsListView_SelectedIndexChanged); - this.shaderOptionsListView.DoubleClick += new System.EventHandler(this.shaderOptionsListView_DoubleClick); - // - // ovlColumn1 - // - this.ovlColumn1.AspectName = "Name"; - this.ovlColumn1.HeaderForeColor = System.Drawing.Color.Empty; - this.ovlColumn1.Text = "Name"; - this.ovlColumn1.Width = 170; - // - // ovlColumn2 - // - this.ovlColumn2.AspectName = "Value"; - this.ovlColumn2.Text = "Value"; - this.ovlColumn2.Width = 385; - // // ShaderOptionsEditor // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.chkFilterDefaults); this.Controls.Add(this.shaderOptionsListView); this.Controls.Add(this.btnScrolDown); this.Controls.Add(this.btnScrollUp); @@ -146,6 +161,7 @@ this.Size = new System.Drawing.Size(496, 435); ((System.ComponentModel.ISupportInitialize)(this.shaderOptionsListView)).EndInit(); this.ResumeLayout(false); + this.PerformLayout(); } @@ -159,5 +175,6 @@ private Toolbox.Library.Forms.STListView shaderOptionsListView; private BrightIdeasSoftware.OLVColumn ovlColumn1; private BrightIdeasSoftware.OLVColumn ovlColumn2; + private Toolbox.Library.Forms.STCheckBox chkFilterDefaults; } } diff --git a/File_Format_Library/GUI/BFRES/Materials/ShaderAssign/ShaderOptionsEditor.cs b/File_Format_Library/GUI/BFRES/Materials/ShaderAssign/ShaderOptionsEditor.cs index 9f533611..393fa0ed 100644 --- a/File_Format_Library/GUI/BFRES/Materials/ShaderAssign/ShaderOptionsEditor.cs +++ b/File_Format_Library/GUI/BFRES/Materials/ShaderAssign/ShaderOptionsEditor.cs @@ -14,6 +14,8 @@ namespace FirstPlugin.Forms { public partial class ShaderOptionsEditor : UserControl { + private bool FilterDefaults => chkFilterDefaults.Checked; + public ShaderOptionsEditor() { InitializeComponent(); @@ -47,7 +49,12 @@ namespace FirstPlugin.Forms shaderOptionsListView.ForeColor = FormThemes.BaseTheme.FormForeColor; foreach (var option in material.shaderassign.options) + { + if (FilterDefaults && option.Value == "") + continue; + options.Add(new Options() { Name = option.Key, Value = option.Value }); + } shaderOptionsListView.SetObjects(options); options.Clear(); @@ -140,5 +147,10 @@ namespace FirstPlugin.Forms } } } + + private void chkFilterDefaults_CheckedChanged(object sender, EventArgs e) + { + InitializeShaderOptionList(material); + } } } diff --git a/File_Format_Library/GUI/BFRES/Skeleton/FSKLEditor.Designer.cs b/File_Format_Library/GUI/BFRES/Skeleton/FSKLEditor.Designer.cs index e8d27d49..4e9dec36 100644 --- a/File_Format_Library/GUI/BFRES/Skeleton/FSKLEditor.Designer.cs +++ b/File_Format_Library/GUI/BFRES/Skeleton/FSKLEditor.Designer.cs @@ -41,6 +41,7 @@ this.stLabel5 = new Toolbox.Library.Forms.STLabel(); this.stLabel4 = new Toolbox.Library.Forms.STLabel(); this.stLabel3 = new Toolbox.Library.Forms.STLabel(); + this.textBox1 = new System.Windows.Forms.TextBox(); this.stFlowLayoutPanel1.SuspendLayout(); this.stDropDownPanel1.SuspendLayout(); this.stDropDownPanel2.SuspendLayout(); @@ -51,7 +52,10 @@ this.stFlowLayoutPanel1.AutoScroll = true; this.stFlowLayoutPanel1.Controls.Add(this.stDropDownPanel1); this.stFlowLayoutPanel1.Controls.Add(this.stDropDownPanel2); + this.stFlowLayoutPanel1.Controls.Add(this.textBox1); this.stFlowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.stFlowLayoutPanel1.FixedHeight = false; + this.stFlowLayoutPanel1.FixedWidth = true; this.stFlowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; this.stFlowLayoutPanel1.Location = new System.Drawing.Point(0, 0); this.stFlowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); @@ -75,8 +79,8 @@ this.stDropDownPanel1.PanelName = "Skeleton Info"; this.stDropDownPanel1.PanelValueName = ""; this.stDropDownPanel1.SetIcon = null; - this.stDropDownPanel1.SetIconAlphaColor = System.Drawing.Color.Empty; - this.stDropDownPanel1.SetIconColor = System.Drawing.Color.Empty; + this.stDropDownPanel1.SetIconAlphaColor = System.Drawing.Color.White; + this.stDropDownPanel1.SetIconColor = System.Drawing.Color.White; this.stDropDownPanel1.Size = new System.Drawing.Size(434, 108); this.stDropDownPanel1.TabIndex = 0; // @@ -86,6 +90,7 @@ this.scalingModeCB.BorderStyle = System.Windows.Forms.ButtonBorderStyle.Solid; this.scalingModeCB.ButtonColor = System.Drawing.Color.Empty; this.scalingModeCB.FormattingEnabled = true; + this.scalingModeCB.IsReadOnly = false; this.scalingModeCB.Location = new System.Drawing.Point(114, 64); this.scalingModeCB.Name = "scalingModeCB"; this.scalingModeCB.Size = new System.Drawing.Size(172, 21); @@ -107,6 +112,7 @@ this.rotationModeCB.BorderStyle = System.Windows.Forms.ButtonBorderStyle.Solid; this.rotationModeCB.ButtonColor = System.Drawing.Color.Empty; this.rotationModeCB.FormattingEnabled = true; + this.rotationModeCB.IsReadOnly = false; this.rotationModeCB.Location = new System.Drawing.Point(114, 37); this.rotationModeCB.Name = "rotationModeCB"; this.rotationModeCB.Size = new System.Drawing.Size(172, 21); @@ -139,8 +145,8 @@ this.stDropDownPanel2.PanelName = "Matricies"; this.stDropDownPanel2.PanelValueName = ""; this.stDropDownPanel2.SetIcon = null; - this.stDropDownPanel2.SetIconAlphaColor = System.Drawing.Color.Empty; - this.stDropDownPanel2.SetIconColor = System.Drawing.Color.Empty; + this.stDropDownPanel2.SetIconAlphaColor = System.Drawing.Color.White; + this.stDropDownPanel2.SetIconColor = System.Drawing.Color.White; this.stDropDownPanel2.Size = new System.Drawing.Size(434, 182); this.stDropDownPanel2.TabIndex = 5; // @@ -200,6 +206,19 @@ this.stLabel3.TabIndex = 5; this.stLabel3.Text = "Smooth Matrix Indices"; // + // textBox1 + // + this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.textBox1.Location = new System.Drawing.Point(3, 293); + this.textBox1.Multiline = true; + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(428, 332); + this.textBox1.TabIndex = 13; + this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged); + // // FSKLEditor // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -209,6 +228,7 @@ this.Name = "FSKLEditor"; this.Size = new System.Drawing.Size(434, 628); this.stFlowLayoutPanel1.ResumeLayout(false); + this.stFlowLayoutPanel1.PerformLayout(); this.stDropDownPanel1.ResumeLayout(false); this.stDropDownPanel1.PerformLayout(); this.stDropDownPanel2.ResumeLayout(false); @@ -232,5 +252,6 @@ private Toolbox.Library.Forms.STLabel stLabel5; private Toolbox.Library.Forms.STLabel stLabel4; private Toolbox.Library.Forms.STLabel stLabel3; + private System.Windows.Forms.TextBox textBox1; } } diff --git a/File_Format_Library/GUI/BFRES/Skeleton/FSKLEditor.cs b/File_Format_Library/GUI/BFRES/Skeleton/FSKLEditor.cs index 1b2044df..851d8337 100644 --- a/File_Format_Library/GUI/BFRES/Skeleton/FSKLEditor.cs +++ b/File_Format_Library/GUI/BFRES/Skeleton/FSKLEditor.cs @@ -23,6 +23,9 @@ namespace FirstPlugin.Forms BackColor = FormThemes.BaseTheme.FormBackColor; ForeColor = FormThemes.BaseTheme.FormForeColor; + + textBox1.BackColor = FormThemes.BaseTheme.ListViewBackColor; + textBox1.ForeColor = FormThemes.BaseTheme.FormForeColor; } public FSKL activeSkeleton; @@ -61,6 +64,12 @@ namespace FirstPlugin.Forms scalingModeCB.SelectedItem = fskl.node.Skeleton.FlagsScaling; } + if (fskl.node.Skeleton != null && fskl.node.Skeleton.userIndices != null) + { + var indices = string.Join(",", fskl.node.Skeleton.userIndices); + this.textBox1.Text = indices; + } + IsLoaded = true; } @@ -129,5 +138,23 @@ namespace FirstPlugin.Forms } LibraryGUI.UpdateViewport(); } + + private void textBox1_TextChanged(object sender, EventArgs e) + { + if (activeSkeleton.node.Skeleton != null) + { + List indices = new List(); + + foreach (var line in textBox1.Text.Split(',')) + { + if (string.IsNullOrEmpty(line)) + continue; + + if (ushort.TryParse(line, out ushort id)) + indices.Add(id); + } + activeSkeleton.node.Skeleton.userIndices = indices.ToArray(); + } + } } } diff --git a/File_Format_Library/GUI/TextureUI/Importers/BNTX/TextureImporterSettings.cs b/File_Format_Library/GUI/TextureUI/Importers/BNTX/TextureImporterSettings.cs index 752d65c2..d090ea39 100644 --- a/File_Format_Library/GUI/TextureUI/Importers/BNTX/TextureImporterSettings.cs +++ b/File_Format_Library/GUI/TextureUI/Importers/BNTX/TextureImporterSettings.cs @@ -22,6 +22,8 @@ namespace FirstPlugin { } + public bool CombineMipLevel = true; + public int Alignment = 512; public bool GammaFix = false; public string TexName; public AccessFlags AccessFlags = AccessFlags.Texture; @@ -279,17 +281,20 @@ namespace FirstPlugin for (int i = 0; i < arrayFaces.Count; i++) { - List mipmaps = SwizzleSurfaceMipMaps(tex, arrayFaces[i], tex.MipCount); + List mipmaps = SwizzleSurfaceMipMaps(tex, arrayFaces[i], tex.MipCount, settings.Alignment); tex.TextureData.Add(mipmaps); //Combine mip map data - byte[] combinedMips = Utils.CombineByteArray(mipmaps.ToArray()); - tex.TextureData[i][0] = combinedMips; + if (settings.Alignment != 1) + { + byte[] combinedMips = Utils.CombineByteArray(mipmaps.ToArray()); + tex.TextureData[i][0] = combinedMips; + } } return tex; } - public static List SwizzleSurfaceMipMaps(Texture tex, byte[] data, uint MipCount) + public static List SwizzleSurfaceMipMaps(Texture tex, byte[] data, uint MipCount, int alignment = 512) { var TexFormat = TextureData.ConvertFormat(tex.Format); @@ -319,7 +324,7 @@ namespace FirstPlugin { blockHeight = TegraX1Swizzle.GetBlockHeight(DIV_ROUND_UP(tex.Height, blkHeight)); tex.BlockHeightLog2 = (uint)Convert.ToString(blockHeight, 2).Length - 1; - tex.Alignment = 512; + tex.Alignment = alignment; tex.ReadTextureLayout = 1; linesPerBlockHeight = blockHeight * 8; @@ -346,6 +351,9 @@ namespace FirstPlugin byte[] AlignedData = new byte[(TegraX1Swizzle.round_up(SurfaceSize, (uint)tex.Alignment) - SurfaceSize)]; + if (tex.Alignment == 1) + AlignedData = new byte[0]; + SurfaceSize += (uint)AlignedData.Length; // Console.WriteLine("SurfaceSize Aligned " + AlignedData); @@ -372,8 +380,10 @@ namespace FirstPlugin SurfaceSize += Pitch * TegraX1Swizzle.round_up(height__, Math.Max(1, blockHeight >> blockHeightShift) * 8); } - byte[] SwizzledData = TegraX1Swizzle.swizzle(width_, height_, depth_, blkWidth, blkHeight, blkDepth, target, bpp, (uint)tex.TileMode, (int)Math.Max(0, tex.BlockHeightLog2 - blockHeightShift), data_); + byte[] SwizzledData = TegraX1Swizzle.swizzle(width_, height_, depth_, blkWidth, blkHeight, blkDepth, target, bpp, (uint)tex.TileMode, (int)Math.Max(0, tex.BlockHeightLog2 - blockHeightShift), data_, size); mipmaps.Add(AlignedData.Concat(SwizzledData).ToArray()); + + Console.WriteLine("SwizzledData " + SwizzledData.Length); } tex.ImageSize = SurfaceSize; diff --git a/File_Format_Library/Main.cs b/File_Format_Library/Main.cs index fa1e8619..25bb6a86 100644 --- a/File_Format_Library/Main.cs +++ b/File_Format_Library/Main.cs @@ -462,7 +462,9 @@ namespace FirstPlugin Formats.Add(typeof(NKN)); Formats.Add(typeof(MetroidDreadLibrary.BSMAT)); Formats.Add(typeof(TRANM)); - + Formats.Add(typeof(GFA)); + Formats.Add(typeof(TXTG)); + //Formats.Add(typeof(XLINK_FILE)); // Formats.Add(typeof(MPBIN)); @@ -478,7 +480,6 @@ namespace FirstPlugin if (Runtime.DEVELOPER_DEBUG_MODE) { Formats.Add(typeof(BFSAR)); - Formats.Add(typeof(GFA)); } diff --git a/Switch_Toolbox_Library/Animations/Animation.cs b/Switch_Toolbox_Library/Animations/Animation.cs index 2ac97912..e3e62c1e 100644 --- a/Switch_Toolbox_Library/Animations/Animation.cs +++ b/Switch_Toolbox_Library/Animations/Animation.cs @@ -299,46 +299,56 @@ namespace Toolbox.Library.Animations return false; } - - int LastFound = 0; - float LastFrame; - public float GetValue(float frame) + private float GetWrapFrame(float frame) { - if (Keys.Count == 0) - return 0; + var lastFrame = Keys.Last().Frame; + if (frame < 0 || lastFrame < 0) + return frame; - float startFrame = Keys.First().Frame; + return frame; + } + public virtual float GetValue(float frame, float startFrame = 0) + { + if (Keys.Count == 0) return 0; + if (Keys.Count == 1) return Keys[0].Value; KeyFrame LK = Keys.First(); KeyFrame RK = Keys.Last(); + float Frame = GetWrapFrame(frame - startFrame); foreach (KeyFrame keyFrame in Keys) { - if (keyFrame.Frame <= frame) LK = keyFrame; - if (keyFrame.Frame >= frame && keyFrame.Frame < RK.Frame) RK = keyFrame; + if (keyFrame.Frame <= Frame) LK = keyFrame; + if (keyFrame.Frame >= Frame && keyFrame.Frame < RK.Frame) RK = keyFrame; } + if (LK == RK) + return LK.Value; - if (LK.Frame != RK.Frame) + return GetInterpolatedValue(Frame, LK, RK); + } + + private float GetInterpolatedValue(float Frame, KeyFrame LK, KeyFrame RK) + { + float FrameDiff = Frame - LK.Frame; + float Weight = FrameDiff / (RK.Frame - LK.Frame); + + switch (InterpolationType) { - // float FrameDiff = frame - LK.Frame; - // float Weight = 1.0f / (RK.Frame - LK.Frame); - // float Weight = FrameDiff / (RK.Frame - LK.Frame); + case InterpolationType.CONSTANT: return LK.Value; + case InterpolationType.STEP: return LK.Value; + case InterpolationType.LINEAR: return InterpolationHelper.Lerp(LK.Value, RK.Value, Weight); + case InterpolationType.HERMITE: + float length = RK.Frame - LK.Frame; - float FrameDiff = frame - LK.Frame; - float Weight = FrameDiff / (RK.Frame - LK.Frame); - - Console.WriteLine($"frame diff {FrameDiff} frame {frame} LK {LK.Frame} RK {RK} ratio {Weight}"); - - switch (InterpolationType) - { - case InterpolationType.CONSTANT: return LK.Value; - case InterpolationType.STEP: return LK.Value; - case InterpolationType.LINEAR: return InterpolationHelper.Lerp(LK.Value, RK.Value, Weight); - case InterpolationType.HERMITE: - float val = Hermite(frame, LK.Frame, RK.Frame, LK.In, LK.Out != -1 ? LK.Out : RK.In, LK.Value, RK.Value); - return val; - } + return InterpolationHelper.HermiteInterpolate(Frame, + LK.Frame, + RK.Frame, + LK.Value, + RK.Value, + LK.Out * length, + RK.In * length); } + return LK.Value; } @@ -508,7 +518,7 @@ namespace Toolbox.Library.Animations float x = node.XROT.HasAnimation() ? node.XROT.GetValue(Frame) : b.EulerRotation.X; float y = node.YROT.HasAnimation() ? node.YROT.GetValue(Frame) : b.EulerRotation.Y; float z = node.ZROT.HasAnimation() ? node.ZROT.GetValue(Frame) : b.EulerRotation.Z; - b.rot = EulerToQuat(z, y, x); + b.rot = STMath.FromEulerAngles(new Vector3(x, y, z)); } } } @@ -558,16 +568,37 @@ namespace Toolbox.Library.Animations // return (((cf0 * t + cf1) * t + cf2) * t + cf3); } - public static float Hermite(float frame, float frame1, float frame2, float outSlope, float inSlope, float val1, float val2) + public static float HermiteInterpolate(float frame, float frame1, float frame2, + float inSlope, float outSlope, float p0, float p1) { - if (frame == frame1) return val1; - if (frame == frame2) return val2; + if (frame == frame1) return p0; + if (frame == frame2) return p1; - float distance = frame - frame1; - float invDuration = 1f / (frame2 - frame1); - float t = distance * invDuration; - float t1 = t - 1f; - return (val1 + ((((val1 - val2) * ((2f * t) - 3f)) * t) * t)) + ((distance * t1) * ((t1 * outSlope) + (t * inSlope))); + float t = (frame - frame1) / (frame2 - frame1); + return GetPointHermite(p0, p1, outSlope, inSlope, t); + } + + private static float GetPointHermite(float p0, float p1, float s0, float s1, float t) + { + float cf0 = (p0 * 2) + (p1 * -2) + (s0 * 1) + (s1 * 1); + float cf1 = (p0 * -3) + (p1 * 3) + (s0 * -2) + (s1 * -1); + float cf2 = (p0 * 0) + (p1 * 0) + (s0 * 1) + (s1 * 0); + float cf3 = (p0 * 1) + (p1 * 0) + (s0 * 0) + (s1 * 0); + return GetPointCubic(cf0, cf1, cf2, cf3, t); + } + + private static float GetPointBezier(float p0, float p1, float p2, float p3, float t) + { + float cf0 = (p0 * -1) + (p1 * 3) + (p2 * -3) + (p3 * 1); + float cf1 = (p0 * 3) + (p1 * -6) + (p2 * 3) + (p3 * 0); + float cf2 = (p0 * -3) + (p1 * 3) + (p2 * 0) + (p3 * 0); + float cf3 = (p0 * 1) + (p1 * 0) + (p2 * 0) + (p3 * 0); + return GetPointCubic(cf0, cf1, cf2, cf3, t); + } + + private static float GetPointCubic(float cf0, float cf1, float cf2, float cf3, float t) + { + return (((cf0 * t + cf1) * t + cf2) * t + cf3); } public static float Lerp(float av, float bv, float v0, float v1, float t) diff --git a/Switch_Toolbox_Library/Animations/AnimationRewrite/InterpolationHelper.cs b/Switch_Toolbox_Library/Animations/AnimationRewrite/InterpolationHelper.cs index e3b20ccf..cfc09784 100644 --- a/Switch_Toolbox_Library/Animations/AnimationRewrite/InterpolationHelper.cs +++ b/Switch_Toolbox_Library/Animations/AnimationRewrite/InterpolationHelper.cs @@ -23,27 +23,40 @@ namespace Toolbox.Library.Animations return Result; } - public static float BezierInterpolate(float frame, float frame1, float frame2, - float inSlope, float outSlope, float p0, float p1) + public static float BezierInterpolate(float frame, float FrameL, float frameR, + float inSlope, float outSlope, float p0, float p1) { - if (frame == frame1) return p0; - if (frame == frame2) return p1; + if (frame == FrameL) return p0; + if (frame == frameR) return p1; - float t = (frame - frame1) / (frame2 - frame1); - return GetPointBezier(p0, p1, outSlope, inSlope, t); + float t = (frame - FrameL) / (frameR - FrameL); + return GetPointBezier(p0, p1, inSlope, outSlope, t); + } + + public static float CubicHermiteInterpolate(float frame, float FrameL, float frameR, + float cf0, float cf1, float cf2, float cf3) + { + float t = (frame - FrameL) / (frameR - FrameL); + return GetPointCubic(cf3, cf2, cf1, cf0, t); + } + + private static float GetPointCubic(float cf0, float cf1, float cf2, float cf3, float t) + { + return (((cf0 * t + cf1) * t + cf2) * t + cf3); } public static float HermiteInterpolate(float frame, float frame1, float frame2, - float inSlope, float outSlope, float p0, float p1) + float p0, float p1, float s0, float s1) { if (frame == frame1) return p0; if (frame == frame2) return p1; float t = (frame - frame1) / (frame2 - frame1); - return GetPointHermite(p0, p1, outSlope, inSlope, t); + return GetPointHermite(p0, p1, s0, s1, t); } - private static float GetPointHermite(float p0, float p1, float s0, float s1, float t) { + private static float GetPointHermite(float p0, float p1, float s0, float s1, float t) + { float cf0 = (p0 * 2) + (p1 * -2) + (s0 * 1) + (s1 * 1); float cf1 = (p0 * -3) + (p1 * 3) + (s0 * -2) + (s1 * -1); float cf2 = (p0 * 0) + (p1 * 0) + (s0 * 1) + (s1 * 0); @@ -51,7 +64,8 @@ namespace Toolbox.Library.Animations return GetPointCubic(cf0, cf1, cf2, cf3, t); } - private static float GetPointBezier(float p0, float p1, float p2, float p3, float t) { + private static float GetPointBezier(float p0, float p1, float p2, float p3, float t) + { float cf0 = (p0 * -1) + (p1 * 3) + (p2 * -3) + (p3 * 1); float cf1 = (p0 * 3) + (p1 * -6) + (p2 * 3) + (p3 * 0); float cf2 = (p0 * -3) + (p1 * 3) + (p2 * 0) + (p3 * 0); @@ -59,11 +73,8 @@ namespace Toolbox.Library.Animations return GetPointCubic(cf0, cf1, cf2, cf3, t); } - private static float GetPointCubic(float cf0, float cf1, float cf2, float cf3, float t) { - return (((cf0 * t + cf1) * t + cf2) * t + cf3); - } - - public static float[] CalculateCubicCoef(float frameA, float frameB, float valueA, float valueB, float inSlope, float outSlope) { + public static float[] CalculateCubicCoef(float frameA, float frameB, float valueA, float valueB, float inSlope, float outSlope) + { return CalculateCubicCoef(frameB - frameA, valueA, valueB, inSlope, outSlope); } diff --git a/Switch_Toolbox_Library/Compression/Formats/Zstb.cs b/Switch_Toolbox_Library/Compression/Formats/Zstb.cs index c5f2ec4c..74c8a477 100644 --- a/Switch_Toolbox_Library/Compression/Formats/Zstb.cs +++ b/Switch_Toolbox_Library/Compression/Formats/Zstb.cs @@ -70,9 +70,9 @@ namespace Toolbox.Library return decompressor.Unwrap(b, MaxDecompressedSize); } } - public static byte[] SCompress(byte[] b) + public static byte[] SCompress(byte[] b, int level = 5) { - using (var compressor = new ZstdNet.Compressor()) + using (var compressor = new ZstdNet.Compressor(new ZstdNet.CompressionOptions(level))) { return compressor.Wrap(b); } diff --git a/Switch_Toolbox_Library/FileFormats/Animation/ANIM.cs b/Switch_Toolbox_Library/FileFormats/Animation/ANIM.cs index 987fb5f3..4369d7df 100644 --- a/Switch_Toolbox_Library/FileFormats/Animation/ANIM.cs +++ b/Switch_Toolbox_Library/FileFormats/Animation/ANIM.cs @@ -69,7 +69,7 @@ namespace Toolbox.Library.Animations } } - return Animation.Hermite (frame+1, f1.input, f2.input, weighted ? f1.t1 : 0, weighted ? f2.t1 : 0, f1.output, f2.output); + return Animation.HermiteInterpolate (frame+1, f1.input, f2.input, weighted ? f1.t1 : 0, weighted ? f2.t1 : 0, f1.output, f2.output); } } diff --git a/Switch_Toolbox_Library/Maths/Math.cs b/Switch_Toolbox_Library/Maths/STMath.cs similarity index 54% rename from Switch_Toolbox_Library/Maths/Math.cs rename to Switch_Toolbox_Library/Maths/STMath.cs index 916161dc..aa27ba98 100644 --- a/Switch_Toolbox_Library/Maths/Math.cs +++ b/Switch_Toolbox_Library/Maths/STMath.cs @@ -9,6 +9,9 @@ namespace Toolbox.Library { public static class STMath { + public const float Deg2Rad = (float)System.Math.PI / 180.0f; + public const float Rad2Deg = 180.0f / (float)System.Math.PI; + private const long SizeOfKb = 1024; private const long SizeOfMb = SizeOfKb * 1024; private const long SizeOfGb = SizeOfMb * 1024; @@ -40,11 +43,13 @@ namespace Toolbox.Library //From https://github.com/Ploaj/SSBHLib/blob/e37b0d83cd088090f7802be19b1d05ec998f2b6a/CrossMod/Tools/CrossMath.cs#L42 //Seems to give good results - public static Vector3 ToEulerAngles(double X, double Y, double Z, double W) { + public static Vector3 ToEulerAngles(double X, double Y, double Z, double W) + { return ToEulerAngles(new Quaternion((float)X, (float)Y, (float)Z, (float)W)); } - public static Vector3 ToEulerAngles(float X, float Y, float Z, float W) { + public static Vector3 ToEulerAngles(float X, float Y, float Z, float W) + { return ToEulerAngles(new Quaternion(X, Y, Z, W)); } @@ -80,6 +85,70 @@ namespace Toolbox.Library return q; } + public static Matrix4 RotationFromTo(Vector3 start, Vector3 end) + { + var axis = Vector3.Cross(start, end).Normalized(); + var angle = (float)Math.Acos(Vector3.Dot(start, end)); + return Matrix4.CreateFromAxisAngle(axis, angle); + } + + public static Quaternion QuatRotationFromTo(Vector3 start, Vector3 end) + { + var axis = Vector3.Cross(start, end).Normalized(); + var angle = (float)Math.Acos(Vector3.Dot(start, end)); + return Quaternion.FromAxisAngle(axis, angle); + } + + public static Vector3 GetEulerAngle(Matrix4 m) + { + float pitch, yaw, roll; // 3 angles + yaw = Rad2Deg * (float)Math.Asin(GetValue(m, 8)); + if (GetValue(m, 10) < 0) + { + if (yaw >= 0) yaw = 180.0f - yaw; + else yaw = -180.0f - yaw; + } + + // find roll (around z-axis) and pitch (around x-axis) + // if forward vector is (1,0,0) or (-1,0,0), then m[0]=m[4]=m[9]=m[10]=0 + if (m.M11 > -double.Epsilon && m.M11 < double.Epsilon) + { + roll = 0; //@@ assume roll=0 + pitch = Rad2Deg * (float)Math.Atan2(GetValue(m, 1), GetValue(m, 5)); + } + else + { + roll = Rad2Deg * (float)Math.Atan2(-GetValue(m, 4), GetValue(m, 0)); + pitch = Rad2Deg * (float)Math.Atan2(-GetValue(m, 9), GetValue(m, 10)); + } + return new Vector3(pitch, yaw, roll) * Deg2Rad; + } + + static float GetValue(Matrix4 mat, int index) + { + switch (index) + { + case 0: return mat.M11; + case 1: return mat.M12; + case 2: return mat.M13; + case 3: return mat.M14; + case 4: return mat.M21; + case 5: return mat.M22; + case 6: return mat.M23; + case 7: return mat.M24; + case 8: return mat.M31; + case 9: return mat.M32; + case 10: return mat.M33; + case 11: return mat.M34; + case 12: return mat.M41; + case 13: return mat.M42; + case 14: return mat.M43; + case 15: return mat.M44; + default: + throw new Exception("Invalid index for 4x4 matrix!"); + } + } + public static float Clamp(float v, float min, float max) { if (v < min) return min; diff --git a/Switch_Toolbox_Library/Texture Decoding/Switch/TegraX1Swizzle.cs b/Switch_Toolbox_Library/Texture Decoding/Switch/TegraX1Swizzle.cs index 6a04f64f..f885940e 100644 --- a/Switch_Toolbox_Library/Texture Decoding/Switch/TegraX1Swizzle.cs +++ b/Switch_Toolbox_Library/Texture Decoding/Switch/TegraX1Swizzle.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; +using System.Windows.Media; namespace Toolbox.Library { @@ -104,6 +105,37 @@ namespace Toolbox.Library return GetImageData(texture, ImageData, ArrayLevel, MipLevel, DepthLevel, BlockHeightLog2, target, LinearTileMode); } + public static byte[] GetDirectImageData(STGenericTexture texture, byte[] ImageData, int mipLevel, int target = 1, bool LinearTileMode = false) + { + uint blkWidth = STGenericTexture.GetBlockWidth(texture.Format); + uint blkHeight = STGenericTexture.GetBlockHeight(texture.Format); + uint blkDepth = STGenericTexture.GetBlockDepth(texture.Format); + var blockHeightMip0 = GetBlockHeight(DIV_ROUND_UP(texture.Height, blkHeight)); + uint bpp = STGenericTexture.GetBytesPerPixel(texture.Format); + uint TileMode = LinearTileMode ? 1u : 0u; + + uint width = Math.Max(1, texture.Width >> mipLevel); + uint height = Math.Max(1, texture.Height >> mipLevel); + uint depth = Math.Max(1, texture.Depth >> mipLevel); + uint heightInBlocks = DIV_ROUND_UP(height, blkHeight); + // tegra_swizzle only allows block heights supported by the TRM (1,2,4,8,16,32). + var mipBlockHeightLog2 = (int)Math.Log(GetMipBlockHeight(heightInBlocks, blockHeightMip0), 2); + + try + { + byte[] result = deswizzle(width, height, depth, blkWidth, blkHeight, blkDepth, target, bpp, TileMode, mipBlockHeightLog2, ImageData); + return result; + } + catch (Exception e) + { + System.Windows.Forms.MessageBox.Show($"Failed to swizzle texture {texture.Text}!"); + Console.WriteLine(e); + + return new byte[0]; + } + } + + public static byte[] GetImageData(STGenericTexture texture, byte[] ImageData, int ArrayLevel, int MipLevel, int DepthLevel, uint BlockHeightLog2, int target = 1, bool LinearTileMode = false) { uint bpp = STGenericTexture.GetBytesPerPixel(texture.Format); @@ -179,7 +211,7 @@ namespace Toolbox.Library } private static unsafe byte[] SwizzleDeswizzleBlockLinear(uint width, uint height, uint depth, uint blkWidth, uint blkHeight, uint blkDepth, - uint bpp, int blockHeightLog2, byte[] data, bool deswizzle) + uint bpp, int blockHeightLog2, byte[] data, bool deswizzle, uint size, uint alignment = 512) { // This function expects the surface dimensions in blocks rather than pixels for block compressed formats. // This ensures the bytes per pixel parameter is used correctly. @@ -245,17 +277,17 @@ namespace Toolbox.Library public static byte[] deswizzle(uint width, uint height, uint depth, uint blkWidth, uint blkHeight, uint blkDepth, int roundPitch, uint bpp, uint tileMode, int blockHeightLog2, byte[] data) { if (tileMode == 1) - return SwizzlePitchLinear(width, height, depth, blkWidth, blkHeight, blkDepth, roundPitch, bpp, blockHeightLog2, data, true); + return SwizzlePitchLinear(width, height, depth, blkWidth, blkHeight, blkDepth, roundPitch, bpp, blockHeightLog2, data, true, 0); else - return SwizzleDeswizzleBlockLinear(width, height, depth, blkWidth, blkHeight, blkDepth, bpp, blockHeightLog2, data, true); + return SwizzleDeswizzleBlockLinear(width, height, depth, blkWidth, blkHeight, blkDepth, bpp, blockHeightLog2, data, true, 0); } - public static byte[] swizzle(uint width, uint height, uint depth, uint blkWidth, uint blkHeight, uint blkDepth, int roundPitch, uint bpp, uint tileMode, int blockHeightLog2, byte[] data) + public static byte[] swizzle(uint width, uint height, uint depth, uint blkWidth, uint blkHeight, uint blkDepth, int roundPitch, uint bpp, uint tileMode, int blockHeightLog2, byte[] data, uint size) { if (tileMode == 1) - return SwizzlePitchLinear(width, height, depth, blkWidth, blkHeight, blkDepth, roundPitch, bpp, blockHeightLog2, data, false); + return SwizzlePitchLinear(width, height, depth, blkWidth, blkHeight, blkDepth, roundPitch, bpp, blockHeightLog2, data, false, size); else - return SwizzleDeswizzleBlockLinear(width, height, depth, blkWidth, blkHeight, blkDepth, bpp, blockHeightLog2, data, false); + return SwizzleDeswizzleBlockLinear(width, height, depth, blkWidth, blkHeight, blkDepth, bpp, blockHeightLog2, data, false, size); } @@ -283,7 +315,7 @@ namespace Toolbox.Library return x + 1; } - private static byte[] SwizzlePitchLinear(uint width, uint height, uint depth, uint blkWidth, uint blkHeight, uint blkDepth, int roundPitch, uint bpp, int blockHeightLog2, byte[] data, bool deswizzle) + private static byte[] SwizzlePitchLinear(uint width, uint height, uint depth, uint blkWidth, uint blkHeight, uint blkDepth, int roundPitch, uint bpp, int blockHeightLog2, byte[] data, bool deswizzle, uint size) { // TODO: Investigate doing this more efficiently in Rust. width = DIV_ROUND_UP(width, blkWidth); diff --git a/Switch_Toolbox_Library/Toolbox_Library.csproj b/Switch_Toolbox_Library/Toolbox_Library.csproj index 9fcb0979..93c4a470 100644 --- a/Switch_Toolbox_Library/Toolbox_Library.csproj +++ b/Switch_Toolbox_Library/Toolbox_Library.csproj @@ -439,6 +439,7 @@ + @@ -872,7 +873,6 @@ - UserControl @@ -965,6 +965,7 @@ + diff --git a/Switch_Toolbox_Library/Util/WebUtil.cs b/Switch_Toolbox_Library/Util/WebUtil.cs new file mode 100644 index 00000000..84030a55 --- /dev/null +++ b/Switch_Toolbox_Library/Util/WebUtil.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using System.Diagnostics; + +namespace Toolbox.Library +{ + public class WebUtil + { + public static void OpenDonation() { + OpenURLEncoded("aHR0cHM6Ly9rby1maS5jb20vc2ltcGx5a3hn"); + } + + public static void OpenURLEncoded(string encodedString) + { + byte[] data = Convert.FromBase64String(encodedString); + OpenURL(Encoding.UTF8.GetString(data)); + } + + public static void OpenURL(string url) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { + Process.Start(new ProcessStartInfo(url) { UseShellExecute = true }); // Works ok on windows + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { + Process.Start("xdg-open", url); // Works ok on linux + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { + Process.Start("open", url); // Not tested + } + } + } +} diff --git a/Toolbox/Lib/Syroot.NintenTools.NSW.Bfres.dll b/Toolbox/Lib/Syroot.NintenTools.NSW.Bfres.dll index 26b6a05b..83950b45 100644 Binary files a/Toolbox/Lib/Syroot.NintenTools.NSW.Bfres.dll and b/Toolbox/Lib/Syroot.NintenTools.NSW.Bfres.dll differ diff --git a/Toolbox/Lib/Syroot.NintenTools.NSW.Bfres.xml b/Toolbox/Lib/Syroot.NintenTools.NSW.Bfres.xml index c5634109..3755baae 100644 --- a/Toolbox/Lib/Syroot.NintenTools.NSW.Bfres.xml +++ b/Toolbox/Lib/Syroot.NintenTools.NSW.Bfres.xml @@ -2013,7 +2013,7 @@ - Reads BFRES offsets which is the absolute addresses. + Reads BFRES offsets which is the absolute addresses.+ The number of offsets to read. The absolute addresses of the offsets. @@ -2275,7 +2275,7 @@ The name to save. The in which the name will be stored. - + Reserves space for offsets to the written later in the string pool with the specified @@ -3160,6 +3160,11 @@ Gets or sets the instance applied on the to color their surface. + + + + + Gets or sets customly attached names. @@ -3713,7 +3718,7 @@ rigidbodies (no skinning), 1 equal rigid skinning and 2 or more smooth skinning. - + Gets the number of vertices stored by the . It is calculated from the size of the first in bytes divided by the . @@ -4850,6 +4855,16 @@ Gets or sets instances animating properties of objects stored in this section. + + + Gets or sets customly attached names. + + + + + Gets or sets customly attached instances. + + Gets or sets initial transformation values. Only stores specific transformations according to @@ -5173,6 +5188,12 @@ Euler XYZ, 3 components. + + + A cache of strings that are saved through raw IDs in place of the pointer field of a name offset. + This is used and required for TOTK models. + + Represents an FVIS subfile in a , storing visibility animations of or diff --git a/Toolbox/Lib/Syroot.NintenTools.NSW.Bntx.dll b/Toolbox/Lib/Syroot.NintenTools.NSW.Bntx.dll index ece95dd3..fff43554 100644 Binary files a/Toolbox/Lib/Syroot.NintenTools.NSW.Bntx.dll and b/Toolbox/Lib/Syroot.NintenTools.NSW.Bntx.dll differ diff --git a/Toolbox/Lib/Syroot.NintenTools.NSW.Bntx.xml b/Toolbox/Lib/Syroot.NintenTools.NSW.Bntx.xml index 3d068b84..8d8976e0 100644 --- a/Toolbox/Lib/Syroot.NintenTools.NSW.Bntx.xml +++ b/Toolbox/Lib/Syroot.NintenTools.NSW.Bntx.xml @@ -117,623 +117,6 @@ The name of the file to save the contents into. - - - Represents a 16-bit fixed-point decimal consisting of 1 sign bit, 10 integer bits and 5 fractional bits (denoted - as Q10.5). Note that the implementation is not reporting over- and underflowing errors. - - - Examples: - SIIIIIII_IIIFFFFF - 0b00000000_00010000 = 0.5 - 0b00000000_00100000 = 1 - 0b00000001_00000000 = 8 - 0b01000000_00000000 = 512 - 0b10000000_00000000 = -1024 - - - - - Represents the largest possible value of . - - - - - Represents the smallest possible value of . - - - - - Initializes a new instance of the struct from the given - representation. - - The raw representation of the internally stored bits. - - - - Gets the internally stored value to represent the instance. - - Signed to get arithmetic rather than logical shifts. - - - - Returns the given . - - The . - The result. - - - - Adds the first to the second one. - - The first . - The second . - The addition result. - - - - Negates the given . - - The to negate. - The negated result. - - - - Subtracts the first from the second one. - - The first . - The second . - The subtraction result. - - - - Multiplicates the given by the scalar. - - The . - The scalar. - The multiplication result. - - - - Multiplicates the first by the second one. - - The first . - The second . - The multiplication result. - - - - Divides the given through the scalar. - - The . - The scalar. - The division result. - - - - Divides the first through the second one. - - The first . - The second . - The division result. - - - - Gets a value indicating whether the first specified is the same as the second - specified . - - The first to compare. - The second to compare. - true, if both are the same. - - - - Gets a value indicating whether the first specified is not the same as the second - specified . - - The first to compare. - The second to compare. - true, if both are not the same. - - - - Converts the given value to a instance. - - The value to represent in the new - instance. - - - - Converts the given value to a instance. - - The value to represent in the new - instance. - - - - Converts the given value to a instance. - - The value to represent in the new - instance. - - - - Converts the given value to a instance. - - The value to represent in the new - instance. - - - - Converts the given value to a instance. - - The value to represent in the new - instance. - - - - Converts the given value to a instance. - - The value to represent in the new - instance. - - - - Gets a value indicating whether this is the same as the second specified - . - - The object to compare, if it is a . - true, if both are the same. - - - - Gets a hash code as an indication for object equality. - - The hash code. - - - - Gets a string describing this . - - A string describing this . - - - - Indicates whether the current is equal to another . - - A to compare with this . - true if the current is equal to the other parameter; otherwise, false. - - - - - Represents a 4-byte value which can hold differently typed data. - - - - - The data as an . - - - - - The data as a . - - - - - The data as an . - - - - - Converts the given value to a instance. - - The value to represent in the new instance. - - - - - Converts the given value to a instance. - - The value to represent in the new instance. - - - - - Converts the given value to a instance. - - The value to represent in the new instance. - - - - - Converts the given value to an instance. - - The value to represent in the new instance. - - - - - Converts the given value to a instance. - - The value to represent in the new instance. - - - - - Converts the given value to an instance. - - The value to represent in the new instance. - - - - - Returns the for this instance. - - The enumerated constant that is the of the class or value type that - implements this interface. - - - - This operation is not supported. - - - - - This operation is not supported. - - - - - This operation is not supported. - - - - - This operation is not supported. - - - - - This operation is not supported. - - - - - Converts the value of this instance to an equivalent double-precision floating-point number using the - specified culture-specific formatting information. - - An interface implementation that supplies - culture-specific formatting information. - A double-precision floating-point number equivalent to the value of this instance. - - - - This operation is not supported. - - - - - Converts the value of this instance to an equivalent 32-bit signed integer using the specified - culture-specific formatting information. - - An interface implementation that supplies - culture-specific formatting information. - An 32-bit signed integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 64-bit signed integer using the specified - culture-specific formatting information. - - An interface implementation that supplies - culture-specific formatting information. - An 64-bit signed integer equivalent to the value of this instance. - - - - This operation is not supported. - - - - - Converts the value of this instance to an equivalent single-precision floating-point number using the - specified culture-specific formatting information. - - An interface implementation that supplies - culture-specific formatting information. - A single-precision floating-point number equivalent to the value of this instance. - - - - This operation is not supported. - - - - - Converts the value of this instance to an of the specified that has - an equivalent value, using the specified culture-specific formatting information. - - The to which the value of this instance is converted. - - An interface implementation that supplies - culture-specific formatting information. - An instance of type conversionType whose value is equivalent to the value of - this instance. - - - - This operation is not supported. - - - - - This operation is not supported. - - - - - This operation is not supported. - - - - - Represents a 16-bit half-precision floating point value according to the IEEE 754 standard. - - - Examples: - SEEEEEFF_FFFFFFFF - 0b00000000_00000000 = 0 - 1b00000000_00000000 = -0 - 0b00111100_00000000 = 1 - 0b11000000_00000000 = -2 - 0b11111011_11111111 = 65504 (MaxValue) - 0b01111100_00000000 = PositiveInfinity - 0b11111100_00000000 = NegativeInfinity - - - - - Represents the smallest positive value greater than zero. - - - - - Represents the largest possible value of . - - - - - Represents the smallest possible value of . - - - - - Represents not a number (NaN). - - - - - Represents negative infinity. - - - - - Represents positive infinity. - - - - - Initializes a new instance of the struct from the given - representation. - - The raw representation of the internally stored bits. - - - - Gets the internally stored value to represent the instance. - - Signed to get arithmetic rather than logical shifts. - - - - Returns the given . - - The . - The result. - - - - Adds the first to the second one. - - The first . - The second . - The addition result. - - - - Negates the given . - - The to negate. - The negated result. - - - - Subtracts the first from the second one. - - The first . - The second . - The subtraction result. - - - - Multiplicates the first by the second one. - - The first . - The second . - The multiplication result. - - - - Divides the first through the second one. - - The first . - The second . - The division result. - - - - Gets a value indicating whether the first specified is the same as the second - specified . - - The first to compare. - The second to compare. - true, if both are the same. - - - - Gets a value indicating whether the first specified is not the same as the second - specified . - - The first to compare. - The second to compare. - true, if both are not the same. - - - - Converts the given value to a instance. - - The value to represent in the new - instance. - - - - Converts the given value to a instance. - - The value to represent in the new - instance. - - - - Converts the given value to a instance. - - The value to represent in the new - instance. - - - - Converts the given value to a instance. - - The value to represent in the new - instance. - - - - Converts the given value to a instance. - - The value to represent in the new - instance. - - - - Converts the given value to a instance. - - The value to represent in the new - instance. - - - - Gets a value indicating whether this is the same as the second specified - . - - The object to compare, if it is a . - true, if both are the same. - - - - Gets a hash code as an indication for object equality. - - The hash code. - - - - Gets a string describing this . - - A string describing this . - - - - Indicates whether the current is equal to another . - - A to compare with this . - true if the current is equal to the other parameter; otherwise, false. - - - - - Returns a value indicating whether the specified number evaluates to not a number (). - - A half-precision floating-point number. - true if value evaluates to not a number (); otherwise false. - - - - Returns a value indicating whether the specified number evaluates to negative or positive infinity. - - A half-precision floating-point number. - true if half evaluates to or ; - otherwise false. - - - - Returns a value indicating whether the specified number evaluates to negative infinity. - - A half-precision floating-point number. - true if half evaluates to ; otherwise false. - - - - Returns a value indicating whether the specified number evaluates to positive infinity. - - A half-precision floating-point number. - true if half evaluates to ; otherwise false. - - - - Represents a buffer of data uploaded to the GPU which can hold arbitrary data. - - - - - The size of a full vertex in bytes. - - - - - The raw bytes stored for each buffering. - - - - - Represents an memory pool section in a subfile, storing memory. - - - - - Represents an memory info section in a subfile. References vertex and index buffers - - - - - Gets or sets the buffer instance that stores face data first, then vertex buffer after. - - - - - Gets or sets the memory pool property - - Represents an _RLT section in a subfile, storing pointers to sections in a Bntx. @@ -826,162 +209,6 @@ Represents a node forming the Patricia trie of the dictionary. - - - Represents a which is stored in a . - - - - - The textual represented by this instance. - - - - - The with which this string was read or will be written. - - - - - Converts the given value to a instance. - - The value to represent in the new instance. - - - - - Converts the given value to an instance. - - The value to represent in the new instance. - - - - - Returns the value of the property. - - The value of the property. - - - - Represents a 2D transformation. - - - - - The size of this structure. - - - - - The scaling amount of the transformation. - - - - - The rotation angle of the transformation. - - - - - The translation amount of the transformation. - - - - - Represents a 3D transformation. - - - - - The size of this structure. - - - - - The scaling amount of the transformation. - - - - - The rotation amount of the transformation. - - - - - The translation amount of the transformation. - - - - - Represents a 2D texture transformation. - - - - - The size of this structure. - - - - - The with which the transformation is applied. - - - - - The scaling amount of the transformation. - - - - - The rotation angle of the transformation. - - - - - The translation amount of the transformation. - - - - - Represents a 2D texture transformation which is multiplied by a 3x4 matrix referenced at runtime by the - . - - - - - The size of this structure. - - - - - The with which the transformation is applied. - - - - - The scaling amount of the transformation. - - - - - The rotation angle of the transformation. - - - - - The translation amount of the transformation. - - - - - A pointer to a 3x4 matrix to multiply the transformation with. Set at runtime. - - - - - Represents the texture transformation mode used in and . - - Represents custom user variables which can be attached to many sections and subfiles of a . @@ -1087,609 +314,6 @@ The values is a array encoded in UTF-16. - - - Represents extension methods for the class. - - - - - Reads a instance from the current stream and returns it. - - The extended . - The instance. - - - - Reads instances from the current stream and returns them. - - The extended . - The number of instances to read. - The instances. - - - - Reads a instance from the current stream and returns it. - - The extended . - The instance. - - - - Reads instances from the current stream and returns them. - - The extended . - The number of instances to read. - The instances. - - - - Reads a instance from the current stream and returns it. - - The extended . - The instance. - - - - Reads instances from the current stream and returns them. - - The extended . - The number of instances to read. - The instances. - - - - Reads a instance from the current stream and returns it. - - The extended . - The instance. - - - - Reads instances from the current stream and returns them. - - The extended . - The number of instances to read. - The instances. - - - - Reads a instance from the current stream and returns it. - - The extended . - The in which values are stored. - The instance. - - - - Reads instances from the current stream and returns them. - - The extended . - The number of instances to read. - The in which values are stored. - The instances. - - - - Reads a instance from the current stream and returns it. - - The extended . - The instance. - - - - Reads instances from the current stream and returns them. - - The extended . - The number of instances to read. - The instances. - - - - Reads a instance from the current stream and returns it. - - The extended . - The instance. - - - - Reads instances from the current stream and returns them. - - The extended . - The number of instances to read. - The instances. - - - - Reads a instance from the current stream and returns it. - - The extended . - The instance. - - - - Reads instances from the current stream and returns them. - - The extended . - The number of instances to read. - The instances. - - - - Reads a instance from the current stream and returns it. - - The extended . - The in which values are stored. - The instance. - - - - Reads instances from the current stream and returns them. - - The extended . - The number of instances to read. - The in which values are stored. - The instances. - - - - Reads a instance from the current stream and returns it. - - The extended . - The instance. - - - - Reads instances from the current stream and returns them. - - The extended . - The number of instances to read. - The instances. - - - - Reads a instance from the current stream and returns it. - - The extended . - The instance. - - - - Reads instances from the current stream and returns them. - - The extended . - The number of instances to read. - The instances. - - - - Reads a instance from the current stream and returns it. - - The extended . - The instance. - - - - Reads instances from the current stream and returns them. - - The extended . - The number of instances to read. - The instances. - - - - Reads a instance from the current stream and returns it. - - The extended . - The in which values are stored. - The instance. - - - - Reads instances from the current stream and returns them. - - The extended . - The number of instances to read. - The in which values are stored. - The instances. - - - - Reads a instance from the current stream and returns it. - - The extended . - The instance. - - - - Reads instances from the current stream and returns them. - - The extended . - The number of instances to read. - The instances. - - - - Reads a instance from the current stream and returns it. - - The extended . - The instance. - - - - Reads instances from the current stream and returns them. - - The extended . - The number of instances to read. - The instances. - - - - Represents extension methods for the class. - - - - - Writes a instance into the current stream. - - The extended . - The instance. - - - - Writes instances into the current stream. - - The extended . - The instances. - - - - Writes a instance into the current stream. - - The extended . - The instance. - - - - Writes instances into the current stream. - - The extended . - The instances. - - - - Writes a instance into the current stream. - - The extended . - The instance. - - - - Writes instances into the current stream. - - The extended . - The instances. - - - - Writes a instance into the current stream. - - The extended . - The instance. - The in which values are stored. - - - - Writes instances into the current stream. - - The extended . - The instances. - The in which values are stored. - - - - Writes a instance into the current stream. - - The extended . - The instance. - - - - Writes instances into the current stream. - - The extended . - The instances. - - - - Writes a instance into the current stream. - - The extended . - The instance. - - - - Writes instances into the current stream. - - The extended . - The instances. - - - - Writes a instance into the current stream. - - The extended . - The instance. - - - - Writes instances into the current stream. - - The extended . - The instances. - - - - Writes a instance into the current stream. - - The extended . - The instance. - The in which values are stored. - - - - Writes instances into the current stream. - - The extended . - The instances. - The in which values are stored. - - - - Writes a instance into the current stream. - - The extended . - The instance. - - - - Writes instances into the current stream. - - The extended . - The instances. - - - - Writes a instance into the current stream. - - The extended . - The instance. - - - - Writes instances into the current stream. - - The extended . - The instances. - - - - Writes a instance into the current stream. - - The extended . - The instance. - - - - Writes instances into the current stream. - - The extended . - The instances. - - - - Writes a instance into the current stream. - - The extended . - The instance. - The in which values are stored. - - - - Writes instances into the current stream. - - The extended . - The instances. - The in which values are stored. - - - - Writes a instance into the current stream. - - The extended . - The instance. - - - - Writes instances into the current stream. - - The extended . - The instances. - - - - Writes a instance into the current stream. - - The extended . - The instance. - - - - Writes instances into the current stream. - - The extended . - The instances. - - - - Represents extension methods for instances. - - - - - Returns an instance represented by the given number of , starting - at the . - - The extended instance. - The first bit of the encoded value. - The number of least significant bits which are used to store the - value. - The decoded . - - - - Returns the current with the bit at the set (being 1). - - The extended instance. - The 0-based index of the bit to enable. - The current with the bit enabled. - - - - Returns the current with the given set into the given number - of starting at . - - The extended instance. - The value to encode. - The first bit used for the encoded value. - The number of bits which are used to store the value. - The current with the value encoded into it. - - - - Returns the current with the bit at the cleared (being 0). - - The extended instance. - The 0-based index of the bit to disable. - The current with the bit disabled. - - - - Returns a value indicating whether the bit at the in the current - is enabled or disabled. - - The extended instance. - The 0-based index of the bit to check. - true when the bit is set; otherwise false. - - - - Returns the current with all bits rotated in the given , - where positive directions rotate left and negative directions rotate right. - - The extended instance. - The direction in which to rotate, where positive directions rotate left. - The current with the bits rotated. - - - - Returns the current with the bit at the enabled or disabled, - according to . - - The extended instance. - The 0-based index of the bit to enable or disable. - true to enable the bit; otherwise false. - The current with the bit enabled or disabled. - - - - Returns the current with the bit at the enabled when it is - disabled or disabled when it is enabled. - - The extended instance. - The 0-based index of the bit to toggle. - The current with the bit toggled. - - - - Represents extension methods for instances. - - - - - Returns an instance represented by the given number of , starting - at the . - - The extended instance. - The first bit of the encoded value. - The number of least significant bits which are used to store the - value. - The decoded . - - - - Returns the current with the bit at the set (being 1). - - The extended instance. - The 0-based index of the bit to enable. - The current with the bit enabled. - - - - Returns the current with the given set into the given number - of starting at . - - The extended instance. - The value to encode. - The first bit used for the encoded value. - The number of bits which are used to store the value. - The current with the value encoded into it. - - - - Returns the current with the bit at the cleared (being 0). - - The extended instance. - The 0-based index of the bit to disable. - The current with the bit disabled. - - - - Returns a value indicating whether the bit at the in the current - is enabled or disabled. - - The extended instance. - The 0-based index of the bit to check. - true when the bit is set; otherwise false. - - - - Returns the current with all bits rotated in the given , - where positive directions rotate left and negative directions rotate right. - - The extended instance. - The direction in which to rotate, where positive directions rotate left. - The current with the bits rotated. - - - - Returns the current with the bit at the enabled or disabled, - according to . - - The extended instance. - The 0-based index of the bit to enable or disable. - true to enable the bit; otherwise false. - The current with the bit enabled or disabled. - - - - Returns the current with the bit at the enabled when it is - disabled or disabled when it is enabled. - - The extended instance. - The 0-based index of the bit to toggle. - The current with the bit toggled. - Represents the common interface for data instances. @@ -1832,7 +456,7 @@ - Gets or sets a data block alignment typically seen with . + Gets or sets a data block alignment typically seen with . @@ -1961,11 +585,6 @@ A valid signature. - - - Represents a sorting empty strings to the end of lists. - - Represents shapes of a given surface or texture. @@ -1986,26 +605,6 @@ Represents the desired tiling modes for a surface. - - - Represents an exception raised when handling data. - - - - - Initializes a new instance of the class with a specified error - . - - The error message that explains the reason for the exception. - - - - Initializes a new instance of the class with a specified error message created - from the given and . - - The format of the error message. - The parameters to format the error message with. - Represents an FMDL subfile in a , storing multi-dimensional texture data. @@ -2151,333 +750,5 @@ Gets or sets sample amount - - - Represents the AA modes (number of samples) for a surface. - - - - - Represents the format of a vertex attribute entry. Possible type conversions: - UNorm: attrib unsigned integer is converted to/from [0.0, 1.0] in shader. - UInt: attrib unsigned integer is copied to/from shader as unsigned int. - SNorm: attrib signed integer is converted to/from [-1.0, 1.0] in shader. - SInt: attrib signed integer is copied to/from shader as signed int. - Single: attrib single is copied to/from shader as Single. - UIntToSingle: attrib unsigned integer is converted Single in shader. - SIntToSingle: attrib signed integer is converted Single in shader. - - - - - Represents how the terms of the blend function are combined. - - - - - Represents the factors used in the blend function. - - - - - Represents compare functions used for depth and stencil tests. - - - - - Represents the source channels to map to a color channel in textures. - - - - - Represents the vertex order of front-facing polygons. - - - - - Represents the type in which vertex indices are stored. - - - - - Represents the logic op function to perform. - - - - - Black - - - - - White - - - - - Source (Default) - - - - - ~Source - - - - - Destination - - - - - ~Destination - - - - - Source & Destination - - - - - ~(Source & Destination) - - - - - Source | Destination - - - - - ~(Source | Destination) - - - - - Source ^ Destination - - - - - ~(Source ^ Destination) - - - - - Source & ~Destination - - - - - ~Source & Destination - - - - - Source | ~Destination - - - - - ~Source | Destination - - - - - Represents the base primitive used to draw each side of the polygon when dual-sided polygon mode is enabled. - - - - - Represents the type of primitives to draw. - - - - - Requires at least 1 element and 1 more to draw another primitive. - - - - - Requires at least 2 elements and 2 more to draw another primitive. - - - - - Requires at least 2 elements and 1 more to draw another primitive. - - - - - Requires at least 3 elements and 3 more to draw another primitive. - - - - - Requires at least 3 elements and 1 more to draw another primitive. - - - - - Requires at least 3 elements and 1 more to draw another primitive. - - - - - Requires at least 4 elements and 4 more to draw another primitive. - - - - - Requires at least 4 elements and 1 more to draw another primitive. - - - - - Requires at least 6 elements and 6 more to draw another primitive. - - - - - Requires at least 6 elements and 2 more to draw another primitive. - - - - - Requires at least 3 elements and 3 more to draw another primitive. - - - - - Requires at least 2 elements and 1 more to draw another primitive. - - - - - Requires at least 4 elements and 4 more to draw another primitive. - - - - - Requires at least 4 elements and 2 more to draw another primitive. - - - - - Requires at least 2 elements and 2 more to draw another primitive. - - - - - Requires at least 2 elements and 1 more to draw another primitive. - - - - - Requires at least 3 elements and 3 more to draw another primitive. - - - - - Requires at least 3 elements and 1 more to draw another primitive. - - - - - Requires at least 4 elements and 4 more to draw another primitive. - - - - - Requires at least 4 elements and 2 more to draw another primitive. - - - - - Represents the stencil function to be performed if stencil tests pass. - - - - - Represents shapes of a given surface or texture. - - - - - Represents desired texture, color-buffer, depth-buffer, or scan-buffer formats. - - - - - Represents Indicates how a given surface may be used. A final TV render target is one that will be copied to a - TV scan buffer. It needs to be designated to handle certain display corner cases (when a HD surface must be - scaled down to display in NTSC/PAL). - - - - - Represents maximum desired anisotropic filter ratios. Higher ratios give better image quality, but slower - performance. - - - - - Represents type of border color to use. - - - - - Represents how to treat texture coordinates outside of the normalized coordinate texture range. - - - - - Represents desired texture filter options between mip levels. - - - - - Represents desired texture filter options within a plane. - - - - - Represents desired texture filter options between Z planes. - - - - - Represents the desired tiling modes for a surface. - - - - - Computes a CRC32 checksum. - - Based on - - - - Compute the checksum of a UTF8 text. - - Text to calculate - Checksum - - - - Compute the checksum of a text using a specific encoding. - - Text to calculate - Text encoding - Checksum - - - - Compute the checksum of a binary buffer. - - Buffer to calculate - -