JavaFX 3D: вращение PerspectiveCamera с помощью клавиатуры приводит к изменению вида камеры - PullRequest
0 голосов
/ 03 июня 2019

Я хочу иметь возможность вращать перспективную камеру с помощью клавиш 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);
    }
}
...