On Can Texture switching example

This is a basic example of using Custom Code to change model texture

<aside> ☝ This is full code, explanation is below

</aside>

const sugarfreeTexture = this.textureLoader.load('<https://i.postimg.cc/fRgrZzq9/sugarfree.png>');
const tropicallTexture = this.textureLoader.load('<https://i.postimg.cc/ZYVgjxPH/original-yellow.png>');
const originalTexture = this.textureLoader.load('<https://i.postimg.cc/vHhKqLWX/classic.png>');

let activeTexture = 't';

const getRightTexture = () => {
    if (activeTexture === 't') {
        activeTexture = 's';
        return sugarfreeTexture;
    }

    if (activeTexture === 's') {
        activeTexture = 'o';
        return originalTexture;
    }

    if (activeTexture === 'o') {
        activeTexture = 't';
        return tropicallTexture;
    }

    activeTexture = 't';

    return tropicallTexture;
}

const changeCanTexture = (mesh) => {
    // save previous texture settings
    const prevTexture = mesh.material.map;

    // loading new image
    mesh.material.map = getRightTexture();

    // make sure to copy all necessary settings fro prev texture
    mesh.material.map.flipY = prevTexture.flipY;
    mesh.material.map.wrapS = prevTexture.wrapS;
    mesh.material.map.wrapT = prevTexture.wrapT;
    mesh.material.map.matrix = prevTexture.matrix;
    mesh.material.map.offset = prevTexture.offset;
    mesh.material.map.repeat = prevTexture.repeat;
    
		// update material
    mesh.material.transparent = true;
    mesh.material.needsUpdate = true;
    mesh.material.opacity = 0.5;
}; 

var value = 0;

function myTimer() {
    canBaseMesh.material.transparent = true;

		canBaseMesh.material.map.offset.x = value;
    value += 0.1;
    canBaseMesh.material.needsUpdate = true;
    canBaseMesh.material.map.updateMatrix();
}

var myVar = setInterval(myTimer, 200); 

let canBaseMesh;

this.activeSceneModel.scene.traverse((child) => {
    if (child.isMesh) {
        if (child.name.includes('CanBase')) {
            canBaseMesh = child
        }

    }

});

this.on('on-model-click', () => {
    changeCanTexture(canBaseMesh)
});

First of all we need textures to switch:

const sugarfreeTexture = this.textureLoader.load('<https://i.postimg.cc/fRgrZzq9/sugarfree.png>');
const tropicallTexture = this.textureLoader.load('<https://i.postimg.cc/ZYVgjxPH/original-yellow.png>');
const originalTexture = this.textureLoader.load('<https://i.postimg.cc/vHhKqLWX/classic.png>');

We're using i.postimg.cc to keep our textures at this time...

The important part is here:

this.activeSceneModel.scene.traverse((child) => {
    if (child.isMesh) {
        if (child.name.includes('CanBase')) {
            canBaseMesh = child
        }
    }
});

this is a context Builder creates for you model

It contains activeSceneModel which is a mobx model, which is documented here, but we're interested in activeSceneModel.scene property. It is a THREE.JS general scene object which represents currently active scene of your experience.

this.activeSceneModel.scene.traverse - is a THREE method of the scene. We're using it to find a mesh with name CanBase to switch it's textures - child.name.includes('CanBase') (our empathy-filled 3D-artist already named it handy to ease our search).

The last important thing is on method which is assigned to this. It is fired on the event it listens to fires. At the moment we've implemented only 'on-model-click' method, but more to come!

// THIS IS HOW EASY WE ARE USING THIS EVENT TO FIRE TEXTURE CHANGEING 
// LOGIC ON USER CLICK
// WHAT AN INTERACTIVITY!!!
this.on('on-model-click', () => {
    changeCanTexture(canBaseMesh)
});

And for ease of use THREE object is accessible here as well, and it brings all the might of THREE.JS library to this particular model and you needs.

The code assigned to model runs when the model is loaded to the scene.