有象無象

カメラの設定

ここではカメラ(視点)に関する設定を行います.このページで扱うのはシーングラフの以下の部分に相当します.
本ページで扱う範囲(シーングラフ)

視点の変更

上のシーングラフを見ると分かるとおり,ViewPlatformの上にTransformGroupがあります. カメラの位置や向きはこのTransformGroupを使って変更します.

ViewingPlatform

SimpleUniverseでは視点を移動するにはViewingPlatformを取得し,それにTransform3Dをセットすることで可能です. ViewingPlatformはViewPlatformと,その上にあるTransformGroupがまとまったものと思ってください.
import javax.media.j3d.*;
import javax.vecmath.Vector3d;
import com.sun.j3d.utils.geometry.ColorCube;

public class ViewingPlatformTest extends SimpleUniverseApplet {
    public void init(){
        // カラーキューブを作成
        BranchGroup bg = new BranchGroup();
        bg.addChild(new ColorCube(0.5));
        addBranchGraph(bg);

        // 視点を移動
        Transform3D cameraTrans = new Transform3D();
        cameraTrans.rotX(-Math.PI/4); // ・・・(a)
        cameraTrans.setTranslation(new Vector3d( 0.0, 4.0, 4.0)); // ・・・(b)
        getUniverse().getViewingPlatform().getViewPlatformTransform().setTransform(cameraTrans);
    }
}
上のソースコードは,視点を(0, 4, 4)に移動し,カラーキューブを見下ろすようにカメラを変更しました. ここで,(a)(b)の2行を入れ替えて実行してみてください.異なった結果が得られます. どうして? と思われた方は下の図を見てください. 回転というのは基本的に原点を中心として行われます. そのため,平行移動してから回転するのと,回転してから平行移動するのでは結果が大きく異なってしまいます.
回転と平行移動の順序の違いと結果

lookAt

視点を移動するのは簡単ですが,視対象が映るようにカメラの向きを回転させる(上のソースコードのrotX)のは,回転角度を計算する必要があるため手動では面倒です. そこでTransform3DにはlookAtという便利なメソッドが用意されています.lookAtで視点などの設定をした後,invert()メソッドを呼び出すのを忘れないでください.
Transform3D#lookAt(Point3d eye, Point3d center, Vector3d up)
eye : カメラの位置
center : カメラの見る座標
up : カメラの上側を指定するベクトル

lookAtメソッドの引数
import javax.media.j3d.*;
import javax.vecmath.Vector3d;
import javax.vecmath.Point3d;
import com.sun.j3d.utils.geometry.ColorCube;


@SuppressWarnings("serial")
public class ViewingPlatformTest extends SimpleUniverseApplet {
    public void init(){
        BranchGroup bg = new BranchGroup();
        bg.addChild(new ColorCube(0.5));
        addBranchGraph(bg);

        Transform3D cameraTrans = new Transform3D();
        cameraTrans.lookAt(new Point3d(4,4,4),new Point3d(0,0,0), new Vector3d(0,1,0));
        cameraTrans.invert();
        
        getUniverse().getViewingPlatform().getViewPlatformTransform().setTransform(cameraTrans);
    }
}