Open IrfanSamuel-aai opened 1 year ago
Hi @IrfanSamuel-aai,
Thanks for reporting.
The cause of the problem is that the glTF export does not re-calculate the min/max values based on the actual vertex positions (as this requires iterating all vertices), but calculates them from the Mesh's bounds. Those are stored as center/extends vectors and this floating point operation introduces a tiny bit of error, enough to trigger an error by the glTF validator (see issue) and apparently UE's import.
So solutions to solve this:
Hi, Thank you for the reply. Will it be possible to calculate min/max of each mesh in export jobs? We can make this an optional operation to be performed while exporting. We can't be sure, when UE devs will work on their importer. Best regards.
Hi, Thank you for the reply. Will it be possible to calculate min/max of each mesh in export jobs?
Yes, that's the best approach I think.
Hi, do you have idea how to calculate min/max of each mesh in export jobs?
Hi, do you have idea how to calculate min/max of each mesh in export jobs?
Hi, I'm able to correctly calculate the the bounds (double) but only limited by meshBound.SetMinMax( ) as it only accepts Vector3. @atteneder can provide us an option to pass the min/max for each mesh along with the Export function then the issue can be easily rectified.
@IrfanSamuel-aai Can you give example of your code with correct bound calculation?
@RAsoftware916, yes sure :)
public static void GetMeshBounds(Mesh mesh, out double3 min, out double3 max)
{
int count = mesh.vertexCount;
List
min = new double3();
max = new double3();
for (int i = 0; i < 3; i++)
{
min[i] = float.MaxValue;
max[i] = float.MinValue;
}
for (int i = 0; i < count; i++)
{
var v = vertices[i];
if ((double)v.x < min[0]) min[0] = (double)v.x;
if ((double)v.y < min[1]) min[1] = (double)v.y;
if ((double)v.z < min[2]) min[2] = (double)v.z;
if ((double)v.x > max[0]) max[0] = (double)v.x;
if ((double)v.y > max[1]) max[1] = (double)v.y;
if ((double)v.z > max[2]) max[2] = (double)v.z;
}
}
@IrfanSamuel-aai Thanks for your code. I applied your code to GltfWriter.cs and changed the code in lines from 963 first part of switch. I tested this change on my models which makes errors of min/max mismatch in the validator and after this fix errors didn't appear. `switch (attribute.attribute) { case VertexAttribute.Position: Assert.AreEqual(VertexAttributeFormat.Float32,attribute.format); Assert.AreEqual(3,attribute.dimension);
int count = uMesh.vertexCount;
List<Vector3> vertices = new List<Vector3>();
uMesh.GetVertices(vertices);
double3 minD = new double3();
double3 maxD = new double3();
for (int i = 0; i < 3; i++)
{
minD[i] = float.MaxValue;
maxD[i] = float.MinValue;
}
for (int i = 0; i < count; i++)
{
var v = vertices[i];
if (v.x < minD[0]) minD[0] = v.x;
if (v.y < minD[1]) minD[1] = v.y;
if (v.z < minD[2]) minD[2] = v.z;
if (v.x > maxD[0]) maxD[0] = v.x;
if (v.y > maxD[1]) maxD[1] = v.y;
if (v.z > maxD[2]) maxD[2] = v.z;
}
accessor.min = new[] {(float)-maxD.x, (float)minD.y, (float)minD.z };
accessor.max = new[] { (float)-minD.x, (float)maxD.y, (float)maxD.z };
attributes.POSITION = accessorId;
break;`
@RAsoftware916 great, thanks for sharing your code. @atteneder, can this be merged?
@RAsoftware916 Thanks for sharing your solution.
@IrfanSamuel-aai Unfortunately I won't merge this particular solution due to performance concerns. It essentially creates another copy of the vertex positions. Granted, this is not everyone's concern, but I certainly care about that stuff.
Describe the bug I'm exporting a mesh from Unity3d as GLB to bring it into UE but due to ACCESSOR_MIN_MISMATCH, UE is not able to load the mesh and it crashes.
The house is built via an editor tool so house parts can be flipped (X,Z) and different modules are combined to form one house.
Now I can see the value -0.553424656391144 for SubMesh(1) via manual vertices check but when it's been fetched to meshBound.SetMinMax( ), this is changed to -0.553424835205078 because the function accepts only Vector3(float xyz)
Files zip file has fbx and glb files. SingleHouse.zip
To Reproduce Steps to reproduce the behavior:
Expected behavior Is there any way to have the correct min/max value with double precision stored for each model submesh?
Screenshot loads fine in Windows 3d Viewer
Desktop
Additional context How can this issue be resolved to correctly export glb with no mismatch issue. System.Convert.ToSingle( ) also doesn't work.