SharedNode and DiscreteLodNode

Hi all,



I encountered a little problem with the jME API using saved DiscreteLodNode to retain SwitchModel information and all that is needed to have my objects switched to billboarded view whenever I get away from them.



The DiscreteLodNodes are saved in jME format and loads fine. But, I need to be able to instantiate these nodes (for now it represents trees to make a forest), I tried using SharedNode upon the DiscreteLodNode, but I ran into the following problem : The SharedNode implementation makes a copy of the target node, but without taking it's Class into account, it always create a Node object, even for the original node's subnodes.



So all my DiscreteLodNode turns into normal Node after attaching to a SharedNode.



I tried to think of a way to make my own implementation of a SharedDiscreteLodNode but I am missing a getModel() function from DiscreteLodNode to be able to copy it.



Is there another way to do what I'm trying to do, or am I doing something wrong ? Or is it really something missing in jME ?



Thanks in advance.

Why try and save your DLOD info in the model??  Maybe in the future you will want farther/closer switch distances…





Maybe just save the models as is, construct the sharedmeshes at runtime then create your DLOD switch models from those.

Thank you for your answer, however the fact is that I'm developping a networked client / server app, and the client has very little knowledge of what object it is handling, it simply receives bytes array representing jME objects in binary form, so it won't be able to create the DiscreteLodNode when appropriate without adding much knowledge to it.



I also want to be able to control the distances differently on my models (bigger models will switch farther) so I find it may be a not so bad idea to store the distance data along with the models (jME does that wonderfully with it's importer / exporter) ?



But even if I created the DiscreteLodNodes on the client, it would still require me to manually create the node using new SharedMeshes for each element of the replicated SwitchNode, or load one copy of the model for every "instance" nodes created.



Seems pretty inefficient considering jME already has automatic SharedMesh creation when building a SharedNode. And the SharedNode implementation just need to be able to recognize a DiscreteLodNode and replicate it instead of converting it to a Node, which will allow for a deeper sense of encapsulation and simplicity.



Thanks again

Hi again :wink:



I managed to find a way around this by modifying the jME code, so I post the changes here as a small contribution to this wonderful API. (Maybe this should be done elsewhere on the forum, so please tell me if I'm wrong).



These changes allow jME to use Nodes containing DiscreteLodNodes as SharedNodes. I use it for my forests, and it works very well for now.





Here is the patch :


Index: src/com/jme/scene/lod/DiscreteLodNode.java
--- src/com/jme/scene/lod/DiscreteLodNode.java Base (BASE)
+++ src/com/jme/scene/lod/DiscreteLodNode.java Locally Modified (Based On LOCAL)
@@ -105,4 +105,8 @@
         worldCenter = (Vector3f)capsule.readSavable("worldCenter", Vector3f.ZERO.clone());
         model = (SwitchModel)capsule.readSavable("model", null);
     }
+   
+    public SwitchModel getSwitchModel() {
+        return model;
 }
+}
Index: src/com/jme/scene/SharedNode.java
--- src/com/jme/scene/SharedNode.java Base (BASE)
+++ src/com/jme/scene/SharedNode.java Locally Modified (Based On LOCAL)
@@ -35,6 +35,7 @@
 import java.io.IOException;
 
 import com.jme.renderer.Renderer;
+import com.jme.scene.lod.DiscreteLodNode;
 import com.jme.scene.state.RenderState;
 import com.jme.util.export.InputCapsule;
 import com.jme.util.export.JMEExporter;
@@ -106,8 +107,15 @@
    private void processTarget(Node parent, Spatial target) {
       if(target instanceof Node) {
          Node ntarget = (Node)target;
-         Node node = new Node();
 
+                        Node node;
+                       
+                        if (target instanceof DiscreteLodNode) {
+                            node = new DiscreteLodNode(ntarget.getName(), ((DiscreteLodNode)ntarget).getSwitchModel());
+                        } else {
+                            node = new Node();
+                        }
+
            UserDataManager.getInstance().bind(node, target);
             copyNode(ntarget, node);         
          parent.attachChild(node);