BatchNode - remove a Child Spatial - Dungeon Keeper alike Game

Hey Guys,

first: your Work here is Amazing! Thanks for this great Engine.
I am really impressed how fast the BatchNode is. But i have some issues.
I making an Dungeon Keeper like game. The hole Map is an BatchNode organized as an Grid and the Workers can influence the Maps Spatials:

Sometimes i get an java.lang.IndexOutOfBoundsException at java.nio.Buffer.checkBounds(Buffer.java:559). I am not 100% Sure if it cames from the adding or my stupid deleting “trys”.

Some code for you: I have an Update Loop outside the app, but it´s enquened in the App as an Callable like this:

[java]_app.enqueue(new MyCallAction(objectList, staticvisuals));[/java]

The App is my JMonkey Application and created like that:
[java]
_app = new MonkeyApp(_scaleApp, scale, areaSize.getXAsFloat(), isGrid, shader, camera);
AppSettings settings = new AppSettings(true);
_app.setPauseOnLostFocus(false);
_app.setSettings(settings);
_app.createCanvas();
_app.startCanvas();

	_context = (JmeCanvasContext)_app.getContext();
	canvas_ = _context.getCanvas();
	canvas_.setSize(settings.getWidth(), settings.getHeight());
	canvasSize = canvas_.getSize();

[/java]

It all works fine. Just sometimes. especially when i have lots of Workers in my Scene who influence the map i got the Error.

When a new Spatial is added to the Batchnode i do this (inside the MyCallAction):

[java]
sVisualsBatch.attachChild(objectNode);
sVisualsBatch.batch();
[/java]

And to remove:

[java]
Spatial toRemove = sVisualsBatch.getChild(id.toString());
toRemove.setLocalScale(0);
sVisualsBatch.updateGeometricState();
[/java]

First: Why i get the stupid error only when i have lots of actors on my Map?

Second: What is an better Solution to “delete” Spatials from a BatchNode? I dont find anything about that in the documentation. Its just said you can also remove Spatials but is more Expensive than on a Normal Node.

When i just call one of these or both, NOTHING happens.
[java]
sVisualsBatch.detachChild(toRemove);
toRemove.removeFromParent();
[/java]

So please have mercy and give me a hint how to Smart remove Meshes/Spatials from a BatchNode :slight_smile:

Greetings,

Philip

As you are using Swing… You sure you got your threads right? Inconsistent issues are mostly threading issues. So I guess you like exchange some spatial directly on a UI button press or do something else, causing that to be executed on the AWT dispatch thread, causing inconsistencies in the processing on the OpenGL thread, like changed array sizes and whatnot. Its generally a really bad idea to use swing as a GUI for jME games only because you have a visual editor, if its for some other reason (e.g. as in the SDK) you really have to know your threading or you are doomed.

Looks nice already, gj :slight_smile:

@PhilipWilluweit said: When i just call one of these or both, NOTHING happens. [java] sVisualsBatch.detachChild(toRemove); toRemove.removeFromParent(); [/java]

This sounds like a bug. I think you’ll have to submit a simple test case, though. That will rule out any other contributing factors and make it easier for other developers to spot the problem.

The fact that you call updateGeometricState(0) is even more disturbing and further hints at threading issues that were at some point “solved” by adding this call because the engine complains about the scene not being updated.

@pspeed said:
@PhilipWilluweit said: When i just call one of these or both, NOTHING happens. [java] sVisualsBatch.detachChild(toRemove); toRemove.removeFromParent(); [/java]

This sounds like a bug. I think you’ll have to submit a simple test case, though. That will rule out any other contributing factors and make it easier for other developers to spot the problem.


Actually when an object is removed from the batch you have to call batch() again as for when you add an object.
Right now removing is really not optimized though as it rebach from scratch (all the sub geometries) and generates quite a lot of garbage.
Adding is a bit better because it batch the old batch and the new geometry, but still generates garbage.

1 Like
@normen said: As you are using Swing.. You sure you got your threads right? Inconsistent issues are mostly threading issues. So I guess you like exchange some spatial directly on a UI button press or do something else, causing that to be executed on the AWT dispatch thread, causing inconsistencies in the processing on the OpenGL thread, like changed array sizes and whatnot. Its generally a *really* bad idea to use swing as a GUI for jME games only because you have a visual editor, if its for some other reason (e.g. as in the SDK) you really have to know your threading or you are doomed.

Looks nice already, gj :slight_smile:

yeah, its inside our SDK, has to be in Swing. But its just embetted, i dont change Spatials over the UI or something. The issues are totally new now since I am using BatchNode. Before never happend. But Imagine, most Maps have a Size of 100x100 Tiles, thats to much to not use a BatchNode, the Performance Loss is to heavy.

@normen said: The fact that you call updateGeometricState(0) is even more disturbing and further hints at threading issues that were at some point "solved" by adding this call because the engine complains about the scene not being updated.
ok....do i even need updateGeometricState?
@nehon said:
@pspeed said:
@PhilipWilluweit said: When i just call one of these or both, NOTHING happens. [java] sVisualsBatch.detachChild(toRemove); toRemove.removeFromParent(); [/java]

This sounds like a bug. I think you’ll have to submit a simple test case, though. That will rule out any other contributing factors and make it easier for other developers to spot the problem.


Actually when an object is removed from the batch you have to call batch() again as for when you add an object.
Right now removing is really not optimized though as it rebach from scratch (all the sub geometries) and generates quite a lot of garbage.
Adding is a bit better because it batch the old batch and the new geometry, but still generates garbage.

hm, okay, but even if i do that, remove from Parent and then do the Batch, nothing "visually" happens.

I also read about that you can influence the Mesh directly. By using getOffsetIndex from the Batch node. So then i have the Index, how to continue then?

[java]
if(tmpsp instanceof Node)
{
for(Spatial geospatial : ((Node)tmpsp).getChildren())
{
Geometry delgeo = (Geometry)geospatial;
System.out.println("geospatial " + geospatial + sVisualsBatch.getOffsetIndex(delgeo))
}
}
[/java]

Here is another Screen, the Workers do something like destroy walls and claim ground and so on:

Really hope someday i can fix it with BatchNode, otherwise the Game is only suitable for High-End Computers :slight_smile:

@PhilipWilluweit said:

hm, okay, but even if i do that, remove from Parent and then do the Batch, nothing “visually” happens.

This should work. If it does not then it’s a bug. Can you make a simple test case illustrating the issue and ruling out any other things your code might be doing?

@pspeed said:
@PhilipWilluweit said:

hm, okay, but even if i do that, remove from Parent and then do the Batch, nothing “visually” happens.

This should work. If it does not then it’s a bug. Can you make a simple test case illustrating the issue and ruling out any other things your code might be doing?


oh, i am wrong, when i make .batch afther sVisualsBatch.detachChild(toRemove) I get an java.lang.IndexOutOfBoundsException immediatly. Try to make an testcase and/our reduce it to that, the project is already pretty big.

What about the Mesh-Directly Manipulation. Could that work?

@PhilipWilluweit said: What about the Mesh-Directly Manipulation. Could that work?
BatchNode does Mesh manipulations for you. Apparently there is an issue though :p But I wouldn't start a custom system from scratch, better help investigate to fix the issue with BatchNode

But yeah i’d like a test case, it can really help
Could you please post the exception too ?

Your game looks good btw

2 Likes

@nehon and norman Yeah, thanks, we love the Style too, just need better Textures and we still have small issues with the ParticleEmitters und Soundeffects, but its still far away from even Alpha. But the AI is already pretty good.

If this issue is fixed the next big step is an good in-game GUI (we will choose Nifty (Offtopic: Good Choice or not?)) and smart Box-Select (instead of just one Spatial) Algorithm.

@nehon: Of course i could post the Exception too:

