Walls that collide in three.js

I am currently developing a game using three.js and despite being new to this field, I have extensively studied collision documentation. To handle collisions between my boat (inside a cube) and the islands (contained in cubes), I implemented raycasting. Here is how I approached solving the issue:

collision2 = false;

    var originPoint = MovingCube.position.clone();
    clearText();
    for (var vertexIndex = 0; vertexIndex < MovingCube.geometry.vertices.length; vertexIndex++)
        {       
            var localVertex = MovingCube.geometry.vertices[vertexIndex].clone();
            var globalVertex = localVertex.applyMatrix4( MovingCube.matrix );
            var directionVector = globalVertex.sub( MovingCube.position );

            var ray = new THREE.Raycaster( originPoint, directionVector.clone().normalize() );
            var collisionResults = ray.intersectObjects( collidableMeshList );
            if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() ) {
                appendText(" Hit "),
                collision2 = true;
            }
}

    if ( keyboard.pressed("W") ){
        obj.translateZ( moveDistance ),
    if (collision2==true){
        obj.translateZ( -moveDistance*4 ),
        }
    }
    if ( keyboard.pressed("S") ){
        obj.translateZ( - moveDistance ),
    if (collision2==true){
        obj.translateZ( moveDistance*4 ),
        }
    }
    if ( keyboard.pressed("A") ){
        obj.rotateOnAxis( new THREE.Vector3(0,1,0), rotateAngle),
    if (collision2==true){
        obj.rotateOnAxis( new THREE.Vector3(0,1,0), -rotateAngle*3),
        }
    }
    if ( keyboard.pressed("D") ){
        obj.rotateOnAxis( new THREE.Vector3(0,1,0), -rotateAngle),
    if (collision2==true){
        obj.rotateOnAxis( new THREE.Vector3(0,1,0), rotateAngle*3),
        }
    }    

To ensure that my ship does not collide with the rays produced by the raycasting, I decided to multiply "moveDistance" and "rotateAngle" by 3. Although this method is mostly effective, there are situations where the ship either gets stuck or penetrates the island. I am considering adjusting the ship's position slightly when a collision occurs, based on the face of the cube it hits. For instance, if the ship collides with the cube's positive X-axis face, I would subtract pixels from the cube's position to move the boat away. I am unsure how to implement this solution effectively. How can I address collision issues with walls without using a physics engine for now? Thanks in advance for any assistance!

https://i.sstatic.net/akiCm.jpg

EDIT:
I am interested in determining which side of the cube (island) the ship collided with. For each face that the ship collides with, I want to move the boat 40 pixels backwards (obj.position = +40). This approach should prevent the boat from entering the cube. I came across an example that I believe could be helpful, but I have yet to fully grasp its implementation.

Here is the cube containing the boat:

var mats2 = [];

    var cubeGeometry = new THREE.CubeGeometry(25,135,121,10,10,10);
    for (var i = 0; i < 6; i ++) {
    mats2.push(new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe:true } ));

}
    MovingCube = new THREE.Mesh( cubeGeometry, mats2 );
    scene.add( MovingCube );
    collidableMeshList0.push(MovingCube);

Answer №1

In my opinion, I have come up with a solid solution.
Whenever a collision occurs, it is possible to determine which face has been impacted by using the .face.normal property. For instance, if the collided face is the one facing the -x axis, the coordinates will be x: -1, y: 0, z: 0. Similarly, if the collided face is the one facing the + x axis, the coordinates will be x: +1, y: 0, z: 0. This same logic applies to the other axes. With this approach, I managed to resolve the issue and prevent the boat from getting stuck in the walls!

