【问题标题】:How to check if the model out of the viewer container?如何检查模型是否超出查看器容器?
【发布时间】:2021-12-19 05:13:50
【问题描述】:

我制作了一张信息卡片,如果旋转查看器直到模型不可见,这张卡片就会消失。我使用isNodevisible,但它总是返回true。

  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";
    }
  }

【问题讨论】:

    标签: autodesk-forge autodesk-viewer


    【解决方案1】:

    函数isNodeVisible 返回场景中节点的可见性状态。如果您执行this.viewer.hide(id, model) 之类的操作,您的函数将返回false

    如果我很好理解您想要实现的目标,您想在关联对象被其他对象遮挡时隐藏信息卡,因此我们无法从我们的角度看到它?

    所以我认为您需要检查遮挡。你可以看看 Philippe Leefsma 制作的这个point cloud markup extensioncheckOcclusion 功能。 要检查节点遮挡,您基本上需要从您的角度投射到要检查的节点。如果你撞到某个东西并且它是你的节点,那么就没有遮挡。如果不是同一个节点,说明有东西遮挡了你的节点。

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

    【讨论】:

    • 在被另一个物体覆盖之前不会消失。但是在拖动和旋转场景时是看不到物体的,直到物体不可见为止。我在上面添加了一张图片。
    • 正如 Alex 指出的那样,isNodeVisible 方法用于不同的用例(当您想要隐藏/显示 3D 模型的各个元素时)。
    • 如果节点不在相机视图中,您可能不会得到 hitTest 。因此,如果您在没有 hitTest 成立时隐藏信息卡,这应该可以工作。
    【解决方案2】:

    如果我正确理解了您的问题,您可能希望在相机的平截头体和模型的边界框之间进行交叉测试。可以这样做:

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

    【讨论】:

      猜你喜欢
      • 2013-05-18
      • 1970-01-01
      • 1970-01-01
      • 2021-08-29
      • 1970-01-01
      • 1970-01-01
      • 2012-11-06
      • 1970-01-01
      • 2017-12-06
      相关资源
      最近更新 更多