Compare commits

..

No commits in common. "30bfd05073e5729dba509f3428e4819ec4a59a0c" and "117f5b924cd0f5b379ca91e80302068ba0edc011" have entirely different histories.

4 changed files with 83 additions and 84 deletions

View File

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

View File

@ -13,7 +13,6 @@ public class ResourcePathManager
public Dictionary<string, string> missionPathMap;
public Dictionary<string, string> texturePathMap;
public Dictionary<string, string> objectPathMap;
public Dictionary<string, string> objectTexturePathMap;
}
private bool _initialised = false;
@ -54,14 +53,12 @@ public class ResourcePathManager
}
ZipFile.OpenRead(objPath).ExtractToDirectory(objExtractPath);
var objectPathMap = GetObjectPaths(_extractionPath);
var objectTexturePathMap = GetObjectTexturePaths(_extractionPath);
_omResources = new CampaignResources
{
missionPathMap = omsMap,
texturePathMap = texturePathMap,
objectPathMap = objectPathMap,
objectTexturePathMap = objectTexturePathMap,
};
}
@ -69,17 +66,13 @@ public class ResourcePathManager
_fmResources = new Dictionary<string, CampaignResources>();
foreach (var (campaign, missionPathMap) in fmsMap)
{
var root = Path.Join(fmsDir, campaign);
var texturePathMap = GetTexturePaths(root);
var objectPathMap = GetObjectPaths(root);
var objectTexturePathMap = GetObjectTexturePaths(root);
var texturePathMap = GetTexturePaths(Path.Join(fmsDir, campaign));
var objectPathMap = GetObjectPaths(Path.Join(fmsDir, campaign));
var resource = new CampaignResources
{
missionPathMap = missionPathMap,
texturePathMap = texturePathMap,
objectPathMap = objectPathMap,
objectTexturePathMap = objectTexturePathMap,
};
_fmResources.Add(campaign, resource);
_fmsDir = fmsDir;
@ -198,59 +191,49 @@ public class ResourcePathManager
return null;
}
public string GetObjectTexturePath(string campaignName, string textureName)
// TODO: Store these as part of the resources
public string GetObjectTexturePath(string campaignName, string modelName, string textureName)
{
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
var options = new EnumerationOptions
{
MatchCasing = MatchCasing.CaseInsensitive,
RecurseSubdirectories = true,
};
var pathMap = new Dictionary<string, string>();
foreach (var dir in Directory.EnumerateDirectories(root, "obj", dirOptions))
textureName = textureName.ToLower();
var omDir = Path.Join(_extractionPath, "obj");
var omPaths = Directory.GetFiles(omDir, textureName, options);
if (campaignName == null || campaignName == "")
{
foreach (var path in Directory.EnumerateFiles(dir, "*", texOptions))
if (omPaths.Length > 0)
{
var ext = Path.GetExtension(path);
if (validExtensions.Contains(ext.ToLower()))
return omPaths[0];
}
}
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)
{
var key = Path.GetFileNameWithoutExtension(path).ToLower();
pathMap.TryAdd(key, path);
return fmPaths[0];
}
else if (omPaths.Length > 0)
{
return omPaths[0];
}
}
else if (omPaths.Length > 0)
{
return omPaths[0];
}
}
return pathMap;
return null;
}
// TODO: Handle object textures?

View File

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

View File

@ -33,7 +33,15 @@ public class ModelLoader
// 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);
_cache[(campaignName, modelName)] = model;
var key = (campaignName, modelName);
if (_cache.ContainsKey(key))
{
_cache[key] = model;
}
else
{
_cache.TryAdd(key, model);
}
return model == null ? model : model.Duplicate() as MeshInstance3D;
}
@ -56,11 +64,12 @@ public class ModelLoader
{
if (material.Type == 0)
{
var path = pathManager.GetObjectTexturePath(campaignName, material.Name);
var path = pathManager.GetObjectTexturePath(campaignName, modelName, material.Name);
if (path == null)
{
path = "user://textures/jorge.png";
// TODO: JORGE
GD.Print($"Failed to load model texture: {material.Name}");
continue;
}
materials.Add(new StandardMaterial3D