ソースを参照

Merge remote-tracking branch 'upstream/master'

Daniel Johansson 10 年 前
コミット
7f2626af65
22 ファイル変更499 行追加243 行削除
  1. 6 5
      .travis.yml
  2. 11 2
      jme3-blender/src/main/java/com/jme3/scene/plugins/blender/animations/Ipo.java
  3. 45 12
      jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsRigidBody.cpp
  4. 22 5
      jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsRigidBody.h
  5. 46 6
      jme3-bullet/src/main/java/com/jme3/bullet/objects/PhysicsRigidBody.java
  6. 3 1
      jme3-core/src/main/java/com/jme3/cinematic/Cinematic.java
  7. 11 9
      jme3-core/src/main/java/com/jme3/cinematic/events/AnimationEvent.java
  8. 3 1
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java
  9. 12 1
      jme3-core/src/main/java/com/jme3/scene/BatchNode.java
  10. 69 0
      jme3-core/src/test/java/com/jme3/cinematic/CinematicTest.java
  11. 2 2
      sdk/jme3-core-updatecenters/src/com/jme3/gde/core/updatecenters/Bundle.properties
  12. 4 6
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionCurve.java
  13. 3 5
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionStraight.java
  14. 89 44
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Diagram.java
  15. 17 3
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/DraggablePanel.java
  16. 5 24
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/NodePanel.java
  17. 2 2
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/OutBusPanel.java
  18. 4 2
      sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DeleteShortcut.java
  19. 8 6
      sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java
  20. 8 6
      sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/RotateShortcut.java
  21. 8 6
      sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ScaleShortcut.java
  22. 121 95
      sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java

+ 6 - 5
.travis.yml

@@ -8,9 +8,9 @@ cache:
    - gradle-cache
    - netbeans
 
-branches:
-  only:
-  - master
+# branches:
+#   only:
+#   - master
 
 notifications:
   slack:
@@ -29,10 +29,11 @@ script:
 deploy:
   provider: releases
   api_key:
-    secure: "KbFiMt0a8FxUKvCJUYwikLYaqqGMn1p6k4OsXnGqwptQZEUIayabNLHeaD2kTNT3e6AY1ETwQLff/lB2LttmIo4g5NWW63g1K3A/HwgnhJwETengiProZ/Udl+ugPeDL/+ar43HUhFq4knBnzFKnEcHAThTPVqH/RMDvZf1UUYI="
-  file: build/distributions/jME3.1.0_snapshot-github_2015-06-20.zip
+    secure: PuEsJd6juXBH29ByITW3ntSAyrwWs0IeFvXJ5Y2YlhojhSMtTwkoWeB6YmDJWP4fhzbajk4TQ1HlOX2IxJXSW/8ShOEIUlGXz9fHiST0dkSM+iRAUgC5enCLW5ITPTiem7eY9ZhS9miIam7ngce9jHNMh75PTzZrEJtezoALT9w=
+  file: build/distributions/jME3.1.0_snapshot-github_2015-08-02.zip
   skip_cleanup: true
   on:
+    repo: jMonkeyEngine/jmonkeyengine
     tags: true
 
 # before_install:

+ 11 - 2
jme3-blender/src/main/java/com/jme3/scene/plugins/blender/animations/Ipo.java

