[SOLVED] BufferUtils + random errors + memory issues

/sigh… I seem to be having significant issues using the BufferUtils class.

I put together a relatively simple test to try and narrow down the issue… and here is what the test consists of:

I load a .j3o and extract the buffers like so:

[java]
Mesh template = ((Geometry)((Node)assetManager.loadModel(“Models/SomeRandomJ3O.j3o”)).getChild(0)).getMesh();

// Extract template buffers
FloatBuffer verts = template.getFloatBuffer(VertexBuffer.Type.Position);
FloatBuffer coords = template.getFloatBuffer(VertexBuffer.Type.TexCoord);
ShortBuffer indexes = template.getShortBuffer(VertexBuffer.Type.Index);
FloatBuffer normals = template.getFloatBuffer(VertexBuffer.Type.Normal);
[/java]

I pass these into a custom mesh and only attempt to recreate the buffers as they exist by creating an empty buffer of the appropriate type using the template buffers limit as a size… like such:

[java]
this.finVerts = BufferUtils.createFloatBuffer(templateVerts.limit());
this.finCoords = BufferUtils.createFloatBuffer(templateCoords.limit());
this.finIndexes = BufferUtils.createShortBuffer(templateIndexes.limit());
this.finNormals = BufferUtils.createFloatBuffer(templateNormals.limit());
[/java]

Then I proceed to populate the buffers by looping through the original using .get() and.put():

[java]
Quaternion qR = new Quaternion();
qR = qR.fromAngleAxis( ((float)(Math.random()*360f))2fFastMath.DEG_TO_RAD, Vector3f.UNIT_Y);
Vector3f position = new Vector3f(someXValue, someYValue, someZValue);
Vector3f tempVec = new Vector3f();

int index = 0;
for (int v = 0; v < templateVerts.limit(); v += 3) {
tempVec.set(templateVerts.get(v), templateVerts.get(v+1), templateVerts.get(v+2));
tempVec = qR.mult(tempVec);
tempVec.add(position);
finVerts.put(index, tempVec.getX());
finVerts.put(index+1, tempVec.getY());
finVerts.put(index+2, tempVec.getZ());
index += 3;
}

index = 0;
for (int v = 0; v < templateCoords.limit(); v++) {
finCoords.put(index, templateCoords.get(v));
index++;
}

index = 0;
for (int v = 0; v < templateIndexes.limit(); v++) {
finIndexes.put(index, templateIndexes.get(v));
index++;
}

index = 0;
for (int v = 0; v < templateNormals.limit(); v++) {
finNormals.put(index, templateNormals.get(v));
index++;
}

this.clearBuffer(Type.Position);
this.setBuffer(Type.Position, 3, finVerts);
this.clearBuffer(Type.TexCoord);
this.setBuffer(Type.TexCoord, 2, finCoords);
this.clearBuffer(Type.Index);
this.setBuffer(Type.Index, 3, finIndexes);
this.clearBuffer(Type.Normal);
this.setBuffer(Type.Normal, 3, finNormals);
this.updateBound();
[/java]

Sometimes this works, other times I get random indexOutOfBounds exceptions, sometimes I get OutOfMemory exceptions.

There doesn't seem to be any common factor as I am running the exact same code, but getting random results.

Anyone have ANY clue as to why this is happening?

Forgot to mention a few things. Loading the template mesh and extracting the buffers only happens once. I create multiple instance of the custom mesh… and each one either a) succeeds b) throws the indexOutOfBounds exception or c) oom… etc, etc, amen.

I had a quick scan through and couldn’t see any obvious errors. One thing I did see though is lots of get by index - which is slow. Doing get() get() get() is faster than get(0), get(1), get(2).

Maybe you are confusing limit and capacity somewhere in the code?

1 Like

@zarch the javadoc info on capacity and limit are vaaaaaaaague. What is the difference and which should be used to ensure that both buffer are the same size?

capacity is the capacity of the buffer. The actual size of the underlying “array”.

limit is a limit on what you can write to the buffer at a given time. It’s potentially temporary since it can be reset.

Which I guess is pretty much just restating the Buffer javadocs:
http://docs.oracle.com/javase/6/docs/api/java/nio/Buffer.html

A buffer's capacity is the number of elements it contains. The capacity of a buffer is never negative and never changes.

A buffer’s limit is the index of the first element that should not be read or written. A buffer’s limit is never negative and is never greater than its capacity.

1 Like

Thanks a ton both of you… I was in the middle of putting together a test case and decided… wtf… I’ll change limit to capacity and see what happens (while waiting for a response). And of course this would be the reason for the random index out of bounds and oom errors.

I really appreciate it, as I have been working on this on and off for quite some time >.<

Yep… not the brightest bulb in the six-pack.

Actually… I wanted to share the extent of my frustration. These errors were occurring with really simple objects… and I’m pulling my hair out trying to figure out how JME is able to import extremely complex object and NEVER hit the same issues >.< This makes me a very happy girl!!

@zarch I love the subtle hint… Maybe you’re confusing capacity and limit somewhere in the code?

Yep… that was um… EVERYWHERE! hahahaha

:wink:

Honestly I didn’t look enough to be sure but it seemed the most likely cause of non-deterministic behaviour.