Browse Source

Group surfaces based on texture and lightmap, while keeping them grouped inside each brush submodel

console
Nico de Poel 5 years ago
parent
commit
5598ceeeed
  1. 110
      Assets/Scripts/Modules/BrushModel.cs

110
Assets/Scripts/Modules/BrushModel.cs

@ -37,7 +37,46 @@ public class BrushModel
modelGO.transform.SetParent(rootGameObject.transform);
var headNode = subModels[modelIdx].GetHeadNode(model);
CreateNodeMeshes(headNode, surfaces, modelGO);
var surfaceGroups = new Dictionary<(string, int), List<QSurface>>();
GroupSurfaces(headNode, surfaces, surfaceGroups);
foreach (var group in surfaceGroups)
{
var key = group.Key;
var groupGO = new GameObject($"T{key.Item1}_L{key.Item2}");
groupGO.transform.SetParent(modelGO.transform);
for (int i = 0; i < group.Value.Count; ++i)
{
CreateSurfaceMeshes(group.Value[i], $"{i}", groupGO);
}
}
}
}
private void GroupSurfaces(QNode node, QSurface[] surfaces, Dictionary<(string, int), List<QSurface>> surfaceGroups)
{
if (node.contents < 0) // Leaf node
return;
for (int surfIdx = 0; surfIdx < node.numSurfaces; ++surfIdx)
{
var surface = surfaces[node.firstSurface + surfIdx];
string texName = surface.TextureInfo.Texture.name;
int lightNum = surface.lightmapTextureNum;
var key = (texName, lightNum);
if (!surfaceGroups.ContainsKey(key))
surfaceGroups[key] = new List<QSurface>();
surfaceGroups[key].Add(surface);
}
foreach (var childNode in node.Children)
{
GroupSurfaces(childNode, surfaces, surfaceGroups);
}
}
@ -49,7 +88,11 @@ public class BrushModel
var nodeGO = new GameObject("Node");
nodeGO.transform.SetParent(parentGO.transform);
CreateSurfaceMeshes(node, surfaces, nodeGO);
for (int surfIdx = 0; surfIdx < node.numSurfaces; ++surfIdx)
{
var surface = surfaces[node.firstSurface + surfIdx];
CreateSurfaceMeshes(surface, $"{node.firstSurface + surfIdx}", nodeGO);
}
foreach (var childNode in node.Children)
{
@ -57,48 +100,41 @@ public class BrushModel
}
}
private void CreateSurfaceMeshes(QNode node, QSurface[] surfaces, GameObject nodeGO)
private void CreateSurfaceMeshes(QSurface surface, string key, GameObject nodeGO)
{
for (int surfIdx = 0; surfIdx < node.numSurfaces; ++surfIdx)
foreach (var polyVerts in surface.GetPolygons())
{
var surface = surfaces[node.firstSurface + surfIdx];
tempVertices.Clear();
tempTextureUVs.Clear();
tempLightmapUVs.Clear();
tempIndices.Clear();
foreach (var polyVerts in surface.GetPolygons())
for (int vertIdx = 0; vertIdx < polyVerts.Length; ++vertIdx)
{
tempVertices.Clear();
tempTextureUVs.Clear();
tempLightmapUVs.Clear();
tempIndices.Clear();
for (int vertIdx = 0; vertIdx < polyVerts.Length; ++vertIdx)
{
tempVertices.Add(polyVerts[vertIdx].position.ToVector3().ToUnity());
tempTextureUVs.Add(polyVerts[vertIdx].textureUV.ToVector2());
tempLightmapUVs.Add(polyVerts[vertIdx].lightmapUV.ToVector2());
}
// Reconstruct triangle fan
for (ushort index = 2; index < polyVerts.Length; ++index)
{
tempIndices.Add(0);
tempIndices.Add((ushort) (index - 1));
tempIndices.Add(index);
}
tempVertices.Add(polyVerts[vertIdx].position.ToVector3().ToUnity());
tempTextureUVs.Add(polyVerts[vertIdx].textureUV.ToVector2());
tempLightmapUVs.Add(polyVerts[vertIdx].lightmapUV.ToVector2());
}
Mesh mesh = new Mesh();
mesh.name = $"Surface_{node.firstSurface + surfIdx}";
mesh.SetVertices(tempVertices);
mesh.SetUVs(0, tempTextureUVs);
mesh.SetUVs(1, tempLightmapUVs);
mesh.SetIndices(tempIndices, MeshTopology.Triangles, 0);
mesh.RecalculateNormals();
mesh.UploadMeshData(true);
meshes.Add(mesh);
CreateMeshObject(mesh, nodeGO);
// Reconstruct triangle fan
for (ushort index = 2; index < polyVerts.Length; ++index)
{
tempIndices.Add(0);
tempIndices.Add((ushort) (index - 1));
tempIndices.Add(index);
}
var texNum = surface.TextureInfo.Texture.TextureNum;
Mesh mesh = new Mesh();
mesh.name = $"Surface_{key}";
mesh.SetVertices(tempVertices);
mesh.SetUVs(0, tempTextureUVs);
mesh.SetUVs(1, tempLightmapUVs);
mesh.SetIndices(tempIndices, MeshTopology.Triangles, 0);
mesh.RecalculateNormals();
mesh.UploadMeshData(true);
meshes.Add(mesh);
CreateMeshObject(mesh, nodeGO);
}
}

Loading…
Cancel
Save