トップページ > Java3D入門 > 視点移動(3)

視点移動クラスを作る

ソースコード : Canvas3D_ViewChange.java

//******************************************************************************
//マウスのドラッグで視点移動を行う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ここまで
 //*****************************************************************************

}

ソースコード : ViewChange_test.java

//******************************************************************************
//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);
 }
 
}

実行画面

またカラーキューブを回転させるだけなのですが。。。 今回は直観的に見やすい動きだと思います。動いているのは自分の「目線」です。




前へ   次へ