FPS down when moving BatchNode

First let explain what I did.

I got a tiled map (.tmx file).There are 45 * 31 tiles in a TileLayer, every tile in that TileLayer sharing one image. For each tile, I create a quad mesh and apply the same material to it. Then I attached them to a BatchNode.

I set the queue bucket to Bucket.Gui for every Geometry and Node, and move the scene to screen space (XOY plane, 0<x<width, 0<y<height) so I can see the map.

I made a test app to preview the tiled map.

So far so good until I want to drag the map with my mouse. How I implements the “drag” is:

  • Record the cursor position and mapNode position when mouse left button first pressed.
  • Calculate the translation when moving mouse with left button pressed.

The source:

boolean isPressed = false;
private Vector3f startLoc = new Vector3f();
private Vector2f startPos = new Vector2f();
private Vector2f stopPos = new Vector2f();

@Override
public void onAction(String name, boolean isPressed, float tpf) {
	if (name.equals(DRAG)) {
		this.isPressed = isPressed;
		if (isPressed) {
			// recored the mouse position
			startPos.set(inputManager.getCursorPosition());
			startLoc.set(mapTranslation);
		} else {
			drag(true);
		}
	}

}

@Override
public void onAnalog(String name, float value, float tpf) {
	if (name.equals(DRAG)) {
		drag(true);
	}
}

/**
 * drag camera
 * 
 * @param isPressed
 */
private void drag(boolean isPressed) {

	if (isPressed) {
		// recored the mouse position
		stopPos.set(inputManager.getCursorPosition());
		stopPos.subtractLocal(startPos);

		// move camera
		mapTranslation.set(startLoc.add(stopPos.x, 0, -stopPos.y));
		mapNode.setLocalTranslation(mapTranslation);
	}
}

Run my code, I notied that FPS down from 56 (avg) to 21 (avg).

OK, I have jprofiler.

Oh my god… why BatchNode steal so mush cpu time?:open_mouth:

So I delete all BatchNode from my scene, use only Node. The FPS is even more smooth now. Triangles and Vertices count allow low down a lot.

The BatchNode maybe not the best choice in my case.

Were you dragging the batch node or the children of the batch node? I’m just wondering.

And yes, there are a dozen reasons that batch node is not a good idea in your case. The best way would be not to use quads at all and just build your own batched mesh. Then you control everything and it’s not that hard, really.

I have a root node, batch node attached to the root node. I drag the root node.

Yeah, that’s what I was afraid of. I think BatchNode is not efficiently implemented with respect to parent and child transforms. If it was setup better then dragging the BatchNode (or its parents) shouldn’t cause all of that resetting of the transforms.

If you make your own mesh then that wouldn’t be a problem.

I mean, you could even use the utility class to batch instead: http://javadoc.jmonkeyengine.org/jme3tools/optimize/GeometryBatchFactory.html

…but ultimately, you will be happiest with your own mesh as you will be able to do everything you want. It’s not really that hard once you get the hang of it. It’s conceptually just an array of points. (And another array of texture coordinates, etc…)

Thanks for your advice. I have made a plan to create custom mesh days ago. I planned to do it after implements all the features of tiled map.

Here is part of my mesh util. I create every single rectangle, ellipsem polygon and polyline mesh.

https://github.com/jmecn/TMXLoader/blob/master/src/com/jme3/tmx/util/ObjectMesh.java

The SimpleBatchNode avoid this issue, though you can’t have complex sub graph below the SimpleBatchNode, so all the geometries has to be attached to it directly.

I use this and well abuse the hell out of it. I have no performance issues. I even have a lot of polygon detail that should be baked into normal maps. I put the entire map on the scene at once without LOD! And still i have very few performance issues even on intel onboard gfx cards. In fact i only drop below 60fps when i add a bunch of post processing filters.

For this reason i am finding it hard to justify writing my own. I know it wouldn’t be hard. After all i have done my own terrain system in opengl before with vertex shader based LOD etc. But why fix what is not broke :smiley:

G.

In OPs case, for a tile system I imagine it is sometimes important to swap out tiles at runtime. In that case, having access to a mesh you made yourself would be very beneficial as you could surgically replace the tile you want without rebatching the whole thing.

1 Like