I created a cube using the canvas renderer with r59 of Three.js. The cube has different textures on different sides. This renders okay. I can also TWEEN this cube's position and rotation, so it's fine.
Here's what I want to do: A) The cube has an image texture on it's front side. B) I move this cube out of the camera's view. C) I change the image texture on the cube. D) I move the cube back to its original coordinates so it becomes visible again.
So far, steps A, B and D are working. But when I try to implement step C, it stops working. Here are the relevant code parts...
<body>
<script src="build/three.min.js"></script>
<script src="js/libs/tween.min.js"></script>
<script>
var container;
var camera, scene, renderer, group, particle;
var cubeMesh;
var MatCollection = [];
var Materials = [];
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 3000 );
camera.position.z = 1000;
scene = new THREE.Scene();
var cubeGeometry = new THREE.CubeGeometry(800, 600, 30, 8, 8, 8);
cubeGeometry.dynamic = true;
// creating three textures
var neheTextureSMALL = new THREE.ImageUtils.loadTexture("test3.jpg");
var neheTextureBIG1 = new THREE.ImageUtils.loadTexture("break01.jpg");
var neheTextureBIG2 = new THREE.ImageUtils.loadTexture("break02.jpg");
// putting two different sets of Materials to a material collection array
Materials = [
new THREE.MeshBasicMaterial({
map:neheTextureBIG1,
side: THREE.DoubleSide
}),
new THREE.MeshBasicMaterial({
map:neheTextureSMALL,
side: THREE.DoubleSide
}),
new THREE.MeshBasicMaterial({
map:neheTextureSMALL,
side: THREE.DoubleSide
}),
new THREE.MeshBasicMaterial({
map:neheTextureSMALL,
side: THREE.DoubleSide
}),
new THREE.MeshBasicMaterial({
map:neheTextureBIG1,
side: THREE.DoubleSide
}),
new THREE.MeshBasicMaterial({
map:neheTextureBIG1,
side: THREE.DoubleSide
})
];
MatCollection.push( Materials );
Materials = [
new THREE.MeshBasicMaterial({
map:neheTextureBIG2,
side: THREE.DoubleSide
}),
new THREE.MeshBasicMaterial({
map:neheTextureSMALL,
side: THREE.DoubleSide
}),
new THREE.MeshBasicMaterial({
map:neheTextureSMALL,
side: THREE.DoubleSide
}),
new THREE.MeshBasicMaterial({
map:neheTextureSMALL,
side: THREE.DoubleSide
}),
new THREE.MeshBasicMaterial({
map:neheTextureBIG2,
side: THREE.DoubleSide
}),
new THREE.MeshBasicMaterial({
map:neheTextureBIG2,
side: THREE.DoubleSide
})
];
MatCollection.push( Materials );
cubeMesh = new THREE.Mesh(cubeGeometry, new THREE.MeshFaceMaterial( MatCollection[0] ));
cubeMesh.dynamic = true;
cubeMesh.position.set(0, 0, 500);
// Applying the first set of materials on cubeMesh creation works good
renderer = new THREE.CanvasRenderer();
renderer.setClearColor(0x000000, 1);
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
TWEEN.update();
camera.lookAt( scene.position );
// rotate the cube - dropped value manipulation
cubeMesh.rotation.set(xRotation, yRotation, zRotation);
renderer.render( scene, camera );
}
// this is NOT WORKING
function changetexture() {
currentMat++;
if (currentMat >= MatCollection.length) {
currentMat = 0;
}
cubeMesh.material = MatCollection[currentMat];
cubeMesh.material.needsUpdate = true;
}
</script>
</body>
In my project, I am doing a lot more TWEENING (moving and rotating a lot of objects) and I am calling changetexture() from there...
When leaving out the line...
cubeMesh.material = MatCollection[currentMat];
from that function, everything works fine. The cube moves out and comes back into view showing always the same texture.
What should I change?
Thank you in advance for sharing your expertise.
Oliver
Done.
Instead of trying to preload the Material into an array of materials, I created an array of individual textures called MyTextures and applied a newly created material (using the textures from the MyTextures array) to each side of the cube mesh.
...
var MyTextures = [];
... then, in the init() function:
neheTextureSMALL = new THREE.ImageUtils.loadTexture("test3.jpg");
MyTextures.push( neheTextureSMALL );
for (var myy = 0; myy<imgNameArray.length;myy++) {
neheTexture = new THREE.ImageUtils.loadTexture(imgNameArray[myy]);
MyTextures.push( neheTexture );
}
... then in the changetexture() function:
cubeMesh.material.materials[0] = new THREE.MeshBasicMaterial({map: MyTextures[currentMat+1], side: THREE.DoubleSide });
cubeMesh.material.materials[1] = new THREE.MeshBasicMaterial({map: MyTextures[0], side: THREE.DoubleSide });
cubeMesh.material.materials[2] = new THREE.MeshBasicMaterial({map: MyTextures[0], side: THREE.DoubleSide });
cubeMesh.material.materials[3] = new THREE.MeshBasicMaterial({map: MyTextures[0], side: THREE.DoubleSide });
cubeMesh.material.materials[4] = new THREE.MeshBasicMaterial({map: MyTextures[currentMat+1], side: THREE.DoubleSide });
cubeMesh.material.materials[5] = new THREE.MeshBasicMaterial({map: MyTextures[currentMat+1], side: THREE.DoubleSide });
That works pretty well. But it does not look good (the image seems to be split into many triangles which is another problem...). :-(