トップページ > Java3D入門 > 視点移動(3)
//****************************************************************************** //マウスのドラッグで視点移動を行うCanvas3D拡張クラス“Canvas3D_ViewChange” // //Canvas3Dを継承 //MouseMotionLisenerを実装 // //コンストラクタの引数はカメラの距離とマウス感度 //さらに,コンストラクタの引数にはGraphicsConfigurationが必要(Canvas3Dと同じ仕様) // //フィールドとして,SimpleUniverse,ViewingPlatformを持つ // //球座標を使用 //動径の長さ一定,マウスのX移動はφ,マウスのY移動はθに対応 //動径の長さは“camera_distance”,初期角度は“theta”と“phi”で調節 //マウス感度は“sensitivity”で調節 //****************************************************************************** //全般のためのインポート import java.awt.*; import java.awt.event.*; //Java3D関係のインポート import javax.media.j3d.*; import javax.vecmath.*; import com.sun.j3d.utils.universe.*; import com.sun.j3d.utils.geometry.*; public class Canvas3D_ViewChange extends Canvas3D { //============================================================================= //クラスのフィールド //マウスの動きに対する感度 float sensitivity; //動径の長さ(座標中心と視点との距離) float camera_distance; //新規取得するマウスのx,y座標 int new_x, new_y; //前に取得したマウスのx,y座標 int pre_x, pre_y; //SimpleUniverseをフィールドとしてもっておく。 SimpleUniverse universe; //視点の座標変換のためのグループ TransformGroup Camera; //視点(カメラ)の座標 float camera_x, camera_y, camera_z, camera_xz, camera_xy, camera_yz = 0; //極座標のパラメータ float phi = 0;//(float)Math.PI; float theta = (float)Math.PI/3; //座標変換クラス Transform3D Transform_camera_pos; //カメラの位置 Transform3D Transform_camera_phi; //phiに関する回転 Transform3D Transform_camera_theta; //thetaに関する回転 //3次元ベクトル(カメラの位置用) Vector3f Vector_camera_pos; //============================================================================= //コンストラクタ public Canvas3D_ViewChange(float Distance, float Sensitivity, GraphicsConfiguration config) { //親クラスのコンストラクタを呼ぶ. 引数はGraphicsConfiuration. super(config); //カメラの原点からの距離を設定 camera_distance = Distance; //マウス感度を調節 sensitivity = Sensitivity; //空のSimpleUniverseを生成 universe = new SimpleUniverse(this); //============================================================================ //視点(カメラ)について設定 //============================================================================ //------------------------------------------------------------------ //カメラ全般の初期設定 //SimpleUniverseが生成したViewingPlatformを取得 ViewingPlatform vp = universe.getViewingPlatform(); //ViewingPlatformの座標変換グループとして,“Camera”を割り当てる Camera = vp.getViewPlatformTransform(); //------------------------------------------------------------------ //カメラの位置に関する初期設定 //theta関係の計算(球座標→直交座標) camera_y = camera_distance * (float)Math.sin(theta); camera_xz = camera_distance * (float)Math.cos(theta); //phi関係の計算(球座標→直交座標) camera_x = camera_xz * (float)Math.sin(phi); camera_z = camera_xz * (float)Math.cos(phi); //カメラの位置ベクトルを用意 Vector_camera_pos = new Vector3f(camera_x, camera_y, camera_z); //カメラ位置の座標変換クラスを用意 Transform_camera_pos = new Transform3D(); //初期位置設定ための座標変換を用意する。 Transform_camera_pos.setTranslation(Vector_camera_pos); //------------------------------------------------------------------ //カメラの向きに関する初期設定 //カメラの向きの座標変換クラスを用意 Transform_camera_phi = new Transform3D(); Transform_camera_theta = new Transform3D(); //カメラの向きの初期設定 Transform_camera_theta.rotX(-theta); Transform_camera_phi.rotY(phi); //------------------------------------------------------------------ //以上の設定をカメラに反映 //合成する Transform_camera_theta.mul(Transform_camera_phi); Transform_camera_pos.mul(Transform_camera_theta); //座標変換実行 Camera.setTransform(Transform_camera_pos); //============================================================================ //マウスの設定 //============================================================================ //マウス入力用のクラス,mouse_classをインスタンス化 mouse_ViewChange mouse = new mouse_ViewChange(); //このフレームにマウス入力クラスを登録 addMouseMotionListener(mouse); } //***************************************************************************** //mouse_ViewChange:マウス入力用のクラス //***************************************************************************** class mouse_ViewChange implements MouseMotionListener { //============================================================================ //マウスが動いた時に呼ばれるメソッド //============================================================================ public void mouseMoved(MouseEvent event) { //常にマウス座標を更新しておく pre_x = event.getX(); pre_y = event.getY(); } //============================================================================ //マウスがドラッグされた時に呼ばれるメソッド //============================================================================ public void mouseDragged(MouseEvent event) { //現在のx座標を取得 new_x = event.getX(); new_y = event.getY(); //thetaとphiの値を更新 theta -= sensitivity*(new_y - pre_y); phi += sensitivity*(new_x - pre_x); //=========================================================================== //極座標を直交座標へ直す //theta関係の計算(球座標→直交座標) camera_y = camera_distance * (float)Math.sin(theta); camera_xz = camera_distance * (float)Math.cos(theta); //phi関係の計算(球座標→直交座標) camera_x = camera_xz * (float)Math.sin(phi); camera_z = camera_xz * (float)Math.cos(phi); //=========================================================================== //座標変換クラスを用意する //カメラの位置ベクトルを作る Vector_camera_pos.x = camera_x; Vector_camera_pos.y = camera_y; Vector_camera_pos.z = camera_z; //座標変換クラスを初期化(重要!) Transform_camera_pos.setIdentity(); //平行移動の座標変換を用意 Transform_camera_pos.setTranslation(Vector_camera_pos); //回転の座標変換を用意 Transform_camera_theta.rotX(-theta); Transform_camera_phi.rotY(phi); //=========================================================================== //カメラの座標変換実行 //合成する Transform_camera_phi.mul(Transform_camera_theta); Transform_camera_pos.mul(Transform_camera_phi); //座標変換実行 Camera.setTransform(Transform_camera_pos); //=========================================================================== //マウス座標を更新しておく pre_x = event.getX(); pre_y = event.getY(); } } //mouse_ViewChangeここまで //***************************************************************************** }
//****************************************************************************** //Canvas3Dクラスのテスト “ViewChange_test.java” // //カラーキューブを表示させてマウスドラッグで視点移動 //****************************************************************************** //Swing関係のインポート import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; //Java3D関係のインポート import javax.media.j3d.*; import javax.vecmath.*; import com.sun.j3d.utils.universe.*; import com.sun.j3d.utils.geometry.*; public class ViewChange_test { public static void main(String args[]) { //============================================================================ //まずは、基礎フレームの設定。 //============================================================================ //メイン・ウィンドウ作成 JFrame frame = new JFrame(); //ウィンドウのサイズ設定 frame.setSize(400,400); //ウィンドウのタイトル設定 frame.setTitle("ViewChange_test"); //ウィンドウを閉じる動作の登録 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //コンテントペインを作成 JPanel cp = new JPanel(); //コンテントペイン上のレイアウトは全て手動で行う cp.setLayout(null); //フレームに、コンテントペインを登録 frame.add(cp); //============================================================================ //次にJava3D関係の設定。 //============================================================================ //現在使用している画面の、ハードウェア情報を取得する GraphicsConfiguration g_config = SimpleUniverse.getPreferredConfiguration(); //Cnavas3D_ViewChangeクラスを用意する(距離は3, マウス感度は0.01) Canvas3D_ViewChange canvas = new Canvas3D_ViewChange(3.0f, 0.01f, g_config); //3D表示領域の大きさを設定。今回はウィンドウいっぱいに表示する canvas.setBounds(0,0,400,400); //コンテントペインにCanvas3Dを登録 cp.add(canvas); //============================================================================ //3D空間を構築していきます //============================================================================ //Canvas3DクラスのSimpleUniverseを利用。 SimpleUniverse universe = canvas.universe; //オブジェクトの「枝」を1つ作る BranchGroup group1 = new BranchGroup(); //「カラーキューブ」を1つ生成 ColorCube cube = new ColorCube(0.4f); //座標変換クラスを生成 TransformGroup transform_group1 = new TransformGroup(); //座標変換の書き換えを許可 transform_group1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); //カラーキューブを座標変換クラスに登録 transform_group1.addChild(cube); //座標変換内容 Transform3D transform1 = new Transform3D(); //「枝」に座標変換クラスを登録 group1.addChild(transform_group1); //仮想空間に「枝」を登録(これは最後に・・・!) universe.addBranchGraph(group1); //ウィンドウを可視化 frame.setVisible(true); } }
またカラーキューブを回転させるだけなのですが。。。 今回は直観的に見やすい動きだと思います。動いているのは自分の「目線」です。