2016-11-29 242 views
1

我正在LWJGL 3中創建一個體素引擎,我有所有的基礎知識(塊,網格渲染等)。LWJGL網格JBullet對撞機

現在我正在使用JBullet添加物理。這是我第一次直接使用JBullet,但我之前在其他3D引擎中使用過Bullet。

here我收集了所有我需要做的創建碰撞對象相同的形狀,我的目是塞的頂點和索引到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)。

enter image description here

我想也許這是一個規模問題(雖然我不明白怎麼會是),所以我試圖改變:

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周圍網狀物碰撞的任何資源或代碼,而且我一直在爲此工作近2天,所以我希望也許你們之前做過的一些人可以幫助我:)

更新1:

我創建了IDebugDrawer的實現,所以我可以繪製現場調試信息來源。

爲了測試它,我只用一個基本的地平面和一個落下的立方體來運行它。我注意到,當立方體下落時,aabb與立方體大小相匹配,但是當它碰到地板時,aabb變得明顯大得多。

enter image description here

我要assue,這是正常的子彈的行爲由於collition反彈,並期待在以後,因爲它不會影響我當前的問題。

我重新啓用從塊meshs的對撞機的一代,看到這一點:

enter image description here

看來,大塊的AABB可視化是高了很多,那麼實際塊(我知道我對整體碰撞物體的定位是正確的)。

enter image description here

我要去揣摩,如果我可以得出實際碰撞網格與否。

更新2:

至於我可以看到在看的來源,應該對撞機在調試來繪製meshof,所以我不知道爲什麼它不是。

我嘗試將Box剛體改爲球體,並且它實際上在可視化aabb的頂部滾動以用於地形對撞機。它雖然只是平坦的,並沒有撞到那裏的地形丘陵或窪地,所以它顯然只是滾過橫木平頂。

+1

儘管我使用C++版本的bullet物理,但我認爲你需要首先構建一個圖形調試器來找出問題所在。看一看[這裏](http://stackoverflow.com/questions/19976935/bullet-debug-drawer-with-opengl)。如果JBullet沒有提供(我不這麼認爲)界面,你需要實現自己的圖形調試器,並使用子彈對象的一種'getAABB(min,max)'函數來繪製一個基本的可視框。希望這些幫助。 – Tokenyet

+0

@Tokenyet啊謝謝,我忘記了有一個調試抽屜:)我增加了更多的信息和截圖問題與調試 –

回答

1

因此,在添加調試抽屜後,我很困惑,爲什麼aabb是x2大,那麼它應該是。

花了幾個小時嘗試一些小調整後,我發現一些奇怪的東西 - 對撞機和塊的邊緣之間有一個0.25的差距。我繼續縮小,令人驚訝的注意到了這一點:

enter image description here

有撞機的extera行​​和列?沒有意義,應該有5x5的對撞機來匹配5x5的塊。

然後,我計算塊,並意識到,對角線跨越64塊(我的塊是32x32!)。

我很快意識到,這是一個規模問題,並增加

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

要了一半,一切都配合和努力下縮放撞機後!我的「球體」翻滾並停在那裏,就像它應該在地形上有一座小山。

enter image description here

我對coverting的LWJGL網到JBullet網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:

即使比例是說,對於修復prolem ,它讓我看起來更深,並意識到我錯誤地使用了在我的網格視圖矩陣中爲網格縮放因子分塊大小(0.5f)。更改比例尺到1就像它應該修復它。

+0

我創建了一些代碼,可以調試繪製網格。只要回覆我,如果你想要它。 –

+0

@HelloWorld,這將是整齊的看到:) –

+1

@ Keith M好吧。下面是代碼:dropbox.com/s/z91xc5pknp8g8ys/thing.txt?dl=0請記住,由於某種原因,它只能繪製大約三分之一的頂點 –