package jp.xronia.j3d;
//******************************************************************************
//マウスのドラッグで視点移動を行うCanvas3D拡張クラス“Canvas3DMouseMove”
//
//Canvas3Dを継承
//MouseMotionLisenerを実装
//
//コンストラクタの引数はカメラの距離
//さらに,コンストラクタの引数にはGraphicsConfigurationが必要(Canvas3Dと同じ仕様)
//******************************************************************************
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Vector3f;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.universe.ViewingPlatform;
public class Canvas3DMouseMove extends Canvas3D {
/** SerialVersionUID */
private static final long serialVersionUID = 1L;
//=============================================================================
//クラスのフィールド
//動径の長さ(座標中心と視点との距離)
float camera_distance;
// マウスの座標なんかを保存するオブジェクト
MouseEntity mouse = new MouseEntity();
//SimpleUniverseをフィールドとしてもっておく。
SimpleUniverse universe;
//視点の座標変換のためのグループ
TransformGroup camera;
//=============================================================================
//コンストラクタ
//親クラスのコンストラクタを呼ぶ. 引数はGraphicsConfiuration.
super(config);
//カメラの原点からの距離を設定
camera_distance = Distance;
//空のSimpleUniverseを生成
universe = new SimpleUniverse(this);
//============================================================================
//視点(カメラ)について設定
//============================================================================
//------------------------------------------------------------------
//カメラ全般の初期設定
//SimpleUniverseが生成したViewingPlatformを取得
ViewingPlatform vp = universe.getViewingPlatform();
//ViewingPlatformの座標変換グループとして,“Camera”を割り当てる
camera = vp.getViewPlatformTransform();
//以上の設定をカメラに反映
distance();
//============================================================================
//マウスの設定
//============================================================================
// マウスクリックイベント登録
@Override
mouse.setMouseButton(e.getButton());
mouse.setPrevMouseX(e.getX());
mouse.setPrevMouseY(e.getY());
}
});
// マウスホイールイベント登録
addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
mouse.setScale(mouse.getScale() *
(e.getWheelRotation() > 0 ? 1.25f : 1f / 1.25f));
distance();
}
});
// マウスドラックイベント登録
@Override
float dx = (float)(e.getX() - mouse.getPrevMouseX()) / size.width;
float dy = (float)(mouse.getPrevMouseY() - e.getY()) / size.height;
if (mouse.
getMouseButton() == MouseEvent.
BUTTON1) { // 移動量の更新
mouse.setDistanceX(mouse.getDistanceX() + dx * 30f);
mouse.setDistanceY(mouse.getDistanceY() + dy * 30f);
} else {
// 角度の更新 (ウィンドウの端から端までで、360度回転するようにする)
mouse.setAngleX(mouse.getAngleX() - dy * 360.0f);
mouse.setAngleY(mouse.getAngleY() + dx * 360.0f);
}
// 現在のマウスの位置を保存
mouse.setPrevMouseX(e.getX());
mouse.setPrevMouseY(e.getY());
distance();
}
});
}
//============================================================================
//マウスがドラッグ時に呼ぶメソッド
//============================================================================
public void distance() {
//===========================================================================
//極座標を直交座標へ直す
//===========================================================================
//theta関係の計算(球座標→直交座標)
float camera_y
= camera_distance
* (float)Math.
sin(Math.
toRadians(mouse.
getAngleX())) * mouse.getScale();
float camera_xz
= camera_distance
* (float)Math.
cos(Math.
toRadians(mouse.
getAngleX())) * mouse.getScale();
//phi関係の計算(球座標→直交座標)
float camera_x
= camera_xz
* (float)Math.
sin(Math.
toRadians(mouse.
getAngleY())); float camera_z
= camera_xz
* (float)Math.
cos(Math.
toRadians(mouse.
getAngleY())); //3次元ベクトル(カメラの位置用)
Vector3f Vector_camera_pos = new Vector3f(camera_x, camera_y, camera_z);
Vector3f vector_distance = new Vector3f(-mouse.getDistanceX(), -mouse.getDistanceY(), 0);
//===========================================================================
Transform3D Transform_camera_pos = new Transform3D(); //カメラの位置
//平行移動の座標変換を用意
Transform_camera_pos.setTranslation(Vector_camera_pos);
Transform3D Transform_camera_pos2 = new Transform3D(); //カメラの位置
Transform_camera_pos2.setTranslation(vector_distance);
//===========================================================================
//カメラの座標変換実行
//===========================================================================
Transform3D Transform_camera_theta = new Transform3D(); //thetaに関する回転
Transform_camera_theta.
rotX(-Math.
toRadians(mouse.
getAngleX()));
Transform3D Transform_camera_phi = new Transform3D(); //phiに関する回転
Transform_camera_phi.
rotY(Math.
toRadians(mouse.
getAngleY()));
//合成する
Transform_camera_phi.mul(Transform_camera_theta);
Transform_camera_pos.mul(Transform_camera_phi);
Transform_camera_pos.mul(Transform_camera_pos2);
//座標変換実行
camera.setTransform(Transform_camera_pos);
}
//*****************************************************************************
}