arne
Senior Member   
money is the worst drug- we should not let it rule
|
 |
«
Posted
2005-10-12 01:02:54 » |
|
Hi I sometimes get the following Exception: 1 2 3 4 5 6 7 8 9 10 11 12
| java.nio.BufferUnderflowException at java.nio.Buffer.nextGetIndex(Buffer.java:398) at java.nio.DirectFloatBufferU.get(DirectFloatBufferU.java:205) at com.xith3d.scenegraph.GeomNioFloatData.get(GeomNioFloatData.java:80) at com.xith3d.scenegraph.GeomContainer.getCoordinate(GeomContainer.java:1197) at com.xith3d.scenegraph.GeomContainer.getVertex(GeomContainer.java:1337) at com.xith3d.spatial.bounds.Sphere.compute(Sphere.java:317) at com.xith3d.scenegraph.Node.updateBounds(Node.java:358) at com.xith3d.scenegraph.Node.setParent(Node.java:283) at com.xith3d.scenegraph.Group.addChild(Group.java:83) at objects.Tree.TreeGenerator.calculateSimplification(TreeGenerator.java:253) at objects.Tree.TreeGenerator$1.run(TreeGenerator.java:325) |
It seems as if this is a problem with my Geometry, but I'm wondering, because it doesn't get thrown, when I create the geom or add Geometry to it, nor when I add the Geometry to the Shape, but when the Shape get's added to the Scenegraph. This is also the same time it get's live. Mmh... maybe this could be the problem... But anyways if I add wrong data shouldn't there be an error-message earlier? I'd also like to know what I'm doing wrong (as I said it sometimes works - even at the same point, but I use random generated vertex-data, so this is hard to debug (without risking a not readable output)) if somebody has an idea, please tell me. Arne
|
|
|
|
hawkwind
Junior Member  
Java games rock!
|
 |
«
Reply #1 - Posted
2005-10-12 01:07:07 » |
|
Yoicks!!!! I haver never seen this...ever..really. I makes me wonder if its your setup somehow.
|
|
|
|
|
arne
Senior Member   
money is the worst drug- we should not let it rule
|
 |
«
Reply #2 - Posted
2005-10-12 01:16:16 » |
|
Yeah - I had never had this error before either. And all my other code still works. Could it be the problem, that I very often create big shapes with loads of Triangles and then garbage-collect them (with Branchgroup.removeAllChildren(), removing all references and then System.gc())?
|
|
|
|
Games published by our own members! Check 'em out!
|
|
William Denniss
|
 |
«
Reply #3 - Posted
2005-10-12 03:10:47 » |
|
I'm not surprised it wouldn't fail when adding the geometry data because it is an underflow not overflow exception.
Some background: A buffer overflow will happen when you are trying to add too many bytes to a buffer, and underflow will happen when you are trying to read too many bytes from a buffer.
Sphere is iterating through all the vertexes using "getVertexCount()" on your geometry which for whatever reason is returning an incorrect value. This value is set manually when you initialise the object and NOT automatically (in most cases). Check this value in your code (normally equal to size of data / 3).
It might be better to not have the user specify this value at all.
Will.
|
|
|
|
arne
Senior Member   
money is the worst drug- we should not let it rule
|
 |
«
Reply #4 - Posted
2005-10-12 12:54:18 » |
|
The number of vertices should be coorect: I do this 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| System.out.println(h.size()); TriangleArray ta = new TriangleArray(h.size()*3,GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.TEXTURE_COORDINATE_2); int i = 0; for(float[] f : h) { System.out.print("."); float[] face = new float[9]; float[] uv = new float[6]; System.arraycopy(f,0,face,0,9); ta.setCoordinates(i*3,face); System.arraycopy(f,9,face,0,9); ta.setNormals(i*3,face); System.arraycopy(f,18,uv,0,6); ta.setTextureCoordinates(0,i*3,uv); i++; } System.out.println(i); root.removeAllChildren(); System.gc(); Shape3D tree = createShape(ta); root.addChild(tree); |
|
|
|
|
arne
Senior Member   
money is the worst drug- we should not let it rule
|
 |
«
Reply #5 - Posted
2005-10-18 19:35:46 » |
|
so no ideas?  ok then I'll step into the depth of xith to find the error 
|
|
|
|
arne
Senior Member   
money is the worst drug- we should not let it rule
|
 |
