javascript Three.js THREE.投影仪已移至

zbwhf8kr  于 2022-12-02  发布在  Java
关注(0)|答案(7)|浏览(111)

我知道在71版本中没有THREE.projector(参见不推荐使用的列表),但是我不知道如何替换它,特别是在下面的代码中,它检测哪个对象被点击了:

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(objects);
if (intersects.length > 0) {
  clicked = intersects[0];
  console.log("my clicked object:", clicked);
}
gwbalxhn

gwbalxhn1#

现在有一种更简单的模式,可以同时使用正交摄影机和透视摄影机类型:

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

...

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, recursiveFlag );

第84号三条

h6my8fg2

h6my8fg22#

threeidojs raycaster文档实际上给出了这些答案中列出的所有相关信息,以及所有可能很难让你了解的缺失点。

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

function onMouseMove( event ) { 
  // calculate mouse position in normalized device coordinates 
  // (-1 to +1) for both components 
  mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; 
  mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1; 
} 

function render() { 
  // update the picking ray with the camera and mouse position
  raycaster.setFromCamera( mouse, camera ); 
  // calculate objects intersecting the picking ray var intersects =     
  raycaster.intersectObjects( scene.children ); 

  for ( var i = 0; i < intersects.length; i++ ) { 
    intersects[ i ].object.material.color.set( 0xff0000 ); 
  }

  renderer.render( scene, camera ); 
} 
window.addEventListener( 'mousemove', onMouseMove, false );        
window.requestAnimationFrame(render);`

希望能有所帮助。

cngwdvgl

cngwdvgl3#

您可以使用如上所述的最新推荐版本。
要使特定代码正常工作,请替换:

projector.unprojectVector( vector, camera );

vector.unproject(camera);
dzjeubhm

dzjeubhm4#

我注意到,我认为之前所说的所有这些在一个完整的窗口中都是可以的,但是如果你在页面上除了画布之外还有其他东西,你需要获取点击事件目标的偏移量并删除它。
e =事件,mVec是一个三向量2

let et = e.target, de = renderer.domElement;
    let trueX = (e.pageX - et.offsetLeft);
    let trueY = (e.pageY - et.offsetTop);
    mVec.x = (((trueX / de.width) * 2) - 1);
    mVec.y = (((trueY / de.height) * -2) + 1);
    wup.raycaster.setFromCamera( mVec, camera );
    [Then check for intersections, etc.]

看起来你也需要注意拖动(鼠标移动),否则在使用窗口时释放拖动将触发不需要的点击。addEventListener('click',function(e){});
[You我会注意到我把负号放在了更符合逻辑的地方。]

6tr1vspr

6tr1vspr5#

https://github.com/mrdoob/three.js/issues/5587

var vector = new THREE.Vector3();
var raycaster = new THREE.Raycaster();
var dir = new THREE.Vector3();

...

if ( camera instanceof THREE.OrthographicCamera ) {

    vector.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, - 1 ); // z = - 1 important!

    vector.unproject( camera );

    dir.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );

    raycaster.set( vector, dir );

} else if ( camera instanceof THREE.PerspectiveCamera ) {

    vector.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 ); // z = 0.5 important!

    vector.unproject( camera );

    raycaster.set( camera.position, vector.sub( camera.position ).normalize() );

}

var intersects = raycaster.intersectObjects( objects, recursiveFlag );

Objects = Object3D类型的对象数组,用于检查与光线的相交。可以是场景中的所有内容,但如果有很多内容,则效率可能会很低。
recursiveFlag =如果为true,它也会检查所有子系。否则,它只会检查与对象的交集。预设值为true。
文档

flvlnr44

flvlnr446#

我想分享我的经验与更多的细节这样做,因为我觉得上面的答案并没有真正解释的细节,让这一点去。
在我的例子中,我使用STL_Viewer,你可以在这里找到它(https://www.viewstl.com/plugin/),它帮助创建一个threeJS场景,并为你提供你需要的相机场景

function mouse_click_normalize(clientX,clientY,offset_left,offset_top){
                var mouse = new THREE.Vector2(); // create once
                var c = document.getElementById("stl_contEye").childNodes[0];//get canvas element created in here
                mouse.x = ( (event.clientX-offset_left) / (c.clientWidth)  * 2) - 1;
                mouse.y = - ( (event.clientY-offset_top) / (c.clientHeight) ) * 2 + 1;
                console.log(`clientX=${clientX},clientY=${clientY},mouse.x=${mouse.x},mouse.y=${mouse.y}\nwidth=${c.clientWidth},height=${c.clientHeight},offset_left=${offset_left},offset_top=${offset_top}`);
                return mouse;
           }

上面是我的函数,它将自动规范化被单击空间中的x,y坐标(在-1和1之间),因为这是光线投射器的setFromCamera函数所需要的。
因为您可能会在屏幕的某个部分中单击偏移量,所以我以这种方式对它进行了编程,这样无论它在DOM中的位置如何,它都可以处理。只需将"stl_contEye"替换为div的名称,该div将包含渲染的ThreeJS或STLViewer(在我的示例中)。

function model_clicked(model_id, e, distance, click_type){
                console.log(e);
                
                var pos = new THREE.Vector3(); // create once and reuse
                // var vec = new THREE.Vector3(); // create once and reuse
                
                var camera = stl_viewer1.camera;
                var scene = stl_viewer1.scene;
                // vec.unproject( camera );
                // vec.sub( camera.position ).normalize();
                // //var distance2 = (distance - camera.position.z) / vec.z;
                // pos.copy( camera.position ).add( vec.multiplyScalar( distance ) );
                var mouse_coords_normalized = mouse_click_normalize(e.clientX,e.clientY,e.srcElement.offsetLeft,e.srcElement.offsetTop);
                var raycaster = new THREE.Raycaster(); // create once
                raycaster.setFromCamera( mouse_coords_normalized, camera );
                //console.log(raycaster);
                //console.log(scene);

                var intersects = raycaster.intersectObjects( scene.children, true );
                if(intersects.length > 0){
                    console.log(intersects);
                    console.log(intersects[0].point);
                    pos = intersects[0].point
                }
}

通过这种方式,你将得到你点击的3D空间中的确切点。函数model_clicked只返回一个包含clientX或clientY的事件,如果你没有使用STLViewers事件来检测点击,你只需要以某种方式自己得到这个。上面有很多来自其他答案的例子。
我希望这能帮助那些试图在有或没有stl_viewer的情况下弄清楚这一点的人

pcrecxhr

pcrecxhr7#

camera.shooting = Date.now()

        document.getElementById("div5").addEventListener("mousedown", mousedown);
        document.getElementById("div5").addEventListener("mouseup", mouseup);
    
        document.getElementById("div5").addEventListener( 'mousemove', renderq);
    function mousedown(event) {
    camera.calculator = 1;
    
    
    }
    function mouseup(event) {
     
    camera.calculator = 0;
       

}
    
    function renderq(event){
        
            
     if( ai2bcz.length > 0 &&  ai_key3.length > 0  ){
    
     if( camera.calculator > 0   ){
    
    
        
    camera.mouse = new THREE.Vector2();
        
    
    var fleece = document.getElementById("div5").scrollHeight;
    var fleeceb =  document.getElementById("div5").scrollWidth;
    var fees = (event.clientX / fleeceb)  - 1;
        var feesa = - (event.clientY  / fleece)  + 1;
     camera.mouse.x = fees ;  camera.mouse.y  = feesa;  
    
    var sphereMaterialc = new THREE.MeshBasicMaterial({color: 0x0099FF});
    var sphereGeoc = new THREE.SphereGeometry(5, 5, 5);
    var spherec = new THREE.Mesh(sphereGeoc, sphereMaterialc);
        spherec.position.set(camera.position.x, camera.position.y, camera.position.z);
    
        
       
        spherec.raycaster = new THREE.Raycaster();
       
       spherec.raycaster.setFromCamera( camera.mouse, camera);
            
            
        spherec.owner = 'player';
    
        spherec.health = 100;
        
        bulletsc.push(spherec);
        scene.add(spherec);
    camera.lastshot = Date.now();
    camera.shooting = Date.now();
    }
    }
    
    }
    function render() { const controlscamera = new FirstPersonControls(camera);
        
    controlscamera.update(100);
    
            
     if( ai2bcz.length > 0 &&  ai_key3.length > 0  ){
    
     if( camera.calculator > 0 && camera.shooting + 25 < Date.now()  ){
     renderq(event)
    camera.shooting = Date.now();
    }} 
    
    
    if(bulletsc.length > 1){
    
        for (var i = 0; i < bulletsc.length - 1; i++) {
    
            
            
    var bu = bulletsc[i], pu = bu.position, du = bu.raycaster.ray.direction;
    
    
    if(bu.owner == "player"){
    
    
    
                
                
    var enemybulletspeeda = window.document.getElementById("bulletsplayerspeed").value;
                bu.translateX(enemybulletspeeda * du.x);
                bu.translateY(enemybulletspeeda * du.y);
                bu.translateZ(enemybulletspeeda * du.z);
    
    }
    
    
        
    
    }}
    
    
    renderer.render( scene, camera ); }

相关问题