■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                      2008年09月28日

    楽しいJava講座 - 初心者から達人へのパスポート
                  vol.122

                                セルゲイ・ランダウ
 バックナンバー: http://www.flsi.co.jp/Java_text/
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■


[このメールマガジンは、画面を最大化して見てください。]


========================================================
◆ 01.3Dグラフィックスのアプリケーション開発
========================================================


前回はBackgroundを使って、背景を少し明るくしてみました。

でも、これでは、あまり宇宙らしくありませんね。

というわけで、今回は宇宙らしくするために背景を星がたくさん
光っている宇宙の画像に変えてみましょう。


予めホームページに宇宙の画像ファイルを掲載しておきましたので、
それをダウンロードして使ってください。
universe300.jpgというファイル名ですが、これをC:ドライブの
JavaWorksフォルダーの中にコピーしておいてください。

このファイルを使わずに、独自に自分が持っている画像ファイルを
使いたい人や、あるいは別のフォルダーに画像ファイルを入れてお
きたい人は、以降のソース・コードの該当する箇所を、自分で適切な
ものに書き換えてください。



さて前回は、Backgroundのインスタンスを生成するときに色(Color3f)を
指定しましたが、今回はそれをやめて、代わりに画像を指定することになり
ます。

つまり、画像ファイルを取り込んでBackgroundのインスタンスを生成すれば、
その画像を背景にすることができます。

たとえば、以下のようにします。


まず、使用する画像ファイルのファイル名を設定しておきます。

String fileName = "C:\\JavaWorks\\universe300.jpg";


このファイル名でファイルを読み込み、BufferedImageのインスタンスを
生成しておきます。

BufferedImage jpegImage = ImageIO.read(new File(fileName));

ただし、ImageIO.read()はIOExceptionを発生する可能性がありますから、
詳しく言うと、たとえば下記のようにtry-catchを指定しておく必要が
あります。

BufferedImage jpegImage = null;
try {
   jpegImage = ImageIO.read(new File(fileName));
} catch (IOException e) {
   e.printStackTrace();
}

なお、BufferedImageクラスやImageIOおよびそのread()メソッド、Fileクラス
については、以前(vol.061で)説明しましたね。忘れた人はそちらを復習して
ください。


このBufferedImageインスタンスからImageComponent2Dのインスタンスを生成します。

ImageComponent2D image2D = new ImageComponent2D(ImageComponent2D.FORMAT_RGB, jpegImage);


ImageComponent2Dクラスは今回初めて出てきましたが、これはJava 3Dで画像を扱う
ためのクラスで、煎じつめればBufferedImageクラスとBackgroundなどのJava 3Dの
クラスの間の仲介役をするクラスです。
このコンストラクターの第一引数には画像の形式を指定することになっており、
ここでは、FORMAT_RGBというのを指定していますが、これは、画像の色に(red, green,
blueをそれぞれ8ビット、合計24ビットで表現する)RGBを使うことを指定するもの
です。通常の3Dグラフィックスは、この指定で十分でしょう。


続いて、このImageComponent2Dのインスタンスを指定してBackgroundインスタンスを
生成します。

Background background = new Background(image2D);



あとは、前回と同じようにBackgroundの領域の設定を行い、Backgroundをgroupの子とし
て追加しておきます。



では、これらを踏まえて、下記のようにinitialize()メソッドを書き換えてみてください。

