Javacadabra
Javacadabra

Reputation: 5758

Can't animate OBJ using Three.JS even though it is loaded in browser

Below is a script I am using to load in a obj file into my web browser using WebGL. I am currently having an issue scaling the object and animating it. I know that all of the animation code should go into the render( ) loop function but when I attempt to use the object variable in the loop I am told it is undefined. Can anyone explain to me why? Seen as I can reference my scene and camera variables from there.

<script>
                //Variables
                var container, stats;
                var camera, scene, renderer;
                var mouseX = 0, mouseY = 0;
                var windowHalfX = window.innerWidth/2;
                var windowHalfY = window.innerHeight/2;
                init();
                animate();

                //Initialisation
                function init(){
                    container = document.createElement('div');
                    document.body.appendChild(container);
                    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
                    camera.position.z = 2;

                    //scene
                    scene = new THREE.Scene();

                    //Light
                    var ambient = new THREE.AmbientLight(0x101030);
                    scene.add(ambient);
                    var directionalLight = new THREE.DirectionalLight(0xffeedd);
                    directionalLight.position.set(1,0,1);
                    scene.add(directionalLight);

                    //Texture
                    var manager = new THREE.LoadingManager();
                    manager.onProgress = function ( item, loaded, total ) {
                        console.log("Loading: " + item, loaded, total );
                    };

                    var texture = new THREE.Texture();
                    var loader = new THREE.ImageLoader(manager);
                    loader.load('skin.jpg', function(image){
                        texture.image = image;
                        texture.needsUpdate = true;
                    });

                    //Model
                    var loader = new THREE.OBJLoader(manager);
                    loader.load('test.obj', function(object){
                        object.traverse(function(child){
                                if(child instanceof THREE.Mesh){
                                    //child.material.map = texture;
                                }
                        }); 

                        //Resize the object...
                        object.position.y = .10;
                        object.position.x += .10;

                        //Scale
                        object.scale.x = 0.5;
                        object.scale.z = 0.5;
                        object.scale.y = 0.5;

                        console.log(object);

                        scene.add(object);
                    });

                    //Renderer
                    renderer = new THREE.WebGLRenderer();
                    renderer.setSize(window.innerWidth, window.innerHeight);
                    renderer.setClearColorHex( 0xffffff, 1 );
                    container.appendChild(renderer.domElement);

                    //Event Listeners
                    //document.addEventListener('mousemove', onDocumentMouseMove, false);
                    window.addEventListener('resize', onWindowResize, false);
                }


                //Declaring Event Listeners
                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 onDocumentMouseMove(event){
                    mouseX = (event.clientX - windowHalfX)/2;
                    mouseY = (event.clientY - windowHalfY)/2;
                }
                //Declaring Event Listeners

                //Animation
                function animate(){
                    requestAnimationFrame(animate);
                    render();
                }

                function render(){
                    camera.position.x += (mouseX - camera.position.x) * .05;
                    camera.position.y += (mouseY - camera.position.y) * .05;
                    camera.lookAt(scene.position);
                    renderer.render(scene, camera);
                }
            </script>

Problem is here: Can't console.log(object) or anything.

function render(){
                        camera.position.x += (mouseX - camera.position.x) * .05;
                        camera.position.y += (mouseY - camera.position.y) * .05;
                        camera.lookAt(scene.position);

                        renderer.render(scene, camera);
                    }

Upvotes: 0

Views: 1761

Answers (1)

Leeft
Leeft

Reputation: 3837

You're probably new to JavaScript and not understanding variable scope there. Your:

loader.load('test.obj', function(object){

Means that object is only known within the scope of the function you've declared there.

One way around it is to make another page-global variable at the start:

<script>
            //Variables
            var loadedObject = null;

then in the function assign to it:

loader.load('test.obj', function(object){
    loadedObject = object;

and you can then use loadedObject in your render() function. Make sure to check it is defined before you try to use it, as it'll take time to load:

function render() {
    if ( loadedObject ) {
         // do something with it
    }

Upvotes: 4

Related Questions