所以我一直在尝试使用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>
答案 0 :(得分:0)
查看您的代码我注意到您创建了var mouse = new THREE.Vector2()
,然后您不会在提供的代码中的任何位置设置其值。然后在onDocumentMouseDown()
中,您使用未定义的鼠标坐标raycaster.setFromCamera( mouse, 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中搞乱时,我发现非常方便的是在场景中有一个备用的调试对象。像盒子或球体一样简单的东西。用它来显示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会忽略法线指向的面孔。或者尝试反转每个多边形的方向。
这就是我现在所能提出的所有建议。希望你能找到问题。