Godot Version
4.4
Question
so I’m doing something a little psychotic right now, which is to take a .obj file and parse it directly into an ArrayMesh, so that I can procedurally combine .objs later. But I’m stuck trying to get the UVs to work. This is all c#. I’ve got the data out of the .obj file using this thing: https://github.com/stefangordon/ObjParser
Anyway, .obj files store their data as a list of vertices, a list of uvs, and a list of faces organized as vertIndex / uvIndex that looks like:
f 2/1 1/2 3/3 6/4
f 1/2 5/5 4/6 3/3
f 5/7 1/8 7/9 12/10
f 1/8 2/11 8/12 7/9
f 8/13 9/14 10/15 7/16
f 7/16 10/15 11/17 12/18
f 3/19 4/20 11/21 10/22
f 2/11 6/23 9/24 8/12
f 4/20 5/7 12/10 11/21
f 6/23 3/25 10/26 9/24
each f line being a quad or “Face”. I’m using an array i’m calling allDataArray for the ArrayMesh. It takes the .obj vertices directly like this
alldataArray[(int)Mesh.ArrayType.Vertex] = obj.vertices
and then I create the indexes for primitive.triangle faces as
for (int i = 0; i < obj.FaceList.Count; i++)
{
Face face = obj.FaceList[i];indiceList.Add(face.VertexIndexList[0] - 1); indiceList.Add(face.VertexIndexList[1] - 1); indiceList.Add(face.VertexIndexList[2] - 1); indiceList.Add(face.VertexIndexList[0] - 1); indiceList.Add(face.VertexIndexList[2] - 1); indiceList.Add(face.VertexIndexList[3] - 1);
}
alldataArray[(int)Mesh.ArrayType.Index] = indiceList.ToArray();
where face.VertexIndexList[0] is the 2 of f 2/1
and TextureVertexIndexList[0] is 1
The -1 everywhere is just because .obj starts at 1 and godot starts at 0.
This works fine and can be tested by adding empty UV info, but now I’m trying to add UV data from the obj and I don’t understand how ArrayMesh handles this. ArrayMesh wants an equal number of vertexes and uv coords or else it errors out, so it wants one UV per vertex?
My first approach was to make a uv array the same size of the vertex array, and assign each uv as you parse the faces as like
uvArray[face.VertexIndexList[0] - 1] = obj.TextureList[face.TextureVertexIndexList[0] - 1].xy;
uvArray[face.VertexIndexList[1] - 1] = obj.TextureList[face.TextureVertexIndexList[1] - 1].xy;
uvArray[face.VertexIndexList[2] - 1] = obj.TextureList[face.TextureVertexIndexList[2] - 1].xy;
uvArray[face.VertexIndexList[3] - 1] = obj.TextureList[face.TextureVertexIndexList[3] - 1].xy;
below I’ve got what it should look like vs what the broken textures look like
this is happening because the .obj faces includes both a 2/1 and 2/11 face so vertex[2] has multiple UV coordinates wherever there is a seam in the uv map, and the above code is just applying one of them. The internet says you should just have duplicated vertexes but I’m confused on how you would do that. I can see that there are 26 unique uv coords and 12 unique vertex positions, so I tried filling out duplicate vertexes up to 26 using the face data, but that just made another hexagon with differently wonky UVs. I am stumped.
has anyone worked with the UVs in arrayMesh before?