Go to Contents Go to Java Page
Project Looking Glass
 
 

かたち、あれこれ

 
 

LG3D で 3D アプリケーションを作るための手始めとして、デフォルトで提供されているシェイプやパネルなどにどんなものがあるか調べてみましょう。

デフォルトで提供されている形は org.jdesktop.lg3d.utils.shpe パッケージにあります。大別すると

です。これらを組みあわせることで 3D アプリケーションを組み立てることができます。

使用バージョン : Release-0.61

 

 
 

シェイプ

 
 

まずは基本的なシェイプから。org.jdesktop.lg3d.utils.shape パッケージで提供されているシェイプは 5 種類あります。

ColorCube 色つきの立方体
Box 直方体
Cone 円錐
Cylinder 円柱
Disc 円 (多角形)
Sphere

ColorCube 以外はすべて、org.jdesktop.lg3d.utils.shape.Primitive クラスの派生クラスになっています。

逆にいえば、ColorCube はお約束みたいなもんで、あまり使い道はありません。

百聞は一見にしかず。見てみましょう。

サンプルのソースコード ShapesFactory.java

プログラムの基本的なところをまずは示しておきましょう。

    public ShapesFactory() {
        Frame3D frame = new Frame3D();
        Container3D container = new Container3D();
        container.setLayout(new BookshelfLayout(true, 0.0f, 0.01f, 0.03f));
 
        // ここで生成したシェイプを含んだコンポーネントを
        // コンテナに add する
	 
        new ComponentMover(frame);
        frame.addChild(container);
 
        frame.setCapabilities();
        frame.setActive(true);
        frame.setVisible(true);
    }

3D アプリケーションの基本である Frame3D オブジェクトを生成し、そこにシェイプを保持させるための Container3D オブジェクトを add します。

Container3D オブジェクトにはレイアウトマネージャを指定しておきます。デフォルトだとレイアウトマネージャがないので、みな同じ場所に描画されてしまいます。レイアウトマネージャに関してはまた項をあらためて。

ComponentMover オブジェクトを生成しているのはこのアプリケーションをマウスで移動させられるようにするためです。

後はお約束の setCapability メソッド、setActive メソッド、setVisible メソッドを呼ぶだけです。

それでは、シェイプについて順番に表示させましょう。

まずは ColorCube です。ColorCube の作り方は簡単。大きさを与えるだけです。

    private Component3D createColorCube() {
        ColorCube cube = new ColorCube(0.01);
 
        Component3D comp = new Component3D();
        comp.addChild(cube);
 
        return comp;
    }
ColorCube
ColorCube

LG3D の単位は m (メートル) なので、0.01 は 1cm 四方の立方体を表しています。

このメソッドから戻ったら Container3D オブジェクトに add します。

実行するときは、簡単にするためにLG3D チュートリアルの runtutorial シェルスクリプトを使いました。 もちろん、config に設定ファイルを書いて実行することも可能です。

さて、実行はしたものの、このままじゃただの赤い四角です。ちょっとぐりぐりして見ましょう。

左上の Java のマークをマウスでドラッグすると、描画されているオブジェクトが回転するはずです。

これで各面に違う色がついた直方体ということがわかりました。

でも、これどこで使うんでしょうね?

さて、次は直方体です。

        Appearance app = new SimpleAppearance(1.0f, 0.6f, 0.6f, 1.0f, 
                                              SimpleAppearance.DISABLE_CULLING);
        Box box = new Box(0.01f, 0.02f, 0.005f, app);
Box Box

ColorCube クラスの時にはなかった Appearance クラスというのが登場しています。

LG3D でも、Java3D でも、形状とその見え方は別々のクラスで表すようになっています。Box クラスは形状、そして Appearance が見え方になります。

見え方には色、光、テクスチャなどが含まれます。SimpleAppearance クラスは Appearance クラスの派生クラスです。コンストラクタには RGB とアルファを指定します。

RGB が 1.0f, 0.6f, 0.6f なので、薄い赤ですね。最後の DISABLE_CULLING はここでは気にしなくて大丈夫です。お約束だと思っておいてください。

Box クラスのコンストラクタは、横、縦、奥行き、そして Apperance オブジェクトを指定します。

どんどんいきましょう。次は Cone クラスです。

        Appearance app = new SimpleAppearance(0.6f, 1.0f, 0.6f, 1.0f, 
                                              SimpleAppearance.DISABLE_CULLING);
        Cone cone = new Cone(0.01f, 0.01f, app);
