Creating several light beams from a rotated structure

My current challenge involves shooting multiple rays from a rotating mesh in various directions targeting points on a circle divided by the number of rays.

To assist with debugging, I have added ArrowHelpers for each ray with a goal for the arrows to turn red upon hitting something and white if not. Additionally, the length of the arrows changes based on the distance to the intersected object; remaining at the ray's max length (far) when not intersecting.

However, I am facing a problem where every ray continues to check the same forward direction of the rotating mesh. I suspect I need to determine a formula to calculate a new normalized vector based on the current rotation of the object. Despite trying approaches like object3D.localToGlobal, Vector3.applyQuaternion, my math skills seem to be inadequate.

For reference, the code sandbox can be accessed at: https://codesandbox.io/s/raycast-issue-bch05b

Raycasting code:

import {  RefObject } from "react";
import * as THREE from "three";
import React from "react";
import { useFrame, useThree } from "@react-three/fiber";

export type RayCastResult = {
  hit: boolean;
  angle: number;
  direction: THREE.Vector3;
  distance: number;
};

export const useRaycasts = ({
  count = 4,
  near = 1,
  far = 10,
  obj
}: {
  count?: number;
  near?: number;
  far?: number;
  obj: RefObject<THREE.Mesh>;
}): { rays: RayCastResult[] } => {
  const rays = React.useMemo(() => {
    const rays: RayCastResult[] = [];
    let angle = 0;
    const step = (2 * Math.PI) / count;

    for (let i = 0; i < count; i++) {
      rays.push({
        hit: false,
        angle: angle,
        direction: new THREE.Vector3(
          Math.cos(angle),
          0,
          Math.sin(angle)
        ).normalize(),
        distance: 10
      });
      angle += step;
    }

    return rays;
  }, [count]);

  const pos = React.useMemo(() => new THREE.Vector3(), []);
  const dir = React.useMemo(() => new THREE.Vector3(), []);

  const { scene, raycaster } = useThree();

  useFrame(() => {
    if (!obj.current) return;

    obj.current.getWorldDirection(dir);
    obj.current.getWorldPosition(pos);

    rays.forEach((direction, i) => {
      if (!obj.current) return;
      raycaster.set(
        pos,
        dir
          .applyAxisAngle(rays[0].direction, obj.current?.rotation.y)
          .normalize()
      );

      raycaster.near = near;
      raycaster.far = far;

      const intersects = raycaster.intersectObjects(scene.children);

      // ONLY check first object
      if (intersects.length) {
        rays[i].hit = true;
        rays[i].distance = intersects[0].distance;
      } else {
        rays[i].hit = false;
        rays[i].distance = raycaster.far;
      }
    });
  });

  return { rays };
};


Answer №1

Sharing the solution to my own query, hoping it proves helpful to someone in the future...

Turns out my original approach was correct, and I stumbled upon the answer in another thread on Stack Overflow, where the solution was within the question itself!

The key was to utilize a THREE.Matrix4 class to replicate the rotation of the mesh that was rotating. This rotation matrix should then be applied to the direction of the ray.

To summarize:

// create a Matrix4 instance (only needs to be done once for efficiency)
const matrix = useMemo(() => new THREE.Matrix4(), []);
// Later within the loop:
// retrieve the current position of the object
obj.current.getWorldPosition(pos);
// copy the object's rotation matrix to our matrix
matrix.extractRotation(obj.current.matrix);
// apply the rotation to the ray's direction
raycaster.set(pos, dir.copy(rays[i].direction).applyMatrix4(matrix));

Take a look at the updated sandbox version

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

The function argument does not have the property 'id'

