Objects loaded with ThreeJS GLTF may unexpectedly vanish upon completion

There’s a function in my code that loads a gltf object and adds the mesh to the scene. Inside the gltf load call, I can traverse or getobjectbyname without any issues. However, once outside of the gltf load call, the objects seem to disappear completely. Everything else I've added to the scene, like lights, remains visible - only the objects loaded by the gltf load method vanish.

I tried making variables global within the function, thinking it might solve the scope issue, but no luck so far. I’ve inserted comments throughout the code to indicate where it works and where it doesn’t. Any insight into this problem would be highly appreciated. Thank you.

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();
        }
    }
}

Answer №1

The function you provide to the loader.load function will only execute once the model is fully loaded. It doesn't halt the execution of the code below it, so..
At the point where you mentioned "My gltf objects are undefined here," it actually runs before the model finishes loading. To resolve this, consider moving that code snippet into the callback function for expected results.

UPDATE.. Check out this informative video by ColorCode about working with Async functions in JS

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to retrieve content from a different website using javascript in an asp.net environment?

Currently working on a web application in asp.net where I want to provide users with a JavaScript code that allows them to fetch content from my website and display it on their own website. To handle user requests on my website, I have implemented a gener ...

Distorted UV mappings following Draco compression

After exporting to glTF using Blender's built-in Draco compression, I encountered an issue where all extension attributes are misaligned after the first primitive in the asset. For example, the first extension attribute is aligned correctly, but the ...

Guide to transferring parameters from one function to another in Javascript

For my automation project using Protractor and Cucumber, I have encountered a scenario where I need to use the output of Function A in Function B. While I was able to do this without Cucumber by extending the function with "then", I am facing difficulties ...

In React, what is the correct term for "selection boxes" when choosing multiple items in Finder?

I'm in search of a React component that allows me to select multiple elements on the screen by clicking, holding, and forming a square around them. I've tried searching for terms like 'selection box' and 'React select elements,&apo ...

Incorporate a minor detail within the H1 using jQuery

I am attempting to update the text within an h1 tag that includes a small element inside it. However, despite successfully changing the main content when the button is clicked, the styling for the small element is not being applied. Here is the HTML code: ...

haphazardly showcase circular shapes within a confined space

Is there a way to display circles randomly inside a box without them extending beyond the box or touching its corners? Can the circles be plotted using relative values (percent) within the div? For example, can a circle be placed 10% from the left side and ...

"Node.js mystery: Why does a function call return undefined, only to be evaluated

Utilizing the async module, I am running a series of functions in parallel. However, I have encountered an issue where the return value of another function is undefined because the callback does not wait for it to be evaluated. function getGenresId(genres ...

Adjusting the ContentChildren attributes within the QueryList modification

Let's imagine a scenario where a parent component has @ContentChildren(Child) children. Each individual Child, in its component class, includes an index field. I want to ensure that these index fields remain accurate whenever there is a change in the ...

Find the viewport dimensions of the browser using Javascript and display them in the body CSS

Currently utilizing Andy Langton's JavaScript to retrieve my viewport size. If you're unfamiliar with it, check out the link below: The script is functioning as expected, but I'm uncertain of the optimal method for having the script output ...

ReactJS - Element not specified

I'm experiencing a specific issue with the component below related to the changeColor() function, which is triggering an error message: TypeError: Cannot set property 'color' of undefined This error seems to be isolated within this compo ...

Locating if a certain string in an array is even or odd in JavaScript

I am currently on a mission to locate an odd string within a given array. Here's the code: const friendArray = ["agdum", "bagdum", "chagdum", "lagdum", "jagdum", "magdum"]; function findOddString(arr) { for (let i = 0; i < arr.length; i++) { ...

Removing an item from an array depending on a specific condition and index

I am working with an array structure that looks like this: [ {key: 4, data: {…}, qText: {…}}, {key: 4, data: {…}, qText: {…}, isVisible: false}, {key: 5, data: {…}, qText: {…}, isVisible: false}, {key: 4, data: {…}, qText: {…}, isVi ...

The dropdown on my website is malfunctioning

There seems to be an issue with my dropdown button. Previously, it only appeared when clicking on a specific part of the button. I attempted to resolve this problem but unfortunately, the dropdown no longer works at all and I am unable to revert my changes ...

Combining Codeigniter with AJAX for an efficient system

I'm facing an issue with my like system where a user can give more than one like, but only one is being registered in the database. I suspect it's related to AJAX. Here is the button code: <a class="btn btn-xs btn-white" name="btn" onclick=" ...

Sending a message in the DELETE route using express.js

I'm having trouble displaying a message after deleting a user. I attempted to use req.session properties and then retrieve them in the GET route, but they seem to not be available. Can anyone suggest a solution for fixing this code? router.get("/", ...

What could be the issue with the functionality of my slider link url?

The slider is functional, but the links are not working properly. Each slide should redirect to a different URL For instance: Slide 1 with a link to Bing, Slide 2 with a link to Google, Slide 3 with a link to Yahoo. I am unable to incorporate Javascri ...

Filtering out section boxes does not eliminate empty spaces

Link to Fiddle I've run into a bit of a roadblock while trying to filter my section box for a project I'm currently working on. The issue I'm facing is that instead of collapsing the first section box to display only the filtered options, i ...

How can I display only the y-axis values and hide the default y-axis line in react-chartjs-2?

Although I have some experience with chartjs, I am struggling to figure out how to hide the default line. To clarify, I have attached an image that illustrates the issue. I would like to achieve a result similar to this example: https://i.sstatic.net/UXMpi ...

FilterTextBoxExtender in AJAX enables the input of carriage returns

I need assistance with a multi-line text box that I'm using an AJAX FilteredTextBoxExtender on to restrict user input to just numbers. However, I also want users to be able to add a new line by pressing the enter key. I've looked around for a sol ...

Using Redux to add an object to an array nested within another array

Hey there! I'm facing an issue with creating, updating, or deleting {note} in the [notes] array based on the operationId in the parent array id. I've tried using ADDNOTE but it's not working as expected. The problem is that without these fun ...