Q:

Update Position of ThreeJS model inside Animate (How to access model's position outside of callback)

I am attempting to create a model of the ISS orbiting the earth. I am using threeJS to accomplish this. So far I have everything working perfectly other than I am having trouble with updating the position of the imported ISS model. I have a sphere that orbits the earth getting its position from an AJAX call every 5 seconds that is then converted to coordinates on my earth sphere model. I essentially want to replace the sphere (posSphere in code) that orbits, with the model of the ISS. Having trouble as the model is loaded asynchronously. What I have currently tried is including parameter in the animate function for the model, and on callback send it to the animate function, but this causes the entire scene to freeze.
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - OBJLoader + MTLLoader</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 {
                font-family: Monospace;
                background-color: #000;
                color: #fff;
                margin: 0px;
                overflow: hidden;
            }
        </style>
    </head>

    <body>

        <script src="Resources/three.js"></script>
        <script src="Resources/TDSLoader.js"></script>
        <script src="Resources/FBXLoader.js"></script>
        <script src="Resources/GLTFLoader.js"></script>
        <script src="Resources/inflate.min.js"></script>
        <script src="Resources/TrackballControls.js"></script>
<script>
var lat, long, issPosition;
//*********************PRELIM FUNCTIONS BEGIN**********************************
//AJAX request for current position of the ISS
function GetValue() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
    var requestResponse = xhr.responseText;
    var issInfo = JSON.parse(requestResponse);
    var Lat = issInfo.iss_position.latitude;
    var Long = issInfo.iss_position.longitude;
    callback(Lat, Long); //callback function with lat and long info
                }
            };
            xhr.open("GET", "http://api.open-notify.org/iss-now.json", true);
            xhr.send();
        }

    function callback(Lat, Long) {
        lat = Lat; //set global variables equal to lat and long so animate function has access
        long = Long;
    }

    GetValue(); //function call to get iss location
    setInterval(GetValue, 5000); //interval for iss location, updates every 5 seconds

//convert long & lat to 3D coordinate
function latLongToVector3(lat, lon, radius, heigth) {
    var phi = (lat)*Math.PI/180;
    var theta = (lon-180)*Math.PI/180;

    var x = -(radius+heigth) * Math.cos(phi) * Math.cos(theta);
    var y = (radius+heigth) * Math.sin(phi);
    var z = (radius+heigth) * Math.cos(phi) * Math.sin(theta);

        return new THREE.Vector3(x,y,z);
    }     
//******************PRELIM FUNCTIONS END********************************************

//******************THREE JS ENVIRONMENT BEGIN**************************************   
var width = window.innerWidth;
var height = window.innerHeight;

var scene = new THREE.Scene();

var camera = new THREE.PerspectiveCamera(75, width/height, 0.01, 1000);
camera.position.z = 400;

var controls = new THREE.TrackballControls( camera );

                controls.rotateSpeed = 1.0;
                controls.zoomSpeed = 1.2;
                controls.panSpeed = 0.8;

                controls.noZoom = false;
                controls.noPan = false;

                controls.staticMoving = true;
                controls.dynamicDampingFactor = 0.3;

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

var renderer = new THREE.WebGLRenderer();
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);

var direcLight = new THREE.DirectionalLight(0xffffff, 0.3);
direcLight.position.set(-3,3,1.5);
direcLight.castShadow = true;
scene.add(direcLight);

var ambientLight = new THREE.AmbientLight(0xc9c9c9, 1.5);
scene.add(ambientLight);

var geometry1 = new THREE.SphereGeometry(200,32,32);
var geometry2 = new THREE.SphereGeometry(202.5,32,32);
var geometry3 = new THREE.SphereGeometry(3, 32, 32);
var material1 = new THREE.MeshBasicMaterial ({
    color: 0xff0000
});
var material2 = new THREE.MeshPhongMaterial({
    map: new THREE.TextureLoader().load('Resources/Earth3/earthmapoftwo.jpg'),
    bumpMap: new THREE.TextureLoader().load('Resources/Earth3/Bump2.jpg'),
    bumpScale: 1,
    specularMap: new THREE.TextureLoader().load('Resources/Earth3/oceanmaskbytwo.png'),
    specular: new THREE.Color('grey'),
    shininess: 40
});
var material3 = new THREE.MeshPhongMaterial({
    alphaMap: new THREE.TextureLoader().load('Resources/Earth3/Clouds.png'),
    transparent: true,
});

var issModel;
var loaderGLTF = new THREE.GLTFLoader();  
loaderGLTF.load(
    "Resources/Earth3/iss.gltf",
    function(gltf) { //I want to be able to access this gltf outside of this callback function 
        gltf.scene.scale.x = 0.1;
        gltf.scene.scale.y = 0.1;
        gltf.scene.scale.z = 0.1;
        console.log(gltf.scene.position);
        scene.add(gltf.scene);
        animate(gltf); //send gltf to animate function, this does not work
    }
)

var sphere = new THREE.Mesh(geometry1, material2); 
var clouds = new THREE.Mesh(geometry2, material3);
var posSphere = new THREE.Mesh(geometry3, material1);

sphere.receiveShadow = true;
clouds.receiveShadow = true;
posSphere.receiveShadow = true;
scene.add(sphere);
scene.add(clouds);
scene.add(posSphere);

function animate(gltf) {
    clouds.rotation.x += 0.0001;
    clouds.rotation.y += 0.0001;
    clouds.rotation.z += 0.0001; 

    issPosition = latLongToVector3(lat, long, 200, 10);
    posSphere.position.x = issPosition.x; //sphere's location is updated with the issPosition & works 
    posSphere.position.y = issPosition.y;
    posSphere.position.z = issPosition.z;

    gltf.scene.position.x = issPosition.x; //Part I am struggling with here, how to access the gltf's position from within this function. Essentially I want to replace the sphere with the gltf
    gltf.scene.position.y = issPosition.y;
    gltf.scene.position.z = issPosition.z;

    controls.update();
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
            }          
animate();
//**************************THREE JS ENVIRONMENT END*************************************  
</script>

</body>
</html>

A:

You're defining a parameter to the animate function but then immediately calling it with no parameter.. (down at the last line of your code). that's why your app is "freezing". (its not freezing.. it's probably throwing an exception.. You can see that in the debugger console.. Ctrl+Shift+J in chrome or More Tools->Developer Tools from the ... menu in the upper right.. Exceptions should show up in red at the bottom.)
Take out the line of code where you do 'animate(gltf)' and instead do "issModel = gltf.scene;"
Then in your animate function instead of doing "gltf.scene.position.x = " etc.
Just do "issModel.position.copy(issPosition);"
If you're still stuck, try hosting it online somewhere and we can take a deeper look.

