Toggle visibility on/off on different .glb files loaded with gltf loader

hi there, been trying to get this to work for a while now, having looked everywhere online and having tried all sorts of methods. i’m quite new at this and would really really appreciate the help.

I’m trying to toggle visibility on and off with Hide/Show buttons for different .glb files loaded via gltfloader. i’ve loaded the .glb files with separate loaders and have an addEventListener going for both that triggers the visibility on click. what is super strange to me is that I can get this to work for one .glb file (so if i comment out the first loader, it works for the second!), but when both loaders are there the buttons don’t work.

I’ve also tried to do this via gui , but can’t figure how to add different .glb files (2 or more)…

any suggestions and help are welcome and thanks so much in advance!

Here is the code:

// add in object 1

    var loader1 = new THREE.GLTFLoader();

    loader1.load('../models/text2.glb', handle_load);       
    var mesh1;

   function handle_load(gltf) {           

    console.log(gltf);

    mesh1 = gltf.scene;

    console.log(mesh1);
             
    scene.add(mesh1);

    mesh1.position.z = 0;

        
    // visibility

      mesh1.visible = true;              

      document.getElementById("hideShow").addEventListener("click", function(){

      mesh1.visible = !mesh1.visible;
 
   });

};

    // add in object 2

   var loader = new THREE.GLTFLoader();

   loader.load('../models/objects.glb', handle_load);

   var mesh2;

   function handle_load(gltf) {

      console.log(gltf);

      mesh2 = gltf.scene;

      console.log(mesh2.children[0]);

      scene.add(mesh2);

      mesh2.position.z = 0; 

      //visibility 
      
     mesh2.visible = true;

      document.getElementById("hideShowModels").addEventListener("click", function(){

      mesh2.visible = !mesh2.visible;
  
         });

  }

@pixelpixel

You could do what you need with a boolean

var on = false;

document.getElementById("hideShow").addEventListener("click", function(){
on = !on;
      If (on === true) {
      mesh1.visible = true;
} 
      If (on === false) {
      mesh1.visible =false;
}  
   });

although this will not remove the object from the scene and dispose of the models geometry and material/texture… meaning it will still be stored in the device vram, not so good if you have many models and materials, you would need to remove from scene and dispose each object…

1 Like

@Lawrence3DPK thank you so much for getting back!

I’ve added your solution to both of the handle_load functions that i’ve set up for the 2 loaders - your solution works…however, I’m getting the same issue as before,it only works with either one of the loaders and buttons…so if I comment out either one of the functions, it works for the other… but not when both are there…makes me think it’s an issue with how the loading of models works?

any thoughts? would be greatly appreciated!

@pixelpixel

not sure how you’ve got it set up, would be good to see some code or a live example…

i made this pen for you to get an idea, i’ve used 2 basic cubes for the principle but should demonstrate the same thing…

let me know if this solves your problem, if not share a live example or some code to debug…

2 Likes

May be shortened:

document.getElementById("hideShow").addEventListener("click", function(){
  mesh1.visible = !mesh1.visible;
}
3 Likes

ohh it might be simpler than what i was thinking… try moving your

document.getElementById("hideShowModels").addEventListener("click", function(){

  mesh2.visible = !mesh2.visible;

     });

to outside of your handle_load function…

like this…

var loader1 = new THREE.GLTFLoader();

loader1.load('../models/text2.glb', handle_load);       
var mesh1;

function handle_load(gltf) {
console.log(gltf);
mesh1 = gltf.scene;
console.log(mesh1);             
scene.add(mesh1);
mesh1.position.z = 0;
    
// visibility

mesh1.visible = true;
};

document.getElementById("hideShow").addEventListener("click", function(){
mesh1.visible = !mesh1.visible; 
});

// add in object 2
var loader = new THREE.GLTFLoader();

loader.load('../models/objects.glb', handle_load);
var mesh2;
function handle_load(gltf) {
console.log(gltf);
mesh2 = gltf.scene;
console.log(mesh2.children[0]);
scene.add(mesh2);
mesh2.position.z = 0; 

  //visibility       
  mesh2.visible = true;
}

  document.getElementById("hideShowModels").addEventListener("click", function(){
  mesh2.visible = !mesh2.visible;  
  });

@Lawrence3DPK thank you! i tried this before… getting this error: Uncaught TypeError: Cannot set property ‘visible’ of undefined , so at this line: mesh2.visible = true; and this line mesh1.visible = !mesh1.visible;

here’s a code pen : https://codepen.io/pixelpixel/pen/JjRVvBo

@pixelpixel

your pen doesn’t run because it has no three.module.js, loaders or actual models imported into it…
nevertheless i’ve changed your code so it should work here…

let me know if that works…

@Lawrence3DPK hello, thank you so much for giving this so much of your time ! sorry, had issues with loading the gltf loader and loading the models in codepen…I followed ur solution in my code locally and I am still getting an error with visible of undefined …

BUT after some more griding at it, I found a solution, via getting objects by name. Posting here so it helps anyone who might be running into this issue:

// add in object 1

    const loader1 = new THREE.GLTFLoader()
    
    **var mesh1 = new THREE.Object3D();**

    loader1.load('../models/objects1.glb', function(gltf){                 

    mesh1 = gltf.scene;

    **mesh1.name = "mesh1";**

    scene.add(mesh1);

    mesh1.position.z = 0;

    });

    **mesh1 = scene.getObjectByName(mesh1.name);**

    mesh1.visible = true;           

    // visibility
  
    document.getElementById("hideShowModels").addEventListener("click", function(){

    mesh1.visible = !mesh1.visible;       

});

    // add in object 2

    const loader = new THREE.GLTFLoader();

    **var mesh2 = new THREE.Object3D();**

   loader.load('../models/text1.glb', function(gltf){

      mesh2 = gltf.scene;

      console.log(mesh2);

      scene.add(mesh2);

      mesh2.position.z = 0; 

   });

       **mesh2 = scene.getObjectByName(mesh2.name);**

       mesh2.visible = true;

      //visibility                      

    document.getElementById("hideShowText").addEventListener("click", function(){

    mesh2.visible = !mesh2.visible;   

});
2 Likes