Как да добавите материал (.mtl) към обект (.obj) с помощта на three.js?

Успешно получих .obj файл за показване с помощта на three.js от фрагмент от код, който намерих онлайн и който адаптирах за моите нужди. Но сега се опитвам да добавя .mtl материалния файл и се забивам.

Опитах няколко неща, но изглежда нищо не работи. Нов съм в three.js, така че определено не съм разбрал нещо тук...

Ето текущия код, който използвам, който работи прекрасно за показване на моя .obj файл:

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();

Ето един фрагмент, който се опитах да добавя, за да заредя mtl файла, който не работи (току-що съкратих действителния път до /mypath/ за чистота тук)

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 );


};

От проучването виждам, че трябва да има мрежа, за да работи даден материал, но просто не мога да разбера от каквато и да е документация как мога да го внедря правилно.

Всяка помощ за добавянето на mtl файл към моя код ще бъде много оценена!!

** РЕДАКТИРАНЕ **

Така че промених кодовия фрагмент въз основа на съвета от Mugen87 на следното:

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 );


};

И аз също включих MTLLoader.js от примерите на three.js (не съм сигурен дали това е правилно, трудно ми е да намеря информация за това) и получавам следните грешки в конзолата:

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

Някакви идеи? Има ли нещо нередно с това как имам MTL в кода?


person Kiki    schedule 18.10.2019    source източник


Отговори (1)


object.position.y = - 95;
scene.add( object );

Предполагам, че сте копирали и двата реда код от официалния пример за OBJ/MTL, нали? За съжаление, те нямат смисъл тук, тъй като object е undefined. Имайте предвид, че addNefertitiInScene е вашето onLoad() обратно извикване, което отговаря за добавянето на заредения обект към сцената.

Освен това mtlLoader.setBaseUrl( '/mypath/' ); не трябва да е необходимо. Методът беше премахнат преди доста време.

Също така се уверете с инструментите за разработка на браузъра, че MTL файлът действително е зареден.

three.js R109

person Mugen87    schedule 18.10.2019
comment
Благодаря за отговора, оценявам го. Ще редактирам оригиналната си публикация с направените промени и какви грешки получавам сега, за да видя дали има някакъв шанс за повече помощ - person Kiki; 19.10.2019
comment
Можете ли да покажете как импортирате MTLLoader? Cannot use import statement outside a module обикновено показва, че използвате ES6 модули по грешен начин. - person Mugen87; 19.10.2019
comment
Копирах MTLLoader.js от файла GitHub тук от примера: github.com/mrdoob/three.js/blob/dev/examples/js/loaders/ Ето как след това зареждам всички скриптове: ‹script src=//cdnjs.cloudflare. com/ajax/libs/three.js/85/three.min.js›‹/script› ‹script src=//threejs.org/examples/js/loaders/OBJLoader.js›‹/script› ‹script src= /mypath/MTLLoader.js›‹/script› - person Kiki; 20.10.2019
comment
Можете ли да се уверите, че използвате версия на three.js, която съответства на версиите на OBJLoader и MTLLoader? Не е добре, ако използвате най-новите класове за зареждане с такава стара версия three.js (R85). Използвайте тези URL адреси вместо threejs.org/build/three.js и threejs.org/examples/js/loaders/MTLLoader.js. - person Mugen87; 20.10.2019
comment
Във всеки случай опитайте да споделите пълния си код като git хранилище. След това мога да отстраня грешки в моята система. - person Mugen87; 20.10.2019