Updating the position attribute of a mesh in Three.js using boxGeometry

I am currently working on a project that involves resizing a cube by clicking and dragging its faces.

My approach is to update the position attribute on the buffer geometry object, and then either recreate the mesh or set the needsUpdate flag to let it update itself. However, so far, none of these options have been successful for me. Here is my latest attempt:

  this.boxGeo = new THREE.BoxGeometry(2,2,2)
  this.boxMesh = new THREE.Mesh(this.boxGeo, this.boxMaterial)    

...

  // let disp = the amount we want to move the face

  // vertex indices
  let indices = this.planes[index].indices

  // creating a new array for the position attribute
  let positions = new Float32Array(8 * 3)

  // looping through the 8 vertices
  for (let i=0; i < 8; i++) {
    if(!indices.includes(i) || disp === 0) {
      positions[i * 3]     = this.boxGeo.vertices[i].x
      positions[i * 3 + 1] = this.boxGeo.vertices[i].y
      positions[i * 3 + 2] = this.boxGeo.vertices[i].z
    } else {
      // modifying vertices
      let d = new THREE.Vector3(disp, disp, disp).multiply(plane.normal)
      positions[i * 3]     = this.boxGeo.vertices[i].x + d.x
      positions[i * 3 + 1] = this.boxGeo.vertices[i].y + d.y
      positions[i * 3 + 2] = this.boxGeo.vertices[i].z + d.z
    } 
  }
  // updating geometry
  this.boxMesh.geometry._bufferGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))

I have explored various methods, including consulting the documentation mentioned here:

Any assistance or guidance on this matter would be greatly appreciated!

EDIT: Addressing the comments below, I am analyzing my ...attribute.position.array more closely and it seems that each face lists all its vertices, which restricts my ability to access or set them as previously. Any suggestions on relevant documentation I should refer to? Is there a simpler way to accomplish this task?

As per @Murgen87's suggestion, the following code successfully updates the position attribute. It appears that the BoxGeometry primitive does not utilize indexed faces, so I am now considering scaling or translating the box instead.

let positions = 
      this.boxMesh.geometry._bufferGeometry.getAttribute('position')

 // this loop doesn't pick the right positions for my use case 
 faces.map((f, i) => {
    positions.array[f * 6 + i * 3]     += displacement.x
    positions.array[f * 6 + i * 3 + 1] += displacement.y
    positions.array[f * 6 + i * 3 + 1] += displacement.z
  })

  positions.needsUpdate = true;

My final question pertains to why I cannot execute the following:

box.geometry.vertices.multiply(displacement)
box.geometry.verticesNeedsUpdate = true

... And through this inquiry, I have arrived at the solution to my own question!

Answer №1

To simplify this process, follow these steps:

  this.boxMesh.geometry.vertices.map((v,i) => {
    if(!planeObj.indices.includes(i)) return
    this.boxMesh.geometry.vertices[i].add(displacement)
  })
  this.boxMesh.geometry.verticesNeedUpdate = true

A recommended method for updating the position attribute is as follows:

  let positions = 
      this.boxMesh.geometry._bufferGeometry.getAttribute('position')
  planeObj.faces.map((f, i) => {
    positions.array[f * 6 + i * 3]     += displacement.x
    positions.array[f * 6 + i * 3 + 1] += displacement.y
    positions.array[f * 6 + i * 3 + 1] += displacement.z
  })
  positions.needsUpdate = true

Keep in mind that the loop above may not target the correct elements in the positions.array; it simply provides guidance on updating when necessary.

Appreciate the assistance!

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

Select component experiencing issue with Material Ui label breaking

I've been working on implementing a select component, which is new to me. However, I'm encountering an issue with my MUI-select component. The label of the select element is no longer syncing properly with the select component itself as shown in ...

Froala Editor: Innovative external toolbar that pops up when the button is clicked

In our project, we are implementing the latest version of Froala and aim to configure it so that the toolbar is activated by a separate external button, similar to Gmail where the editor initially does not display a toolbar. I attempted to modify the &apo ...

Having trouble accessing the information stored in the Firebase Database?

As a newcomer to Firebase and JS, I am attempting to showcase user information on a webpage that is stored within the Firebase database. The data format resembles the image linked here I have written this Javascript code based on various tutorials. Howev ...

Vue js has a feature that enables users to input numbers with precision up to two decimal places

