CreateResource(HWContext context, string filename) { string extension = Path.GetExtension(filename).ToLowerInvariant(); if (TypeDefinitions.TryGetValue(extension, out HWResourceTypeDefinition definition)) { if (Activator.CreateInstance(definition.Class) is HWResource resource) { resource.Type = definition.Type; resource.Context = context; resource.RelativePath = filename; return(resource); } } return(null); }
protected static HWResource GetOrCreateFromFile(HWContext context, string filename, HWResourceType expectedType = HWResourceType.None) { // Set the extension based on the resource type if the filename doesn't have one if (string.IsNullOrEmpty(Path.GetExtension(filename)) && TypeExtensions.TryGetValue(expectedType, out string defaultExtension)) { filename = Path.ChangeExtension(filename, defaultExtension); } var resource = CreateResource(context, filename); resource?.Load(File.ReadAllBytes(resource.AbsolutePath)); return(resource); }
public static new HWXtdResource FromFile(HWContext context, string filename) => GetOrCreateFromFile(context, filename, HWResourceType.Xtd) as HWXtdResource;
FromFile(HWContext context, string filename) => GetOrCreateFromFile(context, filename, HWResourceType.Xtt) as HWXttResource;
public static new HWGlsResource FromFile(HWContext context, string filename) { return(GetOrCreateFromFile(context, filename, HWResourceType.Gls) as HWGlsResource); }
public void Run(string scratchDirectoryPath, string outputDirectoryPath) { string gameDirectory = null; if (OperatingSystem.IsWindows()) { gameDirectory = SteamInterop.GetGameInstallDirectory("HaloWarsDE"); Console.WriteLine( $"Found Halo Wars Definitive Edition install at {gameDirectory}"); } // Point the framework to the game install and working directories var context = new HWContext(gameDirectory, scratchDirectoryPath); // Expand all compressed/encrypted game files. This also handles the .xmb -> .xml conversion context.ExpandAllEraFiles(); var scratchDirectory = new FinDirectory(scratchDirectoryPath); var mapDirectories = scratchDirectory .GetSubdir("scenario/skirmish/design") .GetExistingSubdirs(); var outputDirectory = new FinDirectory(outputDirectoryPath); var baseDstMapDirectory = outputDirectory.GetSubdir("scenario/skirmish/design", true); foreach (var srcMapDirectory in mapDirectories) { var mapName = srcMapDirectory.Name; var dstMapDirectory = baseDstMapDirectory.GetSubdir(mapName, true); var gltfFile = new FinFile( Path.Combine(dstMapDirectory.FullName, $"{mapName}.gltf")); if (gltfFile.Exists) { continue; } var xttFile = srcMapDirectory.GetExistingFiles() .Single(file => file.Extension == ".xtt"); var xtdFile = srcMapDirectory.GetExistingFiles() .Single(file => file.Extension == ".xtd"); var xtt = HWXttResource.FromFile(context, xttFile.FullName); var xtd = HWXtdResource.FromFile(context, xtdFile.FullName); var finModel = xtd.Mesh; var xttMaterial = finModel.MaterialManager.AddStandardMaterial(); xttMaterial.DiffuseTexture = finModel.MaterialManager.CreateTexture( xtt.AlbedoTexture); xttMaterial.DiffuseTexture.Name = $"{mapName}_albedo"; xttMaterial.AmbientOcclusionTexture = finModel.MaterialManager.CreateTexture( xtd.AmbientOcclusionTexture); xttMaterial.AmbientOcclusionTexture.Name = $"{mapName}_ao"; foreach (var primitive in finModel.Skin.Meshes[0].Primitives) { primitive.SetMaterial(xttMaterial); } var exporter = new AssimpIndirectExporter { LowLevel = true }; exporter.Export(gltfFile.CloneWithExtension(".fbx"), finModel); // Cleans up any remaining .bin files. var binFiles = dstMapDirectory.GetExistingFiles() .Where(file => file.Extension == ".bin"); foreach (var binFile in binFiles) { binFile.Info.Delete(); } // Forces an immediate garbage-collection cleanup. This is required to // prevent OOM errors, since Halo Wars maps are just so huge. GC.Collect(); GC.WaitForFullGCComplete(); GC.WaitForPendingFinalizers(); } var artDirectory = scratchDirectory.GetSubdir("art"); var artSubdirQueue = new FinQueue <IDirectory>(artDirectory); // TODO: Switch to DFS instead, it's more intuitive as a user while (artSubdirQueue.TryDequeue(out var artSubdir)) { // TODO: Skip a file if it's already been extracted // TODO: Parse UGX files instead, as long as they specify their own animations var visFiles = artSubdir.GetExistingFiles() .Where(f => f.Extension == ".vis") .ToList(); foreach (var visFile in visFiles) { var vis = HWVisResource.FromFile(context, visFile.FullName); var finModel = vis.Model; var outFilePath = visFile.FullName.Replace(scratchDirectoryPath, outputDirectoryPath); var outFile = new FinFile(outFilePath).CloneWithExtension(".fbx"); outFile.GetParent().Create(); var exporter = new AssimpIndirectExporter(); exporter.Export(outFile, finModel); Console.WriteLine($"Processed {visFile.FullName}"); } artSubdirQueue.Enqueue(artSubdir.GetExistingSubdirs()); } /*var gls = HWGlsResource.FromFile(context, * "scenario\\skirmish\\design\\blood_gulch\\blood_gulch.gls"); * Console.WriteLine($"Processed {gls}"); * * var scn = HWScnResource.FromFile(context, * "scenario\\skirmish\\design\\blood_gulch\\blood_gulch.scn"); * PrintScenarioObjects(scn); * Console.WriteLine($"Processed {scn}"); * * var sc2 = HWSc2Resource.FromFile(context, * "scenario\\skirmish\\design\\blood_gulch\\blood_gulch.sc2"); * PrintScenarioObjects(sc2); * Console.WriteLine($"Processed {sc2}"); * * var sc3 = HWSc3Resource.FromFile(context, * "scenario\\skirmish\\design\\blood_gulch\\blood_gulch.sc3"); * PrintScenarioObjects(sc3); * Console.WriteLine($"Processed {sc3}"); * }*/ }
public static HWUgxResource?FromFile( HWContext context, string filename, (IModel mesh,
//public HWVisResource Visual; public static HWObjectDefinition GetOrCreateFromId(HWContext context, string id) { return(context.ObjectDefinitions.GetValueOrDefault(id)); }
public static HWResource FromFile(HWContext context, string filename) { return(GetOrCreateFromFile(context, filename)); }
FromFile(HWContext context, string filename) { return((HWVisResource)GetOrCreateFromFile( context, filename, HWResourceType.Vis)); }