2013-10-25 9 views
3

Короче - у меня есть 2 вращающихся прямоугольника. При вращении (по оси Y) они должны пересекаться один над другим - неудовлетворительный один из ractangles «всегда впереди», несмотря на поворот на 180 градусов. Как исправить это поведение? Похоже, что это важно для порядка в прямоугольниках whitch, добавленных в группу. Тот, который был добавлен как последний, всегда впереди.Перекрытие фигур - неправильное поведение перекрывающихся фигур

сцена:

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. Для других типов геометрии используйте Sphere, Cylinder или MeshView.
  4. Используйте Point и Ambient огни, чтобы осветить вашу сцену.
  5. Применить Materials к вашим 3D-объектам, чтобы их затенять.
  6. Используйте Model importers для импорта сложных моделей сетки.
  7. Builders устарели.
  8. Для обработки анимации не рекомендуется создавать другую нить, но использовать JavaFX animation package.
  9. Для конкретной анимации в вашем вопросе подходящей анимацией является RotateTransition.
  10. Ваше решение не является потоковым. Не следует изменять свойства узлов в графике активной сцены (например, свойства преобразования отображаемого узла) из потока приложения (вместо этого используйте Platform.runLater).
  11. Вы не создаете сцену с depth buffering, установленным в true. Флаг буферизации глубины сообщает JavaFX, что он должен применять сортировку глубины и отбрасывание трехмерных объектов.

Также проверьте, что ваша система поддерживает 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); 
    } 

} 

Java-8 3D образец кода для двух вращающихся прямоугольников

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); 
    } 

} 

В первой картине темный прямоугольник был повернут в передней части светового прямоугольника.

На первом снимке прямоугольник света был повернут перед темным прямоугольником.

Итак, вы можете видеть, что система JavaFX правильно отображает отсортированные по глубине фигуры в сцене.

rotatingrectdark rotatingrectlight

+0

Теперь это прекрасный ответ сэр! +1 и принятый ответ для вашего эффекта. Спасибо! – Antoniossss

Смежные вопросы