- 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 keyexperimental
parent
e9b1972aca
commit
bbca035a43
@ -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); |
||||
} |
||||
} |
||||
} |
@ -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(); |
||||
} |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue