diff --git a/src/BlitzKit.CLI/Functions/Mangler.cs b/src/BlitzKit.CLI/Functions/Mangler.cs index be1451e57..67419526a 100644 --- a/src/BlitzKit.CLI/Functions/Mangler.cs +++ b/src/BlitzKit.CLI/Functions/Mangler.cs @@ -1,18 +1,26 @@ +using System.Data; +using AssetRipper.TextureDecoder.Rgb.Channels; using Blitzkit; using BlitzKit.CLI.Models; using BlitzKit.CLI.Utils; using CommunityToolkit.HighPerformance; using CommunityToolkit.HighPerformance.Helpers; +using CUE4Parse; using CUE4Parse_Conversion; using CUE4Parse_Conversion.Animations; using CUE4Parse_Conversion.Meshes; using CUE4Parse_Conversion.Meshes.glTF; using CUE4Parse_Conversion.Textures; using CUE4Parse_Conversion.UEFormat.Enums; +using CUE4Parse.FileProvider.Objects; +using CUE4Parse.UE4.Assets.Exports; using CUE4Parse.UE4.Assets.Exports.Engine; using CUE4Parse.UE4.Assets.Exports.Material; using CUE4Parse.UE4.Assets.Exports.StaticMesh; using CUE4Parse.UE4.Assets.Exports.Texture; +using CUE4Parse.UE4.Assets.Objects; +using CUE4Parse.UE4.Assets.Objects.Properties; +using CUE4Parse.UE4.Assets.Utils; using CUE4Parse.UE4.Objects.UObject; using CUE4Parse.UE4.Readers; using CUE4Parse.UE4.Writers; @@ -40,7 +48,7 @@ namespace BlitzKit.CLI.Functions } } - void MangleNation(VfsDirectory nation) + void MangleNation(VFS nation) { foreach (var tankDir in nation.Directories) { @@ -56,61 +64,17 @@ namespace BlitzKit.CLI.Functions } } - Tank? MangleTank(VfsDirectory tankDir) + Tank? MangleTank(VFS tankDir) { var pdaName = $"PDA_{tankDir.Name}"; - var pda = tankDir.GetUasset($"{pdaName}.uasset").Get(pdaName); - var tankId = pda.GetName("TankId"); - var isDev = pda.TryGetBool("bInDevelopment") ?? true; + var pda = provider.LoadObject($"{tankDir.Path}/{pdaName}.{pdaName}"); + var hulls = PropertyUtil.Get(pda, "DT_Hulls"); + UDataTableUtility.TryGetDataTableRow(hulls, "hull", StringComparison.Ordinal, out var hull); + var hullVisualData = PropertyUtil.Get(hull, "VisualData"); + var hullMeshSettings = PropertyUtil.Get(hullVisualData, "MeshSettings"); + var hullCollision = PropertyUtil.Get(hullMeshSettings, "CollisionMesh"); - if (isDev) - { - PrettyLog.Warn($"Skipping dev tank: {tankId}"); - return null; - } - else - { - PrettyLog.Success($"Mangling tank: {tankId}"); - } - - var hulls = pda.GetObjectDataTable("DT_Hulls"); - var hull = hulls.GetRow("hull"); - var hullVisual = hull.GetObject("VisualData"); - var hullMeshSettings = hullVisual.GetStruct("MeshSettings"); - var hullMesh = hullMeshSettings.GetSoftObject("Mesh"); - - MonoGltf hullGltf = new(hullMesh); - - // Gltf gltf = new(hullMesh.Name, hullLod0, null, new() { }); - // FArchiveWriter archiveWriter = new(); - - // gltf.Save(EMeshFormat.Gltf2, archiveWriter); - - // MeshExporter hullMeshExporter = new( - // hullMesh, - // new() - // { - // MeshFormat = EMeshFormat.Gltf2, - // ExportMaterials = true, - // ExportMorphTargets = false, - // LodFormat = ELodFormat.FirstLod, - // TextureFormat = ETextureFormat.Jpeg, - // SocketFormat = ESocketFormat.None, - // Platform = ETexturePlatform.DesktopMobile, - // } - // ); - - - - - // var hullLod0 = hullMeshExporter.MeshLods[0]; - // var hullMeshData = hullLod0.FileData; - - // File.WriteAllBytes($"../../temp/{tankId}.glb", hullMeshData); - - // hullMeshExporter.TryWriteToDir(new("../../temp"), out _, out _); - - return new() { Id = tankId }; + return new() { Id = "" }; } Dictionary CrewTypes = new() diff --git a/src/BlitzKit.CLI/Models/BlitzProvider.cs b/src/BlitzKit.CLI/Models/BlitzProvider.cs index e3ee8e042..ea2782095 100644 --- a/src/BlitzKit.CLI/Models/BlitzProvider.cs +++ b/src/BlitzKit.CLI/Models/BlitzProvider.cs @@ -15,7 +15,7 @@ namespace BlitzKit.CLI.Models private static readonly string LOCAL_MAPPINGS_PATH = "../../submodules/blitzkit-closed/blitz.usmap"; - public readonly VfsDirectory RootDirectory; + public readonly VFS RootDirectory; public BlitzProvider() : base( @@ -25,7 +25,13 @@ namespace BlitzKit.CLI.Models versions: new(EGame.GAME_UE5_3) ) { - RootDirectory = new() { Name = "", provider = this }; + RootDirectory = new() + { + ParentPath = "", + Path = "", + Name = "", + provider = this, + }; MappingsContainer = new FileUsmapTypeMappingsProvider(LOCAL_MAPPINGS_PATH); Initialize(); @@ -37,6 +43,7 @@ namespace BlitzKit.CLI.Models var path = gameFile.Path.Split('/'); var lastPathSegment = path.Last(); var directory = RootDirectory; + var parentPath = ""; foreach (var segment in path) { @@ -52,10 +59,18 @@ namespace BlitzKit.CLI.Models } else { - VfsDirectory newDirectory = new() { Name = segment, provider = this }; + VFS newDirectory = new() + { + ParentPath = parentPath, + Path = parentPath == "" ? "" : $"{parentPath}{segment}", + Name = segment, + provider = this, + }; directory.AddDirectory(segment, newDirectory); directory = newDirectory; } + + parentPath += $"{segment}/"; } } } diff --git a/src/BlitzKit.CLI/Models/MappedUDataTable.cs b/src/BlitzKit.CLI/Models/MappedUDataTable.cs deleted file mode 100644 index d4bc04b87..000000000 --- a/src/BlitzKit.CLI/Models/MappedUDataTable.cs +++ /dev/null @@ -1,21 +0,0 @@ -using CUE4Parse.UE4.Assets.Exports.Engine; -using CUE4Parse.UE4.Assets.Objects; - -namespace BlitzKit.CLI.Models -{ - public class MappedUDataTable : MappedUObject - { - readonly Dictionary StructFallbacks = []; - - public MappedUDataTable(UDataTable table) - : base(table.Properties) - { - foreach (var row in table.RowMap) - { - StructFallbacks.Add(row.Key.Text, row.Value); - } - } - - public MappedUObject GetRow(string name) => new(StructFallbacks[name].Properties); - } -} diff --git a/src/BlitzKit.CLI/Models/MappedUObject.cs b/src/BlitzKit.CLI/Models/MappedUObject.cs deleted file mode 100644 index bcf8c88e3..000000000 --- a/src/BlitzKit.CLI/Models/MappedUObject.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System.Collections; -using System.Collections.Frozen; -using System.Dynamic; -using CUE4Parse.FileProvider; -using CUE4Parse.FileProvider.Objects; -using CUE4Parse.UE4.Assets.Exports; -using CUE4Parse.UE4.Assets.Exports.Engine; -using CUE4Parse.UE4.Assets.Objects; -using CUE4Parse.UE4.Assets.Objects.Properties; -using CUE4Parse.UE4.Objects.UObject; - -namespace BlitzKit.CLI.Models -{ - public class MappedUObject : UObject - { - readonly Dictionary Names = []; - readonly Dictionary SoftObjects = []; - readonly Dictionary Objects = []; - readonly Dictionary Structs = []; - readonly Dictionary Booleans = []; - readonly Dictionary Floats = []; - readonly Dictionary Arrays = []; - readonly Dictionary Texts = []; - readonly Dictionary Ints = []; - readonly Dictionary Maps = []; - - public MappedUObject(List properties) - : base(properties) - { - foreach (var property in properties) - { - switch (property.Tag) - { - case NameProperty name: - { - Names.Add(property.Name.Text, name); - break; - } - - case SoftObjectProperty softObject: - { - SoftObjects.Add(property.Name.Text, softObject); - break; - } - - case ObjectProperty obj: - { - Objects.Add(property.Name.Text, obj); - break; - } - - case StructProperty structure: - { - Structs.Add(property.Name.Text, structure); - break; - } - - case BoolProperty boolean: - { - Booleans.Add(property.Name.Text, boolean); - break; - } - - case FloatProperty number: - { - Floats.Add(property.Name.Text, number); - break; - } - - case ArrayProperty array: - { - Arrays.Add(property.Name.Text, array); - break; - } - - case TextProperty text: - { - Texts.Add(property.Name.Text, text); - break; - } - - case IntProperty integer: - { - Ints.Add(property.Name.Text, integer); - break; - } - - case MapProperty map: - { - Maps.Add(property.Name.Text, map); - break; - } - - default: - { - throw new Exception($"Unhandled property type: {property}"); - } - } - } - } - - public FPropertyTag GetAny(string name) => - Properties.First(property => property.Name.Text == name); - - public string GetName(string name) => Names[name].Value.Text; - - public string? TryGetName(string name) => - Names.TryGetValue(name, out var entry) ? entry.Value.Text : null; - - public bool GetBool(string name) => Booleans[name].Value; - - public bool? TryGetBool(string name) => - Booleans.TryGetValue(name, out var entry) ? entry.Value : null; - - public T GetSoftObject(string name) - where T : UObject => SoftObjects[name].Value.Load(); - - public MappedUObject GetMappedSoftObject(string name) => - new(GetMappedSoftObject(name).Properties); - - public MappedUObject? TryGetSoftObject(string name) => - SoftObjects.TryGetValue(name, out var entry) - ? new MappedUObject(entry.Value.Load().Properties) - : null; - - public MappedUObject GetObject(string name) => new(Objects[name].Value!.Load()!.Properties); - - public MappedUDataTable GetObjectDataTable(string name) => - new(Objects[name].Value!.Load()!); - - public MappedUObject GetStruct(string name) => - new(Structs[name].GetValue()!.Properties); - - public MappedUObject[] GetArray(string name) - { - return - [ - .. Arrays[name] - .Value!.Properties.Select(property => new MappedUObject( - property.GetValue()!.Properties - )), - ]; - } - } -} diff --git a/src/BlitzKit.CLI/Models/MonoGltf.cs b/src/BlitzKit.CLI/Models/MonoGltf.cs index ec8f302da..b008a01f2 100644 --- a/src/BlitzKit.CLI/Models/MonoGltf.cs +++ b/src/BlitzKit.CLI/Models/MonoGltf.cs @@ -18,6 +18,7 @@ using SharpGLTF.Geometry.VertexTypes; using SharpGLTF.Materials; using SharpGLTF.Scenes; using SharpGLTF.Schema2; +using SkiaSharp; namespace BlitzKit.CLI.Models { @@ -76,21 +77,38 @@ namespace BlitzKit.CLI.Models ) return; - var encodedBitmap = bitmap.Encode(options.TextureFormat, 100); - try { - var textureBytes = encodedBitmap.ToArray(); - switch (parameterTexture.Key) { case "BaseColor": - materialBuilder.WithBaseColor(textureBytes); + { + var encoded = bitmap.Encode(options.TextureFormat, 100); + var bytes = encoded.ToArray(); + materialBuilder.WithBaseColor(bytes); + break; + } case "RM": - materialBuilder.WithMetallicRoughness(textureBytes); + { + var encoded = bitmap.Encode(options.TextureFormat, 100); + + for (int y = 0; y < bitmap.Height; y++) + { + for (int x = 0; x < bitmap.Width; x++) + { + var index = y * bitmap.Width + x; + var color = bitmap.Pixels[index]; + bitmap.Pixels[index] = new(color.Blue, color.Red, color.Green, color.Alpha); + } + } + + var bytes = encoded.ToArray(); + materialBuilder.WithBaseColor(bytes); + break; + } case "PM_SpecularMasks": // materialBuilder.WithSpecularGlossiness(textureBytes); diff --git a/src/BlitzKit.CLI/Models/Uasset.cs b/src/BlitzKit.CLI/Models/Uasset.cs deleted file mode 100644 index 13f1ca483..000000000 --- a/src/BlitzKit.CLI/Models/Uasset.cs +++ /dev/null @@ -1,25 +0,0 @@ -using CUE4Parse.FileProvider; -using CUE4Parse.FileProvider.Objects; -using CUE4Parse.UE4.Assets.Exports; - -namespace BlitzKit.CLI.Models -{ - public class Uasset - { - readonly GameFile file; - readonly Dictionary objects = []; - - public Uasset(GameFile file, AbstractFileProvider provider) - { - this.file = file; - var objects = provider.LoadAllObjects(file.Path); - - foreach (var obj in objects) - { - this.objects.Add(obj.Name, new(obj.Properties)); - } - } - - public MappedUObject Get(string name) => objects[name]; - } -} diff --git a/src/BlitzKit.CLI/Models/VfsDirectory.cs b/src/BlitzKit.CLI/Models/VFS.cs similarity index 61% rename from src/BlitzKit.CLI/Models/VfsDirectory.cs rename to src/BlitzKit.CLI/Models/VFS.cs index 8cdf36a3e..051209919 100644 --- a/src/BlitzKit.CLI/Models/VfsDirectory.cs +++ b/src/BlitzKit.CLI/Models/VFS.cs @@ -1,25 +1,31 @@ using CUE4Parse.FileProvider; using CUE4Parse.FileProvider.Objects; +using CUE4Parse.UE4.Assets.Exports; +using CUE4Parse.UE4.Assets.Exports.Engine; +using CUE4Parse.UE4.Assets.Objects; +using CUE4Parse.UE4.Assets.Objects.Properties; namespace BlitzKit.CLI.Models { - public class VfsDirectory + public class VFS { - public Dictionary Directories = []; + public Dictionary Directories = []; public Dictionary Files = []; + + public required string ParentPath; + public required string Path; public required string Name; + public required AbstractFileProvider provider; public void AddFile(string name, GameFile file) => Files.TryAdd(name, file); public bool HasFile(string name) => Files.ContainsKey(name); - public Uasset GetUasset(string name) => new(GetFile(name), provider); - public GameFile GetFile(string name) { - var directoryPath = Path.GetDirectoryName(name); - var fileName = Path.GetFileName(name); + var directoryPath = System.IO.Path.GetDirectoryName(name); + var fileName = System.IO.Path.GetFileName(name); var directory = directoryPath == null || directoryPath.Length == 0 ? this : GetDirectory(directoryPath); @@ -28,7 +34,7 @@ namespace BlitzKit.CLI.Models public bool HasDirectory(string name) => Directories.ContainsKey(name); - public VfsDirectory GetDirectory(string name) + public VFS GetDirectory(string name) { var segments = name.Split('/'); var directory = this; @@ -41,7 +47,6 @@ namespace BlitzKit.CLI.Models return directory; } - public void AddDirectory(string name, VfsDirectory directory) => - Directories.Add(name, directory); + public void AddDirectory(string name, VFS directory) => Directories.Add(name, directory); } } diff --git a/submodules/CUE4Parse b/submodules/CUE4Parse index e45f85472..624e07c8c 160000 --- a/submodules/CUE4Parse +++ b/submodules/CUE4Parse @@ -1 +1 @@ -Subproject commit e45f85472248e38b35fae893fa1bf69851aa90eb +Subproject commit 624e07c8c396724b3ae72d4e1e2854fdc5269e24