Detecting collisions and halting/moving again in THREE.js

I am facing an issue with moving a ball inside a rounded ground using smartphone orientation. The ball stops at the edge when it reaches there, but I'm having trouble getting it to move again if the orientation points in the opposite direction. Here is a link to the working sample:

Sample Code

Check out the code snippet below;

export const LIGHT = () => {
  const light = new THREE.SpotLight(0xffffff, 1);
  light.position.set(100, 1, 0);
  light.castShadow = true;
  light.position.set(0, 0, 35);

  return light;
};

export const BALL = () => {
  const geometry = new THREE.SphereGeometry(3, 10, 10);
  const material = new THREE.MeshLambertMaterial({ color: "#f1c40f" });
  const mesh = new THREE.Mesh(geometry, material);

  mesh.castShadow = true;
  mesh.receiveShadow = false;
  return mesh;
};

export const BALL_BOUNDING = (sphere) => {
  return new THREE.Sphere(sphere.position, 3);
};

export const GROUND = () => {
  const geometry = new THREE.CircleGeometry(21, 21, 0);
  const material = new THREE.MeshPhongMaterial({
    color: "#bdc3c7"
    // transparent: true,
    // opacity: 0,
  });

  const mesh = new THREE.Mesh(geometry, material);

  mesh.castShadow = true;
  mesh.position.z = 1;
  return mesh;
};

export const GROUND_BOUNDING = (ground) => {
  const geometry = new THREE.SphereGeometry(13, 8, 8);
  const material = new THREE.MeshLambertMaterial({
    color: "#FFF"
  });

  const mesh = new THREE.Mesh(geometry, material);
  // expanding bounding XYZ
  return new THREE.Sphere(mesh.position, 18);
};

const ww = window.innerWidth;
const wh = window.innerHeight;
const renderer = new THREE.WebGLRenderer({ canvas: canvas.value, alpha: true });
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(35, ww / wh, 0.1, 1000);
const light = _light()
const ball = BALL()
const ball_bounding = BALL_BOUNDING(ball)
const ground = GROUND()
const ground_bounding = GROUND_BOUNDING(ground)

renderer.shadowMap.enabled = true;
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.z = 120;

scene.add(ball)
scene.add(ground)
scene.add(light)

function animate() {
  requestAnimationFrame(animate)
  render()
}

function render() {
  const x = posX.value / 20
  const y = posY.value / 20

  if (ball.geometry.boundingSphere !== null) {
    ball.geometry.computeBoundingSphere()
    ball_bounding.copy(ball.geometry.boundingSphere).applyMatrix4(ball.matrixWorld)
  }

  if (ground_bounding.intersectsSphere(ball_bounding)) {
    
    ball.position.x += x;
    ball.position.y -= y;
  }

  renderer.render(scene, camera)

}

animate()

Answer №1

Consider the precise moment when the ball exits the intersection area, indicated by the final instance when

ground_bounding.intersectsSphere(ball_bounding)
evaluates to true. What transpires at this crucial juncture? Take a moment to reflect on the following:

  1. ground_bounding.intersectsSphere(ball_bounding)
    yields true
  2. This instills confidence in moving the ball using ball.position.x += x
  3. In the subsequent iteration of animate(),
    ground_bounding.intersectsSphere(ball_bounding)
    switches to false
  4. By now, the ball has been shifted (during the prior cycle) to a location where
    ground_bounding.intersectsSphere(ball_bounding)
    consistently returns false, leading to an eternal standstill situation.

The blunder occurs in step 2; resisting the urge to relocate the ball despite the affirmation in step 1 (true). Moving it prematurely results in an inevitable false outcome in the subsequent round, trapping it indefinitely.

The remedy involves crafting a replica of ball_bounding, maneuvering the duplicate first, and running an intersection assessment against it. If the dummy remains within the intersection post-movement, it deems safe to proceed with relocating the actual ball.

const dummy = ball_bounding.clone();
dummy.center.x += x;
dummy.center.y -= y;
if (ground_bounding.intersectsSphere(dummy)) {
    ball.position.x += x;
    ball.position.y -= y;
}

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 Express Generator is having trouble detecting the routes within the users file when using app.use('/login', users)

Having used the express generator, I am facing confusion regarding why I cannot utilize the users.js routes file for my login routes. I have created the POST route below, and when I keep it in app.js, everything works smoothly. However, if I attempt to mo ...

Tips for creating a binding between an HTTP service and a variable in AngularJS that adjusts when the server data is modified