I created a function that authorizes a user, which can return either a User object or a ResponseError Here is my function: async loginUser ({ commit }, data) { try { const user = await loginUser(data) commit('setUser', user) ...

Having trouble accessing Vuex's getter property within a computed property

Can you help me troubleshoot an issue? When I call a getter inside a computed property, it is giving me the following error message: TS2339: Property 'dictionary' does not exist on type 'CreateComponentPublicInstance{}, {}, {}, {}, {}, Com ...

Tips for displaying field options after typing parentheses in TypeScript in Visual Studio Code

Whenever the letter "b" is typed, the suggestion of "bar" appears. However, I would prefer if the suggestions show up immediately after typing the brackets. https://i.stack.imgur.com/OFTO4.png ...

Error message: "Lazy-loaded modules encounter a TypeError stating that '' is not a function when accessed through NGINX."

Hey, I've got some distribution files for you to check out: AOT-enabled dist with Lazy Modules No AOT Lazy Modules dist AOT without Lazy Modules dist Here's what's been going on: When served locally with webpack-dev-server or live-serve ...

Error code -8 occurred while executing the yarn dev command, unable to identify the issue

I'm facing an issue with my development script that is structured like this: "scripts": { "dev": "./test.sh", }, Upon running the 'yarn dev' command, I encounter the following error message: Internal Error: ...

Angular2's asynchronous data binding is still lagging even after the data has been successfully loaded

I have integrated Firebase with Angular2 to retrieve an object. import { Component, OnInit } from '@angular/core'; import { AngularFire, FirebaseObjectObservable } from 'angularfire2'; import { ActivatedRoute, Params } from '@angu ...

Place content following a three.js display created within a <div id="mainWindow">

Recently, I created a small Three.js animation and embedded it in my HTML page like this: <div id="mainWindow" class="popup_block"> <!-- JavaScript for simulation --> <script src="../temp/webgl-debug.js"></script> <scri ...

Managing multiple Sequelize DB connections in NestJS: A guide

I recently came across the example in the NestJS documentation regarding setting up a Sequelize DB connection. I'm curious about how to connect to multiple databases using Sequelize and TypeScript with NestJS. Can anyone provide guidance on this? ...

Having trouble with clearInterval in my Angular code

After all files have finished running, the array this.currentlyRunning is emptied and its length becomes zero. if(numberOfFiles === 0) { clearInterval(this.repeat); } I conducted a test using console.log and found that even though ...

I'm experiencing issues with camera rotation being lost when I implement OrbitControls in my three

I'm in the process of developing a web application that incorporates 3D buildings as models. My goal is to implement a button that positions the camera in an ideal location for viewing the model, but I've encountered issues with manual rotation r ...

Having trouble adjusting the appearance of the dropdown menu in Angular Material's Select component

I've been attempting to adjust the style of the overlay panel within an Angular Material's MdSelect component in order to change the default max-width property of 280px. I have tried various methods, such as using '!important' to overr ...

Hiding a specific tag with vanilla JavaScript based on its content

I am facing a challenge with my code that is supposed to hide div elements containing a specific word along with additional text. I have tried multiple solutions but none seem to work effectively. Any assistance on how to hide divs properly will be greatl ...

I am having trouble establishing a connection between two containers on Heroku

My web application is built using Node.js and MongoDB. After containerizing it with Docker, everything worked fine locally. However, when I tried to deploy it to production, I encountered an issue where the backend could not establish a connection with the ...

Utilizing external imports in webpack (dynamic importing at runtime)

This is a unique thought that crossed my mind today, and after not finding much information on it, I decided to share some unusual cases and how I personally resolved them. If you have a better solution, please feel free to comment, but in the meantime, th ...

Encountering an issue when trying to upload numerous base64 images to Cloudinary through Node.js and receiving an error with code -4064, specifically 'ENAMETOOLONG'

I'm encountering an issue with base64 URLs when trying to upload multiple images to Cloudinary. When I send only one image, it gets uploaded correctly, but when sending multiple images, I receive an error 'ENAMETOOLONG' with error number 406 ...

What is the method for retrieving an attribute's value from an object that does not have key-value pairs?

My current project involves working with dynamoose and running a query that produces the following output: [ Document { cost: 100 }, lastKey: undefined, count: 1, queriedCount: undefined, timesQueried: 1 ] When I use typeof(output), it returns O ...

Instructions on invoking a function from another Material UI TypeScript component using React

In this scenario, we have two main components - the Drawer and the AppBar. The AppBar contains a menu button that is supposed to trigger an event opening the Drawer. However, implementing this functionality has proven challenging. I attempted to use the li ...

What is the best way to access an optional field in Typescript without causing errors?

Is there a way to dereference an optional field from an interface in the following scenario? interface Sample { key1?: Array<Obj1> } interface Obj1 { a?: Obj2; } interface Obj2 { b?: string; } const a: Sample["key1"][number][" ...

The distortion of Blender animation becomes apparent once it is imported into three.js

I've been working on a project where I'm incorporating animations into a scene using a combination of blender and three.js. It took me several hours of trial and error to finally get the model and animation successfully imported into three.js. I ...

Exploring Relative Rotations in Three.js

I currently have a scenario where I have a THREE.Scene containing two meshes, namely meshA and meshB. Both of these meshes have been rotated differently. My objective is to take meshB out of the scene and attach it as a child of meshA, while maintaining it ...