Hello! I am trying to merge a Group ( THREE.Group<THREE.Object3DEventMap> ) into a single Mesh, so that i can manage it in an easier way.
I came upon this post, and tried to adapt the last answer, but didn’t succeed, due to being a beginner at ThreeJS, and it being slightly different to what I was looking for.
function groupToMesh ( group ) {
if ( ! group.isGroup ) return;
let geoms = [];
let meshes = [];
group.children.forEach( e => {
if ( e.geometry.attributes.uv1 ) { delete e.geometry.attributes.uv1; }
e.isMesh && meshes.push( e ) && ( geoms.push( ( e.geometry.index ) ? e.geometry.toNonIndexed() : e.geometry.clone() ) )
} );
geoms.forEach( ( g, i ) => g.applyMatrix4( meshes[i].matrixWorld ) );
console.log(geoms);
let gg = BufferGeometryUtils.mergeGeometries( geoms );
gg.applyMatrix4( group.matrix.clone().invert() );
gg.userData.materials = meshes.map( m => m.material );
return new THREE.Mesh( gg , gg.userData.materials );
}
This is my function, but when i try to add the mesh to my scene, it does not show up, as if there was literally nothing there.
Can someone help me please?
And are all of your meshes the first children in hierarchical depth? The above only iterates through the children of the initial group so if any meshes are nested deeper in hierarchy eg in another group they will be omitted it looks like, you may be better off adapting this to use traverse
Have you tried testing with just one instance of a new MeshStandardMaterial? You may need to setup geometry groups to use multiple materials, however this will still result in one draw call per material afaia, you’ll simply just have one mesh definition for all parts (which is what it seems you’re looking for)
Have you also tried camera.lookAt(mesh.position) (or use orbit controls to look around) once this function is finished just to check the mesh hasn’t ended up behind camera or something after the matrix transformations?
Hey, I just tried and, although it the mesh finally shows, I think there is some kind of problem with the material (in the image left is done with the previus function, while right is correct)
You have 2 options in this case, you can use BufferGeometry.groups whereby you would track and specify each geometry’s attributes.position.count additively along with a material index of the mesh where materials are stored in a relative array (baring in mind that one draw call will be used for every group)
Otherwise you could use a third party program such as blender to create a new uv set where all meshes uv’s are laid out and bake all of your individual meshes textures to one larger uv map and apply that texture to one material which can be applied to all parts (setting the new uv map to active and deleting each individual uv map per part)
This may be a bit too simplistic, but can’t you just add the meshes together, using the “add” command. I use that method to create a single mesh from a collection of standard cube and triangle meshes.