diff --git a/jme3-core/src/main/java/com/jme3/environment/LightProbeFactory.java b/jme3-core/src/main/java/com/jme3/environment/LightProbeFactory.java index 462ad22e1..7b8787bef 100644 --- a/jme3-core/src/main/java/com/jme3/environment/LightProbeFactory.java +++ b/jme3-core/src/main/java/com/jme3/environment/LightProbeFactory.java @@ -126,6 +126,51 @@ public class LightProbeFactory { }); return probe; } + + /** + * Updates a LightProbe with the giver EnvironmentCamera in the given scene. + * + * Note that this is an assynchronous process that will run on multiple threads. + * The process is thread safe. + * The created lightProbe will only be marked as ready when the rendering process is done. + * + * The JobProgressListener will be notified of the progress of the generation. + * Note that you can also use a {@link JobProgressAdapter}. + * + * @see LightProbe + * @see EnvironmentCamera + * @see JobProgressListener + * + * @param probe the Light probe to update + * @param envCam the EnvironmentCamera + * @param scene the Scene + * @param listener the listener of the genration progress. + * @return the created LightProbe + */ + public static LightProbe updateProbe(final LightProbe probe, final EnvironmentCamera envCam, Spatial scene, final JobProgressListener listener) { + + envCam.setPosition(probe.getPosition()); + + probe.setReady(false); + + if(probe.getIrradianceMap() == null) { + probe.getIrradianceMap().getImage().dispose(); + probe.getPrefilteredEnvMap().getImage().dispose(); + } + + probe.setIrradianceMap(EnvMapUtils.createIrradianceMap(envCam.getSize(), envCam.getImageFormat())); + probe.setPrefilteredMap(EnvMapUtils.createPrefilteredEnvMap(envCam.getSize(), envCam.getImageFormat())); + + + envCam.snapshot(scene, new JobProgressAdapter() { + + @Override + public void done(TextureCubeMap map) { + generatePbrMaps(map, probe, envCam.getApplication(), listener); + } + }); + return probe; + } /** * Internally called to generate the maps. diff --git a/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeLight.java b/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeLight.java index 673ef189c..f2c7798c4 100644 --- a/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeLight.java +++ b/sdk/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; } diff --git a/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeLightProbe.java b/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeLightProbe.java index 3164c593d..b7f86e3e4 100644 --- a/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeLightProbe.java +++ b/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeLightProbe.java @@ -34,7 +34,11 @@ 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; /** @@ -70,12 +74,16 @@ public class JmeLightProbe extends JmeLight{ 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; @@ -85,5 +93,39 @@ public class JmeLightProbe extends JmeLight{ 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("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 { + } + }; + } } diff --git a/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeLightProbeButtonProperty.java b/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeLightProbeButtonProperty.java new file mode 100644 index 000000000..ade61b4c6 --- /dev/null +++ b/sdk/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() { + + @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); + } +} diff --git a/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeLightProbeProgressHandler.java b/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeLightProbeProgressHandler.java new file mode 100644 index 000000000..af7b539cb --- /dev/null +++ b/sdk/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 { + + 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(); + } + +} diff --git a/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/NewLightPopup.java b/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/NewLightPopup.java index 5ae75dd45..f2b870644 100644 --- a/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/NewLightPopup.java +++ b/sdk/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/NewLightPopup.java @@ -37,6 +37,7 @@ 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; @@ -197,33 +198,7 @@ public class NewLightPopup extends AbstractAction implements Presenter.Popup { } else { envCam.setPosition(new Vector3f(0, 0, 0)); } - LightProbe lightProbe = LightProbeFactory.makeProbe(envCam, node, new JobProgressAdapter() { - - 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(); - } - }); + LightProbe lightProbe = LightProbeFactory.makeProbe(envCam, node, new JmeLightProbeProgressHandler()); node.addLight(lightProbe); ((BoundingSphere)lightProbe.getBounds()).setRadius(10); addLightUndo(node, lightProbe);