[SOLVED] com.jme3.scene.Node IndexOutOfBoundsException


#1

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.


#2

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


#3

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


#4

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


#5

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.


#6

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?


#7

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.


#8

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


#9

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!


#10

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


#11

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


#12

Thank you!