mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 12:14:17 +01:00
Rework AdjustByteArray
This commit is contained in:
parent
3e90524b06
commit
5258c600b7
1 changed files with 20 additions and 28 deletions
|
|
@ -146,41 +146,37 @@ public class VertexAttribute
|
||||||
|
|
||||||
return new VertexAttribute(
|
return new VertexAttribute(
|
||||||
element,
|
element,
|
||||||
index => {
|
index => BuildBlendWeights(weights0[index], weights1?[index] ?? Vector4.Zero)
|
||||||
var weight0 = weights0[index];
|
|
||||||
var weight1 = weights1?[index];
|
|
||||||
var originalData = BuildUshort4(weight0, weight1 ?? Vector4.Zero);
|
|
||||||
var byteValues = originalData.Select(x => (byte)Math.Round(x * 255f)).ToArray();
|
|
||||||
return AdjustByteArray(byteValues, originalData);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] AdjustByteArray(byte[] byteValues, float[] originalValues)
|
private static byte[] BuildBlendWeights(Vector4 v1, Vector4 v2)
|
||||||
{
|
{
|
||||||
|
var originalData = BuildUshort4(v1, v2);
|
||||||
|
var byteValues = new byte[originalData.Length];
|
||||||
|
for (var i = 0; i < originalData.Length; i++)
|
||||||
|
{
|
||||||
|
byteValues[i] = (byte)Math.Round(originalData[i] * 255f);
|
||||||
|
}
|
||||||
|
|
||||||
// Blend weights are _very_ sensitive to float imprecision - a vertex sum being off
|
// Blend weights are _very_ sensitive to float imprecision - a vertex sum being off
|
||||||
// by one, such as 256, is enough to cause a visible defect. To avoid this, we tweak
|
// by one, such as 256, is enough to cause a visible defect. To avoid this, we tweak
|
||||||
// the converted values to have the expected sum, preferencing values with minimal differences.
|
// the converted values to have the expected sum, preferencing values with minimal differences.
|
||||||
var adjustment = 255 - byteValues.Select(value => (int)value).Sum();
|
var adjustment = 255 - byteValues.Sum(value => value);
|
||||||
while (adjustment != 0)
|
while (adjustment != 0)
|
||||||
{
|
{
|
||||||
var convertedValues = byteValues.Select(value => value * (1f / 255f)).ToArray();
|
|
||||||
var closestIndex = Enumerable.Range(0, byteValues.Length)
|
var closestIndex = Enumerable.Range(0, byteValues.Length)
|
||||||
.Where(index =>
|
.Where(i => adjustment switch
|
||||||
{
|
{
|
||||||
var byteValue = byteValues[index];
|
< 0 when byteValues[i] > 0 => true,
|
||||||
if (adjustment < 0)
|
> 0 when byteValues[i] < 255 => true,
|
||||||
return byteValue > 0;
|
_ => true,
|
||||||
if (adjustment > 0)
|
|
||||||
return byteValue < 255;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
})
|
})
|
||||||
.Select(index => (index, delta: Math.Abs(originalValues[index] - convertedValues[index])))
|
.Select(index => (index, delta: Math.Abs(originalData[index] - (byteValues[index] * (1f / 255f)))))
|
||||||
.MinBy(x => x.delta)
|
.MinBy(x => x.delta)
|
||||||
.index;
|
.index;
|
||||||
byteValues[closestIndex] = (byte)(byteValues[closestIndex] + Math.CopySign(1, adjustment));
|
byteValues[closestIndex] += (byte)Math.CopySign(1, adjustment);
|
||||||
adjustment = 255 - byteValues.Select(value => (int)value).Sum();
|
adjustment = 255 - byteValues.Sum(value => value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return byteValues;
|
return byteValues;
|
||||||
|
|
@ -226,7 +222,7 @@ public class VertexAttribute
|
||||||
gltfWeights0.W == 0 ? 0 : boneMap[(ushort)gltfIndices0.W]
|
gltfWeights0.W == 0 ? 0 : boneMap[(ushort)gltfIndices0.W]
|
||||||
);
|
);
|
||||||
|
|
||||||
Vector4 v1;
|
var v1 = Vector4.Zero;
|
||||||
if (gltfIndices1 != null && gltfWeights1 != null)
|
if (gltfIndices1 != null && gltfWeights1 != null)
|
||||||
{
|
{
|
||||||
v1 = new Vector4(
|
v1 = new Vector4(
|
||||||
|
|
@ -236,10 +232,6 @@ public class VertexAttribute
|
||||||
gltfWeights1.Value.W == 0 ? 0 : boneMap[(ushort)gltfIndices1.Value.W]
|
gltfWeights1.Value.W == 0 ? 0 : boneMap[(ushort)gltfIndices1.Value.W]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
v1 = Vector4.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
var byteValues = BuildUshort4(v0, v1);
|
var byteValues = BuildUshort4(v0, v1);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue