Javascript 在Three.js(WebGl渲染器)中创建可单击的几何图形超链接
因此,我一直在尝试使用three.js制作一个360度球形全景图,它实现了可点击的对象,目前我想制作超链接。我已经阅读了许多以前的光线投射等示例,但没有成功地让对象将我重定向到该站点。如果有人能告诉我代码中哪里出了问题,我将不胜感激 我感觉onDocumentMouseDown下的轨道/平移功能正在干扰光线投射?我还是个新手,还没弄明白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"><
<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);
幸运的是,现在你应该知道你要去哪里了
此外,我不确定,但如果您从内部查看球体,可能必须将材质设置为双面材质,因为光线投射器忽略法线指向别处的面,因此在代码中无法看到该材质。或者尝试反转每个多边形的方向
这就是我目前所能提出的全部建议。希望你能找到问题所在