Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/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 Three.js:Raycast有一个空的相交数组_Javascript_Three.js - Fatal编程技术网

Javascript Three.js:Raycast有一个空的相交数组

Javascript Three.js:Raycast有一个空的相交数组,javascript,three.js,Javascript,Three.js,我将此示例用于我的WebGL全景立方体: 我想知道cube用户点击了什么,我发现我可以使用Raycaster来实现这一点。根据文档,我添加了以下功能: function onMouseDown( event ) { event.preventDefault(); var mouseVector = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1,

我将此示例用于我的WebGL全景立方体:

我想知道cube用户点击了什么,我发现我可以使用Raycaster来实现这一点。根据文档,我添加了以下功能:

    function onMouseDown( event ) {
        event.preventDefault();

        var mouseVector = new THREE.Vector3(
            ( event.clientX / window.innerWidth ) * 2 - 1,
          - ( event.clientY / window.innerHeight ) * 2 + 1,
            1 );

        //projector.unprojectVector( mouseVector, camera );
        mouseVector.unproject( camera );
        var raycaster = new THREE.Raycaster( camera.position, mouseVector.sub( camera.position ).normalize() );

        // create an array containing all objects in the scene with which the ray intersects
        var intersects = raycaster.intersectObjects( scene.children );
        console.log(intersects);
        if (intersects.length>0){
            console.log("Intersected object:", intersects.length);
            intersects[ 0 ].object.material.color.setHex( Math.random() * 0xffffff );
        }
        // ...
但是,
相交
始终为空。我的场景定义为

scene = new THREE.Scene();
skyBox还添加了:

var skyBox = new THREE.Mesh( new THREE.CubeGeometry( 1, 1, 1 ), materials );
skyBox.applyMatrix( new THREE.Matrix4().makeScale( 1, 1, - 1 ) );
scene.add( skyBox );

我看到过与此问题相关的类似帖子,但不知道如何应用于此示例。欢迎提供任何指导。

尝试将此添加到材质定义中:

var materials = new THREE.SomeMaterial({
    /* other settings */,
    side: THREE.DoubleSide
});
Raycaster
不会与背面相交,除非
side
属性设置为
thire.BackSide
thire.DoubleSide
。即使从技术上讲,缩放会反转面方向,但顶点顺序保持不变,这对于
Raycaster
非常重要

一些进一步的解释

下面的代码片段显示了从天空盒中心的摄影机投影的光线(按a-Z比例反转)的外观

长方体本身看起来很奇怪,因为它已按-Z比例缩放,法线不再与材质匹配。但这是不存在的

绿色箭头表示原始光线。红色箭头表示在
Mesh.raycast
函数中该光线将发生的情况,该函数将对象的世界矩阵的倒数应用于光线,但不应用于对象的几何体。这是一个完全不同的问题

我要强调的是,在
Mesh.raycast
中,它不会影响顶点/索引顺序,因此当它检查网格的三角形时,它们仍然保持原始顺序。对于标准的
BoxGeometry
/
BoxBufferGeometry
,这意味着所有面都从几何原点向外

这意味着光线(无论变换矩阵如何影响它们)仍在尝试与这些三角形的背面相交,除非将材质设置为
3。DoubleSide
。(它也可以设置为
3.BackSide
,但-Z刻度将破坏这一点。)

如果-Z缩放框未设置为
3,则单击任一光线投射按钮将产生0个相交。双面
(默认)。单击“Set THREE.DoubleSide”按钮并重试--它现在将相交

var渲染器、场景、摄影机、控件、统计信息;
变量宽度=window.innerWidth,
高度=窗内高度,
FOV=35,
近=1,
远=1000,
ray1,ray2,网格;
函数populateScene(){
var cubeGeo=新的3.BoxBufferGeometry(10,10,10),
cubeMat=新的三点网格材质({颜色:“红色”,透明:真,不透明度:0.5});
网格=新的三个网格(cubeGeo,cubeMat);
applyMatrix(新的三个.Matrix4().makeScale(1,1,-1));
更新矩阵世界(true);
场景。添加(网格);
var dir=新的三个向量3(0.5,0.5,1);
dir.normalize();
ray1=new THREE.Ray(new THREE.Vector3(),dir);
var arrow1=新的三个.ArrowHelper(ray1.direction,ray1.origin,200x00ff00);
场景。添加(箭头1);
var inverseMatrix=新的三个.Matrix4();
获取逆矩阵(mesh.matrixWorld);
ray2=ray1.clone();
ray2.ApplyMatrix X4(反向矩阵);
var arrow2=新的三个.ArrowHelper(ray2.direction,ray2.origin,20,0xff0000);
场景。添加(箭头2);
}
函数init(){
document.body.style.backgroundColor=“slateGray”;
renderer=new THREE.WebGLRenderer({antialas:true,alpha:true});
document.body.appendChild(renderer.doElement);
document.body.style.overflow=“隐藏”;
document.body.style.margin=“0”;
document.body.style.padding=“0”;
场景=新的三个。场景();
摄像机=新的三个透视摄像机(视野、宽度/高度、近距离、远距离);
摄像机位置z=50;
场景。添加(摄影机);
控件=新的三个.trackball控件(摄影机、渲染器.doElement);
controls.dynamicDampingFactor=0.5;
controls.rotateSpeed=3;
var灯光=新的三点灯光(0xffffff,1,无穷大);
相机。添加(灯光);
统计数据=新统计数据();
stats.domElement.style.position='绝对';
stats.domElement.style.top='0';
document.body.appendChild(stats.domeElement);
调整大小();
window.onresize=调整大小;
populateScene();
制作动画();
var rayCaster=new THREE.rayCaster();
document.getElementById(“greenCast”).addEventListener(“单击”,函数(){
rayCaster.ray.copy(ray1);
警报(光线投射器。相交对象(网格)。长度+“相交!”);
});
document.getElementById(“redCast”).addEventListener(“单击”,函数(){
rayCaster.ray.copy(ray2);
警报(光线投射器。相交对象(网格)。长度+“相交!”);
});
document.getElementById(“setSide”).addEventListener(“单击”,函数(){
mesh.material.side=3.DoubleSide;
mesh.material.needsUpdate=true;
});
}
函数resize(){
宽度=window.innerWidth;
高度=窗内高度;
if(渲染器和摄影机及控件){
设置大小(宽度、高度);
camera.aspect=宽度/高度;
camera.updateProjectMatrix();
controls.handleResize();
}
}
函数render(){
渲染器。渲染(场景、摄影机);
}
函数animate(){
请求动画帧(动画);
render();
控件更新();
stats.update();
}
函数threeReady(){
init();
}
(功能(){
函数addScript(url,回调){
callback=callback | |函数(){};
var script=document.createElement(“脚本”);
script.addEventListener(“加载”,回调);
setAttribute(“src”,url);
document.head.appendChild(脚本);
}
添加脚本(“https://threejs.org/build/three.js“,函数(){
添加脚本(“https://threejs.org/examples/js/controls/TrackballControls.js“,函数(){
添加脚本(“https://threejs.org/examples/js/libs/stats.min.js“,函数(){
三就绪();
})
})
})
})();
正文{
文本对齐:居中;
}

实际上,您可能希望使用一个更简单的过程从相机确定光线:

THREE.Raycaster.prototype.setFromCamera( Vector2, Camera );
只需像在