diff --git a/project/code/Mission.cs b/project/code/Mission.cs index 78771e5..b14e358 100644 --- a/project/code/Mission.cs +++ b/project/code/Mission.cs @@ -164,7 +164,7 @@ public partial class Mission : Node3D } // Transform UVs - var lightmapUvs = surfaceArrays[rect.Id][(int)Mesh.ArrayType.TexUV].As(); + var lightmapUvs = surfaceArrays[rect.Id][(int)Mesh.ArrayType.TexUV2].As(); for (var i = 0; i < lightmapUvs.Length; i++) { var uv = lightmapUvs[i]; @@ -182,13 +182,13 @@ public partial class Mission : Node3D v = (rect.Y + rect.Height * v) / (int)bounds.Height; lightmapUvs[i] = new Vector2(u, v); } - surfaceArrays[rect.Id][(int)Mesh.ArrayType.TexUV] = lightmapUvs; + surfaceArrays[rect.Id][(int)Mesh.ArrayType.TexUV2] = lightmapUvs; } return image; } - private static List BuildSurfaceArrays( + private List BuildSurfaceArrays( WorldRep.Cell cell, int maxPolyIdx, out PackingRectangle[] packingRects) @@ -202,7 +202,8 @@ public partial class Mission : Node3D var vertices = new List(); var normals = new List(); var indices = new List(); - var uvs = new List(); + var textureUvs = new List(); + var lightmapUvs = new List(); var poly = cell.Polys[i]; var normal = cell.Planes[poly.PlaneId].Normal.ToGodotVec3(); @@ -226,7 +227,7 @@ public partial class Mission : Node3D var renderPoly = cell.RenderPolys[i]; var light = cell.LightList[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; @@ -235,7 +236,8 @@ public partial class Mission : Node3D array[(int)Mesh.ArrayType.Vertex] = vertices.ToArray(); array[(int)Mesh.ArrayType.Normal] = normals.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); } @@ -284,46 +286,68 @@ public partial class Mission : Node3D return meshInstance; } - private static void CalcBaseUV( + private void CalcBaseUV( WorldRep.Cell cell, WorldRep.Cell.Poly poly, WorldRep.Cell.RenderPoly renderPoly, WorldRep.Cell.LightmapInfo light, + List textureUvs, List lightmapUvs, 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 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 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 vv = texV.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 - if (uv == 0.0) { + var txUVec = texU * txUScale / uu; + var txVVec = texV * txVScale / vv; var lmUVec = texU * lmUScale / uu; var lmVVec = texV * lmVScale / vv; for (var i = 0; i < poly.VertexCount; i++) { 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 txUV = new Vector2(delta.Dot(txUVec) + txUBase, delta.Dot(txVVec) + txVBase); var lmUV = new Vector2(delta.Dot(lmUVec) + lmUBase, delta.Dot(lmVVec) + lmVBase); + textureUvs.Add(txUV); lightmapUvs.Add(lmUV); } } else { 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 lmVv = vv * lmUScale * denom; 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 du = delta.Dot(texU); 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); + textureUvs.Add(txUV); lightmapUvs.Add(lmUV); } }