org.fxyz3d.utils.Transformable Maven / Gradle / Ivy
The newest version!
/**
* Transformable.java
*
* Copyright (c) 2013-2016, F(X)yz
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of F(X)yz, any associated website, nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL F(X)yz BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.fxyz3d.utils;
import javafx.geometry.Point3D;
import javafx.scene.Node;
import javafx.scene.transform.Affine;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Scale;
import javafx.scene.transform.Transform;
import javafx.scene.transform.Translate;
import javafx.util.Callback;
import org.fxyz3d.geometry.Vector3D;
/**
* An Interface implementation of Xform found in the Molecule Sample
*
* @author Dub
* @param Node type to be used
*/
public interface Transformable {
public enum RotateOrder {
XYZ,
XZY,
YXZ,
YZX,
ZXY,
ZYX,
USE_AFFINE;
private RotateOrder() {
}
}
// Simple Transforms
//Rotates
public Rotate
rotateX = new Rotate(0.0, Rotate.X_AXIS),
rotateY = new Rotate(0.0, Rotate.Y_AXIS),
rotateZ = new Rotate(0.0, Rotate.Z_AXIS);
public default void setRotate(double x, double y, double z) {
rotateX.setAngle(x);
rotateY.setAngle(y);
rotateZ.setAngle(z);
}
public default void setRotateX(double x) { rotateX.setAngle(x); }
public default void setRotateY(double y) { rotateY.setAngle(y); }
public default void setRotateZ(double z) { rotateZ.setAngle(z); }
// Translates
public Translate
t = new Translate(),
p = new Translate(),
ip = new Translate();
public default void setTx(double x) { t.setX(x); }
public default void setTy(double y) { t.setY(y); }
public default void setTz(double z) { t.setZ(z); }
public default double getTx() { return t.getX(); }
public default double getTy() { return t.getY(); }
public default double getTz() { return t.getZ(); }
// Scale
public Scale s = new Scale();
public default void setScale(double scaleFactor) {
s.setX(scaleFactor);
s.setY(scaleFactor);
s.setZ(scaleFactor);
}
public default void setScale(double x, double y, double z) {
s.setX(x);
s.setY(y);
s.setZ(z);
}
// Transform methods
public default void setPivot(double x, double y, double z) {
p.setX(x);
p.setY(y);
p.setZ(z);
ip.setX(-x);
ip.setY(-y);
ip.setZ(-z);
}
//advanced transform
public Affine affine = new Affine();
//Vectors: fwd, right, up Point3D: pos
//Forward / look direction
Callback forwardDirCallback = (a) -> {
return new Vector3D(a.getMzx(), a.getMzy(), a.getMzz());
};
Callback forwardMatrixRowCallback = (a) -> {
return new Vector3D(a.getMxz(), a.getMyz(), a.getMzz());
};
// up direction
Callback upDirCallback = (a) -> {
return new Vector3D(a.getMyx(), a.getMyy(), a.getMyz());
};
Callback upMatrixRowCallback = (a) -> {
return new Vector3D(a.getMxy(), a.getMyy(), a.getMzy());
};
// right direction
Callback rightDirCallback = (a) -> {
return new Vector3D(a.getMxx(), a.getMxy(), a.getMxz());
};
Callback rightMatrixRowCallback = (a) -> {
return new Vector3D(a.getMxx(), a.getMyx(), a.getMzx());
};
//position
Callback positionCallback = (a) ->{
return new Point3D(a.getTx(), a.getTy(), a.getTz());
};
default Vector3D getForwardDirection(){
return forwardDirCallback.call(getTransformableNode().getLocalToSceneTransform());
}
default Vector3D getForwardMatrixRow(){
return forwardMatrixRowCallback.call(getTransformableNode().getLocalToSceneTransform());
}
default Vector3D getRightDirection(){
return rightDirCallback.call(getTransformableNode().getLocalToSceneTransform());
}
default Vector3D getRightMatrixRow(){
return rightMatrixRowCallback.call(getTransformableNode().getLocalToSceneTransform());
}
default Vector3D getUpDirection(){
return upDirCallback.call(getTransformableNode().getLocalToSceneTransform());
}
default Vector3D getUpMatrixRow(){
return upMatrixRowCallback.call(getTransformableNode().getLocalToSceneTransform());
}
default Point3D getPosition(){
return positionCallback.call(getTransformableNode().getLocalToSceneTransform());
}
public default void reset() {
t.setX(0.0);
t.setY(0.0);
t.setZ(0.0);
rotateX.setAngle(0.0);
rotateY.setAngle(0.0);
rotateZ.setAngle(0.0);
s.setX(1.0);
s.setY(1.0);
s.setZ(1.0);
p.setX(0.0);
p.setY(0.0);
p.setZ(0.0);
ip.setX(0.0);
ip.setY(0.0);
ip.setZ(0.0);
affine.setMxx(1);
affine.setMxy(0);
affine.setMxz(0);
affine.setMyx(0);
affine.setMyy(1);
affine.setMyz(0);
affine.setMzx(0);
affine.setMzy(0);
affine.setMzz(1);
}
public default void resetTSP() {
t.setX(0.0);
t.setY(0.0);
t.setZ(0.0);
s.setX(1.0);
s.setY(1.0);
s.setZ(1.0);
p.setX(0.0);
p.setY(0.0);
p.setZ(0.0);
ip.setX(0.0);
ip.setY(0.0);
ip.setZ(0.0);
}
public default void debug() {
System.out.println("t = (" +
t.getX() + ", " +
t.getY() + ", " +
t.getZ() + ") " +
"r = (" +
rotateX.getAngle() + ", " +
rotateY.getAngle() + ", " +
rotateZ.getAngle() + ") " +
"s = (" +
s.getX() + ", " +
s.getY() + ", " +
s.getZ() + ") " +
"p = (" +
p.getX() + ", " +
p.getY() + ", " +
p.getZ() + ") " +
"ip = (" +
ip.getX() + ", " +
ip.getY() + ", " +
ip.getZ() + ")" +
"affine = " + affine);
}
/**
* Toggle Transforms on / off
* @param b
*/
default void enableTransforms(boolean b) {
// if true, check if node is a camera
if (b) {
if (getRotateOrder() != null) {
switch (getRotateOrder()) {
case XYZ:
getTransformableNode().getTransforms().addAll(t, p, rotateZ, rotateY, rotateX, s, ip);
break;
case XZY:
getTransformableNode().getTransforms().addAll(t, p, rotateY, rotateZ, rotateX, s, ip);
break;
case YXZ:
getTransformableNode().getTransforms().addAll(t, p, rotateZ, rotateX, rotateY, s, ip);
break;
case YZX:
getTransformableNode().getTransforms().addAll(t, p, rotateX, rotateZ, rotateY, s, ip);
break;
case ZXY:
getTransformableNode().getTransforms().addAll(t, p, rotateY, rotateX, rotateZ, s, ip);
break;
case ZYX:
getTransformableNode().getTransforms().addAll(t, p, rotateX, rotateY, rotateZ, s, ip);
break;
case USE_AFFINE:
getTransformableNode().getTransforms().addAll(affine);
break;
}
}
// if false clear transforms from Node.
} else if(!b){
getTransformableNode().getTransforms().clear();
reset();
}
}
public default void initialize(){
if(getTransformableNode() != null){
enableTransforms(true);
}
}
public T getTransformableNode();
public RotateOrder getRotateOrder();
}