Explorar el Código

Merge branch 'sdk-only' of ../jmonkeyengine into PBRisComing

PBR modification of the SDK  originally done on the engine's repo
Rémy Bouquet hace 9 años
padre
commit
9c3a90a09f

+ 4 - 1
jme3-core/src/com/jme3/gde/core/scene/SceneApplication.java

@@ -28,6 +28,8 @@ import com.jme3.app.Application;
 import com.jme3.app.StatsView;
 import com.jme3.asset.AssetManager;
 import com.jme3.bullet.BulletAppState;
+import com.jme3.environment.EnvironmentCamera;
+import com.jme3.environment.util.LightsDebugState;
 import com.jme3.font.BitmapFont;
 import com.jme3.font.BitmapText;
 import com.jme3.gde.core.Installer;
@@ -244,7 +246,8 @@ public class SceneApplication extends Application implements LookupProvider {
                 viewPort.attachScene(toolsNode);
                 guiViewPort.attachScene(guiNode);
                 cam.setLocation(new Vector3f(0, 0, 10));
-
+                getStateManager().attach(new EnvironmentCamera());
+                
                 wireProcessor = new WireProcessor(assetManager);
 
                 inputManager.addMapping("MouseAxisX", new MouseAxisTrigger(MouseInput.AXIS_X, false));

+ 6 - 0
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeLight.java

@@ -150,6 +150,12 @@ public class JmeLight extends AbstractSceneExplorerNode {
         }
     }
 
+    public Spatial getSpatial() {
+        return spatial;
+    }
+    
+    
+
     public Class getExplorerObjectClass() {
         return Light.class;
     }

+ 131 - 0
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeLightProbe.java

@@ -0,0 +1,131 @@
+/*
+ *  Copyright (c) 2009-2010 jMonkeyEngine
+ *  All rights reserved.
+ * 
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ * 
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ *  * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ *  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.gde.core.sceneexplorer.nodes;
+
+import com.jme3.light.LightProbe;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import java.beans.PropertyEditor;
+import java.lang.reflect.InvocationTargetException;
+import org.openide.nodes.PropertySupport;
+import org.openide.nodes.Sheet;
+
+/**
+ *
+ * @author normenhansen
+ */
[email protected](service=SceneExplorerNode.class)
+@SuppressWarnings({"unchecked", "rawtypes"})
+public class JmeLightProbe extends JmeLight{
+    protected LightProbe lightProbe;
+
+    public JmeLightProbe() {
+    }
+
+    public JmeLightProbe(Spatial spatial, LightProbe lightProbe) {
+        super(spatial, lightProbe);
+        this.lightProbe = lightProbe;
+        lookupContents.add(lightProbe);
+        setName("LightProbe");
+    }
+
+    @Override
+    protected Sheet createSheet() {
+        //TODO: multithreading..
+        Sheet sheet = super.createSheet();
+        Sheet.Set set = Sheet.createPropertiesSet();
+        set.setDisplayName("LightProbe");
+        set.setName(LightProbe.class.getName());
+        LightProbe obj = lightProbe;
+        if (obj == null) {
+            return sheet;
+        }
+
+        set.put(makeProperty(obj, Vector3f.class, "getPosition", "setPosition", "Position"));
+        set.put(makeEmbedProperty(obj.getBounds(), obj.getBounds().getClass(), float.class, "getRadius", "setRadius", "Radius"));
+        set.put(createButtonProperty());
+        sheet.put(set);
+        return sheet;
+
+    }
+
+    public LightProbe getLightProbe() {
+        return lightProbe;
+    }
+
+    @Override
+    public Class getExplorerObjectClass() {
+        return LightProbe.class;
+    }
+
+    @Override
+    public Class getExplorerNodeClass() {
+        return JmeLightProbe.class;
+    }
+    
+    protected void setModified(){
+        java.awt.EventQueue.invokeLater(new Runnable() {
+
+            @Override
+            public void run() {
+                fireSave(true);
+            }
+        });
+        
+    }
+
+     private Property createButtonProperty() {
+        return new PropertySupport.ReadWrite<Object>("update", Object.class, "Refresh maps", "Click here to refresh environment maps ") {
+            JmeLightProbeButtonProperty pe;
+
+            @Override
+            public Object getValue() throws IllegalAccessException, InvocationTargetException {
+                return "";
+            }
+
+            @Override
+            public PropertyEditor getPropertyEditor() {
+                if (pe == null) {
+                    pe = new JmeLightProbeButtonProperty(JmeLightProbe.this, (Node)getSpatial());
+                    pe.attachEnv(pe.env);
+                }
+                return pe;
+            }
+
+            @Override
+            public void setValue(Object t) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+            }
+        };
+    }
+}

+ 99 - 0
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeLightProbeButtonProperty.java

@@ -0,0 +1,99 @@
+package com.jme3.gde.core.sceneexplorer.nodes;
+
+import com.jme3.environment.EnvironmentCamera;
+import com.jme3.environment.LightProbeFactory;
+import com.jme3.environment.generation.JobProgressAdapter;
+import com.jme3.gde.core.scene.SceneApplication;
+import com.jme3.gde.core.scene.controller.SceneToolController;
+import com.jme3.gde.core.util.ButtonInplaceEditor;
+import com.jme3.light.LightProbe;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Node;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.beans.PropertyEditorSupport;
+import java.util.concurrent.Callable;
+import org.netbeans.api.progress.ProgressHandle;
+import org.netbeans.api.progress.ProgressHandleFactory;
+import org.openide.explorer.propertysheet.ExPropertyEditor;
+import org.openide.explorer.propertysheet.InplaceEditor;
+import org.openide.explorer.propertysheet.PropertyEnv;
+
+/**
+ *
+ * @author Nehon
+ */
+public class JmeLightProbeButtonProperty extends PropertyEditorSupport implements ExPropertyEditor, InplaceEditor.Factory {
+
+    JmeLightProbe probe;
+    Node node;
+
+    public JmeLightProbeButtonProperty(JmeLightProbe pe, Node node) {
+        super();
+        this.node = node;
+        this.probe = pe;
+    }
+    PropertyEnv env;
+
+    @Override
+    public void attachEnv(PropertyEnv env) {
+        this.env = env;
+        env.registerInplaceEditorFactory(this);
+    }
+    private ButtonInplaceEditor ed = null;
+
+    @Override
+    public InplaceEditor getInplaceEditor() {
+        if (ed == null) {
+            ed = new ButtonInplaceEditor("Refresh");
+            ed.addActionListener(new ActionListener() {
+
+                @Override
+                public void actionPerformed(ActionEvent e) {
+
+                    SceneApplication.getApplication().enqueue(new Callable<Object>() {
+
+                        @Override
+                        public Object call() throws Exception {
+
+                            EnvironmentCamera envCam = SceneApplication.getApplication().getStateManager().getState(EnvironmentCamera.class);
+                            SceneToolController toolController = SceneApplication.getApplication().getStateManager().getState(SceneToolController.class);
+                            if (toolController != null) {
+                                envCam.setPosition(toolController.getCursorLocation());
+                            } else {
+                                envCam.setPosition(new Vector3f(0, 0, 0));
+                            }
+                            LightProbeFactory.updateProbe(probe.getLightProbe(), envCam, node, new JmeLightProbeProgressHandler());
+
+                            probe.setModified();
+
+                            return null;
+                        }
+                    });
+                }
+            });
+        }
+        return ed;
+    }
+
+    @Override
+    public boolean isPaintable() {
+        return true;
+    }
+
+    @Override
+    public void paintValue(Graphics gfx, Rectangle box) {
+        if (ed == null) {
+            getInplaceEditor();
+        }
+        ed.setSize(box.width, box.height);
+        ed.doLayout();
+        Graphics g = gfx.create(box.x, box.y, box.width, box.height);
+        ed.setOpaque(false);
+        ed.paint(g);
+        g.dispose();
+        probe.refresh(false);
+    }
+}

+ 42 - 0
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeLightProbeProgressHandler.java

