You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AmmoJS btBvhTriangleMeshShape碰撞失效物体穿透问题求解

ammo.js btBvhTriangleMeshShape碰撞穿透问题
  • 现有同类参考问题均无有效解答,且多数为非中文内容。
  • 问题表现:基于Blender制作的GLB模型创建btBvhTriangleMeshShape碰撞体时,其他物体与该碰撞体交互会直接穿透掉落。通过Enable3D的DebugDrawer查看调试线框,发现线框显示异常,判断该异常是碰撞失效的核心诱因。
  • 现存疑点:检索到一份公开的「网格转btBvhTriangleMeshShape」实现代码,未完全吃透其实现逻辑,怀疑代码本身存在缺陷。原示例使用的碰撞类型为btConvexTriangleMeshShape,对应创建代码已被注释,不确定是否可以直接替换为btBvhTriangleMeshShape使用。

当前使用的形状创建代码如下:

createConcaveShapeFromObj (obj) {
    // 初始化Ammo三角网格实例
    const triangleMesh = new Ammo.btTriangleMesh();

    // 定义三角形三个顶点的向量容器
    const vectA = new Ammo.btVector3(0, 0, 0);
    const vectB = new Ammo.btVector3(0, 0, 0);
    const vectC = new Ammo.btVector3(0, 0, 0);

    // 从模型几何体中提取顶点位置数组
    const verticesPos = obj.geometry.getAttribute('position').array;
    const triangles = [];

    for (let i = 0; i < verticesPos.length; i += 3) {
        triangles.push({
                x: verticesPos[i],
                y: verticesPos[i + 1],
                z: verticesPos[i + 2]
        })
    }

    // 遍历三角形数据构建碰撞形状
    for (let i = 0; i < triangles.length - 3; i += 3) {
        vectA.setX(triangles[i].x);
        vectA.setY(triangles[i].y);
        vectA.setZ(triangles[i].z);

        vectB.setX(triangles[i + 1].x);
        vectB.setY(triangles[i + 1].y);
        vectB.setZ(triangles[i + 1].z);

        vectC.setX(triangles[i + 2].x);
        vectC.setY(triangles[i + 2].y);
        vectC.setZ(triangles[i + 2].z);

        triangleMesh.addTriangle(vectA, vectB, vectC, true);
    }

    var shape = new Ammo.btConvexTriangleMeshShape(triangleMesh, true); 
    // 注意:btConvexTriangleMeshShape可正常生成,但碰撞检测基于包围盒计算,精度不符合需求
    shape.setMargin(0.05);

    return shape;
}

原提问附完整可运行项目实例,可直接复现上述问题。

内容的提问来源于stack exchange,提问作者powerbuoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 06:01:43