Merge pull request #263 from Dokthar/scenecomposer/master
SDK SceneComposer - 3D scale and rotate toolexperimental
commit
fec5764c34
@ -0,0 +1,182 @@ |
|||||||
|
/* |
||||||
|
* 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; |
||||||
|
|
||||||
|
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 dokthar |
||||||
|
*/ |
||||||
|
@ServiceProvider(service = PickManager.class) |
||||||
|
public class PickManager { |
||||||
|
|
||||||
|
private Vector3f startPickLoc; |
||||||
|
private Vector3f finalPickLoc; |
||||||
|
private Vector3f startSpatialLocation; |
||||||
|
private Quaternion origineRotation; |
||||||
|
private final Node plane; |
||||||
|
private Spatial spatial; |
||||||
|
|
||||||
|
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 enum TransformationType { |
||||||
|
|
||||||
|
local, global, camera |
||||||
|
} |
||||||
|
|
||||||
|
public PickManager() { |
||||||
|
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 void reset() { |
||||||
|
startPickLoc = null; |
||||||
|
finalPickLoc = null; |
||||||
|
startSpatialLocation = null; |
||||||
|
spatial = null; |
||||||
|
} |
||||||
|
|
||||||
|
public void initiatePick(Spatial selectedSpatial, Quaternion planeRotation, TransformationType type, Camera camera, Vector2f screenCoord) { |
||||||
|
spatial = selectedSpatial; |
||||||
|
startSpatialLocation = selectedSpatial.getWorldTranslation().clone(); |
||||||
|
|
||||||
|
setTransformation(planeRotation, type); |
||||||
|
plane.setLocalTranslation(startSpatialLocation); |
||||||
|
|
||||||
|
startPickLoc = SceneEditTool.pickWorldLocation(camera, screenCoord, plane, null); |
||||||
|
} |
||||||
|
|
||||||
|
public void setTransformation(Quaternion planeRotation, TransformationType type) { |
||||||
|
Quaternion rot = new Quaternion(); |
||||||
|
if (type == TransformationType.local) { |
||||||
|
rot.set(spatial.getWorldRotation()); |
||||||
|
rot.multLocal(planeRotation); |
||||||
|
origineRotation = spatial.getWorldRotation().clone(); |
||||||
|
} else if (type == TransformationType.global) { |
||||||
|
rot.set(planeRotation); |
||||||
|
origineRotation = new Quaternion(Quaternion.IDENTITY); |
||||||
|
} else if (type == TransformationType.camera) { |
||||||
|
rot.set(planeRotation); |
||||||
|
origineRotation = planeRotation.clone(); |
||||||
|
} |
||||||
|
plane.setLocalRotation(rot); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean updatePick(Camera camera, Vector2f screenCoord) { |
||||||
|
finalPickLoc = SceneEditTool.pickWorldLocation(camera, screenCoord, plane, null); |
||||||
|
return finalPickLoc != null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @return the start location in WorldSpace |
||||||
|
*/ |
||||||
|
public Vector3f getStartLocation() { |
||||||
|
return startSpatialLocation; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @return the vector from the tool origin to the start location, in |
||||||
|
* WorldSpace |
||||||
|
*/ |
||||||
|
public Vector3f getStartOffset() { |
||||||
|
return startPickLoc.subtract(startSpatialLocation); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @return the vector from the tool origin to the final location, in |
||||||
|
* WorldSpace |
||||||
|
*/ |
||||||
|
public Vector3f getFinalOffset() { |
||||||
|
return finalPickLoc.subtract(startSpatialLocation); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @return the angle between the start location and the final location |
||||||
|
*/ |
||||||
|
public float getAngle() { |
||||||
|
Vector3f v1, v2; |
||||||
|
v1 = startPickLoc.subtract(startSpatialLocation); |
||||||
|
v2 = finalPickLoc.subtract(startSpatialLocation); |
||||||
|
return v1.angleBetween(v2); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @return the Quaternion rotation in the WorldSpace |
||||||
|
*/ |
||||||
|
public Quaternion getRotation() { |
||||||
|
Vector3f v1, v2; |
||||||
|
v1 = startPickLoc.subtract(startSpatialLocation).normalize(); |
||||||
|
v2 = finalPickLoc.subtract(startSpatialLocation).normalize(); |
||||||
|
Vector3f axis = v1.cross(v2); |
||||||
|
float angle = v1.angleBetween(v2); |
||||||
|
return new Quaternion().fromAngleAxis(angle, axis); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @return the Quaternion rotation in the ToolSpace |
||||||
|
*/ |
||||||
|
public Quaternion getLocalRotation() { |
||||||
|
Vector3f v1, v2; |
||||||
|
Quaternion rot = origineRotation.inverse(); |
||||||
|
v1 = rot.mult(startPickLoc.subtract(startSpatialLocation).normalize()); |
||||||
|
v2 = rot.mult(finalPickLoc.subtract(startSpatialLocation).normalize()); |
||||||
|
Vector3f axis = v1.cross(v2); |
||||||
|
float angle = v1.angleBetween(v2); |
||||||
|
return new Quaternion().fromAngleAxis(angle, axis); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @return the translation in WorldSpace |
||||||
|
*/ |
||||||
|
public Vector3f getTranslation() { |
||||||
|
return finalPickLoc.subtract(startPickLoc); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @param axisConstrainte |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Vector3f getTranslation(Vector3f axisConstrainte) { |
||||||
|
Vector3f localConstrainte = (origineRotation.mult(axisConstrainte)).normalize(); // according to the "plane" rotation
|
||||||
|
Vector3f constrainedTranslation = localConstrainte.mult(getTranslation().dot(localConstrainte)); |
||||||
|
return constrainedTranslation; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @param axisConstrainte |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Vector3f getLocalTranslation(Vector3f axisConstrainte) { |
||||||
|
//return plane.getWorldRotation().inverse().mult(getTranslation(axisConstrainte));
|
||||||
|
return getTranslation(origineRotation.inverse().mult(axisConstrainte)); |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue