What is the best way to apply a plane onto a sphere using three.js?

I am currently exploring three.js and facing a challenge in positioning and manipulating a plane object to overlay the surface of a sphere (or any object), mimicking its shape. My goal is to enable movement of the plane on the surface at a later stage.

To achieve this, I have positioned the plane in front of the sphere and iterated through its vertices by casting rays towards the sphere to detect intersections. Despite my attempts to adjust the z position of these vertices based on collision results, I have not been able to achieve the desired outcome. I would greatly appreciate guidance on how to make this work or suggestions for alternative methods.

Here is an example of how I am trying to modify the vertices (with a visible offset of 1 from the sphere's surface):

planeMesh.geometry.vertices[vertexIndex].z = collisionResults[0].distance - 1;

Prior to rendering, I ensure the following settings are in place:

planeMesh.geometry.verticesNeedUpdate = true;
planeMesh.geometry.normalsNeedUpdate = true;

You can view where I am with a fiddle linked below. In my current setup, when casting rays in the z direction, I am unable to detect collisions with the sphere, preventing me from adjusting the plane as intended.

http://jsfiddle.net/stokewoggle/vuezL/

For better visualization, you can rotate the camera around the scene using the left and right arrows (works best in Chrome) to observe the plane's shape. I have made the sphere transparent for improved visibility of the plane.

EDIT: Fiddle has been updated and description mistake corrected.

Answer №1

Apologies for the delayed response, it took me a bit of time to unravel this puzzle. The reason behind the collision issues was as suspected: the planeMesh vertices were localized, resulting in unexpected behavior. Initially, I attempted a solution by applying the worldMatrix similar to stemkoski's approach in his github three.js collision example; however, this did not yield the desired results since the plane lacked z-axis information when initially created as a flat 2D planeMesh.

The breakthrough came when I manually adjusted the z-component of each vertex of the plane. Given your request for the plane to be positioned at z = 201, I iterated through each vertex within a loop and set their z-coordinate to 201 individually. Consequently, all ray start positions aligned globally, and employing a ray direction of (0,0,-1) led to accurate collisions.

var localVertex = planeMesh.geometry.vertices[vertexIndex].clone();
localVertex.z = 201;

To ensure perfect shape conformity in the plane-wrap, instead of relying on (0,0,-1) as the default ray direction, I computed the ray direction manually by calculating the difference between each vertex and the sphere's center position and normalizing the resultant vector. This enhancement should further improve the accuracy of collisionResult intersection points.

var directionVector = new THREE.Vector3();
directionVector.subVectors(sphereMesh.position, localVertex);
directionVector.normalize();
var ray = new THREE.Raycaster(localVertex, directionVector);

For a demonstration, refer to this functional example: http://jsfiddle.net/XRKtJ/2/

The planeMesh now seamlessly conforms to the sphere's surface, akin to a patch or band-aid. :)

I hope this explanation proves useful. Thank you for posing the question on the three.js Github page - stumbling upon it was enlightening. Initially misconstrued as a bug in THREE.Raycaster, the issue boiled down to user error (mine). However, tackling this problem has enriched my understanding of collision code, benefiting my future endeavors in 3D game development. Feel free to explore one of my games at: https://github.com/erichlof/GalaxyQuest3D

Wishing you success! -Erich

Answer №2

Your initial ray starting point may be causing issues due to vertex coordinates being local to the plane. Starting the raycast from inside the sphere can prevent it from making contact with anything.

To test this theory, I adjusted the ray start position and achieved 726 collisions:

var rayStart = new THREE.Vector3(0, 0, 500);
var ray = new THREE.Raycaster(rayStart, new THREE.Vector3(0, 0, -1));

Link to forked jsfiddle: http://jsfiddle.net/H5YSL/

It seems that transforming the vertex coordinates to world coordinates could solve the issue of positioning accurately. This information should be readily available in the documentation and examples provided.

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

Attaching the JSON data to ngModel in Angular 2

I have received a json response containing various fields, including the rewards.rewardName value. I'm trying to figure out how to bind this specific value to [(ngModel)] in Angular 2. [ { "id": 18, "gname": "learning ramayanam", "goalCat ...

Order a portion of a JSON array according to another part of the same array

Having a json array that needs sorting in JavaScript. The EventName field should match the respective Age fields like 01-10 Days and 10-20 Days. [ {Age: "01-10 Days", EventName: "Invoice AP Review", Value: 1, ActiveInvoices: []} ,{Age: "01-10 Days", Even ...

javascript, issues with floating and displaying elements

I am currently working on creating a JavaScript menu that has a click function to smoothly slide up and down. Although the JavaScript code appears to be functioning correctly, it seems that there is some interference with the CSS. Despite attempting vario ...

The checkbox that is checked using prop() will not trigger any events that are linked to the "change" event

When using jQuery's prop() method to check boxes, it does not trigger the listeners attached to the change event. The code I have looks like this: HTML <div> <label> <input type="checkbox" class="ch" />test</label&g ...

Difficulty applying texture to Three.js sides

After creating a mesh by extruding a png image, I used the code reference from . The issue I encountered is that when using a THREE.MeshPhongMaterial with a texture map, the texture only applies to the front and back of the mesh, not the sides. The sides e ...

What is the best way to transfer an array from an Express Server to an AJAX response?

My AJAX request successfully communicates with the server and receives a response that looks like this: [{name: 'example1'}, {name: 'example2'}] The issue arises when the response is passed to the client-side JavaScript code - it is t ...

Retrieve information from a JSON object based on the specified value

Here is the JSON data I am working with: { "sales": [{ "manager": "alberic", "surgeon": "Dr Barry Biggins", "amount": "300", "country": "USA", "percent-seller": "30", "antiquity": "June 2017", "d ...

There are various iterations of html2canvas available

After upgrading html2canvas from v0.5.0 to v1.0.0, a specific function ceased to work on iOS. Therefore, I am interested in utilizing v0.5.0 on iOS and v1.0.0 on other devices. Is there a way to incorporate and switch between both versions of html2canvas ...

What is the best way to convert and update document fields in MongoDB to GeoJSON format using Java?

I have a collection in mongodb that stores information about airports and I need to perform some Geospatial Queries. One example document from this collection looks like this: { "_id" : ObjectId("528e8134556062edda12ffe6"), " ...

Sending a function as a callback to children components in order to update a specific child component

I am currently working on developing a Navbar component that undergoes slight changes when a user logs in through a SignIn component. Here is an overview of how my application is structured: Initially, I have defined a state in the App component where aut ...

What causes AngularJS to generate an error when attempting to construct a URL for the src attribute of an iframe?

Recently, I've been working with AngularJS directives and encountered an issue while trying to use an expression in the src attribute of an iframe. The error message I received referenced a URL that didn't provide much insight: http://errors.ang ...

The cause of Interface A improperly extending Interface B errors in Typescript

Why does extending an interface by adding more properties make it non-assignable to a function accepting the base interface type? Shouldn't the overriding interface always have the properties that the function expects from the Base interface type? Th ...

What are the best practices for creating a contemporary website that functions effectively on IE7?

After creating several websites for my clients, I discovered that they are not functioning well in IE7. Unfortunately, there is still a small percentage of people using IE7. Can anyone suggest a super quick solution to fix this issue? Feel free to recomm ...

What is the correct way to pass a table record value to a jQuery function?

Within my php code, there is this snippet: echo "<td><button id='pausebut_{$record['idTrack']}' name='StopButton' type='Button' value='{$record['PreviewURL']}'>Stop</button> &l ...

Implement a transition effect for the onClick event of a div element

I am looking to create a smoother transition effect when clicking on the section, causing it to expand and display the text underneath. I want to make this transition slower and more seamless. My current attempt at adding a transition to the "active" clas ...

Is there a way to customize the CSS ul menu specifically for the JavaScript autocomplete feature?

I have created a search page with autocomplete for the first textbox, but I noticed that the ul/li CSS classes used for styling the main menu are impacting the JavaScript list. How can I override the menu styling to display a regular list format? Being a ...

What is the best way to monitor parameter changes in a nested route?

I need assistance with managing routes const routes: Routes = [ { path: 'home', component: HomeComponent }, { path: 'explore', component: ExploreComponent, children: [ { path: '', component: ProductListC ...

Retrieve the selected checkbox values and store them in a JavaScript array before sending them in an ajax request

Currently, I am working on a project that involves handling a set of checkboxes (around 50). My goal is to capture the IDs of the checkboxes selected by the user and store them in a JavaScript array. Subsequently, I want to include these checkbox values i ...

What is the appropriate HTTP status code for "item not found" when using RESTful ajax?

Imagine having a single-page web application featuring a list of items. Users can click on an item to view more information about it. The details of each item are loaded asynchronously via an AJAX GET request to the URL http://www.example.com/item/[id], an ...

Achieving accurate JSON output from Elasticsearch's autosuggest feature can be

Running my node.js server involves sending queries to an elasticsearch instance. I have a JSON example of the query's output: { "took": 2, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 ...