THREE.js:如何编码一组具有快速变化长度的圆柱网格对象(+位置+方向+颜色)

时间:2014-05-14 21:02:34

标签: javascript animation three.js geometry

我想在THREE.js动画中重新计算并以每秒30多帧的速度显示至少100个柱面。

方法1

在其他地方(例如WestLangley,Mr.Doob),建议在初始化阶段创建一个网格对象池,然后在动画期间重新使用它们。 我认为如果圆柱几何在动画帧中保持不变,这将是可行的。 但是我的气缸需要在不同的框架之间改变长度。 我认为无法使用Scale,因为对象并非都与主轴(x,y或z)之一对齐。

方法2

每帧创建100个新网格对象。 但是这会导致快速的内存消耗,除非它们在渲染每个帧后也被删除......例如

    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]);
    }

我猜这种频繁的创建和删除会使帧速率过慢 ......正如这个小提琴http://jsfiddle.net/errp5/5/所示,只有10个气缸才能达到10fps。

我的问题

有更好的方法吗?

ANSWER

当与适当使用Scale(由mrdoob建议)和Rotation相结合时,方法1是更好的方法(可重复使用的网格对象池)。 工作演示: - http://jsfiddle.net/KjxZp/2/

代码的关键部分: -

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

1 个答案:

答案 0 :(得分:2)

  

我认为无法使用Scale,因为对象并非全部与主轴(x,y或z)之一对齐。

你可以解决这个问题。

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;