私は自分のアプリに非常に行き詰まっており、誰かが私と同じことをしている例は見当たりません。 https://www.dropbox.com/sh/lqzoegg5v8drzog/nLxDuIVAh0
3D ワールドがあり、STL ファイルから TriagleMesh オブジェクトを 3D ワールドにロードします。3D ワールドは、xforms を使用した Oracle の多くの例を使用して作成されます。カメラを 3D ワールドの周りに向けることができ、すべて問題ありません。
3D ワールドの X+ が右にあり、マウスでオブジェクトを右に移動すると、オブジェクトは実際に右に移動します。X+ が左になるように世界を回転させると、マウスを右に動かすとオブジェクトが左に移動します
アプリケーションは現在、MouseEvent のドラッグされたイベント ハンドラで getScreenX と getScreenY を使用しています。getSceneX と getSceneY を試しましたが、同じように動作します。getX と getY を使用すると、オブジェクトが飛び回り、getX と getY から返される座標が絶えず変化します。これは、オブジェクトが移動しており、getX および getY 座標が移動前のオブジェクトに対するマウスの位置に戻っていることが原因であると考えられます。getX と getY を使用し、オブジェクトを回転すると、座標系が変化するとします。右に X+ があれば、左になります。したがって、オブジェクトを右に移動しようとすると、左に移動します
getScreenX/Y を使用して、カメラの回転に応じてマウス座標を何らかの方法で変換する必要があると考えています。JavaFXでそれを行うにはどうすればよいですか?
編集 1 ソート済み
このjiraで次のコードが与えられましたhttps://javafx-jira.kenai.com/browse/RT-35178
final Rectangle mousePlane = new Rectangle(800, 800, Color.TRANSPARENT);
mousePlane.setMouseTransparent(true);
mousePlane.setDepthTest(DepthTest.DISABLE); // this makes the plane to be picked even if there are objects closer to the camera
// + translation and rotation so it's parallel to your plane
When an object is dragged, it does this:
cube.setOnDragDetected(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent event) {
cube.setMouseTransparent(true); // cube will not be picked
mousePlane.setMouseTransparent(false); // mousePlane will be pickable
cube.startFullDrag(); // see javadoc, this redirects drag events from the origin (cube) to the picked target (which will be mousePlane)
}
});
+ some cleanup:
cube.setOnMouseReleased(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent event) {
cube.setMouseTransparent(false);
mousePlane.setMouseTransparent(true);
}
});
and now the movement itself:
mousePlane.setOnMouseDragOver(new EventHandler<MouseDragEvent>() {
@Override public void handle(MouseDragEvent event) {
Point3D coords = event.getPickResult().getIntersectedPoint();
double x = coords.getX();
double y = coords.getY();
double z = coords.getZ();
coords = mousePlane.localToParent(new Point3D(x, y, z)); //mouseplane has the same parent as the real plane and objects like cube
// You might need to adjust this depending on your hierarchy and transformations
cube.setTranslateX(coords.getX());
cube.setTranslateY(coords.getY());
cube.setTranslateZ(coords.getZ());
}
});
私がしたことは、ドラッグ検出コードを Gizmo オブジェクトに配置することでした。ギズモは、MouseTransparent を true に設定し、FullDrag を開始します。次に、GizmoViewer を呼び出して、GizmoViewer が mousePlane MouseTransparent を設定できるようにします。これにより、Gizmo ではなく mousePlane によってドラッグが検出されます。また、GizmoViewer dragJustStarted = true; にフラグを設定しました。次にドラッグを開始し、OnMouseDragOver が mousePlane で起動すると、mouseOldX、mousePosX、mouseOldY、mousePosY の値が設定され、ドラッグが初めて実行されたことを検出すると終了します。ドラッグが再び実行されると、すべての正しいマウス値が得られ、笑顔でドラッグできます
マウスプレーンのセットアップ
private void setupMousePlane() {
mousePlane.setLayoutX(-800 / 2);
mousePlane.setLayoutY(-800 / 2);
mousePlane.setOpacity(0.7);
mousePlane.setMouseTransparent(true);
mousePlane.setDepthTest(DepthTest.DISABLE); // this makes the plane to be picked even if there are objects closer to the camera
mousePlane.setOnMouseDragOver(new EventHandler<MouseDragEvent>() {
@Override
public void handle(MouseDragEvent me) {
if (me.isPrimaryButtonDown() && me.isShiftDown()) {
//do nothing, we are rotating on the gizmo
} else if (me.isPrimaryButtonDown()) {
Point3D coords = me.getPickResult().getIntersectedPoint();
mouseOldX = mousePosX;
mouseOldY = mousePosY;
mousePosX = coords.getX();
mousePosY = coords.getY();
double z = coords.getZ();
coords = mousePlane.localToParent(new Point3D(mousePosX, mousePosY, z)); //mouseplane has the same parent as the real plane and objects like cube
mousePosX = coords.getX();
mousePosY = coords.getY();
mouseDeltaX = (mousePosX - mouseOldX);
mouseDeltaY = (mousePosY - mouseOldY);
if (dragJustStarted) {
dragJustStarted = false;
} else {
double modifier = 10;
double modifierFactor = 0.15;
double yFlip = 1.0;
double flip = -1.0;
for (Gizmo gizmo : gizmoSelectionHelper.getSelection()) {
gizmo.getGizmoXform2().t.setX(gizmo.getGizmoXform2().t.getX() - flip * mouseDeltaX * modifierFactor * modifier * 0.3); // -
gizmo.getGizmoXform2().t.setY(gizmo.getGizmoXform2().t.getY() + yFlip * mouseDeltaY * modifierFactor * modifier * 0.3); // -
configureGizmoPivot(gizmo);
}
}
}
}
});
world.getChildren().addAll(mousePlane);
}
ギズモ/画面オブジェクトのドラッグが検出されました
private final EventHandler mouseDragDetectedHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent me) {
if (me.isPrimaryButtonDown()) {
Gizmo gizmo = (Gizmo) me.getSource();
gizmo.setMouseTransparent(true);
gizmo.startFullDrag();
gizmo.getGizmoViewer().startDraggingGizmo(me);
}
}
};
ギズモ マウスがリリースされました (この問題にとって重要な方法の始まりにすぎません)
private final EventHandler mouseReleasedHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent me) {
Gizmo gizmo = (Gizmo) me.getSource();
if (MouseButton.PRIMARY == me.getButton()) {
gizmo.setMouseTransparent(false);
gizmo.getGizmoViewer().stopDraggingGizmo();
ギズモビューア
public void startDraggingGizmo(MouseEvent me) {
// mousePlane will be pickable
mousePlane.setMouseTransparent(false);
dragJustStarted = true;
}
public void stopDraggingGizmo() {
mousePlane.setMouseTransparent(true);
}