Cone Cone
Cylinder Cylinder
Sphere  

Cone は半径と高さを指定して生成します。この場合、普通の円錐ですが、頂点の位置を円の中心からずらすこともできます。

なんかちょっと表示がおかしいですが、あまり気にするのはやめましょう ^^;;

Cylinder クラスも半径と高さをして生成します。傾いた円柱を生成することもできます。Sphere クラスは半径だけです。

Cylinder も描画がちょっとおかしいですが、気にしないようにしましょう。

次は、Disc クラスです。

Disc クラスは半径のほかに、円を何角形で表すかを指定します。

        Appearance app = new SimpleAppearance(1.0f, 1.0f, 0.6f, 1.0f, 
                                              SimpleAppearance.DISABLE_CULLING);
        Disc disc = new Disc(0.02f, 20, app);
Disc Disc

この例では 20 角形にしてます。

3D の物体は基本的にはポリゴンで描画するのですが、ポリゴンの形は三角形や四角形が多く使われます。

円を描画するときも、三角形のポリゴンを並べて描画します。その個数を示しているのが、Disc クラスのコンストラクタの第 2 引数です。

ためしに 5 にしたのが、右側の図です。ちゃんと 5 角形になってますね。

ところで、これらのシェイプは Java3D に対応するクラスが提供されています。ところが、LG3D のソースコードを見てみると、独自に作っているようです。

もしかすると、そのへんに Cone や Cylinder がうまく表示されていない原因があるのかもしれません。

Shapes

 

 
 

パネル

 
 

パネルは 2D アプリケーションの表示によく使用されるパーツです。

LG3D でネイティブのアプリケーションを動作させたときに、まわりに半透明の枠が描画されますが、あれがパネルです。

標準で提供されているパネルは次の 4 種類です。すべて org.jdesktop.lg3d.utils.shape パッケージです。

FuzzyEdgePanel まわりがぼやけたパネル
GlassyPanel 半透明のパネル
ImagePanel イメージ用のパネル
BevelEdgePanel まわりをベベルにしたパネル

さっそく、表示してみましょう。

サンプルのソースコード PanelsFactory.java

基本的な枠組みは ShapesFactory クラスと同じです。パネルを生成している部分だけが異なります。

まずは FuzzyEdgePanel です。

        Appearance app = new SimpleAppearance(1.0f, 0.6f, 0.6f, 1.0f, 
                                              SimpleAppearance.DISABLE_CULLING);
        FuzzyEdgePanel panel = new FuzzyEdgePanel(0.04f, 0.03f, 0.002f, app);
FuzzyEdgePanel

パネルにも Appearance は必要なので、SimpleAppearance クラスを使用しています。

FuzzyEdgePanel クラスにはいくつかコンストラクタがありますが、基本的には幅と高さとぼかし量を指定します。

上の例ではすべての辺のぼかし量が同じで 0.002f になっています。

まわりがぼやけているのが分かりますか?

次が GlassyPanel です。

        Appearance app = new SimpleAppearance(0.6f, 1.0f, 0.6f, 1.0f, 
                                              SimpleAppearance.DISABLE_CULLING);
        GlassyPanel panel = new GlassyPanel(0.08f, 0.06f, 0.01f, 0.005f, app);
GlassyPanel

FuzzyEdgePanel と違って GlassyPanel は奥行きがあるので、幅、高さ、奥行きを引数にします。

第 4 引数はエッジの幅になります。

これはどこかで見たことないですか?

そう、X11 のネイティブアプリケーションを動作させたときにまわりにあるのがこの GlassyPanel です。

このパネルを正面から見ていると四角錐台のような感じですが、実際には四角柱の中とエッジで透明度を変えているだけのようです。

錐台: 錐の上部を切り取ったような形

ImagePanel はイメージを貼りつけるためのパネルです。

            ImagePanel panel = new ImagePanel("sample.jpg", 0.08f, 0.06f);
ImagePanel

Apperance は指定せずとも OK です。

ImagePanel クラスはイメージファイルを指定するのですが、ファイルがなかった場合には FileNotFoundException 例外が発生します。また、読み込み時に IOException が発生することもあるので、try ... catch が必要です。

このパネルはイメージ以外は何もありません。右の図でタイトルバーなどが表示されているのは、タイトルバーを含んだ画像を使ったためです。

ImagePanel クラスはこのように画像を表示するには簡単に使えるのですが、問題はパフォーマンスが悪いということです。

