JavaFX Shape3D : Afficher une forme géométrique en 3D

package fr.ronanlefichant.obj3d;

import javafx.animation.Interpolator;
import javafx.animation.RotateTransition;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Point3D;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.input.ScrollEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.Shape3D;
import javafx.stage.Stage;
import javafx.util.Duration;

public class App extends Application {

  private Box box;

  @Override
  public void start(Stage stage) {

    // L'objet 3d avec une couleur
    box = new Box(200, 200, 200);
    box.setMaterial(new PhongMaterial(Color.DEEPSKYBLUE));
    animateWithRotation(box);

    // Groupe contenant l'objet 3d
    Group root = new Group();
    root.getChildren().add(box);

    // Camera pour afficher l'objet 3d
    Camera perspectiveCamera = new PerspectiveCamera();

    // Scene pour afficher l'objet 3d
    Scene scene = new Scene(root, 1280, 720, Color.GRAY);
    scene.setCamera(perspectiveCamera);

    // Recentre l'objet au centre de l'écran quand la fenêtre est redimensionnée
    stage.widthProperty().addListener(this::handleWidthChanges);
    stage.heightProperty().addListener(this::handleHeightChanges);

    // Pour le zoom avec la molette
    stage.addEventHandler(ScrollEvent.SCROLL, this::handleScroll);

    // Ajoute la scene et affiche la fenêtre
    stage.setScene(scene);
    stage.show();
  }

  private void handleWidthChanges(ObservableValue < ? extends Number > obs, Number oldWidth, Number newWidth) {
    // Centre selon la largeur
    box.setTranslateX(newWidth.intValue() / 2);
  }

  private void handleHeightChanges(ObservableValue < ? extends Number > obs, Number oldHeight, Number newHeight) {
    // Centre selon la hauteur
    box.setTranslateY(newHeight.intValue() / 2);
  }

  private void handleScroll(ScrollEvent event) {
    // Ajuste le zoom selon la valeur de delta de la molette
    box.translateZProperty().set(box.getTranslateZ() + event.getDeltaY());
  }

  private void animateWithRotation(Shape3D shape) {
    RotateTransition rotationTransition = new RotateTransition(Duration.millis(2000), shape);
    // Axes de la rotation
    rotationTransition.setAxis(new Point3D(50, 10, 20));

    // Angle de 0 à 360 degrés
    rotationTransition.setFromAngle(0);
    rotationTransition.setToAngle(360);

    // Animation à vitesse constante
    rotationTransition.setInterpolator(Interpolator.LINEAR);

    // Ne s'arrête jamais
    rotationTransition.setCycleCount(Timeline.INDEFINITE);

    rotationTransition.play();
  }

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

}

Résultat :

Commentaires