JavaFX の MeshView を試してみる その2

JavaFX

このエントリーは JavaFX の MeshView を試してみる の続きです。

今回は立方体を表示させるプログラムを組んでみます。

立方体だからといって複雑になり難しくなることはありません。

しょせん、最小構成のポリゴン(  TriangleMesh ) の集まりです。

立方体の頂点の座標は下図のようにしました。

box

 

この立方体に貼るテクスチャは次のものを使います。

duke_uv

 

これを先ほの立方体へ貼ります。

解りやすくするためにテクスチャの座標とインデックスをいれた画像を用意しました。

t_map

 

前回のエントリーをお読みになった方は下記のソースコードを見たら何をやっているか理解できるでしょう。

今回はちょっとピッキング API でお遊びをいれています。

ピッキング API で取得した情報を標準出力に表示させたり、

オブジェクトの拡大縮小をやっています。( この部分は JavaFX の標準機能だけでシンプルな 3D トイピアノをつくろう を参考にしてください。)

scene.setOnMouseClicked(event -> {
    PickResult pickResult = event.getPickResult();        
    System.out.println(“PickResult Node : ” + pickResult.getIntersectedNode());
    System.out.println(“PickResult Face : ” + pickResult.getIntersectedFace());
    System.out.println(“PickResult TexCoord : ” + pickResult.getIntersectedTexCoord());
    System.out.println(“PickResult Distance : ” + pickResult.getIntersectedDistance());          
    if (pickResult.getIntersectedNode() == meshBox) {
        Point3D point3d = pickResult.getIntersectedPoint();
        if (point3d.getX() != 0.0d && point3d.getY() != 0.0d && point3d.getZ() != 0.0d) {
            meshBox.setScaleX(abs(point3d.getX() / 100.0d) * 1.8d);
            meshBox.setScaleY(abs(point3d.getY() / 100.0d) * 1.8d);
            meshBox.setScaleZ(abs(point3d.getZ() / 100.0d) * 1.8d);
        } else {
            meshBox.setScaleX(0.5d);
            meshBox.setScaleY(0.5d);
            meshBox.setScaleZ(0.5d);
        }
    } else {
        meshBox.setScaleX(1.0d);
        meshBox.setScaleY(1.0d);
        meshBox.setScaleZ(1.0d);
    }
});

これによって得られる情報は下記のようになります。

PickResult Node : MeshView@7bc4dd1a
PickResult Face : 10
PickResult TexCoord : Point2D [x = 0.4647918545001403, y = 0.5826962887300013]
PickResult Distance : 675.187084447299

最後の PickResult Distance はカメラからの距離となります。

ついでに 3D オブジェクトの情報もとってみました。

System.out.println(“PointElementSize : ” + this.getPointElementSize());
System.out.println(“TexCoordElementSize : ” + this.getTexCoordElementSize());
System.out.println(“FaceElementSize : ” + this.getFaceElementSize());

プログラムの実行結果で得られた値は下記のようになります。

PointElementSize : 3
TexCoordElementSize : 2
FaceElementSize : 6

これらは上から 3, 2, 6 といつも同じ数値を返すようです。

私はてっきり各配列の要素数を返すものだと思い込んでいたので少しばかり悩んで時間を無駄にしてしまいました。

これらの存在意義が解らないので未だにすっきりしていないし、間違って解釈している可能性もあるので霧の中にいるような感覚が今もあります。

あと、今回は複数のフェイスで 3D オブジェクトが構築されているので次のメソッドを使用します。

javafx.scene.shape.TriangleMesh クラスの ObservableIntegerArray getFaceSmoothingGroups() メソッドです。

これを使いフェイスをグルーピングしてスムーズに表示させることが可能となるようです。

this.getFaceSmoothingGroups().addAll(
        0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5
);

上記コードは、triangle A-C-B と triangle C-D-B をグルーピング ( 0 )

triangle E-F-G と G-F-H ( 1 )、triangle A-B-E と triangle E-B-F ( 2 ) … という具合にグルーピングしていきます。

最終的にはフェイスの数と faceSmoothingGroups の配列の要素数は等しくなります。

これを間違えてもコンパイルエラーにはなりませんし、プログラムもエラーで止まることなく実行されてしまいます。

ただ肝心の 3D オブジェクトは表示されることは無いでしょう。

あっ、空だと表示されますね。(当たり前か)

さて、この機能なんですが本当に効果があるのでしょうか?

私の環境では違いを確認できませんでした。

このような小さなプログラムでは効果が確認できないのかもしれません。

最後にこのプログラムの動画を貼っておきますので興味のある方はご覧くださいませ。

 

JavaFX 楽しすぎるから年末の TODO が減らない! どうしよう(>_<。)

Hatena タグ:

« »

Leave a Reply

* が付いている項目は、必須項目です!

次の HTML タグと属性を利用できます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

*

Trackback URL