Leveraging the Principles of Physics in Three.js with an External Model

I've been diving into the world of Three.js and I'm currently grappling with incorporating Cannon-es to attach a cylinder body to a rose mesh created in Blender, allowing it to gracefully fall into a vase. The challenge arises when attempting to update the position of the rose to match that of the body - an error claims that the rose lacks a position element, despite confirming its existence through logging after loading with gltf-loader. It seems like a coding oversight on my end. Here's what I've attempted so far. Any assistance would be greatly appreciated!

The createRose function is triggered by a dat.gui button, successfully creating both the rose and Cannon body, as long as the code within the tick function at the end is disabled.

const objectsToUpdate = []

const createRose = (px, py, pz, rx, ry, rz) =>{
   gltfLoader.load('/models/pieces/Rose.glb',
      (gltf) =>{
      let rose = gltf.scene.children[0]
      rose.position.set(px, py, pz)
      rose.rotation.set(rx, ry, rz)
      scene.add(rose)
   })

   // Cannon.js body
   const shape = new CANNON.Cylinder(2, 1, 5, 20)
   const body = new CANNON.Body({
      mass: 1,
      position: new CANNON.Vec3(0, 3, 0),
      shape: shape,
      material: defaultMaterial
   })
   world.addBody(body)

   // Save in objects to update
   objectsToUpdate.push({ 
      roseAndBody:{
         rose: rose,
         body: body
      }
   })
}

This section resides within a function named tick, which is called using window.requestAnimationFrame(tick)

for(const object of objectsToUpdate){
    object.roseAndBody.rose.position.copy(object.roseAndBody.body.position)
    object.roseAndBody.rose.quaternion.copy(object.roseAndBody.body.quaternion)
 }

To provide context, I am following Bruno SIMON's paid tutorial and have customized a lot of the code based on his physics lesson. I'm open to exploring alternative formats or add-ons besides Cannon.js, anything that can help me achieve the desired outcome!

Answer №1

The problem arises because the async nature of the gltfLoader function causes issues when attempting to include the rose object in the objectsToUpdate array. At that point, the rose object hasn't been created yet and remains as undefined.

To resolve this issue, it is recommended to create the Cannon.js body within the callback function of the gltfLoader, once the rose object has been successfully created. A revised version of the code could look something like the following:

const createRose = (px, py, pz, rx, ry, rz) =>{
   gltfLoader.load('/models/pieces/Rose.glb',
      (gltf) =>{
         let rose = gltf.scene.children[0]
         rose.position.set(px, py, pz)
         rose.rotation.set(rx, ry, rz)
         scene.add(rose)

         // Include Cannon.js body
         const shape = new CANNON.Cylinder(2, 1, 5, 20)
         const body = new CANNON.Body({
            mass: 1,
            position: new CANNON.Vec3(0, 3, 0),
            shape: shape,
            material: defaultMaterial
         })
         world.addBody(body)

         // Add to objects to update
         objectsToUpdate.push({ 
            roseAndBody:{
               rose: rose,
               body: body
            }
         })
      })
}

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

Is it possible to dynamically assign a value to a property?

Check out the code snippet below: let data.roles = "Admin:Xxxx:Data"; for (let role of data.roles.split(':')) { user.data.role[`is${role}`] = true; } Is there a way to optimize this code to dynamically create role propertie ...

The colors rendered by WebGL fragment shaders can vary greatly depending on the platform being used

Working on a website that heavily relies on WebGL shaders, I encountered an issue where the colors on the WebGL canvas were not consistent across different platforms. Specifically, a shader used to draw a gradient representing the sky appeared much darker ...

Is there a way to customize the animation for a button in material UI?

Trying to implement material UI in React and looking for a button that does not have the standard wave animation effect upon clicking, which you can see demonstrated here. Instead, I am searching for an animation that instantly fills the entire button wit ...

Access the Android mobile application by using a JavaScript click event

I have been attempting to launch an installed android mobile application from an html page in the Chrome browser using a javascript or jQuery click function. While an anchor tag tap works perfectly and opens the installed app, I have encountered issues wh ...

What is the best way to extract the value of a string before a comma in Javascript?

I have a challenge where I need to eliminate the city from a city, state combination. For example, if I have the string "Portland, OR", I want to extract only "Portland". Can someone help me with a Javascript solution or guide me on how to achieve this usi ...

