当我使用raycaster单击相关行星时,我试图导航至相关链接。相反,单击画布的任何部分时,它将带我到最后一个行星的URL(此处称为类别)。我正在使用一个函数来独立于init()创建行星和补间。如何构造raycaster以仅单击行星以导航到其相关的URL。感谢您的宝贵时间。
以下代码:
class App extends Component{
componentDidMount() {
var scene, camera, renderer;
var controls;
var category, orbit, orbitContainer
init();
animate();
function createSubCategory(){}
function createCategory(name, radius, distance, tilt, color, speed, link) {
orbitContainer = new THREE.Object3D();
orbitContainer.rotation.x = tilt;
// orbitContainer.rotation.x = 700;
var id = name
orbit = new THREE.Object3D();
var geometry = new THREE.CircleGeometry(distance, 100);
geometry.vertices.shift();
var line = new THREE.Line(
geometry,
new THREE.LineBasicMaterial({color: 'aqua'})
);
//ring movement
line.rotation.x = Math.PI * 0.5;
category = new THREE.Mesh(
new THREE.SphereGeometry(radius, 0, 0),
//new THREE.MeshPhongMaterial({color:color,wireframe: true})
new THREE.MeshBasicMaterial({color:color,wireframe: true})
);
orbitContainer.userData.URL= link
// initial position
// distance away from the center
//change initial position
category.position.set(distance, 0.0, 0.0);
//orbit.add(line);
orbit.add(category);
new TWEEN.Tween(orbit.rotation,{
loop: true,
//useTicks: true,
//css: true,
//ignoreGlobalPause: true
}).to({y: //'+' or '-' for rotation direction
'+' + (Math.PI * 2)}, 4000 / speed);
orbitContainer.add(orbit);
scene.add(orbitContainer);
}
function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0x202020);
camera = new THREE.PerspectiveCamera(60, 4 / 3, 0.1, 10000.0);
camera.position.set(20.0, 20.0, 20.0);
camera.lookAt(new THREE.Vector3(0, 0, 0));
renderer = new THREE.WebGLRenderer({antialias: false});
document.addEventListener('mousedown', onDocumentMouseDown, false);
controls = new OrbitControls(camera, renderer.domElement);
var ambientLight = new THREE.AmbientLight(0xffffff, 0.1);
scene.add(ambientLight);
//light emission will be the icon with a line connecting to the logo (sun) and will light up the line and icon when selected
var solar = new THREE.Mesh(
new THREE.SphereGeometry(2.5, 32, 32),
new THREE.MeshBasicMaterial({emissive: 0xff5800, emissiveIntensity: 0.5, wireframe: true, color:'silver'})
);
var pointLight = new THREE.PointLight(0xffffff, 1.0, 300.0);
solar.add(pointLight);
scene.add(solar);
createCategory('B',1.35, 7.2, 0.0, 'yellow', 0.4, "http://google.com" );
createCategory('A',1.35, 11.0, 0.0, 'red', 0.3, "http://yahoo.com");
createCategory('D Print', 1.35, 14.0, 0.0, 'blue', 0.2, "http://msn.com");
createCategory('C Design', 1.35, 17.3, 0.0, 'green', 0.1, "http://facebook.com");
createCategory('N', 1.35, 12.2, 5.0, 'pink', 0.4, "http://stackoverflow.com");
window.addEventListener('resize', onWindowResize, false);
onWindowResize();
document.body.appendChild(renderer.domElement);
}
function onDocumentMouseDown(event) {
event.preventDefault();
var raycaster = new THREE.Raycaster(); // create once
var mouse = new THREE.Vector2(); // create once
mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects(orbitContainer);
if (intersects.length === 0) {
window.open(orbitContainer.userData.URL);
}
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
controls.update();
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
}
答案 0 :(得分:1)
您的代码有2个问题:
它将我带到最后一个星球的网址
这是因为您正在使用相同的全局变量orbitContainer
创建5个类别。每次调用createCategory
时,URL都会被覆盖,因此,当您调用window.open(orbitContainer.userData.URL);
时,它将打开您分配的最后一个URL。发生的事情是这样的:
orbitContainer.userData.URL = "http://google.com";
orbitContainer.userData.URL = "http://yahoo.com";
orbitContainer.userData.URL = "http://msn.com";
orbitContainer.userData.URL = "http://facebook.com";
orbitContainer.userData.URL = "http://stackoverflow.com";
window.open(orbitContainer.userData.URL); // <- this opens stackoverflow
解决方案:您应该从raycaster的结果中获取URL:
intersects = raycaster.intersectObjects( scene.children );
if (intersects.length > 0) {
window.open(intersects[0].object.userData.URL);
}
当单击画布的任何部分时
这是因为您在执行此操作时将明确检查零交点:
if (intersects.length === 0) {
window.open(orbitContainer.userData.URL);
}
您应该使用上述解决方案中的if (intersects.length > 0)
检查拦截情况。
此外,请确保您正在对场景的子级执行光线投射:raycaster.intersectObjects( scene.children );
而不是orbitContainer
,因为正如我所说,每次创建新类别时都会覆盖它,因此它会赢得里面没有所有对象。