javascript - Change texture of loaded .obj in three.js at runtime -


i'm trying swap image texture @ runtime on loaded three.js .obj. here's code straight three.js examples slight modification:

        var container, stats;         var camera, scene, renderer;         var mousex = 0, mousey = 0;         var windowhalfx = window.innerwidth / 2;         var windowhalfy = window.innerheight / 2;           init();         animate();           function init() {              container = document.createelement( 'div' );             document.body.appendchild( container );              camera = new three.perspectivecamera( 45, window.innerwidth / window.innerheight, 1, 2000 );             camera.position.z = 100;              //scene             scene = new three.scene();              var ambient = new three.ambientlight( 0x101030 );             scene.add( ambient );              var directionallight = new three.directionallight( 0xffeedd );             directionallight.position.set( 0, 0, 1 );             scene.add( directionallight );              //manager             var manager = new three.loadingmanager();             manager.onprogress = function ( item, loaded, total ) {                  console.log( item, loaded, total );              };              //model             var loader = new three.objloader( manager );             loader.load( 'obj/female02/female02.obj', function ( object ) {                 object.traverse( function ( child ) {                      if ( child instanceof three.mesh ) {                         //create global var reference later when changing textures                         mymesh = child;                         //apply texture                         mymesh.material.map = three.imageutils.loadtexture( 'textures/ash_uvgrid01.jpg');                         mymesh.material.needsupdate = true;                     }                  } );                   object.position.y = - 80;                 scene.add( object );              } );              //render             renderer = new three.webglrenderer();             renderer.setsize( window.innerwidth, window.innerheight );             container.appendchild( renderer.domelement );              document.addeventlistener( 'mousemove', ondocumentmousemove, false );             window.addeventlistener( 'resize', onwindowresize, false );          }          function newtexture() {             mymesh.material.map = three.imageutils.loadtexture( 'textures/land_ocean_ice_cloud_2048.jpg');             mymesh.material.needsupdate = true;         }          function onwindowresize() {              windowhalfx = window.innerwidth / 2;             windowhalfy = window.innerheight / 2;              camera.aspect = window.innerwidth / window.innerheight;             camera.updateprojectionmatrix();              renderer.setsize( window.innerwidth, window.innerheight );          }          function ondocumentmousemove( event ) {              mousex = ( event.clientx - windowhalfx ) / 2;             mousey = ( event.clienty - windowhalfy ) / 2;          }          //animate         function animate() {              requestanimationframe( animate );             render();          }          function render() {              camera.position.x += ( mousex - camera.position.x ) * .05;             camera.position.y += ( - mousey - camera.position.y ) * .05;              camera.lookat( scene.position );              renderer.render( scene, camera );          } 

the thing added newtexture function , reference mesh mymesh. here's original example (http://threejs.org/examples/webgl_loader_obj.html). function doesn't throw errors .obj not update. know i'm missing fundamental here..

update: per excellent answer below, here's correct code additions swap texture via input field:

  var container, stats;   var camera, scene, renderer;   var mousex = 0, mousey = 0;   var windowhalfx = window.innerwidth / 2;   var windowhalfy = window.innerheight / 2;   var globalobject;    init();   animate();    function init() {       container = document.createelement('div');       document.body.appendchild(container);        camera = new three.perspectivecamera(45, window.innerwidth / window.innerheight, 1, 2000);       camera.position.z = 100;        //scene       scene = new three.scene();        var ambient = new three.ambientlight( 0x101030 );       scene.add( ambient );        var directionallight = new three.directionallight( 0xffeedd );       directionallight.position.set( 0, 0, 1 );       scene.add( directionallight );        //manager       var manager = new three.loadingmanager();       manager.onprogress = function (item, loaded, total) {         console.log( item, loaded, total );       };      //model     var loader = new three.objloader( manager );     loader.load( 'obj/female02/female02.obj', function (object) {         //store global reference .obj         globalobject = object;        object.traverse( function (child) {           if ( child instanceof three.mesh ) {               child.material.map = three.imageutils.loadtexture( 'textures/grid.jpg');               child.material.needsupdate = true;           }       });        object.position.y = - 80;       scene.add( object );     });      //render     renderer = new three.webglrenderer();     renderer.setsize( window.innerwidth, window.innerheight );     container.appendchild( renderer.domelement );      document.addeventlistener( 'mousemove', ondocumentmousemove, false );     window.addeventlistener( 'resize', onwindowresize, false );   }    function onwindowresize() {     windowhalfx = window.innerwidth / 2;     windowhalfy = window.innerheight / 2;     camera.aspect = window.innerwidth / window.innerheight;     camera.updateprojectionmatrix();     renderer.setsize( window.innerwidth, window.innerheight );   }    function ondocumentmousemove( event ) {     mousex = ( event.clientx - windowhalfx ) / 2;     mousey = ( event.clienty - windowhalfy ) / 2;   }    //animate   function animate() {     requestanimationframe( animate );     render();   }    function render() {     camera.position.x += ( mousex - camera.position.x ) * .05;     camera.position.y += ( - mousey - camera.position.y ) * .05;             camera.lookat( scene.position );             renderer.render( scene, camera );   }    function newtexture() {     var newtexturepath = "textures/" + document.getelementbyid("texture").value + "";      globalobject.traverse( function ( child ) {       if (child instanceof three.mesh) {           //create global var reference later when changing textures           child;           //apply texture           child.material.map = three.imageutils.loadtexture(newtexturepath);           child.material.needsupdate = true;       }     });   } 

the problem here there multiple child meshes in object variable. having 1 mymesh global variable, storing last child mesh. when try update texture using global variable, 1 of meshes gets texture update, small hidden part not visible.

the solution either:

  • store mymeshes array global variable , push mymesh every time there one. in newtexture() function, iterate through items in array , update maps/materials.
  • or, store object variable (the 1 returned objloader's callback) 1 single global variable. in newtexture() function, iterate through meshes how done in code (using traverse() , if statement), , update maps/materials.

lastly, calling newtexture() somewhere in code ;)


Comments

Popular posts from this blog

java - JavaFX 2 slider labelFormatter not being used -

Detect support for Shoutcast ICY MP3 without navigator.userAgent in Firefox? -

web - SVG not rendering properly in Firefox -