Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将3D曲面添加到锚烷_Java_Model View Controller_Javafx_Scenebuilder_Javafx 3d - Fatal编程技术网

Java 如何将3D曲面添加到锚烷

Java 如何将3D曲面添加到锚烷,java,model-view-controller,javafx,scenebuilder,javafx-3d,Java,Model View Controller,Javafx,Scenebuilder,Javafx 3d,如何将3D曲面添加到视图.fxml,场景生成器面板上没有类似曲面的“东西”。 我的场景生成器层次结构如下所示: 应用程序的ss-我们可以看到在左上角有一些东西,表面应该在中间。 我想首先添加一些3D曲面的示例: 我的控制器代码: package sample.packet3D; import org.fxyz.cameras.CameraTransformer; import javafx.beans.InvalidationListener; import javafx.bea

如何将3D曲面添加到
视图.fxml
,场景生成器面板上没有类似曲面的“东西”。 我的场景生成器层次结构如下所示:

应用程序的ss-我们可以看到在左上角有一些东西,表面应该在中间。

我想首先添加一些3D曲面的示例: 我的控制器代码:

    package sample.packet3D;

import org.fxyz.cameras.CameraTransformer;

import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.fxml.FXML;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.PointLight;
import javafx.scene.layout.AnchorPane;


public class Window3DController {

    @FXML
    private AnchorPane anchorPane;
    @FXML
    private Group group;

    private Window3DBuilder window3dBuilder;
    private PerspectiveCamera perspectiveCamera;



    @FXML
    public void initialize() {
        perspectiveCamera = new PerspectiveCamera(true);

        window3dBuilder = new Window3DBuilder( group, perspectiveCamera );
        window3dBuilder.createScene();



        group.sceneProperty().addListener(new InvalidationListener() {

            @Override
            public void invalidated(Observable observable) {
                group.getScene().setCamera(perspectiveCamera);
                group.sceneProperty().removeListener(this);
            }
        });
    }
}
逻辑类:

   package sample.packet3D;


import org.fxyz.cameras.CameraTransformer;
import org.fxyz.shapes.primitives.SurfacePlotMesh;

import javafx.geometry.Point3D;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.PointLight;
import javafx.scene.SceneAntialiasing;
import javafx.scene.SubScene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.CullFace;
import javafx.scene.shape.TriangleMesh;
import javafx.scene.transform.Rotate;

public class Window3DBuilder {

    private Group group;
    private SurfacePlotMesh surface;
    private PerspectiveCamera perspectiveCamera;
    private CameraTransformer cameraTransformer;
    private PointLight light;

    public Window3DBuilder( Group group, PerspectiveCamera perspectiveCamera ) {
        this.group = group;
        this.perspectiveCamera = perspectiveCamera;
        cameraTransformer = new CameraTransformer();
    }

    public void createScene() {

        createSurface();
        createLight(); 
        group.getChildren().addAll(surface);

        cameraTransformer.setTranslate(0, 0, 0);
        cameraTransformer.getChildren().addAll(perspectiveCamera);

        perspectiveCamera.setNearClip(0.1);
        perspectiveCamera.setFarClip(100000.0);
        perspectiveCamera.setTranslateX((group.getBoundsInLocal().getMaxX() + group.getBoundsInLocal().getMinX()) / 2d);
        perspectiveCamera.setTranslateY((group.getBoundsInLocal().getMaxY() + group.getBoundsInLocal().getMinY()) / 2d);
        double max = Math.max(group.getBoundsInLocal().getWidth(), group.getBoundsInLocal().getHeight());
        perspectiveCamera.setTranslateZ(-2 * max);

    }

    public void createLight() {
        light = new PointLight(Color.WHITE);
        cameraTransformer.getChildren().add(light);
        light.setTranslateX(perspectiveCamera.getTranslateX());
        light.setTranslateY(perspectiveCamera.getTranslateY());
        light.setTranslateZ(perspectiveCamera.getTranslateZ());
    }

    private void createSurface() {
        surface = new SurfacePlotMesh(
                p-> Math.sin(p.magnitude() + 1e-10) / (p.magnitude() + 1e-10),
                20, 20, 100, 100, 4);
        surface.setCullFace(CullFace.NONE);
        surface.setTextureModeVertices3D(1530, p -> p.magnitude());
        surface.getTransforms().addAll(new Rotate(200, Rotate.X_AXIS), new Rotate(-20, Rotate.Y_AXIS));
    }



}
和视图:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.effect.*?>
<?import javafx.scene.canvas.*?>
<?import javafx.scene.*?>
<?import javafx.scene.shape.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.packet3D.Window3DController">
   <children>
      <Group fx:id="group">
         <effect>
            <Lighting>
               <bumpInput>
                  <Shadow />
               </bumpInput>
               <light>
                  <Light.Distant />
               </light>
            </Lighting>
         </effect>
      </Group>
      <PerspectiveCamera fx:id="perspectiveCamera" visible="false" />
   </children>
