Cambie la textura de .obj cargado en three.js en tiempo de ejecución
Estoy tratando de cambiar la textura de la imagen en el tiempo de ejecución en un three.js .obj cargado. Aquí está el código directamente de los ejemplos de three.js con una ligera modificación:
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 a global var to 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 );
}
Lo único que agregué fue la función newTexture y una referencia a la malla como myMesh. Aquí está el ejemplo original (http://threejs.org/examples/webgl_loader_obj.html). La función no arroja ningún error pero el .obj no se actualiza. Sé que me estoy perdiendo algo fundamental aquí ..
Actualizar: Por la excelente respuesta a continuación, aquí está el código correcto con algunas adiciones para cambiar la textura a través de un campo de entrada:
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 to .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 a global var to reference later when changing textures
child;
//apply texture
child.material.map = THREE.ImageUtils.loadTexture(newTexturePath);
child.material.needsUpdate = true;
}
});
}