THREE.js: how to code for a set of cylinder mesh objects with rapidly changing lengths (+ positions + orientations + colors)

StackOverflow https://stackoverflow.com/questions/23665067

Question

I would like to re-compute and display at least 100 cylinders at 30+ frames per second in a THREE.js animation.

Method 1

Elsewhere (e.g. WestLangley, Mr.Doob) it is recommended to create a pool of mesh objects at Initialisation stage and then re-use them during Animation. I think this would be feasible if cylinder geometries were unchanged across animation frames. But my cylinders need to change in length from frame to frame. I think that Scale cannot be used because the objects are not all aligned to one of the principal axes (x, y or z).

Method 2

Create 100 NEW mesh objects every frame. But this will lead to rapid memory drain unless they are also deleted after rendering each frame...e.g.

    for (var iii=1; iii<=10; iii++)
    {    


    if (MyCylinders[iii])     scene.remove (MyCylinders[iii]);

    // cylinder
    // API: THREE.CylinderGeometry(bottomRadius, topRadius, height, segmentsRadius, segmentsHeight)
        cylinder = new THREE.Mesh(new THREE.CylinderGeometry(2, 2, 500 * Math.random(), 100, 100, false), new THREE.MeshBasicMaterial({color: '#880066'}));
        cylinder.overdraw = true;
        cylinder.rotation.x = Math.PI * 0.5 * Math.random();
        cylinder.rotation.y = Math.PI * 0.5 * Math.random();
        cylinder.rotation.z = Math.PI * 0.5 * Math.random();
        cylinder.position.x = 200*Math.random();
        cylinder.position.y = 200* Math.random();
        cylinder.position.z = -200* Math.random();

    MyCylinders[iii] = cylinder;
    scene.add(MyCylinders[iii]);
    }

I guess that such frequent creating and deleting will slow the frame rate too much ...as shown in this fiddle http://jsfiddle.net/errp5/5/ which struggles to reach 10fps with only 10 cylinders.

My Question

Is there a better way to do this?

ANSWER

Method 1 is the better way (Pool of re-usable mesh objects) when combined with appropriate use of Scale (as suggested by mrdoob) and Rotation. Working demo at:- http://jsfiddle.net/KjxZp/2/

Key section of code:-

var desired_cylinder_length = 195 + 5 * Math.random();
      //... Loop
      for (var iii = 1; iii <= Num_Rays; iii++) {
          cylinder = MyCylinders[iii];

          //... apply new scale and rotation to cylinder
          cylinder.scale.y = desired_cylinder_length;
          cylinder.overdraw = true;

          cylinder.rotation.x += (0.005) * Math.PI * Math.random();
          cylinder.rotation.y += (0.005) * Math.PI * Math.random();
          cylinder.rotation.z += (0.005) * Math.PI * Math.random();

          MyCylinders[iii] = cylinder;
          MyCylinders[iii].geometry.verticesNeedUpdate = true
Was it helpful?

Solution

I think that Scale cannot be used because the objects are not all aligned to one of the principal axes (x, y or z).

You can fix that.

var geometry = new THREE.CylinderGeometry( 1, 1, 1 );
geometry.applyMatrix( new THREE.Matrix4().makeTranslation( 0, 0.5, 0 ) );

var mesh = new THREE.Mesh( geometry );
mesh.scale.y = Math.random() * 100;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top