Browse Source

scenecomposer : changed to way spatial are selected
- now all types of jme nodes can be selected as long they can be associated with a spatial

Dokthar 9 years ago
parent
commit
8743b772a0

+ 91 - 284
jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerToolController.java

@@ -5,31 +5,23 @@
 package com.jme3.gde.scenecomposer;
 package com.jme3.gde.scenecomposer;
 
 
 import com.jme3.asset.AssetManager;
 import com.jme3.asset.AssetManager;
-import com.jme3.audio.AudioNode;
 import com.jme3.gde.core.scene.SceneApplication;
 import com.jme3.gde.core.scene.SceneApplication;
 import com.jme3.gde.core.scene.controller.SceneToolController;
 import com.jme3.gde.core.scene.controller.SceneToolController;
+import com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode;
 import com.jme3.gde.core.sceneexplorer.nodes.JmeNode;
 import com.jme3.gde.core.sceneexplorer.nodes.JmeNode;
-import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial;
+import com.jme3.gde.scenecomposer.gizmo.GizmoFactory;
 import com.jme3.gde.scenecomposer.tools.shortcuts.ShortcutManager;
 import com.jme3.gde.scenecomposer.tools.shortcuts.ShortcutManager;
 import com.jme3.input.event.KeyInputEvent;
 import com.jme3.input.event.KeyInputEvent;
-import com.jme3.light.Light;
-import com.jme3.light.PointLight;
-import com.jme3.light.SpotLight;
-import com.jme3.material.Material;
-import com.jme3.material.RenderState.BlendMode;
 import com.jme3.math.Vector2f;
 import com.jme3.math.Vector2f;
-import com.jme3.math.Vector3f;
 import com.jme3.renderer.Camera;
 import com.jme3.renderer.Camera;
 import com.jme3.renderer.RenderManager;
 import com.jme3.renderer.RenderManager;
 import com.jme3.renderer.ViewPort;
 import com.jme3.renderer.ViewPort;
-import com.jme3.renderer.queue.RenderQueue.Bucket;
-import com.jme3.scene.Geometry;
 import com.jme3.scene.Node;
 import com.jme3.scene.Node;
 import com.jme3.scene.Spatial;
 import com.jme3.scene.Spatial;
-import com.jme3.scene.control.BillboardControl;
-import com.jme3.scene.control.Control;
-import com.jme3.scene.shape.Quad;
-import com.jme3.texture.Texture;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Callable;
 import org.openide.util.Lookup;
 import org.openide.util.Lookup;
 
 
