1
votes

I have a loop where I create a multiple Mesh with different geometry, because each mesh has one texture:

var geoCube = new THREE.CubeGeometry(voxelSize, voxelSize, voxelSize);
var geometry = new THREE.Geometry();

for( var i = 0; i < voxels.length; i++ ){
  var voxel = voxels[i];
  var object;
  color = voxel.color; 
  texture = almacen.textPlaneTexture(voxel.texto,color,voxelSize); 
  //Return the texture with a color and a text for each face of the geometry
  material = new THREE.MeshBasicMaterial({ map: texture });                       
  object = new THREE.Mesh(geoCube, material);

  THREE.GeometryUtils.merge( geometry, object );
}

//Add geometry merged at scene
mesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial() );
mesh.geometry.computeFaceNormals();
mesh.geometry.computeVertexNormals();
mesh.geometry.computeTangents();

scene.add( mesh );

But now I have this error in the javascript code Three.js

Uncaught TypeError: Cannot read property 'map' of undefined

In the function:

function bufferGuessUVType ( material ) {
}

Update:

Finally I have removed the merged solution and I can use an unique geometry for the all voxels. Altough I think that If I use merge meshes the app would have a better performance.

2

2 Answers

2
votes

For r53+ the code should be something like this:

var geoCube = new THREE.CubeGeometry(voxelSize, voxelSize, voxelSize);
var geometry = new THREE.Geometry();
var materials = [];

for( var i = 0; i < voxels.length; i++ ){

  for ( var j = 0; j < geoCube.faces.length; j ++ ) {
    geoCube.faces[ j ].materialIndex = i;
  }

  var object = new THREE.Mesh( geoCube );
  // here I assume you'll me positioning the object.
  THREE.GeometryUtils.merge( geometry, object );

  var voxel = voxels[i];
  var texture = almacen.textPlaneTexture(voxel.texto,voxel.color,voxelSize);
  materials.push( new THREE.MeshBasicMaterial( { map: texture } ) );

}

// Add geometry to scene

var mesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) );
mesh.geometry.computeFaceNormals();
mesh.geometry.computeVertexNormals();

scene.add( mesh );
0
votes

Some methods are expecting the materials array to be in the mesh face material. For example:

function getBufferMaterial( object, geometryGroup ) {

    return object.material instanceof THREE.MeshFaceMaterial
        ? object.material.materials[ geometryGroup.materialIndex ]
        : object.material;

};

Its possible to handle this by referencing the materials array both in the geometry and in the mesh face material. So the line where the mesh is created would look something like:

mesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial(geometry.materials) );

and in the loop processing the voxels:

geometry.materials.push( new THREE.MeshBasicMaterial({ map: texture }));

Each face in the geometry also needs to have a materialIndex assigned or there will be an error. Looping through geometry.faces[] and assigning a materialIndex might be a good way if you know how many faces each of the voxels has.