How to correct: The tangents element count (871) does not match the positions count (1161)

Hello,

I am merging multiple objects sharing the same material into one mesh; everything was working fine until now. It seems that the error happens since I changed my workflow from using 3ds max / 3ds max exporter to using Blender / Blender Exporter 6.2.

On the first attempt to use BABYLON.Mesh.MergeMeshes(meshes, true, true), I get the error:

Uncaught (in promise) Error: The tangents element count (871) does not match the positions count (1161)
    at i (babylon.js:formatted:1)
    at e._validate (babylon.js:formatted:1)
    at e.merge (babylon.js:formatted:1)
    at Function.t.MergeMeshes (babylon.js:formatted:1)
    at BlobTilemapInstancer../src/MazeGeneration/Instancers/ATilemapInstancer.ts.ATilemapInstancer.MergeMeshesByChunk (ATilemapInstancer.ts:137)
    at BlobTilemapInstancer.<anonymous> (BlobTilemapInstancer.ts:226)
    at step (BlobTilemapInstancer.ts:45)
    at Object.next (BlobTilemapInstancer.ts:26)
    at BlobTilemapInstancer.ts:20
    at new Promise (<anonymous>)

Do you know what this The tangents element count (871) does not match the positions count (1161) could mean? is it something that I can correct within Blender?

Small update.

I checked all the meshes in the list meshes that I pass to BABYLON.Mesh.MergeMeshes(meshes, true, true), they all have the same number of positions and tangents…

Here the code I used for the check:

console.log("Adding "+ mesh.name);
let temp1:BABYLON.FloatArray = mesh.getVerticesData(BABYLON.VertexBuffer.TangentKind)
let temp2:BABYLON.FloatArray = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind)
console.log("--> Nb. tangents == Nb. positions: "+ (temp1.length == temp2.length) );

EDIT:
After some digging, I found a work around.
I realised that the version of my meshes that worked previously did not have tangent data! It seems that Blender Exporter is adding tangent data because my meshes were using Custom Split Normal Data (because of 3Ds Max?); So I deleted all the Custom Split Normal Data and now I have no tangent data in my exported meshes :smiley: and no problem any more when merging my meshes!

However, it seems to me that BABYLON.Mesh.MergeMeshes() should work even when the meshes have tangent data, right? maybe a bug? @Deltakosh

Hi @Nodragem

MergeMeshes supports tangent data. But all the meshes you want to merge must have the same data types. If 1 mesh has tangent data, all the other one must have tangent data. Same for nornals, uvs, …

The tangents in for vertexData is represented as a Vector4 where the fourth component represents the handedness of the tangent space. I’m guessing you have Vector3 tangent data (since 1161 * 3 / 4 is 870.75). In order for tangents with Vector3 to work, the vertex data usually also comes with bitangents (sometimes mistakenly called binormals). Babylon doesn’t support bitangents in vertex data. If you know for sure the tangents are always a particular handedness you can augment the tangents to have the extra fourth component (1 or -1) before merging.

Hello,

Thanks for your answer :slight_smile:
As said in the second post, I checked whether all my objects had the same number of position data and the same number of tangent data. As the checked returned true for all objects; we can conclude that they all have position and tangent data.

It is very likely that @bghgary is right. Although I have no idea what are handedness or bitangents, his deduction from 1161 seems correct.

@JCPalmer It may mean that, when there are Custom Split Normal Data on the meshes, the Blender Exporter is currently exporting a Vector3 tangent data that is not supported by BabylonJS?

To be honest, this might be a very specific business case scenario, and it might be better that Blender users do not use Custom Split Normal Data. In my case, the problem occurred because I imported my meshes from FBX from 3DS max.

I was unaware tangents needed 4 elements. Do not remember if I just grabbed the first three or not. I know Blender is right handed, so if there were only 3, I have a 50 / 50 shot of adding just adding one. Not looking into it today.

If migrating to Blender 2.80 from MAX, you might also try using the glTF format as transport. Blender 2.80 has an importer, from Khronos, built right in. That combination might not result in split normals. As I described in the exporters approach of getting rid of UI to do flat shading for the 6.0 exporter, internally Blender either stores the type of normal (smooth or flat) on a vertex by vertex basis, or does custom split normals. Perhaps your case would resolve that way using that path.

1 Like

Well, got the time to at least do the Blender API lookup for tangents. It is only a 3 element vector. I am not sure whether a -1 or 1 should be stuck on there.

Is there a simple .blend file which I can test with?

Use bitangent_sign for the fourth component.

1 Like

Blender 6.2.1 has been published with 4 element tangents.

2 Likes