Determining the rotation direction following an object collision using three.js

In my three.js demo, collision detection is achieved using a Raycaster that extends from the front of the camera. The movement of the camera is restricted to follow its facing direction, although the mouse controls allow for steering in different directions.

var ray = new THREE.Raycaster(camera.position, cameraDirectionVector);
var collisionResults = ray.intersectObjects(scene.children);
if (collisionResults.length > 0) {
    if (collisionResults[0].distance < 0.15) {
        var crossAxis = new THREE.Vector3(0, 0, 1);
        crossAxis.crossVectors(cameraDirectionVector, collisionResults[0].face.normal);
        camera.rotateOnAxis(crossAxis, 0.2); // this second parameter needs correct calculation
    }
}

When a collision occurs, I am utilizing the cross product of the collision face normal and the camera's travel direction as the rotation axis. This method aims to rotate the camera away from the point of impact effectively.

To determine the rotation direction around this axis accurately, I need to calculate it based on the orientation of the crossAxis Vector3 relative to the face normal and camera travel direction. The resulting value may have to be positive or negative depending on these factors.

Note that this collision detection system is designed to be basic and has limitations due to the player's forward-only movement capability.

Is there a way to establish whether the camera should rotate clockwise or counterclockwise around the cross product axis? Once this calculation is correctly determined, I can enhance the collision effects, such as reducing the rotation gradually over a specified number of frames.

Any assistance would be highly valued!

Answer №1

Perhaps I didn't fully grasp your inquiry, but the orientation of the camera approaching the collision face normal can alter the direction of the cross product and subsequently affect the rotation direction.

In this scenario, visualize the blue arrow as the collision face normal, the red arrow as the camera's direction, and the green arrow as the cross product between them (red X blue). As the camera approaches the face normal from different angles, it generates varying cross products each time.

Observing closely, whenever the angle between the red and blue arrows exceeds 180 degrees, the rotation direction of the white sphere changes. This occurs because the green arrow (cross product of red and blue) serves as the axis of rotation; when this axis shifts, the rotation direction changes following the right hand rule.

Hence, there is no need to prefix the second parameter with a sign since the rotation direction is inherent in the (cross product) vector used as the rotation axis.

If you are seeking an approach where the camera always rotates away from the collision normal, have you tried incorporating a negative value as the second parameter?

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);

var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var origin = new THREE.Vector3(0, 0, 0)

var a = new THREE.Vector3(1, 0, 0);
var arrowHelperA = new THREE.ArrowHelper(a, origin, 1, 0xff0000);
scene.add(arrowHelperA);

var b = new THREE.Vector3(0, 1, 0);
var arrowHelperB = new THREE.ArrowHelper(b, origin, 1, 0x0000ff);
scene.add(arrowHelperB);

var crossAB = new THREE.Vector3().crossVectors(a, b);
var arrowHelperCrossAB = new THREE.ArrowHelper(crossAB, origin, 1, 0x00ff00);
scene.add(arrowHelperCrossAB);

var geometry = new THREE.SphereGeometry(0.02 ,32, 32);
var material = new THREE.MeshBasicMaterial({color: 0xffffff});
var sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);
sphere.position.copy(crossAB);
sphere.position.x = 0.3;

camera.position.z = 2;
camera.position.x = 2;
camera.position.y = 2;

camera.lookAt(origin);

var animate = function() {
  requestAnimationFrame(animate);
  
  a.applyAxisAngle(new THREE.Vector3(0, 0, 1), 0.01);
  arrowHelperA.setDirection(a);
  
  crossAB = new THREE.Vector3().crossVectors(a, b);
  arrowHelperCrossAB.setDirection(crossAB);
  arrowHelperCrossAB.setLength(crossAB.length())
 
  sphere.position.z = crossAB.z;
  sphere.position.applyAxisAngle(crossAB.normalize(), .1);
  
  renderer.render(scene,camera);
};

animate();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/86/three.min.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

Using useState props in React Native navigation screens with React Navigation

I'm currently working on my first React Native app with react navigation after previously having a background in web react development. In the past, I typically used useState for managing state. For instance, rendering a list of components based on d ...

Receiving encoded characters in the response

URL: I have encountered an issue where I am trying to retrieve the PDF file from the URL above using code. In tools like Postman or Insomnia, I am able to see the output as expected in PDF format. However, when I attempt it with code, I am receiving rando ...

How can I pass a specific value, rather than the entire array, in a ReactJS dropdown menu?

