THREE.Object3D:如何禁用对象而不是材质的Raycast?

时间:2019-01-21 15:56:02

标签: three.js

因此,常识似乎是将对象的材料可见性设置为false。

因此,当我有无数共享相同材质的对象时,这将不起作用。但是我想根据他们的数据禁用其中一些。

使用

Object.visible = false;

我可以隐藏它们,但是它们仍然可以选择。

Object.Material.visible = false

隐藏所有对象,因为它们的共享材质设置为不可见。

可以做到吗?

我没有创建那些对象,因此没有机会创建多种材料。我只能使用获得相同材质并需要隐藏的对象

1 个答案:

答案 0 :(得分:0)

解决方案1:手动过滤射线广播候选对象和结果

看起来没有任何内置字段可以实现您想要的功能,但是您应该能够通过手动过滤要进行射线广播的对象列表来实现类似的行为。这是您可能的处理方法:

// scene with lots of nested objects
const scene, raycaster;

// ...

// Gather up which objects to try to raycast against based on
// a set of conditions
const raycastList = [];
scene.traverse(c => {
    if (c.isMesh && !c.disableRaycast) {
        raycastList.push(c);
    }
});

// raycast against only the items in the array
const intersections = raycaster.raycastObjects(raycastList);

如果您要基于网格物体的父对象disableRaycast字段进行过滤,则可以创建一个自定义遍历功能,使您可以尽早跟踪父母禁用状态停止遍历。

如果您已经提前知道应该或不应该对哪些对象进行射线投射,则可以预先创建该列表并将其保留。

编辑

解决方案2:覆盖并制作自定义Mesh.raycast()函数

如果您无权修改raycast代码,则可以创建一个“ DeactivateableRaycastMesh”类,该类实现自定义raycast方法,并允许您启用或禁用它是否返回raycast命中。

class DeactivateableRaycastMesh extends THREE.Mesh {

    constructor(...args) {
        super(...args);
        this.raycastEnabled = true;
    }

    raycast(...args) {
        if (!this.raycastEnabled) return;
        super.raycast(...args);
    }

}

如果您需要在每个网格上而不只是在创建的网格上都需要此功能,则可以修改THREE.Mesh.prototype以将上述功能添加到所有网格中。但是,不建议这样做。

const originalRaycast = THREE.Mesh.prototype.raycast;
THREE.Mesh.prototype.raycast = function(...args) {
    if (!this.raycastEnabled) return;
    originalRaycast.call(this, ...args);
}