Javascript 捕捉渲染器中特定网格上的单击事件

Javascript 捕捉渲染器中特定网格上的单击事件,javascript,three.js,Javascript,Three.js,我设置了一个包含两个网格(立方体)的画布渲染器。我需要做的是捕获每个多维数据集上的单击事件,为其调用方便的方法 到目前为止,我可以捕捉到所有渲染器上的单击事件,这意味着当我单击cube1和cube2时,单击属于同一个对象,因为它绑定到渲染器:) 我的问题是,如何绑定每个多维数据集上的单击事件 我的相关代码如下: //dom var containerPopUp=document.getElementById('popup'); //renderer

我设置了一个包含两个网格(立方体)的画布渲染器。我需要做的是
捕获每个多维数据集上的单击事件
,为其调用方便的方法

到目前为止,我可以捕捉到所有渲染器上的单击事件,这意味着当我单击cube1和cube2时,单击属于同一个对象,因为它绑定到
渲染器
:)

我的问题是,如何绑定每个多维数据集上的单击事件

我的相关代码如下:

            //dom
    var containerPopUp=document.getElementById('popup');
    //renderer
    var rendererPopUp = new THREE.CanvasRenderer();
    rendererPopUp.setSize(420,200);

    containerPopUp.appendChild(rendererPopUp.domElement);
    //Scene
    var scenePopUp = new THREE.Scene();
    //Camera
    var cameraPopUp = new THREE.PerspectiveCamera(50,60/60,1,1000);

    cameraPopUp.position.z = 220;
    cameraPopUp.position.y =  20;
    //
    scenePopUp.add(cameraPopUp);

    //Add texture for the cube
    //Use image as texture
    var img2D = new THREE.MeshBasicMaterial({ //CHANGED to MeshBasicMaterial
    map:THREE.ImageUtils.loadTexture('img/2d.png') 
    });
    img2D.map.needsUpdate = true; //ADDED
    //Add Cube
    var cubeFor2D = new THREE.Mesh(new THREE.CubeGeometry(40,80,40),img2D);
    cubeFor2D.position.x =- 60;
    cubeFor2D.position.y = 20;

    scenePopUp.add(cubeFor2D);
    //
    var img3D = new THREE.MeshBasicMaterial({ //CHANGED to MeshBasicMaterial
    map:THREE.ImageUtils.loadTexture('img/3d.png') 
    });
    img3D.map.needsUpdate = true;
    var cubeFor3D = new THREE.Mesh(new THREE.CubeGeometry(40,80,40),img3D);
    cubeFor3D.position.x = 60;
    cubeFor3D.position.y=20;

    scenePopUp.add(cubeFor3D);
    //
    rendererPopUp.render(scenePopUp,cameraPopUp);
    //
    animate();

    rendererPopUp.domElement.addEventListener('click',testCall,false);//Here the click event is bound on the whole renderer, means what ever object in the renderer is clicked, the testCall method is called.
如您所见,cubeFor2D和cubeFor3D包含在渲染器中。我需要绑定每个网格上的单击事件。我用
threex.domevent.js
尝试了这一点:

var meshes  = {};
        meshes['mesh1'] = cubeFor2D;
        meshes['mesh1'].on('mouseover', function(event){

              //response to click...
              console.log('you have clicked on cube 2D');

        });
但它不起作用,在控制台中,我得到了以下错误:

TypeError: meshes.mesh1.on is not a function
当然,我包含了API源代码文件:

    <script src="threex.domevent.js"></script>

您可以生成这样的回调。首先为每个对象定义回调函数:

mesh.callback = function() { console.log( this.name ); }
然后按照标准拣选模式进行操作:

var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();

function onDocumentMouseDown( event ) {

    event.preventDefault();

    mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
    mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;

    raycaster.setFromCamera( mouse, camera );

    var intersects = raycaster.intersectObjects( objects ); 

    if ( intersects.length > 0 ) {

        intersects[0].object.callback();

    }

}
编辑:更新为three.js r.70

  • 创建一个单击处理程序

    window.addEventListener('click', onDocumentMouseDown, false);
    
  • 定义onDocumentMouseDown函数,注意,上面答案中的区别是单击对象的索引位置

    var raycaster = new THREE.Raycaster();
    var mouse = new THREE.Vector2();
    function onDocumentMouseDown( event ) {
    event.preventDefault();
    mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
    mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
    raycaster.setFromCamera( mouse, camera );
    console.log(scene.children);
    var intersects = raycaster.intersectObjects( scene.children );
    console.log(intersects[1]);
    if ( intersects.length > 0 ) {
        intersects[1].object.callback();
    }}
    
  • 定义网格对象

    var mesh_menu_title = new THREE.Mesh(geometry_menu, materials_menu);
    mesh_menu_title.name = 'select_lang';
    mesh_menu_title.callback = function() { select_language();}
    scene.add(mesh_menu_title);
    
  • 定义回调函数

    function select_language(){
    var selectedObject = scene.getObjectByName("select_lang"); 
    scene.remove( selectedObject );
    var selectedObject = scene.getObjectByName("start");
    scene.remove( selectedObject );
    var selectedObject = scene.getObjectByName("menu");
    scene.remove( selectedObject );
    }
    
  • 因此,上面的代码将处理在画布中单击的特定对象,然后回调函数“mesh.callback”,并将从画布中删除一些场景子对象


    如果使用交集[0],则无效。对象。回调();因为在索引0处,存储的对象是顶点。

    我认为threex.doEvent.js已经过时了,事实上它已经9个月了。我也这么认为。我试图用纯Three.js实现我的目标。忘掉
    threex.domevent.js
    API吧。你对如何使用Three.js有什么建议吗?我认为这可能是一个很好的开始,可以通过任何方式检测立方体的哪一侧被点击,以及在那一侧点击的x,y是什么?如果你有问题,请发表一篇新文章。我有一扇门,有几个元素,如铰链、螺钉、锚,枢轴等,所以点击我没有得到准确的,这可能是因为他们重叠。有什么办法可以解决这个问题?任何帮助都将不胜感激。@user2906608如果您有问题,您需要发表一篇新文章。