From f6b7c3819a6bb0e062d7a81dac020eb04b64ee10 Mon Sep 17 00:00:00 2001 From: Maselbas Date: Sun, 10 May 2015 01:57:27 +0200 Subject: [PATCH 1/9] SDK SceneComposer : added abstract ShortcutTool class that extends SceneEditTool - added a shortcutManager that provide some usefull methodes for ShortcutTools. Also handle activation of shortcuts. - wip : implementation of the MoveShortcut (based on the same shortcut provided by the selectTool) using ShortcutTool and the ShortcutManager. - modified the SceneComposerToolController to work with the ShortcutManager & ShortcutTool --- .../SceneComposerToolController.java | 48 ++++- .../tools/shortcuts/MoveShortcut.java | 137 ++++++++++++ .../tools/shortcuts/ShortcutManager.java | 197 ++++++++++++++++++ .../tools/shortcuts/ShortcutTool.java | 29 +++ 4 files changed, 403 insertions(+), 8 deletions(-) create mode 100644 sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java create mode 100644 sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java create mode 100644 sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutTool.java diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerToolController.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerToolController.java index 50b6d5cfe..71fee925b 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerToolController.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerToolController.java @@ -11,6 +11,7 @@ import com.jme3.gde.core.scene.controller.SceneToolController; import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; import com.jme3.gde.scenecomposer.tools.PickManager; +import com.jme3.gde.scenecomposer.tools.shortcuts.ShortcutManager; import com.jme3.input.event.KeyInputEvent; import com.jme3.light.Light; import com.jme3.light.PointLight; @@ -31,6 +32,7 @@ import com.jme3.scene.control.Control; import com.jme3.scene.shape.Quad; import com.jme3.texture.Texture; import java.util.concurrent.Callable; +import org.openide.util.Lookup; /** * @@ -184,7 +186,11 @@ public class SceneComposerToolController extends SceneToolController { * @param camera */ public void doEditToolActivatedPrimary(Vector2f mouseLoc, boolean pressed, Camera camera) { - if (editTool != null) { + ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); + + if (scm.isActive()) { + scm.getActiveShortcut().actionPrimary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); + } else if (editTool != null) { editTool.setCamera(camera); editTool.actionPrimary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); } @@ -198,36 +204,62 @@ public class SceneComposerToolController extends SceneToolController { * @param camera */ public void doEditToolActivatedSecondary(Vector2f mouseLoc, boolean pressed, Camera camera) { - if (editTool != null) { + ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); + + if (scm.isActive()) { + scm.getActiveShortcut().actionSecondary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); + } else if (editTool != null) { editTool.setCamera(camera); editTool.actionSecondary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); } } public void doEditToolMoved(Vector2f mouseLoc, Camera camera) { - if (editTool != null) { + ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); + + if (scm.isActive()) { + scm.getActiveShortcut().mouseMoved(mouseLoc, rootNode, editorController.getCurrentDataObject(), selectedSpatial); + } else if (editTool != null) { editTool.setCamera(camera); editTool.mouseMoved(mouseLoc, rootNode, editorController.getCurrentDataObject(), selectedSpatial); } } public void doEditToolDraggedPrimary(Vector2f mouseLoc, boolean pressed, Camera camera) { - if (editTool != null) { + ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); + + if (scm.isActive()) { + scm.getActiveShortcut().draggedPrimary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); + } else if (editTool != null) { editTool.setCamera(camera); editTool.draggedPrimary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); } } public void doEditToolDraggedSecondary(Vector2f mouseLoc, boolean pressed, Camera camera) { - if (editTool != null) { + ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); + + if (scm.isActive()) { + scm.getActiveShortcut().draggedSecondary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); + } else if (editTool != null) { editTool.setCamera(camera); editTool.draggedSecondary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); } } - void doKeyPressed(KeyInputEvent kie) { - if (editTool != null) { - editTool.keyPressed(kie); + public void doKeyPressed(KeyInputEvent kie) { + ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); + + if (scm.isActive()) { + scm.doKeyPressed(kie); + } else { + if (scm.activateShortcut(kie)) { + scm.getActiveShortcut().activate(manager, toolsNode, onTopToolsNode, selected, this); + } else { + if (editTool != null) { + editTool.keyPressed(kie); + } + } } } diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java new file mode 100644 index 000000000..e59fec76e --- /dev/null +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java @@ -0,0 +1,137 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.scenecomposer.tools.shortcuts; + +import com.jme3.asset.AssetManager; +import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; +import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; +import com.jme3.gde.scenecomposer.SceneComposerToolController; +import com.jme3.gde.scenecomposer.tools.PickManager; +import com.jme3.input.KeyInput; +import com.jme3.input.event.KeyInputEvent; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import org.openide.loaders.DataObject; +import org.openide.util.Lookup; + +/** + * + * @author dokthar + */ +public class MoveShortcut extends ShortcutTool { + + private Vector3f currentAxis; + private StringBuilder numberBuilder; + private Spatial spatial; + private Vector3f initalLocation; + private Vector3f finalLocation; + private PickManager pickManager; + + @Override + public boolean isActivableBy(KeyInputEvent kie) { + return kie.getKeyCode() == KeyInput.KEY_G; + } + + @Override + public void cancel() { + spatial.setLocalTranslation(initalLocation); + terminate(); + } + + private void apply() { + // TODO creat UNDO/REDO + terminate(); + } + + @Override + public void activate(AssetManager manager, Node toolNode, Node onTopToolNode, Spatial selectedSpatial, SceneComposerToolController toolController) { + super.activate(manager, toolNode, onTopToolNode, selectedSpatial, toolController); //To change body of generated methods, choose Tools | Templates. + hideMarker(); + numberBuilder = new StringBuilder(); + if (selectedSpatial == null) { + terminate(); + } else { + spatial = selectedSpatial; + initalLocation = spatial.getLocalTranslation(); + currentAxis = new Vector3f().set(Vector3f.UNIT_XYZ); + + pickManager = Lookup.getDefault().lookup(PickManager.class); + ///pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_YZ, getTransformType(), camera, screenCoord); + } + } + + @Override + public void keyPressed(KeyInputEvent kie) { + if (kie.isPressed()) { + + /* + ShortcutTool otherShortcut = Lookup.getDefault().lookup(ShortcutManager.class).getActivableShortcut(kie); + if(otherShortcut != null){ + Lookup.getDefault().lookup(ShortcutManager.class).setShortCut(otherShortcut); + }*/ + Lookup.getDefault().lookup(ShortcutManager.class).activateShortcut(kie); + + boolean axisChanged = ShortcutManager.checkAxisKey(kie, currentAxis); + boolean numberChanged = ShortcutManager.checkNumberKey(kie, numberBuilder); + boolean enterHit = ShortcutManager.checkEnterHit(kie); + boolean escHit = ShortcutManager.checkEscHit(kie); + + if (escHit) { + cancel(); + } else if (enterHit) { + apply(); + } else if (axisChanged || numberChanged) { + //update transformation + float number = ShortcutManager.getNumberkey(numberBuilder); + Vector3f translation = currentAxis.mult(number); + finalLocation = initalLocation.add(translation); + spatial.setLocalTranslation(finalLocation); + + } + + } + } + + @Override + public void actionPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + if (!pressed) { + apply(); + } + } + + @Override + public void actionSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + if (pressed) { + cancel(); + } + } + + @Override + public void mouseMoved(Vector2f screenCoord, JmeNode rootNode, DataObject dataObject, JmeSpatial selectedSpatial) { + pickManager.updatePick(camera, screenCoord); + /* PickManager pickManager = Lookup.getDefault().lookup(PickManager.class); + if (toolController.isSnapToScene()) { + moveManager.setAlternativePickTarget(rootNode.getLookup().lookup(Node.class)); + } + // free form translation + moveManager.move(camera, screenCoord, axis, toolController.isSnapToGrid());*/ + } + + @Override + public void draggedPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void draggedSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + if (pressed) { + cancel(); + } + } + +} diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java new file mode 100644 index 000000000..38548087d --- /dev/null +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java @@ -0,0 +1,197 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.scenecomposer.tools.shortcuts; + +import com.jme3.gde.scenecomposer.SceneEditTool; +import com.jme3.input.KeyInput; +import com.jme3.input.event.KeyInputEvent; +import com.jme3.math.Vector3f; +import java.util.ArrayList; +import org.openide.util.Lookup; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author dokthar + */ +@ServiceProvider(service = ShortcutManager.class) +public class ShortcutManager { + + private ShortcutTool currentShortcut; + private ArrayList shortcutList; + + public ShortcutManager() { + shortcutList = new ArrayList(); + shortcutList.add(new MoveShortcut()); + } + + /* + Methodes + */ + public void terminate() { + currentShortcut = null; + } + + public boolean isActive() { + return currentShortcut != null; + } + + public void setShortCut(ShortcutTool shortcut) { + if (isActive()) { + currentShortcut.cancel(); + } + currentShortcut = shortcut; + } + + public ShortcutTool getActivableShortcut(KeyInputEvent kie) { + for (ShortcutTool s : shortcutList) { + if (s != currentShortcut) { + if (s.isActivableBy(kie)) { + return s; + } + } + } + return null; + } + + public ShortcutTool getActiveShortcut() { + return currentShortcut; + } + + public boolean canActivateShortcut(KeyInputEvent kie) { + return getActivableShortcut(kie) != null; + } + + public boolean activateShortcut(KeyInputEvent kie) { + currentShortcut = getActivableShortcut(kie); + return isActive(); + } + + public void doKeyPressed(KeyInputEvent kie) { + ///todo check commande key + if (isActive()) { + currentShortcut.keyPressed(kie); + } + } + + /* + STATIC + */ + public static boolean checkEnterHit(KeyInputEvent kie) { + if (kie.getKeyCode() == KeyInput.KEY_RETURN) { + return true; + } + return false; + } + + public static boolean checkEscHit(KeyInputEvent kie) { + if (kie.getKeyCode() == KeyInput.KEY_ESCAPE) { + return true; + } + return false; + } + + public static boolean checkCtrlHit(KeyInputEvent kie) { + if (kie.getKeyCode() == KeyInput.KEY_LCONTROL || kie.getKeyCode() == KeyInput.KEY_RCONTROL) { + return true; + } + return false; + } + + public static boolean checkShiftHit(KeyInputEvent kie) { + if (kie.getKeyCode() == KeyInput.KEY_LSHIFT || kie.getKeyCode() == KeyInput.KEY_RSHIFT) { + return true; + } + return false; + } + + public static boolean checkAltHit(KeyInputEvent kie) { + if (kie.getKeyCode() == KeyInput.KEY_LMENU || kie.getKeyCode() == KeyInput.KEY_RMENU) { + return true; + } + return false; + } + + 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, ""); + } else { + numberBuilder.insert(0, '-'); + } + } 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("."); + } + } + return true; + } + + return false; + } + + public static float getNumberkey(StringBuilder numberBuilder) { + if (numberBuilder.length() == 0) { + return 0; + } else { + return new Float(numberBuilder.toString()); + } + } + + public static boolean checkAxisKey(KeyInputEvent kie, Vector3f axisStore) { + if (kie.getKeyCode() == KeyInput.KEY_X) { + axisStore = Vector3f.UNIT_X; + return true; + } else if (kie.getKeyCode() == KeyInput.KEY_Y) { + axisStore = Vector3f.UNIT_Y; + return true; + } else if (kie.getKeyCode() == KeyInput.KEY_Z) { + axisStore = Vector3f.UNIT_Z; + return true; + } + return false; + } + +} diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutTool.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutTool.java new file mode 100644 index 000000000..9b094fc1d --- /dev/null +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutTool.java @@ -0,0 +1,29 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.scenecomposer.tools.shortcuts; + +import com.jme3.gde.scenecomposer.SceneEditTool; +import com.jme3.input.event.KeyInputEvent; +import org.openide.util.Lookup; + +/** + * + * @author dokthar + */ +public abstract class ShortcutTool extends SceneEditTool { + + public abstract boolean isActivableBy(KeyInputEvent kie); + + public abstract void cancel(); + + protected final void terminate() { + Lookup.getDefault().lookup(ShortcutManager.class).terminate(); + } + + @Override + public abstract void keyPressed(KeyInputEvent kie); + +} From 92ab8b806035d89329e0b8ff64e16d5a0615fbef Mon Sep 17 00:00:00 2001 From: Maselbas Date: Thu, 14 May 2015 18:55:07 +0200 Subject: [PATCH 2/9] SDK SceneComposer : small modifications on the PickManager, now the camera rotation isn't cloned so it's no more necessary to update the rotation before the updataPick() --- .../jme3/gde/scenecomposer/tools/PickManager.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/PickManager.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/PickManager.java index 22fa8478a..af4f11fe5 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/PickManager.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/PickManager.java @@ -33,9 +33,9 @@ public class PickManager { private Spatial spatial; private SceneComposerToolController.TransformationType transformationType; - protected static final Quaternion PLANE_XY = new Quaternion().fromAngleAxis(0, new Vector3f(1, 0, 0)); - protected static final Quaternion PLANE_YZ = new Quaternion().fromAngleAxis(-FastMath.PI / 2, new Vector3f(0, 1, 0));//YAW090 - protected static final Quaternion PLANE_XZ = new Quaternion().fromAngleAxis(FastMath.PI / 2, new Vector3f(1, 0, 0)); //PITCH090 + public static final Quaternion PLANE_XY = new Quaternion().fromAngleAxis(0, new Vector3f(1, 0, 0)); + public static final Quaternion PLANE_YZ = new Quaternion().fromAngleAxis(-FastMath.PI / 2, new Vector3f(0, 1, 0));//YAW090 + public static final Quaternion PLANE_XZ = new Quaternion().fromAngleAxis(FastMath.PI / 2, new Vector3f(1, 0, 0)); //PITCH090 public PickManager() { @@ -75,7 +75,7 @@ public class PickManager { origineRotation = new Quaternion(Quaternion.IDENTITY); } else if (transformationType == SceneComposerToolController.TransformationType.camera) { rot.set(camera.getRotation()); - origineRotation = camera.getRotation().clone(); + origineRotation = camera.getRotation(); } plane.setLocalRotation(rot); } @@ -87,10 +87,6 @@ public class PickManager { * @return true if the the new picked location is set, else return false. */ public boolean updatePick(Camera camera, Vector2f screenCoord) { - if(transformationType == SceneComposerToolController.TransformationType.camera){ - origineRotation = camera.getRotation(); - plane.setLocalRotation(camera.getRotation()); - } finalPickLoc = SceneEditTool.pickWorldLocation(camera, screenCoord, plane, null); return finalPickLoc != null; } From e27b8a5739cc5e6fe7e77875f705be60ca828d8f Mon Sep 17 00:00:00 2001 From: Maselbas Date: Thu, 14 May 2015 19:02:35 +0200 Subject: [PATCH 3/9] SDK SceneComposer : bugfix in the ShortcutManager, prevent from setting the currentShorcut to NULL when there are no new activable shortcuts --- .../tools/shortcuts/ShortcutManager.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java index 38548087d..5dad38d7c 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java @@ -66,8 +66,11 @@ public class ShortcutManager { } public boolean activateShortcut(KeyInputEvent kie) { - currentShortcut = getActivableShortcut(kie); - return isActive(); + ShortcutTool newShortcut = getActivableShortcut(kie); + if(newShortcut != null){ + currentShortcut = newShortcut; + } + return newShortcut != null; } public void doKeyPressed(KeyInputEvent kie) { @@ -182,13 +185,13 @@ public class ShortcutManager { public static boolean checkAxisKey(KeyInputEvent kie, Vector3f axisStore) { if (kie.getKeyCode() == KeyInput.KEY_X) { - axisStore = Vector3f.UNIT_X; + axisStore.set(Vector3f.UNIT_X); return true; } else if (kie.getKeyCode() == KeyInput.KEY_Y) { - axisStore = Vector3f.UNIT_Y; + axisStore.set(Vector3f.UNIT_Y); return true; } else if (kie.getKeyCode() == KeyInput.KEY_Z) { - axisStore = Vector3f.UNIT_Z; + axisStore.set(Vector3f.UNIT_Z); return true; } return false; From fb44f5fb7bfd58a971cec4838f314d18204559cd Mon Sep 17 00:00:00 2001 From: Maselbas Date: Thu, 14 May 2015 19:09:07 +0200 Subject: [PATCH 4/9] SDK SceneComposer : Added the new Move Shortcut, you can use this shortcut with all others tools --- .../SceneComposerToolController.java | 7 +- .../tools/shortcuts/MoveShortcut.java | 95 ++++++++++++++----- 2 files changed, 77 insertions(+), 25 deletions(-) diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerToolController.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerToolController.java index 71fee925b..00d15bb2f 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerToolController.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerToolController.java @@ -189,6 +189,7 @@ public class SceneComposerToolController extends SceneToolController { ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); if (scm.isActive()) { + scm.getActiveShortcut().setCamera(camera); scm.getActiveShortcut().actionPrimary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); } else if (editTool != null) { editTool.setCamera(camera); @@ -207,6 +208,7 @@ public class SceneComposerToolController extends SceneToolController { ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); if (scm.isActive()) { + scm.getActiveShortcut().setCamera(camera); scm.getActiveShortcut().actionSecondary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); } else if (editTool != null) { editTool.setCamera(camera); @@ -218,6 +220,7 @@ public class SceneComposerToolController extends SceneToolController { ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); if (scm.isActive()) { + scm.getActiveShortcut().setCamera(camera); scm.getActiveShortcut().mouseMoved(mouseLoc, rootNode, editorController.getCurrentDataObject(), selectedSpatial); } else if (editTool != null) { editTool.setCamera(camera); @@ -229,6 +232,7 @@ public class SceneComposerToolController extends SceneToolController { ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); if (scm.isActive()) { + scm.getActiveShortcut().setCamera(camera); scm.getActiveShortcut().draggedPrimary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); } else if (editTool != null) { editTool.setCamera(camera); @@ -240,6 +244,7 @@ public class SceneComposerToolController extends SceneToolController { ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); if (scm.isActive()) { + scm.getActiveShortcut().setCamera(null); scm.getActiveShortcut().draggedSecondary(mouseLoc, pressed, rootNode, editorController.getCurrentDataObject()); } else if (editTool != null) { editTool.setCamera(camera); @@ -249,7 +254,7 @@ public class SceneComposerToolController extends SceneToolController { public void doKeyPressed(KeyInputEvent kie) { ShortcutManager scm = Lookup.getDefault().lookup(ShortcutManager.class); - + if (scm.isActive()) { scm.doKeyPressed(kie); } else { diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java index e59fec76e..3b0f22562 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java @@ -12,6 +12,7 @@ import com.jme3.gde.scenecomposer.SceneComposerToolController; import com.jme3.gde.scenecomposer.tools.PickManager; import com.jme3.input.KeyInput; import com.jme3.input.event.KeyInputEvent; +import com.jme3.math.Quaternion; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import com.jme3.scene.Node; @@ -28,18 +29,21 @@ public class MoveShortcut extends ShortcutTool { private Vector3f currentAxis; private StringBuilder numberBuilder; private Spatial spatial; - private Vector3f initalLocation; private Vector3f finalLocation; private PickManager pickManager; + private boolean pickEnabled; + private Vector3f startPosition; + private Vector3f finalPosition; @Override + public boolean isActivableBy(KeyInputEvent kie) { return kie.getKeyCode() == KeyInput.KEY_G; } @Override public void cancel() { - spatial.setLocalTranslation(initalLocation); + spatial.setLocalTranslation(startPosition); terminate(); } @@ -48,6 +52,14 @@ public class MoveShortcut extends ShortcutTool { terminate(); } + private void init(Spatial selectedSpatial) { + spatial = selectedSpatial; + startPosition = spatial.getLocalTranslation().clone(); + currentAxis = Vector3f.UNIT_XYZ; + pickManager = Lookup.getDefault().lookup(PickManager.class); + pickEnabled = false; + } + @Override public void activate(AssetManager manager, Node toolNode, Node onTopToolNode, Spatial selectedSpatial, SceneComposerToolController toolController) { super.activate(manager, toolNode, onTopToolNode, selectedSpatial, toolController); //To change body of generated methods, choose Tools | Templates. @@ -56,27 +68,23 @@ public class MoveShortcut extends ShortcutTool { if (selectedSpatial == null) { terminate(); } else { - spatial = selectedSpatial; - initalLocation = spatial.getLocalTranslation(); - currentAxis = new Vector3f().set(Vector3f.UNIT_XYZ); - - pickManager = Lookup.getDefault().lookup(PickManager.class); - ///pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_YZ, getTransformType(), camera, screenCoord); + init(selectedSpatial); } } @Override public void keyPressed(KeyInputEvent kie) { if (kie.isPressed()) { - - /* - ShortcutTool otherShortcut = Lookup.getDefault().lookup(ShortcutManager.class).getActivableShortcut(kie); - if(otherShortcut != null){ - Lookup.getDefault().lookup(ShortcutManager.class).setShortCut(otherShortcut); - }*/ + System.out.println(kie); Lookup.getDefault().lookup(ShortcutManager.class).activateShortcut(kie); - boolean axisChanged = ShortcutManager.checkAxisKey(kie, currentAxis); + Vector3f axis = new Vector3f(); + boolean axisChanged = ShortcutManager.checkAxisKey(kie, axis); + if (axisChanged) { + currentAxis = axis; + System.out.println("AXIS : " + currentAxis); + + } boolean numberChanged = ShortcutManager.checkNumberKey(kie, numberBuilder); boolean enterHit = ShortcutManager.checkEnterHit(kie); boolean escHit = ShortcutManager.checkEscHit(kie); @@ -85,11 +93,24 @@ public class MoveShortcut extends ShortcutTool { cancel(); } else if (enterHit) { apply(); + } else if (axisChanged && pickEnabled) { + //update pick manager + + if (currentAxis.equals(Vector3f.UNIT_X)) { + System.out.println("setTransformation X"); + pickManager.setTransformation(PickManager.PLANE_XY, getTransformType(), camera); + } else if (currentAxis.equals(Vector3f.UNIT_Y)) { + System.out.println("setTransformation Y"); + pickManager.setTransformation(PickManager.PLANE_YZ, getTransformType(), camera); + } else if (currentAxis.equals(Vector3f.UNIT_Z)) { + System.out.println("setTransformation Z"); + pickManager.setTransformation(PickManager.PLANE_XZ, getTransformType(), camera); + } } else if (axisChanged || numberChanged) { //update transformation float number = ShortcutManager.getNumberkey(numberBuilder); Vector3f translation = currentAxis.mult(number); - finalLocation = initalLocation.add(translation); + finalLocation = startPosition.add(translation); spatial.setLocalTranslation(finalLocation); } @@ -99,7 +120,7 @@ public class MoveShortcut extends ShortcutTool { @Override public void actionPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { - if (!pressed) { + if (pressed) { apply(); } } @@ -113,13 +134,39 @@ public class MoveShortcut extends ShortcutTool { @Override public void mouseMoved(Vector2f screenCoord, JmeNode rootNode, DataObject dataObject, JmeSpatial selectedSpatial) { - pickManager.updatePick(camera, screenCoord); - /* PickManager pickManager = Lookup.getDefault().lookup(PickManager.class); - if (toolController.isSnapToScene()) { - moveManager.setAlternativePickTarget(rootNode.getLookup().lookup(Node.class)); - } - // free form translation - moveManager.move(camera, screenCoord, axis, toolController.isSnapToGrid());*/ + + if (!pickEnabled) { + if (currentAxis.equals(Vector3f.UNIT_XYZ)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), camera.getRotation(), SceneComposerToolController.TransformationType.camera, camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_X)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_XY, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_Y)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_YZ, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_Z)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_XZ, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else { + return; + } + } + + if (pickManager.updatePick(camera, screenCoord)) { + //pick update success + Vector3f diff; + + if (currentAxis.equals(Vector3f.UNIT_XYZ)) { + diff = pickManager.getTranslation(); + } else { + diff = pickManager.getTranslation(currentAxis); + } + Vector3f position = startPosition.add(diff); + finalPosition = position; + toolController.getSelectedSpatial().setLocalTranslation(position); + updateToolsTransformation(); + } } @Override From 6ef33e4c10750705d7c407e6c92fda9d62dc7b45 Mon Sep 17 00:00:00 2001 From: Maselbas Date: Fri, 15 May 2015 17:57:47 +0200 Subject: [PATCH 5/9] SDK SceneComposer : added UndoRedo for the MoveShortcut --- .../tools/shortcuts/MoveShortcut.java | 60 +++++++++++++++++-- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java index 3b0f22562..a4dabb66b 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java @@ -6,8 +6,11 @@ package com.jme3.gde.scenecomposer.tools.shortcuts; import com.jme3.asset.AssetManager; +import com.jme3.bullet.control.CharacterControl; +import com.jme3.bullet.control.RigidBodyControl; import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; +import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit; import com.jme3.gde.scenecomposer.SceneComposerToolController; import com.jme3.gde.scenecomposer.tools.PickManager; import com.jme3.input.KeyInput; @@ -29,7 +32,6 @@ public class MoveShortcut extends ShortcutTool { private Vector3f currentAxis; private StringBuilder numberBuilder; private Spatial spatial; - private Vector3f finalLocation; private PickManager pickManager; private boolean pickEnabled; private Vector3f startPosition; @@ -48,7 +50,7 @@ public class MoveShortcut extends ShortcutTool { } private void apply() { - // TODO creat UNDO/REDO + actionPerformed(new MoveUndo(toolController.getSelectedSpatial(), startPosition, finalPosition)); terminate(); } @@ -110,8 +112,8 @@ public class MoveShortcut extends ShortcutTool { //update transformation float number = ShortcutManager.getNumberkey(numberBuilder); Vector3f translation = currentAxis.mult(number); - finalLocation = startPosition.add(translation); - spatial.setLocalTranslation(finalLocation); + finalPosition = startPosition.add(translation); + spatial.setLocalTranslation(finalPosition); } @@ -171,7 +173,9 @@ public class MoveShortcut extends ShortcutTool { @Override public void draggedPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + if (pressed) { + apply(); + } } @Override @@ -180,5 +184,51 @@ public class MoveShortcut extends ShortcutTool { cancel(); } } + + private class MoveUndo extends AbstractUndoableSceneEdit { + + private Spatial spatial; + private Vector3f before = new Vector3f(), after = new Vector3f(); + + MoveUndo(Spatial spatial, Vector3f before, Vector3f after) { + this.spatial = spatial; + this.before.set(before); + if (after != null) { + this.after.set(after); + } + } + + @Override + public void sceneUndo() { + spatial.setLocalTranslation(before); + RigidBodyControl control = spatial.getControl(RigidBodyControl.class); + if (control != null) { + control.setPhysicsLocation(spatial.getWorldTranslation()); + } + CharacterControl character = spatial.getControl(CharacterControl.class); + if (character != null) { + character.setPhysicsLocation(spatial.getWorldTranslation()); + } + // toolController.selectedSpatialTransformed(); + } + + @Override + public void sceneRedo() { + spatial.setLocalTranslation(after); + RigidBodyControl control = spatial.getControl(RigidBodyControl.class); + if (control != null) { + control.setPhysicsLocation(spatial.getWorldTranslation()); + } + CharacterControl character = spatial.getControl(CharacterControl.class); + if (character != null) { + character.setPhysicsLocation(spatial.getWorldTranslation()); + } + //toolController.selectedSpatialTransformed(); + } + + public void setAfter(Vector3f after) { + this.after.set(after); + } + } } From 1f4ee34de8c4110da418d09ae1e7983ab499e82c Mon Sep 17 00:00:00 2001 From: Maselbas Date: Fri, 15 May 2015 18:43:45 +0200 Subject: [PATCH 6/9] SDK SceneComposer : add Rotate and Scale Shortcut, plus done some clean up into the MoveShorcut --- .../tools/shortcuts/MoveShortcut.java | 7 - .../tools/shortcuts/RotateShortcut.java | 189 +++++++++++++++++ .../tools/shortcuts/ScaleShortcut.java | 199 ++++++++++++++++++ .../tools/shortcuts/ShortcutManager.java | 11 +- 4 files changed, 398 insertions(+), 8 deletions(-) create mode 100644 sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/RotateShortcut.java create mode 100644 sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ScaleShortcut.java diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java index a4dabb66b..62cc70612 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java @@ -15,7 +15,6 @@ import com.jme3.gde.scenecomposer.SceneComposerToolController; import com.jme3.gde.scenecomposer.tools.PickManager; import com.jme3.input.KeyInput; import com.jme3.input.event.KeyInputEvent; -import com.jme3.math.Quaternion; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import com.jme3.scene.Node; @@ -77,15 +76,12 @@ public class MoveShortcut extends ShortcutTool { @Override public void keyPressed(KeyInputEvent kie) { if (kie.isPressed()) { - System.out.println(kie); Lookup.getDefault().lookup(ShortcutManager.class).activateShortcut(kie); Vector3f axis = new Vector3f(); boolean axisChanged = ShortcutManager.checkAxisKey(kie, axis); if (axisChanged) { currentAxis = axis; - System.out.println("AXIS : " + currentAxis); - } boolean numberChanged = ShortcutManager.checkNumberKey(kie, numberBuilder); boolean enterHit = ShortcutManager.checkEnterHit(kie); @@ -99,13 +95,10 @@ public class MoveShortcut extends ShortcutTool { //update pick manager if (currentAxis.equals(Vector3f.UNIT_X)) { - System.out.println("setTransformation X"); pickManager.setTransformation(PickManager.PLANE_XY, getTransformType(), camera); } else if (currentAxis.equals(Vector3f.UNIT_Y)) { - System.out.println("setTransformation Y"); pickManager.setTransformation(PickManager.PLANE_YZ, getTransformType(), camera); } else if (currentAxis.equals(Vector3f.UNIT_Z)) { - System.out.println("setTransformation Z"); pickManager.setTransformation(PickManager.PLANE_XZ, getTransformType(), camera); } } else if (axisChanged || numberChanged) { diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/RotateShortcut.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/RotateShortcut.java new file mode 100644 index 000000000..1fb445b59 --- /dev/null +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/RotateShortcut.java @@ -0,0 +1,189 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.scenecomposer.tools.shortcuts; + +import com.jme3.asset.AssetManager; +import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; +import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; +import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit; +import com.jme3.gde.scenecomposer.SceneComposerToolController; +import com.jme3.gde.scenecomposer.tools.PickManager; +import com.jme3.input.KeyInput; +import com.jme3.input.event.KeyInputEvent; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import org.openide.loaders.DataObject; +import org.openide.util.Lookup; + +/** + * + * @author dokthar + */ +public class RotateShortcut extends ShortcutTool { + + private Vector3f currentAxis; + private StringBuilder numberBuilder; + private Spatial spatial; + private PickManager pickManager; + private boolean pickEnabled; + private Quaternion startRotation; + private Quaternion finalRotation; + + @Override + + public boolean isActivableBy(KeyInputEvent kie) { + return kie.getKeyCode() == KeyInput.KEY_R; + } + + @Override + public void cancel() { + spatial.setLocalRotation(startRotation); + terminate(); + } + + private void apply() { + actionPerformed(new RotateUndo(toolController.getSelectedSpatial(), startRotation, finalRotation)); + terminate(); + } + + private void init(Spatial selectedSpatial) { + spatial = selectedSpatial; + startRotation = spatial.getLocalRotation().clone(); + currentAxis = Vector3f.UNIT_XYZ; + pickManager = Lookup.getDefault().lookup(PickManager.class); + pickEnabled = false; + } + + @Override + public void activate(AssetManager manager, Node toolNode, Node onTopToolNode, Spatial selectedSpatial, SceneComposerToolController toolController) { + super.activate(manager, toolNode, onTopToolNode, selectedSpatial, toolController); //To change body of generated methods, choose Tools | Templates. + hideMarker(); + numberBuilder = new StringBuilder(); + if (selectedSpatial == null) { + terminate(); + } else { + init(selectedSpatial); + } + } + + @Override + public void keyPressed(KeyInputEvent kie) { + if (kie.isPressed()) { + Lookup.getDefault().lookup(ShortcutManager.class).activateShortcut(kie); + + Vector3f axis = new Vector3f(); + boolean axisChanged = ShortcutManager.checkAxisKey(kie, axis); + if (axisChanged) { + currentAxis = axis; + } + boolean numberChanged = ShortcutManager.checkNumberKey(kie, numberBuilder); + boolean enterHit = ShortcutManager.checkEnterHit(kie); + boolean escHit = ShortcutManager.checkEscHit(kie); + + if (escHit) { + cancel(); + } else if (enterHit) { + apply(); + } else if (axisChanged && pickEnabled) { + pickEnabled = false; + spatial.setLocalRotation(startRotation.clone()); + } else if (axisChanged || numberChanged) { + //update transformation + /* float number = ShortcutManager.getNumberkey(numberBuilder); + Vector3f translation = currentAxis.mult(number); + finalPosition = startPosition.add(translation); + spatial.setLocalTranslation(finalPosition); + */ + } + + } + } + + @Override + public void actionPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + if (pressed) { + apply(); + } + } + + @Override + public void actionSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + if (pressed) { + cancel(); + } + } + + @Override + public void mouseMoved(Vector2f screenCoord, JmeNode rootNode, DataObject dataObject, JmeSpatial selectedSpatial) { + + if (!pickEnabled) { + if (currentAxis.equals(Vector3f.UNIT_XYZ)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), camera.getRotation(), SceneComposerToolController.TransformationType.camera, camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_X)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_YZ, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_Y)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_XZ, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_Z)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_XY, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else { + return; + } + } + + if (pickManager.updatePick(camera, screenCoord)) { + + Quaternion rotation = startRotation.mult(pickManager.getRotation(startRotation.inverse())); + toolController.getSelectedSpatial().setLocalRotation(rotation); + finalRotation = rotation; + updateToolsTransformation(); + } + } + + @Override + public void draggedPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + if (pressed) { + apply(); + } + } + + @Override + public void draggedSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + if (pressed) { + cancel(); + } + } + + private class RotateUndo extends AbstractUndoableSceneEdit { + + private Spatial spatial; + private Quaternion before, after; + + RotateUndo(Spatial spatial, Quaternion before, Quaternion after) { + this.spatial = spatial; + this.before = before; + this.after = after; + } + + @Override + public void sceneUndo() { + spatial.setLocalRotation(before); + toolController.selectedSpatialTransformed(); + } + + @Override + public void sceneRedo() { + spatial.setLocalRotation(after); + toolController.selectedSpatialTransformed(); + } + } +} diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ScaleShortcut.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ScaleShortcut.java new file mode 100644 index 000000000..21966e385 --- /dev/null +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ScaleShortcut.java @@ -0,0 +1,199 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.scenecomposer.tools.shortcuts; + +import com.jme3.asset.AssetManager; +import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; +import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; +import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit; +import com.jme3.gde.scenecomposer.SceneComposerToolController; +import com.jme3.gde.scenecomposer.tools.PickManager; +import com.jme3.input.KeyInput; +import com.jme3.input.event.KeyInputEvent; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import org.openide.loaders.DataObject; +import org.openide.util.Lookup; + +/** + * + * @author dokthar + */ +public class ScaleShortcut extends ShortcutTool { + + private Vector3f currentAxis; + private StringBuilder numberBuilder; + private Spatial spatial; + private PickManager pickManager; + private boolean pickEnabled; + private Vector3f startScale; + private Vector3f finalScale; + + @Override + + public boolean isActivableBy(KeyInputEvent kie) { + return kie.getKeyCode() == KeyInput.KEY_S; + } + + @Override + public void cancel() { + spatial.setLocalScale(startScale); + terminate(); + } + + private void apply() { + actionPerformed(new ScaleUndo(toolController.getSelectedSpatial(), startScale, finalScale)); + terminate(); + } + + private void init(Spatial selectedSpatial) { + spatial = selectedSpatial; + startScale = spatial.getLocalScale().clone(); + currentAxis = Vector3f.UNIT_XYZ; + pickManager = Lookup.getDefault().lookup(PickManager.class); + pickEnabled = false; + } + + @Override + public void activate(AssetManager manager, Node toolNode, Node onTopToolNode, Spatial selectedSpatial, SceneComposerToolController toolController) { + super.activate(manager, toolNode, onTopToolNode, selectedSpatial, toolController); //To change body of generated methods, choose Tools | Templates. + hideMarker(); + numberBuilder = new StringBuilder(); + if (selectedSpatial == null) { + terminate(); + } else { + init(selectedSpatial); + } + } + + @Override + public void keyPressed(KeyInputEvent kie) { + if (kie.isPressed()) { + Lookup.getDefault().lookup(ShortcutManager.class).activateShortcut(kie); + + Vector3f axis = new Vector3f(); + boolean axisChanged = ShortcutManager.checkAxisKey(kie, axis); + if (axisChanged) { + currentAxis = axis; + } + boolean numberChanged = ShortcutManager.checkNumberKey(kie, numberBuilder); + boolean enterHit = ShortcutManager.checkEnterHit(kie); + boolean escHit = ShortcutManager.checkEscHit(kie); + + if (escHit) { + cancel(); + } else if (enterHit) { + apply(); + } else if (axisChanged && pickEnabled) { + pickEnabled = false; + } else if (axisChanged || numberChanged) { + //update transformation + /* float number = ShortcutManager.getNumberkey(numberBuilder); + Vector3f translation = currentAxis.mult(number); + finalPosition = startPosition.add(translation); + spatial.setLocalTranslation(finalPosition); + */ + } + + } + } + + @Override + public void actionPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + if (pressed) { + apply(); + } + } + + @Override + public void actionSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + if (pressed) { + cancel(); + } + } + + @Override + public void mouseMoved(Vector2f screenCoord, JmeNode rootNode, DataObject dataObject, JmeSpatial selectedSpatial) { + + if (!pickEnabled) { + if (currentAxis.equals(Vector3f.UNIT_XYZ)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), camera.getRotation(), SceneComposerToolController.TransformationType.camera, camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_X)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_XY, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_Y)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_YZ, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else if (currentAxis.equals(Vector3f.UNIT_Z)) { + pickManager.initiatePick(toolController.getSelectedSpatial(), PickManager.PLANE_XZ, getTransformType(), camera, screenCoord); + pickEnabled = true; + } else { + return; + } + } + + if (pickManager.updatePick(camera, screenCoord)) { + Vector3f scale = startScale; + if (currentAxis.equals(Vector3f.UNIT_XYZ)) { + Vector3f constraintAxis = pickManager.getStartOffset().normalize(); + float diff = pickManager.getTranslation(constraintAxis).dot(constraintAxis); + diff *= 0.5f; + scale = startScale.add(new Vector3f(diff, diff, diff)); + } else { + // Get the translation in the spatial Space + Quaternion worldToSpatial = toolController.getSelectedSpatial().getWorldRotation().inverse(); + Vector3f diff = pickManager.getTranslation(worldToSpatial.mult(currentAxis)); + diff.multLocal(0.5f); + scale = startScale.add(diff); + } + finalScale = scale; + toolController.getSelectedSpatial().setLocalScale(scale); + updateToolsTransformation(); + } + } + + @Override + public void draggedPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + if (pressed) { + apply(); + } + } + + @Override + public void draggedSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + if (pressed) { + cancel(); + } + } + + private class ScaleUndo extends AbstractUndoableSceneEdit { + + private Spatial spatial; + private Vector3f before, after; + + ScaleUndo(Spatial spatial, Vector3f before, Vector3f after) { + this.spatial = spatial; + this.before = before; + this.after = after; + } + + @Override + public void sceneUndo() { + spatial.setLocalScale(before); + toolController.selectedSpatialTransformed(); + } + + @Override + public void sceneRedo() { + spatial.setLocalScale(after); + toolController.selectedSpatialTransformed(); + } + } +} diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java index 5dad38d7c..bdbcfbe9e 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java @@ -26,6 +26,8 @@ public class ShortcutManager { public ShortcutManager() { shortcutList = new ArrayList(); shortcutList.add(new MoveShortcut()); + shortcutList.add(new RotateShortcut()); + shortcutList.add(new ScaleShortcut()); } /* @@ -72,7 +74,14 @@ public class ShortcutManager { } return newShortcut != null; } - + + /** + * This should be called to trigger the currentShortcut.keyPressed() method. + * This method do a first check for command key used to provide isCtrlDown, + * isShiftDown ect.. to de + * + * @param kie + */ public void doKeyPressed(KeyInputEvent kie) { ///todo check commande key if (isActive()) { From e9b1972aca2fb217ba79955c6926b63a1a7799a4 Mon Sep 17 00:00:00 2001 From: Maselbas Date: Fri, 15 May 2015 18:47:14 +0200 Subject: [PATCH 7/9] SDK SceneComposer : clean up in the RotateTool, changed the name of the UndoableSceneEdit from ScaleUndo to RotateUndo --- .../com/jme3/gde/scenecomposer/tools/RotateTool.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/RotateTool.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/RotateTool.java index 21e9a56d8..e5a125771 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/RotateTool.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/RotateTool.java @@ -25,7 +25,6 @@ import org.openide.util.Lookup; public class RotateTool extends SceneEditTool { private Vector3f pickedMarker; - private Vector2f lastScreenCoord; private Quaternion startRotate; private Quaternion lastRotate; private boolean wasDragging = false; @@ -48,9 +47,8 @@ public class RotateTool extends SceneEditTool { if (!pressed) { setDefaultAxisMarkerColors(); pickedMarker = null; // mouse released, reset selection - lastScreenCoord = null; if (wasDragging) { - actionPerformed(new ScaleUndo(toolController.getSelectedSpatial(), startRotate, lastRotate)); + actionPerformed(new RotateUndo(toolController.getSelectedSpatial(), startRotate, lastRotate)); wasDragging = false; } pickManager.reset(); @@ -100,10 +98,9 @@ public class RotateTool extends SceneEditTool { if (!pressed) { setDefaultAxisMarkerColors(); pickedMarker = null; // mouse released, reset selection - lastScreenCoord = null; if (wasDragging) { - actionPerformed(new ScaleUndo(toolController.getSelectedSpatial(), startRotate, lastRotate)); + actionPerformed(new RotateUndo(toolController.getSelectedSpatial(), startRotate, lastRotate)); wasDragging = false; } pickManager.reset(); @@ -138,12 +135,12 @@ public class RotateTool extends SceneEditTool { } } - private class ScaleUndo extends AbstractUndoableSceneEdit { + private class RotateUndo extends AbstractUndoableSceneEdit { private Spatial spatial; private Quaternion before, after; - ScaleUndo(Spatial spatial, Quaternion before, Quaternion after) { + RotateUndo(Spatial spatial, Quaternion before, Quaternion after) { this.spatial = spatial; this.before = before; this.after = after; From bbca035a43abd5e77f1859c81418ceca8f329c1a Mon Sep 17 00:00:00 2001 From: Maselbas Date: Fri, 15 May 2015 20:36:55 +0200 Subject: [PATCH 8/9] SDK SceneComposer : all shortcuts tool are now outside of the selectTool, - added the Delete and Duplicate shortcut - deleted the MoveManager - clean up the SelectTool (removed old shortCuts) - now the ShortcutManager can also provide to SorthcutTools the state of ctr, alt and shift key --- .../gde/scenecomposer/tools/MoveManager.java | 204 ----- .../gde/scenecomposer/tools/SelectTool.java | 694 +----------------- .../tools/shortcuts/DeleteShortcut.java | 123 ++++ .../tools/shortcuts/DuplicateShortcut.java | 141 ++++ .../tools/shortcuts/ShortcutManager.java | 52 +- 5 files changed, 342 insertions(+), 872 deletions(-) delete mode 100644 sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/MoveManager.java create mode 100644 sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DeleteShortcut.java create mode 100644 sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DuplicateShortcut.java diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/MoveManager.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/MoveManager.java deleted file mode 100644 index d7b92db91..000000000 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/MoveManager.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package com.jme3.gde.scenecomposer.tools; - -import com.jme3.bullet.control.CharacterControl; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit; -import com.jme3.gde.scenecomposer.SceneEditTool; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.renderer.Camera; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Quad; -import org.openide.util.lookup.ServiceProvider; - -/** - * - * @author Nehon - */ -@ServiceProvider(service = MoveManager.class) -public class MoveManager { - - private Vector3f startLoc; - private Vector3f startWorldLoc; - private Vector3f lastLoc; - private Vector3f offset; - private Node alternativePickTarget = null; - private Node plane; - private Spatial spatial; - protected static final Quaternion XY = new Quaternion().fromAngleAxis(0, new Vector3f(1, 0, 0)); - protected static final Quaternion YZ = new Quaternion().fromAngleAxis(-FastMath.PI / 2, new Vector3f(0, 1, 0)); - protected static final Quaternion XZ = new Quaternion().fromAngleAxis(FastMath.PI / 2, new Vector3f(1, 0, 0)); - //temp vars - private Quaternion rot = new Quaternion(); - private Vector3f newPos = new Vector3f(); - - public MoveManager() { - float size = 1000; - Geometry g = new Geometry("plane", new Quad(size, size)); - g.setLocalTranslation(-size / 2, -size / 2, 0); - plane = new Node(); - plane.attachChild(g); - } - - public Vector3f getOffset() { - return offset; - } - - public void reset() { - offset = null; - startLoc = null; - startWorldLoc = null; - lastLoc = null; - spatial = null; - alternativePickTarget = null; - } - - public void initiateMove(Spatial selectedSpatial, Quaternion planeRotation, boolean local) { - spatial = selectedSpatial; - startLoc = selectedSpatial.getLocalTranslation().clone(); - startWorldLoc = selectedSpatial.getWorldTranslation().clone(); - if (local) { - rot.set(selectedSpatial.getWorldRotation()); - plane.setLocalRotation(rot.multLocal(planeRotation)); - } else { - rot.set(planeRotation); - } - - plane.setLocalRotation(rot); - plane.setLocalTranslation(startWorldLoc); - - } - - public void updatePlaneRotation(Quaternion planeRotation) { - plane.setLocalRotation(rot); - } - - public boolean move(Camera camera, Vector2f screenCoord) { - return move(camera, screenCoord, Vector3f.UNIT_XYZ, false); - } - - public boolean move(Camera camera, Vector2f screenCoord, Vector3f constraintAxis, boolean gridSnap) { - Node toPick = alternativePickTarget == null ? plane : alternativePickTarget; - - Vector3f planeHit = SceneEditTool.pickWorldLocation(camera, screenCoord, toPick, alternativePickTarget == null ? null : spatial); - if (planeHit == null) { - return false; - } - - Spatial parent = spatial.getParent(); - //we are moving the root node, there is a slight chance that something went wrong. - if (parent == null) { - return false; - } - - //offset in world space - if (offset == null) { - offset = planeHit.subtract(spatial.getWorldTranslation()); // get the offset when we start so it doesn't jump - } - - newPos.set(planeHit).subtractLocal(offset); - - //constraining the translation with the contraintAxis. - Vector3f tmp = startWorldLoc.mult(Vector3f.UNIT_XYZ.subtract(constraintAxis)); - newPos.multLocal(constraintAxis).addLocal(tmp); - worldToLocalMove(gridSnap); - return true; - } - - private void worldToLocalMove(boolean gridSnap) { - //snap to grid (grid is assumed 1 WU per cell) - if (gridSnap) { - newPos.set(Math.round(newPos.x), Math.round(newPos.y), Math.round(newPos.z)); - } - - //computing the inverse world transform to get the new localtranslation - newPos.subtractLocal(spatial.getParent().getWorldTranslation()); - newPos = spatial.getParent().getWorldRotation().inverse().normalizeLocal().multLocal(newPos); - newPos.divideLocal(spatial.getParent().getWorldScale()); - - lastLoc = newPos; - spatial.setLocalTranslation(newPos); - - RigidBodyControl control = spatial.getControl(RigidBodyControl.class); - if (control != null) { - control.setPhysicsLocation(spatial.getWorldTranslation()); - } - CharacterControl character = spatial.getControl(CharacterControl.class); - if (character != null) { - character.setPhysicsLocation(spatial.getWorldTranslation()); - } - } - - public boolean moveAcross(Vector3f constraintAxis, float value, boolean gridSnap) { - newPos.set(startWorldLoc).addLocal(constraintAxis.mult(value)); - Spatial parent = spatial.getParent(); - //we are moving the root node, there is a slight chance that something went wrong. - if (parent == null) { - return false; - } - worldToLocalMove(gridSnap); - return true; - } - - public MoveUndo makeUndo() { - return new MoveUndo(spatial, startLoc, lastLoc); - } - - public void setAlternativePickTarget(Node alternativePickTarget) { - this.alternativePickTarget = alternativePickTarget; - } - - protected class MoveUndo extends AbstractUndoableSceneEdit { - - private Spatial spatial; - private Vector3f before = new Vector3f(), after = new Vector3f(); - - MoveUndo(Spatial spatial, Vector3f before, Vector3f after) { - this.spatial = spatial; - this.before.set(before); - if (after != null) { - this.after.set(after); - } - } - - @Override - public void sceneUndo() { - spatial.setLocalTranslation(before); - RigidBodyControl control = spatial.getControl(RigidBodyControl.class); - if (control != null) { - control.setPhysicsLocation(spatial.getWorldTranslation()); - } - CharacterControl character = spatial.getControl(CharacterControl.class); - if (character != null) { - character.setPhysicsLocation(spatial.getWorldTranslation()); - } - // toolController.selectedSpatialTransformed(); - } - - @Override - public void sceneRedo() { - spatial.setLocalTranslation(after); - RigidBodyControl control = spatial.getControl(RigidBodyControl.class); - if (control != null) { - control.setPhysicsLocation(spatial.getWorldTranslation()); - } - CharacterControl character = spatial.getControl(CharacterControl.class); - if (character != null) { - character.setPhysicsLocation(spatial.getWorldTranslation()); - } - //toolController.selectedSpatialTransformed(); - } - - public void setAfter(Vector3f after) { - this.after.set(after); - } - } -} diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/SelectTool.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/SelectTool.java index 43d3cba3a..87f3c283f 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/SelectTool.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/SelectTool.java @@ -8,425 +8,51 @@ import com.jme3.gde.core.sceneexplorer.SceneExplorerTopComponent; import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; import com.jme3.gde.core.sceneviewer.SceneViewerTopComponent; -import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit; import com.jme3.gde.scenecomposer.SceneEditTool; -import com.jme3.input.KeyInput; -import com.jme3.input.event.KeyInputEvent; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.terrain.Terrain; import org.openide.loaders.DataObject; -import org.openide.util.Lookup; /** - * This duplicates the Blender manipulate tool. - * It supports quick access to Grab, Rotate, and Scale operations - * by typing one of the following keys: 'g', 'r', or 's' - * Those keys can be followed by an axis key to specify what axis - * to perform the transformation: x, y, z - * Then, after the operation and axis are selected, you can type in a - * number and then hit 'enter' to complete the transformation. - * - * Ctrl+Shift+D will duplicate an object - * X will delete an object - * - * ITEMS TO FINISH: - * 1) fixed scale and rotation values by holding Ctrl and dragging mouse - * BUGS: - * 1) window always needs focus from primary click when it should focus from secondary and middle mouse - * + * This duplicates the Blender manipulate tool. It supports quick access to + * Grab, Rotate, and Scale operations by typing one of the following keys: 'g', + * 'r', or 's' Those keys can be followed by an axis key to specify what axis to + * perform the transformation: x, y, z Then, after the operation and axis are + * selected, you can type in a number and then hit 'enter' to complete the + * transformation. + * + * Ctrl+Shift+D will duplicate an object X will delete an object + * + * ITEMS TO FINISH: 1) fixed scale and rotation values by holding Ctrl and + * dragging mouse BUGS: 1) window always needs focus from primary click when it + * should focus from secondary and middle mouse + * * @author Brent Owens */ public class SelectTool extends SceneEditTool { - private enum State { - - translate, rotate, scale - }; - private State currentState = null; - private Vector3f currentAxis = Vector3f.UNIT_XYZ; - private StringBuilder numberBuilder = new StringBuilder(); // gets appended with numbers - private Quaternion startRot; - private Vector3f startTrans; - private Vector3f startScale; - private boolean wasDraggingL = false; private boolean wasDraggingR = false; private boolean wasDownR = false; - private boolean ctrlDown = false; - private boolean shiftDown = false; - private boolean altDown = false; - private MoveManager.MoveUndo moving; - private ScaleUndo scaling; - private RotateUndo rotating; - private Vector2f startMouseCoord; // for scaling and rotation - private Vector2f startSelectedCoord; // for scaling and rotation - private float lastRotAngle; // used for rotation /** - * This is stateful: - * First it checks for a command (rotate, translate, delete, etc..) - * Then it checks for an axis (x,y,z) - * Then it checks for a number (user typed a number - * Then, finally, it checks if Enter was hit. - * + * This is stateful: First it checks for a command (rotate, translate, + * delete, etc..) Then it checks for an axis (x,y,z) Then it checks for a + * number (user typed a number Then, finally, it checks if Enter was hit. + * * If either of the commands was actioned, the preceeding states/axis/amount - * will be reset. For example if the user types: G Y 2 R - * Then it will: - * 1) Set state as 'Translate' for the G (grab) - * 2) Set the axis as 'Y'; it will translate along the Y axis - * 3) Distance will be 2, when the 2 key is hit - * 4) Distance, Axis, and state are then reset because a new state was set: Rotate - * it won't actually translate because 'Enter' was not hit and 'R' reset the state. - * + * will be reset. For example if the user types: G Y 2 R Then it will: 1) + * Set state as 'Translate' for the G (grab) 2) Set the axis as 'Y'; it will + * translate along the Y axis 3) Distance will be 2, when the 2 key is hit + * 4) Distance, Axis, and state are then reset because a new state was set: + * Rotate it won't actually translate because 'Enter' was not hit and 'R' + * reset the state. + * */ - @Override - public void keyPressed(KeyInputEvent kie) { - - checkModificatorKeys(kie); // alt,shift,ctrl - Spatial selected = toolController.getSelectedSpatial(); - - if (selected == null) { - return; // only do anything if a spatial is selected - } - // key released - if (kie.isPressed()) { - boolean commandUsed = checkCommandKey(kie); - boolean stateChange = checkStateKey(kie); - boolean axisChange = checkAxisKey(kie); - boolean numberChange = checkNumberKey(kie); - boolean enterHit = checkEnterHit(kie); - boolean escHit = checkEscHit(kie); - - if (commandUsed) { - return; // commands take priority - } - if (stateChange) { - currentAxis = Vector3f.UNIT_XYZ; - numberBuilder = new StringBuilder(); - recordInitialState(selected); - } else if (axisChange) { - } else if (numberChange) { - } else if (enterHit) { - if (currentState != null && numberBuilder.length() > 0) { - applyKeyedChangeState(selected); - clearState(false); - } - } - - - // ----------------------- - // reset conditions below: - - if (escHit) { - if (moving != null) { - moving.sceneUndo(); - } - - moving = null; - clearState(); - } - - if (!stateChange && !axisChange && !numberChange && !enterHit && !escHit) { - // nothing valid was hit, reset the state - //clearState(); // this will be - } - } - } - - /** - * Abort any manipulations - */ - private void clearState() { - clearState(true); - } - - private void clearState(boolean resetSelected) { - Spatial selected = toolController.getSelectedSpatial(); - if (resetSelected && selected != null) { - // reset the transforms - if (startRot != null) { - selected.setLocalRotation(startRot); - } - if (startTrans != null) { - selected.setLocalTranslation(startTrans); - } - if (startScale != null) { - selected.setLocalScale(startScale); - } - } - currentState = null; - currentAxis = Vector3f.UNIT_XYZ; - numberBuilder = new StringBuilder(); - startRot = null; - startTrans = null; - startScale = null; - startMouseCoord = null; - startSelectedCoord = null; - lastRotAngle = 0; - } - - private void recordInitialState(Spatial selected) { - startRot = selected.getLocalRotation().clone(); - startTrans = selected.getLocalTranslation().clone(); - startScale = selected.getLocalScale().clone(); - } - - /** - * Applies the changes entered by a number, not by mouse. - * Translate: adds the value to the current local translation - * Rotate: rotates by X degrees - * Scale: scale the current scale by X amount - */ - private void applyKeyedChangeState(Spatial selected) { - Float value = null; - try { - value = new Float(numberBuilder.toString()); - } catch (NumberFormatException e) { - return; - } - - if (currentState == State.translate) { - MoveManager moveManager = Lookup.getDefault().lookup(MoveManager.class); - moveManager.moveAcross(currentAxis, value, toolController.isSnapToGrid()); - moving.setAfter(selected.getLocalTranslation()); - actionPerformed(moving); - moving = null; - } else if (currentState == State.scale) { - float x = 1, y = 1, z = 1; - if (currentAxis == Vector3f.UNIT_X) { - x = value; - } else if (currentAxis == Vector3f.UNIT_Y) { - y = value; - } else if (currentAxis == Vector3f.UNIT_Z) { - z = value; - } else if (currentAxis == Vector3f.UNIT_XYZ) { - x = value; - y = value; - z = value; - } - Vector3f before = selected.getLocalScale().clone(); - Vector3f after = selected.getLocalScale().multLocal(x, y, z); - selected.setLocalScale(after); - actionPerformed(new ScaleUndo(selected, before, after)); - } else if (currentState == State.rotate) { - float x = 0, y = 0, z = 0; - if (currentAxis == Vector3f.UNIT_X) { - x = 1; - } else if (currentAxis == Vector3f.UNIT_Y) { - y = 1; - } else if (currentAxis == Vector3f.UNIT_Z) { - z = 1; - } - Vector3f axis = new Vector3f(x, y, z); - Quaternion initialRot = selected.getLocalRotation().clone(); - Quaternion rot = new Quaternion(); - rot = rot.fromAngleAxis(value * FastMath.DEG_TO_RAD, axis); - selected.setLocalRotation(selected.getLocalRotation().mult(rot)); - RotateUndo undo = new RotateUndo(selected, initialRot, rot); - actionPerformed(undo); - toolController.updateSelection(null);// force a re-draw of the bbox shape - toolController.updateSelection(selected); - - } - clearState(false); - } - - private void checkModificatorKeys(KeyInputEvent kie) { - if (kie.getKeyCode() == KeyInput.KEY_LCONTROL || kie.getKeyCode() == KeyInput.KEY_RCONTROL) { - ctrlDown = kie.isPressed(); - } - - if (kie.getKeyCode() == KeyInput.KEY_LSHIFT || kie.getKeyCode() == KeyInput.KEY_RSHIFT) { - shiftDown = kie.isPressed(); - } - - if (kie.getKeyCode() == KeyInput.KEY_LMENU || kie.getKeyCode() == KeyInput.KEY_RMENU) { - altDown = kie.isPressed(); - } - } - - private boolean checkCommandKey(KeyInputEvent kie) { - if (kie.getKeyCode() == KeyInput.KEY_D) { - if (shiftDown) { - duplicateSelected(); - return true; - } - } - // X will only delete if the user isn't already transforming - if (currentState == null && kie.getKeyCode() == KeyInput.KEY_X) { - if (!ctrlDown && !shiftDown) { - deleteSelected(); - return true; - } - } - return false; - } - - private boolean checkStateKey(KeyInputEvent kie) { - Spatial selected = toolController.getSelectedSpatial(); - if (kie.getKeyCode() == KeyInput.KEY_G && !ctrlDown) { - currentState = State.translate; - MoveManager moveManager = Lookup.getDefault().lookup(MoveManager.class); - moveManager.reset(); - Quaternion rot = camera.getRotation().mult(new Quaternion().fromAngleAxis(FastMath.PI, Vector3f.UNIT_Y)); - moveManager.initiateMove(selected, rot, false); - moving = moveManager.makeUndo(); - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_R && !ctrlDown) { - currentState = State.rotate; - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_S && !ctrlDown) { - currentState = State.scale; - return true; - } - return false; - } - - private boolean checkAxisKey(KeyInputEvent kie) { - if (kie.getKeyCode() == KeyInput.KEY_X) { - currentAxis = Vector3f.UNIT_X; - checkMovePlane(MoveManager.XY, MoveManager.XZ); - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_Y) { - currentAxis = Vector3f.UNIT_Y; - checkMovePlane(MoveManager.XY, MoveManager.YZ); - return true; - } else if (kie.getKeyCode() == KeyInput.KEY_Z) { - currentAxis = Vector3f.UNIT_Z; - checkMovePlane(MoveManager.XZ, MoveManager.YZ); - return true; - } - return false; - } - - private void checkMovePlane(Quaternion rot1, Quaternion rot2) { - if (currentState == State.translate) { - MoveManager moveManager = Lookup.getDefault().lookup(MoveManager.class); - Quaternion rot = camera.getRotation().mult(new Quaternion().fromAngleAxis(FastMath.PI, Vector3f.UNIT_Y)); - Quaternion planRot = null; - if (rot.dot(rot1) < rot.dot(rot2)) { - planRot = rot1; - } else { - planRot = rot2; - } - moveManager.updatePlaneRotation(planRot); - } - } - - private boolean checkNumberKey(KeyInputEvent kie) { - if (kie.getKeyCode() == KeyInput.KEY_MINUS) { - if (numberBuilder.length() > 0) { - if (numberBuilder.charAt(0) == '-') { - numberBuilder.replace(0, 1, ""); - } else { - numberBuilder.insert(0, '-'); - } - } 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("."); - } - } - return true; - } - - return false; - } - - private boolean checkEnterHit(KeyInputEvent kie) { - if (kie.getKeyCode() == KeyInput.KEY_RETURN) { - return true; - } - return false; - } - - private boolean checkEscHit(KeyInputEvent kie) { - if (kie.getKeyCode() == KeyInput.KEY_ESCAPE) { - return true; - } - return false; - } - @Override public void actionPrimary(Vector2f screenCoord, boolean pressed, final JmeNode rootNode, DataObject dataObject) { - if (!pressed) { - Spatial selected = toolController.getSelectedSpatial(); - // left mouse released - if (!wasDraggingL) { - // left mouse pressed - if (currentState != null) { - // finish manipulating the spatial - if (moving != null) { - moving.setAfter(selected.getLocalTranslation()); - actionPerformed(moving); - moving = null; - clearState(false); - } else if (scaling != null) { - scaling.after = selected.getLocalScale().clone(); - actionPerformed(scaling); - scaling = null; - clearState(false); - toolController.rebuildSelectionBox(); - } else if (rotating != null) { - rotating.after = selected.getLocalRotation().clone(); - actionPerformed(rotating); - rotating = null; - clearState(false); - } - } else { - // mouse released and wasn't dragging, place cursor - final Vector3f result = pickWorldLocation(getCamera(), screenCoord, rootNode); - if (result != null) { - if (toolController.isSnapToGrid()) { - result.set(Math.round(result.x), result.y, Math.round(result.z)); - } - toolController.setCursorLocation(result); - } - } - } - wasDraggingL = false; - } + } @Override @@ -435,19 +61,7 @@ public class SelectTool extends SceneEditTool { Spatial selected = toolController.getSelectedSpatial(); // mouse down - if (moving != null) { - moving.sceneUndo(); - moving = null; - clearState(); - } else if (scaling != null) { - scaling.sceneUndo(); - scaling = null; - clearState(); - } else if (rotating != null) { - rotating.sceneUndo(); - rotating = null; - clearState(); - } else if (!wasDraggingR && !wasDownR) { // wasn't dragging and was not down already + if (!wasDraggingR && !wasDownR) { // wasn't dragging and was not down already // pick on the spot Spatial s = pickWorldSpatial(camera, screenCoord, rootNode); if (!toolController.selectTerrain() && isTerrain(s)) { @@ -498,8 +112,8 @@ public class SelectTool extends SceneEditTool { } /** - * Climb up the spatial until we find the first node parent. - * TODO: use userData to determine the actual model's parent. + * Climb up the spatial until we find the first node parent. TODO: use + * userData to determine the actual model's parent. */ private Spatial findModelNodeParent(Spatial child) { if (child == null) { @@ -519,14 +133,10 @@ public class SelectTool extends SceneEditTool { @Override public void mouseMoved(Vector2f screenCoord, JmeNode rootNode, DataObject currentDataObject, JmeSpatial selectedSpatial) { - if (currentState != null) { - handleMouseManipulate(screenCoord, currentState, currentAxis, rootNode, currentDataObject, selectedSpatial); - } } @Override public void draggedPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { - wasDraggingL = pressed; } @Override @@ -535,252 +145,8 @@ public class SelectTool extends SceneEditTool { } /** - * Manipulate the spatial - */ - private void handleMouseManipulate(Vector2f screenCoord, - State state, - Vector3f axis, - JmeNode rootNode, - DataObject currentDataObject, - JmeSpatial selectedSpatial) { - if (state == State.translate) { - doMouseTranslate(axis, screenCoord, rootNode, selectedSpatial); - } else if (state == State.scale) { - doMouseScale(axis, screenCoord, rootNode, selectedSpatial); - } else if (state == State.rotate) { - doMouseRotate(axis, screenCoord, rootNode, selectedSpatial); - } - - } - - private void doMouseTranslate(Vector3f axis, Vector2f screenCoord, JmeNode rootNode, JmeSpatial selectedSpatial) { - MoveManager moveManager = Lookup.getDefault().lookup(MoveManager.class); - if (toolController.isSnapToScene()) { - moveManager.setAlternativePickTarget(rootNode.getLookup().lookup(Node.class)); - } - // free form translation - moveManager.move(camera, screenCoord, axis, toolController.isSnapToGrid()); - } - - private void doMouseScale(Vector3f axis, Vector2f screenCoord, JmeNode rootNode, JmeSpatial selectedSpatial) { - Spatial selected = toolController.getSelectedSpatial(); - // scale based on the original mouse position and original model-to-screen position - // and compare that to the distance from the new mouse position and the original distance - if (startMouseCoord == null) { - startMouseCoord = screenCoord.clone(); - } - if (startSelectedCoord == null) { - Vector3f screen = getCamera().getScreenCoordinates(selected.getWorldTranslation()); - startSelectedCoord = new Vector2f(screen.x, screen.y); - } - - if (scaling == null) { - scaling = new ScaleUndo(selected, selected.getLocalScale().clone(), null); - } - - float origDist = startMouseCoord.distanceSquared(startSelectedCoord); - float newDist = screenCoord.distanceSquared(startSelectedCoord); - if (origDist == 0) { - origDist = 1; - } - float ratio = newDist / origDist; - Vector3f prev = selected.getLocalScale(); - if (axis == Vector3f.UNIT_X) { - selected.setLocalScale(ratio, prev.y, prev.z); - } else if (axis == Vector3f.UNIT_Y) { - selected.setLocalScale(prev.x, ratio, prev.z); - } else if (axis == Vector3f.UNIT_Z) { - selected.setLocalScale(prev.x, prev.y, ratio); - } else { - selected.setLocalScale(ratio, ratio, ratio); - } - } - - private void doMouseRotate(Vector3f axis, Vector2f screenCoord, JmeNode rootNode, JmeSpatial selectedSpatial) { - Spatial selected = toolController.getSelectedSpatial(); - if (startMouseCoord == null) { - startMouseCoord = screenCoord.clone(); - } - if (startSelectedCoord == null) { - Vector3f screen = getCamera().getScreenCoordinates(selected.getWorldTranslation()); - startSelectedCoord = new Vector2f(screen.x, screen.y); - } - - if (rotating == null) { - rotating = new RotateUndo(selected, selected.getLocalRotation().clone(), null); - } - - Vector2f origRot = startMouseCoord.subtract(startSelectedCoord); - Vector2f newRot = screenCoord.subtract(startSelectedCoord); - float newRotAngle = origRot.angleBetween(newRot); - float temp = newRotAngle; - - if (lastRotAngle != 0) { - newRotAngle -= lastRotAngle; - } - - lastRotAngle = temp; - - Quaternion rotate = new Quaternion(); - if (axis != Vector3f.UNIT_XYZ) { - rotate = rotate.fromAngleAxis(newRotAngle, selected.getWorldRotation().inverse().mult(axis)); - } else { - rotate = rotate.fromAngleAxis(newRotAngle, selected.getWorldRotation().inverse().mult(getCamera().getDirection().mult(-1).normalizeLocal())); - } - selected.setLocalRotation(selected.getLocalRotation().mult(rotate)); - - - } - - private void duplicateSelected() { - Spatial selected = toolController.getSelectedSpatial(); - if (selected == null) { - return; - } - Spatial clone = selected.clone(); - clone.move(1, 0, 1); - - selected.getParent().attachChild(clone); - actionPerformed(new DuplicateUndo(clone, selected.getParent())); - selected = clone; - final Spatial cloned = clone; - final JmeNode rootNode = toolController.getRootNode(); - refreshSelected(rootNode, selected.getParent()); - - java.awt.EventQueue.invokeLater(new Runnable() { - - @Override - public void run() { - if (cloned != null) { - SceneViewerTopComponent.findInstance().setActivatedNodes(new org.openide.nodes.Node[]{rootNode.getChild(cloned)}); - SceneExplorerTopComponent.findInstance().setSelectedNode(rootNode.getChild(cloned)); - } - } - }); - - // set to automatically 'grab'/'translate' the new cloned model - toolController.updateSelection(selected); - currentState = State.translate; - currentAxis = Vector3f.UNIT_XYZ; - } - - private void deleteSelected() { - Spatial selected = toolController.getSelectedSpatial(); - if (selected == null) { - return; - } - Node parent = selected.getParent(); - selected.removeFromParent(); - actionPerformed(new DeleteUndo(selected, parent)); - - selected = null; - toolController.updateSelection(selected); - - final JmeNode rootNode = toolController.getRootNode(); - refreshSelected(rootNode, parent); - } - - private void refreshSelected(final JmeNode jmeRootNode, final Node parent) { - java.awt.EventQueue.invokeLater(new Runnable() { - - @Override - public void run() { - jmeRootNode.getChild(parent).refresh(false); - } - }); - } - - private class ScaleUndo extends AbstractUndoableSceneEdit { - - private Spatial spatial; - private Vector3f before, after; - - ScaleUndo(Spatial spatial, Vector3f before, Vector3f after) { - this.spatial = spatial; - this.before = before; - this.after = after; - } - - @Override - public void sceneUndo() { - spatial.setLocalScale(before); - } - - @Override - public void sceneRedo() { - spatial.setLocalScale(after); - } - } - - private class RotateUndo extends AbstractUndoableSceneEdit { - - private Spatial spatial; - private Quaternion before, after; - - RotateUndo(Spatial spatial, Quaternion before, Quaternion after) { - this.spatial = spatial; - this.before = before; - this.after = after; - } - - @Override - public void sceneUndo() { - spatial.setLocalRotation(before); - } - - @Override - public void sceneRedo() { - spatial.setLocalRotation(after); - } - } - - private class DeleteUndo extends AbstractUndoableSceneEdit { - - private Spatial spatial; - private Node parent; - - DeleteUndo(Spatial spatial, Node parent) { - this.spatial = spatial; - this.parent = parent; - } - - @Override - public void sceneUndo() { - parent.attachChild(spatial); - } - - @Override - public void sceneRedo() { - spatial.removeFromParent(); - } - } - - private class DuplicateUndo extends AbstractUndoableSceneEdit { - - private Spatial spatial; - private Node parent; - - DuplicateUndo(Spatial spatial, Node parent) { - this.spatial = spatial; - this.parent = parent; - } - - @Override - public void sceneUndo() { - spatial.removeFromParent(); - } - - @Override - public void sceneRedo() { - parent.attachChild(spatial); - } - } - - /** - * Check if the selected item is a Terrain - * It will climb up the parent tree to see if - * a parent is terrain too. - * Recursive call. + * Check if the selected item is a Terrain It will climb up the parent tree + * to see if a parent is terrain too. Recursive call. */ protected boolean isTerrain(Spatial s) { if (s == null) { diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DeleteShortcut.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DeleteShortcut.java new file mode 100644 index 000000000..cc13ece1d --- /dev/null +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DeleteShortcut.java @@ -0,0 +1,123 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.scenecomposer.tools.shortcuts; + +import com.jme3.asset.AssetManager; +import com.jme3.gde.core.sceneexplorer.SceneExplorerTopComponent; +import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; +import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; +import com.jme3.gde.core.sceneviewer.SceneViewerTopComponent; +import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit; +import com.jme3.gde.scenecomposer.SceneComposerToolController; +import com.jme3.input.KeyInput; +import com.jme3.input.event.KeyInputEvent; +import com.jme3.math.Vector2f; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import org.openide.loaders.DataObject; +import org.openide.util.Lookup; + +/** + * + * @author dokthar + */ +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()) { + return true; + } + } + return false; + } + + @Override + public void cancel() { + terminate(); + } + + @Override + public void activate(AssetManager manager, Node toolNode, Node onTopToolNode, Spatial selectedSpatial, SceneComposerToolController toolController) { + super.activate(manager, toolNode, onTopToolNode, selectedSpatial, toolController); //To change body of generated methods, choose Tools | Templates. + hideMarker(); + if (selectedSpatial != null) { + delete(); + } + terminate(); + } + + private void delete() { + Spatial selected = toolController.getSelectedSpatial(); + + Node parent = selected.getParent(); + selected.removeFromParent(); + actionPerformed(new DeleteUndo(selected, parent)); + + selected = null; + toolController.updateSelection(selected); + + final JmeNode rootNode = toolController.getRootNode(); + refreshSelected(rootNode, parent); + } + + private void refreshSelected(final JmeNode jmeRootNode, final Node parent) { + java.awt.EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + jmeRootNode.getChild(parent).refresh(false); + } + }); + } + + @Override + public void keyPressed(KeyInputEvent kie) { + + } + + @Override + public void actionPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + } + + @Override + public void actionSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + } + + @Override + public void mouseMoved(Vector2f screenCoord, JmeNode rootNode, DataObject dataObject, JmeSpatial selectedSpatial) { + } + + @Override + public void draggedPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + } + + @Override + public void draggedSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + } + + private class DeleteUndo extends AbstractUndoableSceneEdit { + + private Spatial spatial; + private Node parent; + + DeleteUndo(Spatial spatial, Node parent) { + this.spatial = spatial; + this.parent = parent; + } + + @Override + public void sceneUndo() { + parent.attachChild(spatial); + } + + @Override + public void sceneRedo() { + spatial.removeFromParent(); + } + } +} diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DuplicateShortcut.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DuplicateShortcut.java new file mode 100644 index 000000000..d98eb6ee9 --- /dev/null +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DuplicateShortcut.java @@ -0,0 +1,141 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.scenecomposer.tools.shortcuts; + +import com.jme3.asset.AssetManager; +import com.jme3.gde.core.sceneexplorer.SceneExplorerTopComponent; +import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; +import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; +import com.jme3.gde.core.sceneviewer.SceneViewerTopComponent; +import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit; +import com.jme3.gde.scenecomposer.SceneComposerToolController; +import com.jme3.input.KeyInput; +import com.jme3.input.event.KeyInputEvent; +import com.jme3.math.Vector2f; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import org.openide.loaders.DataObject; +import org.openide.util.Lookup; + +/** + * + * @author dokthar + */ +public class DuplicateShortcut extends ShortcutTool { + + @Override + public boolean isActivableBy(KeyInputEvent kie) { + if (kie.getKeyCode() == KeyInput.KEY_D && kie.isPressed()) { + if (Lookup.getDefault().lookup(ShortcutManager.class).isShiftDown()) { + return true; + } + } + return false; + } + + @Override + public void cancel() { + terminate(); + } + + @Override + public void activate(AssetManager manager, Node toolNode, Node onTopToolNode, Spatial selectedSpatial, SceneComposerToolController toolController) { + super.activate(manager, toolNode, onTopToolNode, selectedSpatial, toolController); //To change body of generated methods, choose Tools | Templates. + hideMarker(); + if (selectedSpatial != null) { + duplicate(); + terminate(); + + //then enable move shortcut + toolController.doKeyPressed(new KeyInputEvent(KeyInput.KEY_G, 'g', true, false)); + } else { + terminate(); + } + } + + private void duplicate() { + Spatial selected = toolController.getSelectedSpatial(); + + Spatial clone = selected.clone(); + clone.move(1, 0, 1); + + selected.getParent().attachChild(clone); + actionPerformed(new DuplicateUndo(clone, selected.getParent())); + selected = clone; + final Spatial cloned = clone; + final JmeNode rootNode = toolController.getRootNode(); + refreshSelected(rootNode, selected.getParent()); + + java.awt.EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + if (cloned != null) { + SceneViewerTopComponent.findInstance().setActivatedNodes(new org.openide.nodes.Node[]{rootNode.getChild(cloned)}); + SceneExplorerTopComponent.findInstance().setSelectedNode(rootNode.getChild(cloned)); + } + } + }); + + toolController.updateSelection(selected); + } + + private void refreshSelected(final JmeNode jmeRootNode, final Node parent) { + java.awt.EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + jmeRootNode.getChild(parent).refresh(false); + } + }); + } + + @Override + public void keyPressed(KeyInputEvent kie) { + + } + + @Override + public void actionPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + } + + @Override + public void actionSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) { + } + + @Override + public void mouseMoved(Vector2f screenCoord, JmeNode rootNode, DataObject dataObject, JmeSpatial selectedSpatial) { + } + + @Override + public void draggedPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + } + + @Override + public void draggedSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { + } + + private class DuplicateUndo extends AbstractUndoableSceneEdit { + + private Spatial spatial; + private Node parent; + + DuplicateUndo(Spatial spatial, Node parent) { + this.spatial = spatial; + this.parent = parent; + } + + @Override + public void sceneUndo() { + spatial.removeFromParent(); + } + + @Override + public void sceneRedo() { + parent.attachChild(spatial); + } + } +} diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java index bdbcfbe9e..512e36e0c 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java @@ -22,12 +22,17 @@ public class ShortcutManager { private ShortcutTool currentShortcut; private ArrayList shortcutList; + private boolean ctrlDown = false; + private boolean shiftDown = false; + private boolean altDown = false; public ShortcutManager() { shortcutList = new ArrayList(); shortcutList.add(new MoveShortcut()); shortcutList.add(new RotateShortcut()); shortcutList.add(new ScaleShortcut()); + shortcutList.add(new DuplicateShortcut()); + shortcutList.add(new DeleteShortcut()); } /* @@ -41,6 +46,27 @@ public class ShortcutManager { return currentShortcut != null; } + /** + * @return the ctrlDown + */ + public boolean isCtrlDown() { + return ctrlDown; + } + + /** + * @return the shiftDown + */ + public boolean isShiftDown() { + return shiftDown; + } + + /** + * @return the altDown + */ + public boolean isAltDown() { + return altDown; + } + public void setShortCut(ShortcutTool shortcut) { if (isActive()) { currentShortcut.cancel(); @@ -49,6 +75,9 @@ public class ShortcutManager { } public ShortcutTool getActivableShortcut(KeyInputEvent kie) { + if (checkCommandeKey(kie)) { + return null; + } for (ShortcutTool s : shortcutList) { if (s != currentShortcut) { if (s.isActivableBy(kie)) { @@ -69,12 +98,12 @@ public class ShortcutManager { public boolean activateShortcut(KeyInputEvent kie) { ShortcutTool newShortcut = getActivableShortcut(kie); - if(newShortcut != null){ + if (newShortcut != null) { currentShortcut = newShortcut; } return newShortcut != null; } - + /** * This should be called to trigger the currentShortcut.keyPressed() method. * This method do a first check for command key used to provide isCtrlDown, @@ -83,12 +112,27 @@ public class ShortcutManager { * @param kie */ public void doKeyPressed(KeyInputEvent kie) { - ///todo check commande key - if (isActive()) { + if (checkCommandeKey(kie)) { + //return; + } else if (isActive()) { currentShortcut.keyPressed(kie); } } + private boolean checkCommandeKey(KeyInputEvent kie) { + if (checkCtrlHit(kie)) { + ctrlDown = kie.isPressed(); + return true; + } else if (checkAltHit(kie)) { + altDown = kie.isPressed(); + return true; + } else if (checkShiftHit(kie)) { + shiftDown = kie.isPressed(); + return true; + } + return false; + } + /* STATIC */ From 97e1cf8cf3344fb1cbcb8c477f1a486386692377 Mon Sep 17 00:00:00 2001 From: Maselbas Date: Fri, 15 May 2015 22:38:18 +0200 Subject: [PATCH 9/9] SDK SceneComposer : added comments in the ShortCutManager - refactor getNumberkey() to getNumberKey() --- .../tools/shortcuts/MoveShortcut.java | 2 +- .../tools/shortcuts/RotateShortcut.java | 2 +- .../tools/shortcuts/ScaleShortcut.java | 2 +- .../tools/shortcuts/ShortcutManager.java | 90 ++++++++++++++++++- 4 files changed, 89 insertions(+), 7 deletions(-) diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java index 62cc70612..6291ab932 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/MoveShortcut.java @@ -103,7 +103,7 @@ public class MoveShortcut extends ShortcutTool { } } else if (axisChanged || numberChanged) { //update transformation - float number = ShortcutManager.getNumberkey(numberBuilder); + float number = ShortcutManager.getNumberKey(numberBuilder); Vector3f translation = currentAxis.mult(number); finalPosition = startPosition.add(translation); spatial.setLocalTranslation(finalPosition); diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/RotateShortcut.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/RotateShortcut.java index 1fb445b59..8b9ffe404 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/RotateShortcut.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/RotateShortcut.java @@ -95,7 +95,7 @@ public class RotateShortcut extends ShortcutTool { spatial.setLocalRotation(startRotation.clone()); } else if (axisChanged || numberChanged) { //update transformation - /* float number = ShortcutManager.getNumberkey(numberBuilder); + /* float number = ShortcutManager.getNumberKey(numberBuilder); Vector3f translation = currentAxis.mult(number); finalPosition = startPosition.add(translation); spatial.setLocalTranslation(finalPosition); diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ScaleShortcut.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ScaleShortcut.java index 21966e385..8fa18858f 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ScaleShortcut.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ScaleShortcut.java @@ -94,7 +94,7 @@ public class ScaleShortcut extends ShortcutTool { pickEnabled = false; } else if (axisChanged || numberChanged) { //update transformation - /* float number = ShortcutManager.getNumberkey(numberBuilder); + /* float number = ShortcutManager.getNumberKey(numberBuilder); Vector3f translation = currentAxis.mult(number); finalPosition = startPosition.add(translation); spatial.setLocalTranslation(finalPosition); diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java index 512e36e0c..187293e92 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/ShortcutManager.java @@ -38,10 +38,17 @@ public class ShortcutManager { /* Methodes */ + /** + * This MUST be called by the shortcut tool once the modifications are done. + */ public void terminate() { currentShortcut = null; } + /** + * + * @return true if a shortCutTool is active, else return false. + */ public boolean isActive() { return currentShortcut != null; } @@ -67,6 +74,12 @@ public class ShortcutManager { return altDown; } + /** + * Set the current shortcut to shortcut. cancel the current + * shortcut if it was still active + * + * @param shortcut the ShortCutTool to set + */ public void setShortCut(ShortcutTool shortcut) { if (isActive()) { currentShortcut.cancel(); @@ -74,10 +87,18 @@ public class ShortcutManager { currentShortcut = shortcut; } + /** + * Get the shortcut that can be enable with the given kei, the current + * shortcut cannot be enable twice. This also check for command key used to + * provide isCtrlDown(), isShiftDown() and isAltDown(). + * + * @param kie the KeyInputEvent + * @return the activable shortcut else return null + */ public ShortcutTool getActivableShortcut(KeyInputEvent kie) { if (checkCommandeKey(kie)) { return null; - } + } for (ShortcutTool s : shortcutList) { if (s != currentShortcut) { if (s.isActivableBy(kie)) { @@ -88,14 +109,30 @@ public class ShortcutManager { return null; } + /** + * + * @return the current active shortcut + */ public ShortcutTool getActiveShortcut() { return currentShortcut; } + /** + * + * @param kie the KeyInputEvent + * @return true if the given Kei can enable a sortcut, else false + */ public boolean canActivateShortcut(KeyInputEvent kie) { return getActivableShortcut(kie) != null; } + /** + * Set the current shortcut with the shortcut one that can be enable with + * the given key + * + * @param kie the KeyInputEvent + * @return true is the shortcut changed, else false + */ public boolean activateShortcut(KeyInputEvent kie) { ShortcutTool newShortcut = getActivableShortcut(kie); if (newShortcut != null) { @@ -106,8 +143,8 @@ public class ShortcutManager { /** * This should be called to trigger the currentShortcut.keyPressed() method. - * This method do a first check for command key used to provide isCtrlDown, - * isShiftDown ect.. to de + * This also check for command key used to provide isCtrlDown(), + * isShiftDown() and isAltDown(). * * @param kie */ @@ -136,6 +173,11 @@ public class ShortcutManager { /* STATIC */ + /** + * + * @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; @@ -143,6 +185,11 @@ public class ShortcutManager { return false; } + /** + * + * @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; @@ -150,6 +197,11 @@ public class ShortcutManager { return false; } + /** + * + * @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; @@ -157,6 +209,11 @@ public class ShortcutManager { return false; } + /** + * + * @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; @@ -164,6 +221,11 @@ public class ShortcutManager { return false; } + /** + * + * @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; @@ -171,6 +233,13 @@ public class ShortcutManager { return false; } + /** + * store the number kie into the numberBuilder + * + * @param kie + * @param numberBuilder + * @return true if the given kie is handled as a number key event + */ public static boolean checkNumberKey(KeyInputEvent kie, StringBuilder numberBuilder) { if (kie.getKeyCode() == KeyInput.KEY_MINUS) { if (numberBuilder.length() > 0) { @@ -228,7 +297,12 @@ public class ShortcutManager { return false; } - public static float getNumberkey(StringBuilder numberBuilder) { + /** + * + * @param numberBuilder the StringBuilder storing the float number + * @return the float value created from the given StringBuilder + */ + public static float getNumberKey(StringBuilder numberBuilder) { if (numberBuilder.length() == 0) { return 0; } else { @@ -236,6 +310,14 @@ public class ShortcutManager { } } + /** + * Check for axis input for key X,Y,Z and store the corresponding UNIT_ into + * the axisStore + * + * @param kie + * @param axisStore + * @return true if the given kie is handled as a Axis input + */ public static boolean checkAxisKey(KeyInputEvent kie, Vector3f axisStore) { if (kie.getKeyCode() == KeyInput.KEY_X) { axisStore.set(Vector3f.UNIT_X);