Bläddra i källkod

SDK :
- added toggle Orthographic / Perspective view button in the scene composer accessible through keyboard shortcuts
- fixed some focus issues

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7870 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

rem..om 14 år sedan
förälder
incheckning
53ad438970

+ 34 - 29
jme3-core/src/com/jme3/gde/core/scene/SceneApplication.java

@@ -1,33 +1,26 @@
 /*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
+ * Copyright (c) 2009-2010 jMonkeyEngine All rights reserved. <p/>
  * 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
+ * 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. <p/> * 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. <p/> * 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. <p/> 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.
+ * 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.scene;
 
@@ -45,6 +38,7 @@ import com.jme3.input.controls.MouseAxisTrigger;
 import com.jme3.input.controls.MouseButtonTrigger;
 import com.jme3.light.PointLight;
 import com.jme3.math.ColorRGBA;
+import com.jme3.math.FastMath;
 import com.jme3.math.Vector3f;
 import com.jme3.renderer.RenderManager;
 import com.jme3.renderer.ViewPort;
@@ -74,7 +68,8 @@ import org.openide.util.Utilities;
 import org.openide.util.lookup.Lookups;
 
 /**
- * 
+ * <p/> <p/> <p/> <p/>
+ * <p/>
  * @author normenhansen
  */
 @SuppressWarnings("unchecked")
@@ -139,6 +134,12 @@ public class SceneApplication extends Application implements LookupProvider, Loo
         }
     }
 
+    public SceneCameraController getCamController() {
+        return camController;
+    }
+    
+    
+
     private void loadFPSText() {
         BitmapFont font = assetManager.loadFont("Interface/Fonts/Default.fnt");
 
@@ -233,12 +234,12 @@ public class SceneApplication extends Application implements LookupProvider, Loo
             guiNode.updateGeometricState();
             toolsNode.updateGeometricState();
             getStateManager().render(renderManager);
-            if (context.isRenderable()){
+            if (context.isRenderable()) {
                 renderManager.render(tpf);
             }
             getStateManager().postRender();
         } catch (NullPointerException e) {
-            handleError("NullPointerException: "+e.getMessage(), e);
+            handleError("NullPointerException: " + e.getMessage(), e);
         } catch (Exception e) {
             handleError(e.getMessage(), e);
         } catch (Error e) {
@@ -469,6 +470,10 @@ public class SceneApplication extends Application implements LookupProvider, Loo
         });
     }
 
