Javascript 在Three.js(WebGl渲染器)中创建可单击的几何图形超链接

Javascript 在Three.js(WebGl渲染器)中创建可单击的几何图形超链接,javascript,html,three.js,Javascript,Html,Three.js,因此,我一直在尝试使用three.js制作一个360度球形全景图,它实现了可点击的对象,目前我想制作超链接。我已经阅读了许多以前的光线投射等示例,但没有成功地让对象将我重定向到该站点。如果有人能告诉我代码中哪里出了问题,我将不胜感激 我感觉onDocumentMouseDown下的轨道/平移功能正在干扰光线投射?我还是个新手,还没弄明白 <div id="container"></div> <script src="three.min.js"><

因此,我一直在尝试使用three.js制作一个360度球形全景图,它实现了可点击的对象,目前我想制作超链接。我已经阅读了许多以前的光线投射等示例,但没有成功地让对象将我重定向到该站点。如果有人能告诉我代码中哪里出了问题,我将不胜感激

我感觉onDocumentMouseDown下的轨道/平移功能正在干扰光线投射?我还是个新手,还没弄明白

<div id="container"></div>
    <script src="three.min.js"></script>
    <script>
        var container, stats;
        var camera, controls, scene, renderer;
        var objects = [], plane;

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

        var fov = 70,
        texture_placeholder,
        isUserInteracting = false,
        onMouseDownMouseX = 0, onMouseDownMouseY = 0,
        lon = 0, onMouseDownLon = 0,
        lat = 0, onMouseDownLat = 0,
        phi = 0, theta = 0;

        init();
        animate();

        function init() {
            var container, mesh1, sphere1, cube1;

            container = document.getElementById( 'container' );

            camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1100 );
            camera.target = new THREE.Vector3( 0, 0, 0 );

            scene = new THREE.Scene();

            mesh1 = new THREE.Mesh( new THREE.SphereGeometry( 500, 60, 40 ), new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'spherical_map_small.jpg' ), transparent: true} ) );
            mesh1.scale.x = -1;
            scene.add( mesh1 );

            meshMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff});

            var sphere1 = new THREE.Mesh( new THREE.SphereGeometry( 2.5,20,20 ), meshMaterial );
            sphere1.position.set( 50, 10, 0 );
            scene.add( sphere1 );

            sphere1.userData = { URL:"http://www.google.com"};

            renderer = new THREE.WebGLRenderer();
            renderer.setSize( window.innerWidth, window.innerHeight );

            container.appendChild( renderer.domElement );

            document.addEventListener( 'mousedown', onDocumentMouseDown, false );
            document.addEventListener( 'mousemove', onDocumentMouseMove, false );
            document.addEventListener( 'mouseup', onDocumentMouseUp, false );
            document.addEventListener( 'mousewheel', onDocumentMouseWheel, false );
            document.addEventListener( 'DOMMouseScroll', onDocumentMouseWheel, false);

            window.addEventListener( 'resize', onWindowResize, false );
        }

        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            renderer.setSize( window.innerWidth, window.innerHeight );
        }

        function onDocumentMouseDown( event ) {
            event.preventDefault();
            isUserInteracting = true;

            onPointerDownPointerX = event.clientX;
            onPointerDownPointerY = event.clientY;

            onPointerDownLon = lon;
            onPointerDownLat = lat;

            raycaster.setFromCamera( mouse, camera );

            var intersects = raycaster.intersectObjects( sphere1 );

            if ( intersects.length > 0 ) {
                controls.enabled = true;

                SELECTED = intersects[ 0 ].sphere1;

                var intersects = raycaster.intersectObject( sphere1 );
                if ( intersects.length > 0 ) {
                    window.open(intersects[0].object.userData.URL);
                }
            }   
        }

        function onDocumentMouseMove( event ) {
            if ( isUserInteracting ) {
                lon = ( onPointerDownPointerX - event.clientX ) * 0.1 + onPointerDownLon;
                lat = ( event.clientY - onPointerDownPointerY ) * 0.1 + onPointerDownLat;
            }
        }

        function onDocumentMouseUp( event ) {
            isUserInteracting = false;
        }

        function onDocumentMouseWheel( event ) {
            isUserInteracting = false;
        }

        function animate() {
            requestAnimationFrame( animate );
            render();
        }

        function render() {
            lat = Math.max( - 85, Math.min( 85, lat ) );
            phi = THREE.Math.degToRad( 90 - lat );
            theta = THREE.Math.degToRad( lon );

            camera.target.x = 500 * Math.sin( phi ) * Math.cos( theta );
            camera.target.y = 500 * Math.cos( phi );
            camera.target.z = 500 * Math.sin( phi ) * Math.sin( theta );

            camera.lookAt( camera.target );

            renderer.render( scene, camera );
        }
    </script>

查看您的代码,我注意到您创建了var mouse=new THREE.Vector2,然后在提供的代码中的任何点上都不设置它的值。然后在onDocumentMouseDown中,使用未定义的鼠标坐标raycaster.setFromCamera鼠标,camera将光线投射到场景中;由于未设置var mouse,很可能这就是您无法启动导航的原因

你需要做的是得到鼠标的标准化屏幕坐标,并将其传递到raycaster.setFromCamera我不太清楚屏幕是一个还是两个单位,而是类似的

mouse.x = (event.clientX / window.innerWidth);  // normalise the mouse screen pos
mouse.y = (event.clientY / window.innerHeight); // same

mouse.x *= 2; // 0 is the center. -1 is left and 1 is right
mouse.y -= 1;  // center 

mouse.y *= -2; // Think this is upside down If it does not work try positive 2
mouse.y += 1;  // center
如果不起作用,试着用另一种方式切换鼠标

mouse.y *= 2; //  remove the -2 and put in 2
mouse.y -= 1;  // remove the += and put in -=
当我在3D中胡闹时,我发现在场景中有一个备用的调试对象非常方便。简单的东西,如盒子或球体。使用它可以显示光线投射器光线上的点

差不多

// creat a box
var box... blah blah box creation code/
boxP = new vector3(); // position of debug object
// position it halfway in the raycasters range
boxP.x = camera.x + rayCaster.ray.x* ((rayCaster.near+rayCaster.far)/2);
boxP.y = camera.y + rayCaster.ray.y* ((rayCaster.near+rayCaster.far)/2);
boxP.z = camera.z + rayCaster.ray.z* ((rayCaster.near+rayCaster.far)/2);
box.position.set(boxP.x,boxP.y,boxP.z);
幸运的是,现在你应该知道你要去哪里了

此外,我不确定,但如果您从内部查看球体,可能必须将材质设置为双面材质,因为光线投射器忽略法线指向别处的面,因此在代码中无法看到该材质。或者尝试反转每个多边形的方向

这就是我目前所能提出的全部建议。希望你能找到问题所在