Compare commits
2 Commits
d125fb2cd3
...
cbf309aaa4
Author | SHA1 | Date |
---|---|---|
Jarrod Doyle | cbf309aaa4 | |
Jarrod Doyle | bb617ffc52 |
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
|
@ -28,6 +29,16 @@ public class WorldRep : IChunk
|
||||||
DataSize = reader.ReadUInt32();
|
DataSize = reader.ReadUInt32();
|
||||||
CellCount = reader.ReadUInt32();
|
CellCount = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public readonly float LightmapScaleMultiplier()
|
||||||
|
{
|
||||||
|
return Math.Sign(LightmapScale) switch
|
||||||
|
{
|
||||||
|
1 => LightmapScale,
|
||||||
|
-1 => 1.0f / LightmapScale,
|
||||||
|
_ => 1.0f,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct Cell
|
public struct Cell
|
||||||
|
@ -137,6 +148,63 @@ public class WorldRep : IChunk
|
||||||
return Vector4.Zero;
|
return Vector4.Zero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public readonly byte[] AsBytesRgba()
|
||||||
|
{
|
||||||
|
var length = Width * Height * 4;
|
||||||
|
var bytes = new byte[length];
|
||||||
|
for (var i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
bytes[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: might be faster to do these fors in the switch?
|
||||||
|
for (var z = 0; z < Layers; z++)
|
||||||
|
{
|
||||||
|
for (var y = 0; y < Height; y++)
|
||||||
|
{
|
||||||
|
for (var x = 0; x < Width; x++)
|
||||||
|
{
|
||||||
|
var pIdx = 0 + x * Bpp + y * Bpp * Width + z * Bpp * Width * Height;
|
||||||
|
var r = 0;
|
||||||
|
var g = 0;
|
||||||
|
var b = 0;
|
||||||
|
var a = 0;
|
||||||
|
switch (Bpp)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
var raw1 = Pixels[pIdx];
|
||||||
|
r = raw1;
|
||||||
|
g = raw1;
|
||||||
|
b = raw1;
|
||||||
|
a = 255;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
var raw2 = Pixels[pIdx] + (Pixels[pIdx + 1] << 8);
|
||||||
|
r = (int)(255 * (raw2 & 31) / 31.0f);
|
||||||
|
g = (int)(255 * ((raw2 >> 5) & 31) / 31.0f);
|
||||||
|
b = (int)(255 * ((raw2 >> 10) & 31) / 31.0f);
|
||||||
|
a = 255;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
r = Pixels[pIdx + 2];
|
||||||
|
g = Pixels[pIdx + 1];
|
||||||
|
b = Pixels[pIdx];
|
||||||
|
a = Pixels[pIdx + 3];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bIdx = x * 4 + y * 4 * Width;
|
||||||
|
bytes[bIdx] = (byte)Math.Min(255, bytes[bIdx] + r);
|
||||||
|
bytes[bIdx + 1] = (byte)Math.Min(255, bytes[bIdx + 1] + g);
|
||||||
|
bytes[bIdx + 2] = (byte)Math.Min(255, bytes[bIdx + 2] + b);
|
||||||
|
bytes[bIdx + 3] = (byte)Math.Min(255, bytes[bIdx + 3] + a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte VertexCount { get; set; }
|
public byte VertexCount { get; set; }
|
||||||
|
|
|
@ -267,7 +267,7 @@ 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 lightmapScale = worldRep.DataHeader.LightmapScale;
|
var lightmapScale = worldRep.DataHeader.LightmapScaleMultiplier();
|
||||||
var textureId = CalcBaseUV(cell, poly, renderPoly, light, textureUvs, lightmapUvs, lightmapScale, indicesOffset);
|
var textureId = CalcBaseUV(cell, poly, renderPoly, light, textureUvs, lightmapUvs, lightmapScale, indicesOffset);
|
||||||
|
|
||||||
if (!surfaceDataMap.ContainsKey(textureId))
|
if (!surfaceDataMap.ContainsKey(textureId))
|
||||||
|
@ -299,23 +299,8 @@ 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.Layers;
|
var cellLm = Image.CreateFromData(lightmap.Width, lightmap.Height, false, Image.Format.Rgba8, lightmap.AsBytesRgba());
|
||||||
var height = (uint)lightmap.Height;
|
image.BlitRect(cellLm, new Rect2I(0, 0, lightmap.Width, lightmap.Height), new Vector2I((int)rect.X, (int)rect.Y));
|
||||||
var width = (uint)lightmap.Width;
|
|
||||||
for (uint y = 0; y < height; y++)
|
|
||||||
{
|
|
||||||
for (uint x = 0; x < width; x++)
|
|
||||||
{
|
|
||||||
var rawColour = System.Numerics.Vector4.Zero;
|
|
||||||
for (uint l = 0; l < layers; l++)
|
|
||||||
{
|
|
||||||
rawColour += lightmap.GetPixel(l, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
var colour = new Color(MathF.Min(rawColour.X, 1.0f), MathF.Min(rawColour.Y, 1.0f), MathF.Min(rawColour.Z, 1.0f), MathF.Min(rawColour.W, 1.0f));
|
|
||||||
image.SetPixel((int)(rect.X + x), (int)(rect.Y + y), colour);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!surfaceDataMap.ContainsKey(info.textureId)) GD.Print("Invalid SurfaceDataMap key");
|
if (!surfaceDataMap.ContainsKey(info.textureId)) GD.Print("Invalid SurfaceDataMap key");
|
||||||
surfaceDataMap[info.textureId].TransformUv2s(info.uvStart, info.uvEnd, (uv) =>
|
surfaceDataMap[info.textureId].TransformUv2s(info.uvStart, info.uvEnd, (uv) =>
|
||||||
|
|
Loading…
Reference in New Issue