@@ -145,7 +145,7 @@ public class Ipo {
 
             float[] times = new float[framesAmount + 1];
             Vector3f[] translations = new Vector3f[framesAmount + 1];
-            float[] translation = new float[] { localTranslation.x, localTranslation.y, localTranslation.z };
+            float[] translation = new float[3];
             Quaternion[] rotations = new Quaternion[framesAmount + 1];
             float[] quaternionRotation = new float[] { localRotation.getX(), localRotation.getY(), localRotation.getZ(), localRotation.getW(), };
             float[] eulerRotation = localRotation.toAngles(null);
@@ -165,6 +165,8 @@ public class Ipo {
 
             // calculating track data
             for (int frame = startFrame; frame <= stopFrame; ++frame) {
+                boolean translationSet = false;
+                translation[0] = translation[1] = translation[2] = 0;
                 int index = frame - startFrame;
                 times[index] = index * timeBetweenFrames;// start + (frame - 1) * timeBetweenFrames;
                 for (int j = 0; j < bezierCurves.length; ++j) {
@@ -173,15 +175,18 @@ public class Ipo {
                         // LOCATION
                         case AC_LOC_X:
                             translation[0] = (float) value;
+                            translationSet = true;
                             break;
                         case AC_LOC_Y:
                             if (swapAxes && value != 0) {
                                 value = -value;
                             }
                             translation[yIndex] = (float) value;
+                            translationSet = true;
                             break;
                         case AC_LOC_Z:
                             translation[zIndex] = (float) value;
+                            translationSet = true;
                             break;
 
                         // EULER ROTATION
@@ -235,7 +240,11 @@ public class Ipo {
                             LOGGER.log(Level.WARNING, "Unknown ipo curve type: {0}.", bezierCurves[j].getType());
                     }
                 }
-                translations[index] = localRotation.multLocal(new Vector3f(translation[0], translation[1], translation[2]));
+                if(translationSet) {
+                    translations[index] = localRotation.multLocal(new Vector3f(translation[0], translation[1], translation[2]));
+                } else {
+                    translations[index] = new Vector3f();
+                }
                 
                 if(boneContext != null) {
                     if(boneContext.getBone().getParent() == null && boneContext.is(BoneContext.NO_LOCAL_LOCATION)) {

+ 45 - 12
jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsRigidBody.cpp

@@ -811,39 +811,72 @@ extern "C" {
     /*
      * Class:     com_jme3_bullet_objects_PhysicsRigidBody
      * Method:    getAngularFactor
-     * Signature: (J)F
+     * Signature: (JLcom/jme3/math/Vector3f;)V
      */
-    JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngularFactor
-    (JNIEnv *env, jobject object, jlong bodyId) {
+    JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngularFactor
+    (JNIEnv *env, jobject object, jlong bodyId, jobject factor) {
         btRigidBody* body = reinterpret_cast<btRigidBody*>(bodyId);
         if (body == NULL) {
             jclass newExc = env->FindClass("java/lang/NullPointerException");
             env->ThrowNew(newExc, "The native object does not exist.");
-            return 0;
+            return;
         }
-        return body->getAngularFactor().getX();
+        jmeBulletUtil::convert(env, &body->getAngularFactor(), factor);
     }
 
+
     /*
      * Class:     com_jme3_bullet_objects_PhysicsRigidBody
      * Method:    setAngularFactor
-     * Signature: (JF)V
+     * Signature: (JLcom/jme3/math/Vector3f;)V
      */
     JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setAngularFactor
-    (JNIEnv *env, jobject object, jlong bodyId, jfloat value) {
+    (JNIEnv *env, jobject object, jlong bodyId, jobject factor) {
         btRigidBody* body = reinterpret_cast<btRigidBody*>(bodyId);
         if (body == NULL) {
             jclass newExc = env->FindClass("java/lang/NullPointerException");
             env->ThrowNew(newExc, "The native object does not exist.");
             return;
         }
-        btVector3 vec1 = btVector3();
-        vec1.setX(value);
-        vec1.setY(value);
-        vec1.setZ(value);
-        body->setAngularFactor(vec1);
+        btVector3 vec = btVector3();
+        jmeBulletUtil::convert(env, factor, &vec);
+        body->setAngularFactor(vec);
     }
 
+    /*
+     * Class:     com_jme3_bullet_objects_PhysicsRigidBody
+     * Method:    getLinearFactor
+     * Signature: (JLcom/jme3/math/Vector3f;)V
+     */
+    JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getLinearFactor
+    (JNIEnv *env, jobject object, jlong bodyId, jobject factor) {
+        btRigidBody* body = reinterpret_cast<btRigidBody*>(bodyId);
+        if (body == NULL) {
+            jclass newExc = env->FindClass("java/lang/NullPointerException");
+            env->ThrowNew(newExc, "The native object does not exist.");
+            return;
+        }
+        jmeBulletUtil::convert(env, &body->getLinearFactor(), factor);
+    }
+
+    /*
+     * Class:     com_jme3_bullet_objects_PhysicsRigidBody
+     * Method:    setLinearFactor
+     * Signature: (JLcom/jme3/math/Vector3f;)V
+     */
+    JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setLinearFactor
+    (JNIEnv *env, jobject object, jlong bodyId, jobject factor) {
+        btRigidBody* body = reinterpret_cast<btRigidBody*>(bodyId);
+        if (body == NULL) {
+            jclass newExc = env->FindClass("java/lang/NullPointerException");
+            env->ThrowNew(newExc, "The native object does not exist.");
+            return;
+        }
+        btVector3 vec = btVector3();
+        jmeBulletUtil::convert(env, factor, &vec);
+        body->setLinearFactor(vec);
+    }
+    
 #ifdef __cplusplus
 }
 #endif

+ 22 - 5
jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsRigidBody.h

@@ -396,18 +396,35 @@ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngula
 /*
  * Class:     com_jme3_bullet_objects_PhysicsRigidBody
  * Method:    getAngularFactor
- * Signature: (J)F
+ * Signature: (JLcom/jme3/math/Vector3f;)V
  */
-JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngularFactor
-  (JNIEnv *, jobject, jlong);
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngularFactor
+  (JNIEnv *, jobject, jlong, jobject);
+
 
 /*
  * Class:     com_jme3_bullet_objects_PhysicsRigidBody
  * Method:    setAngularFactor
- * Signature: (JF)V
+ * Signature: (JLcom/jme3/math/Vector3f;)V
  */
 JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setAngularFactor
-  (JNIEnv *, jobject, jlong, jfloat);
+  (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class:     com_jme3_bullet_objects_PhysicsRigidBody
+ * Method:    getLinearFactor
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getLinearFactor
+  (JNIEnv *, jobject, jlong, jobject);
+
+/*
+ * Class:     com_jme3_bullet_objects_PhysicsRigidBody
+ * Method:    setLinearFactor
+ * Signature: (JLcom/jme3/math/Vector3f;)V
+ */
+JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setLinearFactor
+  (JNIEnv *, jobject, jlong, jobject);
 
 #ifdef __cplusplus
 }

+ 46 - 6
jme3-bullet/src/main/java/com/jme3/bullet/objects/PhysicsRigidBody.java

@@ -627,16 +627,44 @@ public class PhysicsRigidBody extends PhysicsCollisionObject {
     private native float getAngularSleepingThreshold(long objectId);
 
     public float getAngularFactor() {
-        return getAngularFactor(objectId);
+        return getAngularFactor(null).getX();
     }
 
-    private native float getAngularFactor(long objectId);
+    public Vector3f getAngularFactor(Vector3f store) {
+        // doing like this prevent from breaking the API
+        if (store == null) {
+            store = new Vector3f();
+        }
+        getAngularFactor(objectId, store);
+        return store;
+    }
+
+    private native void getAngularFactor(long objectId, Vector3f vec);
 
     public void setAngularFactor(float factor) {
-        setAngularFactor(objectId, factor);
+        setAngularFactor(objectId, new Vector3f(factor, factor, factor));
+    }
+
+    public void setAngularFactor(Vector3f factor) {
+	setAngularFactor(objectId, factor);
+    }
+
+    private native void setAngularFactor(long objectId, Vector3f factor);
+
+    public Vector3f getLinearFactor() {
+        Vector3f vec = new Vector3f();
+	getLinearFactor(objectId, vec);
+        return vec;
     }
 
-    private native void setAngularFactor(long objectId, float factor);
+    private native void getLinearFactor(long objectId, Vector3f vec);
+
+    public void setLinearFactor(Vector3f factor) {
+	setLinearFactor(objectId, factor);
+    }
+
+    private native void setLinearFactor(long objectId, Vector3f factor);
+
 
     /**
      * do not use manually, joints are added automatically
@@ -673,7 +701,13 @@ public class PhysicsRigidBody extends PhysicsCollisionObject {
         capsule.write(getGravity(), "gravity", Vector3f.ZERO);
         capsule.write(getFriction(), "friction", 0.5f);
         capsule.write(getRestitution(), "restitution", 0);
-        capsule.write(getAngularFactor(), "angularFactor", 1);
+        Vector3f angularFactor = getAngularFactor(null);
+        if (angularFactor.x == angularFactor.y && angularFactor.y == angularFactor.z) {
+            capsule.write(getAngularFactor(), "angularFactor", 1);
+        } else {
+            capsule.write(getAngularFactor(null), "angularFactor", Vector3f.UNIT_XYZ);
+            capsule.write(getLinearFactor(), "linearFactor", Vector3f.UNIT_XYZ);
+        }
         capsule.write(kinematic, "kinematic", false);
 
         capsule.write(getLinearDamping(), "linearDamping", 0);
@@ -703,7 +737,13 @@ public class PhysicsRigidBody extends PhysicsCollisionObject {
         setKinematic(capsule.readBoolean("kinematic", false));
 
         setRestitution(capsule.readFloat("restitution", 0));
-        setAngularFactor(capsule.readFloat("angularFactor", 1));
+        Vector3f angularFactor = (Vector3f) capsule.readSavable("angularFactor", Vector3f.NAN.clone());
+        if(angularFactor == Vector3f.NAN) {
+            setAngularFactor(capsule.readFloat("angularFactor", 1));
+        } else {
+            setAngularFactor(angularFactor);
+            setLinearFactor((Vector3f) capsule.readSavable("linearFactor", Vector3f.UNIT_XYZ.clone()));
+        }
         setDamping(capsule.readFloat("linearDamping", 0), capsule.readFloat("angularDamping", 0));
         setSleepingThresholds(capsule.readFloat("linearSleepingThreshold", 0.8f), capsule.readFloat("angularSleepingThreshold", 1.0f));
         setCcdMotionThreshold(capsule.readFloat("ccdMotionThreshold", 0));

+ 3 - 1
jme3-core/src/main/java/com/jme3/cinematic/Cinematic.java

@@ -702,7 +702,9 @@ public class Cinematic extends AbstractCinematicEvent implements AppState {
         dispose();
         cinematicEvents.clear();
         timeLine.clear();
-        eventsData.clear();
+        if (eventsData != null) {
+            eventsData.clear();
+        }
     }
 
     /**

+ 11 - 9
jme3-core/src/main/java/com/jme3/cinematic/events/AnimationEvent.java

@@ -43,7 +43,7 @@ import com.jme3.export.JmeImporter;
 import com.jme3.export.OutputCapsule;
 import com.jme3.scene.Spatial;
 import java.io.IOException;
-import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.logging.Logger;
@@ -431,15 +431,17 @@ public class AnimationEvent extends AbstractCinematicEvent {
     @Override
     public void dispose() {
         super.dispose();
-        Object o = cinematic.getEventData(MODEL_CHANNELS, model);
-        if (o != null) {
-            ArrayList<AnimChannel> list = (ArrayList<AnimChannel>) o;
-            list.remove(channel);
-            if (list.isEmpty()) {
-                cinematic.removeEventData(MODEL_CHANNELS, model);
+        if (cinematic != null) {
+            Object o = cinematic.getEventData(MODEL_CHANNELS, model);
+            if (o != null) {
+                Collection<AnimChannel> values = ((HashMap<Integer, AnimChannel>) o).values();
+                while (values.remove(channel));
+                if (values.isEmpty()) {
+                    cinematic.removeEventData(MODEL_CHANNELS, model);
+                }
             }
+            cinematic = null;
+            channel = null;
         }
-        cinematic = null;
-        channel = null;
     }
 }

+ 3 - 1
jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java

@@ -376,7 +376,9 @@ public class GLRenderer implements Renderer {
             caps.add(Caps.TextureFilterAnisotropic);
         }
 
-        if (hasExtension("GL_EXT_framebuffer_object") || gl3 != null) {
+        if (hasExtension("GL_EXT_framebuffer_object") 
+                || gl3 != null
+                || caps.contains(Caps.OpenGLES20)) {
             caps.add(Caps.FrameBuffer);
 
             limits.put(Limits.RenderBufferSize, getInteger(GLFbo.GL_MAX_RENDERBUFFER_SIZE_EXT));

+ 12 - 1
jme3-core/src/main/java/com/jme3/scene/BatchNode.java

@@ -444,6 +444,7 @@ public class BatchNode extends GeometryGroupNode {
         int maxWeights = -1;
 
         Mesh.Mode mode = null;
+        float lineWidth = 1f;
         for (Geometry geom : geometries) {
             totalVerts += geom.getVertexCount();
             totalTris += geom.getTriangleCount();
@@ -452,6 +453,7 @@ public class BatchNode extends GeometryGroupNode {
                 maxVertCount = geom.getVertexCount();
             }
             Mesh.Mode listMode;
+            float listLineWidth = 1f;
             int components;
             switch (geom.getMesh().getMode()) {
                 case Points:
@@ -462,6 +464,7 @@ public class BatchNode extends GeometryGroupNode {
                 case LineStrip:
                 case Lines:
                     listMode = Mesh.Mode.Lines;
+                    listLineWidth = geom.getMesh().getLineWidth();
                     components = 2;
                     break;
                 case TriangleFan:
@@ -491,13 +494,21 @@ public class BatchNode extends GeometryGroupNode {
             if (mode != null && mode != listMode) {
                 throw new UnsupportedOperationException("Cannot combine different"
                         + " primitive types: " + mode + " != " + listMode);
-            }
+            }            
             mode = listMode;
+            if (mode == Mesh.Mode.Lines) {
+                if (lineWidth != 1f && listLineWidth != lineWidth) {
+                    throw new UnsupportedOperationException("When using Mesh Line mode, cannot combine meshes with different line width "
+                            + lineWidth + " != " + listLineWidth);
+                }
+                lineWidth = listLineWidth;
+            }
             compsForBuf[VertexBuffer.Type.Index.ordinal()] = components;
         }
 
         outMesh.setMaxNumWeights(maxWeights);
         outMesh.setMode(mode);
+        outMesh.setLineWidth(lineWidth);
         if (totalVerts >= 65536) {
             // make sure we create an UnsignedInt buffer so
             // we can fit all of the meshes

+ 69 - 0
jme3-core/src/test/java/com/jme3/cinematic/CinematicTest.java

@@ -0,0 +1,69 @@
+/*
+ * 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.cinematic;
+
+import com.jme3.animation.AnimControl;
+import com.jme3.animation.Animation;
+import com.jme3.cinematic.events.AnimationEvent;
+import com.jme3.scene.Node;
+import org.junit.Test;
+
+/**
+ *
+ * @author davidB
+ */
+public class CinematicTest {
+    
+    /**
+     * No NPE or any exception when clear() a new Cinematic
+     */
+    @Test
+    public void clearEmpty() {
+        Cinematic sut = new Cinematic();
+        sut.clear();
+    }
+    
+    /**
+     * No ClassCastException when clear() a Cinematic with AnimationEvent
+     */
+    @Test
+    public void clearAnimationEvent() {
+        Cinematic sut = new Cinematic();
+        Node model = new Node("model");
+        AnimControl ac = new AnimControl();
+        ac.addAnim(new Animation("animName", 1.0f));
+        model.addControl(ac);
+        sut.enqueueCinematicEvent(new AnimationEvent(model, "animName"));
+        sut.initialize(null, null);
+        sut.clear();
+    }
+}

+ 2 - 2
sdk/jme3-core-updatecenters/src/com/jme3/gde/core/updatecenters/Bundle.properties

@@ -1,6 +1,6 @@
 #jMP update centers
-com_jme3_gde_core_update_center_nightly=http://updates.jmonkeyengine.org/nightly/3.0/plugins/updates.xml
-com_jme3_gde_core_update_center_stable=http://updates.jmonkeyengine.org/stable/3.0/plugins/updates.xml
+com_jme3_gde_core_update_center_nightly=http://updates.jmonkeyengine.org/nightly/3.1/plugins/updates.xml
+com_jme3_gde_core_update_center_stable=http://updates.jmonkeyengine.org/stable/3.1/plugins/updates.xml
 com_jme3_jmp_contributions_update_center=http://updates.jmonkeyengine.org/contributions/updates.xml
 
 #jMP update centers

+ 4 - 6
sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionCurve.java

@@ -123,7 +123,7 @@ public class ConnectionCurve extends JPanel implements ComponentListener, MouseI
 
         g2.setStroke(new BasicStroke(4));
         Path2D.Double path1 = new Path2D.Double();
-         if (getDiagram().selectedItem == this) {
+        if (getDiagram().getSelectedItems().contains(this)) {
             g.setColor(SELECTED_COLOR);
         } else {
             g.setColor(VERY_DARK_GREY);
@@ -162,7 +162,7 @@ public class ConnectionCurve extends JPanel implements ComponentListener, MouseI
         ((Graphics2D) g).draw(path1);
         g2.setStroke(new BasicStroke(2));
        
-        if (getDiagram().selectedItem == this) {
+        if (getDiagram().getSelectedItems().contains(this)) {
             g.setColor(Color.WHITE);
         } else {
             g.setColor(LIGHT_GREY);
@@ -385,7 +385,7 @@ public class ConnectionCurve extends JPanel implements ComponentListener, MouseI
         }
 
         if (selected) {
-            getDiagram().select(this);
+            getDiagram().select(this, e.isShiftDown() || e.isControlDown());
             e.consume();
         }
     }
@@ -407,9 +407,7 @@ public class ConnectionCurve extends JPanel implements ComponentListener, MouseI
 
         if (e.getKeyCode() == KeyEvent.VK_DELETE) {
             Diagram diag = getDiagram();
-            if (diag.selectedItem == this) {
-                diag.removeSelectedConnection();
-            }
+            diag.removeSelected();
         }
     }
 

+ 3 - 5
sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionStraight.java

@@ -209,7 +209,7 @@ public class ConnectionStraight extends JPanel implements ComponentListener, Mou
             g.drawLine(p1.x, p1.y, p2.x, p2.y);
 
 
-            if (getDiagram().selectedItem == this) {
+            if (getDiagram().getSelectedItems().contains(this)) {
                 g.setColor(Color.CYAN);
             } else {
                 g.setColor(Color.GRAY);
@@ -489,7 +489,7 @@ public class ConnectionStraight extends JPanel implements ComponentListener, Mou
         }
 
         if (selected) {
-            getDiagram().select(this);
+            getDiagram().select(this, e.isShiftDown() || e.isControlDown());
             e.consume();
         }
     }
@@ -511,9 +511,7 @@ public class ConnectionStraight extends JPanel implements ComponentListener, Mou
 
         if (e.getKeyCode() == KeyEvent.VK_DELETE) {
             Diagram diag = getDiagram();
-            if (diag.selectedItem == this) {
-                diag.removeSelectedConnection();
-            }
+            diag.removeSelected();
         }
     }
 

+ 89 - 44
sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Diagram.java

@@ -55,7 +55,7 @@ public class Diagram extends JPanel implements MouseListener, MouseMotionListene
 
     protected Dot draggedFrom;
     protected Dot draggedTo;
-    protected Selectable selectedItem;
+    protected List<Selectable> selectedItems = new ArrayList<Selectable>();
     protected List<Connection> connections = new ArrayList<Connection>();
     protected List<NodePanel> nodes = new ArrayList<NodePanel>();
     protected List<OutBusPanel> outBuses = new ArrayList<OutBusPanel>();
@@ -63,6 +63,9 @@ public class Diagram extends JPanel implements MouseListener, MouseMotionListene
     private MatDefEditorlElement parent;
     private String currentTechniqueName;
     private final BackdropPanel backDrop = new BackdropPanel();
+    private final Cursor defCursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
+    private final Cursor hndCursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);
+    private final Point pp = new Point();
 
     @SuppressWarnings("LeakingThisInConstructor")
     public Diagram() {
@@ -99,7 +102,7 @@ public class Diagram extends JPanel implements MouseListener, MouseMotionListene
                 }
             }
 
-            selectedItem = null;
+            selectedItems.clear();
             repaint();
         } else if (e.getButton() == MouseEvent.BUTTON2) {
             setCursor(hndCursor);
@@ -204,13 +207,10 @@ public class Diagram extends JPanel implements MouseListener, MouseMotionListene
     public void mouseExited(MouseEvent e) {
     }
 
-    protected void removeSelectedConnection() {
-        if (selectedItem instanceof Connection) {
-            Connection selectedConnection = (Connection) selectedItem;
-            removeConnection(selectedConnection);
-            selectedItem = null;
-            parent.notifyRemoveConnection(selectedConnection);
-        }
+    protected void removeSelectedConnection(Selectable selectedItem) {        
+        Connection selectedConnection = (Connection) selectedItem;
+        removeConnection(selectedConnection);
+        parent.notifyRemoveConnection(selectedConnection);
     }
 
     private String fixNodeName(String name) {
@@ -276,44 +276,58 @@ public class Diagram extends JPanel implements MouseListener, MouseMotionListene
         np.revalidate();
         repaint();
     }
-
-    protected void removeSelectedNode() {
-        if (selectedItem instanceof NodePanel) {
-            int result = JOptionPane.showConfirmDialog(null, "Delete this node and all its mappings?", "Delete Shader Node", JOptionPane.OK_CANCEL_OPTION);
-            if (result == JOptionPane.OK_OPTION) {
-                NodePanel selectedNode = (NodePanel) selectedItem;
-                nodes.remove(selectedNode);
-                for (Iterator<Connection> it = connections.iterator(); it.hasNext();) {
-                    Connection conn = it.next();
-                    if (conn.start.getNode() == selectedNode || conn.end.getNode() == selectedNode) {
-                        it.remove();
-                        conn.end.disconnect();
-                        conn.start.disconnect();
-                        remove(conn);
-                    }
+    
+    protected void removeSelected(){
+        
+        int result = JOptionPane.showConfirmDialog(null, "Delete all selected items, nodes and mappings?", "Delete Selected", JOptionPane.OK_CANCEL_OPTION);
+        
+        if (result == JOptionPane.OK_OPTION) {
+            for (Selectable selectedItem : selectedItems) {
+                if (selectedItem instanceof NodePanel) {
+                    removeSelectedNode(selectedItem);
                 }
+                if (selectedItem instanceof Connection) {
+                    removeSelectedConnection(selectedItem);
+                }
+            }
+            selectedItems.clear();
+        }
+    }
 
-                selectedNode.cleanup();
-                remove(selectedNode);
-                selectedItem = null;
-                repaint();
-                parent.notifyRemoveNode(selectedNode);
+    private void removeSelectedNode(Selectable selectedItem) {
+
+        NodePanel selectedNode = (NodePanel) selectedItem;
+        nodes.remove(selectedNode);
+        for (Iterator<Connection> it = connections.iterator(); it.hasNext();) {
+            Connection conn = it.next();
+            if (conn.start.getNode() == selectedNode || conn.end.getNode() == selectedNode) {
+                it.remove();
+                conn.end.disconnect();
+                conn.start.disconnect();
+                remove(conn);
             }
         }
+
+        selectedNode.cleanup();
+        remove(selectedNode);
+        repaint();
+        parent.notifyRemoveNode(selectedNode);
     }
 
-    private final Cursor defCursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
-    private final Cursor hndCursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);
-    private final Point pp = new Point();
+    public List<Selectable> getSelectedItems() {
+        return selectedItems;
+    }
 
     @Override
     public void mouseDragged(MouseEvent e) {
         if (SwingUtilities.isLeftMouseButton(e)) {
             if (draggedFrom == null) {
-                if (selectedItem instanceof OutBusPanel) {
-                    OutBusPanel bus = (OutBusPanel) selectedItem;
-                    MouseEvent me = SwingUtilities.convertMouseEvent(this, e, bus);
-                    bus.dispatchEvent(me);
+                for (Selectable selectedItem : selectedItems) {
+                    if (selectedItem instanceof OutBusPanel) {
+                        OutBusPanel bus = (OutBusPanel) selectedItem;
+                        MouseEvent me = SwingUtilities.convertMouseEvent(this, e, bus);
+                        bus.dispatchEvent(me);
+                    }
                 }
             }
         } else if (SwingUtilities.isMiddleMouseButton(e)) {
@@ -373,22 +387,53 @@ public class Diagram extends JPanel implements MouseListener, MouseMotionListene
      *
      * @param selectable
      */
-    public void select(Selectable selectable) {
-        parent.selectionChanged(doSelect(selectable));
+    public void select(Selectable selectable, boolean multi) {
+        parent.selectionChanged(doSelect(selectable, multi));
+    }
+    
+    public void multiMove(DraggablePanel movedPanel ,int xOffset, int yOffset){
+        
+        for (Selectable selectedItem : selectedItems) {
+            if(selectedItem != movedPanel){
+                if(selectedItem instanceof DraggablePanel){
+                    ((DraggablePanel)selectedItem).movePanel(xOffset, yOffset);
+                }
+            }
+        }
     }
 
+    public void multiStartDrag(DraggablePanel movedPanel){
+        for (Selectable selectedItem : selectedItems) {
+            if(selectedItem != movedPanel){
+                if(selectedItem instanceof DraggablePanel){
+                    ((DraggablePanel)selectedItem).saveLocation();
+                }
+            }
+        }
+    }
+    
     /**
      * do select the item and repaint the diagram
      *
      * @param selectable
      * @return
      */
-    private Selectable doSelect(Selectable selectable) {
-        this.selectedItem = selectable;
+    private Selectable doSelect(Selectable selectable, boolean multi) {
+        
+
+        if (!multi && !selectedItems.contains(selectable)) {
+            selectedItems.clear();
+        }
+
+        if (selectable != null) {
+            selectedItems.add(selectable);
+        }
+
         if (selectable instanceof Component) {
             ((Component) selectable).requestFocusInWindow();
         }
         repaint();
+
         return selectable;
     }
 
@@ -403,23 +448,23 @@ public class Diagram extends JPanel implements MouseListener, MouseMotionListene
 
         for (NodePanel nodePanel : nodes) {
             if (nodePanel.getKey().equals(key)) {
-                return doSelect(nodePanel);
+                return doSelect(nodePanel, false);
             }
         }
 
         for (Connection connection : connections) {
             if (connection.getKey().equals(key)) {
-                return doSelect(connection);
+                return doSelect(connection, false);
             }
         }
 
         for (OutBusPanel outBusPanel : outBuses) {
             if (outBusPanel.getKey().equals(key)) {
-                return doSelect(outBusPanel);
+                return doSelect(outBusPanel, false);
             }
         }
 
-        return doSelect(null);
+        return null;
     }
 
     @Override

+ 17 - 3
sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/DraggablePanel.java

@@ -37,16 +37,22 @@ public class DraggablePanel extends JPanel implements MouseListener, MouseMotion
     @Override
     public void mousePressed(MouseEvent e) {
         if (e.getButton() != MouseEvent.BUTTON2) {
-            svdx = getLocation().x;
+            
             if (!vertical) {
                 svdex = e.getXOnScreen();
             }
-            svdy = getLocation().y;
             svdey = e.getYOnScreen();
+            saveLocation();
+            diagram.multiStartDrag(this);
             e.consume();
         }
     }
 
+    protected void saveLocation() {
+        svdy = getLocation().y;
+        svdx = getLocation().x;
+    }
+
     @Override
     public void mouseReleased(MouseEvent e) {
     }
@@ -71,11 +77,19 @@ public class DraggablePanel extends JPanel implements MouseListener, MouseMotion
                 xoffset = e.getLocationOnScreen().x - svdex;
             }
             int yoffset = e.getLocationOnScreen().y - svdey;
-            setLocation(Math.max(0, svdx + xoffset), Math.max(0, svdy + yoffset));
+            movePanel(xoffset, yoffset);
+            diagram.multiMove(this, xoffset, yoffset);
             e.consume();
         }
     }
 
+    protected void movePanel(int xoffset, int yoffset) {
+        if (vertical) {
+            xoffset = 0;
+        }
+        setLocation(Math.max(0, svdx + xoffset), Math.max(0, svdy + yoffset));
+    }
+
     public Diagram getDiagram() {
         return diagram;
     }

+ 5 - 24
sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/NodePanel.java

@@ -56,23 +56,6 @@ public class NodePanel extends DraggablePanel implements Selectable, PropertyCha
     protected List<String> filePaths = new ArrayList<String>();
     protected Shader.ShaderType shaderType;
 
-//    private List listeners = Collections.synchronizedList(new LinkedList());
-//
-//    public void addPropertyChangeListener(PropertyChangeListener pcl) {
-//        listeners.add(pcl);
-//    }
-//
-//    public void removePropertyChangeListener(PropertyChangeListener pcl) {
-//        listeners.remove(pcl);
-//    }
-//
-//    protected void fire(String propertyName, Object old, Object nue) {
-//        //Passing 0 below on purpose, so you only synchronize for one atomic call:
-//        PropertyChangeListener[] pcls = (PropertyChangeListener[]) listeners.toArray(new PropertyChangeListener[0]);
-//        for (int i = 0; i < pcls.length; i++) {
-//            pcls[i].propertyChange(new PropertyChangeEvent(this, propertyName, old, nue));
-//        }
-//    }
     public enum NodeType {
 
         Vertex(new Color(220, 220, 70)),//yellow
@@ -201,13 +184,13 @@ public class NodePanel extends DraggablePanel implements Selectable, PropertyCha
     protected void paintComponent(Graphics g1) {
         Graphics2D g = (Graphics2D) g1;
         Color boderColor = Color.BLACK;
-        if (diagram.selectedItem == this) {
+        if (getDiagram().getSelectedItems().contains(this)) {
             boderColor = Color.WHITE;
         }
         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, // Anti-alias!
                 RenderingHints.VALUE_ANTIALIAS_ON);
         // Color[] colors = {new Color(0, 0, 0, 0.7f), new Color(0, 0, 0, 0.15f)};
-        if (diagram.selectedItem == this) {
+        if (getDiagram().getSelectedItems().contains(this)) {
             Color[] colors = new Color[]{new Color(0.6f, 0.6f, 1.0f, 0.8f), new Color(0.6f, 0.6f, 1.0f, 0.5f)};
             float[] factors = {0f, 1f};
             g.setPaint(new RadialGradientPaint(getWidth() / 2, getHeight() / 2, getWidth() / 2, factors, colors));
@@ -260,8 +243,8 @@ public class NodePanel extends DraggablePanel implements Selectable, PropertyCha
 
     @Override
     public void mousePressed(MouseEvent e) {
-        super.mousePressed(e);
-        diagram.select(this);
+        super.mousePressed(e);        
+        diagram.select(this, e.isShiftDown() || e.isControlDown());
         showToolBar();
     }
     
@@ -442,9 +425,7 @@ public class NodePanel extends DraggablePanel implements Selectable, PropertyCha
 
     public void delete() {
         Diagram diag = getDiagram();
-        if (diag.selectedItem == this) {
-            diag.removeSelectedNode();
-        }
+        diag.removeSelected();
     }
 
     public void keyReleased(KeyEvent e) {

+ 2 - 2
sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/OutBusPanel.java

@@ -110,7 +110,7 @@ public class OutBusPanel extends DraggablePanel implements ComponentListener, Se
 
         Polygon p = new Polygon(xs, ys, 8);
 
-        if (diagram.selectedItem == this) {
+        if (getDiagram().getSelectedItems().contains(this)) {
             int[] xs2 = {0, width - 30, width - 30, width, width - 32, width - 32, 0, 0};
             int[] ys2 = {10, 10, 0, getHeight() / 2 + 2, getHeight(), getHeight() - 8, getHeight() - 8, 10};
 
@@ -154,7 +154,7 @@ public class OutBusPanel extends DraggablePanel implements ComponentListener, Se
             return;
         }
         super.mousePressed(e);
-        diagram.select(this);
+        diagram.select(this, e.isShiftDown() || e.isControlDown());
     }
 
     @Override

+ 4 - 2
sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DeleteShortcut.java

@@ -29,7 +29,9 @@ public class DeleteShortcut extends ShortcutTool {
     @Override
     public boolean isActivableBy(KeyInputEvent kie) {
         if (kie.getKeyCode() == KeyInput.KEY_X && kie.isPressed()) {
-            if (Lookup.getDefault().lookup(ShortcutManager.class).isShiftDown()) {
+            ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class);
+            if (!scm.isActive() && scm.isShiftDown()) {
+                // ^ can't be enable if an other shortcut is allready active
                 return true;
             }
         }
@@ -99,7 +101,7 @@ public class DeleteShortcut extends ShortcutTool {
     @Override
     public void draggedSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) {
     }
-    
+
     private class DeleteUndo extends AbstractUndoableSceneEdit {
 
         private Spatial spatial;

+ 8 - 6
sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java

@@ -78,14 +78,16 @@ public class MoveShortcut extends ShortcutTool {
         if (kie.isPressed()) {
             Lookup.getDefault().lookup(ShortcutManager.class).activateShortcut(kie);
 
-            Vector3f axis = new Vector3f();
-            boolean axisChanged = ShortcutManager.checkAxisKey(kie, axis);
+            boolean axisChanged = ShortcutManager.isAxisKey(kie);
             if (axisChanged) {
-                currentAxis = axis;
+                currentAxis = ShortcutManager.getAxisKey(kie);
             }
-            boolean numberChanged = ShortcutManager.checkNumberKey(kie, numberBuilder);
-            boolean enterHit = ShortcutManager.checkEnterHit(kie);
-            boolean escHit = ShortcutManager.checkEscHit(kie);
+            boolean numberChanged = ShortcutManager.isNumberKey(kie);
+            if(numberChanged){
+                ShortcutManager.setNumberKey(kie, numberBuilder);
+            }
+            boolean enterHit = ShortcutManager.isEnterKey(kie);
+            boolean escHit = ShortcutManager.isEscKey(kie);
 
             if (escHit) {
                 cancel();

+ 8 - 6
sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/RotateShortcut.java

@@ -77,14 +77,16 @@ public class RotateShortcut extends ShortcutTool {
         if (kie.isPressed()) {
             Lookup.getDefault().lookup(ShortcutManager.class).activateShortcut(kie);
 
-            Vector3f axis = new Vector3f();
-            boolean axisChanged = ShortcutManager.checkAxisKey(kie, axis);
+            boolean axisChanged = ShortcutManager.isAxisKey(kie);
             if (axisChanged) {
-                currentAxis = axis;
+                currentAxis = ShortcutManager.getAxisKey(kie);
             }
-            boolean numberChanged = ShortcutManager.checkNumberKey(kie, numberBuilder);
-            boolean enterHit = ShortcutManager.checkEnterHit(kie);
-            boolean escHit = ShortcutManager.checkEscHit(kie);
+            boolean numberChanged = ShortcutManager.isNumberKey(kie);
+            if(numberChanged){
+                ShortcutManager.setNumberKey(kie, numberBuilder);
+            }
+            boolean enterHit = ShortcutManager.isEnterKey(kie);
+            boolean escHit = ShortcutManager.isEscKey(kie);
 
             if (escHit) {
                 cancel();

+ 8 - 6
sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ScaleShortcut.java

@@ -77,14 +77,16 @@ public class ScaleShortcut extends ShortcutTool {
         if (kie.isPressed()) {
             Lookup.getDefault().lookup(ShortcutManager.class).activateShortcut(kie);
 
-            Vector3f axis = new Vector3f();
-            boolean axisChanged = ShortcutManager.checkAxisKey(kie, axis);
+            boolean axisChanged = ShortcutManager.isAxisKey(kie);
             if (axisChanged) {
-                currentAxis = axis;
+                currentAxis = ShortcutManager.getAxisKey(kie);
             }
-            boolean numberChanged = ShortcutManager.checkNumberKey(kie, numberBuilder);
-            boolean enterHit = ShortcutManager.checkEnterHit(kie);
-            boolean escHit = ShortcutManager.checkEscHit(kie);
+            boolean numberChanged = ShortcutManager.isNumberKey(kie);
+            if(numberChanged){
+                ShortcutManager.setNumberKey(kie, numberBuilder);
+            }
+            boolean enterHit = ShortcutManager.isEnterKey(kie);
+            boolean escHit = ShortcutManager.isEscKey(kie);
 
             if (escHit) {
                 cancel();

+ 121 - 95
sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java

@@ -157,13 +157,13 @@ public class ShortcutManager {
     }
 
     private boolean checkCommandeKey(KeyInputEvent kie) {
-        if (checkCtrlHit(kie)) {
+        if (isCtrlKey(kie)) {
             ctrlDown = kie.isPressed();
             return true;
-        } else if (checkAltHit(kie)) {
+        } else if (isAltKey(kie)) {
             altDown = kie.isPressed();
             return true;
-        } else if (checkShiftHit(kie)) {
+        } else if (isShiftKey(kie)) {
             shiftDown = kie.isPressed();
             return true;
         }
@@ -178,11 +178,8 @@ public class ShortcutManager {
      * @param kie
      * @return true if the given kie is KEY_RETURN
      */
-    public static boolean checkEnterHit(KeyInputEvent kie) {
-        if (kie.getKeyCode() == KeyInput.KEY_RETURN) {
-            return true;
-        }
-        return false;
+    public static boolean isEnterKey(KeyInputEvent kie) {
+        return (kie.getKeyCode() == KeyInput.KEY_RETURN);
     }
 
     /**
@@ -190,11 +187,8 @@ public class ShortcutManager {
      * @param kie
      * @return true if the given kie is KEY_ESCAPE
      */
-    public static boolean checkEscHit(KeyInputEvent kie) {
-        if (kie.getKeyCode() == KeyInput.KEY_ESCAPE) {
-            return true;
-        }
-        return false;
+    public static boolean isEscKey(KeyInputEvent kie) {
+        return (kie.getKeyCode() == KeyInput.KEY_ESCAPE);
     }
 
     /**
@@ -202,11 +196,8 @@ public class ShortcutManager {
      * @param kie
      * @return true if the given kie is KEY_LCONTROL || KEY_RCONTROL
      */
-    public static boolean checkCtrlHit(KeyInputEvent kie) {
-        if (kie.getKeyCode() == KeyInput.KEY_LCONTROL || kie.getKeyCode() == KeyInput.KEY_RCONTROL) {
-            return true;
-        }
-        return false;
+    public static boolean isCtrlKey(KeyInputEvent kie) {
+        return (kie.getKeyCode() == KeyInput.KEY_LCONTROL || kie.getKeyCode() == KeyInput.KEY_RCONTROL);
     }
 
     /**
@@ -214,11 +205,8 @@ public class ShortcutManager {
      * @param kie
      * @return true if the given kie is KEY_LSHIFT || KEY_RSHIFT
      */
-    public static boolean checkShiftHit(KeyInputEvent kie) {
-        if (kie.getKeyCode() == KeyInput.KEY_LSHIFT || kie.getKeyCode() == KeyInput.KEY_RSHIFT) {
-            return true;
-        }
-        return false;
+    public static boolean isShiftKey(KeyInputEvent kie) {
+        return (kie.getKeyCode() == KeyInput.KEY_LSHIFT || kie.getKeyCode() == KeyInput.KEY_RSHIFT);
     }
 
     /**
@@ -226,9 +214,40 @@ public class ShortcutManager {
      * @param kie
      * @return true if the given kie is KEY_LMENU || KEY_RMENU
      */
-    public static boolean checkAltHit(KeyInputEvent kie) {
-        if (kie.getKeyCode() == KeyInput.KEY_LMENU || kie.getKeyCode() == KeyInput.KEY_RMENU) {
-            return true;
+    public static boolean isAltKey(KeyInputEvent kie) {
+        return (kie.getKeyCode() == KeyInput.KEY_LMENU || kie.getKeyCode() == KeyInput.KEY_RMENU);
+    }
+
+    /**
+     *
+     * @param kie
+     * @return
+     */
+    public static boolean isNumberKey(KeyInputEvent kie) {
+        switch (kie.getKeyCode()) {
+            case KeyInput.KEY_MINUS:
+            case KeyInput.KEY_0:
+            case KeyInput.KEY_1:
+            case KeyInput.KEY_2:
+            case KeyInput.KEY_3:
+            case KeyInput.KEY_4:
+            case KeyInput.KEY_5:
+            case KeyInput.KEY_6:
+            case KeyInput.KEY_7:
+            case KeyInput.KEY_8:
+            case KeyInput.KEY_9:
+            case KeyInput.KEY_NUMPAD0:
+            case KeyInput.KEY_NUMPAD1:
+            case KeyInput.KEY_NUMPAD2:
+            case KeyInput.KEY_NUMPAD3:
+            case KeyInput.KEY_NUMPAD4:
+            case KeyInput.KEY_NUMPAD5:
+            case KeyInput.KEY_NUMPAD6:
+            case KeyInput.KEY_NUMPAD7:
+            case KeyInput.KEY_NUMPAD8:
+            case KeyInput.KEY_NUMPAD9:
+            case KeyInput.KEY_PERIOD:
+                return true;
         }
         return false;
     }
@@ -236,65 +255,55 @@ public class ShortcutManager {
     /**
      * store the number kie into the numberBuilder
      *
-     * @param kie
-     * @param numberBuilder
-     * @return true if the given kie is handled as a number key event
+     * @param kie the KeiInputEvent to be handled as a number.
+     * @param numberBuilder the number builder that will be modified !
      */
-    public static boolean checkNumberKey(KeyInputEvent kie, StringBuilder numberBuilder) {
-        if (kie.getKeyCode() == KeyInput.KEY_MINUS) {
-            if (numberBuilder.length() > 0) {
-                if (numberBuilder.charAt(0) == '-') {
-                    numberBuilder.replace(0, 1, "");
+    public static void setNumberKey(KeyInputEvent kie, StringBuilder numberBuilder) {
+        switch (kie.getKeyCode()) {
+            case KeyInput.KEY_MINUS:
+                if (numberBuilder.length() > 0) {
+                    if (numberBuilder.charAt(0) == '-') {
+                        numberBuilder.replace(0, 1, "");
+                    } else {
+                        numberBuilder.insert(0, '-');
+                    }
                 } else {
-                    numberBuilder.insert(0, '-');
+                    numberBuilder.append('-');
                 }
-            } else {
-                numberBuilder.append('-');
-            }
-            return true;
-        } else if (kie.getKeyCode() == KeyInput.KEY_0 || kie.getKeyCode() == KeyInput.KEY_NUMPAD0) {
-            numberBuilder.append('0');
-            return true;
-        } else if (kie.getKeyCode() == KeyInput.KEY_1 || kie.getKeyCode() == KeyInput.KEY_NUMPAD1) {
-            numberBuilder.append('1');
-            return true;
-        } else if (kie.getKeyCode() == KeyInput.KEY_2 || kie.getKeyCode() == KeyInput.KEY_NUMPAD2) {
-            numberBuilder.append('2');
-            return true;
-        } else if (kie.getKeyCode() == KeyInput.KEY_3 || kie.getKeyCode() == KeyInput.KEY_NUMPAD3) {
-            numberBuilder.append('3');
-            return true;
-        } else if (kie.getKeyCode() == KeyInput.KEY_4 || kie.getKeyCode() == KeyInput.KEY_NUMPAD4) {
-            numberBuilder.append('4');
-            return true;
-        } else if (kie.getKeyCode() == KeyInput.KEY_5 || kie.getKeyCode() == KeyInput.KEY_NUMPAD5) {
-            numberBuilder.append('5');
-            return true;
-        } else if (kie.getKeyCode() == KeyInput.KEY_6 || kie.getKeyCode() == KeyInput.KEY_NUMPAD6) {
-            numberBuilder.append('6');
-            return true;
-        } else if (kie.getKeyCode() == KeyInput.KEY_7 || kie.getKeyCode() == KeyInput.KEY_NUMPAD7) {
-            numberBuilder.append('7');
-            return true;
-        } else if (kie.getKeyCode() == KeyInput.KEY_8 || kie.getKeyCode() == KeyInput.KEY_NUMPAD8) {
-            numberBuilder.append('8');
-            return true;
-        } else if (kie.getKeyCode() == KeyInput.KEY_9 || kie.getKeyCode() == KeyInput.KEY_NUMPAD9) {
-            numberBuilder.append('9');
-            return true;
-        } else if (kie.getKeyCode() == KeyInput.KEY_PERIOD) {
-            if (numberBuilder.indexOf(".") == -1) { // if it doesn't exist yet
-                if (numberBuilder.length() == 0
-                        || (numberBuilder.length() == 1 && numberBuilder.charAt(0) == '-')) {
-                    numberBuilder.append("0.");
-                } else {
-                    numberBuilder.append(".");
+                break;
+            case KeyInput.KEY_0:
+            case KeyInput.KEY_1:
+            case KeyInput.KEY_2:
+            case KeyInput.KEY_3:
+            case KeyInput.KEY_4:
+            case KeyInput.KEY_5:
+            case KeyInput.KEY_6:
+            case KeyInput.KEY_7:
+            case KeyInput.KEY_8:
+            case KeyInput.KEY_9:
+            case KeyInput.KEY_NUMPAD0:
+            case KeyInput.KEY_NUMPAD1:
+            case KeyInput.KEY_NUMPAD2:
+            case KeyInput.KEY_NUMPAD3:
+            case KeyInput.KEY_NUMPAD4:
+            case KeyInput.KEY_NUMPAD5:
+            case KeyInput.KEY_NUMPAD6:
+            case KeyInput.KEY_NUMPAD7:
+            case KeyInput.KEY_NUMPAD8:
+            case KeyInput.KEY_NUMPAD9:
+                numberBuilder.append(kie.getKeyChar());
+                break;
+            case KeyInput.KEY_PERIOD:
+                if (numberBuilder.indexOf(".") == -1) { // if it doesn't exist yet
+                    if (numberBuilder.length() == 0
+                            || (numberBuilder.length() == 1 && numberBuilder.charAt(0) == '-')) {
+                        numberBuilder.append("0.");
+                    } else {
+                        numberBuilder.append(".");
+                    }
                 }
-            }
-            return true;
+                break;
         }
-
-        return false;
     }
 
     /**
@@ -311,25 +320,42 @@ public class ShortcutManager {
     }
 
     /**
-     * Check for axis input for key X,Y,Z and store the corresponding UNIT_ into
-     * the axisStore
+     * Test if the given kie can be handled as en axis input by the getAxisKey()
+     * method.
      *
-     * @param kie
-     * @param axisStore
-     * @return true if the given kie is handled as a Axis input
+     * @param kie the KeyInputEvent to test
+     * @return true is the kie can be handled as an axis input, else false
      */
-    public static boolean checkAxisKey(KeyInputEvent kie, Vector3f axisStore) {
-        if (kie.getKeyCode() == KeyInput.KEY_X) {
-            axisStore.set(Vector3f.UNIT_X);
-            return true;
-        } else if (kie.getKeyCode() == KeyInput.KEY_Y) {
-            axisStore.set(Vector3f.UNIT_Y);
-            return true;
-        } else if (kie.getKeyCode() == KeyInput.KEY_Z) {
-            axisStore.set(Vector3f.UNIT_Z);
-            return true;
+    public static boolean isAxisKey(KeyInputEvent kie) {
+        switch (kie.getKeyCode()) {
+            case KeyInput.KEY_X:
+            case KeyInput.KEY_Y:
+            case KeyInput.KEY_Z:
+                return true;
         }
         return false;
     }
 
+    /**
+     * Handle the Kie as an axis input : return a Vector3f from the kie keyCode.
+     *
+     * @param kie the KeyInputEvent to handle as an Axis
+     * @return UNIT_X for 'x', UNIT_Y for 'y' and UNIT_Z for 'z' kie.
+     */
+    public static Vector3f getAxisKey(KeyInputEvent kie) {
+        Vector3f result = Vector3f.ZERO;
+        switch (kie.getKeyCode()) {
+            case KeyInput.KEY_X:
+                result = Vector3f.UNIT_X;
+                break;
+            case KeyInput.KEY_Y:
+                result = Vector3f.UNIT_Y;
+                break;
+            case KeyInput.KEY_Z:
+                result = Vector3f.UNIT_Z;
+                break;
+        }
+        return result;
+    }
+
 }