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);
        }
Beispiel #3
0
 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);
 }
Beispiel #6
0
        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}");
             * }*/
        }
Beispiel #7
0
 public static HWUgxResource?FromFile(
     HWContext context,
     string filename,
     (IModel mesh,
Beispiel #8
0
        //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));
 }