I have successfully gotten a .obj file to display using three.js from a snippet of code I found online which I adapted for my needs. But am now trying to add the .mtl material file and am getting stuck.
I've tried a few things but nothing seems to be working. I am new to three.js so am definitely misunderstanding something here...
Here is the current code I am using that works beautifully to display my .obj file:
var renderer, scene, camera, Nefertiti;
var ww = window.innerWidth,
wh = window.innerHeight;
function init(){
renderer = new THREE.WebGLRenderer({canvas : document.getElementById('scene')});
renderer.setSize(ww,wh);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50,ww/wh, 0.1, 10000 );
camera.position.set(0,0,500);
scene.add(camera);
//Add a light in the scene
directionalLight = new THREE.DirectionalLight( 0xffffff, 0.8 );
directionalLight.position.set( 0, 0, 350 );
directionalLight.lookAt(new THREE.Vector3(0,0,0));
scene.add( directionalLight );
//Load the obj file
loadOBJ();
}
var loadOBJ = function(){
//Manager from ThreeJs to track a loader and its status
var manager = new THREE.LoadingManager();
//Loader for Obj from Three.js
var loader = new THREE.OBJLoader( manager );
//Launch loading of the obj file, addNefertitiInScene is the callback when it's ready
loader.load( '/mypath/Nefertiti-3d.obj', addNefertitiInScene);
};
var addNefertitiInScene = function(object){
Nefertiti = object;
//Move the Nefertiti in the scene
Nefertiti.scale.set(0.7,0.7,0.7);
Nefertiti.rotation.x = 0.5;
Nefertiti.rotation.y = 5.5;
Nefertiti.rotation.z = 0.2;
Nefertiti.position.y = -40;
Nefertiti.position.z = 1;
//Go through all children of the loaded object and search for a Mesh
object.traverse( function ( child ) {
//This allow us to check if the children is an instance of the Mesh constructor
if(child instanceof THREE.Mesh){
child.material.color = new THREE.Color(0XFFFFFF);
//Sometimes there are some vertex normals missing in the .obj files, ThreeJs will compute them
child.geometry.computeVertexNormals();
}
});
//Add the 3D object in the scene
scene.add(Nefertiti);
var canvas = renderer.domElement;
canvas.addEventListener('mousemove', onMouseMove);
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
animate();
function onMouseMove(event) {
Nefertiti.rotation.y += event.movementX * 0.001;
Nefertiti.rotation.x += event.movementY * 0.0005;
}
};
init();
Here is a snippet I tried adding in to load the mtl file that didn't work (i've just shortened the actual path to /mypath/ for cleanliness here)
var loadOBJ = function(){
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setBaseUrl( '/mypath/' );
mtlLoader.setPath( '/mypath/' );
var url = "/mypath/Nefertiti-3d.mtl";
mtlLoader.load( url, function( materials ) {
materials.preload();
//Manager from ThreeJs to track a loader and its status
var manager = new THREE.LoadingManager();
//Loader for Obj from Three.js
var loader = new THREE.OBJLoader( manager );
loader.setMaterials( materials );
loader.setPath( '/mypath/' );
//Launch loading of the obj file, addNefertitiInScene is the callback when it's ready
loader.load( '/mypath/Nefertiti-3d.obj', addNefertitiInScene);
object.position.y = - 95;
scene.add( object );
}, onProgress, onError );
};
From researching I can see that there must be a mesh for a material to work, but I just cant figure out from any documentation how I can correctly implement it.
Any assistance in being able to add a mtl file to my code would be so appreciated!!
** EDIT **
So I have changed the snippet of code based on the advice from Mugen87 to the below:
var loadOBJ = function(){
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath( '/mypath/' );
var url = "/mypath/Nefertiti-3d.mtl";
mtlLoader.load( url, function( materials ) {
materials.preload();
//Manager from ThreeJs to track a loader and its status
var manager = new THREE.LoadingManager();
//Loader for Obj from Three.js
var loader = new THREE.OBJLoader( manager );
loader.setMaterials( materials );
loader.setPath( '/mypath/' );
//Launch loading of the obj file, addNefertitiInScene is the callback when it's ready
loader.load( '/mypath/Nefertiti-3d.obj', addNefertitiInScene);
}, onProgress, onError );
};
And I have also included the MTLLoader.js from the examples on three.js (I'm not sure if this is right, I'm finding it difficult to find information on this) and am getting the below errors in console:
Uncaught SyntaxError: Cannot use import statement outside a module
(index):136 Uncaught TypeError: THREE.MTLLoader is not a constructor
at loadOBJ ((index):136)
at init ((index):132)
at (index):199
loadOBJ @ (index):136
init @ (index):132
(anonymous) @ (index):199
Any ideas? Is there something wrong with how I have the MTL in the code?