Browse Source

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.

console
Nico de Poel 5 years ago
parent
commit
dec2be66c6
  1. 35
      Assets/Scripts/Modules/AliasModel.cs

35
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<int> seamVertices = new HashSet<int>();
// 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<int, int> vertexCopies = new Dictionary<int, int>();
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)

Loading…
Cancel
Save