Currently facing an issue where I need to restrict input to no more than 2 decimal places. I came across a solution in a thread on Stack Overflow which addresses this using jQuery: JQuery allow only two numbers after decimal point. However, I am looking ...

What is the best way to navigate through a webpage to find a specific folder and show its contents on the page?

My goal is to design a webpage where users can browse their computer for a specific folder, select it, and have its content displayed on the webpage. I am fairly new to creating pages, but I want to develop a platform where you can easily find and view f ...

Use Protractor to simulate Loss Connection by clearing LocalStorage in a Spec

Currently, I am utilizing the code window.localStorage.removeItem("name of localStorage variable you want to remove"); to eliminate two distinct localStorage Keys within a particular specification, and it is successfully removing them. Afterwards, I proce ...

Uncovering unseen glitches while coding in Vue.js

After changing the page, I noticed that the errors from the form are still visible. Is there a way to make them disappear when navigating away and only show up if I return to the page? Here are the errors I am encountering: <template> <b-form @ ...

What methods can I use to locate the datetime format within an HTML document using JavaScript?

I am working on a page where I need to locate and convert all datetime values. Specifically, I am looking to identify Hijri datetime values and convert them to standard datetimes using JavaScript. Could someone please advise me on how to locate datetime ...

Is it possible to use a += operator with attr() and val() functions in JavaScript?

Ever since I switched to jQuery, my development process has significantly sped up. However, there is one task that has become a bit more time-consuming: appending a string to an attribute or value. For instance, if you wanted to add a letter to the value ...

Three.js - implementing a billboard effect that preserves orientation through camera pans

My situation involves a plane geometry that always faces the camera using the following line of code in the update loop: plane.lookAt(camera.position); While I am utilizing OrbitControls to manipulate the camera, the plane successfully maintains its orie ...

Creating circular patterns with looping on a canvas

My goal is to draw circles in a loop, but when I execute my code, I am encountering an unexpected result: The intention is to simply draw 3 circles in random positions. Here is my current code: for (var i = 0; i < iloscU; i++) { ctx.strokeStyle = ...

Experiencing a problem with the JavaScript loading function

An error was logged in the console SyntaxError: unterminated string literal A piece of code is supposed to display a notification $(document).ready(function () { alertify.success("Success log message"); return false; }); Despite testing the cod ...

Successive Alerts with Material-UI and React-Redux

After realizing that having multiple snackbars scattered across different components was messy, I decided to revamp my app by creating a single custom component that can be called using Redux to display any type of snackbar needed. Desired outcome: I exp ...

Challenging Trigonometry Puzzles in Javascript

In my project, I am creating an interactive application where a group of humans and bacteria engage in a game of chase. However, I encountered a problem where instead of moving directly towards their target, all entities would veer to the left. I attempt ...

Utilizing an external type definition in JSDoc @typedef

I'm encountering an issue with reducing redundancy when defining my imported types. I am trying to streamline the process, but unfortunately I am running into errors. /** @typedef {import("../types/util")} util @typedef {util.mapBehaviors} m ...

Why doesn't AngularJS validation function properly with input elements of type "number"?

Struggling with Angularjs validation here. Ng-pattern seems to work fine only when the input type is text. However, when the input type is number, ng-pattern doesn't seem to work, although required, min, and max attributes still function. <input t ...

Discovering a specific URL link element within the DOM using webdriver.io

I am currently utilizing webdriver io for conducting tests on a webpage. I am in need of verifying the existence of an element with a specific href on the page. I have attempted to achieve this using the following snippet var client = webdriverio.remote ...

Executing several GET requests in JavaScript

Is there a more efficient way to make multiple get requests to 4 different PHP files within my project and wait for all of them to return successfully before appending the results to the table? I have tried nesting the requests, but I'm looking for a ...

Unable to locate a type definition file for module 'vue-xxx'

I keep encountering an error whenever I attempt to add a 3rd party Vue.js library to my project: Could not find a declaration file for module 'vue-xxx' Libraries like 'vue-treeselect', 'vue-select', and 'vue-multiselect ...

the client requires valid intentions to be specified

I'm currently troubleshooting a discord bot designed to stream audio URL to a voice chat. However, I encountered an error message: TypeError [ClientMissingIntents]: Valid intents must be provided for the Client. at Client._validateOptions (/home/runn ...