Page 1 of 1

How do I properly use a TriangleIndexVertexArray?

Posted: Sun May 10, 2015 10:42 pm
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!

Re: How do I properly use a TriangleIndexVertexArray?

Posted: Mon May 11, 2015 9:02 am
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.

Re: How do I properly use a TriangleIndexVertexArray?

Posted: Mon May 11, 2015 4:34 pm
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?

Re: How do I properly use a TriangleIndexVertexArray?

Posted: Mon May 18, 2015 1:48 pm
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;

Re: How do I properly use a TriangleIndexVertexArray?

Posted: Sun Nov 12, 2017 1:29 am
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 }
};