我正在LWJGL 3中创建一个体素引擎,我已经完成了所有的基础工作(块、网格渲染等等)。
现在我正在使用JBullet添加物理。这是我第一次直接使用JBullet,但我以前在其他3D引擎中使用过子弹。
从这里中,我收集到,要创建与网格形状相同的碰撞对象,我所需要做的就是将顶点和索引插入到TriangleIndexVertexArray中,并将其用于BvhTriangleMeshShape。
这是我的代码:
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。
发布于 2016-11-29 21:24:55
因此,在添加调试抽屉后,我对为什么aabb比它应该大的x2感到困惑。
经过几个小时的小调整,我注意到了一些奇怪的东西--对撞机和块边缘之间有一个0.25的缺口。我继续放大,令人惊讶地注意到:

有一排一列的对撞机吗?不,这是没有道理的,应该有5x5对撞机来匹配5x5块。
然后我数了几个块,并意识到跨越64块的对撞机(我的块是32x32!)。
我很快意识到这是一个缩放问题,并且在添加
BvhTriangleMeshShape meshShape = new BvhTriangleMeshShape(vertArray, useQuantizedAabbCompression);
meshShape.setLocalScaling(new Vector3f(0.5f, 0.5f, 0.5f));把对撞机缩小一半,一切都正常工作!我的“球体”滚动着,停在了地形上的一座小山上,就像它应该看到的那样。

我将LWJGL网格转换为JBullet mesh collder的完整代码是:
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应该是固定的。
https://stackoverflow.com/questions/40855945
复制相似问题