如何动态地将JavaFX MeshView置于场景中心?

时间:2017-10-17 17:36:09

标签: java javafx 3d

我正在为.STL文件编写javafx图像生成器。我使用StlMeshImporter导入STL文件。但是,当我在javafx场景中导入文件并尝试拍摄快照时,我会为每个文件获得不同的结果,因为它们不是场景的中心。

我希望能够在场景中对其进行缩放或居中,以拍摄快照。有没有办法获得对象的宽度和高度,所以我可以设置比例因子,并自动偏移?

这是我的班级:

public class STLImageGenerator extends Application {

private static final String MESH_FILENAME
        = "./9sk02_flex_r02.stl";

private static final int VIEWPORT_SIZE = 800;

private static final double MODEL_SCALE_FACTOR = 3;
private static final double MODEL_X_OFFSET = 0;
private static final double MODEL_Y_OFFSET = 0;
private static final double MODEL_Z_OFFSET =0 ;
//  private static final int VIEWPORT_SIZE = 4096;

private static final Color lightColor = Color.rgb(204, 204, 204);
private static final Color jewelColor = Color.rgb(0, 100, 204);

final static int CANVAS_WIDTH = 512;
final static int CANVAS_HEIGHT = 512;

private Group root;
private PointLight pointLight;
Canvas canvas = null;
PerspectiveCamera perspectiveCamera = null;

static MeshView[] loadMeshViews() {
    File file = new File(MESH_FILENAME);
    StlMeshImporter importer = new StlMeshImporter();
    importer.read(file);
    Mesh mesh = importer.getImport();

    return new MeshView[]{new MeshView(mesh)};
}

private Group buildScene() {
    MeshView[] meshViews = loadMeshViews();
    System.out.println("MESHVIEWS: " + meshViews.length);
    for (int i = 0; i < meshViews.length; i++) {
        System.out.println("meshViews[i].getLayoutX():"+meshViews[i].getLayoutX());

        meshViews[i].setScaleX(MODEL_SCALE_FACTOR);
        meshViews[i].setScaleY(MODEL_SCALE_FACTOR);
        meshViews[i].setScaleZ(MODEL_SCALE_FACTOR);
        meshViews[i].setTranslateX((VIEWPORT_SIZE / 2) + MODEL_X_OFFSET-MODEL_SCALE_FACTOR);
        meshViews[i].setTranslateY((VIEWPORT_SIZE / 2) + MODEL_Y_OFFSET-MODEL_SCALE_FACTOR);
        meshViews[i].setTranslateZ((VIEWPORT_SIZE / 2) + MODEL_Z_OFFSET);



        PhongMaterial sample = new PhongMaterial(jewelColor);
        sample.setSpecularColor(lightColor);
        sample.setSpecularPower(16);
        meshViews[i].setMaterial(sample);

        //meshViews[i].getTransforms().setAll(new Rotate(38, Rotate.Z_AXIS), new Rotate(20, Rotate.X_AXIS));

    }

    pointLight = new PointLight(lightColor);
    pointLight.setTranslateX(VIEWPORT_SIZE * 3 / 4);
    pointLight.setTranslateY(VIEWPORT_SIZE / 2);
    pointLight.setTranslateZ(VIEWPORT_SIZE / 2);
    PointLight pointLight2 = new PointLight(lightColor);
    pointLight2.setTranslateX(VIEWPORT_SIZE * 1 / 4);
    pointLight2.setTranslateY(VIEWPORT_SIZE * 3 / 4);
    pointLight2.setTranslateZ(VIEWPORT_SIZE * 3 / 4);
    PointLight pointLight3 = new PointLight(lightColor);
    pointLight3.setTranslateX(VIEWPORT_SIZE * 5 / 8);
    pointLight3.setTranslateY(VIEWPORT_SIZE / 2);
    pointLight3.setTranslateZ(0);

    Color ambientColor = Color.rgb(80, 80, 80, 0);
    AmbientLight ambient = new AmbientLight(ambientColor);

    root = new Group(meshViews);

    root.getChildren().add(pointLight);
    root.getChildren().add(pointLight2);
    root.getChildren().add(pointLight3);
    root.getChildren().add(ambient);
    //root.setAutoSizeChildren(true);


    return root;
}

private PerspectiveCamera addCamera(Scene scene) {
    perspectiveCamera = new PerspectiveCamera();
    System.out.println("Near Clip: " + perspectiveCamera.getNearClip());
    System.out.println("Far Clip:  " + perspectiveCamera.getFarClip());
    System.out.println("FOV:       " + perspectiveCamera.getFieldOfView());
    perspectiveCamera.setFieldOfView(5);

    scene.setCamera(perspectiveCamera);
    return perspectiveCamera;
}

@Override
public void start(Stage primaryStage) {
    //canvas = new Canvas(VIEWPORT_SIZE, VIEWPORT_SIZE);
    Group group = buildScene();


    Scene scene = new Scene(group, VIEWPORT_SIZE, VIEWPORT_SIZE, true, SceneAntialiasing.BALANCED);
    scene.setFill(Color.rgb(255, 255, 255));
    group.setAutoSizeChildren(true);

    addCamera(scene);
    //root.getChildren().add(canvas);
    primaryStage.setMaxHeight(CANVAS_HEIGHT);
    primaryStage.setMaxWidth(CANVAS_WIDTH);

    String fname = MESH_FILENAME.substring(0, MESH_FILENAME.length() - 3) + "png";
    File file = new File(fname);



    primaryStage.setTitle("Jewel Viewer");
    primaryStage.setScene(scene);

    primaryStage.show();

    try {
        SnapshotParameters s = new SnapshotParameters();
       // s.setCamera(perspectiveCamera);
        // s.setViewport(Rectangle2D.EMPTY);
        WritableImage wim = new WritableImage(1024, 1024);
        scene.snapshot(wim);
        // WritableImage writableImage = root.snapshot(new SnapshotParameters(), null);
        RenderedImage renderedImage = SwingFXUtils.fromFXImage(wim, null);
        ImageIO.write(renderedImage, "png", file);
    } catch (Exception e) {
        e.printStackTrace();
    }
}


public static void main(String[] args) {
    System.setProperty("prism.dirtyopts", "false");
    Platform.setImplicitExit(false);
    launch(args);

}

0 个答案:

没有答案