IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaFX Discussion :

Integration Fenetre 3D dans un Pane


Sujet :

JavaFX

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2014
    Messages : 11
    Points : 9
    Points
    9
    Par défaut Integration Fenetre 3D dans un Pane
    Bonjour a tous ,

    je suis novice en JavaFX je souhaite développer une application lourd avec javaFX dont le but est de préparer des chorégraphies.
    Pour cela j'ai créer une fenêtre principale en FXML ainsi qu'une fenêtre 3D ( sans passé par un fichier FXML c'est a dire directement en java) ou un mannequin pourra danser.
    Maintenant j'aimerais intégrer ma fenêtre 3D dans un des panes de ma fenêtre principale.

    Voici principale décrit avec des fichier fxml :

    Nom : View.png
Affichages : 866
Taille : 26,9 Ko

    Voici maintenant la fenêtre que j'aimerais intégrer :

    Nom : mannequin.png
Affichages : 806
Taille : 62,3 Ko

    Après de multiples essaies et recherches je n'arrive toujours pas a intégrer ma fenêtre 3D dans le pane que je lui ai réserve.

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Oui mais qu'est ce que tu appelles une "fenêtre 3D" ?
    Outre Scene, le contrôle pour faire de la 3D en JavaFX 8 s'apelle SubScene ; et utilise les éléments 3D de SceneGraph.

    Tout autre façon d'afficher de la 3D (genre Java3D ou JOGL ou même WebGL) n'est pas officiellement supportée et dans le rare cas où c'est possible tend vers l'expérimental.

    Pour le moment, aucun support officiel de Java3D, JOGL ou WebGL n'est prévu pour le JDK9, donc il faudra attendre au minimum le JDK10 pour peut-être voir cela.

    Si tu suis les posts concernant la 3D de Sean Philipps (qui travaille pour la NASA) sur Twitter : il utilise la 3D native de JavaFX.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2014
    Messages : 11
    Points : 9
    Points
    9
    Par défaut
    En faite j'ai utilisé la 3D de javafx mais via la classe group et non en description FXML mais je ne sais pas comment l'integrė

  4. #4
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Normalement tu peux déclarer un contenu 3D sans soucis dans du FXML.

    Cependant, il n'est pas possible de déclarer une SubScene directement dans du FXML (la classe n'a pas de constructeur par défaut).

    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <?xml version="1.0" encoding="UTF-8"?>
     
    <?import java.lang.*?>
    <?import java.util.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
     
    <AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fxml3d.TestController">
        <SplitPane dividerPositions="0.25" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
            <items>
                <ListView />
                <StackPane id="container3D" fx:id="container3D"> 
                    <children>
                        <!--<SubScene/>--> <!-- Impossible. -->
                    </children>
                </StackPane>
            </items>
        </SplitPane> 
    </AnchorPane>

    Par contre il est possible de le faire dans le contrôleur, ce qui permet également de définir un conteneur qui va agrandir la sous-jacente lorsque son parent est redimensionné. De plus, il est possible de declarer les objets 3D dans un second fichier FXML qui sera chargé lorsque le contrôleur est chargé.

    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <?xml version="1.0" encoding="UTF-8"?>
     
    <?import java.lang.*?>
    <?import java.util.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    <?import javafx.scene.paint.*?>
    <?import javafx.scene.shape.*?>
     
    <Group id="root3D" xmlns:fx="http://javafx.com/fxml/1">
        <children>
            <Sphere radius="25" translateX="100" translateY="100">
                <material>
                    <PhongMaterial diffuseColor="RED"/> 
                </material>
            </Sphere>
        </children>
    </Group>

    Par contre il n'est pas possible de tout faire dans ce FXML (ex: le nombre de divisions de la sphère est a spécifier dans le constructeur donc on ne peut pas l'utiliser dans le FXML puisque le FXML utilise les constructeurs sans argument).

    Et pour le contrôleur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    public class TestController implements Initializable {
     
        @FXML
        private StackPane container3D;
        private Region parent3D;
        private SubScene subScene;
        private Group sceneRoot;
     
        @Override
        public void initialize(URL location, ResourceBundle resources) {
            sceneRoot = new Group();
            subScene = new SubScene(sceneRoot, 1, 1);
            subScene.setCamera(new PerspectiveCamera());
            subScene.setFill(Color.GRAY);
            parent3D = new Region() {
                {
                    getChildren().add(subScene);
                }
     
                @Override
                protected void layoutChildren() {
                    super.layoutChildren();
                    // Redimensionne la sous-scene lorsque le parent change de taille.
                    final double width = getWidth();
                    final double height = getHeight();
                    final Insets insets = getInsets();
                    final double contentX = insets.getLeft();
                    final double contentY = insets.getTop();
                    final double contentW = width - (insets.getLeft() + insets.getRight());
                    final double contentH = height - (insets.getTop() + insets.getBottom());
                    subScene.relocate(contentX, contentY);
                    subScene.setWidth(contentW);
                    subScene.setHeight(contentH);
                }
            };
            container3D.getChildren().add(parent3D);
            // Charge le contenu 3D.
            try {
                final URL fxmlURL = getClass().getResource("Content3D.fxml");
                final FXMLLoader fxmlLoader = new FXMLLoader(fxmlURL);
                final Node content3D = fxmlLoader.load();
                sceneRoot.getChildren().add(content3D);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
    Et l'application :

    Code FXML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public class TestFXML3D extends Application {
     
        @Override
        public void start(Stage primaryStage) throws IOException {
            URL url = getClass().getResource("Test.fxml");
            FXMLLoader fxmlLoader = new FXMLLoader(url);
            Node ui = fxmlLoader.load();
            StackPane root = new StackPane();
            root.getChildren().add(ui);
            Scene scene = new Scene(root, 300, 250);
            primaryStage.setTitle("Test FXML 3D");
            primaryStage.setScene(scene);
            primaryStage.show();
        }
     
        public static void main(String[] args) {
            launch(args);
        }
    }

    Donc du coup, on peut rapidement se créer un contrôle custom dans le genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    public final class Pane3D extends Region {
     
        private SubScene subScene;
     
        public Pane3D() {
            super();
            resetSubScene();
            antialiasingProperty().addListener(observable -> resetSubScene());
            contentProperty().addListener(observable -> {
                final Node content = getContent();
                final Group sceneRoot = (Group) subScene.getRoot();
                if (content != null) {
                    sceneRoot.getChildren().setAll(content);
                } else {
                    sceneRoot.getChildren().clear();
                }
            });
        }
     
        @Override
        protected void layoutChildren() {
            super.layoutChildren();
            // Redimensionne la sous-scene lorsque le parent change de taille.
            if (subScene != null) {
                final double width = getWidth();
                final double height = getHeight();
                final Insets insets = getInsets();
                final double contentX = insets.getLeft();
                final double contentY = insets.getTop();
                final double contentW = width - (insets.getLeft() + insets.getRight());
                final double contentH = height - (insets.getTop() + insets.getBottom());
                subScene.relocate(contentX, contentY);
                subScene.setWidth(contentW);
                subScene.setHeight(contentH);
            }
        }
     
        private void resetSubScene() {
            Node content = null;
            if (subScene != null) {
                final Group sceneRoot = (Group) subScene.getRoot();
                content = sceneRoot.getChildren().remove(0);
                getChildren().remove(subScene);
            }
            final Group sceneRoot = new Group();
            if (content != null) {
                sceneRoot.getChildren().add(content);
            }
            subScene = new SubScene(sceneRoot, 1, 1, true, getAntialiasing());
            subScene.setCamera(new PerspectiveCamera());
            getChildren().add(subScene);
            requestLayout();
        }
     
        private final ReadOnlyObjectWrapper<SceneAntialiasing> antialiasing = new ReadOnlyObjectWrapper<>(this, "antialiasing", SceneAntialiasing.DISABLED);
     
        public final SceneAntialiasing getAntialiasing() {
            return antialiasing.get();
        }
     
        public final void setAntialiasing(final SceneAntialiasing value) {
            final Optional<SceneAntialiasing> op = Optional.ofNullable(value);
            op.ifPresent(val -> antialiasing.set(val));
        }
     
        public final ReadOnlyObjectProperty<SceneAntialiasing> antialiasingProperty() {
            return antialiasing.getReadOnlyProperty();
        }
     
        private final ObjectProperty<Node> content = new SimpleObjectProperty<>(this, "content");
     
        public final Node getContent() {
            return content.get();
        }
     
        public final void setContent(final Node value) {
            content.set(value);
        }
     
        public final ObjectProperty<Node> contentProperty() {
            return content;
        }
    }
    Ce qui permet de tout spécifier dans un unique FXML :

    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    <?xml version="1.0" encoding="UTF-8"?>
     
    <?import java.lang.*?>
    <?import java.util.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    <?import javafx.scene.paint.*?>
    <?import javafx.scene.shape.*?>
    <?import fxml3d.*?>
     
    <BorderPane id="BorderPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fxml3d.Test2Controller">
        <top>
            <ToolBar>
                <items>
                    <CheckBox id="antialiasCheck" fx:id="antialiasCheck" text="Antialising?"/>
                </items>
            </ToolBar>
        </top>
        <center>
            <AnchorPane id="AnchorPane">
                <SplitPane dividerPositions="0.25" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                    <items>
                        <ListView />
                        <StackPane id="container3D" fx:id="container3D"> 
                            <children>
                                <Pane3D id="pane3D" fx:id="pane3D"  style="-fx-background-color: gray;">
                                    <content>
                                        <Group id="root3D">
                                            <children>
                                                <Sphere radius="25" translateX="100" translateY="100">
                                                    <material>
                                                        <PhongMaterial diffuseColor="RED"/> 
                                                    </material>
                                                </Sphere>
                                            </children>
                                        </Group>
                                    </content>
                                </Pane3D>
                            </children>
                        </StackPane>
                    </items>
                </SplitPane> 
            </AnchorPane>
        </center>
    </BorderPane>

    Avec le contrôleur qui va avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public class Test2Controller implements Initializable {
     
        @FXML
        private CheckBox antialiasCheck;
        @FXML
        private Pane3D pane3D;
     
        @Override
        public void initialize(URL location, ResourceBundle resources) {
            antialiasCheck.selectedProperty().addListener(observable -> {
                final boolean useAntialiasing = antialiasCheck.isSelected();
                final SceneAntialiasing antialising = (useAntialiasing) ? SceneAntialiasing.BALANCED : SceneAntialiasing.DISABLED;
                pane3D.setAntialiasing(antialising);
            });
        }
    }
    Et l'application qui va avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public class TestFXML3D2 extends Application {
     
        @Override
        public void start(Stage primaryStage) throws IOException {
            URL url = getClass().getResource("Test2.fxml");
            FXMLLoader fxmlLoader = new FXMLLoader(url);
            Node ui = fxmlLoader.load();
            StackPane root = new StackPane();
            root.getChildren().add(ui);
            Scene scene = new Scene(root, 300, 250);
            primaryStage.setTitle("Test FXML 3D - 2");
            primaryStage.setScene(scene);
            primaryStage.show();
        }
     
        public static void main(String[] args) {
            launch(args);
        }
    }
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2014
    Messages : 11
    Points : 9
    Points
    9
    Par défaut
    Je tiens d'abord tout particulièrement à te remercier bouye pour le temps que tu m'a accordé.

    J'ai réussi a interger ma figure dans ton exemple et c'est exactement ce que je recherchais :
    Nom : fxml_fofo_developez.png
Affichages : 737
Taille : 41,5 Ko

    Maintenant je me heurte a un second problème celui d'y insérer proprement d'une caméra. Cette camera doit pouvoir être contrôlé par l'utilisateur pour visualisé le personnage dans son ensemble. J'ai essayé de créer des cameras directement dans le Pane3D.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
     
    public final class Pane3D extends Region {
     
        private SubScene subScene;
        final PerspectiveCamera camera = new PerspectiveCamera(true);
        final Xform cameraXform = new Xform();
        final Xform cameraXform2 = new Xform();
        final Xform cameraXform3 = new Xform();
        final double cameraDistance = 450;
     
        double ONE_FRAME = 1.0 / 24.0;
        double DELTA_MULTIPLIER = 200.0;
        double CONTROL_MULTIPLIER = 0.1;
        double SHIFT_MULTIPLIER = 0.1;
        double ALT_MULTIPLIER = 0.5;
     
        double mousePosX;
        double mousePosY;
        double mouseOldX;
        double mouseOldY;
        double mouseDeltaX;
        double mouseDeltaY;
     
     
        public Pane3D() {
            super();
            resetSubScene();
            buildCamera();
    //        handleMouse(Main.scene, this);
            antialiasingProperty().addListener(observable -> resetSubScene());
            contentProperty().addListener(observable -> {
                final Node content = getContent();
                final Group sceneRoot = (Group) subScene.getRoot();
                if (content != null) {
                    sceneRoot.getChildren().setAll(content);
                } else {
                    sceneRoot.getChildren().clear();
                }
            });
        }
        public void handleMouse(Scene scene, final Node root) {
            scene.setOnMousePressed(new EventHandler<MouseEvent>() {
                @Override public void handle(MouseEvent me) {
                    mousePosX = me.getSceneX();
                    mousePosY = me.getSceneY();
                    mouseOldX = me.getSceneX();
                    mouseOldY = me.getSceneY();
                }
            });
            scene.setOnMouseDragged(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent me) {
                    mouseOldX = mousePosX;
                    mouseOldY = mousePosY;
                    mousePosX = me.getSceneX();
                    mousePosY = me.getSceneY();
                    mouseDeltaX = (mousePosX - mouseOldX);
                    mouseDeltaY = (mousePosY - mouseOldY);
     
                    double modifier = 1.0;
                    double modifierFactor = 0.1;
     
                    if (me.isControlDown()) {
                        modifier = 0.1;
                    }
                    if (me.isShiftDown()) {
                        modifier = 10.0;
                    }
                    if (me.isPrimaryButtonDown()) {
                        cameraXform.ry.setAngle(cameraXform.ry.getAngle() - mouseDeltaX * modifierFactor * modifier * 2.0);  // +
                        cameraXform.rx.setAngle(cameraXform.rx.getAngle() + mouseDeltaY * modifierFactor * modifier * 2.0);  // -
                    } else if (me.isSecondaryButtonDown()) {
                        double z = camera.getTranslateZ();
                        double newZ = z + mouseDeltaX * modifierFactor * modifier;
                        camera.setTranslateZ(newZ);
                    } else if (me.isMiddleButtonDown()) {
                        cameraXform2.t.setX(cameraXform2.t.getX() + mouseDeltaX * modifierFactor * modifier * 0.3);  // -
                        cameraXform2.t.setY(cameraXform2.t.getY() + mouseDeltaY * modifierFactor * modifier * 0.3);  // -
                    }
                }
            });
        }
     
        public void buildCamera() {
        	this.getChildren().add(cameraXform);
            cameraXform.getChildren().add(cameraXform2);
            cameraXform2.getChildren().add(cameraXform3);
            cameraXform3.getChildren().add(camera);
            cameraXform3.setRotateZ(180.0);
            camera.setNearClip(0.1);
            camera.setFarClip(10000.0);
            camera.setTranslateZ(-cameraDistance);
            cameraXform.ry.setAngle(320.0);
            cameraXform.rx.setAngle(40);
        }
    }
    Voici la Classe Xform :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
     
    public class Xform extends Group {
        public enum RotateOrder {
            XYZ, XZY, YXZ, YZX, ZXY, ZYX
        }
     
        public Translate t = new Translate();
        public Translate p = new Translate();
        public Translate ip = new Translate();
     
        public Rotate rx = new Rotate();
        {rx.setAxis(Rotate.X_AXIS);}
     
        public Rotate ry = new Rotate();
        {ry.setAxis(Rotate.Y_AXIS);}
     
        public Rotate rz = new Rotate();
        {rz.setAxis(Rotate.Z_AXIS);}
     
        public Scale s = new Scale();
     
        public Xform() {
            super();
            getTransforms().addAll(t, rz, ry, rx, s);
        }
     
        public Xform(RotateOrder rotateOrder) {
            super();
     
            //Chosse the order of rotations based on the rotateOrder
            switch(rotateOrder) {
                case XYZ:
                    getTransforms().addAll(t, p, rz, ry, rx, s, ip);
                    break;
                case XZY:
                    getTransforms().addAll(t, p, ry, rz, rx, s, ip);
                    break;
                case YXZ:
                    getTransforms().addAll(t, p, rz, rx, ry, s, ip);
                    break;
                case YZX:
                    getTransforms().addAll(t, p, rx, rz, ry, s, ip);
                    break;
                case ZXY:
                    getTransforms().addAll(t, p, ry, rx, rz, s, ip);
                    break;
                case ZYX:
                    getTransforms().addAll(t, p, rx, ry, rz, s, ip);
                    break;
            }
        }
     
        public void setTranslate(double x, double y, double z) {
            t.setX(x);
            t.setY(y);
            t.setZ(z);
        }
     
        public void setTranslate(double x, double y) {
            t.setX(x);
            t.setY(y);
        }
     
        /*
         * Cannot override these methods as they are final:
         * public void setTranslateX(double x) { t.setX(x); }
         * public void setTranslateY(double y) { t.setY(y); }
         * public void setTranslateZ(double z) { t.setZ(z); }
         * Use these methods instead:
         */
        public void setTx(double x) { t.setX(x); }
        public void setTy(double y) { t.setY(y); }
        public void setTz(double z) { t.setZ(z); }
     
        public void setRotate(double x, double y, double z) {
            rx.setAngle(x);
            ry.setAngle(y);
            rz.setAngle(z);
        }
     
        public void setRotateX(double x) { rx.setAngle(x); }
        public void setRotateY(double y) { ry.setAngle(y); }
        public void setRotateZ(double z) { rz.setAngle(z); }
     
        public void setRx(double x) { t.setX(x); }
        public void setRy(double y) { t.setY(y); }
        public void setRz(double z) { t.setZ(z); }
     
        public void setScale(double scaleFactor) {
            s.setX(scaleFactor);
            s.setY(scaleFactor);
            s.setZ(scaleFactor);
        }
        /*
         * Cannot override these methods as they are final:
         * public void setScaleX(double x) { s.setX(x); }
         * public void setScaleY(double y) { s.setY(y); }
         * public void setScaleZ(double z) { s.setZ(z); }
         * Use these methods instead:
         */
        public void setSx(double x) { s.setX(x); }
        public void setSy(double y) { s.setY(y); }
        public void setSz(double z) { s.setZ(z); }
     
        public void setPivot(double x, double y, double z) {
            p.setX(x);
            p.setY(y);
            p.setZ(z);
            ip.setX(-x);
            ip.setY(-y);
            ip.setZ(-z);
        }
     
        public void reset() {
            t.setX(0.0);
            t.setY(0.0);
            t.setZ(0.0);
            rx.setAngle(0.0);
            ry.setAngle(0.0);
            rz.setAngle(0.0);
            s.setX(0.0);
            s.setY(0.0);
            s.setZ(0.0);
            ip.setX(0.0);
            ip.setY(0.0);
            ip.setZ(0.0);
        }
     
        public void resetTSP() {
            t.setX(0.0);
            t.setY(0.0);
            t.setZ(0.0);
            s.setX(1.0);
            s.setY(1.0);
            s.setZ(1.0);
            p.setX(0.0);
            p.setY(0.0);
            p.setZ(0.0);
            ip.setX(0.0);
            ip.setY(0.0);
            ip.setZ(0.0);
        }
     
        public void debug() {
            System.out.println("t = ("+
                    t.getX()+", "+
                    t.getY()+", "+
                    t.getZ()+")"+
                    "r = ("+
                    rx.getAngle()+", "+
                    ry.getAngle()+", "+
                    rz.getAngle()+")"+
                    "s = ("+
                    s.getX()+", "+
                    s.getY()+", "+
                    s.getZ()+")");
        }
    }
    Mes questions sont les suivantes : ou dois écrire le code qui définira ma camera ? Doit on l'écrire dans du code ou bien existe t'il une solution via le fxml ?

  6. #6
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Je ne suis pas totalement sur de ce que tu essaies de faire (je n'ai que des connaissances superficielles en 3D) mais pour ce que j'en ai pu tester :
    • une camera est un nœud et donc on peut la déplacer ou la transformer telle quelle (j'ai mis une TranslateTransition sur la camera de mon code précédent et l'affichage s'anime correctement.
    • Il n'est pas possible de faire que la camera cible un point ou un nœud en particulier tout le temps, ce qui veut dire qu'il faut faire les transformations nécessaires pour l'orienter dans la bonne direction a mano lorsqu'on la deplace. Il me semble qu'un ticket a été ouvert a ce sujet sur l'ancien Jira et que ca mentionnait le JDK 9 mais aucune garantie que ca soit fait d'ici la d'autant plus que je ne trouve rien concernant ca sur le JDK bug systeme qui remplace le Jira.
    • apparemment on ne peut avoir qu'une seule et unique camera par sous-graphe du SceneGraph. J'avais pense qu'on aurait la camera maitresse attachée a la sous-scene et qui rend cette sous-scene a l'ecran et qu'il soit possible d'ajouter dans le SceneGraph des camera annexes qu'on place comme des noeuds normaux et qu'on peut attacher qq part sur un contrôle quelconque pour obtenir des "vues" rendues (genre afficher la vue de cote ou de haut de la structure 3D) mais apparemment ce n'est pas faisable. En théorie il faudrait avoir un sous-graphe du SceneGraph par vue (donc des clones/copie a l'identique de l'objet qu'on manipule) sachant qu'il est possible de partager un matériau ou des meshes entre plusieurs objets pour éviter une trop grosse utilisation mémoire.

      Sinon, il existe un proof of concept utilisant snapshot() (capture d’écran bitmap) mais il me semble que l'auteur avait indique sur StakOverflow qu'il avait des soucis avec l’éclairage (voir FXTuxCubeSV - Simultaneous Viewing - Proof of Concept en bas de page)


    Pour ce qui est de la declaration FXML, j'ai juste eut a rajouter une propriete camera :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    package fxml3d;
     
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Optional;
    import javafx.beans.property.ObjectProperty;
    import javafx.beans.property.ReadOnlyObjectProperty;
    import javafx.beans.property.ReadOnlyObjectWrapper;
    import javafx.beans.property.SimpleObjectProperty;
    import javafx.geometry.Insets;
    import javafx.scene.Camera;
    import javafx.scene.Group;
    import javafx.scene.Node;
    import javafx.scene.PerspectiveCamera;
    import javafx.scene.SceneAntialiasing;
    import javafx.scene.SubScene;
    import javafx.scene.layout.Region;
     
    public final class Pane3D extends Region {
     
        private SubScene subScene;
        private final Camera defaultCamera;
     
        public Pane3D() {
            super();
            defaultCamera = new PerspectiveCamera();
            defaultCamera.setId("defaultCamera");
            setCamera(defaultCamera);
            resetSubScene();
            cameraProperty().addListener(observable -> resetCamera());
            antialiasingProperty().addListener(observable -> resetSubScene());
            contentProperty().addListener(observable -> {
                final Node content = getContent();
                final Group sceneRoot = (Group) subScene.getRoot();
                if (content != null) {
                    sceneRoot.getChildren().setAll(content);
                } else {
                    sceneRoot.getChildren().clear();
                }
            });
        }
     
        @Override
        protected void layoutChildren() {
            super.layoutChildren();
            // Redimensionne la sous-scene lorsque le parent change de taille.
            if (subScene != null) {
                final double width = getWidth();
                final double height = getHeight();
                final Insets insets = getInsets();
                final double contentX = insets.getLeft();
                final double contentY = insets.getTop();
                final double contentW = width - (insets.getLeft() + insets.getRight());
                final double contentH = height - (insets.getTop() + insets.getBottom());
                subScene.relocate(contentX, contentY);
                subScene.setWidth(contentW);
                subScene.setHeight(contentH);
            }
        }
     
        private void resetSubScene() {
            List<Node> content = null;
            if (subScene != null) {
                final Group sceneRoot = (Group) subScene.getRoot();
                content = new LinkedList<>(sceneRoot.getChildren());
                getChildren().remove(subScene);
                subScene.setCamera(null);
            }
            final Group sceneRoot = new Group();
            if (content != null) {
                sceneRoot.getChildren().addAll(content);
            }
            subScene = new SubScene(sceneRoot, 1, 1, true, getAntialiasing());
            getChildren().add(subScene);
            resetCamera();
            requestLayout();
        }
     
        private void resetCamera() {
            if (subScene == null) {
                return;
            }
            final Camera camera = getCamera();
            subScene.setCamera(camera);
        }
     
        private final ReadOnlyObjectWrapper<SceneAntialiasing> antialiasing = new ReadOnlyObjectWrapper<>(this, "antialiasing", SceneAntialiasing.DISABLED);
     
        public final SceneAntialiasing getAntialiasing() {
            return antialiasing.get();
        }
     
        public final void setAntialiasing(final SceneAntialiasing value) {
            final Optional<SceneAntialiasing> op = Optional.ofNullable(value);
            op.ifPresent(val -> antialiasing.set(val));
        }
     
        public final ReadOnlyObjectProperty<SceneAntialiasing> antialiasingProperty() {
            return antialiasing.getReadOnlyProperty();
        }
     
        private final ObjectProperty<Node> content = new SimpleObjectProperty<>(this, "content");
     
        public final Node getContent() {
            return content.get();
        }
     
        public final void setContent(final Node value) {
            content.set(value);
        }
     
        public final ObjectProperty<Node> contentProperty() {
            return content;
        }
     
        private final ReadOnlyObjectWrapper<Camera> camera = new ReadOnlyObjectWrapper<>(this, "camera");
     
        public final Camera getCamera() {
            return camera.get();
        }
     
        public final void setCamera(final Camera value) {
            final Camera v = (value == null) ? defaultCamera : value;
            camera.set(v);
        }
     
        public final ReadOnlyObjectProperty<Camera> cameraProperty() {
            return camera.getReadOnlyProperty();
        }
    }
    Et le FXML :

    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    <?xml version="1.0" encoding="UTF-8"?>
     
    <?import java.lang.*?>
    <?import java.util.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    <?import javafx.scene.paint.*?>
    <?import javafx.scene.shape.*?>
    <?import fxml3d.*?>
     
    <BorderPane id="BorderPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fxml3d.Test2Controller">
        <top>
            <ToolBar>
                <items>
                    <CheckBox id="antialiasCheck" fx:id="antialiasCheck" text="Antialising?"/>
                    <Button id="animateCameraCheck" fx:id="animateCameraCheck" text="Move camera" onAction="#handleAnimateButton"/>
                </items>
            </ToolBar>
        </top>
        <center>
            <AnchorPane id="AnchorPane">
                <SplitPane dividerPositions="0.25" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                    <items>
                        <ListView />
                        <StackPane id="container3D" fx:id="container3D"> 
                            <children>
                                <Pane3D id="pane3D" fx:id="pane3D"  style="-fx-background-color: gray;">
                                    <camera>
                                        <ParallelCamera id="camera1" fx:id="camera1"/>
                                    </camera>
                                    <content>
                                        <Group id="root3D">
                                            <children>
                                                <Sphere radius="25" translateX="100" translateY="100">
                                                    <material>
                                                        <PhongMaterial diffuseColor="RED"/> 
                                                    </material>
                                                </Sphere>
                                                <Cylinder radius="150" height="300"  translateX="75" translateY="300" translateZ="200" >
                                                    <material>
                                                        <PhongMaterial diffuseColor="CYAN"/> 
                                                    </material>
                                                </Cylinder>
                                            </children>
                                        </Group>
                                    </content>
                                </Pane3D>
                            </children>
                        </StackPane>
                    </items>
                </SplitPane> 
            </AnchorPane>
        </center>
    </BorderPane>

    Et le contrôleur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    package fxml3d;
     
    import java.net.URL;
    import java.util.ResourceBundle;
    import javafx.animation.TranslateTransition;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.Camera;
    import javafx.scene.SceneAntialiasing;
    import javafx.scene.control.CheckBox;
    import javafx.util.Duration;
     
    public class Test2Controller implements Initializable {
     
        @FXML
        private CheckBox antialiasCheck;
        @FXML
        private Pane3D pane3D;
        @FXML
        private Camera camera1;
     
        @Override
        public void initialize(URL location, ResourceBundle resources) {
            antialiasCheck.selectedProperty().addListener(observable -> {
                final boolean useAntialiasing = antialiasCheck.isSelected();
                final SceneAntialiasing antialising = (useAntialiasing) ? SceneAntialiasing.BALANCED : SceneAntialiasing.DISABLED;
                pane3D.setAntialiasing(antialising);
            });
        }
     
        private TranslateTransition animation;
     
        @FXML
        private void handleAnimateButton() {
            if (animation == null) {
                final Camera camera = pane3D.getCamera(); // Should be camera1.
                animation = new TranslateTransition(Duration.seconds(5), camera);
                animation.setCycleCount(TranslateTransition.INDEFINITE);
                animation.setFromX(0);
                animation.setToX(100);
                animation.setFromY(0);
                animation.setToY(100);
                animation.setAutoReverse(true);
            }
            if (animation.getStatus() != TranslateTransition.Status.RUNNING) {
                animation.play();
            } else {
                animation.pause();
            }
        }
    }
    Ce qui permet dans ce test d'animer la camera et de remplacer la camera perspective par défaut par une caméra parallèle définie dans le FXML.

    PS : avant que qqun ne pose la question, actuellement on ne peut avoir que 3 sources de lumière dans une scene ([JDK-8091256] Support more than 3 lights in JavaFX 3D )
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [SDL] Integration fenetre SDL dans fenetre C# ?
    Par Amiraamir dans le forum Développement 2D, 3D et Jeux
    Réponses: 3
    Dernier message: 18/12/2010, 23h34
  2. integrer une fenetre sdl dans un environement gtk
    Par nikoul dans le forum GTK+ avec C & C++
    Réponses: 2
    Dernier message: 10/01/2010, 16h42
  3. [SDL] Integration fenetre SDL dans fenetre C# ?
    Par salammbo dans le forum OpenGL
    Réponses: 3
    Dernier message: 07/02/2005, 09h47
  4. fenetre dos dans une application
    Par jfb53 dans le forum C++Builder
    Réponses: 3
    Dernier message: 19/10/2003, 18h06
  5. integration de repertoire dans ma webapp
    Par thomy dans le forum JBuilder
    Réponses: 2
    Dernier message: 04/06/2003, 10h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo