Skip to content

Commit 5c9568c

Browse files
committed
Introduced more thorough scrubbing of Vertex Color/Alpha data & warning popup when that data is bashed to help reduce user error occurring with these fields.
1 parent 808a77a commit 5c9568c

File tree

1 file changed

+63
-12
lines changed
  • xivModdingFramework/Models/FileTypes

1 file changed

+63
-12
lines changed

xivModdingFramework/Models/FileTypes/Mdl.cs

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,8 @@ public async Task<Dictionary<string, string>> ImportModel(IItemModel item, XivMd
13641364

13651365
// A dictionary containing any warnings raised by the import in the format <Warning Title, Warning Message>
13661366
var warningsDictionary = new Dictionary<string, string>();
1367+
var colorWarnings = new List<int>();
1368+
var alphaWarnings = new List<int>();
13671369

13681370
var dae = new Dae(_gameDirectory, _dataFile, pluginTarget);
13691371

@@ -1773,19 +1775,27 @@ Dictionary<string,int> GetIndexLocDictionary(int meshIndex,int index,string key)
17731775
colladaData.Normals[i + 2]));
17741776
}
17751777

1778+
1779+
bool badColorData = false;
17761780
for (var i = 0; i < colladaData.VertexColors.Count; i += colladaData.VertexColorStride)
17771781
{
17781782
var colors = new float[] {colladaData.VertexColors[i], colladaData.VertexColors[i + 1], colladaData.VertexColors[i + 2]};
17791783

1780-
// Check vertex colors for bad data, if any is found replace with default of 1
1784+
// Check vertex colors for bad data, if any is found, reset the entire mesh's color data.
17811785
if (colors.Any(x => x < 0f || x > 1f))
17821786
{
1783-
vertexColorCollection.Add(new Vector3(1, 1, 1));
1784-
}
1785-
else
1786-
{
1787-
vertexColorCollection.Add(new Vector3(colors[0], colors[1], colors[2]));
1787+
badColorData = true;
1788+
break;
17881789
}
1790+
1791+
vertexColorCollection.Add(new Vector3(colors[0], colors[1], colors[2]));
1792+
}
1793+
// Reset the Color data with blanks if it was invalid.
1794+
if (badColorData)
1795+
{
1796+
vertexColorCollection.Clear();
1797+
vertexColorCollection.AddRange(Enumerable.Repeat(new Vector3(1, 1, 1), colladaData.VertexColors.Count / colladaData.VertexColorStride));
1798+
colorWarnings.Add(meshIdx);
17891799
}
17901800

17911801
if (colladaData.BiNormals.Count > 0)
@@ -1861,16 +1871,24 @@ Dictionary<string,int> GetIndexLocDictionary(int meshIndex,int index,string key)
18611871
}
18621872

18631873

1874+
bool badAlphaData = false;
18641875
for (var i = 0; i < colladaData.VertexAlphas.Count; i += colladaData.TextureCoordinateStride)
18651876
{
1866-
// Sanity check
1867-
if (colladaData.VertexAlphas[i] > 0 && colladaData.VertexAlphas[i] < 1)
1877+
// To be considered valid, Vertex Alpha U channel must be [0-1], and Vertex Alpha V channel must be [0/1]
1878+
if (colladaData.VertexAlphas[i] > 1 || colladaData.VertexAlphas[i] < 0 || (colladaData.VertexAlphas[i+1] != 0 && colladaData.VertexAlphas[i] != 1))
18681879
{
1869-
vertexAlphaCollection.Add(new Vector2(colladaData.VertexAlphas[i], 0));
1870-
} else
1871-
{
1872-
vertexAlphaCollection.Add(new Vector2(1, 0));
1880+
badAlphaData = true;
1881+
break;
18731882
}
1883+
vertexAlphaCollection.Add(new Vector2(colladaData.VertexAlphas[i], 0));
1884+
}
1885+
1886+
// Reset the Alpha data with blanks if it was invalid.
1887+
if(badAlphaData)
1888+
{
1889+
vertexAlphaCollection.Clear();
1890+
vertexAlphaCollection.AddRange(Enumerable.Repeat(new Vector2(1, 0), colladaData.VertexAlphas.Count / colladaData.TextureCoordinateStride));
1891+
alphaWarnings.Add(meshIdx);
18741892
}
18751893

18761894
if (!isHousingItem) // housing items do not have bones
@@ -2394,6 +2412,39 @@ Dictionary<string,int> GetIndexLocDictionary(int meshIndex,int index,string key)
23942412
warningsDictionary.Add($"Weight Corrections", weightErrorString);
23952413
}
23962414

2415+
if(alphaWarnings.Any() || colorWarnings.Any())
2416+
{
2417+
var warningString = "";
2418+
if (colorWarnings.Any())
2419+
{
2420+
2421+
warningString += "The following Meshes had their Vertex Color(UV0) data reset due to having bad/invalid data:\n\tMesh(es): ";
2422+
foreach (var mId in colorWarnings)
2423+
{
2424+
warningString += mId.ToString() + ' ';
2425+
2426+
}
2427+
warningString += "\n\n";
2428+
}
2429+
if (alphaWarnings.Any())
2430+
{
2431+
warningString += "The following Meshes had their Vertex Alpha(UV3) data reset due to bad/invalid data:\n\tMesh(es): ";
2432+
foreach (var mId in alphaWarnings)
2433+
{
2434+
warningString += mId.ToString() + ' ';
2435+
}
2436+
warningString += "\n\n";
2437+
}
2438+
warningsDictionary.Add($"Vertex Color/Alpha Correction", warningString);
2439+
}
2440+
2441+
2442+
// -- Update bounding box with calculated bounding box data --
2443+
// This is kind of a janky way to do this -- Technically this is overwriting the base MDL object,
2444+
// Rather than passing the data forwards in a way that indicates it's been modified. However
2445+
// There was no convenient spot in the next function to calculate the data there without doing
2446+
// another full iterration over the entire vertex array, which is extremely costly.
2447+
23972448
xivMdl.BoundBox.PointList[0] = new Vector4(minPos, 1);
23982449
xivMdl.BoundBox.PointList[1] = new Vector4(maxPos, 1);
23992450
xivMdl.BoundBox.PointList[2] = new Vector4(minPos, 1);

0 commit comments

Comments
 (0)