var originPoint = MovingCube.position.clone();
clearText();
for (var vertexIndex = 0; vertexIndex < MovingCube.geometry.vertices.length; vertexIndex++)
    {       
        var localVertex = MovingCube.geometry.vertices[vertexIndex].clone();
        var globalVertex = localVertex.applyMatrix4( MovingCube.matrix );
        var directionVector = globalVertex.sub( MovingCube.position );

        var ray = new THREE.Raycaster( originPoint, directionVector.clone().normalize() );
         collisionResults1 = ray.intersectObjects( collidableMeshList );
        if ( collisionResults1.length > 0 && collisionResults1[0].distance < directionVector.length() ) {
            appendText(" Hit "),
            faccia = collisionResults1[0].face.normal;
            if (faccia.x <=-0.9 ){
                obj.position.x = originPoint.x -30,
            }
            if (faccia.x >=0.9 ){
                obj.position.x = originPoint.x +30,
            }
            if (faccia.z <=-0.9 ){,
                obj.position.z = originPoint.z -30,
            }
            if (faccia.z >=0.9 ){
                obj.position.z = originPoint.z +30,
            }

Answer №2

There are countless methods to tackle this issue using raycasts, but one approach that has proven effective for me is creating a simple point mass system. By placing 3 point masses in a triangular formation connected with springs and utilizing a verlet-style simulation to maintain the shape, you can reconstruct the object matrix using the vectors of the triangle. This forms an orthonormal basis that can be plugged into your three.js object. With each frame, you can apply gravitational and buoyancy forces to the point masses, adjusting their positions relative to sea level. Additionally, by raycasting downward from the center of each point mass, you can ensure they maintain a specific distance from the ground height of the height map.

If you're interested, here's a prototype of a similar concept I created a while back: (Use ASWD + Arrow keys to control the chopper)

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

Enhance the efficiency of synchronized horizontal scrolling using React/Redux to boost overall performance

I'm currently working on creating a grid with synchronized horizontal scrolling across different sections (such as a header and multiple table sections below). Each section should scroll together horizontally, maintaining synchronization using a redux ...

What is the best way to create a blurred effect on an image during loading, and then transition to a sharp image once it is fully loaded?

I'm currently working on a project where I want the images to display as a blurred preview initially, and then become clear once fully loaded. This is similar to the feature seen on Instagram, where the app shows a blurred image before displaying the ...

What exactly does the next() function do in NodeJS/SailsJS?

I recently came across a SailsJS tutorial where the next(); function was used for user authentication. However, I'm still unsure of its exact purpose. Can anyone provide clarification on this? ...

Having trouble adding a div in React due to the error "Objects are not allowed as a React child"?

While I am rendering the data and displaying it between divs, I keep getting this error: Objects are not valid as a React child (found: Wed Dec 09 1998 00:00:00 GMT+0530 (India Standard Time)). If you meant to render a collection of children, use an ...

Delete the final comma in a JSON file using JavaScript so that it can be utilized by a Vue application

Using Axios in my Vue app, I am consuming a JSON file. The field "country" contains trailing commas which are creating issues. Here is the structure of the JSON: "country": "spain,france," .... "country": " ...

A guide to securely retrieving data from the Hono API endpoint using type safety within a Next.js application

Currently, I am using Hono as my API endpoint with Bun. Now, I am working on a new app with Next.js and I want to ensure type safety when fetching data from my API. I believe I can accomplish this through RPC. However, I am unable to locate AppType mention ...

Interactive Thumbnail Previews

There seems to be an issue with the thumbnail links on my page. The leftmost and rightmost links work fine, but the middle ones are not functioning properly when clicked. The PHP code used to generate these links is the same for all of them, so it's p ...

Can we expect React's useState to wait before executing subsequent logic, or will it immediately update the state and trigger a re-render

I have a specific scenario in my code where I am using the useState setter function in React to update a value on line 5. Everything seems to be functioning well without any errors, but I'm curious about something. Since setState updates the state and ...

Please provide the necessary environment variable

While developing my ReactJS app, I have been pondering on the process of specifying the necessary environment variables for the application. Where should I define that "my app requires a DATABASE_URL variable with a string formatted like this, and a PORT v ...

The null error occurs when rendering with React's state array

When I try to call an API that emits JSON, I am encountering an issue. I call the promise API function in componentDidMount, set the state, and then call it in the render method, but it always returns a null error. I need assistance, please. Interface fo ...

Exploring the intricacies of Node-Craigslist syntax

Greetings! I am currently utilizing the node-craigslist package found at https://github.com/brozeph/node-craigslist and I am in need of assistance with some syntax related to the details method. The documentation provides the following example: client . ...

Distinguishing between a video or image when uploading files in JavaScript

I've been researching whether JavaScript can determine if a file is a video or an image. However, most of the information I found only shows how to accept these types using the input tag. What I really need is for JS to identify the file type and the ...

Input the chosen icon list values into a designated box

As a beginner in the world of Javascript, I am venturing into creating a password generator that involves using icons. The concept is simple - by clicking on any number of icons from a list, the corresponding hex code will be displayed in an input box. The ...

Unable to transmit a collection of JavaScript objects in a node.js environment

Below is the code snippet I am currently working with: app.get('/posts',function(req,res){ console.log(posts); res.send(posts); res.send(200); }); I am using the following approach to retrieve and display an array of JavaScript objects (posts ...

Tips for conducting a simultaneous test on several devices

Struggling to execute a single test script on multiple devices, regardless of efforts. There is one test apk and script obtained from a website as a sample. The script locates a textbox in the application, enters "Hello World!" into it, then completes the ...

Load different fonts dynamically based on environment configuration

My question is regarding loading multiple fonts from a font.css file in React. I need to make the font path dynamic based on the environment variables. Can anyone suggest a solution for achieving this? I've attempted to create a font.scss file and de ...

Learn how to utilize the Page props in the getServerSideProps method with Next.js

I have passed some properties to the _app page. <PageWrapper> <Component someProps={someProps} /> <GlobalCSS /> </PageWrapper> Can these props be accessed in the getServerSideProps method on each individual Page? export const g ...

Issue with Material UI tool tip not closing upon clicking on an element is persistent

Check out this link for a material UI tooltip demo I have been experimenting with the material UI tooltip in the provided link. The tooltip pops up when hovering over the button, but it doesn't disappear when clicking on the button. Is this the defau ...

Issue found: React-Redux action is not being dispatched

I'm currently working on setting up Google authentication in my React Next.js application. The process involves sending the access token to my backend, where it is validated before a new token is returned in the header for accessing protected resource ...

"Manipulate the contents of a state array by adding or removing items at specific indices in React, alongside other array

I am facing a challenge in removing items from an array that have been added to a state array in React. While I can successfully add new items, the removal process is not working as expected. The current remove function removes all elements, but I only wan ...