2016-05-15 8 views
2

Wie kann ich der view.fxml 3D-Oberfläche hinzufügen, gibt es kein "Ding" auf der Oberfläche des Szenenbildners. Meine Szene Builder-Hierarchie wie folgt aussieht:Wie kann ich dem AnchorPane 3D-Oberfläche hinzufügen?

Hierarchy

und SS von app - wie wir haben etwas auf der linken oberen Ecke sehen kann, sollte die Fläche, auf der Mitte sein. enter image description here

ich zuerst nur einige Beispiele von 3D-Oberfläche hinzufügen möchten: Mein Controller-Code:

package sample.packet3D; 

import org.fxyz.cameras.CameraTransformer; 

import javafx.beans.InvalidationListener; 
import javafx.beans.Observable; 
import javafx.fxml.FXML; 
import javafx.scene.Group; 
import javafx.scene.PerspectiveCamera; 
import javafx.scene.PointLight; 
import javafx.scene.layout.AnchorPane; 


public class Window3DController { 

    @FXML 
    private AnchorPane anchorPane; 
    @FXML 
    private Group group; 

    private Window3DBuilder window3dBuilder; 
    private PerspectiveCamera perspectiveCamera; 



    @FXML 
    public void initialize() { 
     perspectiveCamera = new PerspectiveCamera(true); 

     window3dBuilder = new Window3DBuilder(group, perspectiveCamera); 
     window3dBuilder.createScene(); 



     group.sceneProperty().addListener(new InvalidationListener() { 

      @Override 
      public void invalidated(Observable observable) { 
       group.getScene().setCamera(perspectiveCamera); 
       group.sceneProperty().removeListener(this); 
      } 
     }); 
    } 
} 

Logic Klasse:

package sample.packet3D; 


import org.fxyz.cameras.CameraTransformer; 
import org.fxyz.shapes.primitives.SurfacePlotMesh; 

import javafx.geometry.Point3D; 
import javafx.scene.Group; 
import javafx.scene.PerspectiveCamera; 
import javafx.scene.PointLight; 
import javafx.scene.SceneAntialiasing; 
import javafx.scene.SubScene; 
import javafx.scene.layout.AnchorPane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.CullFace; 
import javafx.scene.shape.TriangleMesh; 
import javafx.scene.transform.Rotate; 

public class Window3DBuilder { 

    private Group group; 
    private SurfacePlotMesh surface; 
    private PerspectiveCamera perspectiveCamera; 
    private CameraTransformer cameraTransformer; 
    private PointLight light; 

    public Window3DBuilder(Group group, PerspectiveCamera perspectiveCamera) { 
     this.group = group; 
     this.perspectiveCamera = perspectiveCamera; 
     cameraTransformer = new CameraTransformer(); 
    } 

    public void createScene() { 

     createSurface(); 
     createLight(); 
     group.getChildren().addAll(surface); 

     cameraTransformer.setTranslate(0, 0, 0); 
     cameraTransformer.getChildren().addAll(perspectiveCamera); 

     perspectiveCamera.setNearClip(0.1); 
     perspectiveCamera.setFarClip(100000.0); 
     perspectiveCamera.setTranslateX((group.getBoundsInLocal().getMaxX() + group.getBoundsInLocal().getMinX())/2d); 
     perspectiveCamera.setTranslateY((group.getBoundsInLocal().getMaxY() + group.getBoundsInLocal().getMinY())/2d); 
     double max = Math.max(group.getBoundsInLocal().getWidth(), group.getBoundsInLocal().getHeight()); 
     perspectiveCamera.setTranslateZ(-2 * max); 

    } 

    public void createLight() { 
     light = new PointLight(Color.WHITE); 
     cameraTransformer.getChildren().add(light); 
     light.setTranslateX(perspectiveCamera.getTranslateX()); 
     light.setTranslateY(perspectiveCamera.getTranslateY()); 
     light.setTranslateZ(perspectiveCamera.getTranslateZ()); 
    } 

    private void createSurface() { 
     surface = new SurfacePlotMesh(
       p-> Math.sin(p.magnitude() + 1e-10)/(p.magnitude() + 1e-10), 
       20, 20, 100, 100, 4); 
     surface.setCullFace(CullFace.NONE); 
     surface.setTextureModeVertices3D(1530, p -> p.magnitude()); 
     surface.getTransforms().addAll(new Rotate(200, Rotate.X_AXIS), new Rotate(-20, Rotate.Y_AXIS)); 
    } 



} 

und Aussicht:

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

<?import javafx.scene.effect.*?> 
<?import javafx.scene.canvas.*?> 
<?import javafx.scene.*?> 
<?import javafx.scene.shape.*?> 
<?import javafx.scene.control.*?> 
<?import java.lang.*?> 
<?import javafx.scene.layout.*?> 

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.packet3D.Window3DController"> 
    <children> 
     <Group fx:id="group"> 
     <effect> 
      <Lighting> 
       <bumpInput> 
        <Shadow /> 
       </bumpInput> 
       <light> 
        <Light.Distant /> 
       </light> 
      </Lighting> 
     </effect> 
     </Group> 
     <PerspectiveCamera fx:id="perspectiveCamera" visible="false" /> 
    </children> 
</AnchorPane> 

Was mache ich falsch? Könnte mir jemand helfen? Auch dies ist eines der Fenster, zu denen ich durch Drücken der Taste komme.

@FXML 
    public void moveTo3DScene(ActionEvent event) throws IOException { 
     Stage stage3D = (Stage) ((Node) event.getSource()).getScene().getWindow(); 
     Parent parent3D = FXMLLoader.load(getClass().getResource("packet3D/Window3DSceneView.fxml")); 
     stage3D.setTitle("Animation 3D"); 
     stage3D.setScene(new Scene(parent3D, 1200, 800)); 
     stage3D.show(); 

    } 

enter image description here

Antwort

2

Sie haben ein Problem mit PerspectiveCamera. Es hat einen booleschen Parameter namens fixedEyeAtCameraZero, der standardmäßig falsch ist, und eine sehr kleine Oberfläche wird in der oberen linken Ecke der Szene angezeigt.

Wir müssen es auf true gesetzt, so:

Wenn fixedEyeAtCameraZero wahr ist, wird die Augenposition zu festen (0, 0, 0) in den lokalen Koordinaten der Kamera

Aber leider können Sie den Parameter nicht einstellen, es gibt keine setFixedEyeAtCameraZero() Methode. Die einzige Möglichkeit, dies zu ändern, ist der Kamerakonstruktor.

Das bedeutet, dass Sie die PerspectiveCamera aus der FXML-Datei zu entfernen, und es durch Code auf den

public class Window3DController { 

    @FXML 
    private AnchorPane anchorPane; 
    @FXML 
    private Group group; 

    private Window3DBuilder window3dBuilder; 
    private PerspectiveCamera perspectiveCamera; 

    @FXML 
    public void initialize() { 
     perspectiveCamera = new PerspectiveCamera(true); 

     window3dBuilder = new Window3DBuilder(group, perspectiveCamera); 
     window3dBuilder.createScene(); 

     group.sceneProperty().addListener(new InvalidationListener() { 
      @Override 
      public void invalidated(Observable observable) { 
       group.getScene().setCamera(perspectiveCamera); 
       group.sceneProperty().removeListener(this); 
      } 
     }); 
    } 

} 

Ein letzten Schritt

Controller hinzufügen: Sie einige Parameter an die Kamera, im Grunde seine z festlegen müssen Koordinate auf der Größe des Netzes basiert:

public void createScene() { 
    createSurface(); 
    group.getChildren().addAll(surface); 

    perspectiveCamera.setNearClip(0.1); 
    perspectiveCamera.setFarClip(100000.0); 
    perspectiveCamera.setTranslateX((group.getBoundsInLocal().getMaxX() + group.getBoundsInLocal().getMinX())/2d); 
    perspectiveCamera.setTranslateY((group.getBoundsInLocal().getMaxY() + group.getBoundsInLocal().getMinY())/2d); 
    double max = Math.max(group.getBoundsInLocal().getWidth(), group.getBoundsInLocal().getHeight()); 
    perspectiveCamera.setTranslateZ(-2 * max); 
} 

Dies wird Ihre Oberfläche zeigen, aber nicht wie Sie erwarten: die Effekte, die Sie sich bewerben für 2D bestimmt:

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

<?import javafx.scene.Group?> 
<?import javafx.scene.layout.AnchorPane?> 

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Window3DController"> 
    <children> 
     <Group fx:id="group" /> 
    </children> 
</AnchorPane> 

diese Effekte entfernen, und fügen Sie sie mithilfe von Code PointLight:

public class Window3DBuilder { 

    private final Group group; 
    private SurfacePlotMesh surface; 
    private final CameraTransformer cameraTransformer; 
    private final PerspectiveCamera perspectiveCamera; 
    private PointLight light; 

    public Window3DBuilder(Group group, PerspectiveCamera perspectiveCamera) { 
     this.group = group; 
     this.perspectiveCamera = perspectiveCamera; 
     cameraTransformer = new CameraTransformer(); 
    } 

    public void createScene() { 
     createSurface(); 
     group.getChildren().addAll(surface, cameraTransformer); 

     cameraTransformer.setTranslate(0, 0, 0); 
     cameraTransformer.getChildren().addAll(perspectiveCamera); 

     perspectiveCamera.setNearClip(0.1); 
     perspectiveCamera.setFarClip(100000.0); 
     perspectiveCamera.setTranslateX((group.getBoundsInLocal().getMaxX() + group.getBoundsInLocal().getMinX())/2d); 
     perspectiveCamera.setTranslateY((group.getBoundsInLocal().getMaxY() + group.getBoundsInLocal().getMinY())/2d); 
     double max = Math.max(group.getBoundsInLocal().getWidth(), group.getBoundsInLocal().getHeight()); 
     perspectiveCamera.setTranslateZ(-2 * max); 
     createLight(); 
    } 

    public void createLight() { 
     light = new PointLight(Color.WHITE); 
     cameraTransformer.getChildren().add(light); 
     light.setTranslateX(perspectiveCamera.getTranslateX()); 
     light.setTranslateY(perspectiveCamera.getTranslateY()); 
     light.setTranslateZ(perspectiveCamera.getTranslateZ()/10); 
    } 

    private void createSurface() { 
     surface = new SurfacePlotMesh(
       p-> Math.sin(p.magnitude() + 1e-10)/(p.magnitude() + 1e-10), 
       20, 20, 100, 100, 4); 
     surface.setCullFace(CullFace.NONE); 
     surface.setTextureModeVertices3D(1530, p -> p.magnitude()); 
     surface.getTransforms().addAll(new Rotate(200, Rotate.X_AXIS), new Rotate(-20, Rotate.Y_AXIS)); 
    } 

} 

Surface

+0

Ich erstellte die Methode public void createLight() { \t Licht = neue PointLight (Color.WHITE); cameraTransformer.getChildren(). Add (hell); light.setTranslateX (perspectiveCamera.getTranslateX()); light.setTranslateY (perspectiveCamera.getTranslateY()); light.setTranslateZ (perspectiveCamera.getTranslateZ()); } und rufen Sie innerhalb der crateScene(), aber es funktioniert nicht, was brauche ich noch? – yerpy

+0

Haben Sie einen 'KameraTransformer'? Sonst ist 'light' ein Knoten, Sie müssen ihn zum Szenengraphen hinzufügen, also fügen Sie ihn zur Gruppe –

+0

hinzu Ja, ich habe: createSurface(); \t createLight(); \t group.getChildren(). AddAll (Oberfläche, hell); – yerpy

1

ich die Kamera in der .fxml Datei behalten wollte. Ich habe ein benutzerdefiniertes Steuerelement basierend auf PerspectiveCamera erstellt.

beginnt mit einer sehr einfachen Klasse ...

import javafx.scene.PerspectiveCamera; 


public class PerspectiveCamera3D extends PerspectiveCamera { 

// force 3D 
public PerspectiveCamera3D() { 
    super(true); 
} 

// toss the parameter, force 3D 
public PerspectiveCamera3D(final boolean fixedEyeAtCameraZero) { 
    this(); 
} 
} 

Exportieren in eine .jar-Datei. Starten Sie den Szenen-Generator und öffnen Sie die .fxml-Datei für den Ort, an dem die Kamera sein soll.

Öffnen Sie das Menü "Zahnrad" im Header der Bibliothek. Dann importieren Sie FXML/Jar. Importieren Sie Ihre neu erstellte .jar-Datei. Es erscheint ein Dialog, in dem Ihr Steuerelement aufgeführt ist. Nach der Bestätigung erscheint das Steuerelement im benutzerdefinierten Menü. Ihre Steuerung ist nun wie jedes andere auch betriebsbereit.

Das Kontrollkästchen "Fixed Eye ..." ist weiterhin schreibgeschützt, aber wird überprüft. Alle anderen Eigenschaften können wie gewünscht festgelegt werden. So stellen Sie die fx: id die folgenden in Ihrem Controller-Code fügen Sie einfach ...

@FXML 
public PerspectiveCamera3D cambot; 

hier etwas ausführlichere eines Beispiels ist ... https://rterp.wordpress.com/2014/07/28/adding-custom-javafx-component-to-scene-builder-2-0-part-2/

Das einzige Problem, das ich es zu tun habe Auf diese Weise verursacht das Starten von Scene Builder durch Klicken auf die .fxml-Datei in Eclipse eine Ausnahme (ich glaube, dass es sich um ein lokales Problem auf meinem Computer handelt, weil ich Dinge und ihre Arbeitsverzeichnisse starte). Es funktioniert gut, wenn ich den Szenen-Generator öffne und dann die .fxml-Datei über das Scene Builder-Menü Datei öffne.

Verwandte Themen