ソースを参照

Added a light gizmo for light probe. Refactored the way light markers were done

Nehon 9 年 前
コミット
ab9ffd866b

+ 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);
+            }
+        }
+
+    }
+
+}

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

@@ -0,0 +1,66 @@
+/*
+ * 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.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.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 = BoundingSphereDebug.createDebugSphere(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) {
+        
+    }
+
+}