Using an http get request in angular to extract data into an object with the users currently connected to my app requires refreshing the information every time for binding to the scope. To achieve this, I implemented a method to refresh the data from the a ...

Having trouble accessing my API through localhost with NextJS

I'm currently working on an app that involves fetching data from my own API. The goal is to retrieve user-specific information and use it within the app. However, I've encountered a roadblock with CORS headers and I'm unsure of how to procee ...

Preventing the horizontal scrolling of my application's sticky header

My application layout can be viewed here: http://jsfiddle.net/rhgyLjvx/ The layout includes a main header (red), sticky section header (dark blue), fixed footer (grey), and fixed left side nav (green). The application should have full scroll bars on both ...

Tips for fetching the chosen choices from a drop-down menu and then performing multiplication with input fields

Hey there! I'm attempting to create a system that checks if the user has selected an item from a dropdown menu, and based on their selection, perform a multiplication operation with three different variables and display the result. For instance, if " ...

Steps to retrieve component values within the same component

I am currently working on developing a React component where I need to manage the checked status of checkboxes and select options when a change event occurs. However, I am unsure of how to retrieve the value of the checked checkboxes and update the state a ...

I'm baffled by the constant undefined status of the factory in AngularJS

I have encountered an issue where I defined a factory that makes a get request, but when I inject it into a controller, it always throws an undefined error. Below is the code for the factory: (function() { 'use strict'; var app = angul ...

Randomize the elements of an array to the fullest extent possible

My array looks like this: [0,2,3] The different permutations of this array are: [0,2,3], [2,3,0], [3,0,2], [3,2,0], [0,3,2], [2,0,3] How can I generate these combinations? Currently, my only idea is: n = maximum number of possible combinations, coms = ...

The event listener for "popstate" is not triggering on the .document

Struggling with implementing a popstate event handler on an Ajax page using the .document object: document.addEventListener("popstate", myPopState); Despite my efforts, this handler never seems to fire. I was hoping that after reloading the page, the po ...

Putting off the execution of a setTimeout()

I'm encountering difficulties with a piece of asynchronous JavaScript code designed to fetch values from a database using ajax. The objective is to reload a page once a list has been populated. To achieve this, I attempted to embed the following code ...

Automatically generate the first user on the Parse Server system

Is it feasible to programmatically create a User on Parse server without the need for sign up? More information can be found at https://github.com/parse-community/parse-server We attempted this using cloud code. var user = Parse.User(); user.setUserna ...

The Vue.js application appears to be functioning properly with no error messages, however

Currently, I am in the process of learning Vue. Recently, I came across a helpful tutorial that I've been trying to implement using the standard vue-cli webpack template by splitting it into single file components. Despite not encountering any errors ...

Control the frequency of server requests within a set limit

Currently, I am utilizing the request-sync library to fetch data from a specific site's API. This is how my code looks: let req = request('GET', LINK, { 'headers': { 'Accept' ...

Is it possible to erase the text area in MarkItUp?

I'm currently facing an issue with clearing my MarkItUp editor. I've successfully managed to insert text using the $.markItUp function, but I'm struggling to clear the text box afterward. I attempted to use replaceWith: "", however, I encoun ...

Scripts fail to load randomly due to RequireJs

I have obtained an HTML template from a platform like Themeforest, which came with numerous jQuery plugins and a main.js file where all these plugins are initialized and configured for the template. I am now in the process of developing an AngularJS applic ...

What could be causing the data in getServerSideProps to be altered?

After fetching data from an API and passing it to index.js using getServerSideProps, I noticed that the prop array is initially in order by rank [1, 2, 3, etc]. Here's an example of the data: [ {rank: 1, price: 123}, {rank: 2, price: 1958}, {rank: ...

Modify the background color of a div by selecting a hex code from a dropdown menu

Is there a way to utilize jQuery in order to alter the background of a <div> by choosing the HEX code from a separate dropdown menu? HTML <select id="target"> <option value="#c2c2c2">Grey</option> <option value="blue">Bl ...

Sequelize - Leveraging Associations in Where Clauses

Within sequelize, my setup includes boards and users with a many-to-many association structured like this: User.hasMany(Board, {through: BoardUsers}); Board.hasMany(User, {through:BoardUsers}); I'm trying to figure out if there's a way to use a ...

Having problems getting my fixed header to work on my datatable. What could be the

Struggling to make my data table Thead sticky? I attempted using position: fixed;, top: 0; with CSS but it only worked in Firefox, not Chrome, Edge, or Opera. Here is an excerpt of my Ajax code: "stateSave": false, "orderCellsTop&quo ...