latitude longitude on sphere in three.js

1.8k views Asked by At

I have a globe in threeJS that can be rotated in any direction. As it is currently, I can read the correct longitude and latitude located at the center of the globe regardless of rotation. The globe is orientated so that the raycaster.ray.origin.x and raycaster.ray.origin.y read 0,0 where the prime meridian and the equator cross. The raycaster.ray.origin.z reads 500.

Where I am trying to get to, however, is determining the latitude and longitude based on where the mouse is clicked on the globe. I was trying to calculate it off of the raycaster.ray.direction.x , y , z, but I am getting readings whether I am on the object or not.

If I read the direction from origin 0,0, my raycaster.ray.direction.x and y will both read 0 and the z will read -100 (I multiplied these by one hundred to work with better numbers). On the circumference the X will read 0 on the top and bottom of the globe and -40 to 40 left to right. The Y will read 40 to - 40 top to bottom and 0 left to right and the Z direction will be -90 around the entire circumference. However the numbers will continue increasing/ decreasing as all the way to the edge of the screen.

Same is true when the globe is orientated to the north pole/south pole, however, the y at the center is -100/100 and -90/90 on the circumference and the x would be - 100/100 quarter way around the globe and -90/90 around the circumference.

Is a way to get the value of where I am clicking that is just on the object and not the entire screen? I can't wrap my head how to correlate the direction to the origin. I feel like I am getting somewhere, but then just leave confused. Here is everything I got. Any help would be hugely appreciated.

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>latAndLong</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body {
                color: #808080;
                font-family:Monospace;
                font-size:13px;
                text-align:center;

                background-color: #ffffff;
                margin: 0px;
                overflow: hidden;
            }

            #info {
                position: absolute;
                top: 0px; width: 100%;
                padding: 5px;
            }

            a {

                color: #0080ff;
            }

        </style>
    </head>
    <body>

        <div id="container"></div>
        <div id="info"><a href="http://threejs.org" target="_blank">three.js</a> - earth demo</div>

        <script src="javascript/mrdoob-three.js-ad419d4/build/three.min.js"></script>

        <script src="javascript/TrackballControls.js"></script>

        <script>

            var container, stats;
            var camera, scene, renderer;
            var group;
            var mouseX = 0, mouseY = 0;
            var mesh;
            var windowHalfX = window.innerWidth / 2;
            var windowHalfY = window.innerHeight / 2;
            var earthgeometry;
            var earthmaterial;
            var earthloader;

            var vector;
            var raycaster;
            projector = new THREE.Projector();


            var text, plane;


            init();
            animate();

            function init() {

                container = document.getElementById( 'container' );

                camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 2000 );
                camera.position.z = 500;

                scene = new THREE.Scene();

                group = new THREE.Object3D();
                scene.add( group );

                // earth

                earthloader = new THREE.TextureLoader();
                earthloader.load( 'images/oMap.png', function ( texture ) {

                 earthgeometry = new THREE.SphereGeometry( 200, 50, 50 );

                 earthmaterial = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );
                 mesh = new THREE.Mesh( earthgeometry, earthmaterial );
                    group.add( mesh );

                } );

                //init renderer
                renderer = new THREE.CanvasRenderer();
                renderer.setSize( window.innerWidth, window.innerHeight );

                container.appendChild( renderer.domElement );


                window.addEventListener( 'resize', onWindowResize, false );


                // trackball mouse controls
                // Control Camera with Mouse

                controls = new THREE.TrackballControls( camera, container );

                controls.rotateSpeed = 1.0;

                controls.zoomSpeed = 1.2;

                controls.panSpeed = 0.8;

                controls.noZoom = true;

                controls.noPan = true;

                controls.staticMoving = true;

                controls.dynamicDampingFactor = 0.3;

                controls.keys = [ 65, 83, 68 ];

                controls.addEventListener( 'change', render );
            }

            function onWindowResize() {

                windowHalfX = window.innerWidth / 2;
                windowHalfY = window.innerHeight / 2;

                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();

                renderer.setSize( window.innerWidth, window.innerHeight );

            }

            function animate() {

                requestAnimationFrame( animate );

                // Update the Camera Controls
                controls.update();


                render();
            }

            function render() {



                /*camera.position.x += ( mouseX -camera.position.x) * 0.05;
                camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
                camera.lookAt( scene.position );*/



                renderer.render( scene, camera );

            }

            container.onmouseup = function(event) {
                vector = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5);
                projector.unprojectVector( vector, camera );
                raycaster = new THREE.Raycaster(camera.position, vector.sub( camera.position ).normalize());
                    //  var intersects = raycaster.intersectObjects(earthgeometry, true);
                    //  not working
                    //  console.log(intersects[0].position.x + ' intersect x');
                    //  not working
                    //  console.log(intersects[0].postion.y + ' intersect y');

                //  console.log(vector.x + 'vector x');
                //  console.log(raycaster.ray.origin.x + ' origin x');
                //  console.log(vector.y + 'vector y');
                //  console.log(raycaster.ray.origin.y + ' origin y');
                //  console.log(vector.z + 'vector z');
                //  console.log(raycaster.ray.origin.z + ' origin z');
                //  console.log(vector);
                //  console.log(raycaster);
                //  console.log(earthgeometry);
                //  console.log(earthmaterial);
                //  console.log(earthloader);
                //  console.log(raycaster.ray.origin.z + 'ray origin z');
                //  console.log(group);
                //  console.log(scene);


                //Gets latitude and longitude for the center of globe facing you


                var long;
                if(raycaster.ray.origin.x <= 0 && raycaster.ray.origin.z >=0 ) {
                    long = raycaster.ray.origin.x * -.18;
                    console.log('West');
                    console.log(long);
                    console.log(raycaster.ray.direction.x * 100 + 'ray x');
                } else if (raycaster.ray.origin.x <= 0 && raycaster.ray.origin.z <=0 ) {
                    long = (raycaster.ray.origin.x + 500) * .18 + 90;
                    console.log('West');
                    console.log(long);
                    console.log(raycaster.ray.direction.x * 100 + 'ray x');
                } else if (raycaster.ray.origin.x >= 0 && raycaster.ray.origin.z >=0 ) {
                    long = raycaster.ray.origin.x * .18;
                    console.log('East');
                    console.log(long);
                    console.log(raycaster.ray.direction.x * 100 + 'ray x');
                } else {
                    long = (raycaster.ray.origin.x - 500) * -.18 + 90;
                    console.log('East');
                    console.log(long);
                    console.log(raycaster.ray.direction.x * 100 + 'ray x');
                }

                    var lat;
                if (raycaster.ray.origin.y >= 0) {
                lat = raycaster.ray.origin.y * .18;
                console.log('North');
                console.log(lat);
                console.log(raycaster.ray.direction.y * 100 + 'ray y');
                console.log(raycaster.ray.direction.z * 100 + 'ray z');
                } else {
                lat = raycaster.ray.origin.y * -.18;
                console.log('South');
                console.log(lat);
                console.log(raycaster.ray.direction.y * 100 + 'ray y');
                console.log(raycaster.ray.direction.z * 100 + 'ray z');
                }
            }



        </script>

    </body>
</html>
0

There are 0 answers