Javascript Three.js THREE.Projector 已移至

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29366109/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:16:09  来源:igfitidea点击:

Three.js THREE.Projector has been moved to

javascriptthree.js

提问by Martin

I understand there is no THREE.projectorin version 71 (see the deprecated list), but I don't understand how to replace it, particularly in this code that detects which object has been clicked on:

我知道THREE.projector版本 71 中没有(请参阅已弃用列表),但我不明白如何替换它,尤其是在这段检测已单击对象的代码中:

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);
}

回答by WestLangley

There is now an easier pattern that works with both orthographic and perspective camera types:

现在有一个更简单的模式,适用于正交和透视相机类型:

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

three.js r.84

三.js r.84

回答by odlh

The THREE.JS raycaster documentationactually gives all the relevant information that is laid out in these answers as well as all the missing points that may be difficult to get your head around.

three.js所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);`

Hope it helps.

希望能帮助到你。

回答by Master James

I noted that all this that was said before is fine in a full window I think, but if you have other things besides a canvas on the page you need to get the click events target's offset and remove it.

我注意到之前所说的所有这些在我认为的完整窗口中都很好,但是如果页面上除了画布之外还有其他东西,则需要获取单击事件目标的偏移量并将其删除。

e = event and mVec is a THREE.Vector2

e = 事件,mVec 是一个 THREE.Vector2

    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.]

Looks like you need to watch for dragging (mouse movements) too or releasing from a drag will trigger an unwanted click when using window.addEventListener( 'click', function(e) {<code>});

看起来您也需要注意拖动(鼠标移动),或者在使用 window.addEventListener( 'click', function(e) {<code>}); 时,从拖动中释放会触发不需要的点击。

[You'll notice I put the negative sign where it's more logical as well.]

[你会注意到我把负号也放在了更合乎逻辑的地方。]

回答by Ivan Bacher

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

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

回答by George B

You can use the latest recommended version as stated above.

您可以使用如上所述的最新推荐版本。

To get your specific code working, replace:

要使您的特定代码正常工作,请替换:

projector.unprojectVector( vector, camera );

with

vector.unproject(camera);