feat: canon interface

This commit is contained in:
tresabhi committed 2025-02-25 15:15:03 -06:00
1 parent 90c5c16b00
commit 63d27aec64
8 files changed
+74 -263

No files matched your search

+17 -53
View File
@@ -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<UDataTable>(pda, "DT_Hulls");
UDataTableUtility.TryGetDataTableRow(hulls, "hull", StringComparison.Ordinal, out var hull);
var hullVisualData = PropertyUtil.Get<UObject>(hull, "VisualData");
var hullMeshSettings = PropertyUtil.Get<FStructFallback>(hullVisualData, "MeshSettings");
var hullCollision = PropertyUtil.Get<UStaticMesh>(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<UStaticMesh>("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<string, CrewType> CrewTypes = new()
+18 -3
View File
@@ -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}/";
}
}
}
@@ -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<string, FStructFallback> 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);
}
}
-145
View File
@@ -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<string, NameProperty> Names = [];
readonly Dictionary<string, SoftObjectProperty> SoftObjects = [];
readonly Dictionary<string, ObjectProperty> Objects = [];
readonly Dictionary<string, StructProperty> Structs = [];
readonly Dictionary<string, BoolProperty> Booleans = [];
readonly Dictionary<string, FloatProperty> Floats = [];
readonly Dictionary<string, ArrayProperty> Arrays = [];
readonly Dictionary<string, TextProperty> Texts = [];
readonly Dictionary<string, IntProperty> Ints = [];
readonly Dictionary<string, MapProperty> Maps = [];
public MappedUObject(List<FPropertyTag> 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<T>(string name)
where T : UObject => SoftObjects[name].Value.Load<T>();
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<UDataTable>()!);
public MappedUObject GetStruct(string name) =>
new(Structs[name].GetValue<FStructFallback>()!.Properties);
public MappedUObject[] GetArray(string name)
{
return
[
.. Arrays[name]
.Value!.Properties.Select(property => new MappedUObject(
property.GetValue<FStructFallback>()!.Properties
)),
];
}
}
}
+24 -6
View File
@@ -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);
-25
View File
@@ -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<string, MappedUObject> 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];
}
}
@@ -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<string, VfsDirectory> Directories = [];
public Dictionary<string, VFS> Directories = [];
public Dictionary<string, GameFile> 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);
}
}