Box not lighted when added to loaded scene

Hi! I met a problem that seems noob, but I couldn't find any solution for hours now…

I loaded a file (a scene consisting of 5 boxes and 10 lights) and attached it to the rootNode (the file Szene.jpg is the scene binary). Right after loading a new box is spawned which is supposed to integrate in the new Node. The box is between the 2nd and 3rd box.



This new Box however remains black and is not being lighted. I guess I am missing something important… but I can't figure out what. I tried combinations of this.loaded, CopyOfTest.loaded, this.spawnBox(), CopyOfTest.loaded.this, box.setRenderState(ls).setEnabled(true) etc. trying to get it work but no success.



Also when I try to add a new Light => only the new Box is lighted, although I expected the other boxes to be lit-up too. It behaves as if the loaded file is a different node than the spawned box/light although SceneMonitor shows all of them in the same Node.

Any ideas  :?




import javax.swing.JFileChooser;

//import com.acarter.scenemonitor.SceneMonitor;
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.light.DirectionalLight;
import com.jme.light.LightControllerManager;
import com.jme.light.SimpleLightNode;
import com.jme.math.FastMath;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
import com.jme.scene.state.LightState;
import com.jme.system.DisplaySystem;
import com.jme.util.export.binary.BinaryImporter;

public class CopyOfTest extends SimpleGame {
    static Node loaded;
    JFileChooser fileChooser;
 
    public static void main(String[] args) {
        CopyOfTest app = new CopyOfTest();
        app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG);
        app.start();
    }
    public void simpleInitGame() {
       // clear first
       rootNode.detachAllChildren();
       lightState.detachAll();
       LightControllerManager.reset();
       
       fileChooser = new JFileChooser();
        int returnVal = fileChooser.showOpenDialog(null);
      if(returnVal == JFileChooser.APPROVE_OPTION){
         /*** Read File ***/
         try   {
            //Select the file you want to load
            loaded = (Node) BinaryImporter.getInstance().load(fileChooser.getSelectedFile());
                        
            rootNode.attachChild(loaded);
            rootNode.updateGeometricState(0,false);
            rootNode.updateRenderState();
            
            // add a new Box to current scene
            spawnBox();
            
//            SceneMonitor.getMonitor().registerNode(rootNode, "Root Node");
//            SceneMonitor.getMonitor().showViewer(true);
         }
         catch (Exception e)   {
            e.printStackTrace();
         }
      }
      else
         System.out.println("Loading cancelled");      
    }
   
    public void spawnBox()
    {
       Box box = new Box("Box",new Vector3f(0,0,0),10,10,10);
        box.setLocalTranslation(0,0,0);
        box.updateGeometricState(0,false);
        box.setModelBound(new BoundingBox());
        box.updateModelBound();
        box.updateRenderState();           
        loaded.attachChild(box);
       
        // make usable for more than 8 lights
        LightState ls = DisplaySystem.getDisplaySystem().getRenderer().createLightState();
        ls.setEnabled(true);
        box.setRenderState(ls);
        LightControllerManager.addSpatial(box);
        box.setLightCombineMode(LightState.REPLACE);
       
        // test adding a new light
//        DirectionalLight dl = new DirectionalLight();
//       dl.setDirection(new Vector3f(-0.5f,-1,-0.8f));
//       dl.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
//       dl.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
//       dl.setSpecular(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f));
//       dl.setEnabled(true);     
//       dl.setShadowCaster(true);
//       LightControllerManager.addLight(dl);
//       SimpleLightNode ln2 = new SimpleLightNode("ln2",dl);
//       ln2.getLocalRotation().fromAngleAxis(60*FastMath.DEG_TO_RAD,new Vector3f(1,0,-1));
//       loaded.attachChild(ln2);
      
        loaded.updateRenderState();       
        loaded.updateGeometricState(0,false);
        loaded.updateRenderState();
        rootNode.updateGeometricState(0,false);
      rootNode.updateRenderState();
    }
   
//    @Override
//    protected void simpleUpdate() {
//            super.simpleUpdate();
//            SceneMonitor.getMonitor().updateViewer(tpf);
//    }
//    @Override
//    protected void simpleRender() {
//            super.simpleRender();
//            SceneMonitor.getMonitor().renderViewer(display.getRenderer());
//    }
//    @Override
//    protected void cleanup() {
//            super.cleanup();
//            SceneMonitor.getMonitor().unregisterNode(rootNode);
//    }
}

The class LightControllerManager holds the singleton instance of LightManagement.

So there is meant to be only one instance of LightManagement.



But after saving/ loading the Scene, there will be suddenly two instances.

The 'old' instance is referenced by the LightControlles who are already in the scene.

The 'new' instance is the one that you can access through the Singleton LightControllerManager.getLightManagement().



The new Box you add to the scene after loading it, is not lit because its LightState is not managed by the old LightManagement. Its managed by the new LightManagement which has no light attached to it yet.



Once you add a new Light to the new LightManagement , the new box and only the new Box is lit by it.



Something like that is happening i guess :slight_smile:



I don't know whats the best solution to that misery.

Damn, and I hoped I had made a noob mistake that could be solved in 1-2 lines of code… Thanks for your explanation, that sounds perfectly logical to me.

The only solution I can currently think of now is to extract all Lights from the loaded file (which would work after your patch and the corrected typo), and add them to the 'new' LightControllerManager… but wait… even if that works how do I remove afterwards the 'old' LightControllerManager (with the still existing and thus double lights)???



Maybe I am taking the wrong steps anyways and therefore I want to ask plainly: is this the wrong way to save & re-edit a scene?



Maybe the lighting must be handled in the following way?

In the saving action of the scene only the "real spatials" like models/boxes/meshes will be saved whereas the lights/properties shall not be saved binary but instead will be saved in some kind of xml or textfile? When loading the scene this textfile will be read and create the Lights according to the textfile and adds them to the active lightmanager…



Where are all the game programmers who can tell?

http://www.jmonkeyengine.com/jmeforum/index.php?topic=7799.0

"The light handling was revamped to handle light prioritizing/sorting as part of core (making the old complex LightManagement stuff obsolete) …"



Can you try without the LightManagement at all ? it seems it shouldn't be needed anymore.

Hmmm interesting. I will definitely try that out even when it means that I need to migrate my code to JME2. I'll report back later :slight_smile: