[SOLVED] com.jme3.scene.Node IndexOutOfBoundsException

Hi!

I have a problem in my project.

I’m using Nodes in my code but attachChild doesn’t work properly when I add a lot of elements in the node.

There is the trace:

Exception in thread "Thread-5" java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at java.util.ArrayList.add(ArrayList.java:480)
at com.jme3.util.SafeArrayList.add(SafeArrayList.java:302)
at com.jme3.scene.Node.attachChildAt(Node.java:354)
at com.jme3.scene.Node.attachChild(Node.java:330)
at cursedproject.main.system.game.Block.<init>(Block.java:45)
at cursedproject.main.system.game.FlatWorldGenerator.run(FlatWorldGenerator.java:39)

Or sometimes…

Exception in thread "Thread-6" java.lang.IndexOutOfBoundsException: Index: 36435, Size: 36470
at java.util.ArrayList.rangeCheckForAdd(ArrayList.java:665)
at java.util.ArrayList.add(ArrayList.java:477)
at com.jme3.util.SafeArrayList.add(SafeArrayList.java:302)
at com.jme3.scene.Node.attachChildAt(Node.java:354)
at com.jme3.scene.Node.attachChild(Node.java:330)
at cursedproject.main.system.game.Block.<init>(Block.java:46)
at cursedproject.main.system.game.FlatWorldGenerator.run(FlatWorldGenerator.java:39)

There is the code:

public Block(int x, int y, int z, Node superNode, String blockName, com.jme3.material.Material mat, Camera flyCam){
    this.x = x;
    this.y = y;
    this.z = z;
    
    blockNode = new Node(blockName + x + " " + y + " " + z);
    
    this.superNode = superNode;
    
    this.superNode.attachChild(blockNode); //PROBLEM IS HERE
    
    this.mat = mat;
    this.flyCam = flyCam;
    
    buildUnblockyTexture();
}

In the executor thread:

@Override
public void run(){
    chunks[x][y] = new Chunk(x - world.renderDist/2, y - world.renderDist / 2, world);

    for(int p = 0; p < 16 && (!abort); p++){
        for(int q = 0; q < 16; q++){
            for(int r = 0; r < world.z/3; r++){
                chunks[x][y].blocks[p][q][r] = new Block(p, q, r, chunks[x][y].chunkNode, x + "" + y, world.test, world.flyCam); //HERE THE BLOCK CONSTRUCTOR IS CALLED
            }
        }
    }
    g.processors++;
}

Thanks.

Seems like there is more than one thread accessing the same Node. That’s super-bad.

I should have one thread per node. But i’m now using one thread to attach all nodes. Thanks though!

Well, something was modifying the list while the thread was attaching. That’s the only way the size would change during the copy.

Actually, this message is really interesting since it’s extra information indicates no problem at all.

What version of Java are you using?

Edit: but looking at those numbers… you are adding WAAAAAY too many children. You’ll be lucky to get one frame per second.

36k children is a crazy number of children. You know that block worlds are not really made out of blocks? They are made of batched meshes of visible surfaces.

It’s the only world generation. I’m creating block objects.
And I think so it’s not necessary to attach nodes to the parent node :smiley:

But how can I use these batched meshes? Can I use Quads?

I’m using Java 7.

Thanks for your reply.

Edit:
Also, how can I find what Block areas I have to render? I think I have to find which blocks is the camera looking at, but how can I manage this?

The general algorithm is like this:

for each cell {
    if( !solid ) continue;
    for each neighbor cell {
        if( !solid ) emit a face;
    }
}

If you are just learning everything then you could create a list Quad geometries and use the BatchGeometryFactory to turn them into one…
https://javadoc.jmonkeyengine.org/jme3tools/optimize/GeometryBatchFactory.html#makeBatches-java.util.Collection-

But ultimately you will want to build your own mesh because it’s super-inefficient to create thousands of geometries + meshes just to throw them away.

Edit: and note that it’s not about what is/isn’t in camera view. It’s about what will never be seen because it’s blocked by other blocks. Even in the most complicated scene, probably 70+% of the block surfaces are between two blocks and can never be seen.

1 Like

When I was trying to figure out what pspeed meant when he said ‘block worlds aren’t made from blocks’ 3 years ago I stumbled across this.

https://wiki.jmonkeyengine.org/jme3/contributions/cubes.html

I loaded it and read the code. Then I understood. Give it a try.

Wobblytrout

1 Like

Yes! Just what I thought! I already made an isAirAdjacent() method to check if neighbor blocks are not solid (then i’ll generalize it for transparent blocks).

I’ll start with the first approach, then how can I build a Mesh dynamically?

Thanks!

Yes, I already merged blocks into chunks. I think It’s the best method.

https://wiki.jmonkeyengine.org/jme3/advanced/custom_meshes.html#toolbar

2 Likes

Thank you!

1 Like