I’m trying to figure out if I can reconstruct a mesh by extracting its vertex data. The ultimate goal being for example a front end sending the data to a backend for the backend to reconstruct the mesh in a nullEngine or something like that.
I have this playground
Babylon.js Playground which attempts at creating a copy of the original mesh by using vertex data.
However as you can see, I’m pretty far from the desired result.
How could this be achieved? Am I on the right track? Do we need to account for something else other than the vertex data?
It’s possible to reconstruct a mesh by hand but it’s a bit complicated by the fact some meshes can be loaded from a gltf/glb file which stores data as right-handed…
To fix your PG:
- you should call
mesh.makeGeometryUnique() after cloning the mesh. By default, cloned meshes share the same geometry (which is the purpose of cloning), so calling
bakeCurrentTransformIntoVertices() on the clone (or the source mesh) will impact the other one if you don’t duplicate the geometry
- you should not parent your new meshes to anything as
bakeCurrentTransformIntoVertices() will take care of all the parent hierarchy (this is why your mesh is 10x too big in your PG)
vertexData.colors should be left
undefined if there are no vertex colors for the mesh (this is why your mesh is black in your screenshot)
- for meshes loaded through a gltf/glb file, the
mesh.overrideMaterialSideOrientation is set with a value which will override the
material.sideOrientation property: you should copy this property when you create the new mesh
- you should also assign the material to the new mesh if you want the same rendering
- last complication is that gltf/glb meshes have right-handed geometry, meaning that computing normals with a
BABYLON.VertexData.ComputeNormals call will need to negate the normal => you can use the
useRightHandedSystem option for that.
Note that I determine that a mesh has a right-handed geometry by checking that
overrideMaterialSideOrientation has a value (not
null) because there’s only the gltf/glb loader which is setting this property. It’s not a very robust way to recover this piece of information but I don’t know if there’s a better way to do it… Maybe @bghgary will know?
Here’s the corrected PG:
If the vertex data is from a glTF, the winding order of triangles are guaranteed to be counterclockwise if the geometry is not mirrored due to negative scales (i.e., negative determinant). So, in this case, you can just use
ComputeNormals is using the 3D space coordinates of the vertices as read from the file, so those are not impacted by transformations applied to the mesh.
So, in my understanding, for glTF meshes we should always pass
ComputeNormals. Or did I miss something? The question is how to detect that a mesh has a right-handed geometry… We don’t have this information in Babylon.js (?). We have it indirectly for glTF meshes because it’s the only case where
overrideMaterialSideOrientation is set with an actual value.
I don’t understand what “right-handed geometry” means. AFAIK, geometries are not right-handed or left-handed. For ComputeNormal, this flag just changes which way the normals are computed.
We discussed about this offline with @bghgary and the outcome is that we should do the same thing than:
useRightHandedSystem depending on the value of
you should also assign the material to the new mesh if you want the same rendering
I’m aware the colors are given by the textures and the material, but ideally, since my question mentioned that a backend should be able to fully reconstruct the asset, is there a way we can merge the colors into the vertex data / vertices? maybe via some attribute?
Not really, vertices can have a vertex color, but you won’t be able to get the same rendering than with a full material (albedo/bump/metallic/… textures).