Importing FBX into PC changes vertex Order

Hello, I’m trying to import a mesh into Playcanvas from blender where the vertex order is important as i’m using to to offset UVs based on a settings file.

When I import the mesh I can see that the vertex index is offset, I checked this using positions of the verts, vertex count is the same tho.

PC vertex number and position
Blender Vertex number and position

Reimporting the fbx into blender shows no changes, so I think it happens on the .glb conversion. Is this something that is known, and in that case is there a way to restore the old vertex order?

Hi @Mads_Nielsen,

Hmm, I vaguely remember that I’ve run into that issue in the past. @yaustar @mvaligursky any idea about that?

I’m not sure, but in general, I would not depend on the order, as often the import pipelines resort triangle for better vertex cache utilisation on the GPU and similar. I’m not sure exactly what happens on our side though, @slimbuck might know.

2 Likes

It makes sense that the importer would optimise for triangle strips, but would be very preferred to have a option to turn that off.

As an alternative, you may be able to load an OBJ directly, if that helps with your pipeline:

That will not work in editor, you will have to load the model on runtime.

Edit: Of course if you do that, you may as well load a GLB on runtime :innocent:

2 Likes

That was something I thought about, but as our export tools are fairly married to FBX and all the meshes are skinned meshes its a last resort kind of thing

1 Like

I had a similar issue when building a race track, I needed the vertices in PlayCanvas, in the same order they were indexed in Blender (for pathfinding).

That wasn’t the case as you figured out, so at the end I sorted them based on their Z pos (the race track progressed towards positive Z values). That worked for my simple case, but it may not be as trivial generally.

1 Like

The current workaround I’m working on is to mark each vert with custom vertex data burning the vertex index into it, then reading that data in PC and making a lookup table of “old->new” vertex index. But it feels like such a giant hack.

Nice trick! But yes seems like a hack and increases file size too.

This is the hack I’m using now, in case anyone want to use anything like it I’ll leave it here, would be great official support for it tho:

I first mark uv[0].y in blender to vert.index / “amount of verts”.

(PYTHON)

for l in faceData.loops:
        V = l.vert.index/verts_len
        l[uv_layer].uv = (U, V) 

then when I import into PC I create a lookup table where the key is BlenderVertIndex and the Value is PC Vert index, this is made by this simple code.

UvController.prototype.getRealVertLUT = function(){
    let mesh = this.activeEntity.model.model.meshInstances[0].mesh;
    let uvs = [];
    mesh.getUvs(0, uvs);

    let vertLUT = {};
    let verts_len = uvs.length / 2;
    for(let i = 0; i < uvs.length; i += 2){
        let PCVertNumber = i/2;
        let BlendVertNumber = Math.round((1 - uvs[i+1])*verts_len);
        vertLUT[BlendVertNumber] = PCVertNumber;
    }

    console.log(vertLUT);
    return vertLUT;
};

if you are using boy x and y of uv[0] you can use a new UV channel or vertex colors to same effect, custom vertex data may be use full as well, but I’m not sure how PC handles custom vertex data.

Hopefully this will help someone finding this thread down the line :slight_smile:

4 Likes

Nice, thanks for sharing! That’s easy enough on the Blender side.