From dec2be66c6fb9c4db76a93a591146bdc37f98035 Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Sun, 18 Apr 2021 12:17:33 +0200 Subject: [PATCH] Keep track of already duplicated vertices and reuse those for triangles that need them. Fixes vertex counts being way too high because seam vertices would get duplicated multiple times. --- Assets/Scripts/Modules/AliasModel.cs | 35 +++++++++++++++++----------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/Assets/Scripts/Modules/AliasModel.cs b/Assets/Scripts/Modules/AliasModel.cs index 544613b..0e16c6b 100644 --- a/Assets/Scripts/Modules/AliasModel.cs +++ b/Assets/Scripts/Modules/AliasModel.cs @@ -5,7 +5,7 @@ using UnityEngine; public class AliasModel { - public static readonly Regex AnimationRegex = new Regex(@"^[a-zA-Z]+"); + private static readonly Regex AnimationRegex = new Regex(@"^[a-zA-Z]+"); private readonly string name; private readonly List<(int, Mesh)> animationMeshes = new List<(int, Mesh)>(); @@ -84,7 +84,7 @@ public class AliasModel int startFrame = 0; for (int frameIdx = 0; frameIdx < header.numFrames; ++frameIdx) { - string frameName = AliasModel.AnimationRegex.Match(header.frames[frameIdx].name).Value; + string frameName = AnimationRegex.Match(header.frames[frameIdx].name).Value; if (animName == null) { animName = frameName; @@ -116,8 +116,8 @@ public class AliasModel private static void PreprocessMeshData(QAliasHeader header, QTriangle[] triangles, ref QTriVertex[][] poseVertices, ref QSTVert[] stVerts) { - int newVertCount = 0; - + HashSet seamVertices = new HashSet(); + // First count how many new vertices we need to make, so we can preallocate the required arrays for (int triIdx = 0; triIdx < header.numTriangles; ++triIdx) { @@ -126,24 +126,25 @@ public class AliasModel for (int indIdx = 0; indIdx < 3; ++indIdx) { - int index = triangles[triIdx].vertIndex[indIdx]; - if (stVerts[index].onSeam == 0) + int vertIndex = triangles[triIdx].vertIndex[indIdx]; + if (stVerts[vertIndex].onSeam == 0) continue; // Back-side vertex on seam, needs to be duplicated and corrected - ++newVertCount; + seamVertices.Add(vertIndex); } } - if (newVertCount == 0) + if (seamVertices.Count == 0) return; - Array.Resize(ref stVerts, header.numVerts + newVertCount); + Array.Resize(ref stVerts, header.numVerts + seamVertices.Count); for (int frameIdx = 0; frameIdx < header.numFrames; ++frameIdx) { - Array.Resize(ref poseVertices[frameIdx], header.numVerts + newVertCount); + Array.Resize(ref poseVertices[frameIdx], header.numVerts + seamVertices.Count); } + Dictionary vertexCopies = new Dictionary(); int newVertIndex = header.numVerts; // Now we go over all the triangles again and duplicate the vertices that are on a seam @@ -157,7 +158,14 @@ public class AliasModel int vertIndex = triangles[triIdx].vertIndex[indIdx]; if (stVerts[vertIndex].onSeam == 0) continue; - + + if (vertexCopies.ContainsKey(vertIndex)) + { + // We've already duplicated this vertex before + triangles[triIdx].vertIndex[indIdx] = vertexCopies[vertIndex]; + continue; + } + // Clone the ST value and correct it to map onto the backside of the skin QSTVert stVertCopy = stVerts[vertIndex]; stVertCopy.s += header.skinWidth / 2; @@ -170,11 +178,12 @@ public class AliasModel poseVertices[frameIdx][newVertIndex] = triVertCopy; } - triangles[triIdx].vertIndex[indIdx] = newVertIndex++; + triangles[triIdx].vertIndex[indIdx] = newVertIndex; + vertexCopies.Add(vertIndex, newVertIndex++); } } - header.numVerts += newVertCount; + header.numVerts = newVertIndex; } private static void ConvertVertices(QAliasHeader header, QTriVertex[] triVerts, out Vector3[] vertices, out Vector3[] normals)