我正在研究在LWJGL 3中创建一个体素引擎,我已经掌握了所有基础知识(块,网格渲染等)。
现在我正在使用JBullet添加物理。这是我第一次直接使用JBullet,但我之前在其他3D引擎中使用了Bullet。
从here我收集了所有我需要做的就是创建一个与我的网格形状相同的碰撞对象,将顶点和索引插入TriangleIndexVertexArray
并将其用于{{1} }}
这是我的代码:
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)));
改变比例后,它的作用就像网格对撞机不存在一样。
很难找到JBullet围绕网格碰撞的任何资源或代码,而且我已经在这方面工作了将近2天,所以我希望也许你们中的一些人以前做过这些可以帮助我: )
更新1:
我创建了IDebugDrawer的实现,因此我可以在场景中绘制调试信息。
为了测试它,我只用一个基本的地平面和一个下降的立方体来运行它。我注意到当立方体落下时,aabb与立方体大小相匹配,但当它击中地板时,aabb变得比它大得多。
我要确认这是由于碰撞弹跳导致的普通Bullet行为,并且稍后再看,因为它不会影响我当前的问题。
我重新启用了块网格中碰撞器的生成,并看到了这个:
看起来块的aabb可视化比实际块高很多(我知道整个碰撞对象的y定位是正确的)。
我将尝试弄清楚是否可以绘制实际的碰撞网格。
更新2:
就我看到的来源而言,碰撞器的网格应该在调试中绘制,所以我不确定它为什么不是。
我尝试将Box刚体更换为球体,它实际上滚过了可视化的aabb顶部,用于地形对撞机。它只是平坦地滚动而且没有在地形上有丘陵或倾斜的地方被击中或下降,所以它显然只是滚动在aabb的平顶上。
答案 0 :(得分:1)
因此,在调试抽屉中添加后,我很困惑为什么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网格渲染器的完整代码是:
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
应该修复它。