Hi, a quick question mostly for @nehon but please if anybody knows, feel free to give me some information about this.
My question is: How does one go about predicting what GeometryBatchFactory optimization will output in terms of geometry names? You know, if you optimize a 3 submeshes node and each of them uses a different material, you will end up with batch batch and batch for exemple. I don’t want to rename batch[0,1,2…] but rather, to predict what will be inside of those geometries.
I have done some quick testing and everytime I run my project, the GeometryBatchFactory gives me different geometry sets inside batch[0,1,2…] so for example, the first time I ran my project with a tree model, I got: leaves in batch trunk in batch and branches in batch and then when I ran my project again, the second time I got trunk in batch leaves in batch and branches in batch. It looks quite random to me, even tough it’s the exact same model.
So… how would one go about predicting everytime what name GeometryBatchFactory will give to what gathered geometries (in my case submeshes of a model) ???
If it’s not possible, then what would be the best approach to GeometryBatchFactory-optimize a multi submeshes model?
OK, I know, I never had a use or a need to name geometries before, except for this application. I just don’t know how else I could do it. It uses jayfella’s multithreaded terrain library and the only real working way to add stuff to a terrain chunk I’ve found is to append the geometries to the terrain node in the chunk creation thread and apply materials outside of the thread when the terrain chunk has finished generating. Any applied material gets lost when the thread finishes its execution. But the fact is that it’s been working for months and I used GeometryBatchFactory for plenty of stuff before, like thousands and thousands of grass blades, flowers, rocks, etc… but all those models are only using 1 texture, so it never really was an issue. The tree model is now using 3 textures and has 3 separated submeshes, so basically, I’m wondering if I should simply generate a bunch of trees, gather all their submeshes MANUALLY and then feeding them one by one in order to the GeometryBatchFactory. There has to be a simpler way to predict exactly what material those batches are compiled for, no?
ON A SIDE NOTE: Is it normal that GeometryBatchFactory optimized trees are using around 15% MORE triangles than their UNOPTIMIZED normal geometries? It also runs 10% to 12% slower?! I tried 3 tests and they all have exactly this result. It’s pretty weird no? I’m using exactly the same way to batch thousands of grass blades and I’m saving like 500% fps but the contrary is happening with my 30 tree models… :-/
It shouldn’t result in more triangles, no. You’d have to put together a test case to see if there is something else strange but it shouldn’t be manufacturing triangles. Perhaps the meshes are somehow poorly defined and they get “fixed” when combined.
As to your other issue, I still don’t see why you need to know the names or materials. I don’t understand. Something is very strange, really. You shouldn’t count on the names anyway as tomorrow we may decide to do it completely differently. It’s an internal detail and not part of the API. Why do you care that the trees end up batched as three different objects. That part is unclear to me.
Why do you care that the trees end up batched as three different objects. That part is unclear to me.
First of all, thank you for your interest in my question.
Because there are 3 materials. FAIK, batching works by making an array of vertices for the same material. I could be wrong, but if all vertices are batched together, how will the SDK know what material each vertex is supposed to be bound to? That’s the whole idea in this question. Like I said before I’m using batching on 1-texture objects and it is working perfectly as I do not have to know the batching name convention or anything, I just apply 1 material to the batch and that’s it, I know everything inside uses this only material.
For a 3-submeshes (3-material) object, I’m not sure how to go about, since it will produce 3 batches and they never have the same name because of the hash that varies from execution to execution.
EDIT: So, what I was thinking yesterday was: Should I generate a bunch of trees, then manually take all the branches apart, leaves apart and trunks apart and then GeometryBatchFactory-optimize those 3 objects (leaves, trunks, branches) as 3 unrelated layers? In my mind, that’s like the only way I can think of that could work. I’d have to try it I think. As a matter of fact, I’ll do that right now, it’s not that complicated.
I still don’t understand the question. If you pass a thousand Trees, (three geometries each, three materials each but the three are shared across the trees) then you will end up with three geometries when done with all 1000 tree parts in each. The same three materials.
You have not explained why you need the names. At least not in a way that I can understand why on earth you would need such a thing… because you really should never need names. They are for debugging/logging purposes only, really.
Because like I said, the only ANCHOR I have to apply materials back to the batches are the node names. I’m wondering: is there any other option left?
Let’s put it this way:
A terrain chunk is about to be generated. It executes in a thread. This thread outputs a node containing multiple submeshes.
After the chunk generation, this thread ends execution and the pool sees this new chunk. It has to apply right materials to its submeshes.
What can you do other than checking the node’s name before applying the material to it? (e.g.: “trunk”, “leaves” or “branches”)
By the way, a couple hours ago: I tried the alternative that I put in my last message consisting of isolating all the trees’ trunks together in one node, all the leaves together in one node and all the branches together in one node, so ending up with 100 trees, but only 3 nodes total (one per material) and giving them a name “trunks”, “leaves” and “branches” (instead of relaying on the batch generated name (“batch-0”, “batch-1” and “batch-2”) which is of course unreliable and changes at every run) and then I called the optimize method on the 3 nodes separately, so ending up with “trunks” > “batch-0” and “branches” > “batch-0” and “leaves” > “batch-0”. So the batch names, well I don’t care about them anymore, because I have my own node hard names very clearly set. I found that it’s not slower to generate the trees like this, and at least I end up with hard named nodes that I can easily apply materials on outside of the terrain chunk generation thread.
I think the problem is how the terrain chunk generation thread is designed. It should let us apply materials to nodes WITHIN the thread, but unfortunately, they get lost after the thread finishes execution. Same thing with the BulletAppState collision shapes, I have to add them to the PhysicsSpace outside of the chunk generation thread. So I do the materials and the physics at the same time right after the pool receives the geometries.
Well… if nobody sees a better way around this, I’ll stick with this… I mean, it works but it’s like… probably not the proper way to do this.
But they had to have materials to begin with. You need to explain why you need to add new materials or why the original materials weren’t enough to determine which materials to add.
Using names is not a good idea. There are a dozen better ways.
Wait… reading your last bit… yeah, not being able to set your own materials seems pretty messed up. I have no idea why your materials get overridden… and if the library is forcing you to do this by name instead of some other logical means then you may want to pick a different library that isn’t so fragile.
No, that’s the thing, they don’t have materials to begin with, and even if I set them prior to batching, it would result in the same 3 batched nodes. They’re already divided in submeshes in the OBJ file, so that’s why the batching process naturally separates them into 3 batch nodes.
Well… there we have it. The conclusion seems to be that what I’m currently doing is the only out of the box option I have and it works, so I’ll stick with it for now, until I realize I should write my own thing, but you know… I’m not doing this, I fear I’m not skilled enough to rewrite the terrain chunk threads and that’s why I’m using JME3 to begin with, because somebody else, more skilled already thought this through and it’s tested by a bunch of people like me.
Thank you Paul for your time. As we speak right now, I’m already running with batched submeshes (all the leaves, trunks and branches separated into 3 batched nodes) and for 50 trees of 15000 triangles each, it runs at about 40 fps on my modest GTX 650 Ti, so I think I’ll be alright for now. I’m planning on making billboards for distant trees anyway, so 40-50 real full vertices trees seems to be more than enough… we’ll see. To be continued!