three.js使用raycaster.intersectObject

时间:2017-02-16 22:29:56

标签: javascript arrays object three.js parent-child

我正在尝试制作一系列可以点击以突出显示它们的立方体。这将使我能够改变颜色或添加纹理或以某种方式操纵它们。我查看了https://threejs.org/examples/处所有交互式示例的源代码,看起来每个示例都使用了一种稍微不同的方式来创建和选择场景中的对象。我不习惯使用javascript,所以也许我错过了一些简单的东西。

我创建了一个名为blocks的Object3D类来存储所有的多维数据集

blocks = new THREE.Object3D()

我使用for循环创建一个9 x 9的立方体数组,从(0,0,0)坐标开始,它们之间有一点间隙,并将它们添加到块中,并将()块添加到场景中。例如:(立方体大小2,2,2)

   function stack(mx,my,mz){
        for (var i = 0; i < 9; i++){
          line(mx,my,mz);
          mz += 3;
        }
    }

    function line(mx,my,mz){
        for (var i = 0;i<9;i++){
          var block = new THREE.Mesh( Geometry, Material);
          block.position.x = mx;
          block.position.y = my;
          block.position.z = mz;

          blocks.add(block);
          mx+=3;
        }
    }
    stack(mx,my,mz) 
    scene.add(blocks)

当我运行此代码时,我可以看到它们呈现。我使用raycaster到.intersectObjects(),它需要一个对象数组。这就是我遇到只选择一个对象的问题。

function onDocumentMouseDown(event) {

    var vector = new THREE.Vector3(( event.clientX / window.innerWidth ) * 2 - 1, -( event.clientY / window.innerHeight ) * 2 + 1, 0.5);
    projector.unprojectVector(vector, camera);
    var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
    **var intersects = raycaster.intersectObjects(blocks.children, true);**

    if (intersects.length > 0) {
        intersects[0].object.material.transparent = true;
        other code stuff blah blah blah
    {

这将使所有孩子都可以点击,但他们与创建的第一个对象具有相同的.id。所以,如果我尝试.getObjectById()以便改变某些东西,它就不起作用。

我试图生成每个元素并迭代地将它们添加到场景中,而不是创建一个对象数组来保存它们,它仍然具有类似的效果。我已经尝试将它们存储在常规数组中,然后使用true参数递归搜索.intersectObject()数组,但是当我单击它时它会选择所有对象。

var intersects = raycaster.intersectObjects(blocks, true);

我考虑创建81个唯一变量来保存每个元素并静态输入81个变量的数组(绝望选项),但我找不到一种安全的方法来在for循环中动态创建变量名来保存对象。这种方式在stackoverflow上发布,作为创建不同命名变量的解决方案,但它似乎根本不创建变量。

for (var i=0, i<9, i++){
    var window["cube" + i] = new THREE.Mesh( Geometry, Material)
    {

主要问题:如何以可控制的方式迭代创建多个网格(足以静态输入每个变量将是不明智的),我可以选择它们并单独操作它们而不是作为一组操作?

1 个答案:

答案 0 :(得分:1)

我认为您遇到此问题的原因是您引用相同Material来构建Mesh,您确实在blocks.children中与单个对象相交,但是当您更改某些属性时其他使用这种材料的网格材料也会发生变化。

function line(mx,my,mz){
    for (var i = 0;i<9;i++){
      material = new THREE.MeshLambertMaterial({color: 0xffffff});
      var block = new THREE.Mesh( Geometry, material);
      block.position.x = mx;
      block.position.y = my;
      block.position.z = mz;

      blocks.add(block);
      mx+=3;
    }
}

它对我有用。