I am trying to patch up an OBJ loading class, as it only supported Short numbers, and I have a large OBJ that goes above the Short number limit.
I had to change the code to use Integer Vectors (instead of Short ones) and a ShortBuffer was changed to an IntBuffer.
Now, the basic OBJ I had (10,000 lines) which used to load in 3 seconds, no longer loads at all and gives me a BufferOverflowException.
Below is the problematic chunk of code:
ByteBuffer fBuf = ByteBuffer.allocateDirect(faces.size() * 2);
fBuf.order(ByteOrder.nativeOrder());
faceBuffer = fBuf.asIntBuffer();
faceBuffer.put(toPrimitiveArrayS(faces)); // this gives the exception
faceBuffer.position(0);
Below is the function toPrimitiveArrayS
private static int[] toPrimitiveArrayS(Vector<Integer> vector){
int[] s;
s = new int[vector.size()];
for (int i=0; i<vector.size(); i++){
s[i] = vector.get(i);
}
return s;
}
Oddly, if I changed the 2 to a 4 in allocateDirect, the model loads, but is rendered incorrectly (previously, it loaded fine with that number as 2, so I only just changed it to see)
Full class code below:
public class TDModelPart {
Vector<Integer> faces;
Vector<Integer> vtPointer;
Vector<Integer> vnPointer;
Material material;
private FloatBuffer normalBuffer;
IntBuffer faceBuffer;
public TDModelPart(Vector<Integer> faces, Vector<Integer> vtPointer, Vector<Integer> vnPointer, Material material, Vector<Float> vn) {
super();
this.faces = faces;
this.vtPointer = vtPointer;
this.vnPointer = vnPointer;
this.material = material;
ByteBuffer byteBuf = ByteBuffer.allocateDirect(vnPointer.size() * 4 * 3);
byteBuf.order(ByteOrder.nativeOrder());
normalBuffer = byteBuf.asFloatBuffer();
for(int i=0; i<vnPointer.size(); i++){
float x=vn.get(vnPointer.get(i)*3);
float y=vn.get(vnPointer.get(i)*3+1);
float z=vn.get(vnPointer.get(i)*3+2);
normalBuffer.put(x);
normalBuffer.put(y);
normalBuffer.put(z);
}
normalBuffer.position(0);
ByteBuffer fBuf = ByteBuffer.allocateDirect(faces.size() * 2);
fBuf.order(ByteOrder.nativeOrder());
faceBuffer = fBuf.asIntBuffer();
faceBuffer.put(toPrimitiveArrayS(faces));
faceBuffer.position(0);
}
public String toString(){
String str=new String();
if(material!=null)
str+="Material name:"+material.getName();
else
str+="Material not defined!";
str+="\nNumber of faces:"+faces.size();
str+="\nNumber of vnPointers:"+vnPointer.size();
str+="\nNumber of vtPointers:"+vtPointer.size();
return str;
}
public IntBuffer getFaceBuffer(){
return faceBuffer;
}
public FloatBuffer getNormalBuffer(){
return normalBuffer;
}
private static int[] toPrimitiveArrayS(Vector<Integer> vector){
int[] s;
s = new int[vector.size()];
for (int i=0; i<vector.size(); i++){
s[i] = vector.get(i);
}
return s;
}
public int getFacesCount(){
return faces.size();
}
public Material getMaterial(){
return material;
}
}