Add basic model caching

This commit is contained in:
Jarrod Doyle 2024-08-26 12:38:13 +01:00
parent afb6689683
commit 7ec48abda5
Signed by: Jayrude
GPG Key ID: 38B57B16E7C0ADF7
3 changed files with 48 additions and 8 deletions

View File

@ -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;
}
}

View File

@ -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<Control>("%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;

View File

@ -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;