I have a web 3D model viewer that uses Three.JS. I'm trying to implement a way to choose different models from a dropdown list, using dat.GUI. I'm trying to accomplish this with a switch statement, as inspired by some examples on the Three.JS website (materials/reflectivity and envmaps/hdr/nodes).
My loader works fine when I'm just trying to load one model. But when I try to connect it to the GUI and switch statement, the model doesn't appear (console log says 100% loaded, but I don't know if that's true or a fault of my load reporter). The console log also returns this error:
Error: THREE.OBJLoader: Unexpected line: "<!DOCTYPE html>" OBJLoader.js:624:12
Googling of the error returns suggestions that the .obj file is broken. I know my models are fine because I've loaded them successfully by themselves. So I can only assume the problem is my variable that I'm having the loader load. I know OBJLoader can load from variables, because I tried just defining one variable as the model (var model = 'my_model.obj', then having the loader load "model"), which worked. So I've narrowed it down to a problem with the GUI code or switch statement.
Here's my script with some irrelevant parts cut out.
var gui;
var camera, scene, renderer;
var species, params;
//3D models to choose from in dropdown list.
var speciesList = {
'Goldenrod': 'models/solidago_rugosa.obj',
'Mountain Laurel': 'models/kalmia_latifolia.obj',
};
//Model loaded by default
params = {
Species: 'models/solidago_rugosa.obj'
};
init();
animate();
function init() {
//defining the scene, camera, renderer...
//GUI
gui = new dat.GUI({hideable: false});
gui.add(params, 'Species', speciesList)
//controls, window resizer...
};
//Switch to load a different model.
//speciesCurrent is used by loader.
//No method to remove the previously loaded model yet, but I figure it should be able to load models on top of each other for now.
var speciesCurrent;
switch (speciesList) {
case 'models/solidago_rugosa.obj':
speciesCurrent = 'models/solidago_rugosa.obj';
break;
case 'models/kalmia_latifolia.obj':
speciesCurrent = 'models/kalmia_latifolia.obj';
break;
};
//Loader
var loader = new THREE.OBJLoader();
loader.load(
speciesCurrent,
function(object){
var material = new THREE.MeshLambertMaterial({color: 0x99a300});
object.traverse(function (child){
if (child instanceof THREE.Mesh){
child.material=material;
child.material.flatShading = 0;
}
});
scene.add(object);
},
function(xhr){
console.log((xhr.loaded / xhr.total * 100) + '% loaded');
},
function(error){
console.log('An error happened');
}
);
//Light sources...
//Game loop
function animate(){
requestAnimationFrame( animate );
render();
};
function render(){
renderer.render(scene,camera);
};
How can I have my loader actually load the model selected from the dropdown list? Thank you.
Update: The network tab of my browser's dev tools show my index file listed twice. The one labeled "xhr" links by stack trace to line 93 of the index file, which is where the loader begins ("loader.load"). Commenting out the switch statement removes that extra html file. What could be causing my loader to perceive the switch statement as html?
OBJLoader
. Please ensure with the network tab of the browser's dev tools that you actually load the correct resource from the backend. – Mugen87node.js
and http-server and see if it works. – Mugen87onChange
event listener on the gui select which I don't see in your code. eg. workshop.chromeexperiments.com/examples/gui/#7--Events – 2pha