[C++, DX9] btTriangleIndexVertexArray issue

Post Reply
Ripiz
Posts: 47
Joined: Mon Aug 16, 2010 10:43 am

[C++, DX9] btTriangleIndexVertexArray issue

Post by Ripiz »

Well it throws point.getX() <= m_bvhAabbMax.getX() error somewhere inside new btTriangleIndexVertexArray(). Here's my code:

Code: Select all

	// get vertex data
	LPDIRECT3DVERTEXBUFFER9 pVertices;
	Mesh->GetVertexBuffer(&pVertices);
	DWORD dwVertexSize = Mesh->GetNumBytesPerVertex();
	BYTE *pVertexData = 0;
	uint numVertices = Mesh->GetNumVertices();
	float *dataVertex = new float[numVertices];
	pVertices->Lock( 0, 0, ( void** )&pVertexData, 0 );
	for(DWORD i = 0; i < numVertices; i += 3){
		dataVertex[i + 0] = (*(Vector3*)(pVertexData + (i + 0)*dwVertexSize)).x;
		dataVertex[i + 1] = (*(Vector3*)(pVertexData + (i + 1)*dwVertexSize)).y;
		dataVertex[i + 2] = (*(Vector3*)(pVertexData + (i + 2)*dwVertexSize)).z;
	}
	pVertices->Unlock();
	pVertices->Release();

	// get index data
	LPDIRECT3DINDEXBUFFER9 pIndices;
	Mesh->GetIndexBuffer(&pIndices);
	BYTE* pIndexData;
	pIndices->Lock(0, 0, (void**)&pIndexData, 0);
	uint numIndex = Mesh->GetNumFaces() * 3;
	int *dataIndex = new int[numIndex];
	for(DWORD i = 0; i < numIndex; i++)
		dataIndex[i] = pIndexData[i];
	pIndices->Unlock();
	pIndices->Release();

	btTriangleIndexVertexArray *trimesh = new btTriangleIndexVertexArray(Mesh->GetNumFaces(), dataIndex, 3 * sizeof(int), Mesh->GetNumVertices(), dataVertex, 3 * sizeof(float));
Strange thing is, it doesn't happen on first call, but but specific model. That model appears correctly when rendered, so I doubt there's any problem with vertex data. To be safe I outputed it to files

Index Data:

Code: Select all

0 0 1 
0 2 0 
3 0 4 
0 5 0 
6 0 7 
0 8 0 
9 0 10 
0 11 0 
12 0 13 
0 14 0 
15 0 16 
0 17 0 
18 0 19 
0 20 0 
21 0 22 
0 23 0 
Index Data doesn't feel correct to me, so I have doubts I read it correctly, but then why other models don't crash?

Vertex Data:

Code: Select all

-14.1421 0 -14.1421 
14.1421 40 14.1421 
-14.1421 40 -14.1421 
14.1421 0 14.1421 
20 0 -3.8147e-006 
-20 40 3.8147e-006 
20 40 -8.58307e-006 
-20 0 8.58307e-006 
-1.90735e-006 0 -20 
1.90735e-006 40 20 
-6.67572e-006 40 -20 
6.67572e-006 0 20 
14.1421 0 -14.1421 
-14.1421 40 14.1421 
14.1421 40 -14.1421 
-14.1421 0 14.1421
SteveSegreto
Posts: 32
Joined: Sun Sep 12, 2010 10:25 am

Re: [C++, DX9] btTriangleIndexVertexArray issue

Post by SteveSegreto »

I think your question has already been answered here:

http://bulletphysics.org/Bullet/phpBB3/ ... f=9&t=5615

Basically you need to specify a different index width and that's not possible with the Bullet 2.76 btTriangleIndexVertexArray() constructor, either create your own (as described in the thread above) or do this:

Code: Select all

			pMesh->m_pTriMesh = new btTriangleIndexVertexArray();

			btIndexedMesh iMesh;
			iMesh.m_numTriangles        = pMesh->m_numFaces;
			iMesh.m_triangleIndexBase   = (const unsigned char *)pMesh->m_pIndices;
			iMesh.m_triangleIndexStride = 3 * sizeof(IndexFormat);
			iMesh.m_numVertices         = pMesh->m_numVertices;
			iMesh.m_vertexBase          = (const unsigned char *)pMesh->m_pVertices;
			iMesh.m_vertexStride        = sizeof(D3DXVECTOR3);
			pMesh->m_pTriMesh->addIndexedMesh( iMesh, PHY_SHORT );
Ripiz
Posts: 47
Joined: Mon Aug 16, 2010 10:43 am

Re: [C++, DX9] btTriangleIndexVertexArray issue

Post by Ripiz »

SteveSegreto wrote:You need to either change your index format to INT in DirectX or change it to PHY_SHORT in Bullet.
I changed it to INT

Code: Select all

