How do I properly use a TriangleIndexVertexArray?

Post Reply
joehot200
Posts: 15
Joined: Wed Apr 23, 2014 9:47 am

How do I properly use a TriangleIndexVertexArray?

Post by joehot200 »

I'm trying to use JBullet to make a TriangleIndexVertexArray.

Code: Select all

TriangleIndexVertexArray trSh = new TriangleIndexVertexArray(mod.faces.size(), inBuf, 4 * 3, mod.vertices.size(), veBuf, 4 * 3);
However, when I try to add this to a BvhTriangleMeshShape, it throws an IndexOutOfBoundsException, on this line:

Code: Select all

shape = new BvhTriangleMeshShape(trSh, true);
I believe that the issue is that I am supplying the wrong values to TriangleIndexVertexArray, but I cannot work out how. What is the value I am passing wrongly here?

inBuf and veBuf are both just ByteBuffers of all the vertex and index data. I don't think there's anything wrong there.

Code: Select all

// There are 3 floats needed for each vertex (x,y,z)
	    	int vbufferSize = sh.size() * 3 * Float.SIZE;
	    	FloatBuffer verticesBuffer = ByteBuffer.allocateDirect( vbufferSize ).order( ByteOrder.nativeOrder() ).asFloatBuffer();

	    	// Copy the values from the list to the direct float buffer
	    	for ( Vector3f v : sh )
	    	    verticesBuffer.put( v.x ).put( v.y ).put( v.z );
	    	
	    	
	    	// There are 3 floats needed for each vertex (x,y,z)
	    	int fbufferSize = sh.size() * 3 * Float.SIZE;
	    	FloatBuffer facesBuffer = ByteBuffer.allocateDirect( fbufferSize ).order( ByteOrder.nativeOrder() ).asFloatBuffer();

	    	// Copy the values from the list to the direct float buffer
	    	for ( Face v : mod.getFaces() ){
	    		int[] ind = v.getVertexIndices();
	    		facesBuffer.put( ind[0] ).put( ind[1] ).put( ind[2] );
	    	}


	    	ByteBuffer veBuf = (ByteBuffer) ((sun.nio.ch.DirectBuffer)verticesBuffer).attachment();
	    	ByteBuffer inBuf = (ByteBuffer) ((sun.nio.ch.DirectBuffer)facesBuffer).attachment();
I'm using 4 * 3 because in this line of code I got from an example.

Code: Select all

//TriangleIndexVertexArray indexVertexArrays=new TriangleIndexVertexArray(Bunny.NUM_TRIANGLES,Bunny.getIndexBuffer(),4 * 3,Bunny.NUM_VERTICES,Bunny.getVertexBuffer(),4 * 3);
Is this wrong? What should I use instead?

Code: Select all

mod.faces.size()
is the amount of faces (this is the same as the amount of indices, right?) there are in the model, and of course

Code: Select all

mod.vertices.size()
is the amount of vertices in the model.

I cannot find any proper documentation, so I am hoping someone can help me: What am I parsing wrongly to the TriangleIndexVertexArray?

Thanks!
aviator
Posts: 13
Joined: Thu Apr 02, 2015 5:15 pm

Re: How do I properly use a TriangleIndexVertexArray?

Post by aviator »

joehot200 wrote:I'm trying to use JBullet to make a TriangleIndexVertexArray.

Code: Select all

TriangleIndexVertexArray trSh = new TriangleIndexVertexArray(mod.faces.size(), inBuf, 4 * 3, mod.vertices.size(), veBuf, 4 * 3);
However, when I try to add this to a BvhTriangleMeshShape, it throws an IndexOutOfBoundsException, on this line:

Code: Select all

shape = new BvhTriangleMeshShape(trSh, true);
I believe that the issue is that I am supplying the wrong values to TriangleIndexVertexArray, but I cannot work out how. What is the value I am passing wrongly here?

inBuf and veBuf are both just ByteBuffers of all the vertex and index data. I don't think there's anything wrong there.

Code: Select all

