From 59a64473b04641a08b3480c2222da060c00b6668 Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Mon, 19 Jul 2021 16:02:56 +0200 Subject: [PATCH] Marshal only one polygon per brush model surface for conversion into a Unity mesh. Any subsequent polygons are pre-tessellated versions meant for the water warping effect, which we won't need as this will be handled by GPU tessellation. Fixed garbled water surface caused by having two polygon meshes overlapping. --- Assets/Scripts/Data/QModel.cs | 18 +++++---------- Assets/Scripts/Support/BrushModel.cs | 33 ++++++++++++++-------------- 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/Assets/Scripts/Data/QModel.cs b/Assets/Scripts/Data/QModel.cs index 994410f..e20c332 100644 --- a/Assets/Scripts/Data/QModel.cs +++ b/Assets/Scripts/Data/QModel.cs @@ -309,21 +309,13 @@ public struct QSurface // This is safe as the Quake engine guarantees this pointer is never null (see: Mod_LoadFaces) public QTexInfo TextureInfo => Marshal.PtrToStructure(texInfo); - - public IEnumerable GetPolygons() + + public QGLPolyVert[] GetPolygon() { - // This is so nasty. We have to deconstruct a linked list of variable-sized structs. Yuck. + // We have to calculate the position inside the struct where the variable-sized array of vertices starts int offset = Marshal.SizeOf() * 2 + Marshal.SizeOf(); - - IntPtr polyPtr = polys; - while (polyPtr != IntPtr.Zero) - { - QGLPoly polygon = Marshal.PtrToStructure(polyPtr); - QGLPolyVert[] vertices = IntPtr.Add(polyPtr, offset).ToStructArray(polygon.numVerts); - yield return vertices; - - polyPtr = polygon.next; - } + QGLPoly polygon = Marshal.PtrToStructure(polys); + return IntPtr.Add(polys, offset).ToStructArray(polygon.numVerts); } } diff --git a/Assets/Scripts/Support/BrushModel.cs b/Assets/Scripts/Support/BrushModel.cs index e2e13be..cbb4658 100644 --- a/Assets/Scripts/Support/BrushModel.cs +++ b/Assets/Scripts/Support/BrushModel.cs @@ -100,25 +100,24 @@ public class BrushModel for (int surfIdx = 0; surfIdx < surfaces.Count; ++surfIdx) { - foreach (var polyVerts in surfaces[surfIdx].GetPolygons()) + var polyVerts = surfaces[surfIdx].GetPolygon(); + + for (int vertIdx = 0; vertIdx < polyVerts.Length; ++vertIdx) { - for (int vertIdx = 0; vertIdx < polyVerts.Length; ++vertIdx) - { - tempVertices.Add(polyVerts[vertIdx].position.ToUnityPosition()); - 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((ushort)vertOffset); - tempIndices.Add((ushort)(vertOffset + index - 1)); - tempIndices.Add((ushort)(vertOffset + index)); - } - - vertOffset += polyVerts.Length; + tempVertices.Add(polyVerts[vertIdx].position.ToUnityPosition()); + 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((ushort)vertOffset); + tempIndices.Add((ushort)(vertOffset + index - 1)); + tempIndices.Add((ushort)(vertOffset + index)); } + + vertOffset += polyVerts.Length; } Mesh mesh = new Mesh();