@@ -0,0 +1,42 @@
+ 
+package com.jme3.gde.core.sceneexplorer.nodes;
+
+import com.jme3.environment.generation.JobProgressAdapter;
+import com.jme3.light.LightProbe;
+import org.netbeans.api.progress.ProgressHandle;
+import org.netbeans.api.progress.ProgressHandleFactory;
+
+/**
+ *
+ * @author Nehon
+ */
+
+
+public class JmeLightProbeProgressHandler extends JobProgressAdapter<LightProbe> {
+    
+    int lastProgress;
+    
+    ProgressHandle handle = ProgressHandleFactory.createHandle("Generating environment maps");
+    
+    @Override
+    public void start() {
+        handle.start(100);
+    }
+    
+    @Override
+    public void progress(double value) {
+        lastProgress = (int) (value * 100);
+        handle.progress(lastProgress);
+    }
+    
+    @Override
+    public void step(String message) {
+        handle.progress(message, lastProgress);
+    }
+    
+    @Override
+    public void done(LightProbe t) {
+        handle.finish();
+    }
+    
+}

+ 4 - 0
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeSpatialChildren.java

@@ -38,6 +38,7 @@ import com.jme3.light.AmbientLight;
 import com.jme3.light.DirectionalLight;
 import com.jme3.light.Light;
 import com.jme3.light.LightList;
+import com.jme3.light.LightProbe;
 import com.jme3.light.PointLight;
 import com.jme3.light.SpotLight;
 import com.jme3.scene.Geometry;
@@ -180,6 +181,9 @@ public class JmeSpatialChildren extends Children.Keys<Object> {
             if (pair.getLight() instanceof AmbientLight) {
                 return new Node[]{new JmeAmbientLight(pair.getSpatial(), (AmbientLight) pair.getLight()).setReadOnly(readOnly)};
             }
+            if (pair.getLight() instanceof LightProbe) {
+                return new Node[]{new JmeLightProbe(pair.getSpatial(), (LightProbe) pair.getLight()).setReadOnly(readOnly)};
+            }
             return new Node[]{new JmeLight(pair.getSpatial(), pair.getLight()).setReadOnly(readOnly)};
         } else if (key instanceof MeshGeometryPair) {
             MeshGeometryPair pair = (MeshGeometryPair) key;

+ 44 - 1
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/NewLightPopup.java

@@ -31,13 +31,20 @@
  */
 package com.jme3.gde.core.sceneexplorer.nodes.actions;
 
+import com.jme3.bounding.BoundingSphere;
+import com.jme3.environment.EnvironmentCamera;
+import com.jme3.environment.LightProbeFactory;
+import com.jme3.environment.generation.JobProgressAdapter;
 import com.jme3.gde.core.scene.SceneApplication;
+import com.jme3.gde.core.scene.controller.SceneToolController;
+import com.jme3.gde.core.sceneexplorer.nodes.JmeLightProbeProgressHandler;
 import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial;
 import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit;
 import com.jme3.gde.core.undoredo.SceneUndoRedoManager;
 import com.jme3.light.AmbientLight;
 import com.jme3.light.DirectionalLight;
 import com.jme3.light.Light;
+import com.jme3.light.LightProbe;
 import com.jme3.light.PointLight;
 import com.jme3.light.SpotLight;
 import com.jme3.math.ColorRGBA;
@@ -50,6 +57,8 @@ import javax.swing.JMenu;
 import javax.swing.JMenuItem;
 import javax.swing.undo.CannotRedoException;
 import javax.swing.undo.CannotUndoException;
+import org.netbeans.api.progress.ProgressHandle;
+import org.netbeans.api.progress.ProgressHandleFactory;
 import org.openide.loaders.DataObject;
 import org.openide.util.Lookup;
 import org.openide.util.actions.Presenter;
@@ -79,6 +88,7 @@ public class NewLightPopup extends AbstractAction implements Presenter.Popup {
         result.add(new JMenuItem(new AddDirectionalAction()));
         result.add(new JMenuItem(new AddPointAction()));
         result.add(new JMenuItem(new AddSpotAction()));
+        result.add(new JMenuItem(new AddProbeAction()));
         
         return result;
     }
@@ -147,7 +157,7 @@ public class NewLightPopup extends AbstractAction implements Presenter.Popup {
         }
     }
     
-      private class AddSpotAction extends AbstractAction {
+    private class AddSpotAction extends AbstractAction {
 
         public AddSpotAction() {
             putValue(NAME, "Spot Light");
@@ -167,6 +177,39 @@ public class NewLightPopup extends AbstractAction implements Presenter.Popup {
             });
         }
     }
