2016-10-14 12 views
1

ここに私のコードです。あなたは自分自身で問題を見るために、私が執筆したものをコピーして貼り付けることができます。3Dシーンで2Dノードを選択する方法は?

public class MyApp extends Application { 

    @Override 
    public void start(Stage stage) throws Exception { 

     Scene scene = new Scene(new MyView(), 100, 150); 
     stage.setScene(scene); 
     stage.show(); 
    } 

    private class MyView extends BorderPane { 

     MyView() { 

      GridPane board = new GridPane(); 
      int size = 3; 
      for (int i = 0; i < size*size; i++) { 
       BorderPane pane = new BorderPane(); 
       pane.setMinSize(30, 30); 
       pane.setBackground(new Background(new BackgroundFill(Color.RED, null, null))); 
       pane.setBorder(new Border(new BorderStroke(null, BorderStrokeStyle.SOLID, 
                  null, null, null))); 
       pane.setOnMousePressed(e -> { 
        PickResult pick = e.getPickResult(); 
        Pane selectedNode = (Pane) pick.getIntersectedNode(); 
        selectedNode.setBackground(new Background(new BackgroundFill(Color.GREEN, null, null))); 
       }); 
       board.add(pane, i/size, i % size); 
      } 
      Box box = new Box(20d, 20d, 20d); 
      BorderPane boardPane = new BorderPane(box, null, null, board, null); 
      Group root = new Group(boardPane); 

      SubScene scene = new SubScene(root, USE_PREF_SIZE, USE_PREF_SIZE, true, SceneAntialiasing.BALANCED); 
      scene.widthProperty().bind(widthProperty()); 
      scene.heightProperty().bind(heightProperty()); 

      setCenter(scene); 
     } 
    } 

    public static void main(String[] args) throws Exception { 

     launch(args); 
    } 
} 

私は、正方形のグリッドとサブシーンを作成します。私が正方形を押すと、背景が色を変えたい。私はデプスバッファ

またはその両方でのシーンを設定しない場合、私はboardPane

  • にボックスを追加しない場合

    1. :これは2つの状況で動作します。しかし、私は両方のボックスを追加し、深さのバッファを設定する場合、四角形はイベントを受信しません。代わりにboardPaneがそれを受信します。私はそれが3Dシーンの2Dノードと関係があると思います。

      私はこれらの方法の組み合わせを設定しようとしました:setPickOnBoundssetDepthTestsetMouseTransparent何も働いていません。

      解決策は何ですか?

  • 答えて

    1

    3Dシーンを作成したら、2Dノードなどは実際にはありません。シーングラフのすべてにx、y、z座標があります。デプスバッファがfalseに設定されていた場合、以前は2Dノードとして扱われていました。

    ルートペインにペインを配置すると、ルートペインのペインはボックスの3D座標を仮定します。ピッキング目的のために、定義したボックスは、3D空間でz座標-10〜10で表されるので、ルート境界枠はピッキング目的で-10と定義されます。ルート境界枠内に配置された境界枠には、z座標が定義されていないため、z座標が0になります。これは、ビューアーの視点からルート境界枠の後ろにあります。

    ルートボーダーペインはクリックを受けていますが、他のz平面上にあるため、定義した他の2Dスクエアコンテンツはクリックを受けません。ルートペインが色を持たないのでレンダリングされないので、透明で扱われ、クリックは子ノードに送られますが、3DピッキングアルゴリズムがJavaFXは機能します。

    たとえば、すべてのZ平面を取得して正しく動作させるには、forループ内に次の行を追加してください:pane.setTranslateZ(-10);

    注:私は(私にはマウスクリックの対象とX、Y、Zピック結果各クリックのための座標を報告した)ソースコードに次の行を追加することで、これをデバッグ:

    root.setOnMouseClicked(System.out::println); 
    

    私の助言は、2D空間用に設計されたレイアウトペイン(たとえば枠線枠)を使用して3D空間内に要素をレイアウトすることを避けることです。 JavaFXのレイアウトペインは、実際には2Dレイアウトのためのものです。 3D空間での配置を処理するには、Paneから派生したものではなくGroupを使用するだけで、自分で座標を管理する必要があります。少なくとも、結果を混乱させる可能性があるため、3D要素を2Dレイアウトペインに追加することはお勧めしません。

    2次元と3次元のアイテムを別々のサブシーンに配置することでさらに分離することができます(これは実際にはJavaFXのintention of the sub sceneの考え方です)。複数のサブシーンを持つアプリケーションの例を次の回答に示します。How to create custom 3d model in JavaFX 8?

    +0

    ありがとう。私は、ルートペインにイベントを受け取らないようにする方法があると思っていましたが、 'pickOnBounds'や' setMouseTransparent'のようなもので子ペインを受け取ります。確かに実際の解決策は、2Dと3Dを混在させないように言われているようです。 – Mark

    関連する問題