I am having a problem with raycasting into a group I've created in three.js.
I am attempting to trigger animations with TweenMax when I click on object. The problem is when you click an object with another behind it, it triggers both of the objects animation sequences since it's raycasting both objects.
My raycasting code is below and here is a link to the working url to see the entire project. -> www.jacobtruax.info
Is there a better way to achieve what I am attempting to do, or a way I can stop it from raycasting two objects at a time?
let mouse = new THREE.Vector2();
let raycaster = new THREE.Raycaster(),INTERSECTED;
document.addEventListener("mousemove", function (event) {
if (isMouseDown) {
document.body.style.cursor = 'grabbing'
}
aimX = ((window.innerWidth / 2) - event.pageX) * 0.35
aimY = ((window.innerHeight / 2) - event.pageY) * 0.5
aimX2 = ((window.innerWidth / 2) - event.pageX) * 0.05
aimY2 = ((window.innerHeight / 2) - event.pageY) * 0.05
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
raycaster.setFromCamera(mouse, camera)
const intersections = raycaster.intersectObjects(group.children)
const sWorks = document.getElementById('sWorks')
if (intersections.length > 0) {
if (INTERSECTED != intersections[0].object) {
if (INTERSECTED)
INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
INTERSECTED = intersections[0].object;
INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
//setting up new material on hover
INTERSECTED.material.color.setHex( 0xadadad );
// uRL()
if (INTERSECTED){
sWorks.innerHTML = intersections[0].object.userData.NAME
}
if (INTERSECTED){
document.body.style.cursor = "pointer"
}
}
} else {
if (INTERSECTED) INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
sWorks.innerHTML = "Selected Works";
document.body.style.cursor = "grab";
INTERSECTED = null;
}
if(isMouseDown) {
aimX = aimX + (event.pageX - startX)
aimY = aimY + (event.pageY - startY)
group.rotation.set(0, ((aimX + (event.pageX - startX)) + (aimY + (event.pageY - startY))) / 900, 0)
//createShape(event.pageX, event.pageY)
}
})
document.addEventListener('mousedown', onDocumentMouseDown, false);
function onDocumentMouseDown(event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
var intersectFnup = raycaster.intersectObject(fnup);
var intersectOld = raycaster.intersectObject(old);
var intersectCam = raycaster.intersectObject(cam);
var intersectAlex = raycaster.intersectObject(alex);
const intersections = raycaster.intersectObjects(group.children)
if (intersections.length > 0){
if (intersectOld.length > 0) {
TweenMax.to(old, 1.5, {three:{scaleX: 2.5, scaleY: 2.5, x:0, y:0, z:0, rotationX: 0 }, ease:Power2.easeInOut});
TweenMax.to(fnup, 1, {three:{y:-4000, opacity: 0 }, ease:Power2.easeInOut});
TweenMax.to(alex, 1, {three:{y:-4000, opacity: 0 }, ease:Power2.easeInOut});
TweenMax.to(cam, 1, {three:{y:-4000, opacity: 0 }, ease:Power2.easeInOut});
oldRotate = false
groupRotate = false
fnupPosition = false
TweenMax.to(mirrorCube, 1, {three:{y:-400, opacity: 0 }, ease:Power2.easeInOut});
}
if (intersectFnup.length > 0) {
TweenMax.to(fnup, 1.5, {three:{scaleX: 2.5, scaleY: 2.5, x:0, y:0, z:0 }, ease:Power2.easeInOut});
TweenMax.to(old, 1, {three:{y:-4000, opacity: 0 }, ease:Power2.easeInOut});
TweenMax.to(alex, 1, {three:{y:-4000, opacity: 0 }, ease:Power2.easeInOut});
TweenMax.to(cam, 1, {three:{y:-4000, opacity: 0 }, ease:Power2.easeInOut});
oldRotate = false
groupRotate = false
fnupPosition = false
TweenMax.to(mirrorCube, 1, {three:{y:-400, opacity: 0 }, ease:Power2.easeInOut});
}
if (intersectCam.length > 0) {
TweenMax.to(cam, 1.5, {three:{scaleX: 2.5, scaleY: 2.5, x:0, y:0, z:0 , rotationX: 0}, ease:Power2.easeInOut});
TweenMax.to(fnup, 1, {three:{y:-4000, opacity: 0 }, ease:Power2.easeInOut});
TweenMax.to(alex, 1, {three:{y:-4000, opacity: 0 }, ease:Power2.easeInOut});
TweenMax.to(old, 1, {three:{y:-4000, opacity: 0 }, ease:Power2.easeInOut});
oldRotate = false
groupRotate = false
fnupPosition = false
TweenMax.to(mirrorCube, 1, {three:{y:-400, opacity: 0 }, ease:Power2.easeInOut});
}
if (intersectAlex.length > 0) {
TweenMax.to(alex, 1.5, {three:{scaleX: 2.5, scaleY: 2.5, x:0, y:0, z:0, rotationX: 0 }, ease:Power2.easeInOut});
TweenMax.to(fnup, 1, {three:{y:-4000, opacity: 0 }, ease:Power2.easeInOut});
TweenMax.to(cam, 1, {three:{y:-4000, opacity: 0 }, ease:Power2.easeInOut});
TweenMax.to(old, 1, {three:{y:-4000, opacity: 0 }, ease:Power2.easeInOut});
oldRotate = false
groupRotate = false
fnupPosition = false
TweenMax.to(mirrorCube, 1, {three:{y:-400, opacity: 0 }, ease:Power2.easeInOut});
}
}
};
The information which is returned by THREE.Raycaster
, contains the distance to the object and if mor than 1 objects are returned by the then the objects are sorted by its distance (e.g. intersections[0].distance
).
You can compare this distances to find the object with the closest distance.
But I recommend to use a single intersectObject
test, with all the objects. The reference to the closest object can be compared by ==
or ===
to a know object.
Generate an array containing the objects fnup
, old
, cam
, and alex
, and compare the result of intersectObject
to the objects:
var objects = [fnup, old, cam, alex];
var intersections = raycaster.intersectObjects(objects)
if (intersections.length > 0) {
if ( intersects[0].object == fnup ) {
// [...]
}
if ( intersects[0].object == old ) {
// [...]
}
if ( intersects[0].object == cam ) {
// [...]
}
if ( intersects[0].object == alex ) {
// [...]
}
}