btTriangleIndexVertexArray *trimesh = new btTriangleIndexVertexArray(Mesh->GetNumFaces(), dataIndex, 3 * sizeof(int), Mesh->GetNumVertices(), dataVertex, 3 * sizeof(float));
                                                                                                       ^ ^ ^ ^ ^ ^
                                                                                                       | | | | | |
                                                                                                       | | | | | |
                                                                                                       | | | | | |
SteveSegreto
Posts: 32
Joined: Sun Sep 12, 2010 10:25 am

Re: [C++, DX9] btTriangleIndexVertexArray issue

Post by SteveSegreto »

That's not the internal size of a single INDEX as far as bullet is concerned, it's just the stride through the IndexBuffer (to get to the next triangle, which is three indices past the first).

Have a look at the constructor that ships with Bullet 2.76:

Code: Select all

btTriangleIndexVertexArray::btTriangleIndexVertexArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride)
: m_hasAabb(0)
{
	btIndexedMesh mesh;

	mesh.m_numTriangles = numTriangles;
	mesh.m_triangleIndexBase = (const unsigned char *)triangleIndexBase;
	mesh.m_triangleIndexStride = triangleIndexStride;
	mesh.m_numVertices = numVertices;
	mesh.m_vertexBase = (const unsigned char *)vertexBase;
	mesh.m_vertexStride = vertexStride;

	addIndexedMesh(mesh);

}
Now have a look at "addIndexedMesh"

Code: Select all

	void	addIndexedMesh(const btIndexedMesh& mesh, PHY_ScalarType indexType = PHY_INTEGER)
	{
		m_indexedMeshes.push_back(mesh);
		m_indexedMeshes[m_indexedMeshes.size()-1].m_indexType = indexType;
	}
Notice three things:

#1. The constructor doesn't allow you to change the default parameters to addIndexedMesh.
#2. The default value for indexType is PHY_INTEGER and it's used.
#3. PHY_INTEGER is 32-bits wide, your index buffer is an array of 16-bit shorts by default in DirectX.

Which leads us back to what I first said:

You need to either change your index format to INT in DirectX or change it to PHY_SHORT in Bullet.

So what you have told Bullet about your index buffer is this:

Each element is one 32-bit index.
A triangle consists of 3 32-bit indices and the next triangle can be found 96 bits after the first.

However, the default Index setup in DirectX 9.0 gives you this:

Each element is one 16-bit index.
A triangle consists of 3 16-bit indices and the next triangle can be found 48 bits after the first.

Does this make more sense to you?
Ripiz
Posts: 47
Joined: Mon Aug 16, 2010 10:43 am

Re: [C++, DX9] btTriangleIndexVertexArray issue

Post by Ripiz »

SteveSegreto wrote:So what you have told Bullet about your index buffer is this:
Each element is one 32-bit index.
A triangle consists of 3 32-bit indices and the next triangle can be found 96 bits after the first.

However, the default Index setup in DirectX 9.0 gives you this:
Each element is one 16-bit index.
A triangle consists of 3 16-bit indices and the next triangle can be found 48 bits after the first.
I understand that, that's why I had these lines:

Code: Select all

   int *dataIndex = new int[numIndex];
   for(DWORD i = 0; i < numIndex; i++)
      dataIndex[i] = pIndexData[i];
Which you probably didn't notice.

But while I was posting this, I noticed few mistakes in my code.
I was locking Index Buffer as byte, but I needed unsigned short, so I changed that.
Then I noticed my whole vertex loop is wrong too, so I had to change it too.
Now I have these:

Code: Select all

	LPDIRECT3DVERTEXBUFFER9 pVertices;
	Mesh->GetVertexBuffer(&pVertices);
	uint VertexSize = Mesh->GetNumBytesPerVertex() / 4;
	float *pVertexData = 0;
	uint numVertices = Mesh->GetNumVertices();
	float *dataVertex = new float[numVertices * 3];
	pVertices->Lock( 0, 0, ( void** )&pVertexData, 0 );
	for(uint i = 0; i < numVertices; i++){
		dataVertex[i * 3 + 0] = (pVertexData + i * VertexSize)[0];
		dataVertex[i * 3 + 1] = (pVertexData + i * VertexSize)[1];
		dataVertex[i * 3 + 2] = (pVertexData + i * VertexSize)[2];
	}
	pVertices->Unlock();
	pVertices->Release();

	// get index data
	LPDIRECT3DINDEXBUFFER9 pIndices;
	Mesh->GetIndexBuffer(&pIndices);
	unsigned short* pIndexData;
	pIndices->Lock(0, 0, (void**)&pIndexData, 0);
	uint numIndex = Mesh->GetNumFaces() * 3;
	int *dataIndex = new int[numIndex];
	for(DWORD i = 0; i < numIndex; i++)
		dataIndex[i] = pIndexData[i];
	pIndices->Unlock();
	pIndices->Release();

However my application still crashes. It takes really long time to create collisions for all models, then it crashes because of wrong device state (I guess long inactivity causes device to be lost?).
I'll try to delay loading or something, then tell how it did go.
Post Reply