Compare commits
2 Commits
9605c36303
...
d125fb2cd3
Author | SHA1 | Date |
---|---|---|
Jarrod Doyle | d125fb2cd3 | |
Jarrod Doyle | efb15c19dd |
|
@ -97,45 +97,42 @@ public class WorldRep : IChunk
|
||||||
|
|
||||||
public struct Lightmap
|
public struct Lightmap
|
||||||
{
|
{
|
||||||
public byte[,,,] Pixels { get; set; }
|
public byte[] Pixels { get; set; }
|
||||||
|
|
||||||
|
public int Layers;
|
||||||
|
public int Width;
|
||||||
|
public int Height;
|
||||||
|
public int Bpp;
|
||||||
|
|
||||||
public Lightmap(BinaryReader reader, byte width, byte height, uint bitmask, int bytesPerPixel)
|
public Lightmap(BinaryReader reader, byte width, byte height, uint bitmask, int bytesPerPixel)
|
||||||
{
|
{
|
||||||
var count = 1 + BitOperations.PopCount(bitmask);
|
var count = 1 + BitOperations.PopCount(bitmask);
|
||||||
Pixels = new byte[count, height, width, bytesPerPixel];
|
var length = bytesPerPixel * width * height * count;
|
||||||
for (var c = 0; c < count; c++)
|
Pixels = reader.ReadBytes(length);
|
||||||
{
|
Layers = count;
|
||||||
for (var y = 0; y < height; y++)
|
Width = width;
|
||||||
{
|
Height = height;
|
||||||
for (var x = 0; x < width; x++)
|
Bpp = bytesPerPixel;
|
||||||
{
|
|
||||||
for (var b = 0; b < bytesPerPixel; b++)
|
|
||||||
{
|
|
||||||
Pixels[c, y, x, b] = reader.ReadByte();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly Vector4 GetPixel(uint layer, uint x, uint y)
|
public readonly Vector4 GetPixel(uint layer, uint x, uint y)
|
||||||
{
|
{
|
||||||
if (layer >= Pixels.GetLength(0) || x >= Pixels.GetLength(2) || y >= Pixels.GetLength(1))
|
if (layer >= Layers || x >= Width || y >= Height)
|
||||||
{
|
{
|
||||||
return Vector4.Zero;
|
return Vector4.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (Pixels.GetLength(3))
|
var idx = 0 + x * Bpp + y * Bpp * Width + layer * Bpp * Width * Height;
|
||||||
|
switch (Bpp)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
var raw1 = Pixels[layer, y, x, 0];
|
var raw1 = Pixels[idx];
|
||||||
return new Vector4(raw1, raw1, raw1, 255) / 255.0f;
|
return new Vector4(raw1, raw1, raw1, 255) / 255.0f;
|
||||||
case 2:
|
case 2:
|
||||||
var raw2 = Pixels[layer, y, x, 0] + (Pixels[layer, y, x, 1] << 8);
|
var raw2 = Pixels[idx] + (Pixels[idx + 1] << 8);
|
||||||
return new Vector4(raw2 & 31, (raw2 >> 5) & 31, (raw2 >> 10) & 31, 31) / 31.0f;
|
return new Vector4(raw2 & 31, (raw2 >> 5) & 31, (raw2 >> 10) & 31, 31) / 31.0f;
|
||||||
case 4:
|
case 4:
|
||||||
// 4bpp stored as BGRA
|
return new Vector4(Pixels[idx + 2], Pixels[idx + 1], Pixels[idx], Pixels[idx + 3]) / 255.0f;
|
||||||
return new Vector4(Pixels[layer, y, x, 2], Pixels[layer, y, x, 1], Pixels[layer, y, x, 0], Pixels[layer, y, x, 3]) / 255.0f;
|
|
||||||
default:
|
default:
|
||||||
return Vector4.Zero;
|
return Vector4.Zero;
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,7 +215,7 @@ public partial class Mission : Node3D
|
||||||
var cellIdxOffset = 0;
|
var cellIdxOffset = 0;
|
||||||
for (int polyIdx = 0; polyIdx < maxPolyIdx; polyIdx++)
|
for (int polyIdx = 0; polyIdx < maxPolyIdx; polyIdx++)
|
||||||
{
|
{
|
||||||
var lightmapRectData = ProcessCellSurfaceData(surfaceDataMap, cell, cellIdx, polyIdx, cellIdxOffset);
|
var lightmapRectData = ProcessCellSurfaceData(surfaceDataMap, worldRep, cellIdx, polyIdx, cellIdxOffset);
|
||||||
rectDataMap.Add(packingRects.Count, lightmapRectData);
|
rectDataMap.Add(packingRects.Count, lightmapRectData);
|
||||||
|
|
||||||
var light = cell.LightList[polyIdx];
|
var light = cell.LightList[polyIdx];
|
||||||
|
@ -249,8 +249,9 @@ public partial class Mission : Node3D
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private LightmapRectData ProcessCellSurfaceData(Dictionary<int, MeshSurfaceData> surfaceDataMap, WorldRep.Cell cell, int cellIdx, int polyIdx, int indicesOffset)
|
private LightmapRectData ProcessCellSurfaceData(Dictionary<int, MeshSurfaceData> surfaceDataMap, WorldRep worldRep, int cellIdx, int polyIdx, int indicesOffset)
|
||||||
{
|
{
|
||||||
|
var cell = worldRep.Cells[cellIdx];
|
||||||
var poly = cell.Polys[polyIdx];
|
var poly = cell.Polys[polyIdx];
|
||||||
var normal = cell.Planes[poly.PlaneId].Normal.ToGodotVec3();
|
var normal = cell.Planes[poly.PlaneId].Normal.ToGodotVec3();
|
||||||
var vertices = new List<Vector3>();
|
var vertices = new List<Vector3>();
|
||||||
|
@ -266,7 +267,8 @@ public partial class Mission : Node3D
|
||||||
|
|
||||||
var renderPoly = cell.RenderPolys[polyIdx];
|
var renderPoly = cell.RenderPolys[polyIdx];
|
||||||
var light = cell.LightList[polyIdx];
|
var light = cell.LightList[polyIdx];
|
||||||
var textureId = CalcBaseUV(cell, poly, renderPoly, light, textureUvs, lightmapUvs, indicesOffset);
|
var lightmapScale = worldRep.DataHeader.LightmapScale;
|
||||||
|
var textureId = CalcBaseUV(cell, poly, renderPoly, light, textureUvs, lightmapUvs, lightmapScale, indicesOffset);
|
||||||
|
|
||||||
if (!surfaceDataMap.ContainsKey(textureId))
|
if (!surfaceDataMap.ContainsKey(textureId))
|
||||||
{
|
{
|
||||||
|
@ -297,9 +299,9 @@ public partial class Mission : Node3D
|
||||||
if (info.cellIndex >= cells.Length) GD.Print($"CellIndex too big: {info.cellIndex}/{cells.Length}");
|
if (info.cellIndex >= cells.Length) GD.Print($"CellIndex too big: {info.cellIndex}/{cells.Length}");
|
||||||
if (info.lightmapIndex >= cells[info.cellIndex].Lightmaps.Length) GD.Print($"LightmapIndex too big: {info.lightmapIndex}/{cells[info.cellIndex].Lightmaps.Length}");
|
if (info.lightmapIndex >= cells[info.cellIndex].Lightmaps.Length) GD.Print($"LightmapIndex too big: {info.lightmapIndex}/{cells[info.cellIndex].Lightmaps.Length}");
|
||||||
var lightmap = cells[info.cellIndex].Lightmaps[info.lightmapIndex];
|
var lightmap = cells[info.cellIndex].Lightmaps[info.lightmapIndex];
|
||||||
var layers = (uint)lightmap.Pixels.GetLength(0);
|
var layers = (uint)lightmap.Layers;
|
||||||
var height = (uint)lightmap.Pixels.GetLength(1);
|
var height = (uint)lightmap.Height;
|
||||||
var width = (uint)lightmap.Pixels.GetLength(2);
|
var width = (uint)lightmap.Width;
|
||||||
for (uint y = 0; y < height; y++)
|
for (uint y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
for (uint x = 0; x < width; x++)
|
for (uint x = 0; x < width; x++)
|
||||||
|
@ -344,6 +346,7 @@ public partial class Mission : Node3D
|
||||||
WorldRep.Cell.LightmapInfo light,
|
WorldRep.Cell.LightmapInfo light,
|
||||||
List<Vector2> textureUvs,
|
List<Vector2> textureUvs,
|
||||||
List<Vector2> lightmapUvs,
|
List<Vector2> lightmapUvs,
|
||||||
|
float lightmapScale,
|
||||||
int cellIdxOffset)
|
int cellIdxOffset)
|
||||||
{
|
{
|
||||||
// TODO: This is slightly hardcoded for ND. Check other stuff at some point. Should be handled in LG side imo
|
// TODO: This is slightly hardcoded for ND. Check other stuff at some point. Should be handled in LG side imo
|
||||||
|
@ -356,8 +359,8 @@ public partial class Mission : Node3D
|
||||||
var baseU = renderPoly.TextureBases.Item1;
|
var baseU = renderPoly.TextureBases.Item1;
|
||||||
var baseV = renderPoly.TextureBases.Item2;
|
var baseV = renderPoly.TextureBases.Item2;
|
||||||
|
|
||||||
var txUScale = 64.0f / texture.GetWidth();
|
var txUScale = 64.0f / lightmapScale / texture.GetWidth();
|
||||||
var txVScale = 64.0f / texture.GetHeight();
|
var txVScale = 64.0f / lightmapScale / texture.GetHeight();
|
||||||
var lmUScale = 4.0f / light.Width;
|
var lmUScale = 4.0f / light.Width;
|
||||||
var lmVScale = 4.0f / light.Height;
|
var lmVScale = 4.0f / light.Height;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue