1

如何为 fxyz3d 形状指定材质?当我添加到 3D 对象的 JavaFX 组时,fxyz3d 节点

    Cone cone = new Cone(coneFacets, coneRadius, coneHeight);
    cone.setMaterial(Materials.redMaterial());

无论指定的材料是什么,它都会将该组中的每个形状变成纯黑色,而不仅仅是圆锥体。如果我注释掉上面的两行和将圆锥添加到组中的那一行,其他形状的所有显示都会返回到它们指定的外观。

我正在使用 javafx-sdk-17.0.1、fxyz3d-0.5.4.jar、JavaSE-16、Windows 10。Javadoc 在任何地方都可用于 fxyz3d 吗?还是需要下载源码并在本地构建?

redMaterial 定义为

   final PhongMaterial material = new PhongMaterial();
   material.setDiffuseColor(Color.INDIANRED);
   material.setSpecularColor(Color.RED);

以下代码将重现这一点。照原样,圆锥体和圆柱体都显示为黑色。注释掉创建和添加锥体的四行,圆柱体将显示为材料指定的红色。(不要将此作为起点示例,因为在用户调整舞台窗口大小时自动缩放也存在问题尚未解决。)

package org.javafxtests;

import org.fxyz3d.shapes.Cone;

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SubScene;
import javafx.scene.control.Label;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Cylinder;
import javafx.stage.Stage;

public class JxyzConeMaterials extends Application {
    
    // https://www.tutorialspoint.com/javafx/index.htm
    // https://www.javatpoint.com/javafx-tutorial
    // https://openjfx.io/javadoc/11/
    
    /**
     * The application initialization method.
     */
    @Override
    public void init() throws Exception {
        super.init();
    }

    /**
     * Main entry point for all JavaFX applications. The start method is called
     * after the init method has returned and the JavaFX framework and hosting
     * system are ready to start the application.
     */
    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("Test JXzy Cone materials");
        
        double sceneWidth = 750.0d;
        double sceneHeight = 500.0d;
        
        // The scene structure is constructed from the inside-out (bottom-up).
        
        // A tool bar goes along the top
        final FlowPane toolbar = new FlowPane();
        toolbar.setPrefWidth(Double.MAX_VALUE); 
        toolbar.getChildren().addAll(new Label("Files"));   
            
        // A TreeView goes down the left side
        final TreeView<String> treeView = new TreeView<String>();       
        treeView.setPrefHeight(Double.MAX_VALUE);
        TreeItem<String> treeRoot = new TreeItem<String>("<empty>");
        treeView.setRoot(treeRoot); 
        
        // A SubScene for viewing 3D objects goes to the right of the TreeView
        final SubScene canvasScene = new SubScene(new AnchorPane(), 0, 0);  
        final AnchorPane canvasRootPane = (AnchorPane) canvasScene.getRoot();   
        canvasRootPane.setPrefWidth(Double.MAX_VALUE);
        canvasRootPane.setPrefHeight(Double.MAX_VALUE);             
        canvasScene.setWidth(0.75 * sceneWidth); // No setPref methods
        canvasScene.setHeight(sceneHeight); 
        
        // Create a controllable camera for the 3D SubScene
        final PerspectiveCamera canvasCamera = new PerspectiveCamera(true); 
        final Group cameraTruck = new Group();
        final Group cameraGimbal = new Group();     
        canvasCamera.setFarClip(6000);
        canvasCamera.setNearClip(0.01);  
        cameraGimbal.getChildren().add(canvasCamera);           
        cameraTruck.getChildren().add(cameraGimbal);
        cameraTruck.setTranslateZ(-500.0d);        
        canvasScene.setCamera(canvasCamera);
        canvasRootPane.getChildren().add(cameraTruck);        
        
        // Create an HBox at the bottom of the scene,
        // TreeView on the left and 3D canvas on the right.
        HBox treeAnd3dViews = new HBox(treeView, canvasScene);  
        treeAnd3dViews.setFillHeight(true);
        HBox.setHgrow(canvasScene, Priority.ALWAYS);    
        treeAnd3dViews.setMaxHeight(Double.MAX_VALUE);  
        treeAnd3dViews.setMaxWidth(Double.MAX_VALUE);           
        
        // Create a VBox to stack the tool bar over the above.
        VBox toolbarOverViews = new VBox(toolbar, treeAnd3dViews);
        toolbarOverViews.setMaxWidth(Double.MAX_VALUE);
        toolbarOverViews.setMaxHeight(Double.MAX_VALUE);
        VBox.setVgrow(treeAnd3dViews, Priority.ALWAYS);     
        
        AnchorPane.setTopAnchor(toolbarOverViews, 0.0);
        AnchorPane.setBottomAnchor(toolbarOverViews, 0.0);
        AnchorPane.setLeftAnchor(toolbarOverViews, 0.0);
        AnchorPane.setRightAnchor(toolbarOverViews, 0.0);
        
        final Scene scene = new Scene(new AnchorPane(), sceneWidth, sceneHeight);       
        final AnchorPane sceneRootPane = (AnchorPane) scene.getRoot();
        sceneRootPane.getChildren().add(toolbarOverViews);  
                
        // Draw an arrow consisting of a cylinder with a cone on top.
        double lineRadius = 1.0d;
        double lineLength =  25.0d;     
        int coneFacets = 6;
        double coneRadius = 3.0d;
        double coneHeight = 6.0d;

        final PhongMaterial material = new PhongMaterial();
        material.setDiffuseColor(Color.INDIANRED);
        material.setSpecularColor(Color.RED);       
        Cylinder cylinder = new Cylinder(lineRadius, lineLength);
        cylinder.setMaterial(material);
        Cone cone = new Cone(coneFacets, coneRadius, coneHeight);
        cone.setMaterial(material);
        // The cone points in the negative Y direction
        cone.setTranslateY(-(lineLength / 2.0d) - coneHeight );             
        canvasRootPane.getChildren().add(cylinder);
        canvasRootPane.getChildren().add(cone);     
        
        // Show
        primaryStage.setScene(scene);
        primaryStage.show();  
    }

    @Override
    public void stop() throws Exception {
        super.stop();
    }

    /**
     * Main method to launch the application with parameters if needed.
     * This may or may not be called, depending on how this application
     * is launched.
     * 
     * @param args specifies arguments to {@linkplain Application#launch)}.
     */
    public static void main(String[] args) {
        launch(args);
    }
    
}
4

0 回答 0