トップページ > Java3D入門 > Java3Dの座標変換(2)
前回の解説の通り、座標変換の操作を設定するのは“Transform3D”クラスでした。 Transform3Dクラスのメソッドの中で、平行移動のためのものは“setTranslation()”(セット・トランスレイション) メソッドです。“Translation”は「翻訳」ではなく、「移動」という意味のほうです。
setTranslation()の定義を見てみます。 引数の“Vector3f trans”というのは、3つの要素を持つベクトルである、Vector3fクラスのインスタンスです。Vector3fクラスのオブジェクトは、 “vector.x=…”と要素ごとにアクセスするこもできますが、今回はコンストラクトする際に 設定する方法をとります。
Vector3f vector = new Vector3f(0.4f,0.0f,0.0f);
という感じです。これだとx方向に0.4だけ移動するベクトルを表すので、画面上だと右へ動いてみえます。
最後に、Transform3Dで座標変換を設定した後はTransformGroupクラスの中の
“setTransform()”(セット・トランスフォーム)メソッドで登録します。
“setTransform”と“setTranslation”…名前が似ててまぎらわしいですね(^^;
前者はTransformGroupクラスのメソッド、後者はTransform3Dクラスのメソッドです。
//******************************************************************************
//Java3D Translation_test
//Boxを表示
//******************************************************************************
//==============================================================================
//インポート・ファイル
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 Translation_test
{
//=============================================================================
//メイン・メソッド
public static void main(String[] args)
{
Translation_test test = new Translation_test();
}
//=============================================================================
//コンストラクタ
public Translation_test()
{
//============================================================================
//まずは、基礎フレームの設定。
//============================================================================
JFrame frame = new JFrame();
frame.setSize(250,250);
frame.setTitle("Translation_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.0f,1.0f,1.0f);
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);
//============================================================================
//Boxを作る
//============================================================================
Appearance appearance = new Appearance();
Material material = new Material();
material.setDiffuseColor(0.9f,0.75f,0.75f);
appearance.setMaterial(material);
Box box = new Box(0.3f,0.3f,0.3f,appearance);
//============================================================================
//BoxをTransfomrGroupに追加。さらにTransformGroupをBranchGroupへ登録。
//============================================================================
//BranchGroupを生成
BranchGroup group1 = new BranchGroup();
//TransformGroupを生成
TransformGroup transform_group = new TransformGroup();
//座標変換の上書きを許可
transform_group.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
//TransformGroupにBoxを登録
transform_group.addChild(box);
//BranchGroupにTransformGroupを登録
group1.addChild(transform_group);
//最後に、SimpleUniverseにBranchGroupを登録
universe.addBranchGraph(group1);
//============================================================================
//平行移動します。
//============================================================================
//平行移動のためのベクトル生成。今回は右へ0.4動かす。
Vector3f vector1 = new Vector3f(0.4f,0.0f,0.0f);
//Transform3Dを生成
Transform3D transform1 = new Transform3D();
//Transform3Dに、平行移動としてvectorを登録。
transform1.setTranslation(vector1);
//TransformGroupにTransform3Dを登録。
transform_group.setTransform(transform1);
}
}
//ソースコードここまで。
//******************************************************************************
またBoxを選んでしまいした。平行移動したところで、カメラは相変わらず正面から見るだけです。 結局ただの正方形ですね…。とりあえず右方向へ移動していることが確認できました。これ以降、 ソースコードの解説です。
単純なことだけです。BranchGroupなどを生成して、addChild()で登録する作業を繰り返しています 階層構造を改めて確認しておいてください。また、1つだけ重要なポイントがあるので、そこだけ 注目しておきます。
//座標変換の上書きを許可…というところです。これはTransformGroup内のメソッドで、座標変換の上書きを許可するものです。 TransformGroupクラスに図形を登録すると、それ以降の座標変換操作は「上書き」として 扱われます。今回は最初にTransformGroupなどによる階層構造を作って、最後に 座標変換をしています。これは上書き操作として扱われます。 そのために、この記述が必要となっています。引数の“ALLOW_TRANSFORM_WRITE” (アラウ・トランスフォーム・ライト)は座標変換の上書き許可という意味です。
また、アニメーションなどを作る場合は座標変換の繰り返しによって構成される場合が多いです。 その際も、座標変換を何度も上書きすることを許可するために、同様の記述を必要とします。
もし“ALLOW_TRANSFORM_WRITE”をセットしていないとどうなるのか、確認しておきます。
実行画面です。確かに移動していません。座標変換が受けつけられなかったからです。
コマンドプロンプトを見ると、エラーメッセージが表示されています。 “no capability to set transform”(座標変換を上書きできないっす)と書いてあります。 今後この手のエラーが出ると面倒なので、これからは全てTransformGroupを生成するときに 上書きを許可してしまいます。
冒頭に解説した通り、Vector3fを生成してTransform3Dに登録しています。 くどいですが、“setTranslation()”と“setTransform()”を逆にしないように注意します。。。