This is a three.js and typescript project. I am trying to color a sphere by raycasting to it, but it seems like the raycast doesn't know when the object has moved and assumes it still is at it's original position and it doesn't hit the object when it moves. Here is my code:
import * as THREE from "three";
// boilerplate
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
// sphere object
const geometry = new THREE.SphereGeometry();
const sphereMaterial = new THREE.MeshLambertMaterial({
color: "0xFFFFFF",
});
const sphere = new THREE.Mesh(geometry, sphereMaterial);
scene.add(sphere);
// light
const ambientLight = new THREE.AmbientLight();
scene.add(ambientLight);
// raycasting
const mousePosition = new THREE.Vector2();
const raycaster = new THREE.Raycaster();
window.addEventListener("mousemove", (event) => {
mousePosition.x = (event.clientX / window.innerWidth) * 2 - 1; // from the original values (event.clientX/Y) we create normalized values via these formulas
mousePosition.y = (event.clientY / window.innerHeight) * 2 - 1;
raycaster.setFromCamera(mousePosition, camera);
const intersects = raycaster.intersectObjects(scene.children);
console.log(intersects);
for (let i = 0; i < intersects.length; i++) {
if (intersects[i].object === sphere) {
(intersects[i].object as any).material.color.set("red");
}
}
});
// animations
let step = 0;
const animate = (time: number) => {
step += 0.01;
sphere.position.y = 4 * Math.abs(Math.sin(step + 1));
renderer.render(scene, camera);
};
// camera
const camera = new THREE.PerspectiveCamera(
60,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.set(5, 5, 10);
camera.lookAt(new THREE.Vector3(0, 0, 0));
renderer.setAnimationLoop(animate);
I am not even sure if raycasting is supposed to even work with moving objects, so if not what would be a good alternative to raycasting for this situation?
You should be able to solve your issue by computing mouse coordinates via:
const rect = renderer.domElement.getBoundingClientRect();
mousePosition.x = ( ( event.clientX - rect.left ) / ( rect.right - rect.left ) ) * 2 - 1;
mousePosition.y = - ( ( event.clientY - rect.top ) / ( rect.bottom - rect.top) ) * 2 + 1;
Live example: https://jsfiddle.net/9nhftaud/1/