From 7beda908c1b1713d71f837b33545385db627e1fd Mon Sep 17 00:00:00 2001 From: "rem..om" Date: Mon, 30 Jul 2012 15:23:17 +0000 Subject: [PATCH] SDK : - Created a MoveManager than now handles move methods. - MoveTool and SelectTool now use the MoveManager. - Blender like move now use a camera aligned plane to move along so things are more "blenderish" - One can enter move/rotate/scale values with the numpad git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9604 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../SceneComposerToolController.java | 2 +- .../SceneComposerTopComponent.form | 10 +- .../SceneComposerTopComponent.java | 4 +- .../jme3/gde/scenecomposer/SceneEditTool.java | 89 ++++---- .../gde/scenecomposer/tools/MoveManager.java | 203 +++++++++++++++++ .../gde/scenecomposer/tools/MoveTool.java | 133 ++--------- .../gde/scenecomposer/tools/SelectTool.java | 207 +++++++----------- 7 files changed, 351 insertions(+), 297 deletions(-) create mode 100644 sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/MoveManager.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 49a2b5af5..5b4036f54 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerToolController.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerToolController.java @@ -48,7 +48,7 @@ public class SceneComposerToolController extends SceneToolController { private Material audioMarkerMaterial; private JmeSpatial selectedSpatial; private boolean snapToGrid = false; - private boolean snapToScene = true; + private boolean snapToScene = false; private boolean selectTerrain = false; public SceneComposerToolController(final Node toolsNode, AssetManager manager, JmeNode rootNode) { diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.form b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.form index 725e43c87..859e0c471 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.form +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.form @@ -620,7 +620,9 @@ - + + + @@ -634,6 +636,9 @@ + + + @@ -647,6 +652,9 @@ + + + diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.java index bca2a3e67..4364ae82c 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.java @@ -428,7 +428,7 @@ public final class SceneComposerTopComponent extends TopComponent implements Sce } }); - snapToSceneCheckbox.setSelected(true); + snapToSceneCheckbox.setBackground(new java.awt.Color(204, 204, 204)); org.openide.awt.Mnemonics.setLocalizedText(snapToSceneCheckbox, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.snapToSceneCheckbox.text")); // NOI18N snapToSceneCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.snapToSceneCheckbox.toolTipText")); // NOI18N snapToSceneCheckbox.addActionListener(new java.awt.event.ActionListener() { @@ -437,6 +437,7 @@ public final class SceneComposerTopComponent extends TopComponent implements Sce } }); + snapToGridCheckbox.setBackground(new java.awt.Color(204, 204, 204)); org.openide.awt.Mnemonics.setLocalizedText(snapToGridCheckbox, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.snapToGridCheckbox.text")); // NOI18N snapToGridCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.snapToGridCheckbox.toolTipText")); // NOI18N snapToGridCheckbox.addActionListener(new java.awt.event.ActionListener() { @@ -445,6 +446,7 @@ public final class SceneComposerTopComponent extends TopComponent implements Sce } }); + selectTerrainCheckbox.setBackground(new java.awt.Color(204, 204, 204)); org.openide.awt.Mnemonics.setLocalizedText(selectTerrainCheckbox, org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.selectTerrainCheckbox.text")); // NOI18N selectTerrainCheckbox.setToolTipText(org.openide.util.NbBundle.getMessage(SceneComposerTopComponent.class, "SceneComposerTopComponent.selectTerrainCheckbox.toolTipText")); // NOI18N selectTerrainCheckbox.addActionListener(new java.awt.event.ActionListener() { diff --git a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneEditTool.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneEditTool.java index e46e0cbdf..725e9f210 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneEditTool.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneEditTool.java @@ -6,14 +6,6 @@ package com.jme3.gde.scenecomposer; import com.jme3.asset.AssetManager; import com.jme3.bounding.BoundingBox; -import com.jme3.bounding.BoundingVolume; -import com.jme3.bullet.collision.PhysicsCollisionObject; -import com.jme3.bullet.control.CharacterControl; -import com.jme3.bullet.control.GhostControl; -import com.jme3.bullet.control.PhysicsControl; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.control.VehicleControl; -import com.jme3.bullet.util.DebugShapeFactory; import com.jme3.collision.CollisionResult; import com.jme3.collision.CollisionResults; import com.jme3.gde.core.scene.SceneApplication; @@ -27,19 +19,15 @@ import com.jme3.material.RenderState.BlendMode; import com.jme3.material.RenderState.FaceCullMode; import com.jme3.math.ColorRGBA; import com.jme3.math.FastMath; -import com.jme3.math.Matrix3f; import com.jme3.math.Quaternion; import com.jme3.math.Ray; -import com.jme3.math.Transform; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import com.jme3.renderer.Camera; import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.scene.debug.Arrow; -import com.jme3.scene.debug.WireBox; import com.jme3.scene.shape.Quad; import java.util.Iterator; import java.util.concurrent.Callable; @@ -136,7 +124,6 @@ public abstract class SceneEditTool { doUpdateToolsTransformation(); return null; } - }); } @@ -150,7 +137,7 @@ public abstract class SceneEditTool { axisMarker.setLocalRotation(Quaternion.IDENTITY); } } - + /** * Adjust the scale of the marker so it is relative to the size of the * selected spatial. It will have a minimum scale of 2. @@ -160,14 +147,14 @@ public abstract class SceneEditTool { if (selected.getWorldBound() instanceof BoundingBox) { BoundingBox bbox = (BoundingBox) selected.getWorldBound(); float smallest = Math.min(Math.min(bbox.getXExtent(), bbox.getYExtent()), bbox.getZExtent()); - float scale = Math.max(1, smallest/2f); - axisMarker.setLocalScale(new Vector3f(scale,scale,scale)); + float scale = Math.max(1, smallest / 2f); + axisMarker.setLocalScale(new Vector3f(scale, scale, scale)); } } else { - axisMarker.setLocalScale(new Vector3f(2,2,2)); + axisMarker.setLocalScale(new Vector3f(2, 2, 2)); } } - + /** * The primary action for the tool gets activated */ @@ -193,8 +180,9 @@ public abstract class SceneEditTool { */ public abstract void draggedSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject); - public void keyPressed(KeyInputEvent kie) {} - + public void keyPressed(KeyInputEvent kie) { + } + /** * Call when an action is performed that requires the scene to be saved * and an undo can be performed @@ -210,7 +198,7 @@ public abstract class SceneEditTool { * @param jmeRootNode to pick from * @return the selected spatial, or null if nothing */ - protected Spatial pickWorldSpatial(Camera cam, Vector2f mouseLoc, JmeNode jmeRootNode) { + public static Spatial pickWorldSpatial(Camera cam, Vector2f mouseLoc, JmeNode jmeRootNode) { Node rootNode = jmeRootNode.getLookup().lookup(Node.class); CollisionResult cr = pick(cam, mouseLoc, rootNode); if (cr != null) { @@ -226,24 +214,22 @@ public abstract class SceneEditTool { * @param jmeRootNode to pick from * @return the location of the pick, or null if nothing collided with the mouse */ - protected Vector3f pickWorldLocation(Camera cam, Vector2f mouseLoc, JmeNode jmeRootNode) { + public static Vector3f pickWorldLocation(Camera cam, Vector2f mouseLoc, JmeNode jmeRootNode) { Node rootNode = jmeRootNode.getLookup().lookup(Node.class); return pickWorldLocation(cam, mouseLoc, rootNode, null); } - + /** * Pick anything except the excluded spatial * @param excludeSpat to not pick */ - protected Vector3f pickWorldLocation(Camera cam, Vector2f mouseLoc, JmeNode jmeRootNode, JmeSpatial excludeSpat) { + public static Vector3f pickWorldLocation(Camera cam, Vector2f mouseLoc, JmeNode jmeRootNode, JmeSpatial excludeSpat) { Node rootNode = jmeRootNode.getLookup().lookup(Node.class); - return pickWorldLocation(cam, mouseLoc, rootNode, excludeSpat); + Spatial exclude = excludeSpat.getLookup().lookup(Spatial.class); + return pickWorldLocation(cam, mouseLoc, rootNode, exclude); } - protected Vector3f pickWorldLocation(Camera cam, Vector2f mouseLoc, Node rootNode, JmeSpatial excludeSpat) { - Spatial exclude = null; - if (excludeSpat != null) - exclude = excludeSpat.getLookup().lookup(Spatial.class); + public static Vector3f pickWorldLocation(Camera cam, Vector2f mouseLoc, Node rootNode, Spatial exclude) { CollisionResult cr = doPick(cam, mouseLoc, rootNode, exclude); if (cr != null) { return cr.getContactPoint(); @@ -252,46 +238,48 @@ public abstract class SceneEditTool { } } - private CollisionResult doPick(Camera cam, Vector2f mouseLoc, Node node, Spatial exclude) { + private static CollisionResult doPick(Camera cam, Vector2f mouseLoc, Node node, Spatial exclude) { CollisionResults results = new CollisionResults(); Ray ray = new Ray(); Vector3f pos = cam.getWorldCoordinates(mouseLoc, 0).clone(); - Vector3f dir = cam.getWorldCoordinates(mouseLoc, 0.1f).clone(); + Vector3f dir = cam.getWorldCoordinates(mouseLoc, 0.3f).clone(); dir.subtractLocal(pos).normalizeLocal(); ray.setOrigin(pos); ray.setDirection(dir); node.collideWith(ray, results); CollisionResult result = null; - if (exclude == null) + if (exclude == null) { result = results.getClosestCollision(); - else { + } else { Iterator it = results.iterator(); while (it.hasNext()) { CollisionResult cr = it.next(); - if (isExcluded(cr.getGeometry(), exclude)) + if (isExcluded(cr.getGeometry(), exclude)) { continue; - else + } else { return cr; + } } - + } return result; } - + /** * Is the selected spatial the one we want to exclude from the picking? * Recursively looks up the parents to find out. */ - private boolean isExcluded(Spatial s, Spatial exclude) { - if (s.equals(exclude)) + private static boolean isExcluded(Spatial s, Spatial exclude) { + if (s.equals(exclude)) { return true; - + } + if (s.getParent() != null) { return isExcluded(s.getParent(), exclude); } return false; } - + /** * Pick a part of the axis marker. The result is a Vector3f that represents * what part of the axis was selected. @@ -344,7 +332,7 @@ public abstract class SceneEditTool { return null; } - private CollisionResult pick(Camera cam, Vector2f mouseLoc, Node node) { + private static CollisionResult pick(Camera cam, Vector2f mouseLoc, Node node) { CollisionResults results = new CollisionResults(); Ray ray = new Ray(); Vector3f pos = cam.getWorldCoordinates(mouseLoc, 0).clone(); @@ -364,7 +352,7 @@ public abstract class SceneEditTool { protected void highlightAxisMarker(Camera camera, Vector2f screenCoord, AxisMarkerPickType axisMarkerPickType) { highlightAxisMarker(camera, screenCoord, axisMarkerPickType, false); } - + /** * Show what axis or plane the mouse is currently over and will affect. * @param axisMarkerPickType @@ -379,20 +367,18 @@ public abstract class SceneEditTool { if (picked == ARROW_X) { axisMarker.getChild("arrowX").setMaterial(orangeMat); - } - else if (picked == ARROW_Y) { + } else if (picked == ARROW_Y) { axisMarker.getChild("arrowY").setMaterial(orangeMat); - } - else if (picked == ARROW_Z) { + } else if (picked == ARROW_Z) { axisMarker.getChild("arrowZ").setMaterial(orangeMat); - } - + } + if (picked == QUAD_XY || colorAll) { axisMarker.getChild("quadXY").setMaterial(orangeMat); - } + } if (picked == QUAD_XZ || colorAll) { axisMarker.getChild("quadXZ").setMaterial(orangeMat); - } + } if (picked == QUAD_YZ || colorAll) { axisMarker.getChild("quadYZ").setMaterial(orangeMat); } @@ -492,7 +478,6 @@ public abstract class SceneEditTool { quadYZ.setMaterial(cyanMat); } - public Camera getCamera() { return camera; } 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 new file mode 100644 index 000000000..1c0f2db9c --- /dev/null +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/MoveManager.java @@ -0,0 +1,203 @@ +/* + * 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.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/MoveTool.java b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/MoveTool.java index d05391a12..97f48cc9f 100644 --- a/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/MoveTool.java +++ b/sdk/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/MoveTool.java @@ -5,23 +5,16 @@ package com.jme3.gde.scenecomposer.tools; 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.SceneEditTool; -import com.jme3.material.Material; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; import com.jme3.scene.Node; import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Quad; import org.openide.loaders.DataObject; +import org.openide.util.Lookup; /** * Move an object. @@ -35,35 +28,19 @@ import org.openide.loaders.DataObject; public class MoveTool extends SceneEditTool { private Vector3f pickedPlane; - private Vector3f startLoc = new Vector3f(); - private Vector3f lastLoc = new Vector3f(); private boolean wasDragging = false; - private Vector3f offset; - private Node plane; - Material pinkMat; - private final Quaternion XY = new Quaternion().fromAngleAxis(0, new Vector3f(1, 0, 0)); - private final Quaternion YZ = new Quaternion().fromAngleAxis(-FastMath.PI / 2, new Vector3f(0, 1, 0)); - private 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(); + private MoveManager moveManager; public MoveTool() { axisPickType = AxisMarkerPickType.axisAndPlane; setOverrideCameraControl(true); - 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); - - } @Override public void activate(AssetManager manager, Node toolNode, Node onTopToolNode, Spatial selectedSpatial, SceneComposerToolController toolController) { super.activate(manager, toolNode, onTopToolNode, selectedSpatial, toolController); + moveManager = Lookup.getDefault().lookup(MoveManager.class); displayPlanes(); } @@ -72,11 +49,11 @@ public class MoveTool extends SceneEditTool { if (!pressed) { setDefaultAxisMarkerColors(); pickedPlane = null; // mouse released, reset selection - offset = null; if (wasDragging) { - actionPerformed(new MoveUndo(toolController.getSelectedSpatial(), startLoc, lastLoc)); + actionPerformed(moveManager.makeUndo()); wasDragging = false; } + moveManager.reset(); } } @@ -86,11 +63,12 @@ public class MoveTool extends SceneEditTool { @Override public void mouseMoved(Vector2f screenCoord, JmeNode rootNode, DataObject currentDataObject, JmeSpatial selectedSpatial) { + if (pickedPlane == null) { highlightAxisMarker(camera, screenCoord, axisPickType); } else { pickedPlane = null; - offset = null; + moveManager.reset(); } } @@ -99,11 +77,11 @@ public class MoveTool extends SceneEditTool { if (!pressed) { setDefaultAxisMarkerColors(); pickedPlane = null; // mouse released, reset selection - offset = null; if (wasDragging) { - actionPerformed(new MoveUndo(toolController.getSelectedSpatial(), startLoc, lastLoc)); + actionPerformed(moveManager.makeUndo()); wasDragging = false; } + moveManager.reset(); return; } @@ -116,61 +94,18 @@ public class MoveTool extends SceneEditTool { if (pickedPlane == null) { return; } - startLoc = toolController.getSelectedSpatial().getLocalTranslation().clone(); - rot = rot.set(toolController.getSelectedSpatial().getWorldRotation()); + if (pickedPlane.equals(new Vector3f(1, 1, 0))) { - plane.setLocalRotation(rot.multLocal(XY)); + moveManager.initiateMove(toolController.getSelectedSpatial(), MoveManager.XY, true); } else if (pickedPlane.equals(new Vector3f(1, 0, 1))) { - plane.setLocalRotation(rot.multLocal(XZ)); + moveManager.initiateMove(toolController.getSelectedSpatial(), MoveManager.XZ, true); } else if (pickedPlane.equals(new Vector3f(0, 1, 1))) { - plane.setLocalRotation(rot.multLocal(YZ)); + moveManager.initiateMove(toolController.getSelectedSpatial(), MoveManager.YZ, true); } - plane.setLocalTranslation(startLoc); } - - Vector3f planeHit = pickWorldLocation(camera, screenCoord, plane, null); - if (planeHit == null) { + if (!moveManager.move(camera, screenCoord)) { return; } - - Spatial selected = toolController.getSelectedSpatial(); - Spatial parent = selected.getParent(); - - - if (parent == null) { - //we are moving the root node, move is computed in local translation - if (offset == null) { - offset = planeHit.subtract(startLoc); // get the offset when we start so it doesn't jump - } - - newPos.set(planeHit).subtractLocal(offset); - lastLoc.set(newPos); - selected.setLocalTranslation(newPos); - } else { - - //offset in world space - if (offset == null) { - offset = planeHit.subtract(selected.getWorldTranslation()); // get the offset when we start so it doesn't jump - } - - newPos = planeHit.subtract(offset); - - //computing the inverse world transform to get the new localtranslation - newPos.subtractLocal(selected.getParent().getWorldTranslation()); - newPos = selected.getParent().getWorldRotation().inverse().normalizeLocal().multLocal(newPos); - newPos.divideLocal(selected.getWorldScale()); - selected.setLocalTranslation(newPos); - lastLoc.set(newPos); - } - - RigidBodyControl control = toolController.getSelectedSpatial().getControl(RigidBodyControl.class); - if (control != null) { - control.setPhysicsLocation(toolController.getSelectedSpatial().getWorldTranslation()); - } - CharacterControl character = toolController.getSelectedSpatial().getControl(CharacterControl.class); - if (character != null) { - character.setPhysicsLocation(toolController.getSelectedSpatial().getWorldTranslation()); - } updateToolsTransformation(); wasDragging = true; @@ -179,44 +114,4 @@ public class MoveTool extends SceneEditTool { @Override public void draggedSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) { } - - private class MoveUndo extends AbstractUndoableSceneEdit { - - private Spatial spatial; - private Vector3f before, after; - - MoveUndo(Spatial spatial, Vector3f before, Vector3f after) { - this.spatial = spatial; - this.before = before; - this.after = after; - } - - @Override - public void sceneUndo() { - spatial.setLocalTranslation(before); - RigidBodyControl control = toolController.getSelectedSpatial().getControl(RigidBodyControl.class); - if (control != null) { - control.setPhysicsLocation(toolController.getSelectedSpatial().getWorldTranslation()); - } - CharacterControl character = toolController.getSelectedSpatial().getControl(CharacterControl.class); - if (character != null) { - character.setPhysicsLocation(toolController.getSelectedSpatial().getWorldTranslation()); - } - toolController.selectedSpatialTransformed(); - } - - @Override - public void sceneRedo() { - spatial.setLocalTranslation(after); - RigidBodyControl control = toolController.getSelectedSpatial().getControl(RigidBodyControl.class); - if (control != null) { - control.setPhysicsLocation(toolController.getSelectedSpatial().getWorldTranslation()); - } - CharacterControl character = toolController.getSelectedSpatial().getControl(CharacterControl.class); - if (character != null) { - character.setPhysicsLocation(toolController.getSelectedSpatial().getWorldTranslation()); - } - toolController.selectedSpatialTransformed(); - } - } } 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 f70034c22..b3ba5493b 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 @@ -13,16 +13,14 @@ 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.Matrix3f; 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 java.util.logging.Level; -import java.util.logging.Logger; import org.openide.loaders.DataObject; +import org.openide.util.Lookup; /** * This duplicates the Blender manipulate tool. @@ -50,8 +48,8 @@ public class SelectTool extends SceneEditTool { private enum State {translate, rotate, scale}; private State currentState = null; - private enum Axis {x, y, z}; - private Axis currentAxis = null; + + private Vector3f currentAxis = Vector3f.UNIT_XYZ; private StringBuilder numberBuilder = new StringBuilder(); // gets appended with numbers @@ -66,7 +64,7 @@ public class SelectTool extends SceneEditTool { private boolean shiftDown = false; private boolean altDown = false; - private MoveUndo moving; + private MoveManager.MoveUndo moving; private ScaleUndo scaling; private RotateUndo rotating; private Vector2f startMouseCoord; // for scaling and rotation @@ -111,7 +109,7 @@ public class SelectTool extends SceneEditTool { return; // commands take priority if (stateChange) { - currentAxis = null; + currentAxis = Vector3f.UNIT_XYZ; numberBuilder = new StringBuilder(); recordInitialState(selected); } @@ -161,7 +159,7 @@ public class SelectTool extends SceneEditTool { selected.setLocalScale(startScale); } currentState = null; - currentAxis = null; + currentAxis = Vector3f.UNIT_XYZ; numberBuilder = new StringBuilder(); startRot = null; startTrans = null; @@ -192,26 +190,20 @@ public class SelectTool extends SceneEditTool { } if (currentState == State.translate) { - float x = 0, y= 0, z = 0; - if (currentAxis == Axis.x) - x = value; - else if (currentAxis == Axis.y) - y = value; - else if (currentAxis == Axis.z) - z = value; - Vector3f before = selected.getLocalTranslation().clone(); - Vector3f after = selected.getLocalTranslation().addLocal(x, y, z); - selected.setLocalTranslation(after); - actionPerformed(new MoveUndo(selected, before, after)); + 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 == Axis.x) + if (currentAxis == Vector3f.UNIT_X) x = value; - else if (currentAxis == Axis.y) + else if (currentAxis == Vector3f.UNIT_Y) y = value; - else if (currentAxis == Axis.z) + else if (currentAxis == Vector3f.UNIT_Z) z = value; - else if (currentAxis == null) { + else if (currentAxis == Vector3f.UNIT_XYZ) { x = value; y = value; z = value; @@ -222,11 +214,11 @@ public class SelectTool extends SceneEditTool { actionPerformed(new ScaleUndo(selected, before, after)); } else if (currentState == State.rotate) { float x = 0, y= 0, z = 0; - if (currentAxis == Axis.x) + if (currentAxis == Vector3f.UNIT_X) x = 1; - else if (currentAxis == Axis.y) + else if (currentAxis == Vector3f.UNIT_Y) y = 1; - else if (currentAxis == Axis.z) + else if (currentAxis == Vector3f.UNIT_Z) z = 1; Vector3f axis = new Vector3f(x,y,z); Quaternion initialRot = selected.getLocalRotation().clone(); @@ -238,6 +230,7 @@ public class SelectTool extends SceneEditTool { toolController.updateSelection(null);// force a re-draw of the bbox shape toolController.updateSelection(selected); } + clearState(false); } private void checkModificatorKeys(KeyInputEvent kie) { @@ -271,6 +264,11 @@ public class SelectTool extends SceneEditTool { private boolean checkStateKey(KeyInputEvent kie) { if (kie.getKeyCode() == KeyInput.KEY_G) { 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) { currentState = State.rotate; @@ -284,13 +282,40 @@ public class SelectTool extends SceneEditTool { private boolean checkAxisKey(KeyInputEvent kie) { if (kie.getKeyCode() == KeyInput.KEY_X) { - currentAxis = Axis.x; + currentAxis = Vector3f.UNIT_X; + 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(MoveManager.XY)