トップページ > Java3D入門 > Java3Dでプリミティブを描画する(1)
Java3Dには、基本的な図形が“Primitive”(プリミティブ)として登録されています。 Primitiveには、“Box”(ボックス:直方体)、“Cone”(コーン:円錐)、 “Cylinder”(シリンダー:円柱)、“Sphere”(スフィア:球)の4つがあります。 これらのクラスのコンストラクタを呼び出せば、簡単に立体図形を作成することができます。
これらの図形を作成する際にはサイズを設定したり、色などの視覚効果を設定したり することになります。図形をコンストラクトする際の各種設定は、自作のポリゴンの時も 同じです。今回は図形をコンストラクトする際の共通操作についてまとめます。
ここでは例として、Boxクラスのコンストラクタを見てみます。
他にもBoxクラスのコンストラクタは存在しますが、 今回は説明の都合で最も使用頻度が高いと思われる上のコンストラクタ を使います。最初の3つの引数はBoxの寸法を示しています。 “xdim”というのは、x方向のdimension(ディメンション:寸法)の略です。同様にy方向の寸法、z方向の 寸法を設定します。最後の“Appearance”(アピアランス:外観)apという引数はAppearanceクラスのオブジェクトです。 このAppearanceに、色などの外見の要素を設定することになります。
Appearanceクラスには、さらに“Material”(マテリアル:材質)クラスのオブジェクトが含まれ、 このMaterialに具体的な色や光の反射の設定などを行います。ほかにAppearanceに登録されるのは、 図形に貼られるテクスチャや図形表示の形式があります。 テクスチャというのは、表面に貼る模様のついた紙のイメージです。自分で用意した画像を 図形表面に貼ることができます。また、図形表示の形式を変更すれば、図形の骨組だけを 表示させたり、頂点だけを表示させたりすることができます。今回はMaterialに関する話だけを掘り下げます。 テクスチャ等については別のページで解説します。
Materialで設定できる項目は、大きくわけて
…の2つです。「各種」の色と書いているのは、発色する方法の違いで別々に色を設定できるからです。 何も設定しない場合はデフォルトで無色となります。また、今回は光沢の設定はしません。 デフォルトで中くらいの光沢になります。
今回はMaterialの中でも、最も直観的に分かりやすい“DiffuseColor”(ディフューズ・カラー)だけを
設定します。“Diffuse”は「拡散」という意味なので、DiffuseColorを直訳すると「拡散光」となります。
これは、その物体に光源の光が当たった時に反射する光の色というイメージです。
物理っぽい話になりますが、物に色がついて見えるのは様々な色の成分(スペクトル)を含んだ
白色光が物体に当たった際に、光の中のある波長のエネルギーだけが物体へ移るからでした。
電子が励起されるとか、失われた色に対して補色の関係にある色が発色して見える…というやつです。
“DiffuseColor”で設定される「色」は、その原理による発色をシミュレートしています。 物理的な意味で、「物体そのものの色」という感じでしょうか。これは、 ライトを設定しないで図形をuniverse中に置くだけでは、 真っ暗で何も見えなかったことからも納得できます。 しかし、現実世界では物体そのものが光っている場合も考えられます。 そういった物体の発色など、Materialクラスには他にもいろいろ色の設定パラメーターがあります。 (今回はスルーします。)
それでは、具体的にMaterialに色情報を登録する手順を見ていきます。 MaterialにDiffuseColorを設定するには、“setDiffuseColor()”メソッドを使います。 メソッドの名前そのまんまですね。。。
setDiffuseColor(float Red , float Green , float Blue)上に示した引数のメソッドを使います。(実はもう1つ別にある)引数を見ればわかりますが、 赤・緑・青の光の3原色をそれぞれどのくらいの強さで含めるかを設定します。 これは加法混色なので、すべて最大の1.0fに設定すると「白」になります。 逆に、すべてを最小の0.0fに設定すると「黒」になります。 あとは、どんな色になるか自分でパラメーターをいじって遊ぶのが早いと思います(^^;
それでは、Appearanceの生成、Materialの生成、MaterialへDiffuseColorを設定するところまで テストプログラムで確認してみます。以下のソースコードをコピペして “DiffuseColor_test.java”の名前で保存、コンパイルします。 このソースコードの内容は、「Java3Dでグラフィクスを扱う準備」 のライトについてのところのソースコードと ほとんど同じです。よって、説明済みの箇所についてはコメントを省いています。
//******************************************************************************
//Java3D DiffuseColor_test
//プリミティブに色をつけて表示
//******************************************************************************
//==============================================================================
//インポート・ファイル
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.Box;
import javax.vecmath.*;
import java.awt.*;
import javax.swing.*;
//==============================================================================
//メイン・クラス
public class DiffuseColor_test
{
//=============================================================================
//メイン・メソッド
public static void main(String[] args)
{
DiffuseColor_test test = new DiffuseColor_test();
}
//=============================================================================
//コンストラクタ
public DiffuseColor_test()
{
//============================================================================
//まずは、基礎フレームの設定。
//============================================================================
JFrame frame = new JFrame();
frame.setSize(250,250);
frame.setTitle("DiffuseColor_test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel cp = new JPanel();
cp.setLayout(null);
frame.add(cp);
//============================================================================
//次にJava3D関係の設定。
//============================================================================
GraphicsConfiguration g_config = SimpleUniverse.getPreferredConfiguration();
Canvas3D canvas = new Canvas3D(g_config);
canvas.setBounds(0,0,250,250);
cp.add(canvas);
//============================================================================
//空のSimpleUniverseを生成。
//============================================================================
SimpleUniverse universe = new SimpleUniverse(canvas);
frame.setVisible(true);
//============================================================================
//視点の設定
//============================================================================
ViewingPlatform camera = universe.getViewingPlatform();
camera.setNominalViewingTransform();
//============================================================================
//ライトの設定
//============================================================================
Color3f light_color = new Color3f(1.7f,1.7f,1.7f);
Vector3f light_direction = new Vector3f(0.2f,-0.2f,-0.6f);
DirectionalLight light = new DirectionalLight(light_color,light_direction);
BoundingSphere bounds = new BoundingSphere();
light.setInfluencingBounds(bounds);
BranchGroup group2 = new BranchGroup();
group2.addChild(light);
universe.addBranchGraph(group2);
//============================================================================
//プリミティブの設定をして、SimpleUniverseに追加
//============================================================================
//Appearanceクラスのインスタンス生成
Appearance appearance = new Appearance();
//Materialクラスのインスタンス生成
Material material = new Material();
//DiffuseColorを設定します。引数は順に赤、緑、青です。今回は水色・・・。
material.setDiffuseColor(0.0f,0.5f,0.5f);
//AppearanceにMaterialを登録
appearance.setMaterial(material);
//Box用のBranchGroupを生成
BranchGroup group1 = new BranchGroup();
//Box生成。引数はサイズと外見
Box box = new Box(0.5f,0.5f,0.5f,appearance);
//BranchGroupにBoxオブジェクトを追加
group1.addChild(box);
//SimpleUniverseにBranchGroupを追加
universe.addBranchGraph(group1);
}
}
//ソースコードここまで。
//******************************************************************************
立方体・・・じゃないですね。ただの「四角」です(汗)
これは、デフォルトでカメラを設定した場合に図形を真正面から見る位置に設定されるからです。
立方体も、1つの面だけを見たらただの正方形ですね・・・。
カメラを移動させるためには座標変換が必要なので、また後でやります。
色が付いているので、とりあえずDiffuseColorのテストができれば良いということで。
以降、ソースコードの解説です。新しく追加した部分についてのみです。
気づきにくいですが、前回まで“import com.sun.j3d.utils.geometry.*”となっていたところが、 今回は“import com.sun.j3d.utils.geometry.Box;”となっています。 “…geometry.*”と書くと、geometry階層のクラスファイルが全て読み込まれます。 この中にBoxクラスが含まれています。このほうが他のプリミティブも一括して読み込めるので便利なのですが、 今回使用するBoxクラスと同名のクラスがjavax.swingにも含まれているそうです。コンパイルすると エラーが出ます。よって、「Java3Dのgeometryの中の“Box”だよ」とコンパイラに 知らせるために、“…geometry.Box”と限定して書いています。 すごく地味ですが、今後Boxを使う時は注意したい点です。
コメントの通りです。非常に単純な操作しか行っていません。 Materialを設定して、Appearanceに登録、さらにそれを使ってPrimitiveのBoxを生成…と ややこしいのですが、この手順は他のPrimitiveを生成する時に毎回繰り返すことになります。 今のうちに押さえておくと楽です。