|
|
@ -7,6 +7,12 @@ public class BrushModel |
|
|
private readonly string name; |
|
|
private readonly string name; |
|
|
private readonly List<Mesh> meshes = new List<Mesh>(); |
|
|
private readonly List<Mesh> meshes = new List<Mesh>(); |
|
|
|
|
|
|
|
|
|
|
|
// Reusable temporary data containers
|
|
|
|
|
|
private readonly List<Vector3> tempVertices = new List<Vector3>(); |
|
|
|
|
|
private readonly List<Vector2> tempTextureUVs = new List<Vector2>(); |
|
|
|
|
|
private readonly List<Vector2> tempLightmapUVs = new List<Vector2>(); |
|
|
|
|
|
private readonly List<ushort> tempIndices = new List<ushort>(); |
|
|
|
|
|
|
|
|
public BrushModel(string name) |
|
|
public BrushModel(string name) |
|
|
{ |
|
|
{ |
|
|
this.name = name; |
|
|
this.name = name; |
|
|
@ -17,48 +23,12 @@ public class BrushModel |
|
|
var subModels = model.SubModels; |
|
|
var subModels = model.SubModels; |
|
|
var surfaces = model.Surfaces; |
|
|
var surfaces = model.Surfaces; |
|
|
|
|
|
|
|
|
List<Vector3> vertices = new List<Vector3>(); |
|
|
|
|
|
List<Vector2> textureUVs = new List<Vector2>(); |
|
|
|
|
|
List<Vector2> lightmapUVs = new List<Vector2>(); |
|
|
|
|
|
List<ushort> indices = new List<ushort>(); |
|
|
|
|
|
|
|
|
|
|
|
for (int surfIdx = 0; surfIdx < surfaces.Length; ++surfIdx) |
|
|
|
|
|
|
|
|
for (int modelIdx = 0; modelIdx < subModels.Length; ++modelIdx) |
|
|
{ |
|
|
{ |
|
|
foreach (var polyVerts in surfaces[surfIdx].GetPolygons()) |
|
|
|
|
|
{ |
|
|
|
|
|
vertices.Clear(); |
|
|
|
|
|
textureUVs.Clear(); |
|
|
|
|
|
lightmapUVs.Clear(); |
|
|
|
|
|
indices.Clear(); |
|
|
|
|
|
|
|
|
|
|
|
for (int vertIdx = 0; vertIdx < polyVerts.Length; ++vertIdx) |
|
|
|
|
|
{ |
|
|
|
|
|
vertices.Add(polyVerts[vertIdx].position.ToVector3().ToUnity()); |
|
|
|
|
|
textureUVs.Add(polyVerts[vertIdx].textureUV.ToVector2()); |
|
|
|
|
|
lightmapUVs.Add(polyVerts[vertIdx].lightmapUV.ToVector2()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Reconstruct triangle fan
|
|
|
|
|
|
for (ushort index = 2; index < polyVerts.Length; ++index) |
|
|
|
|
|
{ |
|
|
|
|
|
indices.Add(0); |
|
|
|
|
|
indices.Add((ushort)(index - 1)); |
|
|
|
|
|
indices.Add(index); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Mesh mesh = new Mesh(); |
|
|
|
|
|
mesh.SetVertices(vertices); |
|
|
|
|
|
mesh.SetUVs(0, textureUVs); |
|
|
|
|
|
mesh.SetUVs(1, lightmapUVs); |
|
|
|
|
|
mesh.SetIndices(indices, MeshTopology.Triangles, 0); |
|
|
|
|
|
mesh.RecalculateNormals(); |
|
|
|
|
|
mesh.UploadMeshData(true); |
|
|
|
|
|
meshes.Add(mesh); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var texNum = surfaces[surfIdx].TextureInfo.Texture.TextureNum; |
|
|
|
|
|
|
|
|
var headNode = subModels[modelIdx].GetHeadNode(model); |
|
|
|
|
|
CreateNodeMeshes(headNode, surfaces); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// DEBUG
|
|
|
// DEBUG
|
|
|
var go = new GameObject(name); |
|
|
var go = new GameObject(name); |
|
|
var mat = new Material(Shader.Find("Universal Render Pipeline/Simple Lit")); |
|
|
var mat = new Material(Shader.Find("Universal Render Pipeline/Simple Lit")); |
|
|
@ -83,4 +53,59 @@ public class BrushModel |
|
|
|
|
|
|
|
|
go.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity); |
|
|
go.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void CreateNodeMeshes(QNode node, QSurface[] surfaces) |
|
|
|
|
|
{ |
|
|
|
|
|
if (node.contents < 0) // Leaf node
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
CreateSurfaceMeshes(node, surfaces); |
|
|
|
|
|
|
|
|
|
|
|
foreach (var childNode in node.Children) |
|
|
|
|
|
{ |
|
|
|
|
|
CreateNodeMeshes(childNode, surfaces); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void CreateSurfaceMeshes(QNode node, QSurface[] surfaces) |
|
|
|
|
|
{ |
|
|
|
|
|
for (int surfIdx = 0; surfIdx < node.numSurfaces; ++surfIdx) |
|
|
|
|
|
{ |
|
|
|
|
|
var surface = surfaces[node.firstSurface + surfIdx]; |
|
|
|
|
|
|
|
|
|
|
|
foreach (var polyVerts in surface.GetPolygons()) |
|
|
|
|
|
{ |
|
|
|
|
|
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); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Mesh mesh = new Mesh(); |
|
|
|
|
|
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); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var texNum = surface.TextureInfo.Texture.TextureNum; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |