Ammo.js A 框架中 GLTF 模型的碰撞检测

jac*_*bi1 2 javascript ammo.js aframe

如何检测球体与 gltf 模型的碰撞,并在碰撞后使 gltf 模型从场景中消失。我的代码中的碰撞检测适用于球体之间的碰撞,但不适用于 gltf 模型。

<!DOCTYPE html>
<html>
<head>
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://mixedreality.mozilla.org/ammo.js/builds/ammo.wasm.js"></script>
<script src="http://cdn.jsdelivr.net/gh/n5ro/aframe-physics-system@v4.0.1/dist/aframe-physics-system.min.js"></script>
<script src="https://cdn.rawgit.com/donmccurdy/aframe-extras/v6.1.1/dist/aframe-extras.min.js" ></script>
<script>
   AFRAME.registerComponent('explode', {
       init: function() {
           var el = this.el;
           el.addEventListener("collidestart", function () {
               console.log('collision detected');
               el.parentElement.removeChild(el);
    });
  }
});
</script>
</head>
<body>
 <a-scene physics=" driver: ammo">
   <a-assets>
    <a-asset-item id="human" response-type="arraybuffer" src="human.glb"></a-asset-item>
   </a-assets> 
   <a-camera position="2 5 2" look-controls wasd-controls>
        <a-cursor></a-cursor>
        </a-camera>
  <a-entity explode gltf-model="#human" class="enemy" ammo-body="type:   kinematic; 
     emitCollisionEvents: true;" ammo-shape="type: sphere"
     position="3 5 0" scale="0.1 0.1 0.1" rotation="0 180 0">      
    </a-entity>
  <a-sphere explode ammo-body="type: kinematic; emitCollisionEvents: true;"
    ammo-shape="type: sphere" position="1 5 0" velocity="1 0 0" radius="0.5"
    color="blue"></a-sphere>
  <a-sphere explode ammo-body="type: kinematic; emitCollisionEvents: true;"
    ammo-shape="type: sphere" position="5 5 0" velocity="0 0 0" radius="0.5"
    color="blue"></a-sphere>
 
 </a-scene>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

Dia*_*zie 5

我预计这里发生的情况是,当在 GLTF 模型上初始化 ammo-shape 时,不会加载 GLTF 模型。

如果您检查控制台,您很可能会看到以下错误:

Cannot use FIT.ALL without object3DMap.mesh
Run Code Online (Sandbox Code Playgroud)

弹药形状无法自动适应(尚不存在)网格,因此您最终将没有任何形状 - 因此不会发生碰撞。

一个简单的修复方法是明确指定弹药形状的半径:

ammo-shape="type: sphere; fit: manual; sphereRadius:0.5"
Run Code Online (Sandbox Code Playgroud)

另一个解决方案,如果您确实想避免指定半径,则编写一个小组件来等待model-loaded实体上的事件,并且仅在该点添加ammo-shapeammo-body(它们需要同时添加)。

像这样的东西应该有效:

AFRAME.registerComponent("autofit-gltf-ammo-sphere", {

  init() {
    this.el.addEventListener("model-loaded", () => {
        this.el.setAttribute("ammo-shape", "type:sphere");
        this.el.setAttribute("ammo-body", "type:kinematic; emitCollisionEvents: true");
    });
  }
});
Run Code Online (Sandbox Code Playgroud)

然后在实体上使用,如下所示:

<a-entity explode gltf-model="#human" class="enemy" autofit-gltf-ammo-sphere
     position="3 5 0" scale="0.1 0.1 0.1" rotation="0 180 0">      
</a-entity>
Run Code Online (Sandbox Code Playgroud)