アットウィキロゴ

java3Dマウスでごりごり

サンプルコードはいろいろあるが

せっかく3Dなのに視点も変えられないものばかり
とりあえずはマウスでゴリゴリ動かせるようにしないと3Dの面白さはないでしょう。
自然にくるくる回るってのもあるが、やっぱ拡大縮小して欲しい。
てなわけでマウスで動くようにしたい!
いじるのは、Canvas3D。こいつを継承してマウスのイベントを足してしまえばできるっぽい。
ちなみに、ここでのマウスでゴリゴリの仕様は
右ドラッグ:回転
左ドラッグ:視点移動
マウスホイール:拡大・縮小
結構贅沢な仕様である。

そしてできたソースがこれ。

  1. package jp.xronia.j3d;
  2.  
  3. //******************************************************************************
  4. //マウスのドラッグで視点移動を行うCanvas3D拡張クラス“Canvas3DMouseMove”
  5. //
  6. //Canvas3Dを継承
  7. //MouseMotionLisenerを実装
  8. //
  9. //コンストラクタの引数はカメラの距離
  10. //さらに,コンストラクタの引数にはGraphicsConfigurationが必要(Canvas3Dと同じ仕様)
  11. //******************************************************************************
  12.  
  13. import java.awt.Dimension;
  14. import java.awt.GraphicsConfiguration;
  15. import java.awt.event.MouseAdapter;
  16. import java.awt.event.MouseEvent;
  17. import java.awt.event.MouseMotionAdapter;
  18. import java.awt.event.MouseWheelEvent;
  19. import java.awt.event.MouseWheelListener;
  20.  
  21. import javax.media.j3d.Canvas3D;
  22. import javax.media.j3d.Transform3D;
  23. import javax.media.j3d.TransformGroup;
  24. import javax.vecmath.Vector3f;
  25.  
  26. import com.sun.j3d.utils.universe.SimpleUniverse;
  27. import com.sun.j3d.utils.universe.ViewingPlatform;
  28.  
  29. public class Canvas3DMouseMove extends Canvas3D {
  30. /** SerialVersionUID */
  31. private static final long serialVersionUID = 1L;
  32.  
  33. //=============================================================================
  34. //クラスのフィールド
  35.  
  36.  
  37. //動径の長さ(座標中心と視点との距離)
  38. float camera_distance;
  39.  
  40. // マウスの座標なんかを保存するオブジェクト
  41. MouseEntity mouse = new MouseEntity();
  42.  
  43. //SimpleUniverseをフィールドとしてもっておく。
  44. SimpleUniverse universe;
  45.  
  46. //視点の座標変換のためのグループ
  47. TransformGroup camera;
  48.  
  49. //=============================================================================
  50. //コンストラクタ
  51. public Canvas3DMouseMove(float Distance, GraphicsConfiguration config) {
  52. //親クラスのコンストラクタを呼ぶ. 引数はGraphicsConfiuration.
  53. super(config);
  54.  
  55. //カメラの原点からの距離を設定
  56. camera_distance = Distance;
  57.  
  58. //空のSimpleUniverseを生成
  59. universe = new SimpleUniverse(this);
  60.  
  61. //============================================================================
  62. //視点(カメラ)について設定
  63. //============================================================================
  64.  
  65. //------------------------------------------------------------------
  66. //カメラ全般の初期設定
  67.  
  68. //SimpleUniverseが生成したViewingPlatformを取得
  69. ViewingPlatform vp = universe.getViewingPlatform();
  70.  
  71. //ViewingPlatformの座標変換グループとして,“Camera”を割り当てる
  72. camera = vp.getViewPlatformTransform();
  73.  
  74. //以上の設定をカメラに反映
  75. distance();
  76. //============================================================================
  77. //マウスの設定
  78. //============================================================================
  79. // マウスクリックイベント登録
  80. addMouseListener(new MouseAdapter() {
  81. @Override
  82. public void mousePressed(MouseEvent e) {
  83. mouse.setMouseButton(e.getButton());
  84. mouse.setPrevMouseX(e.getX());
  85. mouse.setPrevMouseY(e.getY());
  86. }
  87. });
  88. // マウスホイールイベント登録
  89. addMouseWheelListener(new MouseWheelListener() {
  90. @Override
  91. public void mouseWheelMoved(MouseWheelEvent e) {
  92. mouse.setScale(mouse.getScale() *
  93. (e.getWheelRotation() > 0 ? 1.25f : 1f / 1.25f));
  94.  
  95. distance();
  96. }
  97. });
  98.  
  99. // マウスドラックイベント登録
  100. addMouseMotionListener(new MouseMotionAdapter() {
  101. @Override
  102. public void mouseDragged(MouseEvent e) {
  103. Dimension size = e.getComponent().getSize();
  104. float dx = (float)(e.getX() - mouse.getPrevMouseX()) / size.width;
  105. float dy = (float)(mouse.getPrevMouseY() - e.getY()) / size.height;
  106.  
  107. if (mouse.getMouseButton() == MouseEvent.BUTTON1) {
  108. // 移動量の更新
  109. mouse.setDistanceX(mouse.getDistanceX() + dx * 30f);
  110. mouse.setDistanceY(mouse.getDistanceY() + dy * 30f);
  111. } else {
  112. // 角度の更新 (ウィンドウの端から端までで、360度回転するようにする)
  113. mouse.setAngleX(mouse.getAngleX() - dy * 360.0f);
  114. mouse.setAngleY(mouse.getAngleY() + dx * 360.0f);
  115. }
  116.  
  117. // 現在のマウスの位置を保存
  118. mouse.setPrevMouseX(e.getX());
  119. mouse.setPrevMouseY(e.getY());
  120.  
  121. distance();
  122. }
  123.  
  124. });
  125. }
  126.  
  127. //============================================================================
  128. //マウスがドラッグ時に呼ぶメソッド
  129. //============================================================================
  130. public void distance() {
  131. //===========================================================================
  132. //極座標を直交座標へ直す
  133. //===========================================================================
  134. //theta関係の計算(球座標→直交座標)
  135. float camera_y = camera_distance * (float)Math.sin(Math.toRadians(mouse.getAngleX())) *
  136. mouse.getScale();
  137. float camera_xz = camera_distance * (float)Math.cos(Math.toRadians(mouse.getAngleX())) *
  138. mouse.getScale();
  139.  
  140. //phi関係の計算(球座標→直交座標)
  141. float camera_x = camera_xz * (float)Math.sin(Math.toRadians(mouse.getAngleY()));
  142. float camera_z = camera_xz * (float)Math.cos(Math.toRadians(mouse.getAngleY()));
  143. //3次元ベクトル(カメラの位置用)
  144. Vector3f Vector_camera_pos = new Vector3f(camera_x, camera_y, camera_z);
  145. Vector3f vector_distance = new Vector3f(-mouse.getDistanceX(), -mouse.getDistanceY(), 0);
  146. //===========================================================================
  147. Transform3D Transform_camera_pos = new Transform3D(); //カメラの位置
  148. //平行移動の座標変換を用意
  149. Transform_camera_pos.setTranslation(Vector_camera_pos);
  150.  
  151. Transform3D Transform_camera_pos2 = new Transform3D(); //カメラの位置
  152. Transform_camera_pos2.setTranslation(vector_distance);
  153. //===========================================================================
  154. //カメラの座標変換実行
  155. //===========================================================================
  156. Transform3D Transform_camera_theta = new Transform3D(); //thetaに関する回転
  157. Transform_camera_theta.rotX(-Math.toRadians(mouse.getAngleX()));
  158.  
  159. Transform3D Transform_camera_phi = new Transform3D(); //phiに関する回転
  160. Transform_camera_phi.rotY(Math.toRadians(mouse.getAngleY()));
  161.  
  162. //合成する
  163. Transform_camera_phi.mul(Transform_camera_theta);
  164. Transform_camera_pos.mul(Transform_camera_phi);
  165. Transform_camera_pos.mul(Transform_camera_pos2);
  166.  
  167. //座標変換実行
  168. camera.setTransform(Transform_camera_pos);
  169. }
  170. //*****************************************************************************
  171. }
  172.  

