Compare commits

..

6 Commits

4 changed files with 82 additions and 81 deletions

View File

@ -151,43 +151,36 @@ public class WorldRep : IChunk
public readonly byte[] AsBytesRgba(int layer) public readonly byte[] AsBytesRgba(int layer)
{ {
if (layer >= Layers) ArgumentOutOfRangeException.ThrowIfLessThan(layer, 0, nameof(layer));
{ ArgumentOutOfRangeException.ThrowIfGreaterThan(layer, Layers, nameof(layer));
throw new ArgumentOutOfRangeException(nameof(layer));
}
var length = Width * Height * 4; var pIdx = layer * Bpp * Width * Height;
var layerOffset = layer * Bpp * Width * Height; var length = 4 * Width * Height;
var bytes = new byte[length]; var bytes = new byte[length];
for (var y = 0; y < Height; y++) for (var i = 0; i < length; i += 4, pIdx += Bpp)
{ {
for (var x = 0; x < Width; x++) switch (Bpp)
{ {
var bIdx = x * 4 + y * 4 * Width; case 1:
var pIdx = x * Bpp + y * Bpp * Width + layerOffset; var raw1 = Pixels[pIdx];
switch (Bpp) bytes[i] = raw1;
{ bytes[i + 1] = raw1;
case 1: bytes[i + 2] = raw1;
var raw1 = Pixels[pIdx]; bytes[i + 3] = 255;
bytes[bIdx] = raw1; break;
bytes[bIdx + 1] = raw1; case 2:
bytes[bIdx + 2] = raw1; var raw2 = Pixels[pIdx] + (Pixels[pIdx + 1] << 8);
bytes[bIdx + 3] = 255; bytes[i] = (byte)(255 * (raw2 & 31) / 31.0f);
break; bytes[i + 1] = (byte)(255 * ((raw2 >> 5) & 31) / 31.0f);
case 2: bytes[i + 2] = (byte)(255 * ((raw2 >> 10) & 31) / 31.0f);
var raw2 = Pixels[pIdx] + (Pixels[pIdx + 1] << 8); bytes[i + 3] = 255;
bytes[bIdx] = (byte)(255 * (raw2 & 31) / 31.0f); break;
bytes[bIdx + 1] = (byte)(255 * ((raw2 >> 5) & 31) / 31.0f); case 4:
bytes[bIdx + 2] = (byte)(255 * ((raw2 >> 10) & 31) / 31.0f); bytes[i] = Pixels[pIdx + 2];
bytes[bIdx + 3] = 255; bytes[i + 1] = Pixels[pIdx + 1];
break; bytes[i + 2] = Pixels[pIdx];
case 4: bytes[i + 3] = Pixels[pIdx + 3];
bytes[bIdx] = Pixels[pIdx + 2]; break;
bytes[bIdx + 1] = Pixels[pIdx + 1];
bytes[bIdx + 2] = Pixels[pIdx];
bytes[bIdx + 3] = Pixels[pIdx + 3];
break;
}
} }
} }

View File

@ -13,6 +13,7 @@ public class ResourcePathManager
public Dictionary<string, string> missionPathMap; public Dictionary<string, string> missionPathMap;
public Dictionary<string, string> texturePathMap; public Dictionary<string, string> texturePathMap;
public Dictionary<string, string> objectPathMap; public Dictionary<string, string> objectPathMap;
public Dictionary<string, string> objectTexturePathMap;
} }
private bool _initialised = false; private bool _initialised = false;
@ -53,12 +54,14 @@ public class ResourcePathManager
} }
ZipFile.OpenRead(objPath).ExtractToDirectory(objExtractPath); ZipFile.OpenRead(objPath).ExtractToDirectory(objExtractPath);
var objectPathMap = GetObjectPaths(_extractionPath); var objectPathMap = GetObjectPaths(_extractionPath);
var objectTexturePathMap = GetObjectTexturePaths(_extractionPath);
_omResources = new CampaignResources _omResources = new CampaignResources
{ {
missionPathMap = omsMap, missionPathMap = omsMap,
texturePathMap = texturePathMap, texturePathMap = texturePathMap,
objectPathMap = objectPathMap, objectPathMap = objectPathMap,
objectTexturePathMap = objectTexturePathMap,
}; };
} }
@ -66,13 +69,17 @@ public class ResourcePathManager
_fmResources = new Dictionary<string, CampaignResources>(); _fmResources = new Dictionary<string, CampaignResources>();
foreach (var (campaign, missionPathMap) in fmsMap) foreach (var (campaign, missionPathMap) in fmsMap)
{ {
var texturePathMap = GetTexturePaths(Path.Join(fmsDir, campaign)); var root = Path.Join(fmsDir, campaign);
var objectPathMap = GetObjectPaths(Path.Join(fmsDir, campaign)); var texturePathMap = GetTexturePaths(root);
var objectPathMap = GetObjectPaths(root);
var objectTexturePathMap = GetObjectTexturePaths(root);
var resource = new CampaignResources var resource = new CampaignResources
{ {
missionPathMap = missionPathMap, missionPathMap = missionPathMap,
texturePathMap = texturePathMap, texturePathMap = texturePathMap,
objectPathMap = objectPathMap, objectPathMap = objectPathMap,
objectTexturePathMap = objectTexturePathMap,
}; };
_fmResources.Add(campaign, resource); _fmResources.Add(campaign, resource);
_fmsDir = fmsDir; _fmsDir = fmsDir;
@ -191,49 +198,59 @@ public class ResourcePathManager
return null; return null;
} }
// TODO: Store these as part of the resources public string GetObjectTexturePath(string campaignName, string textureName)
public string GetObjectTexturePath(string campaignName, string modelName, string textureName)
{ {
var options = new EnumerationOptions if (!_initialised) return null;
textureName = Path.GetFileNameWithoutExtension(textureName).ToLower();
if (campaignName == null || campaignName == "")
{
if (_omResources.objectTexturePathMap.TryGetValue(textureName, out var path))
{
return path;
}
}
else if (_fmResources.TryGetValue(campaignName, out var campaign))
{
if (campaign.objectTexturePathMap.TryGetValue(textureName, out var fmPath))
{
return fmPath;
}
else if (_omResources.objectTexturePathMap.TryGetValue(textureName, out var omPath))
{
return omPath;
}
}
return null;
}
private static Dictionary<string, string> GetObjectTexturePaths(string root)
{
string[] validExtensions = { ".dds", ".png", ".tga", ".pcx", ".gif", ".bmp", ".cel", };
var dirOptions = new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive };
var texOptions = new EnumerationOptions
{ {
MatchCasing = MatchCasing.CaseInsensitive, MatchCasing = MatchCasing.CaseInsensitive,
RecurseSubdirectories = true, RecurseSubdirectories = true,
}; };
textureName = textureName.ToLower(); var pathMap = new Dictionary<string, string>();
var omDir = Path.Join(_extractionPath, "obj"); foreach (var dir in Directory.EnumerateDirectories(root, "obj", dirOptions))
var omPaths = Directory.GetFiles(omDir, textureName, options);
if (campaignName == null || campaignName == "")
{ {
if (omPaths.Length > 0) foreach (var path in Directory.EnumerateFiles(dir, "*", texOptions))
{ {
return omPaths[0]; var ext = Path.GetExtension(path);
} if (validExtensions.Contains(ext.ToLower()))
}
else if (_fmResources.TryGetValue(campaignName, out var campaign))
{
// TODO: This is a fucking mess
// Basically we need to handle when the campaign doesn't have a models folder lol
if (campaign.objectPathMap.TryGetValue(modelName, out var modelPath))
{
var dir = Path.GetDirectoryName(modelPath);
var fmPaths = Directory.GetFiles(dir, textureName, options);
if (fmPaths.Length > 0)
{ {
return fmPaths[0]; var key = Path.GetFileNameWithoutExtension(path).ToLower();
pathMap.TryAdd(key, path);
} }
else if (omPaths.Length > 0)
{
return omPaths[0];
}
}
else if (omPaths.Length > 0)
{
return omPaths[0];
} }
} }
return null; return pathMap;
} }
// TODO: Handle object textures? // TODO: Handle object textures?

