From 7ec48abda5b4fc314104937443e0c0f7619b3660 Mon Sep 17 00:00:00 2001 From: Jarrod Doyle Date: Mon, 26 Aug 2024 12:38:13 +0100 Subject: [PATCH] Add basic model caching --- project/code/LGS/ResourcePathManager.cs | 3 +- project/code/TMV/Mission.cs | 7 ++-- project/code/TMV/ModelLoader.cs | 46 ++++++++++++++++++++++--- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/project/code/LGS/ResourcePathManager.cs b/project/code/LGS/ResourcePathManager.cs index 9203cc0..3bb4b90 100644 --- a/project/code/LGS/ResourcePathManager.cs +++ b/project/code/LGS/ResourcePathManager.cs @@ -164,7 +164,7 @@ public class ResourcePathManager return null; } - public string GetObjectPath(string campaignName, string objectName) + public string GetObjectPath(ref string campaignName, string objectName) { if (!_initialised) return null; @@ -184,6 +184,7 @@ public class ResourcePathManager } else if (_omResources.objectPathMap.TryGetValue(objectName, out var omPath)) { + campaignName = ""; return omPath; } } diff --git a/project/code/TMV/Mission.cs b/project/code/TMV/Mission.cs index c1ed970..50f19c7 100644 --- a/project/code/TMV/Mission.cs +++ b/project/code/TMV/Mission.cs @@ -44,11 +44,13 @@ public partial class Mission : Node3D ResourcePathManager _installPaths; DbFile _file; TextureLoader _textureLoader; + ModelLoader _modelLoader; public override void _Ready() { var extractPath = ProjectSettings.GlobalizePath($"user://extracted/tmp"); _installPaths = new ResourcePathManager(extractPath); + _modelLoader = new ModelLoader(_installPaths); var missionSelector = GetNode("%MissionSelector") as MissionSelector; missionSelector.pathManager = _installPaths; missionSelector.MissionSelected += (string campaign, string mission) => @@ -123,8 +125,7 @@ public partial class Mission : Node3D objHierarchy = new ObjectHierarchy(_file); } - if ( - _file.Chunks.TryGetValue("BRLIST", out var brList)) + if (_file.Chunks.TryGetValue("BRLIST", out var brList)) { PlaceObjects((BrList)brList, objHierarchy); } @@ -168,7 +169,7 @@ public partial class Mission : Node3D var rawRot = brush.angle; var rot = new Vector3(rawRot.Y, rawRot.Z, rawRot.X) * 360 / ushort.MaxValue; var scale = scaleProp == null ? Vector3.One : scaleProp.scale.ToGodotVec3(false); - var model = ModelLoader.LoadModel(_installPaths, _campaignName, modelName); + var model = _modelLoader.Load(_campaignName, modelName); if (model != null) { model.Position = pos; diff --git a/project/code/TMV/ModelLoader.cs b/project/code/TMV/ModelLoader.cs index 301d179..5b6eafd 100644 --- a/project/code/TMV/ModelLoader.cs +++ b/project/code/TMV/ModelLoader.cs @@ -1,15 +1,53 @@ using System.Collections.Generic; -using System.IO; using Godot; using KeepersCompound.LGS; namespace KeepersCompound.TMV; -public static class ModelLoader +public class ModelLoader { - public static MeshInstance3D LoadModel(ResourcePathManager pathManager, string campaignName, string modelName) + private readonly Dictionary<(string, string), MeshInstance3D> _cache; + private readonly ResourcePathManager _pathManager; + + public ModelLoader(ResourcePathManager pathManager) { - var modelPath = pathManager.GetObjectPath(campaignName, modelName); + _pathManager = pathManager; + _cache = new Dictionary<(string, string), MeshInstance3D>(); + } + + public MeshInstance3D Load(string campaignName, string modelName, bool forceLoad = false) + { + campaignName ??= ""; + + if (!forceLoad) + { + if (_cache.TryGetValue((campaignName, modelName), out var fmModel)) + { + return fmModel == null ? fmModel : fmModel.Duplicate() as MeshInstance3D; + } + else if (_cache.TryGetValue(("", modelName), out var omModel)) + { + return omModel == null ? omModel : omModel.Duplicate() as MeshInstance3D; + } + } + + // We don't care if this is null actually, we'll still cache that it's null lol + var model = LoadModel(_pathManager, ref campaignName, modelName); + var key = (campaignName, modelName); + if (_cache.ContainsKey(key)) + { + _cache[key] = model; + } + else + { + _cache.TryAdd(key, model); + } + return model == null ? model : model.Duplicate() as MeshInstance3D; + } + + public static MeshInstance3D LoadModel(ResourcePathManager pathManager, ref string campaignName, string modelName) + { + var modelPath = pathManager.GetObjectPath(ref campaignName, modelName); if (modelPath == null) { return null;