是否可以使用 AFrame 仅使 GLTF 模型的特定部分可点击?

Is it possible to make only specific parts of a GLTF model clickable using AFrame?

我正在 AFrame 中加载 GLTF 模型并使用 AFrame 组件遍历其节点。我只想让这个模型的某些部分可以点击,即当用户将鼠标悬停在这些部分上时,光标将是指针,而对于所有其他部分,它将是默认光标。 这可能使用 HTML 或 Aframe 吗?

文档是您的朋友! cursor and the raycaster 组件都公开了相交的对象(不仅是 HTML 元素,还有底层网格)。

因此您可以创建一个 custom component,它将

  • 检查鼠标是否悬停在模型上
  • 跟踪相交的网格并应用您的逻辑

看看这个例子(我希望它有广泛的评论):

<script src="https://aframe.io/releases/1.1.0/aframe.min.js"></script>
<script>
  AFRAME.registerComponent("foo", {
    init: function() {
      // check when the cursor is intersecting with this entity
      this.el.addEventListener("raycaster-intersected", evt => {
        this.intersection = evt.detail;
      });

      // check when the intersection is cleared
      this.el.addEventListener("raycaster-intersected-cleared", evt => {
        this.intersection = null;
      });
    },
    tick: (function() {
      // helper variable to keep track of which element is under the mouse
      var currentMesh = null;

      return function() {
        // if there is no intersection, return
        if (!this.intersection) {
          if (currentMesh) {
            // remove highlight if a mesh was highlighted
            this.highlight(currentMesh, false);
            currentMesh = false;
          }
          return;
        }
        // grab the current intersected object
        var intersection = this.intersection.getIntersection(this.el);
        if (!intersection) return;
        const obj = intersection.object;
        // if nothing was cached, highlight this mesh
        if (!currentMesh) {
          currentMesh = obj;
          this.highlight(currentMesh, true);
        }
        // if a mesh was highlighted, clear the old one, and highlight the new one
        if (obj.uuid !== currentMesh.uuid) {
          this.highlight(currentMesh, false);
          currentMesh = obj;
          this.highlight(currentMesh, true);
        }
      };
    })(),
    highlight: function(mesh, highlight) {
      var color = highlight ? 0xffff00 : 0x000000;
      mesh.material.emissive.setHex(color);
      mesh.material.needsUpdate = true;
    }
  });
</script>
</head>

<body>
  <div style="z-index: 99999; position: fixed; top: 5%; text-align: center">
    <p>
      Model by <a href="https://poly.google.com/view/62zn39CRkbG">google</a>
    </p>
  </div>
  <a-scene background="color: #FAFAFA" cursor="rayOrigin: mouse">
    <a-assets>
      <a-asset-item id="model" src="https://cdn.glitch.com/0c08e4fb-3f49-4a20-bb84-a2eceb70bca4%2FWall_Art_Classical_01.gltf?v=1612251538844"></a-asset-item>
    </a-assets>

    <a-entity position="0 1 -3" scale="0.1 0.1 0.1" gltf-model="#model" foo></a-entity>
  </a-scene>