Fill out FormBuilder using data from a service within Angular2

I am working with an Angular2 model that I'm filling with data from a service. My goal is to use this model to update a form (created using FormBuilder) so that users can easily edit the information. Although my current approach works, I encounter er ...

Tips for converting characters in an array to a Caesar cipher

I tried setting up an array that correlates capital letters with their corresponding Caesar cipher letters, so for example, A would shift 13 places to become N. I attempted to write a code that could generate this transformation, but I seem to have made an ...

Retrieve a single record in Angular/Typescript and extract its ID value

There is data stored in a variable that is displayed in the Chrome console like this: 0: @attributes: actPer: "1", id: "19" 1: @attributes: actPer: "1" id: "17" etc To filter this data, the following code was used: myvar = this.obj.listR ...

Does anyone have insight on which JavaScript library is being utilized in this context?

While perusing an interesting article, I came across an image that caught my attention. Clicking on it revealed a unique way to view the full size. I am curious if anyone knows which JavaScript library was used for this effect. You can find the article her ...

Having troubles with the xml2json jQuery plugin's functionality?

I've implemented the jQuery XML to JSON Plugin by Fyneworks.com. Any idea why my code isn't functioning as expected? index.html <!DOCTYPE html> <html> <head> <script src="build/jquery.xml2json.js"></script> <sc ...

Strip excess white space from a complex string using Javascript

I have the following sets of strings: 14/04/22 10:45:20 12.08N 87.65W 15.0 2.9ML Frente a Corinto 14/04/21 11:05:34 12.10N 87.70W 140.0 3.5MC Cerca de Masachapa 14/04/22 09:00:09 12.35N 86.44W 12.4 1.3ML Cerca del volcan Momotombo 14/04/21 23:33:37 1 ...

Exchange information among unrelated components

I'm working on implementing a vue event bus to facilitate event communication between my components. In my app.js file, I have included the line Vue.prototype.$eventBus = new Vue();. Within one component, I trigger an event using: this.$eventBus.$emit ...

Exploring the world of JavaScript by dynamically retrieving all class functions

Is there a way to retrieve an array of all functions from a given class, including functions inherited from parent classes? For instance: class Foo extends Bar { funcA() {} } class Bar { funcB() {} } const instanceFoo = new Foo(); getClass ...

What could be causing the issue of the background color not being applied with SCSS and CSS?

My project utilizes both scss and css. I have two files named styles.css and styles.css, which I imported in my _app.js. import "../styles.scss"; import Head from "next/head"; import React from "react"; import App from "n ...

Efficient ways to organize JSON objects using JavaScript

I am in need of restructuring the data retrieved from an API call, which currently looks like this: { "Label3": [ { "name": "superman", "power": 8900 }, { "name": "iron man", "power": 3000 }, { "name": "spike spiegal", "power": 200 ...

Creating an array dynamically by parsing a JSON object in Javascript

I am currently working with a JSON object that looks like this: var testJSON = [ { "AssetA": "asset_a", "AssetB": "asset_b" }, { "AssetA": "asset_a", "AssetB": "asset_b" }, { "AssetA": "asset_c", "AssetB": "asset_d" }, { "AssetA": "asset_c", " ...

Creating a specialized feature for saving form data with React Admin

Within my react-admin application, I am faced with a scenario where I have a list of items accompanied by two separate buttons: "Create using email" and simply "Create". The "create" button utilizes the functionality provided by the data provider, which is ...

Issue with Angular2 Router not recognizing route for homepage

I recently incorporated the Angular2 Webpack Starter into my Angular2 app, which has been working great. However, after adding a fallback route to my app.routes.ts file and including its module (NotFoundModule) in app.module.ts, I encountered an issue wher ...

In what situations is it essential to utilize the `rerender` function in the React Testing Library?

In the past, my team and I usually focused on writing React Testing Library (RTL) tests for the main parent components that contained numerous nested child components. This approach made sense and proved to be effective. The child components in question we ...

How can I limit the displayed content of a div to just the initial lines (clamping)?

I have a collection of divs that showcase previews of lengthy documents. These documents utilize various font styles, resulting in inconsistent line heights. An example can be seen here: http://jsfiddle.net/z56vn/ My goal is to display only the initial fe ...