如何检查模型是否超出查看器容器?

How to check if the model out of the viewer container?

我制作了一张信息卡片,如果旋转查看器,这张卡片就会消失,直到模型不可见。我使用 isNodevisible 但它始终 returns 正确。

  updateInfoCard() {
    if (this.infoCard && this.posModel) {
      const pos = this.viewer.worldToClient(this.posModel);

      console.log(pos);
      this.infoCard.style.left = `${Math.floor(
        50 + pos.x - this.infoCard.offsetWidth / 2
      )}px`;
      this.infoCard.style.top = `${Math.floor(
        50 + pos.y - this.infoCard.offsetWidth / 2
      )}px`;
      const id = this.infoCard.dataset.id;
      console.log(this.viewer.isNodeVisible(id));
      this.infoCard.style.display = this.viewer.isNodeVisible(id)
        ? "block"
        : "none";
    }
  }

函数isNodeVisible return设置您的节点在场景中的可见性状态。如果你做类似 this.viewer.hide(id, model) 你的功能将 return false.

如果我很好理解你想实现什么,你想在关联对象被其他对象遮挡时隐藏信息卡,所以我们无法从我们的角度看到它?

所以我认为你需要的是检查遮挡。你可以看一下这个point cloud markup extensioncheckOcclusion函数,作者是Philippe Leefsma。 要检查节点遮挡,您基本上需要从您的角度对要检查的节点进行光线投射。如果您击中某物并且它是您的节点,则没有遮挡。如果不是同一个节点,说明有东西遮挡了你的节点。

checkOcclusion (markup) {

    const clientPoint = this.viewer.worldToClient(
      markup.point)

    const offset = $(this.viewer.container).offset()

    const rayCaster = this.pointToRaycaster(
      this.viewer.impl.canvas,
      this.viewer.impl.camera, {
        x: clientPoint.x + offset.left,
        y: clientPoint.y + offset.top
      })

    const hitTest = this.viewer.model.rayIntersect(
      rayCaster, true, this.dbIds)

    if (hitTest) {

      if (hitTest.fragId === markup.fragId) {

        const offset = {
          x: hitTest.point.x - markup.point.x,
          y: hitTest.point.y - markup.point.y,
          z: hitTest.point.z - markup.point.z
        }

        const dist = Math.sqrt(
          offset.x * offset.x +
          offset.y * offset.y +
          offset.z * offset.z)

        if (this.options.logOcclusionDist) {

          console.log(dist)
        }

        if (dist < this.options.occlusionDist) {

          return false
        }
      }

      return true
    }
  }

如果我对你的问题的理解正确,你可能想要在相机的截锥体和模型的边界框之间进行相交测试。可以这样做:

    viewer.addEventListener(Autodesk.Viewing.CAMERA_CHANGE_EVENT, function () {
        if (!viewer.model) {
            return;
        }
        const camera = viewer.getCamera();
        const matrix = new THREE.Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
        const frustum = new THREE.Frustum().setFromMatrix(matrix);
        const bbox = viewer.model.getBoundingBox();
        console.log('Model in the view?', frustum.intersectsBox(bbox));
    });

如果您只想检查模型的特定 元素(基于其 dbID)的可见性,您可以像这样计算其边界框:

    function objectBounds(model, dbId) {
        const tree = model.getInstanceTree();
        const frags = model.getFragmentList();
        const objectBounds = new THREE.Box3();
        tree.enumNodeFragments(dbId, function (fragId) {
            const fragBounds = new THREE.Box3();
            frags.getWorldBounds(fragId, fragBounds);
            objectBounds.union(fragBounds);
        }, true);
        return objectBounds;
    }