How do I set fxyz3d shape materials so they work?

81 views Asked by At

How do I specify a material for an fxyz3d shape? When I add to a JavaFX Group of 3D objects the fxyz3d node

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

it turns every shape in that group solid black, not just the cone, regardless of what any of the specified materials are. If I comment out the above two lines and the one that adds the cone to the group, all the displays of the other shapes return to their specified appearances.

I am using javafx-sdk-17.0.1, fxyz3d-0.5.4.jar, JavaSE-16, Windows 10. Is Javadoc available for fxyz3d anywhere? Or is it necessary to download source and build it locally?

The redMaterial is defined as

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

The following code will reproduce this. As is, both cone and cylinder display black. Comment out the four lines that create and add the Cone, and the cylinder will display red as specified by the material. (Don't otherwise use this as a starting-point example, as there are also issues with automatic scaling as the user adjusts the stage window size yet to be addressed.)

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);
    }
    
}
0

There are 0 answers