View File

@ -375,7 +375,7 @@ public partial class Mission : Node3D
lmImages.Resize(lmLayerCount); lmImages.Resize(lmLayerCount);
for (var i = 0; i < lmLayerCount; i++) for (var i = 0; i < lmLayerCount; i++)
{ {
lmImages[i] = Image.CreateEmpty((int)bounds.Width, (int)bounds.Height, false, lightmapFormat); lmImages[i] = Image.CreateEmpty(bounds.Width, bounds.Height, false, lightmapFormat);
} }
foreach (var rect in packingRects) foreach (var rect in packingRects)
@ -391,7 +391,7 @@ public partial class Mission : Node3D
var height = lightmap.Height; var height = lightmap.Height;
var layerCount = lightmap.Layers; var layerCount = lightmap.Layers;
var srcRect = new Rect2I(0, 0, width, height); var srcRect = new Rect2I(0, 0, width, height);
var dst = new Vector2I((int)rect.X, (int)rect.Y); var dst = new Vector2I(rect.X, rect.Y);
for (var i = 0; i < layerCount; i++) for (var i = 0; i < layerCount; i++)
{ {
var cellLm = Image.CreateFromData(width, height, false, lightmapFormat, lightmap.AsBytesRgba(i)); var cellLm = Image.CreateFromData(width, height, false, lightmapFormat, lightmap.AsBytesRgba(i));
@ -411,8 +411,8 @@ public partial class Mission : Node3D
if (v < 0) v = Math.Abs(v); if (v < 0) v = Math.Abs(v);
// Transform! // Transform!
u = (rect.X + rect.Width * u) / (int)bounds.Width; u = (rect.X + rect.Width * u) / bounds.Width;
v = (rect.Y + rect.Height * v) / (int)bounds.Height; v = (rect.Y + rect.Height * v) / bounds.Height;
return new Vector2(u, v); return new Vector2(u, v);
}); });
} }

View File

@ -33,15 +33,7 @@ public class ModelLoader
// We don't care if this is null actually, we'll still cache that it's null lol // 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 model = LoadModel(_pathManager, ref campaignName, modelName);
var key = (campaignName, modelName); _cache[(campaignName, modelName)] = model;
if (_cache.ContainsKey(key))
{
_cache[key] = model;
}
else
{
_cache.TryAdd(key, model);
}
return model == null ? model : model.Duplicate() as MeshInstance3D; return model == null ? model : model.Duplicate() as MeshInstance3D;
} }
@ -64,12 +56,11 @@ public class ModelLoader
{ {
if (material.Type == 0) if (material.Type == 0)
{ {
var path = pathManager.GetObjectTexturePath(campaignName, modelName, material.Name); var path = pathManager.GetObjectTexturePath(campaignName, material.Name);
if (path == null) if (path == null)
{ {
// TODO: JORGE path = "user://textures/jorge.png";
GD.Print($"Failed to load model texture: {material.Name}"); GD.Print($"Failed to load model texture: {material.Name}");
continue;
} }
materials.Add(new StandardMaterial3D materials.Add(new StandardMaterial3D