Having difficulty performing raycasting on a singular object within a group in three.js to trigger an animation

Having issues with raycasting into a group in my three.js project.

The goal is to trigger animations using TweenMax on object click. However, the problem arises when clicking on an object with another object behind it, causing both animations to be triggered due to raycasting on both objects.

Below is my raycasting code and you can view the complete project at www.jacobtruax.info

Is there a more effective way to achieve this functionality or a method to prevent raycasting on two objects simultaneously?

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});
            }

          }


      };

Answer №1

When using THREE.Raycaster, the returned information includes the distance to the object. If more than one object is returned, they are sorted by distance (e.g. intersections[0].distance). By comparing these distances, you can easily find the object with the closest proximity.

However, I suggest utilizing a single intersectObject test for all objects. You can then compare the closest object using == or === against a known object.
Create an array containing the objects fnup, old, cam, and alex, and compare the result of intersectObject with these 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 ) {
        // [...]
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Why does my Angular service throw an error stating "undefined is not a function" when passing my function as an argument?

I am currently working on implementing factory and two constructor patterns in Angular. My goal is to convert the factory into an Angular service. Below is a simplified version of the code I am working with: function processFactory () { // some code ...

Steps for creating a personalized query or route in feathersjs

I'm feeling a bit lost and confused while trying to navigate through the documentation. This is my first time using feathersjs and I am slowly getting the hang of it. Let's say I can create a /messages route using a service generator to GET all ...

When arrays are recalled, access to functions is lost for Javascript object instances

Check out this code snippet I have: var cobj = { a: 0, b: 0, c: 0, asdinit: function(x, y, w, h) { this.a = x; this.b = y; this.c = w; this.h = h; }, adsfads: function(a, b, c, d) { this.a = a; this.b = b; this.c ...

How come the ".includes" method is not functioning properly with my two-dimensional array?

Introduction: As part of a school project, I am tasked with creating a program that checks answers in a "test" to determine their correctness. This project requires the use of a two-dimensional array and the ".includes" function. Requirements: Mand ...

What is the best way to retrieve the file name from the current document's URL using JavaScript?

I need help with a Javascript function that can extract the current file name without any parameters. $(location).attr('href').match(/([a-zA-Z\-\_0-9]+\.\w+)$/); var current_path = RegExp.$1; if ((current_path == 'index. ...

Enabling the `skin` property in the ShaderMaterial triggers an error message about exceeding the limit of uniforms

Currently, I have a function that is responsible for loading a mesh from a JSON file: loadJSONModel(filename, modelName) { let loader = new THREE.JSONLoader(); loader.load(`assets/${filename}`, (geometry, materials) => { let material = Shader.create ...

Transforming a <Class Component> into a <Stateless Functional Component> by implementing Hooks and integrating a callback function

I am currently in the process of transforming a Class Component into a Stateless Functional Component by utilizing the concept of React Hooks. My focus is on working with custom field components in react-jsonschema-form. You can find more information on c ...

Troubleshooting a GetStaticProps problem in Next.js

I'm currently facing an issue with retrieving posts from my WordPress site. After running tests on the URL endpoint, it seems to be functioning properly with client-side rendering. However, when I attempt to utilize the getStaticProps function, the re ...

What is the best way to retrieve and utilize various data from a JSON object? Is creating an array necessary for this task?

As a novice, I am currently utilizing $.get to fetch data from a REST API, the JSON response looks like this: [{"id":"1","url":"http:\/\/123.456.78.910\/workforce\/images\/item1.jpg","price":"99","description":"Mobile Phone"}, ...

When two divs are activated, the third div goes into invisible mode

I attempted this code, but it doesn't appear to be functioning correctly. if(div1)&& (div2)==display:none { div3=display:none; } else { div3=display:block; } ...

Concealing a div depending on the price variation

I'm looking for a way to dynamically show or hide a div based on the price of selected variations in my online store. Let's take a product with options priced at £359 and £455 as an example. In addition, there is a finance plugin with a minim ...

The challenge with linking within Layerslider

Having some trouble with an external link to a specific layerslider slide (html version, NOT wordpress). Here is the webpage in question: After reaching out in the support forum, I was advised to use this javascript: <a href="javascript:void(0);" onc ...

Refresh the table following deletion of a row from firebase

I have developed an application where I display data from a firebase object in a table. However, I have encountered an issue where I need to manually refresh the page every time I remove a row from the table. Is there a way to automate this process? The sa ...

The integration of Angular and Node API within the IISNode directory structure is experiencing functionality issues

Read more about the question I have successfully set up my Node API and Angular component with IISnode. However, when accessing the application from the IIS server, I noticed that they are showing in different directories (see image below). Additionally, I ...

Retrieve the fully loaded webpage source code in Java as it is displayed by the browser

There are certain webpages that utilize JavaScript and AJAX calls to populate fields during or after the page has loaded. An example can be found at this link, where the content in a size dropdown box is filled using JavaScript. I am wondering if it is po ...

The issue of the menu in the <Select /> component unexpectedly closing is caused by the MaterialUI -withStyles higher-order component (HOC)

Issue Description When utilizing the <Select /> component with the multiple attribute, users should be able to select multiple options without the dropdown menu closing. This functionality works as intended when using the <Select /> component ...

Implementing sorting functionality in a list with Vue.js by incorporating an arrow icon in the column using v-bind

Is there a way to implement sorting functionality in Vue.js by clicking on table headers and displaying an arrow to indicate the sorting order? I am struggling with creating a function in Vue for sorting and using v-bind to add the arrow. Can someone guide ...

"Utilize Three.js to construct walls that intersect at right angles in a

Is it feasible to generate 3D perpendicular walls using Three.js like the ones shown in this image? I attempted to use THREE.Shape to sketch a rectangle, but I'm unsure how to incorporate additional perpendicular or parallel rectangles. ...

Can one create a set of rest arguments in TypeScript?

Looking for some guidance on working with rest parameters in a constructor. Specifically, I have a scenario where the rest parameter should consist of keys from an object, and I want to ensure that when calling the constructor, only unique keys are passed. ...

Tips on extracting code differences from code inspector

Utilizing the Chrome code inspector is extremely valuable, but I often find it challenging to track the modifications made to CSS and HTML live. This becomes particularly cumbersome when there are multiple tags being modified. Are there any Chromium exten ...