About The Exception in game loop

When I load the texture for skybox,Why it prints the following MESSAGEs in the console:

Exception in game loop

java.lang.IndexOutOfBoundsException: Index: 3, Size: 1

at java.util.ArrayList.RangeCheck(ArrayList.java:547)

at java.util.ArrayList.get(ArrayList.java:322)

at com.jme.scene.Node.draw(Unknown Source)

at com.jme.scene.Spatial.onDraw(Unknown Source)

at com.jme.renderer.lwjgl.LWJGLRenderer.draw(Unknown Source)

at com.jme.renderer.pass.RenderPass.doRender(Unknown Source)

at com.jme.renderer.pass.Pass.renderPass(Unknown Source)

at com.jme.renderer.pass.BasicPassManager.renderPasses(Unknown Source)

at com.jme.app.SimplePassGame.render(Unknown Source)

at com.jme.app.BaseGame.start(Unknown Source)

at ess.client.view.Welcome.<init>(Welcome.java:189)

at ess.client.view.Welcome.main(Welcome.java:197)

2008-5-25 0:19:47 com.jme.app.BaseSimpleGame cleanup

message: Cleaning up resources.

2008-5-25 0:19:47 com.jme.scene.Node <init>

message: Node created.

2008-5-25 0:19:47 com.jme.scene.Node <init>

message: Node created.

2008-5-25 0:19:47 com.jme.scene.Node <init>

信息: Node created.

2008-5-25 0:19:47 com.jme.app.BaseGame start

信息: Application ending.



Can you tell me why? :?

Put the code snipet for the SkyBox to help finding a solution.

clovis said:

Put the code snipet for the SkyBox to help finding a solution.
But the Exception is thrown from the game loop,how can i find the solution?

You said:


When I load the texture for skybox,Why it prints the following MESSAGEs in the console


This indicates that you may have a problem when you start up/load your skybox. Therefore it would be useful if you could post related code - the method where you load skybox and possibly a couple of lines showing how you call that method and from where.
Mindgamer said:

You said:

When I load the texture for skybox,Why it prints the following MESSAGEs in the console


This indicates that you may have a problem when you start up/load your skybox. Therefore it would be useful if you could post related code - the method where you load skybox and possibly a couple of lines showing how you call that method and from where.

It's oddness.When I remove a model from  my program,it doesn't throw the exception!I'm wondering what will cause the ArrayList in the SimpleGame class throw exception! :?
And how many nodes can I attach to the rootNode of the SimpleGame?IDoes it exist this situation that the number of the Nodes attached to the rootNode will be too large to be displayed?
I suspect that the number is limited.

Are you maybe attaching / removing obects from another thread than the main SimpleGame thread?

The exception you posted has not much to do with the SkyBox .

Core-Dump said:

Are you maybe attaching / removing obects from another thread than the main SimpleGame thread?
The exception you posted has not much to do with the SkyBox .
No,I attach objects in the main SimpleGame thread.Why can't I attaching / removing obects from another thread?
I'm not sure whether the exception has something to do with the skybox,but form my program I belive that if the number of the nodes is too large,it may throw that exception which I can't figure it out .:? :?
Do you meet the problem when you attach too many nodes in the rootNode?

i'm just guessing.

i'm sure its not the number of objects.

maybe you are initializing the RenderPass wrong somehow.

what kind of RenderPass did you create?

Core-Dump said:

i'm just guessing.
i'm sure its not the number of objects.
maybe you are initializing the RenderPass wrong somehow.
what kind of RenderPass did you create?
What will happen if i initializie the RenderPass wrong?My class extends SimplePassGame.
And I create WaterRenderPass
waterEffectRenderPass.setWaterEffectOnSpatial(projectedGrid);
rootNode.attachChild(projectedGrid);

waterEffectRenderPass.setReflectedScene(reflectedNode);
waterEffectRenderPass.setSkybox(skybox);
pManager.add(waterEffectRenderPass);

RenderPass rootPass = new RenderPass();
rootPass.add(rootNode);
pManager.add(rootPass);

RenderPass fpsPass = new RenderPass();
fpsPass.add(fpsNode);
pManager.add(fpsPass);

Your Exception is thrown at Node.draw().

it tries to get the 4th child, but the node has only one.



but i dunno how that happens, i have no more clues :slight_smile:

Core-Dump said:

Your Exception is thrown at Node.draw().
it tries to get the 4th child, but the node has only one.

but i dunno how that happens, i have no more clues :)

I don't know how thet happens.Why it can get the 4th child? :-o

It's oddness.When I remove a model from  my program,it doesn't throw the exception!I'm wondering what will cause the ArrayList in the SimpleGame class throw exception! :?


Sound like your model isnt importing correctly. Just try and load the model.

it would be easier if you could reproduce the problem in a small SimpleGame example which you can post here.

theprism said:


It's oddness.When I remove a model from  my program,it doesn't throw the exception!I'm wondering what will cause the ArrayList in the SimpleGame class throw exception! :?


Sound like your model isnt importing correctly. Just try and load the model.


2008-5-26 19:41:39 com.jme.scene.Node detachChildAt
信息: Child removed.
2008-5-26 19:41:39 com.jme.scene.Node detachChildAt
信息: Child removed.
2008-5-26 19:41:39 com.jme.scene.Node detachChildAt
信息: Child removed.
2008-5-26 19:41:39 com.jme.scene.Node detachAllChildren
信息: All children removed.
2008-5-26 19:41:39 com.jme.scene.Node <init>
信息: Node created.
2008-5-26 19:41:39 class ess.server.Administrator start()
严重: Exception in game loop
java.lang.IndexOutOfBoundsException: Index: 2, Size: 0
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at com.jme.scene.Node.draw(Unknown Source)
at com.jme.scene.Spatial.onDraw(Unknown Source)
at com.jme.scene.Node.draw(Unknown Source)
at com.jme.scene.Spatial.onDraw(Unknown Source)
at com.jme.renderer.lwjgl.LWJGLRenderer.draw(Unknown Source)
at com.jme.app.SimpleGame.render(Unknown Source)
at com.jme.app.BaseGame.start(Unknown Source)
at ess.server.Administrator.<init>(Administrator.java:172)
at ess.server.Administrator.main(Administrator.java:180)
2008-5-26 19:41:39 com.jme.app.BaseSimpleGame cleanup
信息: Cleaning up resources.
2008-5-26 19:41:39 com.jme.scene.Node <init>
信息: Node created.
2008-5-26 19:41:39 com.jme.scene.Node <init>
信息: Node created.
2008-5-26 19:41:39 com.jme.scene.Node <init>
信息: Node created.
2008-5-26 19:41:39 com.jme.app.BaseGame start
信息: Application ending.

Is it because when I detach all nodes,and then load another nodes,but the loading is so slower that it can't get it from  the ArrayList?

where/when do you detach the nodes?

In BaseGame.update() or somewhere else like in a controller??

Core-Dump said:

hmm still the same exception ?
Yes :(
May I have your email?Would you please check my code?
Core-Dump said:

where/when do you detach the nodes?
In BaseGame.update() or somewhere else like in a controller??

When I receive a message from a server , I detach the Nodes and load another to simulate a scene to change.Thus, it's in somewhere like in a controller.
The following code is to simulate a scene change from one to another.
public void floor(int floorID) {
setOutside(false);
rootNode.detachAllChildren();
initDoor();
rootNode.attachChild(desktopNode);
rootNode.attachChild(floorNode);
rootNode.attachChild(elevatorLocationNode);
buildSkyBox("floor" + floorID);
rootNode.attachChild(skybox);

buttonCreate.setEnabled(false);
buttonEnter.setEnabled(true);
buttonLeave.setEnabled(false);
buttonExit.setEnabled(true);

fullScreenButton.setVisible(false);
fullScreenButton.setEnabled(false);
rotateButtonLeft.setVisible(false);
rotateButtonLeft.setEnabled(false);
rotateButtonRight.setVisible(false);
rotateButtonRight.setEnabled(false);
jmeDesktop.getJDesktop().setBackground(new Color(1, 1, 1, 0.0f));
fullScreen();

cam.setLocation(new Vector3f(7,-132,93));

Node n = new Node("n");
n.attachChild(createModel("Dennis_HR", 0, 0, 0, 4f));
n.updateRenderState();
System.out.println("Number of People in FloorID " + fs.getFloorID() + " is " + fs.getNumOfPeopleInFloor());
for (int i = 0; i < fs.getNumOfPeopleInFloor(); i++) {
SharedNode sm = new SharedNode("Share" + i, n);
sm.setLocalTranslation(new Vector3f(40 * i, 0, 0));
peopleInFloorNode.attachChild(sm);
}
peopleInFloorNode.setLocalTranslation(new Vector3f(-SCENE_X / 2, -SCENE_Y, -SCENE_Z / 2));
peopleInFloorNode.updateRenderState();
rootNode.attachChild(peopleInFloorNode);
rootNode.updateRenderState();
new Thread(new Runnable() {

@Override
public void run() {
while (true) {
if (numOfPeopleInFloorChanged) {
peopleInFloorNode.detachAllChildren();
Node n = new Node("n");
n.attachChild(createModel("Dennis_HR", 0, 0, 0, 4f));

for (int i = 0; i < fs.getNumOfPeopleInFloor(); i++) {
SharedNode sm = new SharedNode("Share" + i, n);
sm.setLocalTranslation(new Vector3f(-20 + 40 * i,
0, 0));
peopleInFloorNode.attachChild(sm);
}

peopleInFloorNode.setLocalTranslation(new Vector3f(-SCENE_X / 2, -SCENE_Y, -SCENE_Z / 2));
peopleInFloorNode.updateRenderState();
numOfPeopleInFloorChanged = false;
} else {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}).start();
}

aha! you are removing the elements in another thread. (which was my first question :slight_smile: )



If you detach elements from the scenegraph, then you need to do this in the main thread.



try the following to detach the nodes:


         GameTaskQueueManager.getManager().update(new Callable<Object>() {
             public Object call() throws Exception {
                 peopleInFloorNode.detachAllChildren();
                 return null;
             }
         }).get();

I think in this case the engine could do it for us. Let me explain.

The engine could hide a second "List" of nodes to remove/add and effectively do it when it can do it safely (inside the GameTaskQueueManager).

Because the way the queueManager must be used is not so elegant. It could be "under the hood".

We don't need duplicate the Nodes, just mark them to be removed in the next "safe time".

Do you think its a good solution?

Core-Dump said:

aha! you are removing the elements in another thread. (which was my first question :) )

If you detach elements from the scenegraph, then you need to do this in the main thread.

try the following to detach the nodes:


         GameTaskQueueManager.getManager().update(new Callable<Object>() {
             public Object call() throws Exception {
                 peopleInFloorNode.detachAllChildren();
                 return null;
             }
         }).get();


oh!~~And is it safe if I attach nodes in another thread?How can I do if I want to attach nodes in another Thread?But I'm really confused why it sometimes throw exception while sometimes not!