I wanted to bring a little more attention to this and wasn’t exactly sure where to stick it.
Back story: during my live stream, I discovered that my (3.6.0-based-local-hacked) jMonkeyEngine’s BatchNode was throwing IndexOutOfBounds exceptions. In trying to track down whether this was a “me problem” or a “jme problem”, I found the issue and implemented a fix locally.
That PR is really only fixing the symptom, though. (might be worth keeping that ‘last ditch effort’ style fix but it’s not really fixing the underlying problem)
I have to be pretty ruthless with where I spend my time these days so I don’t have time to make a proper PR, etc… I’m currently not even setup to push to JME on github anymore.
For those that don’t like to click through, quick synopses of the problem:
have a BatchNode
add some Spheres with a red material
add some boxes with a blue material
batch()
add some arrows with a green material
batch()
move one of the boxes
The issue is that the maxVertCount is only calculated from what is batched in doBatch() and not what is actually being managed by the BatchNode. doBatch() will only batch geometries that aren’t already batched. The only thing that uses maxVertCount is the temporary buffer allocation and those buffers are only used by the code that handles object transforms.
The current solution in github just checks the size of these temp arrays at the point of use and reallocates them if they are too small. Which works… at the expense of perhaps several extra array allocations.
Current github solution array allocations:
have a BatchNode
add some Spheres with a red material
batch() → reallocate the arrays nice and big
add some boxes with a blue material
batch() → reallocate the arrays too small for spheres
add some arrows with a green material
batch() → reallocate the arrays too small for boxes or spheres
move one of the boxes → reallocate the arrays (where the old code threw an exception) to be big enough for boxes but not for spheres
move one of the spheres → reallocate the arrays to be big enough for spheres
The patch I’ve attached to that PR instead calculates the maxVertCount when iterating over all of the geometry to gather them during doBatch(). (Which is the right place to do it.) And then only reallocates the buffers if they are the wrong size. This better matches the intent of maxVertCount and so I will refer to this as the “correct solution” (with casting aspersions to the current fix)
Correct fix:
have a BatchNode
add some Spheres with a red material
batch() → reallocate the arrays
add some boxes with a blue material
batch() → arrays are already big enough
add some arrows with a green material
batch() → arrays are already big enough
move one of the boxes
move one of the spheres
Sorry I don’t have time to do more than bring attention to it.
Glad you found a better way of fixing this!
I don’t remember the exact details of this code, just I wasn’t super confident of my solution, but also didn’t want to risk messing up a core class.
In my day job, I feel like I spend 50% of my time getting to the actual root of a bug because I won’t get to fix it myself… but will have to explain it to someone else in a way that gives them agency to make decisions on their own. (ie: if I give someone line-by-line instructions, I can be reasonably sure that at the first sign of trouble then they will abandon that and start over. )
Bottom line is that I spend a reasonable amount of my time trying to boil down a problem into one sentence explanations and so have a lot of practice with this sort of decomposition.
I also get really curious about “why” something happens… because it often leads to a better “one sentence explanation”.
For the curious, the one sentence bug explanation here is: “BatchNode needs maxVertCount to be the maximum per-geometry vertex count for the whole batch node but only calculates it based on what was recently batched.” (Which is really close to some of the sentences in the linked post.)
The one sentence solution is: “BatchNode already iterates over all of the geometry when deciding what should be batched, so that is where it should be calculating the maxVertCount”.