Author Topic: getting Indexbuffer from Object 3d  (Read 3882 times)

Offline javamak

  • byte
  • *
  • Posts: 13
    • View Profile
getting Indexbuffer from Object 3d
« on: December 16, 2015, 04:25:01 pm »
Hello,

I am trying to create a TriangleIndexVertexArray Object from Object3D for GImpactMeshShape (JBullet intergration). How do I get the IndexBuffer? The below code works for BvhTriangleMeshShape but GImpactMeshShape  throws IndexOutOfBoundsException. calculating the indexBuffer is the problem. Please help.

Code: [Select]
private static TriangleIndexVertexArray createIndexVertexArray(Object3D obj) {
RigidObject ro = RigidObjectManager.getInstance().getRigidObject(obj.getName());

int numTriangles = obj.getMesh().getTriangleCount();
int numVertices = obj.getMesh().getVertexCount();
// int numVertices = obj.getMesh().getUniqueVertexCount();
//4 represents Byte size of Integer
ByteBuffer indexBuffer = BufferUtils.createByteBuffer(numVertices * 4).order(ByteOrder.nativeOrder());
for (int i=0; i<numTriangles; i++) {

indexBuffer.putInt(i);
indexBuffer.putInt(i);
indexBuffer.putInt(i);
}

ByteBuffer vertexBuffer = BufferUtils.createByteBuffer(numVertices * 4).order(ByteOrder.nativeOrder());
vertexBuffer.clear();

SimpleVector[] vertices = ro.getvController().getSourceMesh();
for (int i = 0; i < vertices.length; i++) {
vertexBuffer.putFloat(vertices[i].x);
vertexBuffer.putFloat(vertices[i].y);
vertexBuffer.putFloat(vertices[i].z);
}
vertexBuffer.rewind();
indexBuffer.rewind();

TriangleIndexVertexArray vertexArray = new TriangleIndexVertexArray(numTriangles, indexBuffer, 3*4, obj.getMesh().getVertexCount(), vertexBuffer, 3*4);
return vertexArray;
}

Thanks.

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12298
    • View Profile
    • http://www.jpct.net
Re: getting Indexbuffer from Object 3d
« Reply #1 on: December 16, 2015, 04:39:03 pm »
I'm not sure what this index buffer is supposed to store, but I guess these are the indices to the vertices that form a triangle!? In that case, your approach to create the index buffer is wrong...it's more complicated than that, I'm afraid. The VertexController gives you access to the vertices. It doesn't hold any information about the triangle to which a vertex belongs. Then, there's also the PolygonManager which gives you access to polygon informations, but it doesn't care about the vertex itself. You have to combine the information from both to get what you want, i.e. do something like:

  • store all vertex information obtained from the VertexController
  • make sure that no rotation, no translation and scale are applied to the object in question at that stage
  • obtain the PolygonManager from the object
  • iterate over all polygons and all (transformed) vertices of each polygon
  • ...because no transformations are applied, these vertices will be equal to the ones in your vertex array which you've created above
  • ...with that in mind, find the corresponding vertex in that array
  • ...and that's your index!

Offline javamak

  • byte
  • *
  • Posts: 13
    • View Profile
Re: getting Indexbuffer from Object 3d
« Reply #2 on: December 16, 2015, 06:14:41 pm »
how to iterate over the polygons? pMgr.getTransformedVertex(polyID, vertexNumber)  I just see this method to get the vertex.

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12298
    • View Profile
    • http://www.jpct.net
Re: getting Indexbuffer from Object 3d
« Reply #3 on: December 16, 2015, 06:58:30 pm »
By counting the polyId up from 0 to the maximum!?

Offline javamak

  • byte
  • *
  • Posts: 13
    • View Profile
Re: getting Indexbuffer from Object 3d
« Reply #4 on: December 17, 2015, 06:24:14 am »
Thanks Egon. Got it working now. There were two mistakes
1. Wrong indices
2. Wrong vertex length passed to the TriangleIndexVertexArray Constructor. (Reason for the IndexOutofBoundException).

