Three.js, raycasting - создать сферу как гиперссылку - PullRequest
0 голосов
/ 08 ноября 2018

Я хотел бы создать гиперссылки на сферы, планеты ". Ссылки будут ссылаться на div, созданный в index.html, для создания push-up-контента (как при нажатии на иконку гамбургера на этом сайте). : http://serwer1814906.home.pl/LEM-01/lem_desktop.html). Таким образом, каждая сфера откроет еще один div.

Я создал базовый код, используя raycaster, чтобы сделать сферу Землю гиперссылкой на домашнюю страницу three.js, но она не работает. Можете ли вы помочь мне написать правильный код для этого?

Код приходит сюда (он довольно длинный, я сделал 6 сфер):

// --- cleaning console --- //
console.clear();

// --- threeJS --- //
var renderer, scene, camera, distance, raycaster, projector, labelRenderer;

var container = document.getElementById('container');

var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var distance = 400;


var clock = new THREE.Clock();
var textureLoader = new THREE.TextureLoader();

var earth, saturn, mars, jowish, mercury, jupiter, line;


init();
animate();



// -- basic initialization -- //
function init() {


    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.2, 25000);
    camera.position.set(100, 100, 2000);
    scene.add(camera);

    light = new THREE.PointLight(0xffffff, 1, 1000);
    light.position.set(150, 50, 100);
    light_two = new THREE.PointLight(0xffffff, 1, 1000);
    light_two.position.set(-100, 50, 500);
    light_three = new THREE.PointLight(0xffffff, 1, 1000);
    light_three.position.set(250, 800, 450);

    scene.add(light, light_two, light_three);

    createPlanet();



    var size = 10000, step = 70;

    var geometry = new THREE.Geometry();
    var material = new THREE.LineBasicMaterial({
        color: 0x404040,
        linewidth: 1
    });

    for ( var i = - size; i <= size; i += step){
        geometry.vertices.push(new THREE.Vector3( - size, - 0.04, i));
        geometry.vertices.push(new THREE.Vector3( size, - 0.04, i));

        geometry.vertices.push(new THREE.Vector3( i, - 0.04, - size));
        geometry.vertices.push(new THREE.Vector3( i, - 0.04, size));
    }

    var line = new THREE.Line( geometry, material, THREE.LinePieces);
    line.rotation.x = Math.PI / 2;
    scene.add(line);



    var curve = new THREE.SplineCurve( [
        new THREE.Vector2( -1000, -100 ),
        new THREE.Vector2( -500, -250 ),
        new THREE.Vector2( 10, -200 ),
        new THREE.Vector2( 50, -500 ),
        new THREE.Vector2( 1200, 0 )
    ] );

    var points = curve.getPoints( 500 );
    var geometry = new THREE.BufferGeometry().setFromPoints( points );

    var material = new THREE.LineBasicMaterial( { 
        color : 0xffffff,
        linewidth: 2
    } );

                // Create the final object to add to the scene
    var splineObject = new THREE.Line( geometry, material );
    scene.add(splineObject);

    var curve = new THREE.SplineCurve( [
        new THREE.Vector2( -1500, 800 ),
        new THREE.Vector2( -500, 300 ),
        new THREE.Vector2( 220, 450 ),
        new THREE.Vector2( 300, 300 ),
        new THREE.Vector2( 1100, 600 )
    ] );

    var points = curve.getPoints( 500 );
    var geometry = new THREE.BufferGeometry().setFromPoints( points );

    var material = new THREE.LineBasicMaterial( { 
        color : 0xffffff,
        linewidth : 2 
    } );

                // Create the final object to add to the scene
    var splineObject = new THREE.Line( geometry, material );
    scene.add(splineObject);


    renderer = new THREE.WebGLRenderer({
        antialias: true
    });
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColor(0x000, 1);
    container.appendChild(renderer.domElement);
    document.body.appendChild( renderer.domElement );


    labelRenderer = new THREE.CSS2DRenderer();
    labelRenderer.setSize( window.innerWidth, window.innerHeight );
    labelRenderer.domElement.style.position = 'absolute';
    labelRenderer.domElement.style.top = 0;
    document.body.appendChild( labelRenderer.domElement );


    renderer.render(scene, camera);

    document.addEventListener('mousemove', onMouseMove, false);
    window.addEventListener('resize', onWindowResize, false);
}


