首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LWJGL网格到JBullet对撞机

LWJGL网格到JBullet对撞机
EN

Stack Overflow用户
提问于 2016-11-29 00:36:16
回答 1查看 691关注 0票数 1

我正在LWJGL 3中创建一个体素引擎,我已经完成了所有的基础工作(块、网格渲染等等)。

现在我正在使用JBullet添加物理。这是我第一次直接使用JBullet,但我以前在其他3D引擎中使用过子弹。

这里中,我收集到,要创建与网格形状相同的碰撞对象,我所需要做的就是将顶点和索引插入到TriangleIndexVertexArray中,并将其用于BvhTriangleMeshShape

这是我的代码:

代码语言:javascript
复制
    float[] coords = mesh.getVertices();
    int[] indices = mesh.getIndices();

    if (indices.length > 0) {
        IndexedMesh indexedMesh = new IndexedMesh();
        indexedMesh.numTriangles = indices.length / 3;
        indexedMesh.triangleIndexBase = ByteBuffer.allocateDirect(indices.length*Float.BYTES).order(ByteOrder.nativeOrder());
        indexedMesh.triangleIndexBase.asIntBuffer().put(indices);
        indexedMesh.triangleIndexStride = 3 * Float.BYTES;
        indexedMesh.numVertices = coords.length / 3;
        indexedMesh.vertexBase = ByteBuffer.allocateDirect(coords.length*Float.BYTES).order(ByteOrder.nativeOrder());
        indexedMesh.vertexBase.asFloatBuffer().put(coords);
        indexedMesh.vertexStride = 3 * Float.BYTES;

        TriangleIndexVertexArray vertArray = new TriangleIndexVertexArray();
        vertArray.addIndexedMesh(indexedMesh);

        boolean useQuantizedAabbCompression = false;
        BvhTriangleMeshShape meshShape = new BvhTriangleMeshShape(vertArray, useQuantizedAabbCompression);

        CollisionShape collisionShape = meshShape;

        CollisionObject colObject = new CollisionObject();
        colObject.setCollisionShape(collisionShape);
        colObject.setWorldTransform(new Transform(new Matrix4f(new Quat4f(0, 0, 0, 1), new Vector3f(position.x, position.y, position.z), 1f)));
        dynamicsWorld.addCollisionObject(colObject);

    } else {
        System.err.println("Failed to extract geometry from model. ");
    }

我知道顶点和索引都是有效的,因为我在绘制网格后将它们放在这里。

这似乎有点工作,但当我试图把一个立方体刚体在地形上,它似乎碰撞的方式以上的地形!(我知道立方体的设置是正确的,因为如果我去掉网格对撞机,它就会击中y=0的基准面)。

我想这可能是一个缩放问题(虽然我不知道这是怎么回事),所以我试着改变了:

colObject.setWorldTransform(new Transform(new Matrix4f(new Quat4f(0, 0, 0, 1), new Vector3f(position.x, position.y, position.z), 1f)));到:

colObject.setWorldTransform(new Transform(new Matrix4f(new Quat4f(0, 0, 0, 1), new Vector3f(position.x, position.y, position.z), 0.5f)));

但是在改变了1的规模后,它的作用就像网格对撞机不存在一样。

很难为JBullet周围的网格冲突找到任何资源或代码,我已经做了将近两天的工作,所以我希望你们中的一些人能帮我解决这个问题:)

更新1:

我创建了IDebugDrawer的一个实现,以便在场景中绘制调试信息。

为了测试它,我只运行了一个基本的地面平面和一个下降的立方体。我注意到,当立方体下降时,aabb与立方体大小相匹配,但当它落在地板上时,aabb变得比以前要大得多。

我要告诉你,这是由于碰撞弹跳而产生的正常的子弹行为,稍后再看,因为它不会影响我目前的问题。

我重新启用了从块网格生成对撞机,并看到了以下内容:

看起来,块的aabb可视化要比实际的块高得多(我知道我对整个碰撞对象的y定位是正确的)。

我要试着弄清楚我是否能画出实际的碰撞网格。

更新2:

据我所能看到的源代码,对撞机的网状图应该是在调试,所以我不知道为什么不是。

我试着把Box刚体变成一个球体,它实际上滚过了地形对撞机可视化的aabb顶部。它只是平缓地滚动,并没有击中或下降的地方,那里的山丘或倾斜的地形,所以它显然只是滚动通过平坦的顶部的aabb。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-29 21:24:55

因此,在添加调试抽屉后,我对为什么aabb比它应该大的x2感到困惑。

经过几个小时的小调整,我注意到了一些奇怪的东西--对撞机和块边缘之间有一个0.25的缺口。我继续放大,令人惊讶地注意到:

有一排一列的对撞机吗?不,这是没有道理的,应该有5x5对撞机来匹配5x5块。

然后我数了几个块,并意识到跨越64块的对撞机(我的块是32x32!)。

我很快意识到这是一个缩放问题,并且在添加

代码语言:javascript
复制
BvhTriangleMeshShape meshShape = new BvhTriangleMeshShape(vertArray, useQuantizedAabbCompression);
meshShape.setLocalScaling(new Vector3f(0.5f, 0.5f, 0.5f));

把对撞机缩小一半,一切都正常工作!我的“球体”滚动着,停在了地形上的一座小山上,就像它应该看到的那样。

我将LWJGL网格转换为JBullet mesh collder的完整代码是:

代码语言:javascript
复制
public void addMesh(org.joml.Vector3f position, Mesh mesh){
    float[] coords = mesh.getVertices();
    int[] indices = mesh.getIndices();

    if (indices.length > 0) {

        IndexedMesh indexedMesh = new IndexedMesh();
        indexedMesh.numTriangles = indices.length / 3;
        indexedMesh.triangleIndexBase = ByteBuffer.allocateDirect(indices.length*Integer.BYTES).order(ByteOrder.nativeOrder());
        indexedMesh.triangleIndexBase.rewind();
        indexedMesh.triangleIndexBase.asIntBuffer().put(indices);
        indexedMesh.triangleIndexStride = 3 * Integer.BYTES;
        indexedMesh.numVertices = coords.length / 3;
        indexedMesh.vertexBase = ByteBuffer.allocateDirect(coords.length*Float.BYTES).order(ByteOrder.nativeOrder());
        indexedMesh.vertexBase.rewind();
        indexedMesh.vertexBase.asFloatBuffer().put(coords);
        indexedMesh.vertexStride = 3 * Float.BYTES;

        TriangleIndexVertexArray vertArray = new TriangleIndexVertexArray();
        vertArray.addIndexedMesh(indexedMesh);

        boolean useQuantizedAabbCompression = false;
        BvhTriangleMeshShape meshShape = new BvhTriangleMeshShape(vertArray, useQuantizedAabbCompression);
        meshShape.setLocalScaling(new Vector3f(0.5f, 0.5f, 0.5f));

        CollisionShape collisionShape = meshShape;

        CollisionObject colObject = new CollisionObject();
        colObject.setCollisionShape(collisionShape);
        colObject.setWorldTransform(new Transform(new Matrix4f(new Quat4f(0, 0, 0, 1), new Vector3f(position.x, position.y, position.z), 1f)));
        dynamicsWorld.addCollisionObject(colObject);

    } else {
        System.err.println("Failed to extract geometry from model. ");
    }

}

更新1:

尽管缩放是对上述问题的修正,但它使我看得更深,并意识到我错误地使用了块大小(0.5f)来表示网格视图矩阵中的网格缩放因子。将刻度更改为1应该是固定的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40855945

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档