JavafX 8 3D Z订单.重叠的形状行为是错误的. [英] JavafX 8 3D Z Order. Overlapping shape behaviour is wrong.

查看:309
本文介绍了JavafX 8 3D Z订单.重叠的形状行为是错误的.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个JavaFX 3D场景,在随机位置添加了一堆盒子和球体.深度顺序似乎全错了,我不确定为什么.我尝试使用 myNode.setDepthTest(DepthTest.ENABLE)但这似乎无济于事.我已经附上了一个应演示该问题的应用程序.

I have a JavaFX 3D scene with a bunch of boxes and spheres added at random locations. It seems like the depth order is all wrong and I'm not sure why. I have tried to use myNode.setDepthTest(DepthTest.ENABLE) but that doesn't seem to help. I've attached an application which should demonstrate the problem.

您知道我在这里做错了什么吗?任何帮助,不胜感激.

Any idea what I might be doing wrong here? Any help much appreciated.

import javafx.application.Application;
import javafx.application.ConditionalFeature;
import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.scene.DepthTest;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SubScene;
import javafx.scene.input.MouseEvent;
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.scene.shape.Sphere;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;

public class Array3DTest extends Application {


double mousePosX;
double mousePosY;
double mouseOldX;
double mouseOldY;
double mouseDeltaX;
double mouseDeltaY;

/**
 * This is the group which rotates 
 */
Group root3D;

/**
 * The camnera to 
 */
private Rotate rotateY;
private Rotate rotateX;
private Translate translate;

public Array3DTest( ){


}

public Group createScene(){

    // Create and position camera
    PerspectiveCamera camera = new PerspectiveCamera(true);
    camera.setFarClip(15000);
    camera.setNearClip(0.1);
    camera.setDepthTest(DepthTest.ENABLE);
    camera.getTransforms().addAll(
            rotateY=new Rotate(0, Rotate.Y_AXIS),
            rotateX=new Rotate(0, Rotate.X_AXIS),
            translate=new Translate(250, 250, -1000));

    root3D=new Group(); 
    root3D.getChildren().add(camera);
    root3D.setDepthTest(DepthTest.ENABLE);


    final PhongMaterial redMaterial = new PhongMaterial();
       redMaterial.setSpecularColor(Color.ORANGE);
       redMaterial.setDiffuseColor(Color.RED);      

    for (int i=0; i<50; i++){
         Shape3D mySphere;
        if (i%2==0)    mySphere = new Box(100,100, 100);
        else mySphere= new Sphere(30);
        mySphere.setTranslateX(Math.random()*500);
        mySphere.setTranslateY(Math.random()*500);
        mySphere.setTranslateZ(Math.random()*200);
        mySphere.setMaterial(redMaterial);
        mySphere.setDepthTest(DepthTest.ENABLE);
        root3D.getChildren().add(mySphere);
    }

    // Use a SubScene to mix 3D and 3D stuff.        
    SubScene subScene = new SubScene(root3D, 500,500);        
    subScene.setFill(Color.WHITE);
    subScene.setCamera(camera);
    subScene.setDepthTest(DepthTest.ENABLE);
    Group group = new Group();
    group.getChildren().add(subScene);

    handleMouse(subScene); 

    return group;

}

 private void handleMouse(SubScene scene) {

        scene.setOnMousePressed(new EventHandler<MouseEvent>() {

            @Override public void handle(MouseEvent me) {
                mousePosX = me.getSceneX();
                mousePosY = me.getSceneY();
                mouseOldX = me.getSceneX();
                mouseOldY = me.getSceneY();
            }
        });

        scene.setOnScroll(new EventHandler<ScrollEvent>() {
            @Override public void handle(ScrollEvent event) {
                System.out.println("Scroll Event: "+event.getDeltaX() + " "+event.getDeltaY()); 
                translate.setZ(translate.getZ()+  event.getDeltaY() *0.001*translate.getZ());   // + 


            }
        });


        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()) {
                    rotateY.setAngle(rotateY.getAngle() + mouseDeltaX * modifierFactor * modifier * 2.0);  // +
                    rotateX.setAngle(rotateX.getAngle() - mouseDeltaY * modifierFactor * modifier * 2.0);  // -
                }
                if (me.isSecondaryButtonDown()) {
                    translate.setX(translate.getX() -mouseDeltaX * modifierFactor * modifier * 5);
                    translate.setY(translate.getY() - mouseDeltaY * modifierFactor * modifier * 5);   // +
                }


            }
        });
    }

@Override
public void start(Stage primaryStage) throws Exception {
    System.out.println(
            "3D supported? " + 
                    Platform.isSupported(ConditionalFeature.SCENE3D)
            );  
    Group group=createScene();
    primaryStage.setResizable(false);
    Scene scene = new Scene(group, 500,500, true);
    primaryStage.setScene(scene);
    primaryStage.show();
}



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

}

推荐答案

由于使用的是SubScene对象,因此像对Scene那样启用深度缓冲区很方便.另外,启用抗锯齿也将有所帮助.

Since you are using a SubScene object, it's convenient that you enable deep buffer like you already do for the Scene. Also, enabling anti-aliasing will help too.

根据JavaDoc:

depthBuffer和antiAliasing标志是条件功能.分别具有默认值:false和SceneAntialiasing.DISABLED.

The depthBuffer and antiAliasing flags are conditional features. With the respective default values of: false and SceneAntialiasing.DISABLED.

因此,只需将其他构造函数用于SubScene:

So just use the other constructor for SubScene:

SubScene subScene = new SubScene(root3D, 500, 500, true, SceneAntialiasing.BALANCED);  

您会注意到其中的区别.

and you'll notice the difference.

这篇关于JavafX 8 3D Z订单.重叠的形状行为是错误的.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