How to color the clicked mesh in Threejs using Orbitcontrol?

68 views Asked by At

I'm trying to color the clicked mesh in a mesh group in ThreeJs. In addition, I'm using orbitcontrol for 3D model. But when I tried to color the clicked mesh, a different mesh was colored.

Here some part of my code:

    lines.forEach(line => {
        const values = line.split('\t'); // tab separated
        if (values.length === 3) {
            const x = parseFloat(values[0]);
            const y = parseFloat(values[1]);
            const z = parseFloat(values[2]);
        
            const sphere = new THREE.Mesh(geometry, defaultMaterial.clone());
           
            switch (currentAxis) {
                case 'x':
                    sphere.position.set(x, 0, 0);
                    break;
                case 'y':
                    sphere.position.set(0, y, 0);
                    break;
                case 'z':
                    sphere.position.set(0, 0, z);
                    break;
                default:
                    sphere.position.set(x, y, z);
                    break;
            }          
           
            scene.add(sphere); 
            spheres.push(sphere);        
        }
    });
    renderer.domElement.addEventListener('click', onCanvasClick, false);

function onCanvasClick(event) {
    // Calculate the mouse click position in normalized device coordinates (NDC)
    var mouse = new THREE.Vector2();
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

    // Raycasting is used to determine which object was clicked
    var raycaster = new THREE.Raycaster();
    raycaster.setFromCamera(mouse, camera);

    var intersects = raycaster.intersectObjects(spheres);

    if (intersects.length > 0) {
        // Check if the clicked mesh is different from the previously clicked mesh
        if (intersects[0].object !== clickedMesh) {
            // Reset the color of the previously clicked mesh (if any)
            if (clickedMesh) {
                clickedMesh.material.color.set(0xffffff); // Reset to the original color
            }

            // Change the color of the clicked mesh
            intersects[0].object.material.color.set(0x0000ff);
            clickedMesh = intersects[0].object; // Update the currently clicked mesh
        }
    }
}
    

I used Raycaster, but unfortunately, it didn't work yet. How can I color the clicked mesh only?

EDIT:

When i changed x,y like this:

const containerRect = container.getBoundingClientRect();
const x = ((event.clientX - containerRect.left) / container.clientWidth) * 2 - 1;
const y = -((event.clientY - containerRect.top) / container.clientHeight) * 2 + 1;

It started to get too close. When I enlarge the model, the probability of finding the correct mesh increases greatly, but as the model moves further away, it moves further away from the correct mesh.

Some info:

const container = document.querySelector('.design');      
// Create a camera with appropriate aspect ratio and size
const width = container.clientWidth;
const height = container.clientHeight;
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000); 
const CAM_DISTANCE = 10;

EDIT 2: I also tried this example: https://threejs.org/examples/?q=select#misc_boxselection. I've added two new js files SelectionBox.js and SelectionHelper.js.

SelectionBox.js: https://github.com/mrdoob/three.js/blob/master/examples/jsm/interactive/SelectionBox.js SelectionHelper.js: https://github.com/mrdoob/three.js/blob/master/examples/jsm/interactive/SelectionHelper.js

But they're not what I wanted. Because the problem was the same.

0

There are 0 answers