JavaFX 8 中 PerspectiveCamera 的位置

Position of PerspectiveCamera in JavaFX 8

代码如下:

import javafx.animation.Animation;
import javafx.animation.RotateTransition;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.PointLight;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Box;
import javafx.scene.shape.CullFace;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;

public class CameraTest extends Application {
    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage stage) {
        Box box = new Box(100, 100, 100);
        box.setCullFace(CullFace.NONE);
        box.setTranslateX(0);
        box.setTranslateY(0);
        box.setTranslateZ(0);

        PerspectiveCamera camera = new PerspectiveCamera(false);
        camera.setTranslateX(0);
        camera.setTranslateY(0);
        camera.setTranslateZ(0);

        // Add a Rotation animation to the camera
        RotateTransition rt = new RotateTransition(Duration.seconds(2), box);
        rt.setCycleCount(Animation.INDEFINITE);
        rt.setFromAngle(0);
        rt.setToAngle(360);
        rt.setAutoReverse(true);
        rt.setAxis(Rotate.Y_AXIS);
        rt.play();

//        PointLight redLight = new PointLight();
//        redLight.setColor(Color.RED);
//        redLight.setTranslateX(250);
//        redLight.setTranslateY(-100);
//        redLight.setTranslateZ(250);

        PointLight greenLight = new PointLight();
        greenLight.setColor(Color.GREEN);
        greenLight.setTranslateX(250);
        greenLight.setTranslateY(300);
        greenLight.setTranslateZ(300);

        Group root = new Group(box, greenLight);
        root.setRotationAxis(Rotate.X_AXIS);
        root.setRotate(30);

        Scene scene = new Scene(root, 500, 300, true);
        scene.setCamera(camera);
        stage.setScene(scene);
        stage.setTitle("Using camaras");
        stage.show();
    }
}
  1. 为什么我感觉y轴有上下运动?
  2. 摄像头和立方体在同一个位置,怎么立方体出现在右上角?

第一个问题:是的,正如你描述的那样,有一个上下运动。解释很简单:

您已将旋转框添加到 Group,并且根据 Javadoc:

A Group node contains an ObservableList of children that are rendered in order whenever this node is rendered. A Group will take on the collective bounds of its children and is not directly resizable. Any transform, effect, or state applied to a Group will be applied to all children of that group. Such transforms and effects will NOT be included in this Group's layout bounds, however if transforms and effects are set directly on children of this Group, those will be included in this Group's layout bounds.

最后的说法是应用到框的旋转影响组布局边界。

由于场景根是组,它的布局变化反映在场景上。

如果跟踪组的 Y 中心:

root.boundsInLocalProperty().addListener((obs, oldBounds, newBounds)->{
        double yCenterLocal = newBounds.getWidth()/2;
        double yCenterScene = root.localToScene(new Point2D(0,yCenterLocal)).getY();
        System.out.println(yCenterScene);
    });

你会看到位置的变化:

212.89169311523438
209.2910614013672
209.34730529785156
209.4747772216797
209.52439880371094
209.576171875

这是旋转两次(720º)后的图表:

为避免此问题,您可以使用另一个容器,例如 StackPane:

StackPane root = new StackPane(box, greenLight);

在您的情况下,Y 中心始终位于 237.03555297851562。

你也解决了第二个问题,因为盒子会出现在场景的中心。

请注意,我已将灯光移动到负 Z 坐标(屏幕外)。

greenLight.setTranslateZ(-300);

此外,您应该使用场景抗锯齿:

Scene scene = new Scene(root, 500, 300, true, SceneAntialiasing.BALANCED);