Search code examples
svgthree.jsresizegsap

threejs : trying to pass objloader to a var


I'm trying to pass the result of the objLoader command to a var to use it in an animation. So when I put the console.log inside the objLoader function I get the object. But when I put the console.log outside the function I get undefined.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style type="text/css">
        html, body {height: 100%}
        body {margin: 0}
        #cnv {
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <canvas id="cnv">
    </canvas>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js'></script>
    <script src='https://unpkg.com/[email protected]/examples/js/loaders/OBJLoader.js'></script>
    <script type="text/javascript">
            var scene = new THREE.Scene(),
            sun = new THREE.DirectionalLight(0xffffff, 1),
            camera = new THREE.PerspectiveCamera(30, 1, 0.1, 10),
            renderer = new THREE.WebGLRenderer({canvas:cnv}),
            boxGeom = new THREE.BoxGeometry(.5, .5, .5),
            mtrlStdr = new THREE.MeshStandardMaterial(),
            box0 = new THREE.Mesh(boxGeom, mtrlStdr),
            minLoader = new THREE.OBJLoader(),
            minObj,
            canvasResize = function () {
                var canvas = renderer.domElement,
                width = canvas.clientWidth,
                height = canvas.clientHeight;
                if (canvas.width !== width || canvas.height !== height) {
                    renderer.setSize(width, height, false);
                    camera.aspect = width / height;
                    camera.updateProjectionMatrix();
                }
            };
            sun.position.set(-5, 10, 6);
            sun.target.position.set(0, 0, 0);
            scene.add(sun,sun.target,box0,camera);
            minLoader.load('models/min.obj', function (obj) {
                scene.add(obj);
                minObj=obj;
            console.log(minObj);
            });
            camera.position.z = 6;
            renderer.render(scene, camera);
            function animate(time) {
                time *= 0.001;
                box0.rotation.x = time * 0.5;
                box0.rotation.y = time * 1;
                renderer.render(scene, camera);
                requestAnimationFrame(animate);
            }
            requestAnimationFrame(animate);
            window.addEventListener('load', canvasResize, false);
            window.addEventListener('resize', canvasResize, false);
    </script>
</body>
</html>

Could anyone help me?

the obj file is at : https://banner-testing.neocities.org/models/min.obj

Cheers

Michael

so after Mugen's answer I changed the end of my code a bit and now it works. Woooohooo! Thx Mugen.

Here's the code (only the bits I changed)

function loadObjs () {
                minLoader.load(
                    'models/min.obj',
                    function (obj) {
                        scene.add(obj);
                        minObj=obj;
                        requestAnimationFrame(animate);
                    }
                );
            };
            function animate(time) {
                time *= 0.001;
                minObj.rotation.x = time * 0.5;
                minObj.rotation.y = time * 1;
                renderer.render(scene, camera);
                requestAnimationFrame(animate);
            };
            function winit () {
                canvasResize();
                loadObjs ();
            };
            window.addEventListener('load', winit, false);
            window.addEventListener('resize', canvasResize, false);


Solution

  • But when I put the console.log outside the function I get undefined.

    That happens because the OBJ asset is loaded asynchronously. That means if you access minObj before the loading process has been finished, runtime errors will occur since the variable is still undefined.

    One simple solution is to implement a check before accessing minObj:

    if ( minObj !== undefined ) console.log( minObj );
    

    However, it's better if you start your animation in the onLoad() callback so you have the guarantee that minObj has a valid value.