// There are 3 floats needed for each vertex (x,y,z)
	    	int vbufferSize = sh.size() * 3 * Float.SIZE;
	    	FloatBuffer verticesBuffer = ByteBuffer.allocateDirect( vbufferSize ).order( ByteOrder.nativeOrder() ).asFloatBuffer();

	    	// Copy the values from the list to the direct float buffer
	    	for ( Vector3f v : sh )
	    	    verticesBuffer.put( v.x ).put( v.y ).put( v.z );
	    	
	    	
	    	// There are 3 floats needed for each vertex (x,y,z)
	    	int fbufferSize = sh.size() * 3 * Float.SIZE;
	    	FloatBuffer facesBuffer = ByteBuffer.allocateDirect( fbufferSize ).order( ByteOrder.nativeOrder() ).asFloatBuffer();

	    	// Copy the values from the list to the direct float buffer
	    	for ( Face v : mod.getFaces() ){
	    		int[] ind = v.getVertexIndices();
	    		facesBuffer.put( ind[0] ).put( ind[1] ).put( ind[2] );
	    	}


	    	ByteBuffer veBuf = (ByteBuffer) ((sun.nio.ch.DirectBuffer)verticesBuffer).attachment();
	    	ByteBuffer inBuf = (ByteBuffer) ((sun.nio.ch.DirectBuffer)facesBuffer).attachment();
I'm using 4 * 3 because in this line of code I got from an example.

Code: Select all

//TriangleIndexVertexArray indexVertexArrays=new TriangleIndexVertexArray(Bunny.NUM_TRIANGLES,Bunny.getIndexBuffer(),4 * 3,Bunny.NUM_VERTICES,Bunny.getVertexBuffer(),4 * 3);
Is this wrong? What should I use instead?

Code: Select all

mod.faces.size()
is the amount of faces (this is the same as the amount of indices, right?) there are in the model, and of course

Code: Select all

mod.vertices.size()
is the amount of vertices in the model.

I cannot find any proper documentation, so I am hoping someone can help me: What am I parsing wrongly to the TriangleIndexVertexArray?

Thanks!
Hello !

Actually somewhere there was a post about this.
But I will post it once more:
numTriangles: number of triangles
triangleIndexBase: the array of vertex indices that makes up the triangles
triangleIndexStride: the number of bytes to skip in the vertex indices array to go from the start of one triangle to the start of the next triangle. Typically this is 3 times the sizeof the vertex index type.
numVertices: number of vertices
vertexBase: the array of vertex positions
vertexStride: the number of bytes to skip in the vertex position array to go from the start of one vertex to the start of the next vertex.
If the vertex position is composed of 3 floats for example, then this would be 3*sizeof(float).
If it is 3 doubles with 1 double as padding, then 4*sizeof(double), for example.
So:

Code: Select all

int				vertexCount_;
int				indiciesCount_;

float*			vertices;
int*				indicies;

btTriangleMeshShape*			fsTrimeshShape;
btTriangleIndexVertexArray*		indexVertexArray;
btCollisionShape*	colShape;

indexVertexArray = new btTriangleIndexVertexArray(indiciesCount_, indicies, 3 * sizeof(int),
		vertexCount_, vertices, 3 * sizeof(float));

fsTrimeshShape = new btBvhTriangleMeshShape(indexVertexArray, true);

colShape = fsTrimeshShape;
Oops missed JBullet part ... but hopefully this will be helpful.
joehot200
Posts: 15
Joined: Wed Apr 23, 2014 9:47 am

Re: How do I properly use a TriangleIndexVertexArray?

Post by joehot200 »

aviator wrote: Hello !

Actually somewhere there was a post about this.
But I will post it once more:
numTriangles: number of triangles
triangleIndexBase: the array of vertex indices that makes up the triangles
triangleIndexStride: the number of bytes to skip in the vertex indices array to go from the start of one triangle to the start of the next triangle. Typically this is 3 times the sizeof the vertex index type.
numVertices: number of vertices
vertexBase: the array of vertex positions
vertexStride: the number of bytes to skip in the vertex position array to go from the start of one vertex to the start of the next vertex.
If the vertex position is composed of 3 floats for example, then this would be 3*sizeof(float).
If it is 3 doubles with 1 double as padding, then 4*sizeof(double), for example.
So:

Code: Select all

int				vertexCount_;
int				indiciesCount_;

float*			vertices;
int*				indicies;

btTriangleMeshShape*			fsTrimeshShape;
btTriangleIndexVertexArray*		indexVertexArray;
btCollisionShape*	colShape;

indexVertexArray = new btTriangleIndexVertexArray(indiciesCount_, indicies, 3 * sizeof(int),
		vertexCount_, vertices, 3 * sizeof(float));

fsTrimeshShape = new btBvhTriangleMeshShape(indexVertexArray, true);

colShape = fsTrimeshShape;
Oops missed JBullet part ... but hopefully this will be helpful.
Definitely helpful - The exact information I needed.

Unfortunately, it is still throwing the same Exception.

My current code is:

Code: Select all

TriangleIndexVertexArray trSh = new TriangleIndexVertexArray(mod.faces.size(), inBuf, 3 * Float.SIZE, mod.vertices.size(), veBuf, 3 * Float.SIZE);
Have you got any idea what's wrong here?
aviator
Posts: 13
Joined: Thu Apr 02, 2015 5:15 pm

