Javascript three.js无法使用Raycaster选择对象

Javascript three.js无法使用Raycaster选择对象,javascript,jquery,three.js,Javascript,Jquery,Three.js,我有下面的函数来获取所选对象,所以我的函数在这里 function onMouseDown(event) { console.log(event); event.preventDefault(); mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1; // find inter

我有下面的函数来获取所选对象,所以我的函数在这里

function onMouseDown(event) {
    console.log(event);
    event.preventDefault();

    mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
    mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
    // find intersections

    var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
    projector.unprojectVector( vector, camera );


    var pLocal = new THREE.Vector3(0, 0, -1);
    var pWorld = pLocal.applyMatrix4(camera.matrixWorld);
    var ray = new THREE.Raycaster(pWorld, vector.sub(pWorld).normalize());




    ray.set( camera.position, vector.sub( camera.position ).normalize() );
    var intersects = ray.intersectObjects( scene.children );
    //console.log(intersects);
    console.log(scene.children);
    if ( intersects.length > 0 ) {

    var clickedObject = intersects[0].object;

    console.log('objects '+intersects[ 0 ].object);
    console.log('objects id'+intersects[ 0 ].object.id);
    console.log('objects name'+intersects[ 0 ].object.name);

    if ( INTERSECTED != intersects[ 0 ].object ) {

    if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );

    INTERSECTED = intersects[ 0 ].object;
    console.log('INTERSECTED '+INTERSECTED);
    INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
    INTERSECTED.material.emissive.setHex( 0xff0000 );

    }

    } else {

    if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );

    INTERSECTED = null;

    }
}
但是当我在相交处得到空数组时,我尽了最大努力,但是如果我控制场景,我在这里找不到任何解决方案。孩子们,我可以看到场景中所有附加的对象 在此之前,我将对象添加到场景中,如下所示

var   loader = new THREE.JSONLoader();      
loader.load("uploads/accessories/3d/code/3dfile_"+file+".js",
      function(geometry, object_material) 
      {

          var object = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(object_material));
          model = new THREE.Object3D();
          model.id="Myid"+file;
          model.name="Myname"+file;
          model.userData ={ URL: "http://myurl.com" };
          model.add(object);    
          model.position.set(x,y,z);        
          model.scale.set(obj_width,obj_height,obj_rotation);   
          model.opacity =2;
          model.rotation.y = 600; 
          model.duration = 12000;
          model.mirroredLoop = true;
          model.castShadow = true;
          model.receiveShadow = true;

          console.log(model);   
          var smodel=model;
          scene.add(smodel);                            
      }
  );
现在我想通过新的THREE.Object3D获得添加的模型;在onMouseDown,但我不能,有人有同样的问题吗

您需要将递归标志传递给Raycaster.intersectObjects

另外,不要覆盖Object3D.id。改为设置Object3D.userData.id

three.js r.68

试着通过这个。查看控制台中的消息

<script src="js/controls/EventsControls.js"></script>

EventsControls = new EventsControls( camera, renderer.domElement );
EventsControls.draggable = false;

EventsControls.onclick = function() {

   console.log( this.focused.name );

}

var jsonLoader = new THREE.JSONLoader();
jsonLoader.load( "models/Tux.js", addModelToScene ); 


function addModelToScene( geometry, materials ) {

   var material = new THREE.MeshFaceMaterial( materials );
   model = new THREE.Mesh( geometry, material );
   model.scale.set( 10, 10, 10 ); model.name = 'Tux';
   model.rotation.x = -Math.PI/2; 
   model.position.set( 175, 45, 125 );
   scene.add( model ); 
   EventsControls.attach( model );

}

您使用的是无需抓取十六进制的MeshFace材质。您必须从“材质”中获取“材质数组”,如下所示:

for(var p =0; p < INTERSECTED.material.materials.length; p++){
    INTERSECTED.currentHex = INTERSECTED.material.materials[p].emissive.getHex();
}
这样,您就不会选择MeshFace材质,而是选择用于每个面的Meshlambert材质或MeshBasicMaterial。如果你使用图像作为纹理,我建议你快速回答这个问题

希望这是有帮助的

Raycaster有点狡猾我补充了解释

要使raycaster工作,需要进行典型的设置,如下所示:

首先初始化一个变量以保持鼠标位置,我们需要从该位置发射光线

var mouse = {
  x: 0,
  y: 0
};

 //object intersected 
var INTERSECTED;

// pool of objects which can be selected
var objects = [];

// ray caster initialization
var  raycaster = new THREE.Raycaster();
我们需要创建Object3D父对象以容纳所有子网格

let mainGroup = new THREE.Object3D();
// add into object pool
objects.push(mainGroup);
scene.add(mainGroup);


// add mesh to be select by ray caster in Object3D parent
mainGroup.add(meshToSelect);
添加事件侦听器以获取鼠标的X、Y位置

document.addEventListener("mousemove", this.onDocumentMouseMove, false);


  onDocumentMouseMove = event => {
    event.preventDefault();

    if (event && typeof event !== undefined) {
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
    }
  };
现在像这样使用光线投射器:

  renderScene = () => {

    // Emit ray
    raycaster.setFromCamera(mouse, this.camera);

    // all intersects 
    var intersects = raycaster.intersectObjects(objects, true);

    if (intersects.length > 0) {
      if (INTERSECTED != intersects[0].object) {
         //if new item selected swap color of new item 
         //& revert color of previous item
        if (INTERSECTED)
          INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
        INTERSECTED = intersects[0].object;
        INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
        INTERSECTED.material.color.setHex(0xff0000);

      }
    } else {
       // None selected then revert color of previous item
      if (INTERSECTED)
        INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
      INTERSECTED = null;
    }

    if (this.renderer) this.renderer.render(scene, this.camera);
  };

嗨,我做到了。我仍然无法选择相交的对象。佐提,这并不难。我打赌你可以找到你自己的错误。我找不到我这边的任何问题,所以我对这些事情感到沮丧,我正在做你所做的一切来获得相交的对象,但我失败了。这可能与异步调用load的回调有关吗?ie回调不会在与.load自身相同的事件回合中运行,因此场景直到将来某个不确定的时间才会接收新模型-可能只有几秒钟,但肯定是在将来的javascript事件回合中。在给定的示例中,我找不到任何与Raycaster相关的术语?Raycaster位于置换控件中。对于那些不想知道这样一个Raycaster=。如果需要任何其他机会,请修改DisplaceControl.js代码。我将DisplaceControl重命名为ObjectControls,发现并更正了一个bug,并更改了链接。如果它仍然是真实的,也请改变。
  renderScene = () => {

    // Emit ray
    raycaster.setFromCamera(mouse, this.camera);

    // all intersects 
    var intersects = raycaster.intersectObjects(objects, true);

    if (intersects.length > 0) {
      if (INTERSECTED != intersects[0].object) {
         //if new item selected swap color of new item 
         //& revert color of previous item
        if (INTERSECTED)
          INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
        INTERSECTED = intersects[0].object;
        INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
        INTERSECTED.material.color.setHex(0xff0000);

      }
    } else {
       // None selected then revert color of previous item
      if (INTERSECTED)
        INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
      INTERSECTED = null;
    }

    if (this.renderer) this.renderer.render(scene, this.camera);
  };