@@ -41,27 +33,27 @@ public class SceneComposerToolController extends SceneToolController {
 
 
     private JmeNode rootNode;
     private JmeNode rootNode;
     private SceneEditTool editTool;
     private SceneEditTool editTool;
-    private SceneEditorController editorController;  
+    private SceneEditorController editorController;
     private ViewPort overlayView;
     private ViewPort overlayView;
     private Node onTopToolsNode;
     private Node onTopToolsNode;
     private Node nonSpatialMarkersNode;
     private Node nonSpatialMarkersNode;
-    private Material lightMarkerMaterial;
-    private Material audioMarkerMaterial;
-    private JmeSpatial selectedSpatial;
+    private HashMap<AbstractSceneExplorerNode, Spatial> nonSpatialMarkers;
+
     private boolean snapToGrid = false;
     private boolean snapToGrid = false;
     private boolean snapToScene = false;
     private boolean snapToScene = false;
     private boolean selectTerrain = false;
     private boolean selectTerrain = false;
     private boolean selectGeometries = false;
     private boolean selectGeometries = false;
     private TransformationType transformationType = TransformationType.local;
     private TransformationType transformationType = TransformationType.local;
-          
+
     public enum TransformationType {
     public enum TransformationType {
         local, global, camera
         local, global, camera
     }
     }
-    
+
     public SceneComposerToolController(final Node toolsNode, AssetManager manager, JmeNode rootNode) {
     public SceneComposerToolController(final Node toolsNode, AssetManager manager, JmeNode rootNode) {
         super(toolsNode, manager);
         super(toolsNode, manager);
         this.rootNode = rootNode;
         this.rootNode = rootNode;
         nonSpatialMarkersNode = new Node("lightMarkersNode");
         nonSpatialMarkersNode = new Node("lightMarkersNode");
+        nonSpatialMarkers = new HashMap<AbstractSceneExplorerNode, Spatial>();
         SceneApplication.getApplication().enqueue(new Callable<Object>() {
         SceneApplication.getApplication().enqueue(new Callable<Object>() {
 
 
             public Object call() throws Exception {
             public Object call() throws Exception {
@@ -130,7 +122,8 @@ public class SceneComposerToolController extends SceneToolController {
 
 
     /**
     /**
      * If the current tool overrides camera zoom/pan controls
      * If the current tool overrides camera zoom/pan controls
-     * @return 
+     *
+     * @return
      */
      */
     public boolean isOverrideCameraControl() {
     public boolean isOverrideCameraControl() {
         if (editTool != null) {
         if (editTool != null) {
@@ -142,8 +135,8 @@ public class SceneComposerToolController extends SceneToolController {
 
 
     /**
     /**
      * Scene composer edit tool activated. Pass in null to remove tools.
      * Scene composer edit tool activated. Pass in null to remove tools.
-     * 
-     * @param sceneEditTool pass in null to hide any existing tool markers 
+     *
+     * @param sceneEditTool pass in null to hide any existing tool markers
      */
      */
     public void showEditTool(final SceneEditTool sceneEditTool) {
     public void showEditTool(final SceneEditTool sceneEditTool) {
         SceneApplication.getApplication().enqueue(new Callable<Object>() {
         SceneApplication.getApplication().enqueue(new Callable<Object>() {
@@ -178,15 +171,16 @@ public class SceneComposerToolController extends SceneToolController {
     }
     }
 
 
     /**
     /**
-     * Primary button activated, send command to the tool
-     * for appropriate action.
+     * Primary button activated, send command to the tool for appropriate
+     * action.
+     *
      * @param mouseLoc
      * @param mouseLoc
      * @param pressed
      * @param pressed
      * @param camera
      * @param camera
      */
      */
     public void doEditToolActivatedPrimary(Vector2f mouseLoc, boolean pressed, Camera camera) {
     public void doEditToolActivatedPrimary(Vector2f mouseLoc, boolean pressed, Camera camera) {
         ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class);
         ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class);
-        
+
         if (scm.isActive()) {
         if (scm.isActive()) {
             scm.getActiveShortcut().setCamera(camera);
             scm.getActiveShortcut().setCamera(camera);
             scm.getActiveShortcut().actionPrimary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject());
             scm.getActiveShortcut().actionPrimary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject());
@@ -197,15 +191,16 @@ public class SceneComposerToolController extends SceneToolController {
     }
     }
 
 
     /**
     /**
-     * Secondary button activated, send command to the tool
-     * for appropriate action.
+     * Secondary button activated, send command to the tool for appropriate
+     * action.
+     *
      * @param mouseLoc
      * @param mouseLoc
      * @param pressed
      * @param pressed
      * @param camera
      * @param camera
      */
      */
     public void doEditToolActivatedSecondary(Vector2f mouseLoc, boolean pressed, Camera camera) {
     public void doEditToolActivatedSecondary(Vector2f mouseLoc, boolean pressed, Camera camera) {
         ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class);
         ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class);
-        
+
         if (scm.isActive()) {
         if (scm.isActive()) {
             scm.getActiveShortcut().setCamera(camera);
             scm.getActiveShortcut().setCamera(camera);
             scm.getActiveShortcut().actionSecondary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject());
             scm.getActiveShortcut().actionSecondary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject());
@@ -217,19 +212,19 @@ public class SceneComposerToolController extends SceneToolController {
 
 
     public void doEditToolMoved(Vector2f mouseLoc, Camera camera) {
     public void doEditToolMoved(Vector2f mouseLoc, Camera camera) {
         ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class);
         ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class);
-        
+
         if (scm.isActive()) {
         if (scm.isActive()) {
             scm.getActiveShortcut().setCamera(camera);
             scm.getActiveShortcut().setCamera(camera);
-            scm.getActiveShortcut().mouseMoved(mouseLoc, rootNode, editorController.getCurrentDataObject(), selectedSpatial);
+            scm.getActiveShortcut().mouseMoved(mouseLoc, rootNode, editorController.getCurrentDataObject());
         } else if (editTool != null) {
         } else if (editTool != null) {
             editTool.setCamera(camera);
             editTool.setCamera(camera);
-            editTool.mouseMoved(mouseLoc, rootNode, editorController.getCurrentDataObject(), selectedSpatial);
+            editTool.mouseMoved(mouseLoc, rootNode, editorController.getCurrentDataObject());
         }
         }
     }
     }
 
 
     public void doEditToolDraggedPrimary(Vector2f mouseLoc, boolean pressed, Camera camera) {
     public void doEditToolDraggedPrimary(Vector2f mouseLoc, boolean pressed, Camera camera) {
         ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class);
         ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class);
-        
+
         if (scm.isActive()) {
         if (scm.isActive()) {
             scm.getActiveShortcut().setCamera(camera);
             scm.getActiveShortcut().setCamera(camera);
             scm.getActiveShortcut().draggedPrimary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject());
             scm.getActiveShortcut().draggedPrimary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject());
@@ -241,7 +236,7 @@ public class SceneComposerToolController extends SceneToolController {
 
 
     public void doEditToolDraggedSecondary(Vector2f mouseLoc, boolean pressed, Camera camera) {
     public void doEditToolDraggedSecondary(Vector2f mouseLoc, boolean pressed, Camera camera) {
         ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class);
         ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class);
-        
+
         if (scm.isActive()) {
         if (scm.isActive()) {
             scm.getActiveShortcut().setCamera(null);
             scm.getActiveShortcut().setCamera(null);
             scm.getActiveShortcut().draggedSecondary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject());
             scm.getActiveShortcut().draggedSecondary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject());
@@ -250,112 +245,76 @@ public class SceneComposerToolController extends SceneToolController {
             editTool.draggedSecondary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject());
             editTool.draggedSecondary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject());
         }
         }
     }
     }
-    
+
     public void doKeyPressed(KeyInputEvent kie) {
     public void doKeyPressed(KeyInputEvent kie) {
         ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class);
         ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class);
 
 
         if (scm.isActive()) {
         if (scm.isActive()) {
             scm.doKeyPressed(kie);
             scm.doKeyPressed(kie);
-        } else {
-            if (scm.activateShortcut(kie)) {
-                scm.getActiveShortcut().activate(manager, toolsNode, onTopToolsNode, selected, this);
-            } else {
-                if (editTool != null) {
-                    editTool.keyPressed(kie);
-                }
-            }
-        }
-    }
-    
-    /**
-     * Adds a marker for the light to the scene if it does not exist yet
-     * @param light
-     */
-    public void addLightMarker(Light light) {
-        if (!(light instanceof PointLight) && !(light instanceof SpotLight))
-            return; // only handle point and spot lights
-        
-        Spatial s = nonSpatialMarkersNode.getChild(light.getName());
-        if (s != null) {
-            // update location maybe? Remove old and replace with new?
-            return;
+        } else if (scm.activateShortcut(kie)) {
+            scm.getActiveShortcut().activate(manager, toolsNode, onTopToolsNode, selected, this);
+        } else if (editTool != null) {
+            editTool.keyPressed(kie);
         }
         }
-        
-        LightMarker lm = new LightMarker(light);
-        nonSpatialMarkersNode.attachChild(lm);
     }
     }
-    
-    public void addAudioMarker(AudioNode audio) {
-        
-        Spatial s = nonSpatialMarkersNode.getChild(audio.getName());
-        if (s != null) {
-            // update location maybe? Remove old and replace with new?
-            return;
-        }
-        
-        AudioMarker am = new AudioMarker(audio);
-        nonSpatialMarkersNode.attachChild(am);
+
+    protected void refreshNonSpatialMarkers() {
+        addMarkers();
     }
     }
-    
-    /**
-     * Removes a light marker from the scene's tool node
-     * @param light
-     */
-    public void removeLightMarker(Light light) {
-        Spatial s = nonSpatialMarkersNode.getChild(light.getName());
-        s.removeFromParent();
-    }
-    
-    private Material getLightMarkerMaterial() {
-        if (lightMarkerMaterial == null) {
-            Material mat = new Material(manager, "Common/MatDefs/Misc/Unshaded.j3md");
-            Texture tex = manager.loadTexture("com/jme3/gde/scenecomposer/lightbulb32.png");
-            mat.setTexture("ColorMap", tex);
-            mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
-            lightMarkerMaterial = mat;
+
+    private void getNodes(org.openide.nodes.Node node, List<AbstractSceneExplorerNode> list) {
+        if (node instanceof AbstractSceneExplorerNode) {
+            list.add((AbstractSceneExplorerNode) node);
         }
         }
-        return lightMarkerMaterial;
-    }
-    
-    private Material getAudioMarkerMaterial() {
-        if (audioMarkerMaterial == null) {
-            Material mat = new Material(manager, "Common/MatDefs/Misc/Unshaded.j3md");
-            Texture tex = manager.loadTexture("com/jme3/gde/scenecomposer/audionode.gif");
-            mat.setTexture("ColorMap", tex);
-            mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
-            audioMarkerMaterial = mat;
+        if (!node.isLeaf()) {
+            for (org.openide.nodes.Node n : node.getChildren().getNodes(true)) {
+                getNodes(n, list);
+            }
         }
         }
-        return audioMarkerMaterial;
     }
     }
 
 
-    protected void refreshNonSpatialMarkers() {
+    private void addMarkers() {
+        final List<AbstractSceneExplorerNode> nodes = new ArrayList<AbstractSceneExplorerNode>();
+        // gather nodes, have to be in an other thread than the sceneApplication
+        getNodes(rootNode, nodes);
+        
+        // then update markers
         SceneApplication.getApplication().enqueue(new Callable<Void>() {
         SceneApplication.getApplication().enqueue(new Callable<Void>() {
-
+            @Override
             public Void call() throws Exception {
             public Void call() throws Exception {
-                   nonSpatialMarkersNode.detachAllChildren();
-                   addMarkers(rootNode.getLookup().lookup(Node.class));
-                   return null;
+                
+                Iterator<AbstractSceneExplorerNode> it = nonSpatialMarkers.keySet().iterator();
+                while (it.hasNext()) {
+                    AbstractSceneExplorerNode n = it.next();
+                    if (nodes.contains(n)) {
+                        // a node is already added
+                        nodes.remove(n);
+                    } else {
+                        // a node is no more needed
+                        nonSpatialMarkers.get(n).removeFromParent();
+                        it.remove();
+                        //nonSpatialMarkers.remove(n);
+                    }
+                }
+
+                it = nodes.iterator();
+                while (it.hasNext()) {
+                    AbstractSceneExplorerNode n = it.next();
+                    if (!nonSpatialMarkers.containsKey(n)) {
+                        Spatial s = GizmoFactory.createGizmo(manager, n);
+                        if (s != null) {
+                            nonSpatialMarkers.put(n, s);
+                            nonSpatialMarkersNode.attachChild(s);
+                        }
+                    }
+                }
+                return null;
             }
             }
         });
         });
-        
     }
     }
-    
-    private void addMarkers(Node parent) {
-        
-        for (Light light : parent.getLocalLightList())
-            addLightMarker(light);
-        
-        if (parent instanceof AudioNode) {
-            addAudioMarker((AudioNode)parent);
-        }
-        
-        for (Spatial s : parent.getChildren()) {
-            if (s instanceof Node)
-                addMarkers((Node)s);
-            else {
-                //TODO later if we include other types of non-spatial markers
-            }
-        }
+
+    public Spatial getMarker(AbstractSceneExplorerNode node) {
+        return nonSpatialMarkers.get(node);
     }
     }
 
 
     public boolean isSnapToGrid() {
     public boolean isSnapToGrid() {
@@ -391,12 +350,12 @@ public class SceneComposerToolController extends SceneToolController {
     }
     }
 
 
     public void setTransformationType(String type) {
     public void setTransformationType(String type) {
-        if(type != null){
-            if(type.equals("Local")){
+        if (type != null) {
+            if (type.equals("Local")) {
                 setTransformationType(TransformationType.local);
                 setTransformationType(TransformationType.local);
-            } else if(type.equals("Global")){
+            } else if (type.equals("Global")) {
                 setTransformationType(TransformationType.global);
                 setTransformationType(TransformationType.global);
-            } else if(type.equals("Camera")){
+            } else if (type.equals("Camera")) {
                 setTransformationType(TransformationType.camera);
                 setTransformationType(TransformationType.camera);
             }
             }
         }
         }
@@ -406,176 +365,24 @@ public class SceneComposerToolController extends SceneToolController {
      * @param type the transformationType to set
      * @param type the transformationType to set
      */
      */
     public void setTransformationType(TransformationType type) {
     public void setTransformationType(TransformationType type) {
-        if(type != this.transformationType){
+        if (type != this.transformationType) {
             this.transformationType = type;
             this.transformationType = type;
-            if(editTool != null){
+            if (editTool != null) {
                 //update the transform type of the tool
                 //update the transform type of the tool
                 editTool.setTransformType(transformationType);
                 editTool.setTransformType(transformationType);
             }
             }
         }
         }
     }
     }
-    
+
     /**
     /**
      * @return the transformationType
      * @return the transformationType
      */
      */
     public TransformationType getTransformationType() {
     public TransformationType getTransformationType() {
         return transformationType;
         return transformationType;
     }
     }
-
-    /**
-     * A marker on the screen that shows where a point light or
-     * a spot light is. This marker is not part of the scene,
-     * but is part of the tools node.
-     */
-    protected class LightMarker extends Geometry {
-        private Light light;
-        
-        protected LightMarker() {}
-    
-        protected LightMarker(Light light) {
-            this.light = light;
-            Quad q = new Quad(0.5f, 0.5f);
-            this.setMesh(q);
-            this.setMaterial(getLightMarkerMaterial());
-            this.addControl(new LightMarkerControl());
-            this.setQueueBucket(Bucket.Transparent);
-        }
-        
-        protected Light getLight() {
-            return light;
-        }
-        
-        @Override
-        public void setLocalTranslation(Vector3f location) {
-            super.setLocalTranslation(location);
-            if (light instanceof PointLight)
-                ((PointLight)light).setPosition(location);
-            else if (light instanceof SpotLight)
-                ((SpotLight)light).setPosition(location);
-        }
-        
-        @Override
-        public void setLocalTranslation(float x, float y, float z) {
-            super.setLocalTranslation(x, y, z);
-            if (light instanceof PointLight)
-                ((PointLight)light).setPosition(new Vector3f(x,y,z));
-            else if (light instanceof SpotLight)
-                ((SpotLight)light).setPosition(new Vector3f(x,y,z));
-        }
-    }
-    
-    /**
-     * Updates the marker's position whenever the light has moved.
-     * It is also a BillboardControl, so this marker always faces
-     * the camera
-     */
-    protected class LightMarkerControl extends BillboardControl {
-
-        LightMarkerControl(){
-            super();
-        }
-        
-        @Override
-        protected void controlUpdate(float f) {
-            super.controlUpdate(f);
-            LightMarker marker = (LightMarker) getSpatial();
-            if (marker != null) {
-                if (marker.getLight() instanceof PointLight) {
-                    marker.setLocalTranslation(((PointLight)marker.getLight()).getPosition());
-                } else if (marker.getLight() instanceof SpotLight) {
-                    marker.setLocalTranslation(((SpotLight)marker.getLight()).getPosition());
-                }
-            }
-        }
-
-        @Override
-        protected void controlRender(RenderManager rm, ViewPort vp) {
-            super.controlRender(rm, vp);
-        }
-
-        @Override
-        public Control cloneForSpatial(Spatial sptl) {
-            LightMarkerControl c = new LightMarkerControl();
-            c.setSpatial(sptl);
-            //TODO this isn't correct, none of BillboardControl is copied over
-            return c;
-        }
-        
-    }
-    
-    /**
-     * A marker on the screen that shows where an audio node is. 
-     * This marker is not part of the scene, but is part of the tools node.
-     */
-    protected class AudioMarker extends Geometry {
-        private AudioNode audio;
-        
-        protected AudioMarker() {}
-    
-        protected AudioMarker(AudioNode audio) {
-            this.audio = audio;
-            Quad q = new Quad(0.5f, 0.5f);
-            this.setMesh(q);
-            this.setMaterial(getAudioMarkerMaterial());
-            this.addControl(new AudioMarkerControl());
-            this.setQueueBucket(Bucket.Transparent);
-        }
-        
-        protected AudioNode getAudioNode() {
-            return audio;
-        }
-        
-        @Override
-        public void setLocalTranslation(Vector3f location) {
-            super.setLocalTranslation(location);
-        }
-        
-        @Override
-        public void setLocalTranslation(float x, float y, float z) {
-            super.setLocalTranslation(x, y, z);
-        }
-    }
-    
-    /**
-     * Updates the marker's position whenever the audio node has moved.
-     * It is also a BillboardControl, so this marker always faces
-     * the camera
-     */
-    protected class AudioMarkerControl extends BillboardControl {
-
-        AudioMarkerControl(){
-            super();
-        }
-        
-        @Override
-        protected void controlUpdate(float f) {
-            super.controlUpdate(f);
-            AudioMarker marker = (AudioMarker) getSpatial();
-            if (marker != null) {
-                marker.setLocalTranslation(marker.getAudioNode().getWorldTranslation());
-            }
-        }
-
-        @Override
-        protected void controlRender(RenderManager rm, ViewPort vp) {
-            super.controlRender(rm, vp);
-        }
-
-        @Override
-        public Control cloneForSpatial(Spatial sptl) {
-            AudioMarkerControl c = new AudioMarkerControl();
-            c.setSpatial(sptl);
-            //TODO this isn't correct, none of BillboardControl is copied over
-            return c;
-        }
-        
-    }
-
+     
     public JmeNode getRootNode() {
     public JmeNode getRootNode() {
         return rootNode;
         return rootNode;
     }
     }
-    
-    public void setSelectedSpatial(JmeSpatial selectedSpatial) {
-        this.selectedSpatial = selectedSpatial;
-    }
+
 }
 }

+ 62 - 36
jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.java

@@ -14,6 +14,7 @@ import com.jme3.gde.core.scene.SceneApplication;
 import com.jme3.gde.core.scene.SceneListener;
 import com.jme3.gde.core.scene.SceneListener;
 import com.jme3.gde.core.scene.SceneRequest;
 import com.jme3.gde.core.scene.SceneRequest;
 import com.jme3.gde.core.sceneexplorer.SceneExplorerTopComponent;
 import com.jme3.gde.core.sceneexplorer.SceneExplorerTopComponent;
+import com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode;
 import com.jme3.gde.core.sceneexplorer.nodes.JmeNode;
 import com.jme3.gde.core.sceneexplorer.nodes.JmeNode;
 import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial;
 import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial;
 import com.jme3.gde.core.sceneexplorer.nodes.NodeUtility;
 import com.jme3.gde.core.sceneexplorer.nodes.NodeUtility;
@@ -57,15 +58,17 @@ import org.openide.util.Utilities;
  * TODO: some threading stuff
  * TODO: some threading stuff
  */
  */
 @ConvertAsProperties(dtd = "-//com.jme3.gde.scenecomposer//SceneComposer//EN",
 @ConvertAsProperties(dtd = "-//com.jme3.gde.scenecomposer//SceneComposer//EN",
-autostore = false)
+        autostore = false)
 @SuppressWarnings("unchecked")
 @SuppressWarnings("unchecked")
 public final class SceneComposerTopComponent extends TopComponent implements SceneListener, LookupListener {
 public final class SceneComposerTopComponent extends TopComponent implements SceneListener, LookupListener {
 
 
     private static SceneComposerTopComponent instance;
     private static SceneComposerTopComponent instance;
-    /** path to the icon used by the component and its open action */
+    /**
+     * path to the icon used by the component and its open action
+     */
     static final String ICON_PATH = "com/jme3/gde/scenecomposer/jme-logo24.png";
     static final String ICON_PATH = "com/jme3/gde/scenecomposer/jme-logo24.png";
     private static final String PREFERRED_ID = "SceneComposerTopComponent";
     private static final String PREFERRED_ID = "SceneComposerTopComponent";
-    private final Result<JmeSpatial> result;
+    private final Result<AbstractSceneExplorerNode> result;
     ComposerCameraController camController;
     ComposerCameraController camController;
     SceneComposerToolController toolController;
     SceneComposerToolController toolController;
     SceneEditorController editorController;
     SceneEditorController editorController;
@@ -79,13 +82,13 @@ public final class SceneComposerTopComponent extends TopComponent implements Sce
         setName(NbBundle.getMessage(SceneComposerTopComponent.class, "CTL_SceneComposerTopComponent"));
         setName(NbBundle.getMessage(SceneComposerTopComponent.class, "CTL_SceneComposerTopComponent"));
         setToolTipText(NbBundle.getMessage(SceneComposerTopComponent.class, "HINT_SceneComposerTopComponent"));
         setToolTipText(NbBundle.getMessage(SceneComposerTopComponent.class, "HINT_SceneComposerTopComponent"));
         setIcon(ImageUtilities.loadImage(ICON_PATH, true));
         setIcon(ImageUtilities.loadImage(ICON_PATH, true));
-        result = Utilities.actionsGlobalContext().lookupResult(JmeSpatial.class);
+        result = Utilities.actionsGlobalContext().lookupResult(AbstractSceneExplorerNode.class);
     }
     }
 
 
-    /** This method is called from within the constructor to
-     * initialize the form.
-     * WARNING: Do NOT modify this code. The content of this method is
-     * always regenerated by the Form Editor.
+    /**
+     * This method is called from within the constructor to initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is always
+     * regenerated by the Form Editor.
      */
      */
     @SuppressWarnings("UnnecessaryBoxing")
     @SuppressWarnings("UnnecessaryBoxing")
     // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
     // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
@@ -617,7 +620,7 @@ private void emitButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FI
     SceneApplication.getApplication().enqueue(new Callable<Object>() {
     SceneApplication.getApplication().enqueue(new Callable<Object>() {
 
 
         public Object call() throws Exception {
         public Object call() throws Exception {
-            emit(editorController.getSelectedSpat().getLookup().lookup(Spatial.class));
+            emit(editorController.getSelectedSpat());
             return null;
             return null;
         }
         }
     });
     });
@@ -659,7 +662,7 @@ private void jToggleSelectGeomActionPerformed(java.awt.event.ActionEvent evt) {/
 }//GEN-LAST:event_jToggleSelectGeomActionPerformed
 }//GEN-LAST:event_jToggleSelectGeomActionPerformed
 
 
     private void transformationTypeComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_transformationTypeComboBoxActionPerformed
     private void transformationTypeComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_transformationTypeComboBoxActionPerformed
-        toolController.setTransformationType((String)transformationTypeComboBox.getSelectedItem());
+        toolController.setTransformationType((String) transformationTypeComboBox.getSelectedItem());
     }//GEN-LAST:event_transformationTypeComboBoxActionPerformed
     }//GEN-LAST:event_transformationTypeComboBoxActionPerformed
 
 
     // Variables declaration - do not modify//GEN-BEGIN:variables
     // Variables declaration - do not modify//GEN-BEGIN:variables
@@ -728,10 +731,12 @@ private void jToggleSelectGeomActionPerformed(java.awt.event.ActionEvent evt) {/
     }
     }
 
 
     /**
     /**
-     * Gets default instance. Do not use directly: reserved for *.settings files only,
-     * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
-     * To obtain the singleton instance, use {@link #findInstance}.
-     * @return 
+     * Gets default instance. Do not use directly: reserved for *.settings files
+     * only, i.e. deserialization routines; otherwise you could get a
+     * non-deserialized instance. To obtain the singleton instance, use
+     * {@link #findInstance}.
+     *
+     * @return
      */
      */
     public static synchronized SceneComposerTopComponent getDefault() {
     public static synchronized SceneComposerTopComponent getDefault() {
         if (instance == null) {
         if (instance == null) {
@@ -741,8 +746,10 @@ private void jToggleSelectGeomActionPerformed(java.awt.event.ActionEvent evt) {/
     }
     }
 
 
     /**
     /**
-     * Obtain the SceneComposerTopComponent instance. Never call {@link #getDefault} directly!
-     * @return 
+     * Obtain the SceneComposerTopComponent instance. Never call
+     * {@link #getDefault} directly!
+     *
+     * @return
      */
      */
     public static synchronized SceneComposerTopComponent findInstance() {
     public static synchronized SceneComposerTopComponent findInstance() {
         TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
         TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
@@ -855,7 +862,7 @@ private void jToggleSelectGeomActionPerformed(java.awt.event.ActionEvent evt) {/
         final SceneComposerTopComponent inst = this;
         final SceneComposerTopComponent inst = this;
         if (jmeNode != null) {
         if (jmeNode != null) {
             ((TitledBorder) sceneInfoPanel.getBorder()).setTitle(jmeNode.getName());
             ((TitledBorder) sceneInfoPanel.getBorder()).setTitle(jmeNode.getName());
-            selectSpatial(jmeNode);
+            selectSpatial(jmeNode.getLookup().lookup(Node.class));
         } else {
         } else {
             ((TitledBorder) sceneInfoPanel.getBorder()).setTitle("");
             ((TitledBorder) sceneInfoPanel.getBorder()).setTitle("");
         }
         }
@@ -941,6 +948,7 @@ private void jToggleSelectGeomActionPerformed(java.awt.event.ActionEvent evt) {/
 
 
     /**
     /**
      * listener for node selection changes
      * listener for node selection changes
+     *
      * @param ev
      * @param ev
      */
      */
     @Override
     @Override
@@ -948,35 +956,53 @@ private void jToggleSelectGeomActionPerformed(java.awt.event.ActionEvent evt) {/
         if (currentRequest == null || !currentRequest.isDisplayed()) {
         if (currentRequest == null || !currentRequest.isDisplayed()) {
             return;
             return;
         }
         }
-        Collection<JmeSpatial> items = (Collection<JmeSpatial>) result.allInstances();
-        for (JmeSpatial spatial : items) {
-            selectSpatial(spatial);
-            return;
+        Collection<AbstractSceneExplorerNode> items = (Collection<AbstractSceneExplorerNode>) result.allInstances();
+        for (AbstractSceneExplorerNode node : items) {
+            if (select(node)) {
+                return;
+            }
+        }
+    }
+
+    private boolean select(AbstractSceneExplorerNode node) {
+        if (editorController != null) {
+            editorController.setSelectedExplorerNode(node);
+        }
+        if (node instanceof JmeSpatial) {
+            selectSpatial(((JmeSpatial) node).getLookup().lookup(Spatial.class));
+            SceneViewerTopComponent.findInstance().setActivatedNodes(new org.openide.nodes.Node[]{node});
+            SceneExplorerTopComponent.findInstance().setSelectedNode(node);
+            return true;
+        } else if (toolController != null) {
+            Spatial selectedGizmo = toolController.getMarker(node);
+            if (selectedGizmo != null) {
+                selectSpatial(selectedGizmo);
+                SceneViewerTopComponent.findInstance().setActivatedNodes(new org.openide.nodes.Node[]{node});
+                SceneExplorerTopComponent.findInstance().setSelectedNode(node);
+                return true;
+            }
         }
         }
+        return false;
     }
     }
 
 
-    private void selectSpatial(JmeSpatial spatial) {
+    private void selectSpatial(Spatial selection) {
         if (editorController != null) {
         if (editorController != null) {
-            editorController.setSelectedSpat(spatial);
+            editorController.setSelectedSpat(selection);
         }
         }
-        if (spatial == null) {
+        if (selection == null) {
             setSelectedObjectText(null);
             setSelectedObjectText(null);
             return;
             return;
-        } else {
-            if (toolController != null) {
-                toolController.setSelectedSpatial(spatial);
-                toolController.updateSelection(spatial.getLookup().lookup(Spatial.class));
-            }
+        } else if (toolController != null) {
+            toolController.updateSelection(selection);
         }
         }
-        if (spatial.getLookup().lookup(Node.class) != null) {
-            setSelectedObjectText(spatial.getLookup().lookup(Node.class).getName());
-        } else if (spatial.getLookup().lookup(Spatial.class) != null) {
-            setSelectedObjectText(spatial.getLookup().lookup(Spatial.class).getName());
+        if (selection instanceof Node) {
+            setSelectedObjectText(((Node) selection).getName());
+        } else if (selection instanceof Spatial) {
+            setSelectedObjectText(selection.getName());
         } else {
         } else {
             setSelectedObjectText(null);
             setSelectedObjectText(null);
         }
         }
-        SceneViewerTopComponent.findInstance().setActivatedNodes(new org.openide.nodes.Node[]{spatial});
-        SceneExplorerTopComponent.findInstance().setSelectedNode(spatial);
+
     }
     }
 
 
     private void cleanupControllers() {
     private void cleanupControllers() {
@@ -1029,7 +1055,7 @@ private void jToggleSelectGeomActionPerformed(java.awt.event.ActionEvent evt) {/
             editorController.setToolController(toolController);
             editorController.setToolController(toolController);
             toolController.refreshNonSpatialMarkers();
             toolController.refreshNonSpatialMarkers();
             toolController.setCamController(camController);
             toolController.setCamController(camController);
-            
+
             editorController.setTerrainLodCamera();
             editorController.setTerrainLodCamera();
             final SpatialAssetDataObject dobj = ((SpatialAssetDataObject) currentRequest.getDataObject());
             final SpatialAssetDataObject dobj = ((SpatialAssetDataObject) currentRequest.getDataObject());
             listener = new ProjectAssetManager.ClassPathChangeListener() {
             listener = new ProjectAssetManager.ClassPathChangeListener() {

+ 131 - 190
jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneEditorController.java

@@ -52,115 +52,92 @@ import org.openide.util.Exceptions;
 import org.openide.util.Lookup;
 import org.openide.util.Lookup;
 
 
 /**
 /**
- * Example of a class that edits the scene, logic happens on the AWT side,
- * do.. methods do not use global variables.
+ * Example of a class that edits the scene, logic happens on the AWT side, do..
+ * methods do not use global variables.
+ *
  * @author normenhansen
  * @author normenhansen
  */
  */
 @SuppressWarnings({"unchecked", "rawtypes"})
 @SuppressWarnings({"unchecked", "rawtypes"})
-public class SceneEditorController implements PropertyChangeListener, NodeListener {
-    
+public class SceneEditorController implements NodeListener {
+
     private final JmeSpatial jmeRootNode;
     private final JmeSpatial jmeRootNode;
-    private JmeSpatial selectedSpat;
+    private Spatial selectedSpat;
+    private AbstractSceneExplorerNode selectedExplorerNode;
+
     private DataObject currentFileObject;
     private DataObject currentFileObject;
 //    private boolean needSave = false;
 //    private boolean needSave = false;
     private SceneComposerToolController toolController;
     private SceneComposerToolController toolController;
-    
+
     public SceneEditorController(JmeSpatial jmeRootNode, DataObject currentFileObject) {
     public SceneEditorController(JmeSpatial jmeRootNode, DataObject currentFileObject) {
         this.jmeRootNode = jmeRootNode;
         this.jmeRootNode = jmeRootNode;
+        jmeRootNode.addNodeListener(this);
         this.currentFileObject = currentFileObject;
         this.currentFileObject = currentFileObject;
     }
     }
-    
+
     public void setToolController(SceneComposerToolController toolController) {
     public void setToolController(SceneComposerToolController toolController) {
         this.toolController = toolController;
         this.toolController = toolController;
     }
     }
-    
+
     public JmeSpatial getJmeRootNode() {
     public JmeSpatial getJmeRootNode() {
         return jmeRootNode;
         return jmeRootNode;
     }
     }
-    
-    public JmeSpatial getSelectedSpat() {
+
+    public Spatial getSelectedSpat() {
         return selectedSpat;
         return selectedSpat;
     }
     }
-    
-    public void setSelectedSpat(JmeSpatial selectedSpat) {
-        if (this.selectedSpat == selectedSpat) {
-            return;
+
+    public void setSelectedExplorerNode(AbstractSceneExplorerNode node) {
+        if (selectedExplorerNode != null) {
+            selectedExplorerNode.removePropertyChangeListener(this);
+            selectedExplorerNode.removeNodeListener(this);
         }
         }
-        if (this.selectedSpat != null) {
-            this.selectedSpat.removePropertyChangeListener(this);
-            this.selectedSpat.removeNodeListener(this);
+        
+        selectedExplorerNode = node;
+        
+        if (selectedExplorerNode != null) {
+            selectedExplorerNode.addPropertyChangeListener(this);
+            selectedExplorerNode.addNodeListener(this);
         }
         }
+
+    }
+
+    public void setSelectedSpat(Spatial selectedSpat) {
         this.selectedSpat = selectedSpat;
         this.selectedSpat = selectedSpat;
-        if (selectedSpat != null) {
-            selectedSpat.addPropertyChangeListener(this);//WeakListeners.propertyChange(this, selectedSpat));
-            selectedSpat.addNodeListener(this);//WeakListeners.propertyChange(this, selectedSpat));
-        }
+
     }
     }
-    
+
     public FileObject getCurrentFileObject() {
     public FileObject getCurrentFileObject() {
         return currentFileObject.getPrimaryFile();
         return currentFileObject.getPrimaryFile();
     }
     }
-    
+
     public DataObject getCurrentDataObject() {
     public DataObject getCurrentDataObject() {
         return currentFileObject;
         return currentFileObject;
     }
     }
-    
+
     private void addSpatialUndo(final Node undoParent, final Spatial undoSpatial, final Light undoLight, final AbstractSceneExplorerNode parentNode) {
     private void addSpatialUndo(final Node undoParent, final Spatial undoSpatial, final Light undoLight, final AbstractSceneExplorerNode parentNode) {
         //add undo
         //add undo
         if (undoParent != null && undoSpatial != null) {
         if (undoParent != null && undoSpatial != null) {
             Lookup.getDefault().lookup(SceneUndoRedoManager.class).addEdit(this, new AbstractUndoableSceneEdit() {
             Lookup.getDefault().lookup(SceneUndoRedoManager.class).addEdit(this, new AbstractUndoableSceneEdit() {
-                
+
                 @Override
                 @Override
                 public void sceneUndo() throws CannotUndoException {
                 public void sceneUndo() throws CannotUndoException {
                     //undo stuff here
                     //undo stuff here
                     undoSpatial.removeFromParent();
                     undoSpatial.removeFromParent();
                 }
                 }
-                
+
                 @Override
                 @Override
                 public void sceneRedo() throws CannotRedoException {
                 public void sceneRedo() throws CannotRedoException {
                     //redo stuff here
                     //redo stuff here
                     undoParent.attachChild(undoSpatial);
                     undoParent.attachChild(undoSpatial);
                 }
                 }
-                
-                @Override
-                public void awtRedo() {
-                    if (parentNode != null) {
-                        parentNode.refresh(true);
-                    }
-                }
-                
-                @Override
-                public void awtUndo() {
-                    if (parentNode != null) {
-                        parentNode.refresh(true);
-                    }
-                }
-            });
-        }
-        if (undoParent != null && undoLight != null) {
-            Lookup.getDefault().lookup(SceneUndoRedoManager.class).addEdit(this, new AbstractUndoableSceneEdit() {
-                
-                @Override
-                public void sceneUndo() throws CannotUndoException {
-                    //undo stuff here
-                    undoParent.removeLight(undoLight);
-                    toolController.removeLightMarker(undoLight);
-                }
-                
-                @Override
-                public void sceneRedo() throws CannotRedoException {
-                    //redo stuff here
-                    undoParent.addLight(undoLight);
-                    toolController.addLightMarker(undoLight);
-                }
-                
+
                 @Override
                 @Override
                 public void awtRedo() {
                 public void awtRedo() {
                     if (parentNode != null) {
                     if (parentNode != null) {
                         parentNode.refresh(true);
                         parentNode.refresh(true);
                     }
                     }
                 }
                 }
-                
+
                 @Override
                 @Override
                 public void awtUndo() {
                 public void awtUndo() {
                     if (parentNode != null) {
                     if (parentNode != null) {
@@ -170,21 +147,21 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             });
             });
         }
         }
     }
     }
-    
+
     public void moveSelectedSpatial(final Vector3f point) {
     public void moveSelectedSpatial(final Vector3f point) {
         if (selectedSpat == null) {
         if (selectedSpat == null) {
             return;
             return;
         }
         }
         try {
         try {
-            final Spatial node = selectedSpat.getLookup().lookup(Spatial.class);
+            final Spatial node = selectedSpat;
             if (node != null) {
             if (node != null) {
                 setNeedsSave(true);
                 setNeedsSave(true);
                 SceneApplication.getApplication().enqueue(new Callable() {
                 SceneApplication.getApplication().enqueue(new Callable() {
-                    
+
                     public Object call() throws Exception {
                     public Object call() throws Exception {
                         doMoveSpatial(node, point);
                         doMoveSpatial(node, point);
                         return null;
                         return null;
-                        
+
                     }
                     }
                 }).get();
                 }).get();
             }
             }
@@ -194,7 +171,7 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             Exceptions.printStackTrace(ex);
             Exceptions.printStackTrace(ex);
         }
         }
     }
     }
-    
+
     public void doMoveSpatial(Spatial selected, Vector3f translation) {
     public void doMoveSpatial(Spatial selected, Vector3f translation) {
         Vector3f localTranslation = selected.getLocalTranslation();
         Vector3f localTranslation = selected.getLocalTranslation();
         Vector3f before = new Vector3f(localTranslation);
         Vector3f before = new Vector3f(localTranslation);
@@ -211,17 +188,17 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
         selected.setLocalTranslation(localTranslation);
         selected.setLocalTranslation(localTranslation);
         moveUndo(selected, before, after);
         moveUndo(selected, before, after);
     }
     }
-    
+
     private void moveUndo(final Spatial spatial, final Vector3f before, final Vector3f after) {
     private void moveUndo(final Spatial spatial, final Vector3f before, final Vector3f after) {
         if (spatial != null && before != null) {
         if (spatial != null && before != null) {
             Lookup.getDefault().lookup(SceneUndoRedoManager.class).addEdit(this, new AbstractUndoableSceneEdit() {
             Lookup.getDefault().lookup(SceneUndoRedoManager.class).addEdit(this, new AbstractUndoableSceneEdit() {
-                
+
                 @Override
                 @Override
                 public void sceneUndo() throws CannotUndoException {
                 public void sceneUndo() throws CannotUndoException {
                     //undo stuff here
                     //undo stuff here
                     spatial.setLocalTranslation(before);
                     spatial.setLocalTranslation(before);
                 }
                 }
-                
+
                 @Override
                 @Override
                 public void sceneRedo() throws CannotRedoException {
                 public void sceneRedo() throws CannotRedoException {
                     //redo stuff here
                     //redo stuff here
@@ -230,21 +207,21 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             });
             });
         }
         }
     }
     }
-    
+
     public void nudgeSelectedSpatial(final Vector3f amount) {
     public void nudgeSelectedSpatial(final Vector3f amount) {
         if (selectedSpat == null) {
         if (selectedSpat == null) {
             return;
             return;
         }
         }
         try {
         try {
-            final Spatial node = selectedSpat.getLookup().lookup(Spatial.class);
+            final Spatial node = selectedSpat;
             if (node != null) {
             if (node != null) {
                 setNeedsSave(true);
                 setNeedsSave(true);
                 SceneApplication.getApplication().enqueue(new Callable() {
                 SceneApplication.getApplication().enqueue(new Callable() {
-                    
+
                     public Object call() throws Exception {
                     public Object call() throws Exception {
                         doNudgeSpatial(node, amount);
                         doNudgeSpatial(node, amount);
                         return null;
                         return null;
-                        
+
                     }
                     }
                 }).get();
                 }).get();
             }
             }
@@ -254,24 +231,24 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             Exceptions.printStackTrace(ex);
             Exceptions.printStackTrace(ex);
         }
         }
     }
     }
-    
+
     public void doNudgeSpatial(Spatial selected, Vector3f translation) {
     public void doNudgeSpatial(Spatial selected, Vector3f translation) {
         Vector3f before = new Vector3f(selected.getLocalTranslation());
         Vector3f before = new Vector3f(selected.getLocalTranslation());
         selected.setLocalTranslation(before.add(translation));
         selected.setLocalTranslation(before.add(translation));
         Vector3f after = new Vector3f(selected.getLocalTranslation());
         Vector3f after = new Vector3f(selected.getLocalTranslation());
         nudgeUndo(selected, before, after);
         nudgeUndo(selected, before, after);
     }
     }
-    
+
     private void nudgeUndo(final Spatial spatial, final Vector3f before, final Vector3f after) {
     private void nudgeUndo(final Spatial spatial, final Vector3f before, final Vector3f after) {
         if (spatial != null && before != null) {
         if (spatial != null && before != null) {
             Lookup.getDefault().lookup(SceneUndoRedoManager.class).addEdit(this, new AbstractUndoableSceneEdit() {
             Lookup.getDefault().lookup(SceneUndoRedoManager.class).addEdit(this, new AbstractUndoableSceneEdit() {
-                
+
                 @Override
                 @Override
                 public void sceneUndo() throws CannotUndoException {
                 public void sceneUndo() throws CannotUndoException {
                     //undo stuff here
                     //undo stuff here
                     spatial.setLocalTranslation(before);
                     spatial.setLocalTranslation(before);
                 }
                 }
-                
+
                 @Override
                 @Override
                 public void sceneRedo() throws CannotRedoException {
                 public void sceneRedo() throws CannotRedoException {
                     //redo stuff here
                     //redo stuff here
@@ -280,21 +257,21 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             });
             });
         }
         }
     }
     }
-    
+
     public void rotateSelectedSpatial(final Quaternion amount) {
     public void rotateSelectedSpatial(final Quaternion amount) {
         if (selectedSpat == null) {
         if (selectedSpat == null) {
             return;
             return;
         }
         }
         try {
         try {
-            final Spatial node = selectedSpat.getLookup().lookup(Spatial.class);
+            final Spatial node = selectedSpat;
             if (node != null) {
             if (node != null) {
                 setNeedsSave(true);
                 setNeedsSave(true);
                 SceneApplication.getApplication().enqueue(new Callable() {
                 SceneApplication.getApplication().enqueue(new Callable() {
-                    
+
                     public Object call() throws Exception {
                     public Object call() throws Exception {
                         doRotateSpatial(node, amount);
                         doRotateSpatial(node, amount);
                         return null;
                         return null;
-                        
+
                     }
                     }
                 }).get();
                 }).get();
             }
             }
@@ -304,24 +281,24 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             Exceptions.printStackTrace(ex);
             Exceptions.printStackTrace(ex);
         }
         }
     }
     }
-    
+
     public void doRotateSpatial(Spatial selected, Quaternion rotation) {
     public void doRotateSpatial(Spatial selected, Quaternion rotation) {
         Quaternion before = new Quaternion(selected.getLocalRotation());
         Quaternion before = new Quaternion(selected.getLocalRotation());
         selected.rotate(rotation);
         selected.rotate(rotation);
         Quaternion after = new Quaternion(selected.getLocalRotation());
         Quaternion after = new Quaternion(selected.getLocalRotation());
         rotateUndo(selected, before, after);
         rotateUndo(selected, before, after);
     }
     }
-    
+
     private void rotateUndo(final Spatial spatial, final Quaternion before, final Quaternion after) {
     private void rotateUndo(final Spatial spatial, final Quaternion before, final Quaternion after) {
         if (spatial != null && before != null) {
         if (spatial != null && before != null) {
             Lookup.getDefault().lookup(SceneUndoRedoManager.class).addEdit(this, new AbstractUndoableSceneEdit() {
             Lookup.getDefault().lookup(SceneUndoRedoManager.class).addEdit(this, new AbstractUndoableSceneEdit() {
-                
+
                 @Override
                 @Override
                 public void sceneUndo() throws CannotUndoException {
                 public void sceneUndo() throws CannotUndoException {
                     //undo stuff here
                     //undo stuff here
                     spatial.setLocalRotation(before);
                     spatial.setLocalRotation(before);
                 }
                 }
-                
+
                 @Override
                 @Override
                 public void sceneRedo() throws CannotRedoException {
                 public void sceneRedo() throws CannotRedoException {
                     //redo stuff here
                     //redo stuff here
@@ -330,21 +307,21 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             });
             });
         }
         }
     }
     }
-    
+
     public void createTangentsForSelectedSpatial() {
     public void createTangentsForSelectedSpatial() {
         if (selectedSpat == null) {
         if (selectedSpat == null) {
             return;
             return;
         }
         }
         try {
         try {
-            final Spatial node = selectedSpat.getLookup().lookup(Spatial.class);
+            final Spatial node = selectedSpat;
             if (node != null) {
             if (node != null) {
                 setNeedsSave(true);
                 setNeedsSave(true);
                 SceneApplication.getApplication().enqueue(new Callable() {
                 SceneApplication.getApplication().enqueue(new Callable() {
-                    
+
                     public Object call() throws Exception {
                     public Object call() throws Exception {
                         doCreateTangents(node);
                         doCreateTangents(node);
                         return null;
                         return null;
-                        
+
                     }
                     }
                 }).get();
                 }).get();
             }
             }
@@ -354,7 +331,7 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             Exceptions.printStackTrace(ex);
             Exceptions.printStackTrace(ex);
         }
         }
     }
     }
-    
+
     public void doCreateTangents(Spatial selected) {
     public void doCreateTangents(Spatial selected) {
         if (selected instanceof Geometry) {
         if (selected instanceof Geometry) {
             Geometry geom = (Geometry) selected;
             Geometry geom = (Geometry) selected;
@@ -365,16 +342,16 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             }
             }
         }
         }
     }
     }
-    
+
     private void createTrangentsUndo(final Mesh mesh) {
     private void createTrangentsUndo(final Mesh mesh) {
         if (mesh != null) {
         if (mesh != null) {
             Lookup.getDefault().lookup(SceneUndoRedoManager.class).addEdit(this, new AbstractUndoableSceneEdit() {
             Lookup.getDefault().lookup(SceneUndoRedoManager.class).addEdit(this, new AbstractUndoableSceneEdit() {
-                
+
                 @Override
                 @Override
                 public void sceneUndo() throws CannotUndoException {
                 public void sceneUndo() throws CannotUndoException {
                     mesh.clearBuffer(Type.Tangent);
                     mesh.clearBuffer(Type.Tangent);
                 }
                 }
-                
+
                 @Override
                 @Override
                 public void sceneRedo() throws CannotRedoException {
                 public void sceneRedo() throws CannotRedoException {
                     TangentBinormalGenerator.generate(mesh);
                     TangentBinormalGenerator.generate(mesh);
@@ -382,21 +359,21 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             });
             });
         }
         }
     }
     }
-    
+
     public void createPhysicsMeshForSelectedSpatial() {
     public void createPhysicsMeshForSelectedSpatial() {
         if (selectedSpat == null) {
         if (selectedSpat == null) {
             return;
             return;
         }
         }
         try {
         try {
-            final Spatial node = selectedSpat.getLookup().lookup(Spatial.class);
+            final Spatial node = selectedSpat;
             setNeedsSave(true);
             setNeedsSave(true);
             if (node != null) {
             if (node != null) {
                 SceneApplication.getApplication().enqueue(new Callable() {
                 SceneApplication.getApplication().enqueue(new Callable() {
-                    
+
                     public Object call() throws Exception {
                     public Object call() throws Exception {
                         doCreatePhysicsMesh(node);
                         doCreatePhysicsMesh(node);
                         return null;
                         return null;
-                        
+
                     }
                     }
                 }).get();
                 }).get();
             }
             }
@@ -406,7 +383,7 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             Exceptions.printStackTrace(ex);
             Exceptions.printStackTrace(ex);
         }
         }
     }
     }
-    
+
     public void doCreatePhysicsMesh(Spatial selected) {
     public void doCreatePhysicsMesh(Spatial selected) {
         RigidBodyControl control = selected.getControl(RigidBodyControl.class);
         RigidBodyControl control = selected.getControl(RigidBodyControl.class);
         if (control != null) {
         if (control != null) {
@@ -422,21 +399,21 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
         refreshSelected();
         refreshSelected();
         addControlUndo(parent, control, jmeRootNode);
         addControlUndo(parent, control, jmeRootNode);
     }
     }
-    
+
     public void createDynamicPhysicsMeshForSelectedSpatial(final float weight) {
     public void createDynamicPhysicsMeshForSelectedSpatial(final float weight) {
         if (selectedSpat == null) {
         if (selectedSpat == null) {
             return;
             return;
         }
         }
         try {
         try {
-            final Spatial node = selectedSpat.getLookup().lookup(Spatial.class);
+            final Spatial node = selectedSpat;
             setNeedsSave(true);
             setNeedsSave(true);
             if (node != null) {
             if (node != null) {
                 SceneApplication.getApplication().enqueue(new Callable() {
                 SceneApplication.getApplication().enqueue(new Callable() {
-                    
+
                     public Object call() throws Exception {
                     public Object call() throws Exception {
                         doCreateDynamicPhysicsMesh(node, weight);
                         doCreateDynamicPhysicsMesh(node, weight);
                         return null;
                         return null;
-                        
+
                     }
                     }
                 }).get();
                 }).get();
             }
             }
@@ -446,7 +423,7 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             Exceptions.printStackTrace(ex);
             Exceptions.printStackTrace(ex);
         }
         }
     }
     }
-    
+
     public void doCreateDynamicPhysicsMesh(Spatial selected, float weight) {
     public void doCreateDynamicPhysicsMesh(Spatial selected, float weight) {
         RigidBodyControl control = selected.getControl(RigidBodyControl.class);
         RigidBodyControl control = selected.getControl(RigidBodyControl.class);
         if (control != null) {
         if (control != null) {
@@ -462,21 +439,21 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
         refreshSelected();
         refreshSelected();
         addControlUndo(parent, control, jmeRootNode);
         addControlUndo(parent, control, jmeRootNode);
     }
     }
-    
+
     public void createCharacterControlForSelectedSpatial(final boolean auto, final float radius, final float height) {
     public void createCharacterControlForSelectedSpatial(final boolean auto, final float radius, final float height) {
         if (selectedSpat == null) {
         if (selectedSpat == null) {
             return;
             return;
         }
         }
         try {
         try {
-            final Spatial node = selectedSpat.getLookup().lookup(Spatial.class);
+            final Spatial node = selectedSpat;
             setNeedsSave(true);
             setNeedsSave(true);
             if (node != null) {
             if (node != null) {
                 SceneApplication.getApplication().enqueue(new Callable() {
                 SceneApplication.getApplication().enqueue(new Callable() {
-                    
+
                     public Object call() throws Exception {
                     public Object call() throws Exception {
                         doCreateCharacterControl(node, auto, radius, height);
                         doCreateCharacterControl(node, auto, radius, height);
                         return null;
                         return null;
-                        
+
                     }
                     }
                 }).get();
                 }).get();
             }
             }
@@ -486,7 +463,7 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             Exceptions.printStackTrace(ex);
             Exceptions.printStackTrace(ex);
         }
         }
     }
     }
-    
+
     public void doCreateCharacterControl(Spatial selected, boolean auto, float radius, float height) {
     public void doCreateCharacterControl(Spatial selected, boolean auto, float radius, float height) {
         CharacterControl control = selected.getControl(CharacterControl.class);
         CharacterControl control = selected.getControl(CharacterControl.class);
         if (control != null) {
         if (control != null) {
@@ -507,30 +484,30 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
         refreshSelected();
         refreshSelected();
         addControlUndo(parent, control, jmeRootNode);
         addControlUndo(parent, control, jmeRootNode);
     }
     }
-    
+
     private void addControlUndo(final Node undoParent, final Control undoControl, final AbstractSceneExplorerNode parentNode) {
     private void addControlUndo(final Node undoParent, final Control undoControl, final AbstractSceneExplorerNode parentNode) {
         if (undoParent != null && undoControl != null) {
         if (undoParent != null && undoControl != null) {
             Lookup.getDefault().lookup(SceneUndoRedoManager.class).addEdit(this, new AbstractUndoableSceneEdit() {
             Lookup.getDefault().lookup(SceneUndoRedoManager.class).addEdit(this, new AbstractUndoableSceneEdit() {
-                
+
                 @Override
                 @Override
                 public void sceneUndo() throws CannotUndoException {
                 public void sceneUndo() throws CannotUndoException {
                     //undo stuff here
                     //undo stuff here
                     undoParent.removeControl(undoControl);
                     undoParent.removeControl(undoControl);
                 }
                 }
-                
+
                 @Override
                 @Override
                 public void sceneRedo() throws CannotRedoException {
                 public void sceneRedo() throws CannotRedoException {
                     //redo stuff here
                     //redo stuff here
                     undoParent.addControl(undoControl);
                     undoParent.addControl(undoControl);
                 }
                 }
-                
+
                 @Override
                 @Override
                 public void awtRedo() {
                 public void awtRedo() {
                     if (parentNode != null) {
                     if (parentNode != null) {
                         parentNode.refresh(true);
                         parentNode.refresh(true);
                     }
                     }
                 }
                 }
-                
+
                 @Override
                 @Override
                 public void awtUndo() {
                 public void awtUndo() {
                     if (parentNode != null) {
                     if (parentNode != null) {
@@ -540,20 +517,20 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             });
             });
         }
         }
     }
     }
-    
+
     public void addModel(final SpatialAssetDataObject file, final Vector3f location) {
     public void addModel(final SpatialAssetDataObject file, final Vector3f location) {
         if (selectedSpat == null) {
         if (selectedSpat == null) {
             return;
             return;
         }
         }
-        final Node selected = selectedSpat.getLookup().lookup(Node.class);
-        ProjectAssetManager manager = file.getLookup().lookup(ProjectAssetManager.class);
-        if (manager != null) {
-            manager.clearCache();
-        }
-        if (selected != null) {
+        if (selectedSpat instanceof Node) {
+            final Node selected = (Node) selectedSpat;
+            ProjectAssetManager manager = file.getLookup().lookup(ProjectAssetManager.class);
+            if (manager != null) {
+                manager.clearCache();
+            }
             setNeedsSave(true);
             setNeedsSave(true);
             SceneApplication.getApplication().enqueue(new Callable<Object>() {
             SceneApplication.getApplication().enqueue(new Callable<Object>() {
-                
+
                 public Object call() throws Exception {
                 public Object call() throws Exception {
                     doAddModel(file, selected, location);
                     doAddModel(file, selected, location);
                     return null;
                     return null;
@@ -563,7 +540,7 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             displayInfo("Please select a Node to attach to\nin the SceneExplorer.");
             displayInfo("Please select a Node to attach to\nin the SceneExplorer.");
         }
         }
     }
     }
-    
+
     public void doAddModel(SpatialAssetDataObject file, Node selected, Vector3f location) {
     public void doAddModel(SpatialAssetDataObject file, Node selected, Vector3f location) {
         ProgressHandle progressHandle = ProgressHandle.createHandle("Adding Model..");
         ProgressHandle progressHandle = ProgressHandle.createHandle("Adding Model..");
         progressHandle.start();
         progressHandle.start();
@@ -588,18 +565,18 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             DialogDisplayer.getDefault().notifyLater(msg);
             DialogDisplayer.getDefault().notifyLater(msg);
         }
         }
         progressHandle.finish();
         progressHandle.finish();
-        
+
     }
     }
-    
+
     public void linkModel(final AssetManager manager, final String assetName, final Vector3f location) {
     public void linkModel(final AssetManager manager, final String assetName, final Vector3f location) {
         if (selectedSpat == null) {
         if (selectedSpat == null) {
             return;
             return;
         }
         }
-        final Node selected = selectedSpat.getLookup().lookup(Node.class);
-        if (selected != null) {
+        if (selectedSpat instanceof Node) {
+            final Node selected = (Node) selectedSpat;
             setNeedsSave(true);
             setNeedsSave(true);
             SceneApplication.getApplication().enqueue(new Callable<Object>() {
             SceneApplication.getApplication().enqueue(new Callable<Object>() {
-                
+
                 public Object call() throws Exception {
                 public Object call() throws Exception {
                     doLinkModel(manager, assetName, selected, location);
                     doLinkModel(manager, assetName, selected, location);
                     return null;
                     return null;
@@ -609,7 +586,7 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             displayInfo("Please select a Node to attach to\nin the SceneExplorer.");
             displayInfo("Please select a Node to attach to\nin the SceneExplorer.");
         }
         }
     }
     }
-    
+
     public void doLinkModel(AssetManager manager, String assetName, Node selected, Vector3f location) {
     public void doLinkModel(AssetManager manager, String assetName, Node selected, Vector3f location) {
         ProgressHandle progressHandle = ProgressHandle.createHandle("Adding Model..");
         ProgressHandle progressHandle = ProgressHandle.createHandle("Adding Model..");
         progressHandle.start();
         progressHandle.start();
@@ -639,22 +616,22 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             DialogDisplayer.getDefault().notifyLater(msg);
             DialogDisplayer.getDefault().notifyLater(msg);
         }
         }
         progressHandle.finish();
         progressHandle.finish();
-        
+
     }
     }
-    
+
     public void addModel(final Spatial file) {
     public void addModel(final Spatial file) {
         addModel(file, null);
         addModel(file, null);
     }
     }
-    
+
     public void addModel(final Spatial file, final Vector3f location) {
     public void addModel(final Spatial file, final Vector3f location) {
         if (selectedSpat == null) {
         if (selectedSpat == null) {
             return;
             return;
         }
         }
-        final Node selected = selectedSpat.getLookup().lookup(Node.class);
-        if (selected != null) {
+        if (selectedSpat instanceof Node) {
+            final Node selected = (Node) selectedSpat;
             setNeedsSave(true);
             setNeedsSave(true);
             SceneApplication.getApplication().enqueue(new Callable<Object>() {
             SceneApplication.getApplication().enqueue(new Callable<Object>() {
-                
+
                 public Object call() throws Exception {
                 public Object call() throws Exception {
                     doAddModel(file, selected, location);
                     doAddModel(file, selected, location);
                     return null;
                     return null;
@@ -664,7 +641,7 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             displayInfo("Please select a Node to attach to\nin the SceneExplorer.");
             displayInfo("Please select a Node to attach to\nin the SceneExplorer.");
         }
         }
     }
     }
-    
+
     public void doAddModel(Spatial file, Node selected, Vector3f location) {
     public void doAddModel(Spatial file, Node selected, Vector3f location) {
         ProgressHandle progressHandle = ProgressHandle.createHandle("Adding Model..");
         ProgressHandle progressHandle = ProgressHandle.createHandle("Adding Model..");
         progressHandle.start();
         progressHandle.start();
@@ -687,43 +664,48 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             DialogDisplayer.getDefault().notifyLater(msg);
             DialogDisplayer.getDefault().notifyLater(msg);
         }
         }
         progressHandle.finish();
         progressHandle.finish();
-        
+
     }
     }
-    
+
     public void setNeedsSave(boolean state) {
     public void setNeedsSave(boolean state) {
         currentFileObject.setModified(state);
         currentFileObject.setModified(state);
     }
     }
-    
+
     public boolean isNeedSave() {
     public boolean isNeedSave() {
         return currentFileObject.isModified();
         return currentFileObject.isModified();
     }
     }
-    
+
+    @Override
     public void propertyChange(PropertyChangeEvent evt) {
     public void propertyChange(PropertyChangeEvent evt) {
 //        if ((evt.getOldValue() == null && !(evt.getNewValue() == null)) || ((evt.getOldValue() != null) && !evt.getOldValue().equals(evt.getNewValue()))) {
 //        if ((evt.getOldValue() == null && !(evt.getNewValue() == null)) || ((evt.getOldValue() != null) && !evt.getOldValue().equals(evt.getNewValue()))) {
 //            setNeedsSave(true);
 //            setNeedsSave(true);
 //        }
 //        }
     }
     }
-    
+
+    @Override
     public void childrenAdded(NodeMemberEvent ev) {
     public void childrenAdded(NodeMemberEvent ev) {
 //        setNeedsSave(true);
 //        setNeedsSave(true);
         toolController.refreshNonSpatialMarkers();
         toolController.refreshNonSpatialMarkers();
     }
     }
-    
+
+    @Override
     public void childrenRemoved(NodeMemberEvent ev) {
     public void childrenRemoved(NodeMemberEvent ev) {
 //        setNeedsSave(true);
 //        setNeedsSave(true);
         toolController.refreshNonSpatialMarkers();
         toolController.refreshNonSpatialMarkers();
     }
     }
-    
+
+    @Override
     public void childrenReordered(NodeReorderEvent ev) {
     public void childrenReordered(NodeReorderEvent ev) {
 //        setNeedsSave(true);
 //        setNeedsSave(true);
         toolController.refreshNonSpatialMarkers();
         toolController.refreshNonSpatialMarkers();
     }
     }
-    
+
+    @Override
     public void nodeDestroyed(NodeEvent ev) {
     public void nodeDestroyed(NodeEvent ev) {
 //        setNeedsSave(true);
 //        setNeedsSave(true);
         toolController.refreshNonSpatialMarkers();
         toolController.refreshNonSpatialMarkers();
     }
     }
-    
+
     public void saveScene() {
     public void saveScene() {
         try {
         try {
             currentFileObject.getLookup().lookup(SaveCookie.class).save();
             currentFileObject.getLookup().lookup(SaveCookie.class).save();
@@ -731,60 +713,19 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
             Exceptions.printStackTrace(ex);
             Exceptions.printStackTrace(ex);
         }
         }
     }
     }
-    
-    private void refreshSelected(final JmeSpatial spat) {
-        java.awt.EventQueue.invokeLater(new Runnable() {
-            
-            public void run() {
-                if (spat != null) {
-                    spat.refresh(false);
-                }
-            }
-        });
-        
-    }
-    
+
     private void refreshSelected() {
     private void refreshSelected() {
         java.awt.EventQueue.invokeLater(new Runnable() {
         java.awt.EventQueue.invokeLater(new Runnable() {
-            
-            public void run() {
-                if (getSelectedSpat() != null) {
-                    getSelectedSpat().refresh(false);
-                }
-            }
-        });
-        
-    }
-    
-    private void refreshSelectedParent() {
-        java.awt.EventQueue.invokeLater(new Runnable() {
-            
-            public void run() {
-                if (getSelectedSpat() != null) {
-                    ((JmeSpatial) getSelectedSpat().getParentNode()).refresh(false);
-                }
-            }
-        });
-        
-    }
-    
-    private void refreshRoot() {
-        java.awt.EventQueue.invokeLater(new Runnable() {
-            
+
             public void run() {
             public void run() {
-                if (getJmeRootNode() != null) {
-                    getJmeRootNode().refresh(true);
-                }
+                jmeRootNode.refresh(false);
             }
             }
         });
         });
-        
+
     }
     }
-    
+
     public void cleanup() {
     public void cleanup() {
         final Node node = jmeRootNode.getLookup().lookup(Node.class);
         final Node node = jmeRootNode.getLookup().lookup(Node.class);
-        if (selectedSpat != null) {
-            selectedSpat.removePropertyChangeListener(this);
-        }
     }
     }
 
 
     /**
     /**
@@ -795,7 +736,7 @@ public class SceneEditorController implements PropertyChangeListener, NodeListen
         Node root = jmeRootNode.getLookup().lookup(Node.class);
         Node root = jmeRootNode.getLookup().lookup(Node.class);
         TerrainUtils.enableLodControl(camera, root);
         TerrainUtils.enableLodControl(camera, root);
     }
     }
-    
+
     public void displayInfo(String info) {
     public void displayInfo(String info) {
         Message msg = new NotifyDescriptor.Message(info);
         Message msg = new NotifyDescriptor.Message(info);
         DialogDisplayer.getDefault().notifyLater(msg);
         DialogDisplayer.getDefault().notifyLater(msg);