0

I have a 3D model of a car. I would like to add a function to change the color of the vehicle upon clicking on one of the color choice but currently I'm getting an error saying "parent.traverse is not a function" at "at setMaterial" and "HTMLDivElement.selectSwatch". Can anyone notice what am I doing wrong?

HTML

<div class="palette" id="js-palette">
    <div class="pallete__slide" id="js-palette-slide"></div>
</div>

JavaScript

let theModel = './cars/scene.gltf'

let activeOption = 'Object_59'

const colors = [
        {
            color: "000000",
        },
        {
            color: "545252",
        },
    ];



function buildColors(colors) {
    for (let [i, color] of colors.entries()) {
        let colorpalette = document.createElement('div');
        colorpalette.classList.add('pallete__colors');

        colorpalette.style.background = '#' + color.color;

        colorpalette.setAttribute('data-key', i);
        palette.append(colorpalette)

    }
}

buildColors(colors)

// Swatches
const swatches = document.querySelectorAll(".pallete__colors");

for (const colorpalette of swatches) {
    colorpalette.addEventListener('click', selectSwatch);
}

function selectSwatch(e) {
    let color = colors[parseInt(e.target.dataset.key)];
    let new_mtl;
    let new_color = parseInt('0x' + color.color)

    if (color.texture) {
        let txt = new THREE.TextureLoader().load(color.texture);

        txt.repeat.set(color.size[0], color.size[1], color.size[2]);
        txt.wrapS = THREE.RepeatWrapping;
        txt.wrapT = THREE.RepeatWrapping;

        new_mtl = new THREE.MeshPhongMaterial({map: txt, shininess: color.shininess ? color.shininess : 10});
    } else {
        new_mtl = new THREE.MeshPhongMaterial({
            color: parseInt('0x' + color.color),
            shininess: color.shininess ? color.shininess : 10
        });
    }
    setMaterial(theModel, activeOption, new_mtl, new_color);
}

function setMaterial(parent, type, mtl, new_color) {
    parent.traverse(o => {
        if (o.isMesh && o.nameID != null) {
            if (o.nameID == type) {
                o.material.color.set(new_color);
            }
        }
    });
}
Archon
  • 69
  • 6
  • You define theModel as a string which looks to be a path to your model and pass it to setMaterial function which calls traverse function on it. Looks like you need to load the model from that file before calling the setMaterial function. https://stackoverflow.com/questions/25391529/how-to-load-a-gltf-model-to-three-js may be helpful – burkay Feb 11 '22 at 01:24
  • @burkay My loader is underneath the let activeOption = "Object_59", I tried declaring the Model as a variable and setting model_path as a new path for the model and now I'm getting "Cannot read properties of undefined (reading 'traverse')" error. – Archon Feb 11 '22 at 01:34
  • Sorry but I could not understand. activeOption is just another string. If this is not your full code, please provide more. – burkay Feb 11 '22 at 01:39
  • @burkay https://codepen.io/Arconi/pen/NWwjZrm – Archon Feb 11 '22 at 01:41
  • 1
    Could not see the problem. I would try debugging with breakpoints. Good luck! – burkay Feb 11 '22 at 01:52

0 Answers0