Re: How do I properly use a TriangleIndexVertexArray?

Post by aviator »

joehot200 wrote:
aviator wrote: Hello !

Actually somewhere there was a post about this.
But I will post it once more:
numTriangles: number of triangles
triangleIndexBase: the array of vertex indices that makes up the triangles
triangleIndexStride: the number of bytes to skip in the vertex indices array to go from the start of one triangle to the start of the next triangle. Typically this is 3 times the sizeof the vertex index type.
numVertices: number of vertices
vertexBase: the array of vertex positions
vertexStride: the number of bytes to skip in the vertex position array to go from the start of one vertex to the start of the next vertex.
If the vertex position is composed of 3 floats for example, then this would be 3*sizeof(float).
If it is 3 doubles with 1 double as padding, then 4*sizeof(double), for example.
So:

Code: Select all

int				vertexCount_;
int				indiciesCount_;

float*			vertices;
int*				indicies;

btTriangleMeshShape*			fsTrimeshShape;
btTriangleIndexVertexArray*		indexVertexArray;
btCollisionShape*	colShape;

indexVertexArray = new btTriangleIndexVertexArray(indiciesCount_, indicies, 3 * sizeof(int),
		vertexCount_, vertices, 3 * sizeof(float));

fsTrimeshShape = new btBvhTriangleMeshShape(indexVertexArray, true);

colShape = fsTrimeshShape;
Oops missed JBullet part ... but hopefully this will be helpful.
Definitely helpful - The exact information I needed.

Unfortunately, it is still throwing the same Exception.

My current code is:

Code: Select all

TriangleIndexVertexArray trSh = new TriangleIndexVertexArray(mod.faces.size(), inBuf, 3 * Float.SIZE, mod.vertices.size(), veBuf, 3 * Float.SIZE);
Have you got any idea what's wrong here?
Can you debug and show values what exactly you have got in these: mod.faces.size(), inBuf, 3 * Float.SIZE, mod.vertices.size(), veBuf, 3 * Float.SIZE but with a really small shape like 2 triangles ?

In theory this should work:

Code: Select all

int            vertexCount_;
int            indiciesCount_; //Triangle count

float*         vertices;
int*           indicies; //Triangles

vertexCount_ = 6;
indiciesCount_ = 2;

vertices = new float[12]
{
	-10.0f, -10.0f, 0.0f,
	-10.0f, 10.0f, 0.0f,
	10.0f, 10.0f, 0.0f,
	10.0f, -10.0f, 0.0f
};

indicies = new int[6]
{
	0, 1, 3,
	3, 2, 1
};


btTriangleMeshShape*         fsTrimeshShape;
btTriangleIndexVertexArray*      indexVertexArray;
btCollisionShape*   colShape;

indexVertexArray = new btTriangleIndexVertexArray(indiciesCount_, indicies, 3 * sizeof(int),
      vertexCount_, vertices, 3 * sizeof(float));

fsTrimeshShape = new btBvhTriangleMeshShape(indexVertexArray, true);

colShape = fsTrimeshShape;
LastBlow
Posts: 18
Joined: Mon Jul 11, 2016 10:36 am
Location: SAN DIEGO

Re: How do I properly use a TriangleIndexVertexArray?

Post by LastBlow »

The point is that Blender names the vertices starting at 1 while Bullet Physics starts at 0.
Here below another example, the cube mesh.

Code: Select all

const int NUMBER_VERTICES = 8;
const int NUMBER_TRIANGLES = 12;


static float bunnyVertices[NUMBER_VERTICES * 3] = {
	1.000000, -1.000000, -1.000000,
	1.000000, -1.000000, 1.000000,
	-1.000000, -1.000000, 1.000000,
	-1.000000, -1.000000, -1.000000,
	1.000000, 1.000000, -0.999999,
	0.999999, 1.000000, 1.000001,
	-1.000000, 1.000000, 1.000000,
	-1.000000, 1.000000, -1.000000
};

static int bunnyIndices[NUMBER_TRIANGLES][3] = {
	{ 1, 3, 0 },
	{ 7, 5, 4 },
	{ 4, 1, 0 },
	{ 5, 2, 1 },
	{ 2, 7, 3 },
	{ 0, 7, 4 },
	{ 1, 2, 3 },
	{ 7, 6, 5 },
	{ 4, 5, 1 },
	{ 5, 6, 2 },
	{ 2, 6, 7 },
	{ 0, 3, 7 }
};
Post Reply