イメージビューアー的なものを作るとしたら、ImagePanel クラスを使うよりも、自分でイメージからテクスチャを作って FuzzyEdgePanel オブジェクトに貼るほうがいいかもしれません。

最後に残ったのが BevelEdgePanel です。

        Appearance app = new SimpleAppearance(0.6f, 0.6f, 1.0f, 1.0f, 
                                              SimpleAppearance.DISABLE_CULLING);
        BevelEdgePanel panel = new BevelEdgePanel(0.08f, 0.06f, 0.01f, app);
BevelEdgePanel

ところが、これがなぞのパネルなのです。ベベルというのは盛り上げるような効果のはずなんですが... 表示してみてもぜんぜんベベルになっていないのです。

ベベル量がコンストラクタの引数になっていますが、ソースを読んでみるとベベル量は無視されてしまっているようです。

どうも FuzzyEdgePanel クラスを改造して作ってあるようで、FuzzyEdgePanel クラスのソースとかなり似ています。

この中の setSize メソッドの中で本来はベベル量に応じた処理を処理をするはずなのですが、実際には下のように 0 にされてしまっています。

        northEdge=southEdge=eastEdge=westEdge=0f;

というわけで、今のところは使い道がよくわからないパネルになってしまっています。

パネル

 

 
 

 
 

最後は影です。

影なんてどこに使うのだろうと思われるかもしれませんが、タスクバーをよく見てみてください。アイコンに影がついているのが分かりますか?

こんなところでも影がちょっとつくだけで、リアリティがずっと増してくると思います。ドロップシャドウなんてのもよく使われますね。

ということで、影です。影は 3 種類用意されています。やはり、すべて org.jdesktop.lg3d.utils.shape パッケージになります。

RectShadow 四角形の影
RoundRingShadow ドーナツ型の影
RoundShadow 円錐状の影

 

サンプルのソースコード ShadowsFactory.java

まずは RectShadow から。

        RectShadow shadow = new RectShadow(0.08f, 0.06f,                   // 幅、高さ
                                           0.002f, 0.006f, 0.005f, 0.001f, // 上、左、下、右
                                           0.01f,                          // 内側
                                           -0.01f,                         // 奥行き方向の移動量
                                           1.0f);                          // アルファ値

引数が多くありますが、それほど大変ではないです。

この影は内側の影の幅を指定することからうかがえるように、額縁みたいな影を作ります。四角の内部は黒くならないということです。

奥行き方向にシフトさせていることが分かるように、前面に ImagePanel を配置してみました。

この影はドロップシャドウには最適ですね。

RectShadow RectShadow

次は RoundRingShadow です。

        RoundRingShadow shadow = new RoundRingShadow(0.06f, 0.04f, // 外側、内側
                                                     20, 1.0f);    // 分割数、アルファ値

外側と内側の半径と、Disc クラスと同じように何角形で描画するかを引数にします。

影は内側から外側に向けてぼけるように描画されます。

RoundRingShadow

最後が RoundShadow クラスです。名前だけ聞くと円形の影のようですが...

        RoundShadow shadow = new RoundShadow(0.08f, 0.08f, 20,    // 幅、高さ、分割数
                                             0.01f, 0.02f, 0.04f, // 頂点のシフト量 x, y, z
                                             1.0f);               // アルファ値

幅、高さ、分割数はいいと思いますが、頂点のシフト量とは?

RoundShadow は中心となる点から徐々に薄くなる影を描画します。その、中心の点を移動させることができるのです。奥行き方向にもずらせるので、ちょうど円錐のような形になります。

そのままだとちょっと分かりにくいですが、回転させてみるとよくわかります。

RoundShadow RoundShadow

 

 
 

おわりに

 

 

 
RoundRingShadow

Box などの Primitives クラスの派生クラスを組みあわせて、3D のオブジェを作ることはあまりないかもしれません。3D Max などで作って、それを LG3D に持ってくるのが常道だとは思いますが、手始めにやるには Primitives クラスはいい題材だと思います。

右のロボットぐらいなら、結構簡単につくれます。

白く塗ったらパルタに似ているとかはいわないでください ^^;;

パネルは 2.5D 的なアプリケーションを作るとき、とても重宝します。そのときに影をちょっとつけるだけで、一味違う感じになります。

パネルを作るのはそれほど難しくないので、自分なりのパネルを作ってみるのもいいかもしれません。

 

今回使用したサンプルはここからダウンロードできます。

 

(Mar. 2005)

 
 
Go to Contents Go to Java Page