why dont use one thread do appstate and controller, other one thread rendering the mesh? …
Because thread safety.
How would the rendering know it was safe to render the stuff modified by the app state or the controller?
Why is it that you just don’t want to follow standard scene optimizing tips and choose instead to try to do everything the hard way?
Note that if you’re using an entity system to keep data and visualization cleanly separated then multithreading data updates can be done. I’d suggest not doing that until it proves to be a bottleneck, however, as it substantially complicates things.
I suspect that with 5000 animated characters and 1000 particle emitters that an entity system was warranted a long time ago.
To OP, if your spatials are also your game objects then that is the root of all of your performance troubles.
Godot Engine works this way I think. They have 1 Thread for rendering and another for “appstates/controls”. They use an extra layer to synchronize changes to the scenegraph. That’s what I understood so far.
But as pspeed said: In jme your spatials should not be your game objects but they rather be your visual representation of your game objects
I use the Outside Engine, which is a component based engine on top of jme3 (built in-house by my company). It uses multiple threads for changing game state, then changes are queued for jme. It is very doable to implement a multi-threaded environment with jme, but you need to separate your scene graph from your game logic. The scene graph is for rendering, your components are for your game logic. There should be an abstraction layer to relate the spatial in the scene graph to the components.
An example of how we do it in the Outside Engine:
An Action is generated by the user and forwarded to InteractionHandler.
InteractionHandler finds correct ComponentInteraction for the player and what WorldComponent it interacted with in the action.
ComponentInteraction is evaluated on the WorldComponent being interacted with.
A GameRule contains the logic that manipulates the WorldComponent, it runs on the WorldComponent from the ComponentInteraction.
Once the GameRule is run, the WorldComponent contains a reference to the Node in the scene graph, and will use enqueue from the SimpleApplication to tell the scene graph what to change.
The advantage of this is that we can manipulate our components from any thread, and in a predictable way. Game logic is easy to find and change without worrying about breaking other things. And interactions between components are easily tracked allowing you to run any necessary game logic.
Our setup is designed for a very large and complex multi-server multi-client games. You probably do not need as much complexity as we do. To get similar end results I recommend using one of the component systems that were developed by the community. I would personally recommend Zay-ES developed by Paul Speed: https://github.com/jMonkeyEngine-Contributions/zay-es. It has a lot of documentation and community support.
You will run into nothing but problems attempting to use the scene graph, Nodes, and Spatials as your games component system.
Just my two cents,
well said two cents