[java]
Jan 02, 2013 7:53:53 PM com.jme3.app.Application handleError
Schwerwiegend: Uncaught exception thrown in Thread[LWJGL Renderer Thread,6,main]
java.lang.IndexOutOfBoundsException
at java.nio.Buffer.checkBounds(Buffer.java:559)
at java.nio.DirectFloatBufferU.get(DirectFloatBufferU.java:259)
at com.jme3.scene.BatchNode.doTransforms(BatchNode.java:559)
at com.jme3.scene.BatchNode.updateSubBatch(BatchNode.java:163)
at com.jme3.scene.Geometry.updateWorldTransforms(Geometry.java:297)
at com.jme3.scene.Spatial.updateGeometricState(Spatial.java:683)
at com.jme3.scene.Node.updateGeometricState(Node.java:177)
at com.jme3.scene.Node.updateGeometricState(Node.java:177)
at com.jme3.scene.BatchNode.updateGeometricState(BatchNode.java:120)
at com.jme3.scene.Node.updateGeometricState(Node.java:177)
at com.jme3.scene.Node.updateGeometricState(Node.java:177)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:249)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:149)
at com.jme3.system.lwjgl.LwjglCanvas.runLoop(LwjglCanvas.java:227)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:223)
at java.lang.Thread.run(Thread.java:722)
[/java]

Btw.: Is it also possible/better to wait for all attach/detach operation in one run through then Thread and then do the Batch-Command? Btw -> I also get the Error if i make an .batch-Command twice directly in a row.

@PhilipWilluweit said: Btw.: Is it also possible/better to wait for all attach/detach operation in one run through then Thread and then do the Batch-Command?
that's better to wait all attach/detech have been made before batching yeah. But don't do it from another thread because it attach the batch to the scene graph.
1 Like

Nifty is clunky and far from perfect but it works and can give very good results.

It’s also the only real option at the moment, although a few people are working on alternatives.

Hey Guys, the Problem was: We where using the Maven Version (the one from sonatype) and its just outdatet. Now everything works fine now with nightly build…for the object count.

How to reduce now the Verticies/Triangles Count? Before we where using BatchNode the count was lower when you zoom in (less Objects rendered) now it seems to render the whole “batch” at once, doesent matter which part you are facing:

Look at the Triangle Counts:

No big difference:

What is helping here to solve the Problem? Just LOD Control? (Even in BatchNode?) or something else?

Thanks again for this great engine and this nice communitiy!

-Philip

You may need to break up your world spatially.

This may also give you an opportunity to optimize the areas with no tunnels to be one huge quad for each untouched area. 1 million triangles still seems kind of excessive for this view and that would help a lot.

@pspeed said: You may need to break up your world spatially.

This may also give you an opportunity to optimize the areas with no tunnels to be one huge quad for each untouched area. 1 million triangles still seems kind of excessive for this view and that would help a lot.

ok, how to find the best “approach”? I mean, i just implement the Batch-Support to get rid of all this Single-Objects.

Now i should split it again?

Lets imagine for example a 100x100 map, so there are 10000 Tiles with individual Meshes. So, maybe every 10x10 Block?

Thanks for the Idea. How much will help LOD Control here if i re-export all the Meshes from Blender with LOD-Levels?

Greetings,

Philip

It very much depends on world size, computer power, block size, complexity, etc, etc. There is no one right answer we can give you.

Make it easily configurable/adjustable and try a few values. I think 101010 is fairly common but I don’t make block worlds myself so I’m not sure…

Yeah, 10x10x10 should be a good start, (in my case 10x10) I am using 2d-game-logic just displayed in 3d.

So I have to seperate the Batchnode into several Batchnodes. I should make it dynamic (different Mapsizes). Sounds complex to me, i better make an Individual-Batchnode-Controller or something like that as Super-Type, so i can extract that from the rest of the code, and make this not visible to the game-logic.

Someone did this before and has open-source sources? I dont mind to make it from scratch, but would be a faster start maybe.

There are several voxel worlds at various stages of completion - some have been released on these forums but I’m not sure off hand what state they are in. Try using the forum search :slight_smile:

Hehe, got the point. :slight_smile: Maybe they published some solutions. Thanks for the hint.

Fyi: now it really runs smooth even on big maps, here you can see the result:

Thanks to the Amazing BatchNode you Guys did!