2017-09-02 15 views
3

Ici, j'ai un globe 3D de base dans Three.js. Je reçois l'emplacement de l'utilisateur en utilisant le navigateur et saisis l'emplacement avec un marqueur sur le globe de la position actuelle de l'utilisateur. Je ne peux pas pour la vie de moi obtenir ceci pour montrer la position correcte. Le globe 3D tourne également. Comment pourrais-je obtenir la bonne position et faire en sorte que le marqueur tourne simplement avec le Globe?Comment placer un marqueur avec Lat/Lon sur 3D Globe, Three.js?

Exemple: http://corexsystems.net/Projects/ThreeJs/EarthAndMoon/

code:

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) 
     }) 
    }) 
+0

GIST de travail est ici: https://gist.github.com/bellbind/47f36f39f632d9ab77a3 Télécharger le fichier zip et l'exécuter sur un serveur de test le voir fonctionner. – Radio

+0

Voici l'exemple sur lequel je travaille. Je ne sais pas pourquoi il ne fonctionne pas le marqueur est proche juste pas la position :( –

+0

Le code de votre travail de selon le script que vous avez laissé ici est à http://corexsystems.net/Projects/ThreeJs/EarthAndMoon – Radio

Répondre

3

Vous devez convertir coordonnées sphériques à de coordonnées cartésiennes.

Si vous n'avez pas modifié la texture décalage de votre sphère, le code suivant devrait faire l'affaire:

/** 
* 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); 
} 

Notez que vous pouvez faire la même chose avec THREE.Spherical.

Vérifiez this fiddle.

Si vous voulez que vos broches tournent lorsque la planète tourne, vous devez les considérer comme des enfants de la planète. Ou add la planète et les broches à la même THREE.Object3D:

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

Absolument génial, tu nous as 100% correct je plaçais l'objet dans 3D Space non à la sphère elle-même! –

+1

Je pense qu'une certaine confusion dans l'ordre de la valeur lat-lon à l'intérieur de la fonction sur votre violon, voici le violon modifié https://jsfiddle.net/k0Lz9hek/2/ – Haris

+0

Mon mauvais! J'ai échangé «lat» et «lon». Le violon et le code sont mis à jour, merci de le signaler – neeh