function createPlanet() {


            var EARTH_RADIUS = 2;
            var SATURN_RADIUS = 2.5;
            var MARS_RADIUS = 2;
            var JOWISH_RADIUS = 2;
            var MERCURY_RADIUS = 2.5;
            var JUPITER_RADIUS = 3;


            var earthGeometry = new THREE.SphereBufferGeometry( EARTH_RADIUS, 120, 120 );
            var earthMaterial = new THREE.MeshPhongMaterial( {
                    specular: 0x333333,
                    shininess: 50,
                    map: textureLoader.load( 'js/texture/planet2.jpg' ),
                    specularMap: textureLoader.load( 'js/texture/planet2.jpg' ),
                    normalMap: textureLoader.load( 'js/texture/planet2_NRM.png' ),
                    normalScale: new THREE.Vector2( 0.85, 0.85 )
                } );
            earth = new THREE.Mesh( earthGeometry, earthMaterial );
            earth.position.x = 320;
            earth.position.y = 500;
            earth.position.z = 200;
            earth.rotation.y = Math.random() * 2 * Math.PI;
            earth.scale.x = earth.scale.y = earth.scale.z = Math.random() * 50 + 10;
            earth.userData = { URL: "http://threejs.org"};

                scene.add( earth );


            var earthDiv = document.createElement( 'div' );
            earthDiv.className = 'label';
            earthDiv.textContent = '.Projekt-1';
            earthDiv.style.marginTop = '-1em';
            var earthLabel = new THREE.CSS2DObject( earthDiv );
            earthLabel.position.set( (EARTH_RADIUS + 2), 0, 0 );
            earth.add( earthLabel );


            var saturnGeometry = new THREE.SphereBufferGeometry( SATURN_RADIUS, 120, 120 );
            var saturnMaterial = new THREE.MeshPhongMaterial( {
                    specular: 0xffffff,
                    shininess: 5,
                    map: textureLoader.load( 'js/texture/planet4.jpg' ),
                    specularMap: textureLoader.load( 'js/texture/planet4.jpg' ),
                    normalMap: textureLoader.load( 'js/texture/planet2_NRM.png' ),
                    //normalScale: new THREE.Vector2( 0.85, 0.85 )
                } );
            saturn = new THREE.Mesh( saturnGeometry, saturnMaterial );
            saturn.position.x = 750;
            saturn.position.y = 450;
            saturn.position.z = 100;
            saturn.rotation.y = Math.random() * 2 * Math.PI;
            saturn.scale.x = saturn.scale.y = saturn.scale.z = Math.random() * 50 + 10;

                scene.add( saturn );


            var saturnDiv = document.createElement( 'div' );
            saturnDiv.className = 'label';
            saturnDiv.textContent = '.Projekt-2';
            saturnDiv.style.marginTop = '-1em';
            var saturnLabel = new THREE.CSS2DObject( saturnDiv );
            saturnLabel.position.set( 0, (SATURN_RADIUS + 0.5), 0 );
            saturn.add( saturnLabel );

            var marsGeometry = new THREE.SphereBufferGeometry( MARS_RADIUS, 120, 120 );
            var marsMaterial = new THREE.MeshPhongMaterial( {
                    specular: 0x333333,
                    shininess: 50,
                    map: textureLoader.load( 'js/texture/planet5.jpg' ),
                    specularMap: textureLoader.load( 'js/texture/planet2.jpg' ),
                    normalMap: textureLoader.load( 'js/texture/planet2_NRM.png' ),
                    //normalScale: new THREE.Vector2( 0.95, 0.85 )
                } );
            mars = new THREE.Mesh( marsGeometry, marsMaterial );
            mars.position.x = -350;
            mars.position.y = 250;
            mars.position.z = 100;
            mars.rotation.y = Math.random() * 2 * Math.PI;
            mars.scale.x = mars.scale.y = mars.scale.z = Math.random() * 50 + 10;

            scene.add( mars );


            var marsDiv = document.createElement( 'div' );
            marsDiv.className = 'label';
            marsDiv.textContent = '.Projekt-3';
            marsDiv.style.marginTop = '-1em';
            var marsLabel = new THREE.CSS2DObject( marsDiv );
            marsLabel.position.set( 0, (MARS_RADIUS + 0.5), 0 );
            mars.add( marsLabel );

            var jowishGeometry = new THREE.SphereBufferGeometry( JOWISH_RADIUS, 120, 120 );
            var jowishMaterial = new THREE.MeshPhongMaterial( {
                    specular: 0x333333,
                    shininess: 50,
                    map: textureLoader.load( 'js/texture/planet7.jpg' ),
                    specularMap: textureLoader.load( 'js/texture/planet2.jpg' ),
                    normalMap: textureLoader.load( 'js/texture/planet2_NRM.png' ),
                    //normalScale: new THREE.Vector2( 0.85, 0.85 )
                } );
            jowish = new THREE.Mesh( jowishGeometry, jowishMaterial );
            jowish.position.x = -600;
            jowish.position.y = -200;
            jowish.position.z = 100;
            jowish.rotation.y = Math.random() * 4 * Math.PI;
            jowish.scale.x = jowish.scale.y = jowish.scale.z = Math.random() * 50 + 10;

                scene.add( jowish );


            var jowishDiv = document.createElement( 'div' );
            jowishDiv.className = 'label';
            jowishDiv.textContent = '.Projekt-4';
            jowishDiv.style.marginTop = '-1em';
            var jowishLabel = new THREE.CSS2DObject( jowishDiv );
            jowishLabel.position.set( JOWISH_RADIUS, 2, 0 );
            jowish.add( jowishLabel );


            var mercuryGeometry = new THREE.SphereBufferGeometry( MERCURY_RADIUS, 120, 120 );
            var mercuryMaterial = new THREE.MeshPhongMaterial( {
                    specular: 0x333333,
                    shininess: 50,
                    map: textureLoader.load( 'js/texture/planet6.jpg' ),
                    specularMap: textureLoader.load( 'js/texture/planet2.jpg' ),
                    normalMap: textureLoader.load( 'js/texture/planet2_NRM.png' ),
                    normalScale: new THREE.Vector2( 0.85, 0.85 )
                } );
            mercury = new THREE.Mesh( mercuryGeometry, mercuryMaterial );
            mercury.position.x = 400;
            mercury.position.y = -500;
            mercury.position.z = 100;
            mercury.rotation.y = Math.random() * 2 * Math.PI;
            mercury.scale.x = mercury.scale.y = mercury.scale.z = Math.random() * 50 + 10;

                scene.add( mercury );


            var mercuryDiv = document.createElement( 'div' );
            mercuryDiv.className = 'label';
            mercuryDiv.textContent = '.Projekt-5';
            mercuryDiv.style.marginTop = '-1em';
            var mercuryLabel = new THREE.CSS2DObject( mercuryDiv );
            mercuryLabel.position.set( MERCURY_RADIUS, 2, 0 );
            mercury.add( mercuryLabel );

            var jupiterGeometry = new THREE.SphereBufferGeometry( JUPITER_RADIUS, 120, 120 );
            var jupiterMaterial = new THREE.MeshPhongMaterial( {
                    specular: 0x333333,
                    shininess: 50,
                    map: textureLoader.load( 'js/texture/planet8.jpg' ),
                    specularMap: textureLoader.load( 'js/texture/planet2.jpg' ),
                    normalMap: textureLoader.load( 'js/texture/planet2_NRM.png' ),
                    normalScale: new THREE.Vector2( 0.85, 0.85 )
                } );
            jupiter = new THREE.Mesh( jupiterGeometry, jupiterMaterial );
            jupiter.position.x = 900;
            jupiter.position.y = -180;
            jupiter.position.z = 50;
            jupiter.rotation.y = Math.random() * 2 * Math.PI;
            jupiter.scale.x = jupiter.scale.y = jupiter.scale.z = Math.random() * 50 + 10;
            jupiter.userData = { URL: "http://stackoverflow.com"};
            scene.add( jupiter );


            var jupiterDiv = document.createElement( 'div' );
            jupiterDiv.className = 'label';
            jupiterDiv.textContent = '.Projekt-6';
            jupiterDiv.style.marginTop = '-1em';
            var jupiterLabel = new THREE.CSS2DObject( jupiterDiv );
            jupiterLabel.position.set( JUPITER_RADIUS, 2, 0 );
            jupiter.add( jupiterLabel );



}



// -- events -- //
function onMouseMove(event) {

    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
    mouseX = event.clientX - window.innerWidth / 2;
    mouseY = event.clientY - window.innerHeight / 2;
    camera.position.x += (mouseX - camera.position.x) * 0.01;
    camera.position.y += (mouseY - camera.position.y) * 0.01;
    camera.lookAt(scene.position);

};

function onDocumentMouseDown(event) {
    event.preventDefault();
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

    raycaster.setFromCamera(mouse, camera);

    var intersects = raycaster.intersectObjects(earth);
    if (intersects.length > 0) {
    //get a link from the userData object
        window.open(intersects[0].object.userData.URL);
    }
};


function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    renderer.setSize(window.innerWidth, window.innerHeight);
    labelRenderer.setSize( window.innerWidth, window.innerHeight );
    camera.updateProjectionMatrix();
};


// ---- //
function animate() {
    requestAnimationFrame(animate);
    var elapsed = clock.getElapsedTime();
    render();
};



// -- render all -- //
function render() {

    var timer = 0.00001 * Date.now();

    earth.rotation.z += Math.PI / 500;
    saturn.rotation.y += Math.PI / 500;
    mars.rotation.y += Math.PI / 500;
    jowish.rotation.z += Math.PI / 500;
    mercury.rotation.z += Math.PI / 500;
    jupiter.rotation.z += Math.PI / 700;



    renderer.render(scene, camera);
    labelRenderer.render( scene, camera );


};
...