簡體   English   中英

如何在3D Globe,Three.js上放置帶有Lat / Lon的標記?

[英]How To Place Marker with Lat/Lon On 3D Globe, Three.js?

在這里,我在Three.js中有一個基本的3D Globe。 我使用Navigator獲取用戶的位置,並在用戶當前位置的地球上使用標記輸入位置。 我不能為我的生活得到這個以顯示正確的位置。 3D Globe也會旋轉。 我將如何獲得正確的位置並使標記與Globe一起旋轉?

示例: http//corexsystems.net/Projects/ThreeJs/EarthAndMoon/

碼:

    var renderer    = new THREE.WebGLRenderer({
        antialias   : true
    });
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );
    renderer.shadowMapEnabled   = true

    var onRenderFcts= [];
    var scene   = new THREE.Scene();
    var camera  = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 100 );
    camera.position.z = 1;

    var light   = new THREE.AmbientLight( 0x222222 )
    scene.add( light )

    var light   = new THREE.DirectionalLight( 0xffffff, 1 )
    light.position.set(5,5,5)
    scene.add( light )
    light.castShadow    = true
    light.shadowCameraNear  = 0.01
    light.shadowCameraFar   = 15
    light.shadowCameraFov   = 45

    light.shadowCameraLeft  = -1
    light.shadowCameraRight =  1
    light.shadowCameraTop   =  1
    light.shadowCameraBottom= -1
    // light.shadowCameraVisible    = true

    light.shadowBias    = 0.001
    light.shadowDarkness    = 0.2

    light.shadowMapWidth    = 1024
    light.shadowMapHeight   = 1024

    //////////////////////////////////////////////////////////////////////////////////
    //      added starfield                         //
    //////////////////////////////////////////////////////////////////////////////////

    var starSphere  = THREEx.Planets.createStarfield()
    scene.add(starSphere)

    //////////////////////////////////////////////////////////////////////////////////
    //      add an object and make it move                  //
    //////////////////////////////////////////////////////////////////////////////////

    // var datGUI   = new dat.GUI()

    var containerEarth  = new THREE.Object3D()
    containerEarth.rotateZ(-23.4 * Math.PI/180)
    containerEarth.position.z   = 0
    scene.add(containerEarth)
    var moonMesh    = THREEx.Planets.createMoon()
    moonMesh.position.set(0.5,0.5,0.5)
    moonMesh.scale.multiplyScalar(1/5)
    moonMesh.receiveShadow  = true
    moonMesh.castShadow = true
    containerEarth.add(moonMesh)

    var earthMesh   = THREEx.Planets.createEarth()
    earthMesh.receiveShadow = true
    earthMesh.castShadow    = true
    containerEarth.add(earthMesh)
    onRenderFcts.push(function(delta, now){
        earthMesh.rotation.y += 1/32 * delta;       
    })

    var geometry    = new THREE.SphereGeometry(50, 32, 32)
    var material    = THREEx.createAtmosphereMaterial()
    material.uniforms.glowColor.value.set(0x00b3ff)
    material.uniforms.coeficient.value  = 0.8
    material.uniforms.power.value       = 2.0
    var mesh    = new THREE.Mesh(geometry, material );
    mesh.scale.multiplyScalar(1.01);
    containerEarth.add( mesh );
    // new THREEx.addAtmosphereMaterial2DatGui(material, datGUI)

    var geometry    = new THREE.SphereGeometry(0.5, 32, 32)
    var material    = THREEx.createAtmosphereMaterial()
    material.side   = THREE.BackSide
    material.uniforms.glowColor.value.set(0x00b3ff)
    material.uniforms.coeficient.value  = 0.5
    material.uniforms.power.value       = 4.0
    var mesh    = new THREE.Mesh(geometry, material );
    mesh.scale.multiplyScalar(1.15);
    containerEarth.add( mesh );
    // new THREEx.addAtmosphereMaterial2DatGui(material, datGUI)

    var earthCloud  = THREEx.Planets.createEarthCloud()
    earthCloud.receiveShadow    = true
    earthCloud.castShadow   = true
    containerEarth.add(earthCloud)
    onRenderFcts.push(function(delta, now){
        earthCloud.rotation.y += 1/8 * delta;       
    })

    //////////////////////////////////////////////////////////////////////////////////
    //      Camera Controls                         //
    //////////////////////////////////////////////////////////////////////////////////
    var mouse   = {x : 0, y : 0}
    document.addEventListener('mousemove', function(event){
        mouse.x = (event.clientX / window.innerWidth ) - 0.5
        mouse.y = (event.clientY / window.innerHeight) - 0.5
    }, false)
    onRenderFcts.push(function(delta, now){
        camera.position.x += (mouse.x*5 - camera.position.x) * (delta*3)
        camera.position.y += (mouse.y*5 - camera.position.y) * (delta*3)
        camera.lookAt( scene.position )
    })





       var marker2 = new THREE.Object3D();
                var loader = new THREE.OBJLoader( );
                loader.load( 'Pin.obj', function ( object2 ) {                 
                    object2.traverse( function ( child ) {
                        if ( child instanceof THREE.Mesh ) {
                            child.material = new THREE.MeshPhongMaterial( { 
                                color: 0x790811, 
                                specular: 0x050505,
                                shininess: 100
                            } );
                        }
                    } );

                    object2.position.set(0.57,-0.15 ,-0.07); // rotating obj should set (X > 0, 0, 0)
                        object2.receiveShadow   = true
    object2.castShadow  = true
    object2.quaternion.setFromUnitVectors(
                    new THREE.Vector3(8, 1, 3.5), new THREE.Vector3(1, 0, 0));
                    object2.scale.set(0.0003,0.0003,0.0003);


                containerEarth.add( object2 );

                });



    scene.add(marker2);


    var rad = Math.PI / 180;

    marker2.quaternion.setFromEuler(
        new THREE.Euler(0, 105 * rad, 45 * rad, "YZX")); 

  navigator.geolocation.watchPosition(function (pos) {


     var lat2 = 42.3125, lon2 = -86.1131;
        marker2.quaternion.setFromEuler(
            new THREE.Euler(45, lon2 * rad, lat2 * rad, "YZX")); 
        });

    //////////////////////////////////////////////////////////////////////////////////
    //      render the scene                        //
    //////////////////////////////////////////////////////////////////////////////////
    onRenderFcts.push(function(){
        renderer.render( scene, camera );       
    })

    //////////////////////////////////////////////////////////////////////////////////
    //      loop runner                         //
    //////////////////////////////////////////////////////////////////////////////////
    var lastTimeMsec= null
    requestAnimationFrame(function animate(nowMsec){
        // keep looping
        requestAnimationFrame( animate );
        // measure time
        lastTimeMsec    = lastTimeMsec || nowMsec-1000/60
        var deltaMsec   = Math.min(200, nowMsec - lastTimeMsec)
        lastTimeMsec    = nowMsec
        // call each update function
        onRenderFcts.forEach(function(onRenderFct){
            onRenderFct(deltaMsec/1000, nowMsec/1000)
        })
    })

您需要從球坐標轉換為笛卡爾坐標

如果您沒有修改球體的紋理偏移量,則以下代碼應該可以解決這個問題:

/**
 * Position an object on a planet.
 * @param {THREE.Object3D} object - the object to place
 * @param {number} lat - latitude of the location
 * @param {number} lon - longitude of the location
 * @param {number} radius - radius of the planet
 */
function placeObjectOnPlanet(object, lat, lon, radius) {
    var latRad = lat * (Math.PI / 180);
    var lonRad = -lon * (Math.PI / 180);
    object.position.set(
        Math.cos(latRad) * Math.cos(lonRad) * radius,
        Math.sin(latRad) * radius,
        Math.cos(latRad) * Math.sin(lonRad) * radius
    );
    object.rotation.set(0.0, -lonRad, latRad - Math.PI * 0.5);
}

請注意,您可以使用THREE.Spherical執行相同的THREE.Spherical

檢查這個小提琴

如果你想讓你的針腳在行星旋轉時旋轉,你需要add它們add為行星的孩子。 或者add行星和引腳add到相同的THREE.Object3D

var object = THREE.Object3D();
object.add(planet);
object.add(pins);
object.rotation.y = 1.0;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM