下面列出了怎么用javafx.scene.transform.Affine的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public Viewer3DConfig deserialize(
final JsonElement json,
final Type typeOfT,
final JsonDeserializationContext context) throws JsonParseException {
final Viewer3DConfig config = new Viewer3DConfig();
final JsonObject map = json.getAsJsonObject();
if (map.has(AFFINE_KEY))
config.setAffine(context.deserialize(map.get(AFFINE_KEY), Affine.class));
if (map.has(ARE_MESHES_ENABLED_KEY))
config.areMeshesEnabledProperty().set(map.get(ARE_MESHES_ENABLED_KEY).getAsBoolean());
if (map.has(BACKGROUND_KEY))
config.backgroundColorProperty().set(Color.web(map.get(BACKGROUND_KEY).getAsString()));
if (map.has(SHOW_BLOCK_BOUNDARIES_KEY))
config.showBlockBoundariesProperty().set(map.get(SHOW_BLOCK_BOUNDARIES_KEY).getAsBoolean());
if (map.has(RENDERER_BLOCK_SIZE_KEY))
config.rendererBlockSizeProperty().set(map.get(RENDERER_BLOCK_SIZE_KEY).getAsInt());
if (map.has(NUM_ELEMENTS_PER_FRAME_KEY))
config.numElementsPerFrameProperty().set(map.get(NUM_ELEMENTS_PER_FRAME_KEY).getAsInt());
if (map.has(FRAME_DELAY_MSEC_KEY))
config.frameDelayMsecProperty().set(map.get(FRAME_DELAY_MSEC_KEY).getAsLong());
if (map.has(SCENE_UPDATE_DELAY_MSEC_KEY))
config.sceneUpdateDelayMsecProperty().set(map.get(SCENE_UPDATE_DELAY_MSEC_KEY).getAsLong());
return config;
}
@Override
public void drag(final javafx.scene.input.MouseEvent event)
{
synchronized (getTransformLock())
{
LOG.trace("drag - rotate");
final Affine target = new Affine(affineDragStart);
final double dX = event.getX() - getStartX();
final double dY = event.getY() - getStartY();
final double v = step * this.speed.get();
LOG.trace("dx: {} dy: {}", dX, dY);
target.prependRotation(v * dY, CENTER_X, CENTER_Y, 0, xNormal);
target.prependRotation(v * -dX, CENTER_X, CENTER_Y, 0, yNormal);
LOG.trace("target: {}", target);
InvokeOnJavaFXApplicationThread.invoke(() -> setAffine(target));
}
}
@Override
public void drag(final MouseEvent event)
{
synchronized (getTransformLock())
{
LOG.trace("drag - translate");
final double dX = event.getX() - getStartX();
final double dY = event.getY() - getStartY();
LOG.trace("dx " + dX + " dy: " + dY);
final Affine target = affine.clone();
target.prependTranslation(2 * dX / viewer.getHeight(), 2 * dY / viewer.getHeight());
InvokeOnJavaFXApplicationThread.invoke(() -> setAffine(target));
setStartX(getStartX() + dX);
setStartY(getStartY() + dY);
}
}
public void setAffine(final Affine affine, final Duration duration) {
if (duration.toMillis() == 0.0) {
setAffine(affine);
return;
}
final Timeline timeline = new Timeline(60.0);
timeline.setCycleCount(1);
timeline.setAutoReverse(false);
final Affine currentState = new Affine();
getAffine(currentState);
final DoubleProperty progressProperty = new SimpleDoubleProperty(0.0);
final SimilarityTransformInterpolator interpolator = new SimilarityTransformInterpolator(
Transforms.fromTransformFX(currentState),
Transforms.fromTransformFX(affine)
);
progressProperty.addListener((obs, oldv, newv) -> setAffine(Transforms.toTransformFX(interpolator.interpolateAt(newv.doubleValue()))));
final KeyValue kv = new KeyValue(progressProperty, 1.0, Interpolator.EASE_BOTH);
timeline.getKeyFrames().add(new KeyFrame(duration, kv));
timeline.play();
}
public void updateArrow(String face, boolean hover){
boolean bFaceArrow=!(face.startsWith("X")||face.startsWith("Y")||face.startsWith("Z"));
MeshView arrow=bFaceArrow?faceArrow:axisArrow;
if(hover && onRotation.get()){
return;
}
arrow.getTransforms().clear();
if(hover){
double d0=arrow.getBoundsInParent().getHeight()/2d;
Affine aff=Utils.getAffine(dimCube, d0, bFaceArrow, face);
arrow.getTransforms().setAll(aff);
arrow.setMaterial(Utils.getMaterial(face));
if(previewFace.get().isEmpty()) {
previewFace.set(face);
onPreview.set(true);
rotateFace(face,true,false);
}
} else if(previewFace.get().equals(face)){
rotateFace(Utils.reverseRotation(face),true,true);
} else if(previewFace.get().equals("V")){
previewFace.set("");
onPreview.set(false);
}
}
public void bindViewerToConfig(final Viewer3DFX viewer)
{
viewer.meshesEnabledProperty().bind(this.areMeshesEnabled);
viewer.showBlockBoundariesProperty().bind(this.showBlockBoundaries);
viewer.rendererBlockSizeProperty().bind(this.rendererBlockSize);
viewer.numElementsPerFrameProperty().bind(this.numElementsPerFrame);
viewer.frameDelayMsecProperty().bind(this.frameDelayMsec);
viewer.sceneUpdateDelayMsecProperty().bind(this.sceneUpdateDelayMsec);
final Affine affineCopy = this.affine.clone();
final boolean wasAffineSet = this.wasAffineSet;
viewer.addAffineListener(this::setAffine);
viewer.backgroundFillProperty().bindBidirectional(this.backgroundColor);
if (wasAffineSet) {
LOG.debug("Setting viewer affine to {}", affineCopy);
viewer.setAffine(affineCopy);
}
}
public void cancelSelection() {
for (CSG key : getCsgMap().keySet()) {
Platform.runLater(() -> getCsgMap().get(key).setMaterial(new PhongMaterial(key.getColor())));
}
this.selectedCsg = null;
// new Exception().printStackTrace();
TransformNR startSelectNr = perviousTarget.copy();
TransformNR targetNR = new TransformNR();
Affine interpolator = new Affine();
Platform.runLater(() -> {
TransformFactory.nrToAffine(startSelectNr, interpolator);
removeAllFocusTransforms();
focusGroup.getTransforms().add(interpolator);
focusInterpolate(startSelectNr, targetNR, 0, 15, interpolator);
});
resetMouseTime();
}
public void updateArrow(String face, boolean hover){
boolean bFaceArrow = !(face.startsWith("X") || face.startsWith("Y") || face.startsWith("Z"));
MeshView arrow = bFaceArrow ? faceArrow : axisArrow;
if (hover && onRotation.get()) {
return;
}
arrow.getTransforms().clear();
if (hover) {
double d0 = arrow.getBoundsInParent().getHeight() / 2d;
Affine aff = Utils.getAffine(dimCube, d0, bFaceArrow, face);
arrow.getTransforms().setAll(aff);
arrow.setMaterial(Utils.getMaterial(face));
if (previewFace.get().isEmpty()) {
previewFace.set(face);
onPreview.set(true);
rotateFace(face, true, false);
}
} else if (previewFace.get().equals(face)) {
rotateFace(Utils.reverseRotation(face), true, true);
} else if (previewFace.get().equals("V")) {
previewFace.set("");
onPreview.set(false);
}
}
/**
* Assigns the transformation values of the <i>src</i> {@link Affine} to the
* <i>dst</i> {@link Affine}.
*
* @param dst
* The destination {@link Affine}.
* @param src
* The source {@link Affine}.
* @return The destination {@link Affine} for convenience.
*/
public static Affine setAffine(Affine dst, Affine src) {
dst.setMxx(src.getMxx());
dst.setMxy(src.getMxy());
dst.setMxz(src.getMxz());
dst.setMyx(src.getMyx());
dst.setMyy(src.getMyy());
dst.setMyz(src.getMyz());
dst.setMzx(src.getMzx());
dst.setMzy(src.getMzy());
dst.setMzz(src.getMzz());
dst.setTx(src.getTx());
dst.setTy(src.getTy());
dst.setTz(src.getTz());
return dst;
}
@Test
public void test_translate() {
Point start = new Point(0, 0);
Point end = new Point(100, 50);
Bendable bendable = new Bendable(start, end);
// check content bend points
List<BendPoint> contentBendPoints = bendable.getContentBendPoints();
assertEquals(start, contentBendPoints.get(0).getPosition());
assertEquals(end, contentBendPoints.get(1).getPosition());
// check size
Dimension contentSize = bendable.getContentSize();
assertEquals(new Rectangle(start, end).getSize(), contentSize);
// check transform (should equal translation to offset)
Point contentOffset = new Point(bendable.getContentTransform().getTx(), bendable.getContentTransform().getTy());
assertEquals(start, contentOffset);
// apply translation
Point newStart = start.getTranslated(20, 50);
Point newEnd = end.getTranslated(20, 50);
Rectangle newBounds = new Rectangle(newStart, newEnd);
bendable.setContentTransform(new Affine(new Translate(newStart.x, newStart.y)));
assertEquals(newBounds.getSize(), bendable.getContentSize());
contentOffset = new Point(bendable.getContentTransform().getTx(), bendable.getContentTransform().getTy());
assertEquals(newStart, contentOffset);
}
@Override
public void drawParticles(Vec2[] centers, float radius, ParticleColor[] colors, int count) {
GraphicsContext g = getGraphics();
saveState(g);
double scaling = transformGraphics(g, zero) * radius;
g.setLineWidth(stroke / scaling);
for (int i = 0; i < count; i++) {
Vec2 center = centers[i];
Color color;
if (colors == null) {
color = pcolorA;
} else {
ParticleColor c = colors[i];
color = cpool.getColor(c.r * 1f / 127, c.g * 1f / 127, c.b * 1f / 127, c.a * 1f / 127);
}
Affine old = g.getTransform();
g.translate(center.x, center.y);
g.scale(radius, radius);
g.setFill(color);
g.fillOval(circle.getMinX(), circle.getMinX(), circle.getWidth(), circle.getHeight());
g.setTransform(old);
}
restoreState(g);
}
@Override
public IStatus execute(IProgressMonitor monitor, IAdaptable info)
throws ExecutionException {
if (canvas.getPrefWidth() != newWidth) {
canvas.setPrefWidth(newWidth);
}
if (canvas.getPrefHeight() != newHeight) {
canvas.setPrefHeight(newHeight);
}
Affine newContentAffine = Geometry2FX.toFXAffine(newContentTransform);
if (!canvas.getContentTransform().equals(newContentAffine)) {
canvas.setContentTransform(newContentAffine);
}
if (canvas.getHorizontalScrollOffset() != newHorizontalScrollOffset) {
canvas.setHorizontalScrollOffset(newHorizontalScrollOffset);
}
if (canvas.getVerticalScrollOffset() != newVerticalScrollOffset) {
canvas.setVerticalScrollOffset(newVerticalScrollOffset);
}
return Status.OK_STATUS;
}
@Override
public IStatus undo(IProgressMonitor monitor, IAdaptable info)
throws ExecutionException {
if (canvas.getPrefWidth() != initialWidth) {
canvas.setPrefWidth(initialWidth);
}
if (canvas.getPrefHeight() != initialHeight) {
canvas.setPrefHeight(initialHeight);
}
Affine initialContentAffine = Geometry2FX
.toFXAffine(initialContentTransform);
if (!canvas.getContentTransform().equals(initialContentAffine)) {
canvas.setContentTransform(initialContentAffine);
}
if (canvas
.getHorizontalScrollOffset() != initialHorizontalScrollOffset) {
canvas.setHorizontalScrollOffset(initialHorizontalScrollOffset);
}
if (canvas.getVerticalScrollOffset() != initialVerticalScrollOffset) {
canvas.setVerticalScrollOffset(initialVerticalScrollOffset);
}
return Status.OK_STATUS;
}
@Override
public Affine deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
final double[] v = context.deserialize(json, double[].class);
return new Affine(
v[0], v[1], v[2], v[3],
v[4], v[5], v[6], v[7],
v[8], v[9], v[10], v[11]);
}
@Override
public JsonElement serialize(Affine a, Type typeOfSrc, JsonSerializationContext context) {
return context.serialize(new double[] {
a.getMxx(), a.getMxy(), a.getMxz(), a.getTx(),
a.getMyx(), a.getMyy(), a.getMyz(), a.getTy(),
a.getMzx(), a.getMzy(), a.getMzz(), a.getTz()
});
}
@Override
public BookmarkConfig.Bookmark deserialize(
final JsonElement json,
final Type typeOfT,
final JsonDeserializationContext context) throws JsonParseException {
final JsonObject map = json.getAsJsonObject();
return new BookmarkConfig.Bookmark(
context.deserialize(map.get(GLOBAL_TRANSFORM_KEY), AffineTransform3D.class),
context.deserialize(map.get(VIEWER_3D_KEY), Affine.class),
map.has(NOTE_KEY) ? map.get(NOTE_KEY).getAsString() : null);
}
public static Affine toTransformFX(final AffineTransform3D transform)
{
return new Affine(
transform.get(0, 0), transform.get(0, 1), transform.get(0, 2), transform.get(0, 3),
transform.get(1, 0), transform.get(1, 1), transform.get(1, 2), transform.get(1, 3),
transform.get(2, 0), transform.get(2, 1), transform.get(2, 2), transform.get(2, 3)
);
}
private void focusInterpolate(TransformNR start, TransformNR target, int depth, int targetDepth,
Affine interpolator) {
double depthScale = 1 - (double) depth / (double) targetDepth;
double sinunsoidalScale = Math.sin(depthScale * (Math.PI / 2));
// double xIncrement =target.getX()- ((start.getX() - target.getX()) *
// depthScale) + start.getX();
double difference = start.getX() - target.getX();
double scaledDifference = (difference * sinunsoidalScale);
double xIncrement = scaledDifference;
double yIncrement = ((start.getY() - target.getY()) * sinunsoidalScale);
double zIncrement = ((start.getZ() - target.getZ()) * sinunsoidalScale);
Platform.runLater(() -> {
interpolator.setTx(xIncrement);
interpolator.setTy(yIncrement);
interpolator.setTz(zIncrement);
});
// System.err.println("Interpolation step " + depth + " x " + xIncrement
// + " y " + yIncrement + " z " + zIncrement);
if (depth < targetDepth) {
FxTimer.runLater(Duration.ofMillis(16), new Runnable() {
@Override
public void run() {
focusInterpolate(start, target, depth + 1, targetDepth, interpolator);
}
});
} else {
// System.err.println("Camera intrpolation done");
Platform.runLater(() -> {
focusGroup.getTransforms().remove(interpolator);
});
perviousTarget = target.copy();
perviousTarget.setRotation(new RotationNR());
focusing=false;
}
}
@SuppressWarnings("boxing")
@Override
public void messageArrived(String topic, MqttMessage message) {
System.out.println("messageArrived(" + topic + ")");
ByteBuffer buffer = ByteBuffer.wrap(message.getPayload());
double[] compass = new double[] { buffer.getDouble(), buffer.getDouble(), buffer.getDouble() };
double[] accel = new double[] { buffer.getDouble(), buffer.getDouble(), buffer.getDouble() };
double[] gyro = new double[] { buffer.getDouble(), buffer.getDouble(), buffer.getDouble() };
double[] quat = new double[] { buffer.getDouble(), buffer.getDouble(), buffer.getDouble(), buffer.getDouble() };
double[] ypr = new double[] { buffer.getDouble(), buffer.getDouble(), buffer.getDouble() };
double w = quat[QUAT_SCALER];
double x = quat[QUAT_X];
double y = quat[QUAT_Y];
double z = quat[QUAT_Z];
System.out.format("Got IMU data: compass=[%f, %f, %f], accel=[%f, %f, %f], "
+ "gyro=[%f, %f, %f], quat=[%f, %f, %f, %f], ypr=[%f, %f, %f]%n",
compass[0], compass[1], compass[2], accel[0], accel[1], accel[2],
gyro[0], gyro[1], gyro[2], quat[0], quat[1], quat[2], quat[3], ypr[0], ypr[1], ypr[2]);
//Rotate rx = new Rotate(Math.toDegrees(ypr[0]), Rotate.X_AXIS);
//Rotate ry = new Rotate(Math.toDegrees(ypr[1]), Rotate.Y_AXIS);
//Rotate rz = new Rotate(Math.toDegrees(ypr[2]), Rotate.Z_AXIS);
double[] idt = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };
Affine matrix = new Affine(idt, MatrixType.MT_3D_3x4, 0);
// http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q54
matrix.setMxx(1 - (2*y*y + 2*z*z)); matrix.setMxy(2*x*y + 2*z*w); matrix.setMxz(2*x*z - 2*y*w);
matrix.setMyx(2*x*y - 2*z*w); matrix.setMyy(1 - (2*x*x + 2*z*z)); matrix.setMyz(2*y*z + 2*x*w);
matrix.setMzx(2*x*z + 2*y*w); matrix.setMzy(2*y*z - 2*x*w); matrix.setMzz(1 - (2*x*x + 2*y*y));
if (! Platform.isFxApplicationThread()) {
Platform.runLater(() -> {
testObject.getTransforms().setAll(matrix);
//testObject.getTransforms().clear();
//testObject.getTransforms().addAll(rx, ry, rz);
}
);
}
}
private void applyTransform(Affine dst, Transform transform) {
AffineTransform affineTransform = FX2Geometry
.toAffineTransform(dst);
AffineTransform result = affineTransform
.concatenate(FX2Geometry.toAffineTransform(transform));
setAffine(dst, result);
}
private void setAffine(Affine dst, AffineTransform src) {
dst.setMxx(src.getM00());
dst.setMxy(src.getM01());
dst.setMyx(src.getM10());
dst.setMyy(src.getM11());
dst.setTx(src.getTranslateX());
dst.setTy(src.getTranslateY());
}
/**
* Sets the transformation matrix of the {@link #getContentTransform()
* viewport transform} to the values specified by the given {@link Affine}.
*
* @param tx
* The {@link Affine} determining the new
* {@link #getContentTransform() viewport transform}.
*/
public void setContentTransform(Affine tx) {
Affine viewportTransform = contentTransformProperty.get();
// Unregister bounds listeners so that transformation changes do not
// cause updates. Use flag to be aware if the transformation changed.
unregisterUpdateScrollBarsOnBoundsChanges();
boolean valuesChanged = false;
if (viewportTransform.getMxx() != tx.getMxx()) {
viewportTransform.setMxx(tx.getMxx());
valuesChanged = true;
}
if (viewportTransform.getMxy() != tx.getMxy()) {
viewportTransform.setMxy(tx.getMxy());
valuesChanged = true;
}
if (viewportTransform.getMyx() != tx.getMyx()) {
viewportTransform.setMyx(tx.getMyx());
valuesChanged = true;
}
if (viewportTransform.getMyy() != tx.getMyy()) {
viewportTransform.setMyy(tx.getMyy());
valuesChanged = true;
}
if (viewportTransform.getTx() != tx.getTx()) {
viewportTransform.setTx(tx.getTx());
valuesChanged = true;
}
if (viewportTransform.getTy() != tx.getTy()) {
viewportTransform.setTy(tx.getTy());
valuesChanged = true;
}
// Update scrollbars if the transformation changed.
if (valuesChanged) {
updateScrollBars();
}
// Register previously unregistered listeners.
registerUpdateScrollBarsOnBoundsChanges();
}
/**
* Disables zooming of the background grid.
*
* @see #zoomGrid()
* @see #zoomGridProperty()
*/
protected void unzoomGrid() {
Affine gridTransform = gridTransformProperty.get();
gridTransform.mxxProperty().unbind();
gridTransform.mxyProperty().unbind();
gridTransform.myxProperty().unbind();
gridTransform.myyProperty().unbind();
gridTransform.txProperty().unbind();
gridTransform.tyProperty().unbind();
}
/**
* This method is called when the grid transformation should be updated to
* match the given {@link Affine}. The grid transformation is
*
* @param transform
* The new transformation matrix for the grid canvas.
*/
protected void updateGridTransform(Affine transform) {
gridTransform.mxxProperty().bind(transform.mxxProperty());
gridTransform.mxyProperty().bind(transform.mxyProperty());
gridTransform.myyProperty().bind(transform.myyProperty());
gridTransform.myxProperty().bind(transform.myxProperty());
gridTransform.txProperty().bind(transform.txProperty());
gridTransform.tyProperty().bind(transform.tyProperty());
}
/**
* Enables zooming of the background grid when the contents are zoomed.
*/
protected void zoomGrid() {
Affine gridTransform = gridTransformProperty.get();
Affine contentTransform = getContentTransform();
gridTransform.mxxProperty().bind(contentTransform.mxxProperty());
gridTransform.mxyProperty().bind(contentTransform.mxyProperty());
gridTransform.myxProperty().bind(contentTransform.myxProperty());
gridTransform.myyProperty().bind(contentTransform.myyProperty());
gridTransform.txProperty().bind(contentTransform.txProperty());
gridTransform.tyProperty().bind(contentTransform.tyProperty());
}
@Override
public Affine getContentTransform() {
Point position = ZestProperties.getPosition(getContent());
if (position == null) {
position = new Point();
}
return new Affine(new Translate(position.x, position.y));
}
@Override
public Affine getContentTransform() {
Point p = getLabelPosition();
if (p == null) {
p = new Point();
}
return new Affine(new Translate(p.x, p.y));
}
/**
* Adjusts the label's position to fit the given {@link Point}.
*
* @param visual
* This node's visual.
* @param position
* This node's position.
*/
protected void refreshPosition(Node visual, Point position) {
if (position != null) {
// translate using a transform operation
TransformVisualOperation refreshPositionOp = new TransformVisualOperation(this,
new Affine(new Translate(position.x, position.y)));
try {
refreshPositionOp.execute(null, null);
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
/**
* Enforce that label is preserved at its respective relative location.
*
* @return Whether the position was adjusted or not.
*/
public boolean preserveLabelOffset() {
if (initialOffset == null) {
return false;
}
Point currentLabelOffset = getLabelOffsetInParent();
Point delta = currentLabelOffset.getTranslated(initialOffset.getNegated());
TransformVisualOperation op = ((TransformVisualOperation) getOperation());
Affine newTransform = op.getNewTransform();
newTransform.setTx(op.getInitialTransform().getTx() - delta.x);
newTransform.setTy(op.getInitialTransform().getTy() - delta.y);
locallyExecuteOperation();
return true;
}
/**
* Converts the given {@link AffineTransform} to a JavaFX {@link Affine}.
*
* @param transform
* The {@link AffineTransform} to convert.
* @return The new {@link Affine}.
*/
public static final Affine toFXAffine(AffineTransform transform) {
Affine affine = new Affine();
affine.setMxx(transform.getM00());
affine.setMxy(transform.getM01());
affine.setMyx(transform.getM10());
affine.setMyy(transform.getM11());
affine.setTx(transform.getTranslateX());
affine.setTy(transform.getTranslateY());
return affine;
}