Javascript class contacs

Hello,

I have a strange issue with javascript (I don’t think it’s a threeJS thing or not) where i have a class I use to organize my code, here’s the code:

import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';

export class SceneManager {

    scene;
    loaded;

    constructor(scene, loaded) {
        this.scene = scene;
        this.loaded = loaded;
    }

    initScene() {
        const loaderManager = new THREE.LoadingManager(
            () => {
                //loaded
                console.log("scene loaded");
            },
            (itemUrl, itemsLoaded, itemsTotal) => {
                // progress
                console.log(`loading: ${itemsLoaded}/${itemsTotal}`);
            },
            (url) => {
                //error
                console.log('There was an error loading ' + url);
            }
        );

        const gltfLoader = new GLTFLoader(loaderManager);
        const dracoLoader = new DRACOLoader(loaderManager);
        dracoLoader.setDecoderPath('/draco/');
        gltfLoader.setDRACOLoader(dracoLoader);
        const textureLoader = new THREE.TextureLoader(loaderManager);

        const tableTexture = textureLoader.load('./textures/table_texture.webp');
        const shelfTexture = textureLoader.load('./textures/shelf_texture.webp');

        loadGLB('table', tableTexture);
        loadGLB('shelf', shelfTexture);
        //... the function is called many times
        //... but the error occurred regadless of number of calls

        function loadGLB(name, tex) {
            gltfLoader.load(`./meshes/${name}.glb`, (gltf) => {
                gltf.scene.traverse((obj) => {
                    if (obj instanceof THREE.Mesh) {
                        obj.material = new THREE.MeshBasicMaterial({ map: tex });
                        this.scene.add(obj); // <--- the error point to here
                    }
                });
            });
        }
    }
}

An error pops up saying

Cannot read properties of undefined (reading 'scene')

I don’t know what’s the propblem coming from, if I took the glb loader outside of the function it works, can anyone help me here? Thanks.

Just a blind guess. Try with that:

3 Likes

@PavelBoytchev
that’s … worked

i have ZERO idea what you’ve done! I need to look it up! thanks

1 Like

…also you can do (obj.isMesh) instead of (obj instanceof THREE.Mesh).

1 Like

Hello, thanks for the tip, but does it relate to the issue or just a tip? thanks again
is it for optemization?

The issue is function loadGLB(name, tex) {
In the body of that function this will reference the function instead of the class that contains it.
Simplest fix would be to do const loadGLB = (name, tex) =>{...}

Understanding how this works in JS is very important or you’ll end up with this kind of error regularly.

3 Likes

ooo thanks for the explanation, that do make sense!

it may be more performant, and also applies to other meshlike things like SkinnedMesh… and is just sorta idiomatic for threejs rather than relying on strict class equality.

1 Like

thanks for the tip, I looked it up and it is better as simple as instead of comparing and as you said, just check the bool inside the file that came with.

1 Like