The Raycaster fails to identify objects that have been rotated

I have recently started working with Three.js and I'm facing an issue with raycasting not detecting certain parts of a rotated mesh object. For instance, in the image below, when the mouse is at the position of the green circle, it's detected as being on the box and intersectObjects returns an array with that box. However, when the mouse is at the position of the red circle, it does not behave like it's on the box and intersectObjects returns an empty array.

https://i.sstatic.net/wmd8f.png

import * as THREE from 'three'
import { Mesh, MeshLambertMaterial } from 'three';

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, .1, 1000);
camera.position.z = 5;

var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor("#e5e5e5");
renderer.setSize(window.innerWidth, window.innerHeight);

document.body.appendChild(renderer.domElement);

var raycaser = new THREE.Raycaster();
var mouse = new THREE.Vector2();

var geometry = new THREE.BoxGeometry(3.5, .5, 3);
var material = new THREE.MeshLambertMaterial({ color: 0xFFCC00 });
var mesh = new THREE.Mesh(geometry, material);
mesh.rotation.set(.5, .8, 0);
scene.add(mesh);

var light = new THREE.PointLight(0xFFFFFF, 1, 500);
light.position.set(0, 1, 7);
scene.add(light);

var render = function () {
    requestAnimationFrame(render);    
    renderer.render(scene, camera);
}
render();

document.body.addEventListener("mousemove", (event) => {
    event.preventDefault();

    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = (event.clientY / window.innerHeight) * 2 - 1;
    raycaser.setFromCamera(mouse, camera);

    var intersects = Array.from(raycaser.intersectObjects(scene.children, true)).map(inter => inter.object as Mesh);

    document.body.style.cursor = intersects.length > 0 ? "pointer" : "default";;

    for (var i = 0; i < scene.children.length - 1; i++) {
        var object = scene.children[i] as Mesh;
        var material = object.material as MeshLambertMaterial;
        material.emissive.set(intersects.includes(object) ? 0x666666 : 0x000000);
    }
});

It could be related to the object rotation causing the issue. How can I ensure the correct behavior of Raycaster?

Answer №1

To calculate the mouse coordinates in a slightly different way, use the getBoundingClientRect() method. Take a look at this interactive example:

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, .1, 1000);
camera.position.z = 5;

const renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setClearColor("#e5e5e5");
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);

document.body.appendChild(renderer.domElement);

const raycaser = new THREE.Raycaster();
const mouse = new THREE.Vector2();

const geometry = new THREE.BoxGeometry(3.5, .5, 3);
const material = new THREE.MeshLambertMaterial({
  color: 0xFFCC00
});
const mesh = new THREE.Mesh(geometry, material);
mesh.rotation.set(.5, .8, 0);
scene.add(mesh);

const light = new THREE.PointLight(0xFFFFFF, 1, 500);
light.position.set(0, 1, 7);
scene.add(light);

function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();

