Multiple objects in Java3D

Hi!

I’m rather new to Java3D, and I was wondering what the apropriate way to include multiple objects in a scene is.

Right now, I’m loading Shape3Ds for each of my entities and attaching them to a SimpleUniverse directly by means of BranchGroups (no hierachy). The entities are all represented by the same mesh, but each one loads a copy of the same mesh data, which isn’t exactly a great thing. When I need them out of the scene, I detach their BranchGroup linkages.

While reading through the forum, I realise these practices are definitely not right.
I was wondering if i could store the geometry just once, then reference the mesh data each time I draw a copy of the mesh on screen?

thanks in advance for the help! :slight_smile:

Distinguish between ‘Node’ and ‘NodeComponent’. You can copy a subtree while keeping the NodeComponents as references w/o copy.

In FlyingGuns e.g. the subtrees provided by the loader are just replicated via cloneTree(). This gives a new subtree while meshes and textures stay the same.

http://cvs.sourceforge.net/viewcvs.py/drts/projects/threed/java3d/core/java/de/hardcode/threed/objects/

Thanks for the advice! I shall use that right away. :slight_smile:
Just one other question though… if I clone a subtree per entity, is it apropriate for me to detach them from the universe in order to remove an entity, or is this an expensive operation?

If you build the trees by hand the rule is you cant share a node, but you can share a Geometry object and Texture objects betrween multiple Shape3D nodes and thats where msot of your memory is loaded and used :slight_smile:

What other options exist than detaching? If the entity is no longer needed, detach it. Although I have no idea about the costs. (event propagation, bounds re-evaluation, renderer instruction).

You could hide it, then keep it in a pool for the next time you need one of those objects. When you need it, move it to the correct location and make it visible again.

From what I remember all that time ago, detaching used to be the thing that Java3D people worried about (I assumed overhead of recomputing bounds etc). However, in my tests at the time I didn’t see a significant problem with it.

Kev

Hi

I remeber having the problem, detaching objects would cause glitches, I’m guessing it was gc related, but didn’t explore it, I did as kev suggests and moved the object somewhere it wouldn’t be seen, and added it to a pool of objects to use later if I needed on.

Endolf

Would it be viable for me, then, to frequently add and detach large numbers of objects in a game situation, say, rapid fire projectiles that need to be moved along their trajectory? I was wondering what would be the established way of doing this…

I really don’t know about the inner workings of Java3D, but detaching does sound like it could be expensive, especially if Java is attempting to optimise the render using the tree… but then again, wouldn’t hiding the objects out of sight by drastically changing their position, force a recomputation of bounds and etc as well?
but in line with the object hiding idea, is there is a cheap way to toggle a visibility for a branch?

Nonetheless, I’ll try out both in code (hiding and detaching) and post the results in case anyone’s interested…

Thanks so much for all the kind responses and suggestions! :slight_smile:
really appreciate all that effort ^^

Sounds stupid, but how to?

Set the Appearance->RenderingAttributes visibility flag.

http://download.java.net/media/java3d/javadoc/1.4.0-latest/javax/media/j3d/RenderingAttributes.html#setVisible(boolean)

Kev

Hm, appearences are per node? Is visibility inherited?

If not, this would be a problem for complex, deeply nested objects with many Shape3D?

Yeah, it would be if you just used the nodes directly I guess. I generally wrapped up collections of Shape3D nodes representing things in the game in game specific objects derived from TransformGroups. So setting the visibility was pretty easy all in one go.

Kev

There is one bug I know of that resulted in memory issues if you did a lot of attaching/detaching. The J3D team knew about it. Im not sure what the status was but I can check.

ANother option btw is the Switch node.

Yup, the Switch node is a particularly good option if you intend to re-use the scenegraph.

Detaching a BranchGroup isn’t MT safe in Java3D. The workaround is to do it from within a Behavior - for example, by having a Behavior waking up on a BehaviorPost by doing a postId() to itself.

And, yes, there is still a very annoying memory leak issue with detaching a BranchGroup. The “hack” which seems to work fairly well for me is to attach and immediately detach a BranchGroup after you detach your actual BranchGroup.

And Java3D still relies upon finalizers in certain parts of the API…

Code sample?

I’m in luck that my whole game runs within a (the single existing) Behavior…

[quote]And, yes, there is still a very annoying memory leak issue with detaching a BranchGroup. The “hack” which seems to work fairly well for me is to attach and immediately detach a BranchGroup after you detach your actual BranchGroup.
[/quote]
You mean attach/detach any other (empty?) instance of a BranchGroup?

A typical example is the AWT_Interaction/AWTInteractionBehavior.java available in the Java 3D demo bundle, in which the Id is posted from the EDT to wake up the Behavior and trigger a call to the processStimulus(…) method wherein the code for BG detach can be handled.
Ah yes, having a single behavior makes it easier …!

Yes, in my experience, and there is also a long neglected Issue filed on this, simply attaching and detaching an empty BG from the parent which just had one of its children removed, seems to clean up much of the associated leak.