JavaFX 3D具有两个场景,两个摄像头可以查看相同的对象

JavaFX 3D具有两个场景,两个摄像头可以查看相同的对象,javafx,3d,camera,Javafx,3d,Camera,有没有办法让两个场景拥有两个不同的摄影机,但同时观看相同的对象,而不复制每个对象的实例? 我正在开发一个3D游戏,它有一个主要的场景,相机跟随玩家,我想在角落里有另一个场景,显示相同环境的鸟瞰图,比如一张迷你地图。 有没有办法发展这一点?首先,你不能在同一阶段有两个场景。您可以有两个场景和两个阶段,但显然这意味着有重复的对象,需要在场景和阶段之间进行同步 但是,在同一阶段和同一场景中,有可能在整个3D节点的顶部获得一个小的迷你地图(2D)节点,每个节点都有自己的相机 这是基于此,以及库中现有的C

有没有办法让两个场景拥有两个不同的摄影机,但同时观看相同的对象,而不复制每个对象的实例? 我正在开发一个3D游戏,它有一个主要的场景,相机跟随玩家,我想在角落里有另一个场景,显示相同环境的鸟瞰图,比如一张迷你地图。
有没有办法发展这一点?

首先,你不能在同一阶段有两个场景。您可以有两个场景和两个阶段,但显然这意味着有重复的对象,需要在场景和阶段之间进行同步

但是,在同一阶段和同一场景中,有可能在整个3D节点的顶部获得一个小的迷你地图(2D)节点,每个节点都有自己的相机

这是基于此,以及库中现有的
CameraView

如您所见,基本上是一个
ImageView
节点,位于主场景的右下角(或其他任何位置),而3D部分位于场景中心的
子场景

subScene和imageView都可以使用鼠标/键盘事件处理,并且都有摄像头,因此在某种程度上,您可以使用两个不同的3D视图来控制同一3D对象

