2013-10-25 83 views
3

總之 - 我有2個旋轉的矩形。在旋轉(通過Y軸)時,它們應該重疊於另一個 - 不幸的是,儘管180度轉彎,矩形之一「總是在前面」。如何解決這個問題?它看起來像是矩形添加到組中的順序。最後添加的那個總是在前面。疊加形狀 - 錯誤的重疊形狀行爲

場景:

package drawing.scene; 

import javafx.application.Application; 
import javafx.geometry.Point3D; 
import javafx.scene.Camera; 
import javafx.scene.Group; 
import javafx.scene.PerspectiveCamera; 
import javafx.scene.Scene; 
import javafx.scene.transform.Rotate; 
import javafx.stage.Stage; 
import drawing.objects.Clock; 
import drawing.objects.Cube; 

public class MyScene extends Application { 

    private int sceneEdgeSize = 800; 
    private int clolcSize = 400; 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     Group g = new Group(); 
     g.setTranslateX((sceneEdgeSize - clolcSize)/2f); 
     g.setTranslateY((sceneEdgeSize - clolcSize)/2f); 

     final Cube c = new Cube(clolcSize); 
     g.getChildren().add(c); 
     Thread t = new Thread(new Runnable() { 

      @Override 
      public void run() { 
       Rotate r = rotate(0, Rotate.Y_AXIS); 
       c.getTransforms().add(r); 
       double angle = 0.0; 
       while (true) { 

        r.setAngle(angle += 2); 
        try { 
         Thread.sleep(25); 
        } catch (InterruptedException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
       } 
      } 
     }); 
     t.setDaemon(true); 
     primaryStage.setScene(new Scene(g, sceneEdgeSize, sceneEdgeSize)); 
     PerspectiveCamera camera = new PerspectiveCamera(); 
     primaryStage.getScene().setCamera(camera); 
     primaryStage.show(); 
     t.start(); 

    } 

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

    public Rotate rotate(double angle, Point3D axis) { 
     return new Rotate(angle, clolcSize/2f, clolcSize/2f, 0, axis); 
    } 

} 

魔方類:

package drawing.objects; 

import javafx.collections.ObservableList; 
import javafx.scene.Group; 
import javafx.scene.Node; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Rectangle; 
import javafx.scene.shape.RectangleBuilder; 
import javafx.scene.transform.Rotate; 

public class Cube extends Group { 

    private double edgeLength = 0; 

    public Cube(double edgeLength) { 
     super(); 
     this.edgeLength = edgeLength; 
     create(); 
    } 

    private void create() { 
     final Rotate rx = new Rotate(0, Rotate.X_AXIS); 
     final Rotate ry = new Rotate(0, Rotate.Y_AXIS); 
     final Rotate rz = new Rotate(0, Rotate.Z_AXIS); 

     this.getTransforms().addAll(rx, ry, rz); 

     ObservableList<Node> children = this.getChildren(); 
     //@formatter:off 

     Rectangle rect; 

     rect = RectangleBuilder // face 
       .create() 
       .width(edgeLength-20) 
       .height(edgeLength-20) 
       .translateZ(edgeLength * 0.5) 
//     .translateY(edgeLength * 0.5) 
       // .translateX(-edgeLength * 0.5) 
       .fill(Color.LIGHTGREEN) 
       .build() 
       ; 
     children.add(rect); 
     rect = RectangleBuilder // face 
       .create() 
       .width(edgeLength-20) 
       .height(edgeLength-20) 
       .translateZ(-edgeLength * 0.5) 
//    .translateY(-edgeLength * 0.5) 
      // .translateX(-edgeLength * 0.5) 
       .fill(Color.DARKGREEN) 
       .build() 
       ; 
     children.add(rect); 


     //@formatter:on 
    } 
} 

回答

10

你應該switch depth buffering on in your scene

在這個問題的代碼主要是過時的,也是不正確的部分:

  1. 對於JavaFX 3D work,建議使用Java 8
  2. 對於構建立方體,請使用Box形狀。
  3. 對於其他幾何類型,使用一個SphereCylinderMeshView
  4. 使用PointAmbient燈,照亮你的場景。
  5. Materials應用到您的3D對象以遮蔽它們。
  6. 使用Model importers來導入複雜的網格模型。
  7. Builders已棄用。
  8. 對於處理動畫不建議產卵另一個線程,而是利用JavaFX animation package
  9. 對於你的問題的特別動畫,RotateTransition是適當的動畫。
  10. 您的解決方案不是線程安全的。您不應該修改活動場景圖中節點的屬性(例如顯示的節點的變換屬性)而不是應用程序線程(改爲使用Platform.runLater)。
  11. 你是不是有depth buffering設置爲true創建一個場景。深度緩衝標誌告訴JavaFX它應該對3D對象應用深度排序和剔除。

還要檢查你的系統支持JavaFX的3D:

System.out.println(
    "3D supported? " + 
    Platform.isSupported(ConditionalFeature.SCENE3D) 
); 

的Java 8旋轉立方體

這裏3D示例代碼是一個旋轉的立方體中的Java 8

編碼

rotatingcube

import javafx.animation.*; 
import javafx.application.Application; 
import javafx.scene.*; 
import javafx.scene.paint.*; 
import javafx.scene.shape.Box; 
import javafx.scene.transform.Rotate; 
import javafx.stage.Stage; 
import javafx.util.Duration; 

public class RotatingCube extends Application { 

