Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从鼠标位置释放三个.js光线_Javascript_Jquery_Html_Three.js - Fatal编程技术网

Javascript 从鼠标位置释放三个.js光线

Javascript 从鼠标位置释放三个.js光线,javascript,jquery,html,three.js,Javascript,Jquery,Html,Three.js,我目前正在three.js和一些jQuery中构建一个应用程序。我当前正在进行光线投射,并在光线投射命中的位置放置辅助对象。或多或少,我正在努力实现 我已经成功地实现了这一点,但是在移动对象的坐标并将摄影机移动到新位置时,我的光线投射(至少是辅助对象)处于禁用状态。它似乎被关闭了大约30个像素,但这取决于你改变相机的角度,你可以从中看到 以下是光线投射的帮助器和onMouseMove事件的代码 // RAYCAST HELPER var geometry = new TH

我目前正在three.js和一些jQuery中构建一个应用程序。我当前正在进行光线投射,并在光线投射命中的位置放置辅助对象。或多或少,我正在努力实现

我已经成功地实现了这一点,但是在移动对象的坐标并将摄影机移动到新位置时,我的光线投射(至少是辅助对象)处于禁用状态。它似乎被关闭了大约30个像素,但这取决于你改变相机的角度,你可以从中看到

以下是光线投射的帮助器和onMouseMove事件的代码

// RAYCAST HELPER
            var geometry = new THREE.CylinderGeometry( 0, 5, 15, 3 ); // radius at top, radius at bottom, height, segments
            //geometry.applyMatrix( new THREE.Matrix4().makeTranslation( -50, 0, 0 ) );
            geometry.applyMatrix( new THREE.Matrix4().makeRotationX( Math.PI / 2 ) );
            helper = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial({ color: 0xEB1515, ambient: 0xEB1515, wireframe: false }) );
            scene.add( helper );
            rays = true;

    function onMouseMove( event ) {
                    //console.log("Mouse moved");
                    $( document ).ready(function() {
                    if ( rays == true ) {

                        cX = event.clientX - $( "#info" ).width()
                        cY = event.clientY - $( "#topbar" ).height()

                        mouseVector.x = 2 * ( cX / canvaswidth ) - 1;
                        mouseVector.y = 1 - 2 * ( cY / canvasheight );
                        mouseVector.z = 1;

                        var raycaster = projector.pickingRay( mouseVector.clone(), camera );

                        for (var i = 0; i < buildingsroofs.length; i++) {
                            var intersects = raycaster.intersectObject( buildingsroofs[i]);

                            // Toggle rotation bool for meshes that we clicked
                            if ( intersects.length > 0 ) {
                                console.log("Intersection");
                                helper.position.set( 0, 0, 0 );
                                helper.lookAt( intersects[ 0 ].face.normal );
                                helper.position.copy(intersects[0].point);
                            } 
                        }
                    } //End of overarching if loop
                }) 
            } //End of onMouse function
//光线投射辅助对象
var几何体=新的三个。圆柱体几何体(0、5、15、3);//顶部半径、底部半径、高度、分段
//applyMatrix(新的三个.Matrix4().makeTranslation(-50,0,0));
geometry.applyMatrix(新的三个.Matrix4().makeRotationX(Math.PI/2));
helper=new THREE.Mesh(几何体,new THREE.MeshLambertMaterial({color:0xEB1515,ambient:0xEB1515,线框:false}));
场景.添加(助手);
射线=真;
mouseMove函数(事件){
//log(“鼠标移动”);
$(文档).ready(函数(){
如果(光线==真){
cX=event.clientX-$(“#info”).width()
cY=event.clientY-$(“#topbar”).height()
mouseVector.x=2*(cX/画布宽度)-1;
mouseVector.y=1-2*(cY/画布高度);
mouseVector.z=1;
var raycaster=projector.pickingRay(mouseVector.clone(),camera);
对于(var i=0;i0){
控制台日志(“交叉点”);
helper.position.set(0,0,0);
helper.lookAt(与[0].face.normal相交);
helper.position.copy(与[0]点相交);
} 
}
}//全局if循环结束
}) 
}//onMouse函数结束

有趣的是,我已经让它工作了,但是这些物体的坐标和我要找的不一样。您还可以看到,我正在调整顶部div和侧面div的高度,因此这似乎不是我最初想象的问题。

奇怪的是,将“透视摄影机近”参数从0.1更改为1后,问题似乎自行解决了

camera = new THREE.PerspectiveCamera(45, canvaswidth / canvasheight , 0.1, 10000 );
致:

我仍然不能100%确定为什么这样做可以解决这个问题,但它似乎起到了作用


编辑:将FOV从45更改为60消除了光线投射中的微小失真,该失真在更改“近相机”参数后仍在发生。

由于其他一切都是正确的,您的
mouseVector
x
y
值(即
clientX
clientY
)与您的WebGL画布相比,最有可能是关闭的(例如,您可能从画布以外的某些元素获得这些


检查此问题的最简单方法是将鼠标放在画布的左上角(应该是
(0,0)
),然后在单击时注销鼠标位置,查看您的值是否已关闭。在右下角应用相同的方法,检查画布的宽度和高度。我用这种方法解决了类似的问题。在我的例子中,
(cx,cy)
(-10,-10)
,这对于光线投射中的一个重大错误来说已经足够了。

如果您使用的是ClientX和ClientY,请使用event.OffsetX和event.OffsetY。

在这方面遇到了很多困难,我仍然不知道为什么这样做,但是x和y的计算对我来说是可行的

// RAYCAST HELPER
            var geometry = new THREE.CylinderGeometry( 0, 5, 15, 3 ); // radius at top, radius at bottom, height, segments
            //geometry.applyMatrix( new THREE.Matrix4().makeTranslation( -50, 0, 0 ) );
            geometry.applyMatrix( new THREE.Matrix4().makeRotationX( Math.PI / 2 ) );
            helper = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial({ color: 0xEB1515, ambient: 0xEB1515, wireframe: false }) );
            scene.add( helper );
            rays = true;

    function onMouseMove( event ) {
                    //console.log("Mouse moved");
                    $( document ).ready(function() {
                    if ( rays == true ) {

                        cX = event.clientX - $( "#info" ).width()
                        cY = event.clientY - $( "#topbar" ).height()

                        mouseVector.x = 2 * ( cX / canvaswidth ) - 1;
                        mouseVector.y = 1 - 2 * ( cY / canvasheight );
                        mouseVector.z = 1;

                        var raycaster = projector.pickingRay( mouseVector.clone(), camera );

                        for (var i = 0; i < buildingsroofs.length; i++) {
                            var intersects = raycaster.intersectObject( buildingsroofs[i]);

                            // Toggle rotation bool for meshes that we clicked
                            if ( intersects.length > 0 ) {
                                console.log("Intersection");
                                helper.position.set( 0, 0, 0 );
                                helper.lookAt( intersects[ 0 ].face.normal );
                                helper.position.copy(intersects[0].point);
                            } 
                        }
                    } //End of overarching if loop
                }) 
            } //End of onMouse function
let canvas = document.querySelector('canvas');

let x = (event.offsetX / canvas.clientWidth) * 2 - 1;
let y = -(event.offsetY / canvas.clientHeight) * 2 + 1;

因为我没有使用全屏分辨率作为我的WebGL画布的大小,所以我需要进行另一种计算来减去窗口和画布之间的距离,以定义我的鼠标实际悬停的位置

function onDocumentMouseMove( event ) {
    mouseVector.x = (event.offsetX / (window.innerWidth - 240)) * 2 - 1;
    mouseVector.y = -(event.offsetY / (window.innerHeight - 100)) * 2 + 1;
}
// when the mouse moves, call the given function
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
正确计算画布大小的鼠标坐标后,画布内的对象的反应会更准确。(此解决方案不操纵摄影机,只返回鼠标坐标。)


希望这能有所帮助。

你好,尼克,谢谢你的回复。我最近又遇到了这个问题。我查看了你的解决方案,但是鼠标坐标似乎是正确的,尽管我认为这仍然是一个很好的答案,因为它确实会影响交叉点位置。将远平截头体和纵横比更改为稍高的值似乎有帮助现在帮我解决这个问题。@Loxodromes很高兴我能提供一些见解,尽管我必须说你的情况很奇怪。我使用r62,甚至是一个最小的跑步应用程序,短距离光线投射(少于100个单位)工作非常准确。您的光线投射距离是否比这大得多?您是否恢复到最小测试用例?您是在移动浏览器还是桌面浏览器中工作?我正在桌面浏览器上运行r67,我确实使用了更大的单位,因为我使用的是英国地理信息(英国国家栅格坐标)因此,目前大约有600000个可能是问题的原因。感谢您完全调整了平截头体和视场似乎解决了问题,尽管我不能诚实地告诉您原因。在此之前,我确实使用了raycaster precision,但这似乎也没有任何影响。我花了数小时来解决这个问题。谢谢!