--------------------------------------------------------
   private void initialize() {
      this.setSize(300, 300);
      this.setContentPane(getJContentPane());
      this.setTitle("立方体と球体");
      GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
      Canvas3D canvas = new Canvas3D(config);
      SimpleUniverse universe = new SimpleUniverse(canvas);
      BranchGroup group = new BranchGroup();
      TransformGroup transGroup = new TransformGroup();
      transGroup.addChild(new ColorCube(0.02));
      Transform3D trans = new Transform3D();
      trans.setTranslation(new Vector3d(0.7, 0.0, 0.0));
      transGroup.setTransform(trans);
      TransformGroup rotationTransGrp = new TransformGroup();
      rotationTransGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
      Alpha alpha = new Alpha(-1, 5000);
      Transform3D axisLean = new Transform3D();
      axisLean.setRotation(new AxisAngle4d(1.0, 0.0, 0.0, Math.PI / 3));
      rotationTransGrp.setTransform(axisLean);
      RotationInterpolator rotator = new RotationInterpolator(
                                                alpha,
                                                rotationTransGrp,
                                                axisLean,
                                                0.0f,
                                                (float) Math.PI * 2.0f);
      BoundingSphere rotationBounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 1.0);
      rotator.setSchedulingBounds(rotationBounds);
      rotationTransGrp.addChild(transGroup);
      rotationTransGrp.addChild(rotator);
      group.addChild(rotationTransGrp);
      BranchGroup group2 = new BranchGroup();
      Color3f darkColor = new Color3f(0.0f, 0.0f, 0.0f);
      Color3f ambiColor = new Color3f(0.0f, 0.1f, 0.0f);  // 弱い色にすること!
      Color3f diffuColor = new Color3f(0.0f, 0.6f, 0.0f);
      Material mat = new Material(ambiColor, darkColor, diffuColor, darkColor, 0.0f);
      Appearance appear = new Appearance();
      appear.setMaterial(mat);
      Sphere sphere = new Sphere(0.5f, Sphere.GENERATE_NORMALS, 100, appear);
      group2.addChild(sphere);
      Color3f color = new Color3f(1.5f, 1.5f, 0.0f);
      BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 1.0);
      Vector3f lightDirection = new Vector3f(-1.0f, -1.0f, -1.0f);
      DirectionalLight light = new DirectionalLight(color, lightDirection);
      light.setInfluencingBounds(bounds);
      group2.addChild(light);
      AmbientLight ambiLight = new AmbientLight(color);
      ambiLight.setInfluencingBounds(bounds);
      group2.addChild(ambiLight);
      group.addChild(group2);
      String fileName = "C:\\JavaWorks\\universe300.jpg";
      BufferedImage jpegImage = null;
      try {
         jpegImage = ImageIO.read(new File(fileName));
      } catch (IOException e) {
         e.printStackTrace();
      }
      ImageComponent2D image2D = new ImageComponent2D(ImageComponent2D.FORMAT_RGB, jpegImage);
      Background background = new Background(image2D);
      BoundingSphere bound = new BoundingSphere(new Point3d(0.0,0.0,0.0), 10.0);
      background.setApplicationBounds(bound);
      group.addChild(background);
      universe.getViewingPlatform().setNominalViewingTransform();
      universe.getViewer().getView().setMinimumFrameCycleTime(5);
      OrbitBehavior behavior = new OrbitBehavior(canvas, OrbitBehavior.REVERSE_ALL);
      BoundingSphere behavBounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 1.0);
      behavior.setSchedulingBounds(behavBounds);
      universe.getViewingPlatform().setViewPlatformBehavior(behavior);
      group.compile();
      universe.addBranchGraph(group);
      getJContentPane().add(canvas);
   }
--------------------------------------------------------


編集が終わったら、保管して実行してみてください。

背景がグーンと宇宙らしくなったでしょう。



(次回に続く)


では、今日はここまでにします。

何か、わからないところがありましたら、下記のWebページまで質問を
お寄せください。



┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
★ホームページ:
      http://www.flsi.co.jp/Java_text/
★このメールマガジンは
     「まぐまぐ(http://www.mag2.com)」
 を利用して発行しています。
★バックナンバーは
      http://www.flsi.co.jp/Java_text/
 にあります。
★このメールマガジンの登録/解除は下記Webページでできます。
      http://www.mag2.com/m/0000193915.html
★このメールマガジンへの質問は下記Webページにて受け付けて
 います。わからない所がありましたら、どしどしと質問をお寄
 せください。
      http://www.flsi.co.jp/Java_text/
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Copyright (C) 2008 Future Lifestyle Inc. 不許無断複製