    private static final double SCENE_SIZE = 300; 
    private static final double BOX_EDGE_LENGTH = SCENE_SIZE/2d; 

    private static final Color BOX_COLOR  = Color.DARKGREEN; 
    private static final Color AMBIENT_COLOR = Color.rgb(30, 30, 30); 
    private static final Color LIGHT_COLOR = Color.WHITE; 

    private static final Duration ROTATION_DURATION = Duration.seconds(4.5); 

    @Override 
    public void start(Stage stage) throws Exception { 
     Scene scene = new Scene(
       new Group(
         new AmbientLight(AMBIENT_COLOR), 
         createPointLight(), 
         createRotatingBox() 
       ), 
       SCENE_SIZE, SCENE_SIZE, 
       true, 
       SceneAntialiasing.BALANCED 
     ); 
     scene.setFill(Color.MIDNIGHTBLUE.darker().darker().darker()); 
     scene.setCamera(new PerspectiveCamera()); 

     stage.setScene(scene); 
     stage.show(); 
    } 

    private PointLight createPointLight() { 
     PointLight light = new PointLight(LIGHT_COLOR); 
     light.setTranslateX(SCENE_SIZE/2d); 
     light.setTranslateY(SCENE_SIZE/2d); 
     light.setTranslateZ(-SCENE_SIZE); 

     return light; 
    } 

    private Box createRotatingBox() { 
     final Box box = new Box(BOX_EDGE_LENGTH, BOX_EDGE_LENGTH, BOX_EDGE_LENGTH); 
     box.setTranslateX(SCENE_SIZE/2d); 
     box.setTranslateY(SCENE_SIZE/2d); 
     box.setTranslateZ(BOX_EDGE_LENGTH/2d); 
     box.setMaterial(new PhongMaterial(BOX_COLOR)); 

     rotateAroundYAxis(box); 

     return box; 
    } 

    private void rotateAroundYAxis(Box box) { 
     RotateTransition rotate = new RotateTransition(ROTATION_DURATION, box); 
     rotate.setFromAngle(0); 
     rotate.setToAngle(360); 
     rotate.setAxis(Rotate.Y_AXIS); 
     rotate.setCycleCount(RotateTransition.INDEFINITE); 
     rotate.setInterpolator(Interpolator.LINEAR); 
     rotate.play(); 
    } 

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

} 
對於兩個旋轉矩形

import javafx.animation.*; 
import javafx.application.*; 
import javafx.scene.*; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Rectangle; 
import javafx.scene.transform.Rotate; 
import javafx.stage.Stage; 
import javafx.util.Duration; 

public class RotatingRectangles extends Application { 

    private static final double SCENE_SIZE = 300; 
    private static final double EDGE_LENGTH = SCENE_SIZE/2d; 

    private static final Duration ROTATION_DURATION = Duration.seconds(4.5); 

    @Override 
    public void start(Stage stage) throws Exception { 
     System.out.println(
      "3D supported? " + 
      Platform.isSupported(ConditionalFeature.SCENE3D) 
     ); 

     Scene scene = new Scene(
       createRotatingShapes(), 
       SCENE_SIZE, SCENE_SIZE, 
       true, 
       SceneAntialiasing.BALANCED 
     ); 
     scene.setFill(Color.MIDNIGHTBLUE.darker().darker().darker()); 
     scene.setCamera(new PerspectiveCamera()); 

     stage.setScene(scene); 
     stage.show(); 
    } 

    private Group createRotatingShapes() { 
     final Rectangle rect1 = new Rectangle(
      EDGE_LENGTH, EDGE_LENGTH, 
      Color.LIGHTGREEN 
     ); 
     rect1.setTranslateX(-EDGE_LENGTH/2d); 
     rect1.setTranslateY(-EDGE_LENGTH/2d); 
     rect1.setTranslateZ(EDGE_LENGTH/2d); 

     final Rectangle rect2 = new Rectangle(
      EDGE_LENGTH, EDGE_LENGTH, 
      Color.DARKGREEN 
     ); 
     rect2.setTranslateX(-EDGE_LENGTH/2d); 
     rect2.setTranslateY(-EDGE_LENGTH/2d); 
     rect2.setTranslateZ(-EDGE_LENGTH/2d); 

     final Group shapes = new Group(
      rect1, rect2 
     ); 

     shapes.setTranslateX(SCENE_SIZE/2d); 
     shapes.setTranslateY(SCENE_SIZE/2d); 
     shapes.setTranslateZ(EDGE_LENGTH/2d); 

     rotateAroundYAxis(shapes); 

     return shapes; 
    } 

    private void rotateAroundYAxis(Node node) { 
     RotateTransition rotate = new RotateTransition(ROTATION_DURATION, node); 
     rotate.setFromAngle(0); 
     rotate.setToAngle(360); 
     rotate.setAxis(Rotate.Y_AXIS); 
     rotate.setCycleCount(RotateTransition.INDEFINITE); 
     rotate.setInterpolator(Interpolator.LINEAR); 
     rotate.play(); 
    } 

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

} 

在第一圖片中的黑色矩形已在光矩形的前面被旋轉

爪哇8 3D示例代碼。

在第一圖象的光的矩形已經在黑暗中矩形的前面轉動。

所以你可以看到,JavaFX的系統是否在現場顯示的深度整理形狀。

rotatingrectdark rotatingrectlight

+0

現在是一個很好的答案先生! +1並接受的答案爲您effoort。謝謝! – Antoniossss