I am facing a problem where the entire array is being passed as an argument when I call onchange after getting correct values in the dropdown. Instead of only receiving the selected value, e contains the whole array. Here is the code snippet that demonst ...

Updating the route path for version control in Express.js

When working with an ExpressJS application, the following paths should be considered: GET /v1/users/detail GET /v2/users/detail The corresponding routers are as follows: // v1/users.js router.get('/v1/users/detail', (req, res, next) => res. ...

You have encountered an error: Uncaught TypeError - the function (intermediate value).findOne is not defined

Encountering an error when attempting to call the getStocks function from a Vue component. smileCalc: import User from "../models/user.js"; let userID = "62e6d96a51186be0ad2864f9"; let userStocks; async function getUserStocks() { ...

Execute a function prior to making a synchronous call

Seeking guidance on a complex issue that I have encountered. In my code, I am dealing with a synchronous AJAX call and need to execute a function before this particular call is made. The function in question is a simple one: $.blockUI(); This function ...

When I try to run "npm start" with node-webkit, it seems like the script specified in my package.json manifest file is not being

After running npm start in the terminal, I encountered the following error message: PS C:\Users\finsa\OneDrive\Documents\UNI\Web Development\NS_Music_App> npm start > <a href="/cdn-cgi/l/email-protection" class= ...

Why won't my setTimeout function work?

I'm having trouble working with the setTimeout function, as it doesn't seem to be functioning properly. First and foremost, Player.prototype.playByUrl = function (url) { this.object.data = url; return this.play(); } The co ...

Surprising Vercel Production Problem: Functions in Development Environment but Fails in Production Even After Reverting to a Functional Commit

In the development environment, everything runs smoothly without any issues. However, when the application is deployed to production, errors start cropping up. What's puzzling is that even after reverting to a previous commit where the production was ...

Seamless animation when collapsing element using angular and css exclusively

I am attempting to incorporate a collapsible feature into my application. Rather than relying on external libraries like jQuery, I want to exclusively utilize Angular. For demonstration purposes, I have created a very basic example here: http://jsfiddle.n ...

Firebase Hosting is not compatible with Express session

After setting up my code as shown below, I noticed that sessions are being persisted and the page is able to count the number of visits. app.set('trust proxy', true) // The documentation specifies '1' instead of 'true' app.u ...

Can you explain the significance of `Component<Props>` in React Native?

Recently, I started a new react-native project and noticed a change in the component syntax. It now reads export default class WelcomeScreen extends Component<Props>, which is different from what it used to be, export default class WelcomeScreen exte ...

Attempting to create a dynamic dropdown menu with animated effects triggered by a key press

I've been attempting to construct a menu that initially appears as a small icon in the corner. Upon pressing a key (currently set to click), the checkbox is activated, initiating the animation. Most of the menu and animation are functional at this po ...

Chrome and FireFox Encounter Ajax Functionality Issues

This script that I have created works flawlessly on Internet Explorer! However, it encounters a few issues when used on Chrome and Firefox. Specifically, it only functions correctly for the first action performed, but fails to do so for subsequent actions. ...

When using JQuery's :first selector, it actually chooses the second element instead of the first

I'm facing an issue with a JQuery script that makes an AJAX request to the following URL https://djjohal.video/video/671/index.html#gsc.tab=0, which holds information about a video song. My goal is to extract and retrieve all the details from the HTM ...

Incorporate distinct items into an array using reactjs

I'm facing an issue where clicking on a certain element multiple times adds it to my array multiple times. I need help in figuring out how to add only unique elements to the array. Can anyone offer some guidance? Thank you in advance. const handleCli ...

The menu was intended to be hidden when the mouse is moved away, but it actually hides

I'm facing an issue with my button and menu functionality. Even though I have coded the menu to hide itself when the mouse leaves, it hides before the mouse even goes over it. Any suggestions on how to resolve this? function showMenu() { var menu ...

Retrieving data from the <script> tag and transferring it to the t-esc tag within Odoo 12

After attempting to retrieve the current coordinates of a location in Odoo, I successfully obtained longitude and latitude data through an alert generated by the following code: <button onclick="getLocation()">Try It</button> ...

What are some ways to direct users from one page to another without relying on server-side programming?

Is there a way to create a redirect page using jQuery or JavaScript? What is the process of writing client-side scripting code to redirect the browser from one page (page1) to another page (page n)? ...

Create a separate server session specifically for handling an ajax request?

Currently, I am working with a collection of PHP server-side scripts that manage user session state by utilizing PHP sessions extensively for authenticated users. For the client side within a mobile application and using Jquery ajax, I am striving to esta ...