document.body.addEventListener("pointermove", (event) => {

  const rect = renderer.domElement.getBoundingClientRect();
  mouse.x = ((event.clientX - rect.left) / (rect.right - rect.left)) * 2 - 1;
  mouse.y = -((event.clientY - rect.top) / (rect.bottom - rect.top)) * 2 + 1;

  raycaser.setFromCamera(mouse, camera);

  const intersects = raycaser.intersectObject(scene, true);

  document.body.style.cursor = intersects.length > 0 ? "pointer" : "default";

});
body {
      margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a8dcc0dacdcde89886999b988699">[email protected]</a>/build/three.js"></script>

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

Oops! Looks like there's an issue with the type error: value.forEach is

I am working on creating an update form in Angular 6 using FormArray. Below is the code snippet I have in editfrom.TS : // Initialising FormArray valueIngrident = new FormArray([]); constructor(private brandService: BrandService, private PValueInfoSe ...

What is the key to ensuring the content in your canvas adapts to different screen sizes

Greetings! I wanted to extract the values from this specific meta tag: <meta name="viewport" property="viewport" content="width-device-width, initial-scale=1"> To retrieve content from a meta tag using JavaScript, I used the following code snippet: ...

Exploring Angular 6's nested routes and corresponding components for child navigation

I'm currently diving into the concept of lazy loading in Angular 6. Here's a visual representation of the structure of my application: ─src ├───app │ ├───components │ │ ├───about │ │ ├─── ...

Replacing URLs in Typescript using Ionic 3 and Angular

Currently facing some difficulties getting this simple task to work... Here is the URL format I am dealing with: https://website.com/image{width}x{height}.jpg My objective is to replace the {width} and {height} placeholders. I attempted using this func ...

Tips for successfully importing $lib in SvelteKit without encountering any TypeScript errors

Is there a way to import a $lib into my svelte project without encountering typescript errors in vscode? The project is building and running smoothly. import ThemeSwitch from '$lib/ThemeSwitch/ThemeSwitch.svelte'; The error message says "Canno ...

Using the spread operator in the console.log function is successful, but encountering issues when attempting to assign or return it in a

Currently facing an issue with a spread operator that's really getting on my nerves. Despite searching extensively, I haven't found a solution yet. Whenever I utilize console.log(...val), it displays the data flawlessly without any errors. Howev ...

Is there a way to reset static data in a TypeScript subclass? (or alternative method for managing global data)

I have a particular set of static data that I would like to access through an API using basic logic. Specifically, this data pertains to metadata about Java classes. My approach involved incorporating the API into a few static methods within a class, alon ...

A helpful guide on fetching the Response object within a NestJS GraphQL resolver

Is there a way to pass @Res() into my graphql resolvers and make it work correctly? I tried the following, but it didn't work as expected: @Mutation(() => String) login(@Args('loginInput') loginInput: LoginInput, @Res() res: Response) ...

What is the best way to access a component's data within its method using Vue and Typescript?

Starting a Vue.js project with TypeScript and using single file components instead of class-styled ones has been my goal. However, I have encountered a recurring issue where I get error TS2339 when trying to reference my components' data using the "th ...

issue TS2322: The function returns a type of '() => string' which cannot be assigned to type 'string

I have recently started learning Angular 6. Below is the code I am currently working on: export class DateComponent implements OnInit { currentDate: string = new Date().toDateString; constructor() { } ngOnInit() { } } However, I am encounterin ...

Storing Data Locally in Angular with User Authentication

Using angular8, I encountered an issue where logging in with USER1 credentials, closing the browser, and then attempting to log in with USER2 credentials still logged me in as USER1. While adding code to the app component resolved this problem, I faced an ...

Entering key-value pairs into a dictionary to show correlation

I've been struggling to find a solution for what seems like a simple issue. The problem lies in typing a dictionary with values of different types so that TypeScript can infer the type based on the key. Here is the scenario: type Id = string; inter ...

My Nextjs project is encountering deployment issues with both Netlify and Heroku

Whenever I attempt to deploy my application on Heroku or Netlify, I encounter an ERROR related to an incorrect import path. It's perplexing because the import is accurate and functions properly locally. Log ./pages/_app.tsx:7:27 6:31:19 PM: Type err ...

Could you provide an explanation of the styled() function in TypeScript?

const Flex = styled(Stack, { shouldForwardProp: (prop) => calcShouldForwardProp(prop), })<LayoutProps>(({ center, autoWidth, autoFlex, theme }) => ({ })); This syntax is a bit confusing to me. I understand the functionality of the code, b ...

Exploring Angular 12: utilizing rxjs observables with chained subscriptions for enhanced functionality and robust error handling

Can someone help me with creating a function that I can subscribe to, returning: an observable containing the result if all operations were successful an observable with an empty string in all other scenarios foo(): void { this.uploadImage.subscr ...

Guide on accessing a modal component in Angular?

I have an Edit Button on my component called SearchComponent. When the user clicks this button, it currently redirects them to another component named EditFormComponent using navigateByUrl('url-link'). However, I would like to enhance the user ex ...

Strange visualization using Three.js version R69

Recently, I've been experiencing a strange rendering issue with the latest release of the Three.js library. It seems that there is a lack of depth perception for the torus and sphere in my scene - they appear to be overlapped by the grid, which is not ...

method for transforming a circular grid overlaying a gltf

Is there a way to create a yellow circular mesh that conforms to the geometry of a shirt and covers it completely? My current approach involves using a raycaster to keep the mesh positioned on top of the shirt, but I am struggling to make it "bend" along ...

An issue occurred while attempting to access the `/blog` page in a next.js project

The Challenge: As I work on developing a blog using Next.js and Sanity, I am facing a browser error when trying to navigate to the /blog route. The specific error message reads as follows: ./sanity.js:2:0 Module not found: Can't resolve '@sanity ...

Developing a Typescript "Map" type using numerical enumerations

In my Typescript project, I came across the need to create record types with numeric enums: enum AxisLabel { X = 0, Y = 1 } export const labelLookup: Record<AxisLabel, string> = { [AxisLabel.X]: "X axis", [AxisLabel.Y]: "Y Axis" }; However, I w ...