mw42
mw42

Reputation: 37

ThreeJS GLTF Objects Disappear After Load

So, I've got a function that loads my gltf object. I add the gltf mesh to the scene, and I can traverse or getobjectbyname with no problem if I'm inside the gltf load call. Once outside of the gltf load call, the objects are gone. Vanished. Anything else I've added to the scene is still there - like lights - those remain, but the objects loaded by the gltf load are gone.

I inserted comments where it works, and where it doesn't. Can't tell if this is a scope issue or not? Made variables global to the function - thought that would do it. No luck.

Any insight provided is GREATLY appreciated. Thanks.

import './style.css'
import * as THREE from 'three'
import { GLTFLoader } from './GLTFLoader.js';
import { OrbitControls } from './OrbitControls.js';
const MODEL_PATH = './GLTF_Filename.gltf';

export function SceneOrganizer(canvas)
{
    let renderer, camera, scene, controls, loader;

    LoadStyle();
    animate();

    function LoadStyle()
    {
        canvas.style.height = "100%";
        canvas.style.border="thin solid #0000FF";
      
        renderer = new THREE.WebGLRenderer( {antialias:true});
        renderer.shadowMap.enabled = true;
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(canvas.clientWidth, canvas.clientHeight);

        var cameraFar = 75;
        camera = new THREE.PerspectiveCamera(50, canvas.innerWidth / canvas.innerHeight, 0.1, 1000);
        camera.position.z = cameraFar;
        camera.position.x = 0;
      
        controls = new OrbitControls(camera, renderer.domElement);
        controls.damping = 0.2;

        canvas.appendChild(renderer.domElement);

        scene = new THREE.Scene()
        scene.background = "#f1f1f1";

        var hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.61);
        hemiLight.position.set(0, 50, 0);
        scene.add(hemiLight);

        var dirLight = new THREE.DirectionalLight(0xffffff, 0.54);
        dirLight.position.set(-8, 12, 8);
        dirLight.castShadow = true;
        dirLight.shadow.mapSize = new THREE.Vector2(1024, 1024);
        scene.add(dirLight);
      
        loader = new GLTFLoader();
        
        let mesh;

        loader.load(MODEL_PATH, 
            function (gltf) 
            {
                mesh = gltf.scene.children[0];
                scene.add(mesh);
                
                // Set the models initial scale / position / rotation  
                mesh.rotation.y = Math.PI/-4;
                mesh.scale.set(4,4,4);
                mesh.position.x = -10;
            
                //When the code gets here, the scene only has all of the objects from the gltf mesh.
                //Works fine here.
                if (scene.getObjectByName("object_name") != undefined)
                {
                    scene.getObjectByName("object_name").material = 
                    new THREE.MeshPhysicalMaterial(
                        _colorFrameColors[1].material
                    );
                }
                else
                {
                    document.getElementById("pagefooter").innerText = "Undefined Inside";    
                }

            }, 
            undefined, 
            function (error) 
            {
                document.getElementById("pagefooter").innerText = error;
            }
        );

        //When the code gets here, the scene only has the lights which were added above.
        //My gltf objects are undefined here.
        if (scene.getObjectByName("object_name") != undefined)
        {
            scene.getObjectByName("object_name").material = 
            new THREE.MeshPhysicalMaterial(
                _colorFrameColors[1].material
            );
        }
        else
        {
            document.getElementById("pagefooter").innerText = "Undefined Outside";    
        }
    }

    function resizeRendererToDisplaySize(renderer) 
    {
        const c = renderer.domElement;
        var width = window.innerWidth;
        var height = window.innerHeight;
        var canvasPixelWidth = c.width / window.devicePixelRatio;
        var canvasPixelHeight = c.height / window.devicePixelRatio;

        const needResize = canvasPixelWidth !== width || canvasPixelHeight !== height;
        if (needResize) {

          renderer.setSize(width, height, false);
        }
        return needResize;
    }

    function animate()
    {
        // controls.update();
        renderer.render(scene, camera);
        requestAnimationFrame(animate);

        if (resizeRendererToDisplaySize(renderer)) {
          const c = renderer.domElement;
          camera.aspect = c.clientWidth / c.clientHeight;
          camera.updateProjectionMatrix();
        }
    }
}

Upvotes: 0

Views: 263

Answers (1)

2pha
2pha

Reputation: 10165

The callback function you send to the loader.load function only runs after the model is loaded. It does not stop the code below it from running, soo..
Where you have commented "My gltf objects are undefined here." runs before the model is loaded. You could move it into the callback function and it should work as expected.

EDIT.. Here is a good video by ColorCode on Async functions in JS

Upvotes: 1

Related Questions