Multiple Parents for one Node

Hey Guys,
My problem is quite simple:
I want to use Node.collideWith(ray, results);
I used to use the rootNode as “Node”, but this is too cpu consuming.

I have an List of Spatials which should be collidable. The problem now is, how to do the collision?

Node node = new Node(""); node.attachChild(s); will remove them from the rootNode as every spatial might only have one parent.

s.clone() is not an option as it leads to an OOM-Exception (and takes time, too).

Should I somehow collide with every single spatial and concenate the results (as collideWith does internally?)
Another plan would be an intermediary Node but since I want to decouple “being rendered” from “being collidable” that’s no real solution.

Under RootNode make a new node and put there all collidable objects. Use this node to determine the collision.

Yeah I already thought about that, the problem is though that I want to have them seperated (like invisible collidables or visible non-collidables).

I should think a bit before posting as I already gave me the answer (do as Node.collideWith).

public int myCollideWith(List<Spatial> spatials, Collidable other, CollisionResults results)
{
    int total = 0;
    for (Spatial s : spatials)
       total += s.collideWith(other, results);
          
    return total;
}

Yes, your own list is a solution. also, you can use userParams and ‘mark’ collidable spatials on the scene. It requires modification to collideWith(ray) or even to implement it on your own.

That’s right but since I attach a Control which simply adds it’s spatial to that List, it works fine.

I have some problems, though:
I need to implement culling checks in that collideWith (already googling that) and

I need to improve performance :frowning:

It limits me down to 40 FPS (What it actually does is only colliding one (!) ray with 50 Character Controls.
I guess it’s not using that capsule but the complex shape. Is there something I could do about it?

Can I maybe simply use s.getControl(BetterCharacterControl.class).getCollisionShape() or something?

Edit: Spatial.checkCulling throws an Exception because of wrong refreshFlags. I guess I can only call that method in onRender()?

Edit2: I now implemented Culling as seen here, but I now see that I have plenty of unneccesary Controls updating when not culled.

Can I simply use the controlRender() for my GameLogic or do I run into troubles when trying to modify the SceneGraph from there?

Yes you will run into trouble when modifying the scene during render().

Sooo.
I updated loads of stuff but couldn’t improve the FPS when only drawing the Stats Window (placed the camera to show nothing).

It is stuck at roughly 40FPS with a constant CPU Load of 25%.

After running several profilings, I figuered out that bullet is taking it’s resources. Having it run in a seperate thread did not improve anything as the synchronization now takes nearly as long as it used to calculate.

Then I removed all the Controls from that spatials. I figured out that 85% of the renderLoop time go into renderViewPort() and it’s descendants.

66% in controlRenderSoftware ofwhich 56% in SkeletonControl.softwareSkinUpdate() and computeSkinningMatrices.

@pspeed: I guess that was what you were talking about.

I changed it. For some reason I still have 17% on controlRenderSoftware. The Output confirms me though: “Hardware skinning engaged for …(Node)” // This is with only one Character having animation at all!

So I am still stuck at 80 FPS with no Physics no Custom Controls .

Somehow AnimControl.update() and it’s Skeleton.reset() and updateWorldVectors() are doing something.
Does that happen automatically without any Animation being played or stopped? I just have the Controls in the SceneGraph.

Note: I have one animated character so that calls might be justified, I only wonder if that could come from the NPCs (As they impact the perfomance)

Edit: If I remove all those 50 Guys I have a racing 1500 FPS, so it has to be something with their .update().
Edit2: The only thing I do to those guys is a) load the model, b) add a BetterCharacterControl but do not add it to the physicsSpace

Edit3: Sorry for those thousand edits. I now made sure that I only load the spatial and add it to the graph. Even when culled a huge impact. No calls done to them.

FYI: Animated characters constantly update their meshes even if there is no animation playing. They could have bones manually moved and stuff so I guess the original authors thought it too complicated to track if something had changed or not. Either that or it risks making typical scenes really spikey… and sometimes predictability is better than huge swings in frame rate draw.

The cpu load at 25% means that you have fully loaded one cpu core, I remember that you have 4x core. Java on its standard configuration uses only one core per jvm. You can use -server switch to enable multicore for jvm, but i think that it won’t help, since the only one (main JME’s) thread uses all the resources.

Odd… do you have a source for this? I routinely max CPU on my 6 core box and I don’t run server mode… and I’ve had this behavior for at least 10 years since there were some old Dells that would report different System.nanoTime() for different CPUs that would cause time to jump around as Java threads were rehomed onto different CPUs.

IIRC I thought that you need to call something after a manual change to the bones?

I think it’s not too complicated to track, simply one boolean variable.
Is there any way to change that behavior?

Or something like AnimationControl.setEnabled(false);

Some (long long) time ago I read that on stackoverflow or similar forum, never tested that and tbh never had any need to verify that.
I’m trying to find that source right now, but so far without success.
If this is not true then sorry for misleading.

The difference between server VM and client VM is more or less that the server is optimized for a long time run and peak operating speed, but the client is optimized for faster startup.

Java will use multiple cores, but you need to move operations to additional threads.

… you need to move operations to additional threads.

I know that, and in this particular case it just means that one thread utilizes the whole core.
And I’m not sure if there is a way to do any ‘engine’s specific’ operation on separate thread.

Strongly recommend enabling hardware skinning for all animated models, it significantly speeds up the game.

@Darkchaos

Remember I answered a question like this from someone else two years ago or so. Anyway, did you find a good method yet?

List is much more flexible compare to Node, so Node consider hacky… I see people are really quick into thinking in hacky way but well, in this case using another parent node is not a bad choice after all… My advices in optimizing your scenegraph in overall, for collision detecting or ray casting for example, you should try to organize your scenegraph in a good way, even extremely:

  • make a lot of nodes with “zero” translation to be a “container only nodes”
  • Jme3 already implement a algorithm called BIH … something to help you speed up. Before let your nodes get tested by jme3 methods, you can also have some smart check of your own. For example: If your game play have some objects that can be consider “points”, you can use point containment checks (RTree or something like that, google it) before a real collision check.
  • You can switch the parent of an object and return it to the original parent later. I DO IT ALL THE TIME… why all the letter are in cap. Because that’s a “really smart way” to optimize your scene.For example: In my framework, there is a util called SceneGraphUtil that travel all object visible in the scene at the start, and in that moment, “index” them. Later, any operation over the scenegraph use indexes to recognize if job have to be done in that specific node, spatial or not, and update the indexes. Object culling, visible check, paging, level of detail, batching, ray checking, collision detect, material changing… to name some of them. The temporary parent nodes are use to “group” those spatials has same index value. And why use Node not just a Set of List of Spatial. Because some operations are built-in with Node support, like Ray checking or Physics collision. Another example is when making an in game editor, we stick all the moved objects to a Node and move, than later return it to the original parents.

So that final check to go with List Spatial or Node, if you want to use built-in operation and have sotiphicated index algorithm, go with Node otherwise, go with List Spatial.

Hope this help.

It helps indeed yes, but the List is way more simple :slight_smile:
Also the thing is, I have multiple types of ray-checks so having seperate Lists is simpler than swapping out Nodes most of the time.

Also: Isn’t SceneGraphTraversal really expensive? My plan is to only have tracked Spatials which are considered (like for AI/Shooting only Characters and such.