Compare commits
6 Commits
117f5b924c
...
30bfd05073
Author | SHA1 | Date |
---|---|---|
Jarrod Doyle | 30bfd05073 | |
Jarrod Doyle | 74bde133bb | |
Jarrod Doyle | 0b347f7745 | |
Jarrod Doyle | e7e9c300fd | |
Jarrod Doyle | c0666a5404 | |
Jarrod Doyle | 5b53d03ae6 |
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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?
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue