1

I'm trying to create multiple meshes, and then merge them into one (with Three.js r.71). Each mesh can have different materials on different faces. I need to get all the materials appear correctly on the resulting mesh.

I found a way to achieve the desired result, but my code looks pretty awful now. Are the developers of three.js really kept in mind this method?

I could not find a suitable example. Can anyone show a better way to do this?

var totalGeom = new THREE.Geometry();
var meshes = [getBlock(), getBlock()];
meshes[0].position.x = 1;

for (var i = 0; i < meshes.length; i++) {
    var mesh = meshes[i];
    totalGeom.mergeMesh(mesh);
    for (var j = mesh.geometry.faces.length-1; j <= 0; j--) {
        totalGeom.faces[j].materialIndex = mesh.geometry.faces[j].materialIndex;
    }
}

var materials = meshes[0].material.materials.concat(meshes[1].material.materials);
var totalMesh = new THREE.Mesh(totalGeom, new THREE.MeshFaceMaterial(materials));

scene.add(totalMesh);


function getBlock() {
    var geometry = new THREE.BoxGeometry(1, 1, 1, 1, 1, 1);
    var material = new THREE.MeshFaceMaterial([
        new THREE.MeshPhongMaterial({map: THREE.ImageUtils.loadTexture('sides/2.png')}),
        new THREE.MeshPhongMaterial({map: THREE.ImageUtils.loadTexture('sides/2.png')}),
        new THREE.MeshPhongMaterial({map: THREE.ImageUtils.loadTexture('sides/1.png')}),
        new THREE.MeshPhongMaterial({map: THREE.ImageUtils.loadTexture('sides/3.png')}),
        new THREE.MeshPhongMaterial({map: THREE.ImageUtils.loadTexture('sides/2.png')}),
        new THREE.MeshPhongMaterial({map: THREE.ImageUtils.loadTexture('sides/2.png')})
    ]);
    return new THREE.Mesh(geometry, material);
}
WestLangley
  • 102,557
  • 10
  • 276
  • 276
  • Related: http://stackoverflow.com/questions/26849791/three-js-can-i-detect-geometry-islands-when-importing/26852926#26852926 – WestLangley May 16 '15 at 15:55

1 Answers1

0

I would suggest you that instead of mixing all the meshes inside one, you create a group containing all the different meshes. If you do that, you don't need to mix all the materials and you avoid a lot of problems there. And, of course, you get all the advantges of having all the meshes on the same object.

As an example, to do so, follow this procedure:

var scene = new THREE.Scene();
var group = new THREE.Object3D();
var numObjects = 5; //As an example

for(var i=0;i<numObjects;i++){
   var cubeGeometry = new THREE.BoxGeometry(100, 100, 100);
   var material = new THREE.MeshPhongMaterial();
   var mesh = new THREE.Mesh(cubeGeometry, material);
   group.add(mesh);
}

scene.add(group);
Llogari Casas
  • 942
  • 1
  • 13
  • 35
  • 1
    Thanks for the answer, but my main goal is performance. I need to construct a fairly large static locations from the components. Groups do not help in this. Merging does. – Pavel Sinitsin May 16 '15 at 14:25
  • In that case, my anwser is not useful! I can not be helpful to you then, sorry! @PavelSinitsin – Llogari Casas May 16 '15 at 14:36