You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
161 lines
5.2 KiB
161 lines
5.2 KiB
14 years ago
|
/*
|
||
|
* To change this template, choose Tools | Templates
|
||
|
* and open the template in the editor.
|
||
|
*/
|
||
|
package com.jme3.gde.scenecomposer.tools;
|
||
|
|
||
|
import com.jme3.gde.core.sceneexplorer.nodes.JmeNode;
|
||
|
import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit;
|
||
|
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;
|
||
|
|
||
|
/**
|
||
|
* Move an object.
|
||
|
* When created, it generates a quad that will lie along a plane
|
||
|
* that the user selects for moving on. When the mouse is over
|
||
|
* the axisMarker, it will highlight the plane that it is over: XY,XZ,YZ.
|
||
|
* When clicked and then dragged, the selected object will move along that
|
||
|
* plane.
|
||
|
* @author Brent Owens
|
||
|
*/
|
||
|
public class MoveTool extends SceneEditTool {
|
||
|
|
||
|
private Vector3f pickedPlane;
|
||
|
private Vector3f startLoc;
|
||
|
private Vector3f lastLoc;
|
||
|
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));
|
||
|
|
||
|
|
||
|
public MoveTool() {
|
||
|
axisPickType = AxisMarkerPickType.planeOnly;
|
||
|
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 actionPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) {
|
||
|
if (!pressed) {
|
||
|
setDefaultAxisMarkerColors();
|
||
|
pickedPlane = null; // mouse released, reset selection
|
||
|
offset = null;
|
||
|
if (wasDragging) {
|
||
|
actionPerformed(new MoveUndo(selectedSpatial, startLoc, lastLoc));
|
||
|
wasDragging = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void actionSecondary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject dataObject) {
|
||
|
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void mouseMoved(Vector2f screenCoord) {
|
||
|
if (pickedPlane == null) {
|
||
|
highlightAxisMarker(camera, screenCoord, axisPickType);
|
||
|
}
|
||
|
else {
|
||
|
pickedPlane = null;
|
||
|
offset = null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void draggedPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) {
|
||
|
if (!pressed) {
|
||
|
setDefaultAxisMarkerColors();
|
||
|
pickedPlane = null; // mouse released, reset selection
|
||
|
offset = null;
|
||
|
if (wasDragging) {
|
||
|
actionPerformed(new MoveUndo(selectedSpatial, startLoc, lastLoc));
|
||
|
wasDragging = false;
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (selectedSpatial == null)
|
||
|
return;
|
||
|
if (pickedPlane == null) {
|
||
|
pickedPlane = pickAxisMarker(camera, screenCoord, axisPickType);
|
||
|
if (pickedPlane == null)
|
||
|
return;
|
||
|
startLoc = selectedSpatial.getLocalTranslation().clone();
|
||
|
|
||
|
if (pickedPlane.equals(new Vector3f(1,1,0)))
|
||
|
plane.setLocalRotation(XY);
|
||
|
else if (pickedPlane.equals(new Vector3f(1,0,1)))
|
||
|
plane.setLocalRotation(XZ);
|
||
|
else if (pickedPlane.equals(new Vector3f(0,1,1)))
|
||
|
plane.setLocalRotation(YZ);
|
||
|
plane.setLocalTranslation(startLoc);
|
||
|
}
|
||
|
|
||
|
Vector3f planeHit = pickWorldLocation(camera, screenCoord, plane);
|
||
|
if (planeHit == null)
|
||
|
return;
|
||
|
|
||
|
if (offset == null)
|
||
|
offset = planeHit.subtract(startLoc); // get the offset when we start so it doesn't jump
|
||
|
|
||
|
Vector3f newPos = planeHit.subtract(offset);
|
||
|
lastLoc = newPos;
|
||
|
selectedSpatial.setLocalTranslation(newPos);
|
||
|
updateToolsTransformation(selectedSpatial);
|
||
|
|
||
|
wasDragging = true;
|
||
|
}
|
||
|
|
||
|
@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);
|
||
|
toolController.selectedSpatialTransformed();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void sceneRedo() {
|
||
|
spatial.setLocalTranslation(after);
|
||
|
toolController.selectedSpatialTransformed();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|