3

How to merge two buffer geometries in one THREE.BufferGeometry in ThreeJS ?

var modelGeometry = null;

geometry = new THREE.CylinderGeometry( 10, 10, 10 );

if (modelGeometry == null)
{
    modelGeometry = new THREE.BufferGeometry().fromGeometry(geometry);
    console.log(modelGeometry);
}

bufGeometry = new THREE.SphereBufferGeometry( 20 , 20, 20 );

var mesh = new THREE.Mesh( bufGeometry, material );

modelGeometry.merge(mesh.geometry, mesh.matrix);

Doesn't do anything with modelGeometry. How merge these geometries correct?

Wilt
  • 41,477
  • 12
  • 152
  • 203
Evgy
  • 386
  • 1
  • 3
  • 10

2 Answers2

3

Strangely calling merge() on a BufferGeometry gave me some errors, but there's a workaround:

  1. Merge two Geometry objects;
  2. Convert to BufferGeometry;
  3. Add to a Mesh

Here's what's working for me:

    var modelGeometry = new THREE.Geometry();

    cylGeometry = new THREE.CylinderGeometry( 10, 10, 10 );

    // if (modelGeometry == null)
    // {
    //     modelGeometry = new THREE.BufferGeometry().fromGeometry(geometry);
    //     console.log(modelGeometry);
    // }

    modelGeometry.merge(cylGeometry);

    sphereGeometry = new THREE.SphereGeometry( 20 , 20, 20 );

    modelGeometry.merge(sphereGeometry);

    bufGeometry = new THREE.BufferGeometry().fromGeometry(modelGeometry);

    var mesh = new THREE.Mesh( bufGeometry, material );

    scene.add(mesh);
leota
  • 1,636
  • 2
  • 13
  • 33
  • It was my first try too. But with much more geometries to merge this trick don't work - browsers crashed while loading script... I need merge only BufferGeometry. – Evgy Apr 06 '16 at 17:02
  • @Evgy Why do you need to merge these geometries? If it's just for having them in the same group you could add them to an Object3D, otherwise I don't know. – leota Apr 06 '16 at 17:09
  • I need to load in GL buffer very big model, created from small primitives. With geometry objects browsers crashs with few houndreds of objects. Loading model to scene splitted on many meshes with many separate BufferGeometries show more speed and less memory usage, but i still need optimize code, one mesh merged from Geometries show good speed, but not enough... My hope is only on mesh with just one BufferGeometry at the end. – Evgy Apr 06 '16 at 17:27
  • @Evgy Tricky. With merge() out of the game it comes very difficult – leota Apr 06 '16 at 18:02
  • This approach worked excellent for me with 5000 PlaneGeometry! – Holger Ludvigsen Nov 30 '18 at 14:01
2

I'll dance all night long. Did it!

sumPosArr = new Float32Array(poslen);
sumNormArr = new Float32Array(normlen);
sumUvArr = new Float32Array(uvlen);

var postotalarr = new Array();

sumPosCursor = 0;
sumNormCursor = 0;
sumUvCursor = 0;

for (a = 0; a < objects.length; a++ )
{
    var posAttArr = objects[a].geometry.getAttribute('position').array;

    for (b = 0; b < posAttArr.length; b++)
    {
        sumPosArr[b + sumPosCursor] = posAttArr[b];
    }

    sumPosCursor += posAttArr.length;


    var numAttArr = objects[a].geometry.getAttribute('normal').array;

    for (b = 0; b < numAttArr.length; b++)
    {
        sumNormArr[b + sumNormCursor] = numAttArr[b];
    }

    sumNormCursor += numAttArr.length;


    var uvAttArr = objects[a].geometry.getAttribute('uv').array;

    for (b = 0; b < uvAttArr.length; b++)
    {
        sumUvArr[b + sumUvCursor] = uvAttArr[b];
    }

    sumUvCursor += uvAttArr.length;

}

modelGeometry.addAttribute('position', new THREE.BufferAttribute(sumPosArr, 3 ));
modelGeometry.addAttribute('normal', new THREE.BufferAttribute(sumNormArr, 3 ));
modelGeometry.addAttribute('uv', new THREE.BufferAttribute(sumUvArr, 2 ));
Evgy
  • 386
  • 1
  • 3
  • 10