</AnchorPane>

您的透视摄像头有问题。它有一个名为
fixedEyeAtCameraZero
的布尔参数,默认情况下该参数为false,并且在场景的左上角显示一个非常小的曲面

我们需要将其设置为true,因此:

如果FixedYeatCamerazero为真,则眼睛位置将固定在相机局部坐标中的(0,0,0)

但不幸的是,您无法设置参数,没有
setFixedYeatCamerazero()
方法。更改它的唯一方法是使用摄影机构造函数

这意味着您必须从FXML文件中删除透视摄像头,然后在控制器上按代码添加

public class Window3DController {

    @FXML
    private AnchorPane anchorPane;
    @FXML
    private Group group;

    private Window3DBuilder window3dBuilder;
    private PerspectiveCamera perspectiveCamera;

    @FXML
    public void initialize() {
        perspectiveCamera = new PerspectiveCamera(true);

        window3dBuilder = new Window3DBuilder(group, perspectiveCamera);
        window3dBuilder.createScene();

        group.sceneProperty().addListener(new InvalidationListener() {
            @Override
            public void invalidated(Observable observable) {
                group.getScene().setCamera(perspectiveCamera);
                group.sceneProperty().removeListener(this);
            }
        });
    } 

}
最后一步:需要为相机设置一些参数,基本上是基于网格大小的z坐标:

public void createScene() {
    createSurface();
    group.getChildren().addAll(surface);

    perspectiveCamera.setNearClip(0.1);
    perspectiveCamera.setFarClip(100000.0);
    perspectiveCamera.setTranslateX((group.getBoundsInLocal().getMaxX() + group.getBoundsInLocal().getMinX()) / 2d);
    perspectiveCamera.setTranslateY((group.getBoundsInLocal().getMaxY() + group.getBoundsInLocal().getMinY()) / 2d);
    double max = Math.max(group.getBoundsInLocal().getWidth(), group.getBoundsInLocal().getHeight());
    perspectiveCamera.setTranslateZ(-2 * max);
}
这将显示您的曲面,但并非如您预期的那样:您要应用的效果适用于二维:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.Group?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Window3DController">
   <children>
      <Group fx:id="group" />
   </children>
</AnchorPane>

我想把相机保存在.fxml文件中。我基于PerspectiveCamera创建了一个自定义控件

从一个非常简单的类开始

import javafx.scene.PerspectiveCamera;


public class PerspectiveCamera3D extends PerspectiveCamera {

// force 3D
public PerspectiveCamera3D() {
    super(true);
}

// toss the parameter, force 3D
public PerspectiveCamera3D(final boolean fixedEyeAtCameraZero) {
    this();
}
}
导出到.jar文件。 启动场景生成器并打开相机所在位置的.fxml文件

打开库标题上的“齿轮”菜单。 然后导入FXML/Jar。导入新创建的.jar文件。将弹出一个对话框,其中列出了您的控件。确认后,该控件将显示在自定义菜单中。您的控件现在可以使用了,就像其他控件一样

“固定眼睛…”复选框仍将是只读的,但它将被选中。可以根据需要设置所有其他属性。要设置fx:id,只需将以下内容添加到控制器代码中

@FXML
public PerspectiveCamera3D cambot;
这里有一个更详细的例子


这样做的唯一问题是,在Eclipse中单击.fxml文件启动Scene Builder时会导致异常(我认为这是我的计算机上的本地问题,因为我启动东西的方式和它们的工作目录)。如果我打开场景生成器,然后从“场景生成器文件”菜单中打开.fxml文件,效果会很好。

我创建了方法public void createLight(){light=new PointLight(Color.WHITE);cameraTransformer.getChildren().add(light);light.setTranslateX(perspectiveCamera.getTranslateX());light.setTranslateY(perspectiveCamera.getTranslateY());light.setTranslateZ(perspectiveCamera.getTranslateZ());}并在场景内调用()但是它不工作,我还需要什么?你有一个
cameraTransformer
?否则,
light
是一个节点,你必须将它添加到场景图中,所以将它添加到组是的,我有:createSurface();createLight();group.getChildren().addAll(surface,light);将
cameraTransformer
添加到组中,而不是
light
节点。如果我在方法
createLight()中添加它
在我拥有它的地方,仍然没有工作,只是在这里我将
节点添加到
摄像机变压器
。它不应该像第一个灯节点添加到摄像机变压器,然后
摄像机变压器
添加到组中吗?
import javafx.scene.PerspectiveCamera;


public class PerspectiveCamera3D extends PerspectiveCamera {

// force 3D
public PerspectiveCamera3D() {
    super(true);
}

// toss the parameter, force 3D
public PerspectiveCamera3D(final boolean fixedEyeAtCameraZero) {
    this();
}
}
@FXML
public PerspectiveCamera3D cambot;