JavaFX 3D:使用键盘旋转PerspectiveCamera最终会更改相机的视图

时间:2019-06-03 16:58:36

标签: javafx rotation javafx-3d

我希望能够使用WASD键旋转透视相机。按下W和S键将使照相机沿X轴旋转,按下A和D键将使照相机沿Y轴旋转。为此,我创建了一个名为RotateCamera的类,该类扩展了PerspectiveCamera类并包括方法I旋转相机。这种方式通常可行,但是我发现是否先使用向上箭头键将摄像机向前移动,然后向W键发送垃圾邮件,以使摄像机旋转360度,当球体返回视图时,它就很远了,并且可以移动使用箭头键的相机似乎会在随机方向上移动它。我想知道为什么这是/如何解决?下面是我课程的副本。

package ui;

import javafx.scene.PerspectiveCamera;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Transform;

/**
 * A PerspectiveCamera that includes methods which allow it to be rotated
 */
public class RotateCamera extends PerspectiveCamera {
    Transform currTransform;

    /**
     * Constructor
     * Creates a new camera with default Rotate transform
     */
    public RotateCamera() {
        currTransform = new Rotate();
    }

    /**
     * Rotates the camera along the x-axis according to the given angle
     * @param angle the amount of degrees the camera is rotated
     */
    public void rotateInX(int angle) {
       Rotate newRotation = new Rotate(angle, Rotate.X_AXIS);
       rotateCam(newRotation);
    }

    /**
     * Rotates the camera along the y-axis according to the given angle
     * @param angle the amount of degrees the camera is rotated
     */
    public void rotateInY(int angle) {
        Rotate newRotation = new Rotate(angle, Rotate.Y_AXIS);
        rotateCam(newRotation);
    }

    /**
     * Applies both the currTransform and given rotation to the camera
     */
    private void rotateCam(Rotate rotation) {
        currTransform = currTransform.createConcatenation(rotation);
        getTransforms().clear();
        getTransforms().addAll(currTransform);
    }
}

>

package ui;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.KeyEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Sphere;
import javafx.stage.Stage;
import javafx.scene.Group;
import model.Molecule;

import java.util.Observable;
import java.util.Observer;

/**
 * Represents the window in which the molecule drawing editor appears.
 * Run the main method to start the program!
 */
public class MarsBonds extends Application {

    private static final int CAM_NEAR_CLIP = 0;
    private static final int CAM_FAR_CLIP = 1000;
    private static final int CAM_ORG_DISTANCE = -10;
    private static final int WIDTH = 1000;
    private static final int HEIGHT = 800;
    private static final Color SCENE_COLOR = Color.BLACK;
    private static final int CAM_SPEED = 30;

    private static Stage primaryStage;
    private static RotateCamera camera;
    private static Scene scene;

    @Override
    public void start(Stage primaryStage) throws Exception {
        setScene();
        setCamera();
        setPrimaryState(primaryStage);
    }

    /**
     * Creates scene with molecule in center of screen and black background
     */
    public static void setScene() {
        Sphere molecule = new Sphere(30);
        molecule.translateXProperty().set(WIDTH/2);
        molecule.translateYProperty().set(HEIGHT/2);
        Group root = new Group();
        root.getChildren().add(molecule);
        scene = new Scene(root, WIDTH, HEIGHT);
        scene.setFill(SCENE_COLOR);
    }

    /**
     * Initializes camera and adds to scene
     */
    private static void setCamera() {
        camera = new RotateCamera();
        camera.setNearClip(CAM_NEAR_CLIP);
        camera.setFarClip(CAM_FAR_CLIP);
        camera.translateZProperty().set(CAM_ORG_DISTANCE);
        scene.setCamera(camera);
    }

    /**
     * Sets up the primary stage by setting its scene, title, and adding key control
     * @param stage the primary stage
     */
    private static void setPrimaryState(Stage stage) {
        primaryStage = stage;
        addEventHandlers();
        primaryStage.setTitle("Mar's Bonds");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * Adds KeyEvent handler to primary stage
     * The KeyEvent handler uses input from the WASD keys to rotate
     * the camera and the arrow keys to move the camera
     */
    private static void addEventHandlers() {
        primaryStage.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
            switch(e.getCode()) {
                case W:
                    camera.rotateInX(-1);
                    break;
                case S:
                    camera.rotateInX(1);
                    break;
                case A:
                    camera.rotateInY(1);
                    break;
                case D:
                    camera.rotateInY(-1);
                    break;
                case UP:
                    camera.setTranslateZ(camera.getTranslateZ() + CAM_SPEED);
                    break;
                case DOWN:
                    camera.setTranslateZ(camera.getTranslateZ() - CAM_SPEED);
                    break;
                case LEFT:
                    camera.setTranslateX(camera.getTranslateX() - CAM_SPEED/3);
                    break;
                case RIGHT:
                    camera.setTranslateX(camera.getTranslateX() + CAM_SPEED/3);
                    break;
            }
        });
    }

    public static void main( String[] args ) {
        launch(args);
    }
}

0 个答案:

没有答案