トップページ > Java3D入門 > Java3Dの座標変換(7)
前回出てきたタイマークラスを使って、簡単なアニメーションを作ってみます。 今回は簡単に、回転の座標変換を繰り返しおこなって物体をくるくる回すだけです。 特に新しい要素はありません…
//******************************************************************************
//Java Timer_test2
//タイマーでアニメーション
//******************************************************************************
//==============================================================================
//インポート・ファイル
import java.awt.*;
import javax.swing.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.geometry.Box;
import java.util.*;
import java.util.Timer;
//==============================================================================
//メイン・クラス
public class Timer_test2
{
//=============================================================================
//フィールド
TransformGroup transform_group;
Transform3D transform1;
Transform3D transform2;
Transform3D transform3;
//=============================================================================
//メイン・メソッド
public static void main(String[] args)
{
//コンストラクタを呼ぶだけです。
Timer_test2 test = new Timer_test2();
}
//=============================================================================
//コンストラクタ
public Timer_test2()
{
//============================================================================
//まずは、基礎フレームの設定。
//============================================================================
JFrame frame = new JFrame();
frame.setSize(500,500);
frame.setTitle("Timer_test2");
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,500,500);
cp.add(canvas);
//============================================================================
//空のSimpleUniverseを生成。
//============================================================================
SimpleUniverse universe = new SimpleUniverse(canvas);
frame.setVisible(true);
//============================================================================
//視点の設定
//============================================================================
ViewingPlatform camera = universe.getViewingPlatform();
camera.setNominalViewingTransform();
//============================================================================
//ライトの設定
//============================================================================
Color3f light_color = new Color3f(1.4f,1.4f,1.4f);
Vector3f light_direction = new Vector3f(0.0f,-0.5f,-1.0f);
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);
//============================================================================
//Coneを作る
//============================================================================
Appearance appearance = new Appearance();
Material material = new Material();
material.setDiffuseColor(0.2f,0.3f,0.9f);
appearance.setMaterial(material);
Box cone = new Box(0.2f,0.2f,0.8f,appearance);
//============================================================================
//coneをTransfomrGroupに追加。さらにTransformGroupをBranchGroupへ登録。
//============================================================================
BranchGroup group1 = new BranchGroup();
transform_group = new TransformGroup();
transform_group.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
transform_group.addChild(cone);
group1.addChild(transform_group);
universe.addBranchGraph(group1);
//============================================================================
//回転の座標変換を2つ、合成します。
//============================================================================
//Transform3Dを生成
transform1 = new Transform3D();
transform2 = new Transform3D();
transform3 = new Transform3D();
//============================================================================
//タイマーの設定
//============================================================================
//タイマークラスのインスタンスを作成
Timer timer = new Timer();
//タイマーの処理内容として、Messageクラスを設定。呼び出し間隔は0.1秒に設定。
timer.schedule(new timer_task(),0,100);
}
//=============================================================================
//メインクラスの内部クラスとして、タイマーのクラスを定義
//=============================================================================
class timer_task extends TimerTask
{
//回転角を入れる変数
float rad1=0;
float rad2=0;
float rad3=0;
//タイマー割り込みによる処理内容を記述
public void run()
{
//回転角を増やします
rad1+=Math.PI/20;
rad2+=Math.PI/30;
rad3+=Math.PI/40;
//オーバーフロー防止
rad1%=(Math.PI*2);
rad2%=(Math.PI*2);
rad3%=(Math.PI*2);
//回転の座標変換実行
transform1.rotX(rad1);
transform2.rotY(rad2);
transform3.rotZ(rad3);
//座標変換を合成します。
transform2.mul(transform3);
transform1.mul(transform2);
//TransformGroupにTransform3Dを登録。
transform_group.setTransform(transform1);
}
}
}
//ソースコードここまで。
//******************************************************************************
直方体がくるくる動いている様子が確認できます。今回のプログラムではX軸まわり、Y軸まわり、Z軸まわりの 3種類の回転を組み合わせています。座標変換の合成の順番をかえてみたり、rotメソッド内の 数値の大きさを変更すると動きに変化がでます。実際に試してみてください。。。
以降、ソースコードの解説です。
//フィールド TransformGroup transform_group; Transform3D transform1; Transform3D transform2; Transform3D transform3;
今回はTransform関係のものをクラスのフィールドとしておきます。 これで他の関数からアクセスできるようになります。 (関数じゃなくてメソッド…ですね。慣れないです。)
class timer_task extends TimerTask
{
//回転角を入れる変数
float rad1=0;
float rad2=0;
float rad3=0;
//タイマー割り込みによる処理内容を記述
public void run()
{
//回転角を増やします
rad1+=Math.PI/20;
rad2+=Math.PI/30;
rad3+=Math.PI/40;
//オーバーフロー防止
rad1%=(Math.PI*2);
rad2%=(Math.PI*2);
rad3%=(Math.PI*2);
//回転の座標変換実行
transform1.rotX(rad1);
transform2.rotY(rad2);
transform3.rotZ(rad3);
//座標変換を合成します。
transform2.mul(transform3);
transform1.mul(transform2);
//TransformGroupにTransform3Dを登録。
transform_group.setTransform(transform1);
}
}
アニメーションの内容にあたる部分です。3種類の回転の座標変換を用意して、合成しています。 図形オブジェクトに作用させた座標変換は、毎回リセットされてしまいます。そのため、 どれだけ回転させたかを保存しておく変数を用意して、それを毎回増加させています。 これで、どんどん図形が回転している効果を出すことができます。 ただし、ずっと加算を繰り返していくと数値が大きすぎてオーバーフローしてしまう可能性があるので、 2πラジアンで割った値を実際には使うようにしています。