Three.js:来自不在场景中的对象的 Box3

Three.js : Box3 from an object not in scene

我在从不同模块中的对象添加边界框时遇到问题。现在,只要我在我的主函数中编写所有内容,它就可以正常工作,但是一旦我在另一个文件中创建我的函数,并在主文件中导入,它就不再工作了。

我得到的错误代码:

Uncaught TypeError: Cannot read properties of undefined (reading 'updateWorldMatrix')
    at Box3.expandByObject (three.module.js:4934:10)
    at Box3.setFromObject (three.module.js:4852:15)
    at camCollision (camColliders.js:68:37)
    at HTMLDocument.<anonymous> (World.js:355:7)

camColliders.js 是我试图将函数放入的文件,World.js 我的主文件。

函数如下:

function camCollision() {
      const camBB = new Box3().setFromObject(camSphereDetector);

      const boule1BB = new Box3().setFromObject(boule1Obj);
      boule1BB.name = 'first';
      const boule2BB = new Box3().setFromObject(boule2Obj);
      boule2BB.name = 'second';
      const boule3BB = new Box3().setFromObject(boule3Obj);
      boule3BB.name = 'third';

      const boulesBB = [boule1BB, boule2BB, boule3BB];

      boulesBB.forEach((bbs) => {
        if (bbs.intersectsBox(camBB)) {
          console.log('got it');
        }
      });
    }

    document.addEventListener('mouseup', () => {
      camCollision();
    });

当我在一个单独的文件中执行此操作时,我首先从另一个文件导入对象,它们都是网格。

我认为问题是我无法在单独的文件中创建边界框,因为它需要先添加到场景中,而我只是在场景中添加它们 World.js.然而,错误将我带到第 68 行,即 'boule1BB' 的变量,这很奇怪,因为 'camBB' 应该首先出现问题?

这是我创建 Box3 的方法(这些只是复制一些 GLTF 对象的位置和大小,因为我无法从中获取 Box3):

const boule1Obj = new Mesh(
    new SphereGeometry(2, 32, 16),
    new MeshBasicMaterial({ color: 'red', transparent: true, opacity: 0 }),
  );
  boule1Obj.position.set(10, -3.5, 0);

然后,我想知道,如果我做对了问题:有没有办法从一个尚未添加到场景中的对象(即使它应该)在不同的 js 文件中创建一个 Box3当函数被调用时)?也许用不同于 'setFromObject' 的方式?还是我没有理解真正的问题。

关于一些上下文,目的是在用户单击每个模型时提供有关每个模型的一些信息,我计划将与模型对应的每个网格的信息作为“.name”。所以我不想在主文件中写所有这些东西,而是在一个单独的文件中。

我希望这已经足够清楚了,并且我已经提供了足够的内容以便找到解决方案。我找不到其他人有这个问题。如果您还需要什么,请告诉我!

非常感谢您的帮助!

I believe the problem is that I can't create the Bounding Boxes in a separate file, because it needs to be added to the scene in World.js.

不是这样。由于构造的 THREE.Mesh 具有带范围的形状(从其几何形状)和变换(默认情况下,平移到原点,没有缩放或旋转),Three.js 可以并且将确定一个边界框该信息就好像网格在场景中一样。我已经在 CodePen 上发布了一个 demo

在一个文件中定义对象并在另一个文件中引用它也不应该有任何区别,只要对象在范围内并且在它绑定到 时初始化。

这里,我怀疑您在 World.js 中分配 boule1Obj、boule2Obj 和 boule3Obj。在那种情况下,导入的函数在分配变量之前被提升,并且该函数看到绑定到它们作为未分配undefined.

尝试更改 camCollision() 以接受 bouleXObj 作为参数。

function camCollision(...objs) {
  const camBB = new Box3().setFromObject(camSphereDetector);

  for(let i = 0; i < objs.length; i++) {
    const objBB = new Box3().setFromGeometry(objs[i]);
    objBB.name = `Bounding Box ${i + 1}`;
    if(objBB.intersectsBox(camBB)) {
      console.log("Got it!");
    }
  }
}

然后称之为

document.addEventListener("mouseup", () => {
  camCollision(boule1Obj, boule2Obj, boule3Obj);
});