2015-11-07 24 views
0

因此,我一直在尝试使用three.js制作球形360全景图,该图可实现可点击的对象,目前我想制作超链接。阅读了许多以前的光线投射的例子,但是没有运气让对象真正将我重定向到网站。如果有人能告诉我在代码中哪里出错,我会非常感激。在Three.js(WebGl Renderer)中制作几何图形可点击超链接

我有一种感觉“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> 

回答

0

找我注意到你创建var mouse = new THREE.Vector2(),那么你就没有在提供的代码中的任何点设置其值。然后在onDocumentMouseDown()中,您使用未定义的鼠标坐标向场景投射光线raycaster.setFromCamera(mouse, camera);由于尚未设置var mouse,所以很有可能这就是导致您无法启动导航的原因。

你需要做的就是让鼠标归屏幕coordiantes并传递到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 
如果它

我不能完全remenber不工作尝试切换mouse.y反过来;

mouse.y *= 2; // remove the -2 and put in 2 
mouse.y -= 1; // remove the += and put in -= 

当我在3D中搞乱时,我发现非常方便的是在场景中有一个备用的调试对象。像盒子或球体一样简单。用它在raycaster的射线上显示一个点。

喜欢的东西

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

现在,运气好的话,你应该看到你的点击会。

此外,我不确定,但如果您从内部查看球体,则可能必须将材质设置为doubleSided(我无法在代码中看到它),因为raycaster忽略法线指向的面。或者尝试颠倒每个多边形的方向。

这就是我现在可以提出的所有建议。希望你找到问题。