+      
+    private class AddProbeAction extends AbstractAction {
+
+        public AddProbeAction() {
+            putValue(NAME, "Light Probe");
+        }
+
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            SceneApplication.getApplication().enqueue(new Callable<Void>() {
+
+                @Override
+                public Void call() throws Exception {
+                    
+                    EnvironmentCamera envCam = SceneApplication.getApplication().getStateManager().getState(EnvironmentCamera.class);
+                    SceneToolController toolController =  SceneApplication.getApplication().getStateManager().getState(SceneToolController.class);
+                    if(toolController != null){
+                        envCam.setPosition(toolController.getCursorLocation());                    
+                    } else {
+                        envCam.setPosition(new Vector3f(0, 0, 0));                    
+                    }
+                    LightProbe lightProbe = LightProbeFactory.makeProbe(envCam, node, new JmeLightProbeProgressHandler());                                
+                    node.addLight(lightProbe);
+                    ((BoundingSphere)lightProbe.getBounds()).setRadius(10);
+                    addLightUndo(node, lightProbe);
+                    setModified();
+                    
+                   
+                    return null;
+                }
+            });
+        }
+    }
 
     private void addLightUndo(final Spatial undoParent, final Light undoLight) {
         //add undo

+ 7 - 98
jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerToolController.java

@@ -10,10 +10,12 @@ import com.jme3.gde.core.scene.SceneApplication;
 import com.jme3.gde.core.scene.controller.SceneToolController;
 import com.jme3.gde.core.sceneexplorer.nodes.JmeNode;
 import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial;
+import com.jme3.gde.scenecomposer.gizmo.light.LightGizmoFactory;
 import com.jme3.gde.scenecomposer.tools.PickManager;
 import com.jme3.gde.scenecomposer.tools.shortcuts.ShortcutManager;
 import com.jme3.input.event.KeyInputEvent;
 import com.jme3.light.Light;
+import com.jme3.light.LightProbe;
 import com.jme3.light.PointLight;
 import com.jme3.light.SpotLight;
 import com.jme3.material.Material;
@@ -45,8 +47,7 @@ public class SceneComposerToolController extends SceneToolController {
     private SceneEditorController editorController;  
     private ViewPort overlayView;
     private Node onTopToolsNode;
-    private Node nonSpatialMarkersNode;
-    private Material lightMarkerMaterial;
+    private Node nonSpatialMarkersNode;    
     private Material audioMarkerMaterial;
     private JmeSpatial selectedSpatial;
     private boolean snapToGrid = false;
@@ -273,7 +274,7 @@ public class SceneComposerToolController extends SceneToolController {
      * @param light
      */
     public void addLightMarker(Light light) {
-        if (!(light instanceof PointLight) && !(light instanceof SpotLight))
+        if (!(light instanceof PointLight) && !(light instanceof SpotLight) && !(light instanceof LightProbe))
             return; // only handle point and spot lights
         
         Spatial s = nonSpatialMarkersNode.getChild(light.getName());
@@ -282,8 +283,7 @@ public class SceneComposerToolController extends SceneToolController {
             return;
         }
         
-        LightMarker lm = new LightMarker(light);
-        nonSpatialMarkersNode.attachChild(lm);
+        nonSpatialMarkersNode.attachChild(LightGizmoFactory.createGizmo(manager, light));
     }
     
     public void addAudioMarker(AudioNode audio) {
@@ -306,17 +306,7 @@ public class SceneComposerToolController extends SceneToolController {
         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;
-        }
-        return lightMarkerMaterial;
-    }
+
     
     private Material getAudioMarkerMaterial() {
         if (audioMarkerMaterial == null) {
@@ -422,88 +412,7 @@ public class SceneComposerToolController extends SceneToolController {
     public TransformationType getTransformationType() {
         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.

+ 57 - 0
jme3-scenecomposer/src/com/jme3/gde/scenecomposer/gizmo/light/LightGizmoControl.java

@@ -0,0 +1,57 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.scenecomposer.gizmo.light;
+
+import com.jme3.light.Light;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.control.BillboardControl;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import org.openide.util.Exceptions;
+
+/**
+ * Updates the marker's position whenever the light has moved. It is also a
+ * BillboardControl, so this marker always faces the camera
+ */
+public class LightGizmoControl extends BillboardControl {
+
+    private final Vector3f lastPos = new Vector3f();
+    private Vector3f lightPos;
+
+    LightGizmoControl(Light light) {
+        super();
+
+        try {
+            Method getPosition = light.getClass().getMethod("getPosition");
+            lightPos = (Vector3f) getPosition.invoke(light);
+        } catch (NoSuchMethodException ex) {
+            //light type doesn't have a get position method, silancing the exception
+        } catch (SecurityException ex) {
+            Exceptions.printStackTrace(ex);
+        } catch (IllegalAccessException ex) {
+            Exceptions.printStackTrace(ex);
+        } catch (IllegalArgumentException ex) {
+            Exceptions.printStackTrace(ex);
+        } catch (InvocationTargetException ex) {
+            Exceptions.printStackTrace(ex);
+        }
+
+    }
+
+    @Override
+    protected void controlUpdate(float f) {
+        super.controlUpdate(f);
+
+        if (!lightPos.equals(lastPos)) {
+            if (getSpatial() != null) {
+                lastPos.set(lightPos);
+                getSpatial().setLocalTranslation(lastPos);
+            }
+        }
+
+    }
+
+}

+ 68 - 0
jme3-scenecomposer/src/com/jme3/gde/scenecomposer/gizmo/light/LightGizmoFactory.java

@@ -0,0 +1,68 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.scenecomposer.gizmo.light;
+
+import com.jme3.asset.AssetManager;
+import com.jme3.environment.util.BoundingSphereDebug;
+import com.jme3.gde.scenecomposer.gizmo.light.shape.ProbeRadiusShape;
+import com.jme3.light.Light;
+import com.jme3.light.LightProbe;
+import com.jme3.material.Material;
+import com.jme3.material.RenderState;
+import com.jme3.renderer.queue.RenderQueue;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.control.BillboardControl;
+import com.jme3.scene.shape.Quad;
+import com.jme3.scene.shape.Sphere;
+import com.jme3.texture.Texture;
+
+/**
+ * Handles the creation of the appropriate light gizmo according to the light type.
+ * @author Nehon
+ */
+public class LightGizmoFactory {
+     
+    public static Spatial createGizmo(AssetManager assetManager, Light light){
+        switch (light.getType()){
+            case Probe:
+                return createLightProbeGizmo(assetManager, light);
+            default:
+                return createDefaultGizmo(assetManager, light);                
+        }
+       
+    }
+    
+    private static Spatial createDefaultGizmo(AssetManager assetManager, Light light){
+        Quad q = new Quad(0.5f, 0.5f);
+        Geometry g =  new Geometry(light.getName(), q);   
+        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+        Texture tex = assetManager.loadTexture("com/jme3/gde/scenecomposer/lightbulb32.png");
+        mat.setTexture("ColorMap", tex);
+        mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
+        g.setMaterial(mat);
+        g.addControl(new LightGizmoControl(light));
+        g.setQueueBucket(RenderQueue.Bucket.Transparent);
+        return g;
+    }
+    
+    private static Spatial createLightProbeGizmo(AssetManager assetManager, Light light){
+        Node debugNode = new Node("Environment debug Node");
+        Sphere s = new Sphere(16, 16, 0.5f);
+        Geometry debugGeom = new Geometry(light.getName(), s);
+        Material debugMaterial = new Material(assetManager, "Common/MatDefs/Misc/reflect.j3md");
+        debugGeom.setMaterial(debugMaterial);
+        Spatial debugBounds = ProbeRadiusShape.createShape(assetManager);
+        
+        debugNode.attachChild(debugGeom);
+        debugNode.attachChild(debugBounds);
+        debugNode.addControl(new LightProbeGizmoControl((LightProbe)light));
+        
+        return debugNode;        
+    }
+         
+}

+ 59 - 0
jme3-scenecomposer/src/com/jme3/gde/scenecomposer/gizmo/light/LightProbeGizmoControl.java

@@ -0,0 +1,59 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.scenecomposer.gizmo.light;
+
+import com.jme3.bounding.BoundingSphere;
+import com.jme3.environment.util.LightsDebugState;
+import com.jme3.light.LightProbe;
+import com.jme3.material.Material;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Node;
+import com.jme3.scene.control.AbstractControl;
+
+/**
+ * Updates the marker's position whenever the light probe has moved. 
+ * Also update the gizmo radius according to the probe radius.
+ */
+public class LightProbeGizmoControl extends AbstractControl{
+
+    private final Vector3f lastPos = new Vector3f();
+    private final LightProbe lightProbe;
+
+    LightProbeGizmoControl(LightProbe light) {
+        lightProbe = light;
+
+    }
+
+    @Override
+    protected void controlUpdate(float f) {       
+
+        if (!lightProbe.getPosition().equals(lastPos)) {
+            if (getSpatial() != null) {
+                lastPos.set(lightProbe.getPosition());
+                getSpatial().setLocalTranslation(lastPos);
+            }
+        }
+          
+        Geometry probeGeom = (Geometry) ((Node) getSpatial()).getChild(0);
+        Material m = probeGeom.getMaterial();        
+        if (lightProbe.isReady()) {            
+            m.setTexture("CubeMap", lightProbe.getPrefilteredEnvMap());            
+        } 
+        Geometry probeRadius = (Geometry) ((Node) getSpatial()).getChild(1);
+        probeRadius.setLocalScale(((BoundingSphere) lightProbe.getBounds()).getRadius());
+        
+
+    }
+
+    @Override
+    protected void controlRender(RenderManager rm, ViewPort vp) {
+        
+    }
+
+}

+ 23 - 0
jme3-scenecomposer/src/com/jme3/gde/scenecomposer/gizmo/light/mat/dashed/Dashed.j3sn

@@ -0,0 +1,23 @@
+ShaderNodeDefinitions{ 
+    ShaderNodeDefinition Dashed {      
+        Type: Fragment
+
+        Shader GLSL100: com/jme3/gde/scenecomposer/gizmo/light/mat/dashed/Dashed100.frag
+        
+        Documentation{
+            Renders dashed lines            
+            @input vec2 texCoord The texture coordinates
+            @input float size the size of the dashes
+            @input vec4 inColor the color of the fragment so far
+            @outColor vec4 color the output color
+        }
+        Input {
+            vec2 texCoord
+            vec4 inColor
+            float size
+        }
+        Output {
+            vec4 outColor
+        }
+    }
+}

+ 11 - 0
jme3-scenecomposer/src/com/jme3/gde/scenecomposer/gizmo/light/mat/dashed/Dashed100.frag

@@ -0,0 +1,11 @@
+
+void main(){
+        //@input vec2 texCoord The texture coordinates
+    //@input float size the size of the dashes
+    //@output vec4 color the output color
+
+    //insert glsl code here
+    outColor = inColor;
+    outColor.a = step(1.0 - size, texCoord.x);
+    
+}

+ 37 - 0
jme3-scenecomposer/src/com/jme3/gde/scenecomposer/gizmo/light/mat/dashed/dashed.j3md

@@ -0,0 +1,37 @@
+MaterialDef Simple {
+    MaterialParameters {
+        Float DashSize
+    }
+    Technique {
+        WorldParameters {
+            WorldViewProjectionMatrix
+        }
+        VertexShaderNodes {
+            ShaderNode CommonVert {
+                Definition : CommonVert : Common/MatDefs/ShaderNodes/Common/CommonVert.j3sn
+                InputMappings {
+                    worldViewProjectionMatrix = WorldParam.WorldViewProjectionMatrix
+                    modelPosition = Global.position.xyz
+                    texCoord1 = Attr.inTexCoord
+                    vertColor = Attr.inColor
+                }
+                OutputMappings {
+                    Global.position = projPosition
+                }
+            }
+        }
+        FragmentShaderNodes {
+            ShaderNode Dashed {
+                Definition : Dashed : com/jme3/gde/scenecomposer/gizmo/light/mat/dashed/Dashed.j3sn
+                InputMappings {
+                    texCoord = CommonVert.texCoord1
+                    inColor = CommonVert.vertColor
+                    size = MatParam.DashSize
+                }
+                OutputMappings {
+                    Global.color = outColor
+                }
+            }
+        }
+    }
+}

+ 168 - 0
jme3-scenecomposer/src/com/jme3/gde/scenecomposer/gizmo/light/shape/ProbeRadiusShape.java

@@ -0,0 +1,168 @@
+ /*
+ * Copyright (c) 2009-2015 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.gde.scenecomposer.gizmo.light.shape;
+
+import com.jme3.asset.AssetManager;
+import com.jme3.material.Material;
+import com.jme3.material.RenderState;
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.FastMath;
+import com.jme3.renderer.queue.RenderQueue;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Mesh;
+import com.jme3.scene.VertexBuffer.Type;
+import com.jme3.scene.control.BillboardControl;
+import com.jme3.util.BufferUtils;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+/**
+ * 
+ * A debuging shape for a BoundingSphere 
+ * Consists of 3 axis aligned circles.
+ * 
+ * @author nehon
+ */
+public class ProbeRadiusShape extends Mesh {
+
+    protected int vertCount;
+    protected int triCount;
+    protected int radialSamples = 256;
+    protected boolean useEvenSlices;
+    protected boolean interior;
+    /**
+     * the distance from the center point each point falls on
+     */
+    public float radius;
+
+    public float getRadius() {
+        return radius;
+    }
+
+    public ProbeRadiusShape() {
+        setGeometryData();
+        setIndexData();
+    }
+
+    /**
+     * builds the vertices based on the radius
+     */
+    private void setGeometryData() {
+        setMode(Mode.Lines);
+
+        FloatBuffer posBuf = BufferUtils.createVector3Buffer((radialSamples + 1));
+        FloatBuffer colBuf = BufferUtils.createFloatBuffer((radialSamples + 1) * 4);
+        FloatBuffer texBuf = BufferUtils.createVector2Buffer(radialSamples + 1);
+        
+
+        setBuffer(Type.Position, 3, posBuf);
+        setBuffer(Type.Color, 4, colBuf);
+        setBuffer(Type.TexCoord, 2, texBuf);
+
+        // generate geometry
+        float fInvRS = 1.0f / radialSamples;
+
+        // Generate points on the unit circle to be used in computing the mesh
+        // points on a sphere slice.
+        float[] afSin = new float[(radialSamples + 1)];
+        float[] afCos = new float[(radialSamples + 1)];
+        for (int iR = 0; iR < radialSamples; iR++) {
+            float fAngle = FastMath.TWO_PI * fInvRS * iR;
+            afCos[iR] = FastMath.cos(fAngle);
+            afSin[iR] = FastMath.sin(fAngle);
+        }
+        afSin[radialSamples] = afSin[0];
+        afCos[radialSamples] = afCos[0];
+
+        for (int iR = 0; iR <= radialSamples; iR++) {
+            posBuf.put(afCos[iR])
+                    .put(afSin[iR])
+                    .put(0);
+            colBuf.put(ColorRGBA.Orange.r)
+                    .put(ColorRGBA.Orange.g)
+                    .put(ColorRGBA.Orange.b)
+                    .put(ColorRGBA.Orange.a);
+            texBuf.put(iR % 2f)
+                    .put(iR % 2f);
+
+        }
+
+        updateBound();
+        setStatic();
+    }
+
+    /**
+     * sets the indices for rendering the sphere.
+     */
+    private void setIndexData() {
+        // allocate connectivity
+        int nbSegments = (radialSamples);// * 3;
+
+        ShortBuffer idxBuf = BufferUtils.createShortBuffer(2 * nbSegments);
+        setBuffer(Type.Index, 2, idxBuf);
+
+        int idx = 0;
+        int segDone = 0;
+        while (segDone < nbSegments) {
+            idxBuf.put((short) idx);
+            idxBuf.put((short) (idx + 1));
+            idx++;
+            segDone++;
+        }
+
+    }
+    
+
+    /**
+     * Convenience factory method that creates a debuging bounding sphere geometry
+     * @param assetManager the assetManager
+     * @return the bounding sphere debug geometry.
+     */
+    public static Geometry createShape(AssetManager assetManager) {
+        ProbeRadiusShape b = new ProbeRadiusShape();
+        Geometry geom = new Geometry("BoundingDebug", b);
+
+        Material mat = new Material(assetManager, "com/jme3/gde/scenecomposer/gizmo/light/mat/dashed/dashed.j3md");        
+        mat.getAdditionalRenderState().setWireframe(true);
+        mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
+        mat.getAdditionalRenderState().setDepthWrite(false);
+        mat.getAdditionalRenderState().setDepthTest(false);  
+        mat.setFloat("DashSize", 0.5f);
+        geom.setQueueBucket(RenderQueue.Bucket.Transparent);
+        geom.addControl(new BillboardControl());
+        
+        
+        geom.setMaterial(mat);
+        return geom;
+
+    }
+}