three.jswebglgltf3d-model

My threeJS class only apply meshs settings to 1 of 2 models in my scene


I am creating a scene in three js with two models in .glb format; I am following a pre-recorded class and I have followed exactly all the steps. We create a class for the models in model.js and in index.js we define them. Everything was working fine until from model.js we created a material for the models and it only loads in one of them. I have checked everything, searched for similar answers here and I can't find the error because everything seems to be fine.

This is model.js (the class)

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

class Model {
    constructor(obj){
        //console.log(obj)
        this.name = obj.name
        this.file = obj.file
        this.scene = obj.scene

        this.loader = new GLTFLoader()
        this.dracoLoader = new DRACOLoader()
        this.dracoLoader.setDecoderPath('./draco/')
        this.loader.setDRACOLoader(this.dracoLoader)

        this.init()
    }

    init (){
        this.loader.load(this.file, (response) => {
           console.log(response)

            this.mesh = response.scene.children[0]
            this.material = new THREE.MeshBasicMaterial({
                color: 'blue',
                wireframe: true
            })
            this.mesh.material = this.material
            this.scene.add(this.mesh)
        })
    }
}

export default Model

And this is my index.js (the scene)

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import Model from './model';

/*------------------------------
Renderer
------------------------------*/
const renderer = new THREE.WebGLRenderer({
  antialias: true,
  alpha: true
});
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );


/*------------------------------
Scene & Camera
------------------------------*/
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 
  50, 
  window.innerWidth / window.innerHeight,
  0.1,
  100
);
camera.position.z = 5;
camera.position.y = 1;


/*------------------------------
Mesh
------------------------------*/
const geometry = new THREE.BoxGeometry(2, 2, 2);
const material = new THREE.MeshBasicMaterial( { 
  color: 0x00ff00,
} );
const cube = new THREE.Mesh( geometry, material );
//scene.add( cube );


/*------------------------------
OrbitControls
------------------------------*/
const controls = new OrbitControls( camera, renderer.domElement );


/*------------------------------
Helpers
------------------------------*/
const gridHelper = new THREE.GridHelper( 10, 10 );
scene.add( gridHelper );
const axesHelper = new THREE.AxesHelper( 5 );
scene.add( axesHelper );


/*------------------------------
Models
------------------------------*/
const laptop = new Model({
  name: 'laptop',
  file: './models/laptop.glb',
  scene: scene
})

const humano = new Model({
  name: 'humano',
  file: './models/humano.glb',
  scene: scene
})


/*------------------------------
Loop
------------------------------*/
const animate = function () {
  requestAnimationFrame( animate );
  renderer.render( scene, camera );
};
animate();


/*------------------------------
Resize
------------------------------*/
function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize( window.innerWidth, window.innerHeight );
}
window.addEventListener( 'resize', onWindowResize, false );

And this is how it look like: The material applies to the first model, but not to the second.

I tried to have it searched throughout the index without success.

I suspect this is the error, but the truth is that I am very novice and I have no clue how or why my children element comes out empty. This is my teachers console This is my teacher's console (children element attention) And this is mine....My console, my children array is empty


Solution

  • I'm also a Three.js novice, but it looks like DracoLoader loads a geometry not a mesh so the way you're crafting your model might be causing the issue. Does instantiating a new THREE.Mesh with the downloaded geometry and material fix the issue:

        init (){
            this.loader.load(this.file, (response) => {
               console.log(response)
    
                this.geometry = response.scene.children[0];
                this.material = new THREE.MeshBasicMaterial({
                    color: 'blue',
                    wireframe: true
                })
                this.mesh = new THREE.Mesh( this.geometry, this.material );
                this.scene.add(this.mesh)
            })
        }