まああれだ、どこのサイトだか忘れたがほぼパクリ。
おっとパクリ元発見→http://www.maroon.dti.ne.jp/koten-kairo/works/Java3D/Java3D_start.html#mouse
なので、左ドラッグの移動とホイールの拡大縮小は完全にオレ仕様であるが、そこはそれということで、
見える!オレにも見える!くく〜(おま

  1. package jp.xronia.j3d;
  2.  
  3. public class MouseEntity {
  4.  
  5. private int prevMouseX = 0;
  6. private int prevMouseY = 0;
  7. private float angleX = 0.0f;
  8. private float angleY = 0.0f;
  9. private float distanceX = 0.0f;
  10. private float distanceY = 0.0f;
  11. private int mouseButton = 0;
  12. private float scale = 1.0f;
  13.  
  14. public float getScale() {
  15. return scale;
  16. }
  17. public void setScale(float scale) {
  18. this.scale = scale;
  19. }
  20. public int getMouseButton() {
  21. return mouseButton;
  22. }
  23. public void setMouseButton(int mouseButton) {
  24. this.mouseButton = mouseButton;
  25. }
  26. public int getPrevMouseX() {
  27. return prevMouseX;
  28. }
  29. public void setPrevMouseX(int prevMouseX) {
  30. this.prevMouseX = prevMouseX;
  31. }
  32. public int getPrevMouseY() {
  33. return prevMouseY;
  34. }
  35. public void setPrevMouseY(int prevMouseY) {
  36. this.prevMouseY = prevMouseY;
  37. }
  38. public float getAngleX() {
  39. return angleX;
  40. }
  41. public void setAngleX(float angleX) {
  42. this.angleX = angleX;
  43. }
  44. public float getAngleY() {
  45. return angleY;
  46. }
  47. public void setAngleY(float angleY) {
  48. this.angleY = angleY;
  49. }
  50. public float getDistanceX() {
  51. return distanceX;
  52. }
  53. public void setDistanceX(float distanceX) {
  54. this.distanceX = distanceX;
  55. }
  56. public float getDistanceY() {
  57. return distanceY;
  58. }
  59. public void setDistanceY(float distanceY) {
  60. this.distanceY = distanceY;
  61. }
  62. @Override
  63. public String toString() {
  64. return "MouseEntity [prevMouseX=" + prevMouseX + ", prevMouseY="
  65. + prevMouseY + ", angleX=" + angleX + ", angleY=" + angleY
  66. + ", distanceX=" + distanceX + ", distanceY=" + distanceY
  67. + ", mouseButton=" + mouseButton + ", scale=" + scale + "]";
  68. }
  69. }
  70.  

おっと、追加したMouse用のエンティティを掲載するのを忘れるところだったぜ
で、使い方。

  1. package jp.xronia.j3d;
  2.  
  3. import java.awt.GraphicsConfiguration;
  4.  
  5. import javax.media.j3d.BoundingSphere;
  6. import javax.media.j3d.BranchGroup;
  7. import javax.media.j3d.DirectionalLight;
  8. import javax.media.j3d.TransformGroup;
  9. import javax.swing.JFrame;
  10. import javax.swing.JPanel;
  11. import javax.vecmath.Color3f;
  12. import javax.vecmath.Point3d;
  13. import javax.vecmath.Vector3f;
  14.  
  15. import com.sun.j3d.utils.geometry.ColorCube;
  16. import com.sun.j3d.utils.universe.SimpleUniverse;
  17.  
  18. public class Test extends JFrame {
  19. /** SerialVersionUID */
  20. private static final long serialVersionUID = 1L;
  21.  
  22. public Test() {
  23. //============================================================================
  24. //まずは、基礎フレームの設定。
  25. //============================================================================
  26. //ウィンドウのサイズ設定
  27. this.setSize(400,400);
  28. //ウィンドウのタイトル設定
  29. this.setTitle("ViewChange_test");
  30. //ウィンドウを閉じる動作の登録
  31. this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  32. //コンテントペインを作成
  33. JPanel cp = new JPanel();
  34. //コンテントペイン上のレイアウトは全て手動で行う
  35. cp.setLayout(null);
  36. //フレームに、コンテントペインを登録
  37. this.add(cp);
  38.  
  39. //============================================================================
  40. //次にJava3D関係の設定。
  41. //============================================================================
  42. //現在使用している画面の、ハードウェア情報を取得する
  43. GraphicsConfiguration g_config = SimpleUniverse.getPreferredConfiguration();
  44. //Cnavas3D_ViewChangeクラスを用意する(距離は40, マウス感度は0.03)
  45. Canvas3DMouseMove canvas = new Canvas3DMouseMove(10.0f, g_config);
  46. //3D表示領域の大きさを設定。今回はウィンドウいっぱいに表示する
  47. canvas.setBounds(0,0,400,400);
  48. //コンテントペインにCanvas3Dを登録
  49. cp.add(canvas);
  50.  
  51. //Canvas3DクラスのSimpleUniverseを利用。
  52. SimpleUniverse universe = canvas.universe;
  53. //universe.getViewingPlatform().setNominalViewingTransform();
  54.  
  55. //============================================================================
  56. //ライトの設定
  57. //============================================================================
  58. //ライトの強さ及び色
  59. Color3f light_color = new Color3f(3.4f, 3.4f, 3.4f);
  60. //ライトの方向
  61. Vector3f light_direction = new Vector3f(-0.8f, -1.2f, -1.0f);
  62. //平行光源を用意
  63. DirectionalLight light = new DirectionalLight(light_color,light_direction);
  64. //ライトで照らす範囲(球範囲で指定,中心座標とその半径)
  65. BoundingSphere bounds = new BoundingSphere(new Point3d(), 100.0);
  66. //範囲を登録
  67. light.setInfluencingBounds(bounds);
  68. //ライト用の「枝」を作る
  69. BranchGroup BranchGroup_Light = new BranchGroup();
  70. //「枝」にライトを登録
  71. BranchGroup_Light.addChild(light);
  72. //仮想空間に「枝」を登録
  73. universe.addBranchGraph(BranchGroup_Light);
  74.  
  75. //============================================================================
  76. //3D空間を構築していきます
  77. //============================================================================
  78.  
  79. BranchGroup bg = new BranchGroup();
  80. //「カラーキューブ」を1つ生成
  81. ColorCube cube = new ColorCube(1.0f);
  82.  
  83. //座標変換クラスを生成
  84. TransformGroup tfg = new TransformGroup();
  85.  
  86. //座標変換の書き換えを許可
  87. tfg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
  88.  
  89. //カラーキューブを座標変換クラスに登録
  90. tfg.addChild(cube);
  91.  
  92. bg.addChild(tfg);
  93.  
  94. universe.addBranchGraph(bg);
  95.  
  96. //ウィンドウを可視化
  97. this.setVisible(true);
  98. }
  99. //============================================================================
  100. // メイン
  101. //============================================================================
  102. public static void main(String args[]) {
  103. new Test();
  104. }
  105. }
  106.  
ここではおざなりにカラーキューブを表示させているが、見てみたいサンプルをブランチグループに登録してあげれば
大抵のサンプルはマウスでグリグリできるようになるはず。
最終更新:2013年08月17日 22:24