The meaning of matricesIndices in .babylon format

hi guys,

I am a little bit confused about the matricesIndices params on this PG
https://playground.babylonjs.com/#D4ZZ8#136

at the bottom of the script, the modelData are provided, which is the same format as the .babylon file.

According to the documentation,

“matricesIndices”: array of ints (4 per vertex) which is the matrices indices for bones (can be omitted),

which indicates is the indices of bones. but I have no idea about why it has such large indices like 256, 513 etc. So where these index come from and how to correspond to the bones.

Thanks

In the serialization, the matrix indices are encoded.

If you start with:
mesh.getVerticesData("matricesIndices") = [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 0, 1, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0]

You take the indices by group of 4 and convert them to a 32 bits number:

(0, 1, 0, 0) => 0 + (1 << 8) + (0 << 16) + (0 << 24) = 256
(0, 0, 0 ,0) => 0
(0, 0, 0 ,0) => 0
(0, 1, 0, 0) => 0 + (1 << 8) + (0 << 16) + (0 << 24) = 256
(0, 0, 0 ,0) => 0
(0, 1, 0, 0) => 0 + (1 << 8) + (0 << 16) + (0 << 24) = 256
(0, 0, 0 ,0) => 0
(0, 1, 0, 0) => 0 + (1 << 8) + (0 << 16) + (0 << 24) = 256
(0, 1, 0, 0) => 0 + (1 << 8) + (0 << 16) + (0 << 24) = 256
(0, 1, 0, 0) => 0 + (1 << 8) + (0 << 16) + (0 << 24) = 256
(0, 1, 0, 0) => 0 + (1 << 8) + (0 << 16) + (0 << 24) = 256
(1, 2, 0, 0) => 1 + (2 << 8) + (0 << 16) + (0 << 24) = 513
(1, 2, 0, 0) => 1 + (2 << 8) + (0 << 16) + (0 << 24) = 513
(0, 1, 0, 0) => 0 + (1 << 8) + (0 << 16) + (0 << 24) = 256
(1, 2, 0, 0) => 1 + (2 << 8) + (0 << 16) + (0 << 24) = 513
(1, 2, 0, 0) => 1 + (2 << 8) + (0 << 16) + (0 << 24) = 513
(1, 2, 0, 0) => 1 + (2 << 8) + (0 << 16) + (0 << 24) = 513
(1, 2, 0, 0) => 1 + (2 << 8) + (0 << 16) + (0 << 24) = 513
(1, 2, 0, 0) => 1 + (2 << 8) + (0 << 16) + (0 << 24) = 513
(2, 0, 0, 0) => 2 + (0 << 8) + (0 << 16) + (0 << 24) = 2
(2, 0, 0, 0) => 2 + (0 << 8) + (0 << 16) + (0 << 24) = 2
(1, 2, 0, 0) => 1 + (2 << 8) + (0 << 16) + (0 << 24) = 513
(2, 0, 0, 0) => 2 + (0 << 8) + (0 << 16) + (0 << 24) = 2
(2, 0, 0, 0) => 2 + (0 << 8) + (0 << 16) + (0 << 24) = 2

which corresponds to the data you can see in your PG:
256,0,0,256,0,256,0,256,256,256,256,513,513,256,513,513,513,513,513,2,2,513,2,2

This is an old format (still supported for backward compatibility), the indices are now serialized “as is” without any transformation when you serialize a scene.

1 Like

Hi @Evgeni_Popov,
Thank you for your kind reply and great explanation. It is clear for me now.

The implication of this is that encoded this way, the maximum number of bones a skeleton may have is 256. I think this is a pretty sufficient top number. In a text format, as a .babylon is, this results in a smaller file due to. Here are the 2 over / under (spaces removed)

0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,1,2,0,0,1,2,0,0,0,1,0,0,1,2,0,0,1,2,0,0,1,2,0,0,1,2,0,0,1,2,0,0,2,0,0,0,2,0,0,0,1,2,0,0,2,0,0,0,2,0,0,0
256,0,0,256,0,256,0,256,256,256,256,513,513,256,513,513,513,513,513,2,2,513,2,2

The difference is dependent on the values, but you are starting with 4x the commas.

Hi @JCPalmer
Thanks for your reply. yes, this way can be smaller than 4 digits representation. But .babylon is a json text. Does it mean gltf/glb format a recommend way to store models in terms of file size, as gltf/glb files are store as binaries? Is there any drawbacks for gltf/glb, I mean is there any case for gltf/glb that cannot work perfectly compared with .babylon file?

Not really. Size comparisons are not that easy to make. Being a text file, it can automatically be compressed during transmission (approx. 70% reduction). While you need to edit a file on your http server to register a .babylon to do gzip, you can also just change the extension to .json. It is a JSON file after all.

The extension change is an important trick to know when publishing to a location where you have no direct access to the http server. Github.io pages for instance.

Also, the exporter for Blender has editable properties to control the maximum precision of numbers to write for various data types. It also does not display trailing 0’s or a trailing ‘.’. See

It does not really make much sense to have more than (+999) & (-999) possible values per dimension of normals, UVs, or vertex colors. If working with WebXR, as an example, which is meter scaled, having 4 digits of precision puts vertex positions within 1 micro-meter. You would need a microscope to see the difference. They are editable properties, so they can be adjusted though.

Sadly, the exporter for the framework, is just totally bloated (sorry @Deltakosh). It outputs in indiscriminately up to 16 decimals of precision on a 64 bit OS. So the comparison for the value 1:

Blender exporter:1,2
Framework       :1.0000000000000000,2.0000000000000000

The best basis for choosing a file format is whether you can get all of things you want to record into that format. GLB has fewer things than the native format.

@JCPalmer. Thank you for your reply. It definitely answers my question and is very helpful! :slight_smile: