【问题标题】:three.js raycaster is selecting all objects behind and in front of the object I want to selectthree.js raycaster 正在选择我要选择的对象后面和前面的所有对象
【发布时间】:2020-01-22 18:56:08
【问题描述】:

我有一个正在使用 3js 渲染的房子的 3d 模型(.obj)。我的代码中的光线投射器正在工作,但我遇到了一个问题,它选择了我试图选择的对象后面和前面的每个对象。我只想返回我选择的对象的名称。任何帮助,将不胜感激。目前我只是将对象的名称发送到控制台。

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({canvas});
  const renderer2 = new THREE.WebGLRenderer({canvas});      
  var kitchenCameraActive = false;
  document.getElementById("roomSelect").addEventListener("change", changeIt);

function changeIt(e) {
    //e.target.value
    document.getElementById(e.target.value).click();
    console.log(e);
}

  var fov = 45;
  var aspect = 2;  // the canvas default
  var near = 0.1;
  var far = 100;
  var camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.set(-97.570, 5.878, -5.289);
  camera.rotation.set(0,0,0);   
  const controls = new THREE.OrbitControls(camera, canvas);
  controls.target.set(0, 5, 0);
  controls.update();

  document.getElementById("kitchen").addEventListener("click", changeCamera);         
  document.getElementById("bathroom").addEventListener("click", changeCamera);        
  document.getElementById("deck").addEventListener("click", changeCamera);        
  document.getElementById("livingRoom").addEventListener("click", changeCamera);        
  document.getElementById("bedRoom").addEventListener("click", changeCamera);
  document.getElementById("walkway").addEventListener("click", changeCamera);
  document.getElementById("sideHouse").addEventListener("click", changeCamera);
  document.getElementById("frontPorch").addEventListener("click", changeCamera);
  document.getElementById("garageDoor").addEventListener("click", changeCamera);
  document.getElementById("insideGarage").addEventListener("click", changeCamera);

function changeCamera(e) {       
    camera.rotation.set(e.toElement.attributes[5].nodeValue, e.toElement.attributes[6].nodeValue, e.toElement.attributes[7].nodeValue);     
    camera.fov = e.toElement.attributes[4].nodeValue;
    camera.position.set(e.toElement.attributes[1].nodeValue, e.toElement.attributes[2].nodeValue, e.toElement.attributes[3].nodeValue);     
    camera.updateProjectionMatrix();

    if (e.target.id == "walkway" || e.target.id == "frontPorch" || e.target.id == "garageDoor" || e.target.id == "insideGarage")
        {
            controls.target.set(0, 5, 0);
            controls.update();
        }

    //controls.target.set(0, 5, 0);
    //controls.update();    
    //controls.minPolarAngle = Math.PI/2;
    //controls.maxPolarAngle = Math.PI/2;
    console.log(e);
    //controls.enabled = false;                                 
  }

  const scene = new THREE.Scene();
  scene.background = new THREE.Color('black');
  {
    const planeSize = 40;

  }

    function frameArea(sizeToFitOnScreen, boxSize, boxCenter, camera) {
    const halfSizeToFitOnScreen = sizeToFitOnScreen * 0.5;
    const halfFovY = THREE.Math.degToRad(camera.fov * .5);
    const distance = halfSizeToFitOnScreen / Math.tan(halfFovY);
    // compute a unit vector that points in the direction the camera is now
    // in the xz plane from the center of the box
    const direction = (new THREE.Vector3()).subVectors(camera.position, boxCenter).multiply(new THREE.Vector3(1, 0, 1)).normalize();
    // move the camera to a position distance units way from the center
    // in whatever direction the camera was from the center already
    camera.position.copy(direction.multiplyScalar(distance).add(boxCenter));
    // pick some near and far values for the frustum that
    // will contain the box.
    camera.near = boxSize / 100;
    camera.far = boxSize * 100;
    camera.updateProjectionMatrix();
    // point the camera to look at the center of the box
    camera.lookAt(boxCenter.x, boxCenter.y, boxCenter.z);
  }

var loader = new THREE.OBJLoader();
// load a resource
loader.load(
    // resource URL
    'dapHouseGood5.obj',
    // called when resource is loaded
    function ( object ) {
        scene.add( object );
    },
    // called when loading is in progresses
    function ( xhr ) {
        console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
    },
    // called when loading has errors
    function ( error ) {
        console.log( 'An error happened' );
    });

function resizeRendererToDisplaySize(renderer) {
    const canvas = renderer.domElement;
    const width = canvas.clientWidth;
    const height = canvas.clientHeight;
    const needResize = canvas.width !== width || canvas.height !== height;
    if (needResize) {
      renderer.setSize(width, height, false);
    }
    return needResize;
  }

function render() {
    if (resizeRendererToDisplaySize(renderer)) {
      const canvas = renderer.domElement;
      camera.aspect = canvas.clientWidth / canvas.clientHeight;
      camera.updateProjectionMatrix();
    }

    renderer.render(scene, camera);                   
    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);

    function onPositionChange(o) {
    console.log("position changed in object");
    console.log(o);
    }
    controls.addEventListener('change', onPositionChange);

var mouse = new THREE.Vector2();
var raycaster, mouse = { x : 0, y : 0};
init();

function init () {
    //Usual setup code here.
    raycaster = new THREE.Raycaster();
    renderer.domElement.addEventListener( 'click', raycast, false );
    //Next setup code there.
}

function raycast ( e ) {
    //1. sets the mouse position with a coordinate system where the center
    //   of the screen is the origin
    mouse.x = ( e.clientX / window.innerWidth ) * 2 - 1;
    mouse.y = - ( e.clientY / window.innerHeight ) * 2 + 1;

    //2. set the picking ray from the camera position and mouse coordinates
    raycaster.setFromCamera( mouse, camera );
    //var mouse3D = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1,   -( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
    //raycaster.setFromCamera( mouse3D, camera );       

    //3. compute intersections
    var intersects = raycaster.intersectObjects( scene.children, true );

    for ( var i = 0; i < intersects.length; i++ ) {
        //console.log( intersects[ i ].object.id );
        console.log( intersects[ i ].object.name );
        //console.log( intersects[ i ] );
    }
}

}

main();

【问题讨论】:

    标签: javascript three.js


    【解决方案1】:

    raycaster.intersectObjects( objects, recursive = true ) 调用返回与您提供的所有对象及其子对象的交集。如果您只想在特定对象上查找交集,请仅在调用 intersectObjects 时包含该对象。这也将提高性能。

    如果您不知道您想要哪个对象,则返回按距离排序的交集结果。最近的对象是第一个,您可以使用它。

    见:https://threejs.org/docs/#api/en/core/Raycaster

    【讨论】:

    • 感谢您的澄清
    猜你喜欢
    • 2015-02-21
    • 2014-11-30
    • 1970-01-01
    • 2013-05-15
    • 1970-01-01
    • 2014-03-16
    • 1970-01-01
    • 2018-11-20
    • 1970-01-01
    相关资源
    最近更新 更多