«
Reply #6 - Posted
2005-10-19 21:08:04 » |
|
Yes it seems, this error get thrown, because it's not able to read the z coordinate of the next vertex. I simplified my code. Even this doesn't work: 1 2 3 4 5 6 7 8 9 10 11 12 13 14
| System.out.println(h.size()); TriangleArray ta = new TriangleArray(h.size()*3,GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.TEXTURE_COORDINATE_2); float[] coordinates,normals,tex; coordinates = new float[h.size()*9]; normals = new float[h.size()*9]; tex = new float[h.size()*6];
ta.setCoordinates(0,coordinates); ta.setNormals(0,normals); ta.setTextureCoordinates(0,0,tex); System.out.println(ta.getVertexCount()); System.out.println(ta.getValidVertexCount()); Shape3D tree = createShape(ta); root.addChild(tree); |
Wit that as the output: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 24608 73824 73824 Exception in thread "Thread-2" java.nio.BufferUnderflowException at java.nio.Buffer.nextGetIndex(Buffer.java:398) at java.nio.DirectFloatBufferU.get(DirectFloatBufferU.java:205) at com.xith3d.scenegraph.GeomNioFloatData.get(GeomNioFloatData.java:80) at com.xith3d.scenegraph.GeomContainer.getCoordinate(GeomContainer.java:1197) at com.xith3d.scenegraph.GeomContainer.getVertex(GeomContainer.java:1337) at com.xith3d.spatial.bounds.Sphere.compute(Sphere.java:235) at com.xith3d.scenegraph.Node.updateBounds(Node.java:358) at com.xith3d.scenegraph.Node.setParent(Node.java:283) at com.xith3d.scenegraph.Group.addChild(Group.java:83) at objects.Tree.TreeGenerator.calculateSimplification(TreeGenerator.java:269) at objects.Tree.TreeGenerator$1.run(TreeGenerator.java:342) |
Strange isn't it? all numbers are multiples of three, so how can there be no more elements in the buffer? + My Algorithm exectutes that part of code multiple times. During the same execution I get before this error occurs this output, for that part of the code: No - I've copied the correct part of the output - the numbers are just the same. It runs this code without problems and then for the next iteration, it throws that error, but sometimes it also throws the error, when that part of the code gets executed the first time. It's so weird  I have no idea what's going wrong  Arne
|
|
|
|
William Denniss
|
 |
«
Reply #7 - Posted
2005-10-21 05:36:54 » |
|
Sorry for the delay, I have been on a short holiday. 1
| TriangleArray ta = new TriangleArray(h.size()*3,GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.TEXTURE_COORDINATE_2); |
Are you sure that shouldn't be: 1
| TriangleArray ta = new TriangleArray(h.size()/3,GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.TEXTURE_COORDINATE_2); |
(note the division instead of multiplication) Will.
|
|
|
|
arne
Senior Member   
money is the worst drug- we should not let it rule
|
 |
«
Reply #8 - Posted
2005-10-21 19:35:16 » |
|
nope - h contains triangles and not Floats. If you would have looked more closely at the code, you would have seen, that I call 1
| coordinates = new float[h*9]; |
(note the *9 ) Arme
|
|
|
|
William Denniss
|
 |
«
Reply #9 - Posted
2005-10-22 02:34:43 » |
|
Ah, I was looking at the other code which doesn't have that line.
Can you add some debug statements in GeomNioFloatData to print the size of the buffer and compare?
Will.
|
|
|
|
Games published by our own members! Check 'em out!
|
|
arne
Senior Member   
money is the worst drug- we should not let it rule
|
 |
«
Reply #10 - Posted
2005-10-22 23:36:26 » |
|
Ok I changed the GeomNioFloatData.get(int,Tuple3f) to 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public void get( int index, Tuple3f value) { buffer.position(index*3); System.out.println(index+" : "+buffer.remaining()+" : "+buffer.limit()); try { value.x = buffer.get(); value.y = buffer.get(); value.z = buffer.get(); } catch(BufferUnderflowException ex) { System.out.flush(); ex.printStackTrace(); System.err.flush(); System.exit(1); } System.out.println("no error"); } |
As a result I get: 1 2 3 4 5 6 7 8 9 10 11 12 13
| ... 12984 : 9 : 38961 no error 12985 : 6 : 38961 no error 12986 : 3 : 38961 no error 8089 : 14694 : 38961 java.nio.BufferUnderflowException at java.nio.Buffer.nextGetIndex(Buffer.java:398) at java.nio.DirectFloatBufferU.get(DirectFloatBufferU.java:205) at com.xith3d.scenegraph.GeomNioFloatData.get(GeomNioFloatData.java:82) ... |
As you can see the BufferUnderflowException gets thrown without the position being negative or greater than the limit. (8089*3 = 24267 < 38961) But it says in FloatBuffer.get() Throws: BufferUnderflowException - If the buffer's current position is not smaller than its limit
So how can this be - is that a bug in nio? Arne
|
|
|
|
William Denniss
|
 |
