2015-11-07 26 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忽略法線指向的面。或者嘗試顛倒每個多邊形的方向。

這就是我現在可以提出的所有建議。希望你找到問題。