final code:
Code: [Select]
private ByteBuffer createIndexBuffer() {
setvController(new VertexController(object3D));

ByteBuffer indexBuffer = BufferUtils.createByteBuffer(object3D.getMesh().getVertexCount() * 4).order(ByteOrder.nativeOrder());
indexBuffer.clear();

PolygonManager pMgr = object3D.getPolygonManager();
SimpleVector vertices[] = vController.getSourceMesh();
SimpleVector vertex;
int index = 0;
for (int i=0; i<pMgr.getMaxPolygonID(); i++) {
vertex = null;
for(int vertexNumber=0; vertexNumber<3; vertexNumber++) {
vertex = pMgr.getTransformedVertex(i, vertexNumber);
index = 0;
for(SimpleVector sourceVertex : vertices){
if(sourceVertex.equals(vertex)) {
indexBuffer.putInt(index);
break;
}
index++;
}
vertexNumber++;
}
}
return indexBuffer;
}


Code: [Select]
private static TriangleIndexVertexArray createIndexVertexArray(Object3D obj) {
RigidObject ro = RigidObjectManager.getInstance().getRigidObject(obj.getName());


int numTriangles = obj.getMesh().getTriangleCount();
int numVertices = obj.getMesh().getVertexCount();

ByteBuffer indexBuffer = ro.getIndexBuffer();

ByteBuffer vertexBuffer = BufferUtils.createByteBuffer(numVertices * 4).order(ByteOrder.nativeOrder());
vertexBuffer.clear();

SimpleVector[] vertices = ro.getvController().getSourceMesh();
for (int i = 0; i < vertices.length; i++) {
vertexBuffer.putFloat(vertices[i].x);
vertexBuffer.putFloat(vertices[i].y);
vertexBuffer.putFloat(vertices[i].z);
}
vertexBuffer.rewind();
indexBuffer.rewind();

TriangleIndexVertexArray vertexArray = new TriangleIndexVertexArray(numTriangles, indexBuffer, 3*4, vertices.length, vertexBuffer, 3*4);
return vertexArray;
}

Offline javamak

  • byte
  • *
  • Posts: 13
    • View Profile
Re: getting Indexbuffer from Object 3d
« Reply #5 on: December 17, 2015, 07:06:43 am »
Just another issue on the same. When I do debug draw of bullet objects there is some difference in Y axis between the Object3D and Shape and this difference only appears for Cone , Pyramid and  Cube, sphere or ellipsoid works fine. See the attachment. Both are having same GImpactShape created using the code in my previous replies.




Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12298
    • View Profile
    • http://www.jpct.net
Re: getting Indexbuffer from Object 3d
« Reply #6 on: December 17, 2015, 08:27:40 am »
Most likely a difference in the rotation pivot between both worlds. Either set the one from bullet (if possible) to the one of jPCT or vice versa. A simple "fix" might be to do a

Code: [Select]
obj.setRotationPivot(new SimpleVector());
right after calling build();.

Offline javamak

  • byte
  • *
  • Posts: 13
    • View Profile
Re: getting Indexbuffer from Object 3d
« Reply #7 on: December 17, 2015, 12:14:13 pm »
I tried it but no luck. I tried to set the setCenterOfMassTransform of the RigidBody to 0 still no luck. It is just 3 unit difference in Y axis when I add it manually it messes up for other shapes.

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12298
    • View Profile
    • http://www.jpct.net
Re: getting Indexbuffer from Object 3d
« Reply #8 on: December 17, 2015, 02:20:36 pm »
But it has to be something like that IMHO. The pivot of the cube is at 0,0,0 due to the way in which it's build. The same goes for ellipsoids and spheres. The pivot of the cone is slightly off...so it has to have something to do with it.

Offline javamak

  • byte
  • *
  • Posts: 13
    • View Profile
Re: getting Indexbuffer from Object 3d
« Reply #9 on: December 22, 2015, 01:23:41 pm »
After so many days of trial and error, adding obj.setCenter(new SimpleVector(0, 0, 0)); after build has fixed my problem.

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12298
    • View Profile
    • http://www.jpct.net
Re: getting Indexbuffer from Object 3d
« Reply #10 on: December 22, 2015, 03:18:01 pm »
The center and the rotation pivot contain the same value after build(). Usually, the center has no purpose except for collision detection methods and such. I don't see how should be related to your problem....however, as long as it helps, all is well...