+    public boolean toggleOrthoPerspMode() {
+        return camController.toggleOrthoPerspMode();
+    }
+
     public void enableWireFrame(final boolean selected) {
         enqueue(new Callable() {
 

+ 159 - 83
jme3-core/src/com/jme3/gde/core/scene/controller/AbstractCameraController.java

@@ -1,33 +1,26 @@
 /*
- *  Copyright (c) 2009-2010 jMonkeyEngine
- *  All rights reserved.
+ * Copyright (c) 2009-2010 jMonkeyEngine All rights reserved. <p/>
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
  * 
- *  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.
+ *  * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer. <p/> * 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. <p/> * 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. <p/> 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.scene.controller;
 
@@ -35,6 +28,7 @@ import com.jme3.app.Application;
 import com.jme3.app.state.AbstractAppState;
 import com.jme3.app.state.AppStateManager;
 import com.jme3.gde.core.scene.SceneApplication;
+import com.jme3.gde.core.sceneviewer.SceneViewerTopComponent;
 import com.jme3.input.InputManager;
 import com.jme3.input.RawInputListener;
 import com.jme3.input.controls.ActionListener;
@@ -50,21 +44,25 @@ import com.jme3.math.Quaternion;
 import com.jme3.math.Vector3f;
 import com.jme3.renderer.Camera;
 import com.jme3.renderer.RenderManager;
+import java.awt.FocusTraversalPolicy;
 import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
 import java.util.logging.Logger;
+import org.openide.util.Exceptions;
 
 /**
  *
  * @author normenhansen
  */
-public abstract class AbstractCameraController extends AbstractAppState implements ActionListener, AnalogListener, RawInputListener{
+public abstract class AbstractCameraController extends AbstractAppState implements ActionListener, AnalogListener, RawInputListener {
 
     protected boolean leftMouse, rightMouse, middleMouse;
     protected float deltaX, deltaY, deltaZ, deltaWheel;
     protected int mouseX = 0;
     protected int mouseY = 0;
     protected Quaternion rot = new Quaternion();
-    protected Vector3f vector = new Vector3f(0,0,5);
+    protected Vector3f vector = new Vector3f(0, 0, 5);
     protected Vector3f focus = new Vector3f();
     protected Camera cam;
     protected InputManager inputManager;
@@ -73,10 +71,13 @@ public abstract class AbstractCameraController extends AbstractAppState implemen
     protected boolean movedR = false;
     protected boolean buttonDownL = false;
     protected boolean buttonDownR = false;
+    protected boolean buttonDownM = false;
     protected boolean checkClickL = false;
     protected boolean checkClickR = false;
+    protected boolean checkClickM = false;
     protected boolean checkReleaseL = false;
     protected boolean checkReleaseR = false;
+    protected boolean checkReleaseM = false;
     protected boolean checkDragged = false;
     protected boolean checkDraggedR = false;
     protected boolean checkReleaseLeft = false;
@@ -84,7 +85,7 @@ public abstract class AbstractCameraController extends AbstractAppState implemen
 
     public AbstractCameraController(Camera cam, InputManager inputManager) {
         this.cam = cam;
-        this.inputManager=inputManager;
+        this.inputManager = inputManager;
     }
 
     public void setMaster(Object component) {
@@ -158,6 +159,55 @@ public abstract class AbstractCameraController extends AbstractAppState implemen
         Vector3f loc = cam.getLocation().clone();
         loc.scaleAdd(amount, cam.getDirection(), loc);
         cam.setLocation(loc);
+
+        if (cam.isParallelProjection()) {
+            float aspect = (float) cam.getWidth() / cam.getHeight();
+            float h = FastMath.tan(45f * FastMath.DEG_TO_RAD * .5f) * dist;
+            float w = h * aspect;
+            cam.setFrustum(-1000, 1000, -w, w, h, -h);
+        }
+
+    }
+
+    public boolean toggleOrthoPerspMode() {
+        try {
+            return SceneApplication.getApplication().enqueue(new Callable<Boolean>() {
+
+                public Boolean call() throws Exception {
+                    return doToggleOrthoPerspMode();
+                }
+            }).get();
+        } catch (InterruptedException ex) {
+            Exceptions.printStackTrace(ex);
+        } catch (ExecutionException ex) {
+            Exceptions.printStackTrace(ex);
+        }
+        return false;
+
+    }
+
+    protected boolean doToggleOrthoPerspMode() {
+
+        float aspect = (float) cam.getWidth() / cam.getHeight();
+        if (!cam.isParallelProjection()) {
+            cam.setParallelProjection(true);
+            float h = cam.getFrustumTop();
+            float w = cam.getFrustumRight();
+            float dist = cam.getLocation().distance(focus);
+            float fovY = FastMath.atan(h) / (FastMath.DEG_TO_RAD * .5f);
+            h = FastMath.tan(fovY * FastMath.DEG_TO_RAD * .5f) * dist;
+            w = h * aspect;
+            cam.setFrustum(-1000, 1000, -w, w, h, -h);
+            return true;
+        } else {
+            cam.setParallelProjection(false);
+            cam.setFrustumPerspective(45f, aspect, 1, 1000);
+            return false;
+        }
+
+
+
+
     }
 
     /*public void onAction(String string, boolean bln, float f) {
@@ -198,12 +248,11 @@ public abstract class AbstractCameraController extends AbstractAppState implemen
             }
         }
     }*/
-
     public void onAnalog(String string, float f1, float f) {
         if ("MouseAxisX".equals(string)) {
             moved = true;
             movedR = true;
-            if (buttonDownL) {
+            if (buttonDownL || buttonDownM) {
                 rotateCamera(Vector3f.UNIT_Y, -f1 * 2.5f);
             }
             if (buttonDownR) {
@@ -212,7 +261,7 @@ public abstract class AbstractCameraController extends AbstractAppState implemen
         } else if ("MouseAxisY".equals(string)) {
             moved = true;
             movedR = true;
-            if (buttonDownL) {
+            if (buttonDownL || buttonDownM) {
                 rotateCamera(cam.getLeft(), -f1 * 2.5f);
             }
             if (buttonDownR) {
@@ -221,7 +270,7 @@ public abstract class AbstractCameraController extends AbstractAppState implemen
         } else if ("MouseAxisX-".equals(string)) {
             moved = true;
             movedR = true;
-            if (buttonDownL) {
+            if (buttonDownL || buttonDownM) {
                 rotateCamera(Vector3f.UNIT_Y, f1 * 2.5f);
             }
             if (buttonDownR) {
@@ -230,7 +279,7 @@ public abstract class AbstractCameraController extends AbstractAppState implemen
         } else if ("MouseAxisY-".equals(string)) {
             moved = true;
             movedR = true;
-            if (buttonDownL) {
+            if (buttonDownL || buttonDownM) {
                 rotateCamera(cam.getLeft(), f1 * 2.5f);
             }
             if (buttonDownR) {
@@ -242,9 +291,11 @@ public abstract class AbstractCameraController extends AbstractAppState implemen
             zoomCamera(-.1f);
         }
     }
-    
+
     public void onAction(String string, boolean pressed, float f) {
         if ("MouseButtonLeft".equals(string)) {
+
+
             if (pressed) {
                 if (!buttonDownL) { // mouse clicked
                     checkClickL = true;
@@ -272,6 +323,22 @@ public abstract class AbstractCameraController extends AbstractAppState implemen
             }
             buttonDownR = pressed;
         }
+        if ("MouseButtonMiddle".equals(string)) {
+            if (pressed) {
+                if (!buttonDownM) { // mouse clicked
+                    checkClickM = true;
+                    checkReleaseM = false;
+                }
+            } else {
+                if (buttonDownM) { // mouse released
+                    checkReleaseM = true;
+                    checkClickM = false;
+                }
+            }
+            buttonDownM = pressed;
+        }
+
+
     }
 
     public void onJoyAxisEvent(JoyAxisEvent jae) {
@@ -286,17 +353,29 @@ public abstract class AbstractCameraController extends AbstractAppState implemen
     }
 
     public void onMouseButtonEvent(MouseButtonEvent mbe) {
+        //on a click release we request the focus for the top component
+        //this allow netbeans to catch keyEvents and trigger actions according to keymapping
+        if (mbe.isReleased()) {
+            java.awt.EventQueue.invokeLater(new Runnable() {
+
+                public void run() {
+                    SceneViewerTopComponent.findInstance().requestActive();
+                }
+            });
+        }
+
     }
 
     public void onKeyEvent(KeyInputEvent kie) {
     }
-    
-    public void onTouchEvent(TouchEvent evt) {        
-    }
 
-    /**APPSTATE**/
+    public void onTouchEvent(TouchEvent evt) {
+    }
+    /**
+     * APPSTATE*
+     */
     private boolean appInit = false;
-    
+
     @Override
     public void initialize(AppStateManager asm, Application aplctn) {
         appInit = true;
@@ -319,23 +398,32 @@ public abstract class AbstractCameraController extends AbstractAppState implemen
     public void update(float f) {
         if (moved) {
             // moved, check for drags
-            if (checkReleaseL || checkReleaseR) {
+            if (checkReleaseL || checkReleaseR || checkReleaseM) {
                 // drag released
-                if (checkReleaseL)
+                if (checkReleaseL) {
                     checkDragged(0, false);
-                if (checkReleaseR)
+                }
+                if (checkReleaseR) {
                     checkDragged(1, false);
+                }
+                if (checkReleaseM) {
+                    checkDragged(2, false);
+                }
                 checkReleaseL = false;
                 checkReleaseR = false;
+                checkReleaseM = false;
             } else {
-                if (buttonDownL)
+                if (buttonDownL) {
                     checkDragged(0, true);
-                else if (buttonDownR)
+                } else if (buttonDownR) {
                     checkDragged(1, true);
-                else
+                } else if (buttonDownM) {
+                    checkDragged(2, true);
+                } else {
                     checkMoved(); // no dragging, just moved
+                }
             }
-            
+
             moved = false;
         } else {
             // not moved, check for just clicks
@@ -355,39 +443,28 @@ public abstract class AbstractCameraController extends AbstractAppState implemen
                 checkClick(1, false);
                 checkReleaseR = false;
             }
-        }
-        
-        /*if (checkDragged || checkDraggedR) {
-            if (checkDragged) {
-                checkDragged(0);
-                checkReleaseLeft = false;
-                checkDragged = false;
-                checkClick = false;
-                checkClickR = false;
-            }
-            if (checkDraggedR) {
-                checkDragged(1);
-                checkReleaseRight = false;
-                checkDraggedR = false;
-                checkClick = false;
-                checkClickR = false;
+            if (checkClickM) {
+                checkClick(2, true);
+                checkClickM = false;
             }
-        } else {
-            if (checkClick) {
-                checkClick(0, checkReleaseLeft);
-                checkReleaseLeft = false;
-                checkClick = false;
-                checkDragged = false;
-                checkDraggedR = false;
+            if (checkReleaseM) {
+                checkClick(2, false);
+                checkReleaseM = false;
             }
-            if (checkClickR) {
-                checkClick(1, checkReleaseRight);
-                checkReleaseRight = false;
-                checkClickR = false;
-                checkDragged = false;
-                checkDraggedR = false;
-            }
-        }*/
+        }
+
+        /*
+         * if (checkDragged || checkDraggedR) { if (checkDragged) {
+         * checkDragged(0); checkReleaseLeft = false; checkDragged = false;
+         * checkClick = false; checkClickR = false; } if (checkDraggedR) {
+         * checkDragged(1); checkReleaseRight = false; checkDraggedR = false;
+         * checkClick = false; checkClickR = false; } } else { if (checkClick) {
+         * checkClick(0, checkReleaseLeft); checkReleaseLeft = false; checkClick
+         * = false; checkDragged = false; checkDraggedR = false; } if
+         * (checkClickR) { checkClick(1, checkReleaseRight); checkReleaseRight =
+         * false; checkClickR = false; checkDragged = false; checkDraggedR =
+         * false; } }
+         */
     }
 
     /**
@@ -395,14 +472,14 @@ public abstract class AbstractCameraController extends AbstractAppState implemen
      * @param pressed true if pressed, false if released
      */
     protected abstract void checkClick(int button, boolean pressed);
-    
+
     /**
      * Mouse dragged while button is depressed
      */
     protected void checkDragged(int button, boolean pressed) {
         // override in sub classes
     }
-    
+
     /**
      * The mouse moved, no dragging or buttons pressed
      */
@@ -427,5 +504,4 @@ public abstract class AbstractCameraController extends AbstractAppState implemen
 
     public void endInput() {
     }
-
 }

+ 5 - 1
jme3-core/src/com/jme3/gde/core/sceneviewer/Bundle.properties

@@ -7,5 +7,9 @@ SceneViewerTopComponent.enableWireframe.toolTipText=Toggle wireframe mode
 SceneViewerTopComponent.enableWireframe.text=
 SceneViewerTopComponent.enableStats.toolTipText=Display Stats
 SceneViewerTopComponent.enableStats.text=
-SceneViewerTopComponent.jToggleButton1.text=
+SceneViewerTopComponent.jToggleButton2.AccessibleContext.accessibleName=Ortho / Persp
 SceneViewerTopComponent.jToggleButton1.toolTipText=show post filter effects
+SceneViewerTopComponent.jToggleButton1.text=
+SceneViewerTopComponent.enableOrtho.text=Persp.
+SceneViewerTopComponent.enableOrtho.textO=Ortho.
+SceneViewerTopComponent.enableOrtho.toolTipText=Toggle Orthographic / Perspective view

+ 44 - 4
jme3-core/src/com/jme3/gde/core/sceneviewer/SceneViewerTopComponent.form

@@ -53,7 +53,7 @@
         <Component class="javax.swing.JToggleButton" name="jToggleButton1">
           <Properties>
             <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
-              <Image iconType="3" name="com/jme3/gde/core/filters/icons/eye.gif"/>
+              <Image iconType="3" name="/com/jme3/gde/core/filters/icons/eye.gif"/>
             </Property>
             <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
               <ResourceString bundle="com/jme3/gde/core/sceneviewer/Bundle.properties" key="SceneViewerTopComponent.jToggleButton1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
@@ -93,6 +93,49 @@
             <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="enableWireframeActionPerformed"/>
           </Events>
         </Component>
+        <Component class="javax.swing.JToolBar$Separator" name="jSeparator2">
+        </Component>
+        <Component class="javax.swing.JToggleButton" name="enableOrtho">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="8" style="0"/>
+            </Property>
+            <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+              <Image iconType="3" name="/com/jme3/gde/core/sceneviewer/icons/persp.png"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/core/sceneviewer/Bundle.properties" key="SceneViewerTopComponent.enableOrtho.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/core/sceneviewer/Bundle.properties" key="SceneViewerTopComponent.enableOrtho.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor">
+              <Color id="Pointeur par d&#xe9;faut"/>
+            </Property>
+            <Property name="focusable" type="boolean" value="false"/>
+            <Property name="horizontalTextPosition" type="int" value="4"/>
+            <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[27, 23]"/>
+            </Property>
+            <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[27, 23]"/>
+            </Property>
+            <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+              <Dimension value="[50, 23]"/>
+            </Property>
+            <Property name="selectedIcon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+              <Image iconType="3" name="/com/jme3/gde/core/sceneviewer/icons/ortho.png"/>
+            </Property>
+          </Properties>
+          <AccessibilityProperties>
+            <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/core/sceneviewer/Bundle.properties" key="SceneViewerTopComponent.jToggleButton2.AccessibleContext.accessibleName" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </AccessibilityProperties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="enableOrthoActionPerformed"/>
+          </Events>
+        </Component>
         <Container class="javax.swing.JPanel" name="jPanel1">
 
           <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
@@ -123,9 +166,6 @@
         <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
           <Dimension value="[100, 100]"/>
         </Property>
-        <Property name="size" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
-          <Dimension value="[100, 100]"/>
-        </Property>
       </Properties>
       <Constraints>
         <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">

+ 81 - 28
jme3-core/src/com/jme3/gde/core/sceneviewer/SceneViewerTopComponent.java

@@ -1,40 +1,39 @@
 /*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
+ * Copyright (c) 2009-2010 jMonkeyEngine All rights reserved. <p/>
  * 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
+ * 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. <p/> * 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. <p/> * 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. <p/> 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.
+ * 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.sceneviewer;
 
 import com.jme3.gde.core.filters.FilterExplorerTopComponent;
 import com.jme3.gde.core.scene.SceneApplication;
+import com.jme3.gde.core.sceneviewer.actions.ToggleOrthoPerspAction;
 import com.jme3.system.JmeCanvasContext;
 import java.awt.Canvas;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
 import java.util.logging.Logger;
 import org.openide.util.NbBundle;
 import org.openide.windows.TopComponent;
@@ -48,6 +47,7 @@ import org.openide.awt.UndoRedo;
 import org.openide.util.Exceptions;
 import org.openide.util.HelpCtx;
 import org.openide.util.Lookup;
+import org.openide.util.lookup.Lookups;
 
 /**
  * Top component which displays something.
@@ -57,16 +57,21 @@ autostore = false)
 public final class SceneViewerTopComponent extends TopComponent {
 
     private static SceneViewerTopComponent 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/core/sceneviewer/jme-logo.png";
     private static final String PREFERRED_ID = "SceneViewerTopComponent";
     private SceneApplication app;
     private HelpCtx helpContext = new HelpCtx("com.jme3.gde.core.sceneviewer");
     private Canvas oglCanvas;
+    //toolbar actions
+    private ToggleOrthoPerspAction toggleOrthoPerspAction;
 
     public SceneViewerTopComponent() {
         initComponents();
         oGLPanel.setMinimumSize(new java.awt.Dimension(10, 10));
+        setFocusable(true);
         setName(NbBundle.getMessage(SceneViewerTopComponent.class, "CTL_SceneViewerTopComponent"));
         setToolTipText(NbBundle.getMessage(SceneViewerTopComponent.class, "HINT_SceneViewerTopComponent"));
         setIcon(ImageUtilities.loadImage(ICON_PATH, true));
@@ -74,6 +79,7 @@ public final class SceneViewerTopComponent extends TopComponent {
             app = SceneApplication.getApplication();
             oglCanvas = ((JmeCanvasContext) app.getContext()).getCanvas();
             oGLPanel.add(oglCanvas);
+            toggleOrthoPerspAction = new ToggleOrthoPerspAction();
         } catch (Exception e) {
             Exceptions.printStackTrace(e);
             showOpenGLError(e.toString());
@@ -81,6 +87,21 @@ public final class SceneViewerTopComponent extends TopComponent {
             Exceptions.printStackTrace(err);
             showOpenGLError(err.toString());
         }
+
+        //We add a mouse wheel listener to the top conmponent in order to correctly dispatch the event ot the cam controller
+        //the oGLPanel may naver have the focus.
+        addMouseWheelListener(new MouseWheelListener() {
+
+            public void mouseWheelMoved(MouseWheelEvent e) {
+                String action = "MouseWheel-";
+                if (e.getWheelRotation() < 0) {
+                    action = "MouseWheel";
+                }
+                app.getCamController().onAnalog(action, e.getWheelRotation(), 0);
+            }
+        });
+        
+       
     }
 
     /** This method is called from within the constructor to
@@ -96,6 +117,8 @@ public final class SceneViewerTopComponent extends TopComponent {
         jToggleButton1 = new javax.swing.JToggleButton();
         jSeparator1 = new javax.swing.JToolBar.Separator();
         enableWireframe = new javax.swing.JToggleButton();
+        jSeparator2 = new javax.swing.JToolBar.Separator();
+        enableOrtho = new javax.swing.JToggleButton();
         jPanel1 = new javax.swing.JPanel();
         enableStats = new javax.swing.JToggleButton();
         oGLPanel = new javax.swing.JPanel();
@@ -145,6 +168,27 @@ public final class SceneViewerTopComponent extends TopComponent {
             }
         });
         jToolBar1.add(enableWireframe);
+        jToolBar1.add(jSeparator2);
+
+        enableOrtho.setFont(new java.awt.Font("Tahoma", 0, 8)); // NOI18N
+        enableOrtho.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/core/sceneviewer/icons/persp.png"))); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(enableOrtho, org.openide.util.NbBundle.getMessage(SceneViewerTopComponent.class, "SceneViewerTopComponent.enableOrtho.text")); // NOI18N
+        enableOrtho.setToolTipText(org.openide.util.NbBundle.getMessage(SceneViewerTopComponent.class, "SceneViewerTopComponent.enableOrtho.toolTipText")); // NOI18N
+        enableOrtho.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
+        enableOrtho.setFocusable(false);
+        enableOrtho.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
+        enableOrtho.setMaximumSize(new java.awt.Dimension(27, 23));
+        enableOrtho.setMinimumSize(new java.awt.Dimension(27, 23));
+        enableOrtho.setPreferredSize(new java.awt.Dimension(50, 23));
+        enableOrtho.setSelectedIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/core/sceneviewer/icons/ortho.png"))); // NOI18N
+        enableOrtho.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                enableOrthoActionPerformed(evt);
+            }
+        });
+        jToolBar1.add(enableOrtho);
+        enableOrtho.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SceneViewerTopComponent.class, "SceneViewerTopComponent.jToggleButton2.AccessibleContext.accessibleName")); // NOI18N
+
         jToolBar1.add(jPanel1);
 
         enableStats.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/core/sceneviewer/icons/65.png"))); // NOI18N
@@ -163,7 +207,6 @@ public final class SceneViewerTopComponent extends TopComponent {
         add(jToolBar1, java.awt.BorderLayout.NORTH);
 
         oGLPanel.setPreferredSize(new java.awt.Dimension(100, 100));
-        oGLPanel.setSize(new java.awt.Dimension(100, 100));
         oGLPanel.setLayout(new java.awt.GridLayout(1, 0));
         add(oGLPanel, java.awt.BorderLayout.CENTER);
     }// </editor-fold>//GEN-END:initComponents
@@ -184,17 +227,27 @@ public final class SceneViewerTopComponent extends TopComponent {
         FilterExplorerTopComponent.findInstance().setFilterEnabled(jToggleButton1.isSelected());
     }//GEN-LAST:event_jToggleButton1ActionPerformed
 
+private void enableOrthoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_enableOrthoActionPerformed
+    toggleOrthoPerspAction.actionPerformed(evt);
+}//GEN-LAST:event_enableOrthoActionPerformed
     // Variables declaration - do not modify//GEN-BEGIN:variables
     private javax.swing.JToggleButton enableCamLight;
+    private javax.swing.JToggleButton enableOrtho;
     private javax.swing.JToggleButton enableStats;
     private javax.swing.JToggleButton enableWireframe;
     private javax.swing.JPanel jPanel1;
     private javax.swing.JToolBar.Separator jSeparator1;
+    private javax.swing.JToolBar.Separator jSeparator2;
     private javax.swing.JToggleButton jToggleButton1;
     private javax.swing.JToolBar jToolBar1;
     private javax.swing.JPanel oGLPanel;
     // End of variables declaration//GEN-END:variables
 
+    public void toggleOrthoModeButton(boolean enabled) {
+        enableOrtho.setText(NbBundle.getMessage(SceneViewerTopComponent.class, "SceneViewerTopComponent.enableOrtho.text" + (enabled ? "O" : "")));
+        enableOrtho.setSelected(enabled);
+    }
+
     /**
      * Gets default instance. Do not use directly: reserved for *.settings files only,
      * i.e. deserialization routines; otherwise you could get a non-deserialized instance.

+ 35 - 0
jme3-core/src/com/jme3/gde/core/sceneviewer/actions/ToggleOrthoPerspAction.java

@@ -0,0 +1,35 @@
+package com.jme3.gde.core.sceneviewer.actions;
+
+import com.jme3.gde.core.scene.SceneApplication;
+import com.jme3.gde.core.sceneviewer.SceneViewerTopComponent;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import org.openide.awt.ActionRegistration;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionID;
+import org.openide.util.NbBundle.Messages;
+
+@ActionID(category = "SceneComposer",
+id = "com.jme3.gde.core.sceneviewer.actions.ToggleOrthoPerspAction")
+@ActionRegistration(displayName = "#CTL_ToggleOrthoPerspAction")
+@ActionReferences({
+    @ActionReference(path = "Actions/jMonkeyPlatform"),
+    @ActionReference(path = "Shortcuts", name = "NUMPAD5")
+})
+@Messages("CTL_ToggleOrthoPerspAction=Toggle ortho / persp")
+public final class ToggleOrthoPerspAction implements ActionListener {
+
+    public ToggleOrthoPerspAction() {       
+    }
+
+    public void actionPerformed(ActionEvent e) {
+
+        SceneViewerTopComponent svtc = SceneViewerTopComponent.findInstance();
+        if (svtc.hasFocus()) {
+            boolean toggle = SceneApplication.getApplication().toggleOrthoPerspMode();
+            svtc.toggleOrthoModeButton(toggle);
+        }
+
+    }
+}

BIN
jme3-core/src/com/jme3/gde/core/sceneviewer/icons/ortho.png


BIN
jme3-core/src/com/jme3/gde/core/sceneviewer/icons/persp.png