Calculate texture UVs and move lightmap UVs to UV2

This commit is contained in:
Jarrod Doyle 2024-08-05 19:49:36 +01:00
parent da3f9b9203
commit 74f4d0e7c6
Signed by: Jayrude
GPG Key ID: 38B57B16E7C0ADF7
1 changed files with 42 additions and 15 deletions

View File

@ -164,7 +164,7 @@ public partial class Mission : Node3D
} }
// Transform UVs // Transform UVs
var lightmapUvs = surfaceArrays[rect.Id][(int)Mesh.ArrayType.TexUV].As<Vector2[]>(); var lightmapUvs = surfaceArrays[rect.Id][(int)Mesh.ArrayType.TexUV2].As<Vector2[]>();
for (var i = 0; i < lightmapUvs.Length; i++) for (var i = 0; i < lightmapUvs.Length; i++)
{ {
var uv = lightmapUvs[i]; var uv = lightmapUvs[i];
@ -182,13 +182,13 @@ public partial class Mission : Node3D
v = (rect.Y + rect.Height * v) / (int)bounds.Height; v = (rect.Y + rect.Height * v) / (int)bounds.Height;
lightmapUvs[i] = new Vector2(u, v); lightmapUvs[i] = new Vector2(u, v);
} }
surfaceArrays[rect.Id][(int)Mesh.ArrayType.TexUV] = lightmapUvs; surfaceArrays[rect.Id][(int)Mesh.ArrayType.TexUV2] = lightmapUvs;
} }
return image; return image;
} }
private static List<Godot.Collections.Array> BuildSurfaceArrays( private List<Godot.Collections.Array> BuildSurfaceArrays(
WorldRep.Cell cell, WorldRep.Cell cell,
int maxPolyIdx, int maxPolyIdx,
out PackingRectangle[] packingRects) out PackingRectangle[] packingRects)
@ -202,7 +202,8 @@ public partial class Mission : Node3D
var vertices = new List<Vector3>(); var vertices = new List<Vector3>();
var normals = new List<Vector3>(); var normals = new List<Vector3>();
var indices = new List<int>(); var indices = new List<int>();
var uvs = new List<Vector2>(); var textureUvs = new List<Vector2>();
var lightmapUvs = new List<Vector2>();
var poly = cell.Polys[i]; var poly = cell.Polys[i];
var normal = cell.Planes[poly.PlaneId].Normal.ToGodotVec3(); var normal = cell.Planes[poly.PlaneId].Normal.ToGodotVec3();
@ -226,7 +227,7 @@ public partial class Mission : Node3D
var renderPoly = cell.RenderPolys[i]; var renderPoly = cell.RenderPolys[i];
var light = cell.LightList[i]; var light = cell.LightList[i];
packingRects[i] = new PackingRectangle(0, 0, light.Width, light.Height, i); packingRects[i] = new PackingRectangle(0, 0, light.Width, light.Height, i);
CalcBaseUV(cell, poly, renderPoly, light, uvs, cellIdxOffset); CalcBaseUV(cell, poly, renderPoly, light, textureUvs, lightmapUvs, cellIdxOffset);
cellIdxOffset += poly.VertexCount; cellIdxOffset += poly.VertexCount;
@ -235,7 +236,8 @@ public partial class Mission : Node3D
array[(int)Mesh.ArrayType.Vertex] = vertices.ToArray(); array[(int)Mesh.ArrayType.Vertex] = vertices.ToArray();
array[(int)Mesh.ArrayType.Normal] = normals.ToArray(); array[(int)Mesh.ArrayType.Normal] = normals.ToArray();
array[(int)Mesh.ArrayType.Index] = indices.ToArray(); array[(int)Mesh.ArrayType.Index] = indices.ToArray();
array[(int)Mesh.ArrayType.TexUV] = uvs.ToArray(); array[(int)Mesh.ArrayType.TexUV] = textureUvs.ToArray();
array[(int)Mesh.ArrayType.TexUV2] = lightmapUvs.ToArray();
surfacesArrays.Add(array); surfacesArrays.Add(array);
} }
@ -284,46 +286,68 @@ public partial class Mission : Node3D
return meshInstance; return meshInstance;
} }
private static void CalcBaseUV( private void CalcBaseUV(
WorldRep.Cell cell, WorldRep.Cell cell,
WorldRep.Cell.Poly poly, WorldRep.Cell.Poly poly,
WorldRep.Cell.RenderPoly renderPoly, WorldRep.Cell.RenderPoly renderPoly,
WorldRep.Cell.LightmapInfo light, WorldRep.Cell.LightmapInfo light,
List<Vector2> textureUvs,
List<Vector2> lightmapUvs, List<Vector2> lightmapUvs,
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
// TODO: This is a mess lol // TODO: This is a mess lol
var textureId = renderPoly.TextureId;
// !HACK: Sky textures :)
if (textureId >= _textures.Count)
{
textureId = 0;
}
var texture = _textures[textureId];
var texU = renderPoly.TextureVectors.Item1.ToGodotVec3(); var texU = renderPoly.TextureVectors.Item1.ToGodotVec3();
var texV = renderPoly.TextureVectors.Item2.ToGodotVec3(); var texV = renderPoly.TextureVectors.Item2.ToGodotVec3();
var baseU = renderPoly.TextureBases.Item1;
var baseV = renderPoly.TextureBases.Item2;
var txUScale = 64.0f / texture.GetWidth();
var txVScale = 64.0f / texture.GetHeight();
var lmUScale = 4.0f / light.Width;
var lmVScale = 4.0f / light.Height;
var txUBase = baseU * txUScale;
var txVBase = baseV * txVScale;
var lmUBase = lmUScale * (baseU + (0.5f - light.Bases.Item1) / 4.0f);
var lmVBase = lmVScale * (baseV + (0.5f - light.Bases.Item2) / 4.0f);
var uu = texU.Dot(texU); var uu = texU.Dot(texU);
var vv = texV.Dot(texV); var vv = texV.Dot(texV);
var uv = texU.Dot(texV); var uv = texU.Dot(texV);
var lmUScale = 4.0f / light.Width;
var lmVScale = 4.0f / light.Height;
var baseU = renderPoly.TextureBases.Item1;
var baseV = renderPoly.TextureBases.Item2;
var lmUBase = lmUScale * (baseU + (0.5f - light.Bases.Item1) / 4.0f);
var lmVBase = lmVScale * (baseV + (0.5f - light.Bases.Item2) / 4.0f);
var anchor = cell.Vertices[cell.Indices[cellIdxOffset + 0]].ToGodotVec3(); // TODO: This probably shouldn't be hardcoded idx 0 var anchor = cell.Vertices[cell.Indices[cellIdxOffset + 0]].ToGodotVec3(); // TODO: This probably shouldn't be hardcoded idx 0
if (uv == 0.0) if (uv == 0.0)
{ {
var txUVec = texU * txUScale / uu;
var txVVec = texV * txVScale / vv;
var lmUVec = texU * lmUScale / uu; var lmUVec = texU * lmUScale / uu;
var lmVVec = texV * lmVScale / vv; var lmVVec = texV * lmVScale / vv;
for (var i = 0; i < poly.VertexCount; i++) for (var i = 0; i < poly.VertexCount; i++)
{ {
var v = cell.Vertices[cell.Indices[cellIdxOffset + i]].ToGodotVec3(); var v = cell.Vertices[cell.Indices[cellIdxOffset + i]].ToGodotVec3();
var delta = new Vector3(v.X - anchor.X, v.Y - anchor.Y, v.Z - anchor.Z); var delta = new Vector3(v.X - anchor.X, v.Y - anchor.Y, v.Z - anchor.Z);
var txUV = new Vector2(delta.Dot(txUVec) + txUBase, delta.Dot(txVVec) + txVBase);
var lmUV = new Vector2(delta.Dot(lmUVec) + lmUBase, delta.Dot(lmVVec) + lmVBase); var lmUV = new Vector2(delta.Dot(lmUVec) + lmUBase, delta.Dot(lmVVec) + lmVBase);
textureUvs.Add(txUV);
lightmapUvs.Add(lmUV); lightmapUvs.Add(lmUV);
} }
} }
else else
{ {
var denom = 1.0f / (uu * vv - uv * uv); var denom = 1.0f / (uu * vv - uv * uv);
var txUu = uu * txVScale * denom;
var txVv = vv * txUScale * denom;
var txUvu = txUScale * denom * uv;
var txUvv = txVScale * denom * uv;
var lmUu = uu * lmVScale * denom; var lmUu = uu * lmVScale * denom;
var lmVv = vv * lmUScale * denom; var lmVv = vv * lmUScale * denom;
var lmUvu = lmUScale * denom * uv; var lmUvu = lmUScale * denom * uv;
@ -334,7 +358,10 @@ public partial class Mission : Node3D
var delta = new Vector3(v.X - anchor.X, v.Y - anchor.Y, v.Z - anchor.Z); var delta = new Vector3(v.X - anchor.X, v.Y - anchor.Y, v.Z - anchor.Z);
var du = delta.Dot(texU); var du = delta.Dot(texU);
var dv = delta.Dot(texV); var dv = delta.Dot(texV);
var txUV = new Vector2(txUBase + txVv * du - txUvu * dv, txVBase + txUu * dv - txUvv * du);
var lmUV = new Vector2(lmUBase + lmVv * du - lmUvu * dv, lmVBase + lmUu * dv - lmUvv * du); var lmUV = new Vector2(lmUBase + lmVv * du - lmUvu * dv, lmVBase + lmUu * dv - lmUvv * du);
textureUvs.Add(txUV);
lightmapUvs.Add(lmUV); lightmapUvs.Add(lmUV);
} }
} }