1
我的問題是:JavaFX的3D旋轉
- 下面的代碼是基於從Oracle教程網站的「MolecularSampleApp」,但非常簡單。它只顯示一個盒子和一個紅色的球體用於定位。旋轉的順序圍繞x軸,然後是y軸,最後是z軸。在旋轉之後顯然是在隨着旋轉而旋轉的座標軸中完成的。因此,當用戶使用鼠標旋轉攝像機視圖時,這是非常不直觀的,因爲在圍繞垂直屏幕軸旋轉後,旋轉行爲會發生變化(因爲水平軸也將被旋轉)。 請使用下面的代碼或MolecularSampleApp嘗試它 - 它具有相同的不自然感覺。有沒有簡單的方法來克服這個問題?
- 但我甚至不明白的是mousePressed-code執行時的行爲:在這裏,相機總是在固定系統中旋轉!儘管其基本上相同的代碼(除了旋轉角度當然不在這裏累積),軸不會與相機一起旋轉。任何人都知道這可能如何?
package trafotest;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.DepthTest;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.Sphere;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
public class TrafoTest extends Application {
final Group root = new Group();
final XformWorld world = new XformWorld();
final PerspectiveCamera camera = new PerspectiveCamera(true);
final XformCamera cameraXform = new XformCamera();
private static final double CAMERA_INITIAL_DISTANCE = -1000;
private static final double CAMERA_NEAR_CLIP = 0.1;
private static final double CAMERA_FAR_CLIP = 10000.0;
double mousePosX, mousePosY, mouseOldX, mouseOldY, mouseDeltaX, mouseDeltaY;
@Override
public void start(Stage primaryStage) {
root.getChildren().add(world);
root.setDepthTest(DepthTest.ENABLE);
buildCamera();
buildBodySystem();
Scene scene = new Scene(root, 800, 600, true);
scene.setFill(Color.GREY);
handleMouse(scene);
primaryStage.setTitle("Transformationen");
primaryStage.setScene(scene);
primaryStage.show();
scene.setCamera(camera);
}
private void buildCamera() {
root.getChildren().add(cameraXform);
cameraXform.getChildren().add(camera);
camera.setNearClip(CAMERA_NEAR_CLIP);
camera.setFarClip(CAMERA_FAR_CLIP);
camera.setTranslateZ(CAMERA_INITIAL_DISTANCE);
}
private void buildBodySystem() {
PhongMaterial whiteMaterial = new PhongMaterial();
whiteMaterial.setDiffuseColor(Color.WHITE);
whiteMaterial.setSpecularColor(Color.LIGHTBLUE);
Box box = new Box(400, 200, 100);
box.setMaterial(whiteMaterial);
PhongMaterial redMaterial = new PhongMaterial();
redMaterial.setDiffuseColor(Color.DARKRED);
redMaterial.setSpecularColor(Color.RED);
Sphere sphere = new Sphere(5);
sphere.setMaterial(redMaterial);
sphere.setTranslateZ(-50.0);
world.getChildren().addAll(box);
world.getChildren().addAll(sphere);
}
private void handleMouse(Scene scene) {
scene.setOnMousePressed((MouseEvent me) -> {
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
mouseOldX = me.getSceneX();
mouseOldY = me.getSceneY();
// this is done after clicking and the rotations are apearently
// performed in coordinates that are NOT rotated with the camera.
// (pls activate the two lines below for clicking)
//cameraXform.rx.setAngle(-90.0);
//cameraXform.ry.setAngle(180.0);
});
scene.setOnMouseDragged((MouseEvent me) -> {
mouseOldX = mousePosX;
mouseOldY = mousePosY;
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
mouseDeltaX = (mousePosX - mouseOldX);
mouseDeltaY = (mousePosY - mouseOldY);
if (me.isPrimaryButtonDown()) {
// this is done when the mouse is dragged and each rotation is
// performed in coordinates, that are rotated with the camera.
cameraXform.ry.setAngle(cameraXform.ry.getAngle() + mouseDeltaX * 0.2);
cameraXform.rx.setAngle(cameraXform.rx.getAngle() - mouseDeltaY * 0.2);
}
});
}
public static void main(String[] args) {
launch(args);
}
}
class XformWorld extends Group {
final Translate t = new Translate(0.0, 0.0, 0.0);
final Rotate rx = new Rotate(0, 0, 0, 0, Rotate.X_AXIS);
final Rotate ry = new Rotate(0, 0, 0, 0, Rotate.Y_AXIS);
final Rotate rz = new Rotate(0, 0, 0, 0, Rotate.Z_AXIS);
public XformWorld() {
super();
this.getTransforms().addAll(t, rx, ry, rz);
}
}
class XformCamera extends Group {
final Translate t = new Translate(0.0, 0.0, 0.0);
final Rotate rx = new Rotate(0, 0, 0, 0, Rotate.X_AXIS);
final Rotate ry = new Rotate(0, 0, 0, 0, Rotate.Y_AXIS);
final Rotate rz = new Rotate(0, 0, 0, 0, Rotate.Z_AXIS);
public XformCamera() {
super();
this.getTransforms().addAll(t, rx, ry, rz);
}
}
歡迎StackOverflow上。請閱讀此http://stackoverflow.com/help/how-to-ask以瞭解如何提出正確的問題。你應該儘量隔離代碼,以激勵他人閱讀它。 –