(JavaFX) 无法将 3D 对象分组并围绕设定的枢轴旋转它们

(JavaFX) Trouble Grouping 3D Objects and rotating them around a set pivot

在 JavaFX 中,我想将我在 scenebuilder 中创建的几个 3D 对象分组,并将此组用作对象以进行适当的旋转和变换。但是,对对象进行分组或对其进行翻译会导致分组的任何对象消失。

这是应用程序 class,我在其中从 'main' 控制器 class 访问对象并尝试分组...

public class MusicGeneratorGUI extends Application { // implements ActionListener

    @FXML
    private void initialize(){
    }

    @Override
    public void start(Stage mainStage) throws IOException {

        //Loading controller
        FXMLLoader loader = new FXMLLoader(getClass().getResource("main.fxml"));
        Parent root = loader.load();
        Main main = loader.getController();

        //Creating application window...
        Scene scene = new Scene(root);
        mainStage.setScene(scene);
        mainStage.setTitle("APPLICATION_NAME");
        mainStage.show();

        //Attempting an object grouping...
        Group iconGroup = new Group();
        iconGroup.getChildren().add(main.icon);
        iconGroup.getChildren().add(main.icon1);
        iconGroup.getChildren().add(main.icon2);
        iconGroup.getChildren().add(main.icon3);
        iconGroup.getChildren().add(main.icon4);
        iconGroup.getChildren().add(main.icon5);

        //Even attempting rotation on a single object causes this disappearing...
        //main.icon.translateXProperty().set(250);
        //main.icon.translateYProperty().set(300);
        //main.icon.translateZProperty().set(-1200);                  
        //Rotate rotate = new Rotate(65, new Point3D(1,0,0));
        //main.icon.getTransforms().add(rotate);
    }

    public static void main(String[] args)
    {
        launch(args);
    }
}

这就是这些对象在 'main' 控制器中实例化的方式 class...

public class Main implements Initializable {
    @FXML public Sphere icon;
    @FXML public Cylinder icon1;
    @FXML public Cylinder icon2;
    @FXML public Cylinder icon3;
    @FXML public Cylinder icon4;
    @FXML public Cylinder icon5;
}

这是 FXML 文件...

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

<?import javafx.geometry.Insets?>
<?import javafx.scene.PerspectiveCamera?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.shape.Cylinder?>
<?import javafx.scene.shape.Sphere?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="500.0" prefWidth="500.0" style="-fx-background-color: #feccff;" xmlns="http://javafx.com/javafx/15.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Main">
   <children>
      <PerspectiveCamera fx:id="camera" layoutX="249.0" layoutY="274.0" />
      <MenuBar maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="70.0" prefWidth="500.0" style="-fx-background-color: #a9e8d2; -fx-use-system-menu-bar: #cba9e8;">
        <menus>
          <Menu mnemonicParsing="false" text="Help">
            <items>
              <MenuItem mnemonicParsing="false" text="Welcome Guide" />
                  <MenuItem mnemonicParsing="false" text="Contact Us" />
            </items>
          </Menu>
          <Menu mnemonicParsing="false" text="Customise">
            <items>
              <MenuItem mnemonicParsing="false" text="Key" />
                  <MenuItem mnemonicParsing="false" text="Time Signature" />
                  <MenuItem mnemonicParsing="false" text="Instruments" />
            </items>
          </Menu>
          <Menu disable="true" mnemonicParsing="false" text="Key">
            <items>
              <MenuItem mnemonicParsing="false" text="About" />
            </items>
          </Menu>
        </menus>
         <opaqueInsets>
            <Insets />
         </opaqueInsets>
         <padding>
            <Insets left="20.0" top="25.0" />
         </padding>
      </MenuBar>
      <Sphere fx:id="icon" layoutX="250.0" layoutY="300.0" radius="150.0" AnchorPane.leftAnchor="100.0" AnchorPane.rightAnchor="100.0" AnchorPane.topAnchor="125.0" />
      <Cylinder fx:id="icon2" height="100.0" layoutX="190.0" layoutY="225.0" radius="10.0" rotate="45.0" />
      <Cylinder fx:id="icon4" height="100.0" layoutX="310.0" layoutY="225.0" radius="10.0" rotate="45.0" />
      <Cylinder fx:id="icon5" height="100" layoutX="250.0" layoutY="345.0" radius="10.0" rotate="90.0" />
      <Cylinder fx:id="icon3" height="100.0" layoutX="310.0" layoutY="225.0" radius="10.0" rotate="-45.0" />
      <Cylinder fx:id="icon1" height="100.0" layoutX="190.0" layoutY="225.0" radius="10.0" rotate="-45.0" />
   </children>
</AnchorPane>

除了您将图标移动到组节点而不是在任何地方渲染组节点之外,您实施的几乎是正确的。以下是使其工作的更改。

给 main.fxml 中的 AnchorPane 一个 fx:id

<AnchorPane fx:id="root" maxHeight="-Infinity"....

在Main.java

中包含实例变量
@FXML public AnchorPane root;

在 MusicGeneratorGUI.java

的根节点中包含 iconGroup
Group iconGroup = new Group();
iconGroup.getChildren().add(main.icon);
iconGroup.getChildren().add(main.icon1);
iconGroup.getChildren().add(main.icon2);
iconGroup.getChildren().add(main.icon3);
iconGroup.getChildren().add(main.icon4);
iconGroup.getChildren().add(main.icon5);

main.root.getChildren().add(iconGroup); // You are missing this line

或者您可以将它们分组在 fxml 本身中并处理组 id,并且可以摆脱所有上述代码。

<Group fx:id="iconGroup">
        <Sphere fx:id="icon" layoutX="250.0" layoutY="300.0" radius="150.0" AnchorPane.leftAnchor="100.0" AnchorPane.rightAnchor="100.0" AnchorPane.topAnchor="125.0" />
        <Cylinder fx:id="icon2" height="100.0" layoutX="190.0" layoutY="225.0" radius="10.0" rotate="45.0" />
        <Cylinder fx:id="icon4" height="100.0" layoutX="310.0" layoutY="225.0" radius="10.0" rotate="45.0" />
        <Cylinder fx:id="icon5" height="100" layoutX="250.0" layoutY="345.0" radius="10.0" rotate="90.0" />
        <Cylinder fx:id="icon3" height="100.0" layoutX="310.0" layoutY="225.0" radius="10.0" rotate="-45.0" />
        <Cylinder fx:id="icon1" height="100.0" layoutX="190.0" layoutY="225.0" radius="10.0" rotate="-45.0" />
    </Group>