«
Reply #11 - Posted
2005-10-27 08:45:47 » |
|
could be - it's very strange that you would get that error with so much of the buffer remaining.
I believe in Xith3D you can use normal arrays to store geometry data instead of NIO buffers - I don't remember how you actually pick them but I have seen the code. Perhaps you could try that and see what you get?
Have you tried different versions of Java (in case the NIO bug isn't present)? I believe Blar*3 has quite a few NIO battle stories, perhaps we should direct him to this thread and get his opinion.
Will.
|
|
|
|
arne
Senior Member   
money is the worst drug- we should not let it rule
|
 |
«
Reply #12 - Posted
2005-10-27 20:55:07 » |
|
Ok I found the problem: It was because I did something very bad and which is also issued as being very bad: I had multiple Threads, one rendering the scene and one, where I created some geometry (as a result of an AWT event, so I wasn't able to use my old one) This had the effect that I changed the scenegraph during rendering - shame on me!  Ok I solved this problem now - and I'll never do any changes to the scenegraph outside the rendering thread. + If anybody comes with a mystiy error we should all ask first: are you creating your geometry outside your rendering thread?  This sure was a lesson to me ! Arne
|
|
|
|
William Denniss
|
 |
«
Reply #13 - Posted
2005-11-01 00:46:46 » |
|
Ouch, nasty bug. Pity Xith3D didn't catch it, sometimes it does but it's not guaranteed. I guess I should have raised an eyebrow at the word "sometimes", often hard to reproduce bugs are due to threading.
Well done on finding it.
Will.
|
|
|
|
rmdire
|
 |
«
Reply #14 - Posted
2006-01-31 23:49:33 » |
|
HI
What is the best way to add a new TransformGroup to my scene at runtime?
Currently I have a Global Transformgroup that I added to my scene during construction. and when schedualed - I am using my rendering loop to add a new child to this Global Transformgroup as needed. However I somtimes get a Buffer Underflow exception when I try to update these childrens positioning.
anybody help? cheers
Rmdire
|
|
|
|
|
arne
Senior Member   
money is the worst drug- we should not let it rule
|
 |
«
Reply #15 - Posted
2006-01-31 23:53:02 » |
|
simply do it in your render thread - this way you don't add it, while it's rendering the scene 
|
|
|
|
rmdire
|
 |
«
Reply #16 - Posted
2006-02-01 00:59:31 » |
|
Sorry arne - but I don't understand what you mean by that. I thought My rendering loop i.e. the run method was the rendering thread.
My scene is contructed in the class constructor - and my run method renders and updates my scene
Do I pass my scene to the run method and add new transformgroups there or do I construct my scene with a global transformgroup and pass this to my run method - to add children to...
confused
Rmdire
|
|
|
|
|
arne
Senior Member   
money is the worst drug- we should not let it rule
|
 |
«
Reply #17 - Posted
2006-02-01 11:35:39 » |
|
In your render thread you'll be doing something like this: 1 2 3
| while(true) { view.render(); } |
then simply change it to: 1 2 3 4 5
| while(true) { group.add(new TransformGroup()); view.render(); } |
This way you change your scenegraph, while view.render() is not running. If you want to modify your scenegraph from other threads, you'll have to cache those "Events" and process them in the render-thread directly. I hope it was now understandable  Arne
|
|
|
|
rmdire
|
 |
«
Reply #18 - Posted
2006-02-01 12:24:19 » |
|
Thanks arne - understood. unfortunately - thats what I am doing - and i still get the buffer underflow exception 
|
|
|
|
|
hawkwind
Junior Member  
Java games rock!
|
 |
«
Reply #19 - Posted
2006-02-01 13:37:36 » |
|
perhaps the relevant code excerpt might help
|
|
|
|
|
rmdire
|
 |
«
Reply #20 - Posted
2006-02-02 14:09:59 » |
|
its alot of code - so I have tried to be relevant here goes: this is my Loop : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| Global BranchGroup : TOPGUESTTRANSFORM
run (){ try {
while (isthreadAlive) { startTime = System.currentTimeMillis(); currentTime = System.currentTimeMillis(); fps++; if (currentTime - lastTime >= 500) { framePerSec=fps << 1; if (!fullScreen) { parentFrame.setTitle("BreedaMorph Demo: FPS "+ String.valueOf(framePerSec)); lastTime = currentTime; fps = 0; } } processMessageQue(); processAnimations(); translateAnyMoves(); processKeyPostRequests(); doAvatarTerrainFollowing(); doCameraTerrainFollowing(); avController.update(view) doMove(new Vector3f(0, height, distance)); setCameraDistances() collisionFrames=doCollisionChecking(collisionFrames); doCameraCollisionChecking(); moveSea(0.0003f,new Vector3f(0.0f,0.00002f,0.0f)); doPingIfRequired(); view.renderOnce();
timeTaken = System.currentTimeMillis() - startTime; if (timeTaken < MILLIS_PER_TICK) { synchronized (this) { wait((int)MILLIS_PER_TICK - timeTaken);
} } else { currentThread.yield(); } } } catch (java.nio.BufferUnderflowException ioe){} } |
method processMessageQue() looks at a Queue of instructions and calls the necessary function so if there is a addNewPlayer() instruction - this function is run: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public void addNewPlayer(String name, String ipAddress,Vector3f positionVector) { MD2ModelInstance playerHead; MD2ModelInstance playerBody; MD2ModelInstance playerShell; TransformGroup t = new TransformGroup();
newMD2Object md22 = new newMD2Object(1.0f,t); md22.loadModel("characters/head.md2","characters/headtex.pcx"); playerHead=md22.getInstance(); newMD2Object md23 = new newMD2Object(1.0f,t); md23.loadModel("characters/shell.md2","characters/shelltex.pcx"); playerShell=md23.getInstance(); setPolygonAttributes(t,true,PolygonAttributes.POLYGON_FILL,PolygonAttributes.CULL_BACK); newMD2Object md21 = new newMD2Object(3.5f,t); md21.loadModel("characters/body.md2","characters/bodytex.pcx"); playerBody=md21.getInstance(); t.addChild(new Text2d(name)); t.getTransform().setTranslation(positionVector); playerObject p = new playerObject(t, ipAddress,name,playerHead,playerBody,playerShell); otherPlayers.addElement(p); TOPGUESTTRANSFORM.addChild(t); } |
now using the same instruction Queue - if there are any positional updates: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public void updatePlayerPositions(TransformGroup playerTransformGroup, String MatrixString) { java.util.List nodes = TOPGUESTTRANSFORM.getChildren(); Matrix4f p =new Matrix4f(); String[] MatrixArray = MatrixString.split(","); p.setRow(0,toFloat(MatrixArray[0]),toFloat(MatrixArray[1]),toFloat(MatrixArray[2]),toFloat(MatrixArray[3])); p.setRow(1,toFloat(MatrixArray[4]),toFloat(MatrixArray[5]),toFloat(MatrixArray[6]),toFloat(MatrixArray[7])); p.setRow(2,toFloat(MatrixArray[8]),toFloat(MatrixArray[9]),toFloat(MatrixArray[10]),toFloat(MatrixArray[11])); p.setRow(3,toFloat(MatrixArray[12]),toFloat(MatrixArray[13]),toFloat(MatrixArray[14]),toFloat(MatrixArray[15]));
for (int i = 0; i < nodes.size(); i++) { SceneGraphObject obj = (SceneGraphObject) nodes.get(i); if (obj instanceof TransformGroup) { String objName=((TransformGroup)obj).getName(); String playerName=playerTransformGroup.getName(); if(objName.equals(playerName)) { Transform3D j = new Transform3D(); j=((TransformGroup)obj).getTransform(); j.set(p);
((TransformGroup)obj).setTransform(j); break; } } } } |
aside from the sloppy code any ideas why i would still be getting Buffer Under Flow exception?
|
|
|
|
|
arne
Senior Member   
money is the worst drug- we should not let it rule
|
 |
«
Reply #21 - Posted
2006-02-02 16:44:33 » |
|
any ideas why i would still be getting Buffer Under Flow exception? nope - you don't modify the scenegraph while rendering.  You sure it's called from the render thread? - maybe you've just forgotten to comment something out and it gets called also from some AWT-event-thread? If you are using Eclipse, you can make it show you the methods that call your updatePlayerPositions-method.
|
|
|
|
rmdire
|
 |
«
Reply #22 - Posted
2006-02-06 15:05:34 » |
|
No - have tried this also - the instruction is definately being called only once and from the rendering thread
The funny thing is that I tried this app on an older version of XITH and I didn't get the error it worked fine.
strange
|
|
|
|
|
arne
Senior Member   
money is the worst drug- we should not let it rule
|
 |
«
Reply #23 - Posted
2006-02-06 17:27:26 » |
|
are you using the latest cvs?
|
|
|
|
rmdire
|
 |
«
Reply #24 - Posted
2006-02-09 15:11:29 » |
|
yep am using:
Parent Directory 24-Sep-2005 10:38 - Xith3D_2005-08-31_cv..> 31-Aug-2005 05:23 4.1M third-party.tar.gz 24-Sep-2005 10:39 5.6M
|
|
|
|
|
arne
Senior Member   
money is the worst drug- we should not let it rule
|
 |
«
Reply #25 - Posted
2006-02-09 21:42:27 » |
|
this is now very strange indeed  I'm at end with my wisdom 
|
|
|
|
|