我正在关注如何使用光线投射来处理可点击对象的mrdoobs示例。我也查看了许多类似的问题,并尝试了无数的事情。 光线投射有效...如果我的距离小于1。
Raycaster设置为接近0且远无穷远(默认值)。 我还没有看到任何设置距离的代码示例。
我希望有另一双眼睛。
// snippet
glow.clickables = [];
var cubeGeo = new THREE.CubeGeometry(2, 2, 2);
cubeGeo.computeFaceNormals();
var cube = new THREE.Mesh(cubeGeo, redmat);
cube.position.y = 10;
cube.position.x = 0;
cube.position.z = -12;
cube.overdraw = true;
glow.Vis.scene.add(cube);
glow.clickables.push(cube);
onclick_();
var onclick_ = function() {
$('#world').on('mousedown', function(e){
var mouseX = (event.offsetX / $('#world').width()) * 2 - 1;
var mouseY = - ( event.offsetY / $('#world').height()) * 2 + 1;
var vector = new THREE.Vector3(mouseX, mouseY, 0.1); //what should z be set to?
//console.info(vector); // A vector between -1,1 for both x and y. Z is whatever is set on the line above
projector.unprojectVector(vector, glow.Vis.camera);
var conts = glow.Vis.controls.getObject().position; // control 3dObject which the camera is added to.
var clickRay = new THREE.Raycaster(conts, vector.sub(conts).normalize());
var intersects = clickRay.intersectObjects(glow.clickables);
console.info(intersects.length);
if(intersects.length > 0) {
alert("Click detected!");
}
});
}
答案 0 :(得分:6)
以这种方式设置鼠标位置更准确。
var rect = renderer.domElement.getBoundingClientRect();
mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1;
mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1;
答案 1 :(得分:2)
对于鼠标检测(远或近!无论!),请执行以下操作:
把它放在你的全球:
var pointerDetectRay, projector, mouse2D;
将它放在你的init()函数中:
pointerDetectRay = new THREE.Raycaster();
pointerDetectRay.ray.direction.set(0, -1, 0);
projector = new THREE.Projector();
mouse2D = new THREE.Vector3(0, 0, 0);
将它放在你的render()循环函数中:
pointerDetectRay = projector.pickingRay(mouse2D.clone(), camera);
这是你的鼠标事件:
function onDocumentMouseMove(event) {
event.preventDefault();
mouse2D.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse2D.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
现在,您希望在鼠标指针下检测对象的每个位置都使用:
var intersects = pointerDetectRay.intersectObjects(scene.children);
if (intersects.length > 0) {
var intersect = intersects[0];
// intersect is the object under your mouse!
// do what ever you want!
}
答案 2 :(得分:0)
我使用以下内容,对我来说,适用于更远的距离:
var projector = new THREE.Projector();
function onDocumentMouseDown( event ) {
event.preventDefault();
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( [sphere,cylinder,cube] );
if ( intersects.length > 0 ) {
intersects[ 0 ].object.material.transparent=true;
intersects[ 0 ].object.material.opacity=0.1;
console.log(intersects[0]);
}
}
这只是将第一个选定的对象设置为半透明。完整示例:https://github.com/josdirksen/learning-threejs/blob/master/chapter-09/02-selecting-objects.html