在 Three.js 中使用物理和导入模型

问题描述 投票:0回答:2

我正在学习 Three.js。我正在尝试使用 Cannon-es 将圆柱体连接到我在搅拌机中创建的玫瑰网格,使其落入花瓶中。我的问题是,当我尝试将玫瑰的位置更新为等于身体的位置时,它指出玫瑰没有位置元素,但我在用 gltf-loader 加载它后记录了它并且它有一个位置所以我想我只是没有正确编码。这是我尝试过的方法,谢谢您的帮助!

createRose 函数是从 dat.gui 按钮调用的,当底部的 tick 函数中的代码被注释时,玫瑰和大炮主体创建得很好。

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
      }
   })
}

这是在一个名为 tick 的函数中,该函数使用 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)
 }

有关更多信息,我正在关注 Bruno SIMON 的付费教程,很多代码都是从他的物理课中修改的,我正在努力为此工作。我完全可以使用不同的格式或其他附加组件而不是 Cannon.js,无论什么都能使它起作用!

javascript three.js game-physics blender cannon.js
2个回答
0
投票

问题是

gltfLoader
函数是异步的,当您尝试将
rose
对象添加到
objectsToUpdate
数组时,
rose
对象尚未创建,因此是
undefined
.

在创建

gltfLoader
对象后,您应该在
rose
的回调函数中移动Cannon.js 主体的创建。像这样的东西:

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
            }
         })
      })
}

0
投票

要在 Three.js 中使用导入模型的物理,您需要执行以下步骤:

使用加载器加载模型,例如 GLTFLoader 或 FBXLoader。这将创建一个包含模型的所有网格和节点的组对象。 创建一个 THREE.Object3D 作为模型的父对象。这是必需的,因为物理引擎需要一个根对象来附加物理体。 遍历组对象并将每个子网格添加到您的 Object3D。您可以使用 Object3D 的 add() 方法来完成此操作。 为模型中的每个网格创建一个物理体。您可以使用 Ammo.js 或 Cannon.js 等物理引擎来创建实体并设置它们的属性(例如质量、形状、位置、速度等)。 将每个物理体附加到模型中相应的网格。您可以使用网格的 userData 属性来存储对物理体的引用,然后根据物理体的位置和旋转更新网格的位置和旋转。 下面是使用 Ammo.js 演示这些步骤的示例代码:

// Load the model
const loader = new THREE.GLTFLoader();
loader.load('model.gltf', function(gltf) {
  // Create a parent object for the model
  const model = new THREE.Object3D();

  // Add each mesh to the model
  gltf.scene.traverse(function(child) {
    if (child.isMesh) {
      model.add(child);
    }
  });

  // Create a physics body for each mesh
  const physicsWorld = new Ammo.btDiscreteDynamicsWorld(/*...*/);
  const bodies = [];
  model.traverse(function(child) {
    if (child.isMesh) {
      const shape = /* create a shape for the mesh */;
      const mass = /* set the mass of the body */;
      const body = new Ammo.btRigidBody(/*...*/);
      physicsWorld.addRigidBody(body);
      bodies.push(body);
      child.userData.physicsBody = body;
    }
  });

  // Animate the model
  function animate() {
    requestAnimationFrame(animate);

    // Update the physics simulation
    physicsWorld.stepSimulation(/*...*/);

    // Update the position and rotation of each mesh based on its physics body
    model.traverse(function(child) {
      if (child.isMesh) {
        const body = child.userData.physicsBody;
        const position = /* get the position of the body */;
        const quaternion = /* get the quaternion of the body */;
        child.position.copy(position);
        child.quaternion.copy(quaternion);
      }
    });

    renderer.render(scene, camera);
  }
});

请注意,这只是一个基本示例,您可能需要调整物理参数并更频繁地更新模拟,具体取决于模型的复杂性和所需的精度水平。

© www.soinside.com 2019 - 2024. All rights reserved.