要获得反映子场景内容的“实时”
ImageView
,看起来像真实的子场景,但不复制对象,
CameraView
主要使用:

  • Node::snapshot
    :使用拍摄子场景的快照将获得ImageView的更新图像

  • SnapshotParameters::setCamera
    (请参阅。这项不太为人所知的功能允许根据给定的相机以给定的视角拍摄快照

  • AnimationTimer
    在每个帧/脉冲上重新执行此过程

以下是
CameraView
的一个简单用例,它可以添加到项目中,包括
org.fxyz3d:fxyz3d:0.5.2
依赖项

    @Override
    public void start(Stage stage) {

        // 1. SubScene

        // 3D node
        SpringMesh spring = new SpringMesh(10, 2, 2, 8 * 2 * Math.PI, 200, 100, 0, 0);
        spring.setCullFace(CullFace.NONE);
        spring.setTextureModeVertices3D(1530, p -> p.f);

        // root
        Group worldRoot = new Group(spring);

        // Camera
        PerspectiveCamera camera = new PerspectiveCamera(true);
        CameraTransformer cameraTransform = new CameraTransformer();
        cameraTransform.setTranslate(0, 0, 0);
        cameraTransform.getChildren().add(camera);
        camera.setNearClip(0.1);
        camera.setFarClip(10000.0);
        camera.setTranslateZ(-100);
        camera.setFieldOfView(20);
        cameraTransform.ry.setAngle(-30.0);
        cameraTransform.rx.setAngle(-15.0);
        worldRoot.getChildren().add(cameraTransform);

        // SubScene
        SubScene subScene = new SubScene(worldRoot, 800,600, true, SceneAntialiasing.BALANCED);
        subScene.setFill(Color.DARKSLATEGRAY);
        subScene.setCamera(camera);

        // mouse, key events on subScene:
    
        // subScene.setOnKeyPressed(event -> {...});
        // subScene.setOnMousePressed(event -> {...});
        // subScene.setOnMouseDragged(event -> {...});

        // 2. CameraView
        CameraView cameraView = new CameraView(subScene);
        cameraView.setFirstPersonNavigationEabled(true);
        cameraView.setFitWidth(350);
        cameraView.setFitHeight(225);
        cameraView.getRx().setAngle(-45);
        cameraView.getT().setZ(-100);
        cameraView.getT().setY(-500);
        cameraView.getCamera().setTranslateZ(-100);

        // Right-bottom corner
        StackPane.setAlignment(cameraView, Pos.BOTTOM_RIGHT);
        StackPane.setMargin(cameraView, new Insets(5));

        // 3. Scene
        StackPane root = new StackPane(subScene, cameraView);
        root.setStyle("-fx-background-color: DEEPSKYBLUE;");
        subScene.widthProperty().bind(root.widthProperty());
        subScene.heightProperty().bind(root.heightProperty());

        Scene scene = new Scene(root, 810,610, true, SceneAntialiasing.BALANCED);
        stage.setTitle("MiniMapTest");
        stage.setScene(scene);
        stage.show();

        // start timer
        cameraView.startViewing();
    }
运行应用程序时,您将获得:

您可以在迷你地图视图上移动相机,以获得3D对象的不同视图:


现在,您可以使用3D亚场景和2D cameraView来获得想要的效果。通过设置
cameraView.setFirstPersonNavigationEnabled(false)
迷你地图将不允许用户交互,您可以控制其相机(即,保持亚场景的给定缩放级别…).

对于初学者,不能在同一阶段有两个场景。可以有两个场景和两个阶段,但显然这意味着有重复的对象,需要在场景和阶段之间同步

但是,在同一阶段和同一场景中,有可能在整个3D节点的顶部获得一个小的迷你地图(2D)节点,每个节点都有自己的相机

这是基于此,以及库中现有的
CameraView

如您所见,基本上是一个
ImageView
节点,位于主场景的右下角(或其他任何位置),而3D部分位于场景中心的
子场景

subScene和imageView都可以使用鼠标/键盘事件处理,并且都有摄像头,因此在某种程度上,您可以使用两个不同的3D视图来控制同一3D对象

要获得反映子场景内容的“实时”
ImageView
,看起来像真实的子场景,但不复制对象,
CameraView
主要使用:

  • Node::snapshot
    :使用拍摄子场景的快照将获得ImageView的更新图像

  • SnapshotParameters::setCamera
    (请参阅。这项不太为人所知的功能允许根据给定的相机以给定的视角拍摄快照

  • AnimationTimer
    在每个帧/脉冲上重新执行此过程

以下是
CameraView
的一个简单用例,它可以添加到项目中,包括
org.fxyz3d:fxyz3d:0.5.2
依赖项

    @Override
    public void start(Stage stage) {

        // 1. SubScene

        // 3D node
        SpringMesh spring = new SpringMesh(10, 2, 2, 8 * 2 * Math.PI, 200, 100, 0, 0);
        spring.setCullFace(CullFace.NONE);
        spring.setTextureModeVertices3D(1530, p -> p.f);

        // root
        Group worldRoot = new Group(spring);

        // Camera
        PerspectiveCamera camera = new PerspectiveCamera(true);
        CameraTransformer cameraTransform = new CameraTransformer();
        cameraTransform.setTranslate(0, 0, 0);
        cameraTransform.getChildren().add(camera);
        camera.setNearClip(0.1);
        camera.setFarClip(10000.0);
        camera.setTranslateZ(-100);
        camera.setFieldOfView(20);
        cameraTransform.ry.setAngle(-30.0);
        cameraTransform.rx.setAngle(-15.0);
        worldRoot.getChildren().add(cameraTransform);

        // SubScene
        SubScene subScene = new SubScene(worldRoot, 800,600, true, SceneAntialiasing.BALANCED);
        subScene.setFill(Color.DARKSLATEGRAY);
        subScene.setCamera(camera);

        // mouse, key events on subScene:
    
        // subScene.setOnKeyPressed(event -> {...});
        // subScene.setOnMousePressed(event -> {...});
        // subScene.setOnMouseDragged(event -> {...});

        // 2. CameraView
        CameraView cameraView = new CameraView(subScene);
        cameraView.setFirstPersonNavigationEabled(true);
        cameraView.setFitWidth(350);
        cameraView.setFitHeight(225);
        cameraView.getRx().setAngle(-45);
        cameraView.getT().setZ(-100);
        cameraView.getT().setY(-500);
        cameraView.getCamera().setTranslateZ(-100);

        // Right-bottom corner
        StackPane.setAlignment(cameraView, Pos.BOTTOM_RIGHT);
        StackPane.setMargin(cameraView, new Insets(5));

        // 3. Scene
        StackPane root = new StackPane(subScene, cameraView);
        root.setStyle("-fx-background-color: DEEPSKYBLUE;");
        subScene.widthProperty().bind(root.widthProperty());
        subScene.heightProperty().bind(root.heightProperty());

        Scene scene = new Scene(root, 810,610, true, SceneAntialiasing.BALANCED);
        stage.setTitle("MiniMapTest");
        stage.setScene(scene);
        stage.show();

        // start timer
        cameraView.startViewing();
    }
运行应用程序时,您将获得:

您可以在迷你地图视图上移动相机,以获得3D对象的不同视图:


现在,您可以使用3D亚场景和2D cameraView来获得想要的效果。通过设置
cameraView.setFirstPersonNavigationEnabled(false)
迷你地图将不允许用户交互,您可以控制其相机(即,保持亚场景的给定缩放级别…).

这是一个有效的问题,但我怀疑这在技术上是否可行。你不能让相同的节点成为两个不同场景的一部分。我建议使用MVC方法:你基本上拥有相同模型的两个视图。这是一个有效的问题,但我怀疑这在技术上是否可行。你不能让相同的节点成为两个不同场景的一部分我推荐一种MVC方法:基本上同一个模型有两个视图。