犀角(Diceros Horn)

とくながの「書き散らかし」です

ここは研究・調査・開発などの記録がメインのページです。 日常の雑事、読書記録は はてなダイアリー の方に書いています。よろしければそちらもどうぞ。

Mon, 06 Mar 2006

Java3D Tips 集

posted at 00:55 | category: /Java/Java3DTips | 固定リンク(Java3D Tips 集 )

Sun, 19 Feb 2006

テクスチャーの貼り付け方

IndexedGeometryArray で TEXTURE_COORDINATE_2を指定する場合

テクスチャーに使う画像は Appearance の setTexture で与える。 IndexedGeometryArray の中で行うことは

  • setTextureCoordinate() でテクスチャーに使う画像上の点に番号をつける。
  • setTextureCoordinateIndex() で上で付けた点と setCoordinateIndex() で番号づけした点との対応を与える。
が全てである。

テクスチャーに使う画像上の点を与える方法

テクスチャーに使う画像の座標系は (s,t) で表され、画像の大きさにかかわらず、 0 から 1 までの値をとる。

下の例では、立方体の各面に画像を張り付けている。TexCoord2f[] t でテクスチャー画像上の点を 8個取り出して、setTextureCoordinateIndices() でそれを立方体の各頂点に対応させている。 立方体に張り付けるときに、大きさを自動的に変換していることに注意する。

import javax.media.j3d.*;
import javax.vecmath.*;

class DiceGeometry extends IndexedQuadArray{
    double[] coord;

    DiceGeometry(){
	super(8,
	      IndexedLineArray.COORDINATES|
	      IndexedLineArray.TEXTURE_COORDINATE_2,
	      24);
	coord = new double[3*8];
	createGeometry();
	setCoordinates(0,coord);
	createTexture();
    }

    public void createGeometry(){
	// 0
	coord[0] = 0.5;
	coord[1] = 0.5;
	coord[2] = 0.5;
	// 1
	coord[3] = -0.5;
	coord[4] = 0.5;
	coord[5] = 0.5;
	// 2
	coord[6] = -0.5;
	coord[7] = -0.5;
	coord[8] = 0.5;
	// 3
	coord[9] = 0.5;
	coord[10] = -0.5;
	coord[11] = 0.5;
	// 4 
	coord[12] = 0.5;
	coord[13] = 0.5;
	coord[14] = -0.5;
	// 5
	coord[15] = -0.5;
	coord[16] = 0.5;
	coord[17] = -0.5;
	// 6
	coord[18] = -0.5;
	coord[19] = -0.5;
	coord[20] = -0.5;
	// 7
	coord[21] = 0.5;
	coord[22] = -0.5;
	coord[23] = -0.5;
	// index の設定
	setCoordinateIndex(0,0);
	setCoordinateIndex(1,1);
	setCoordinateIndex(2,2);
	setCoordinateIndex(3,3);

	setCoordinateIndex(4,0);
	setCoordinateIndex(5,4);
	setCoordinateIndex(6,5);
	setCoordinateIndex(7,1);

	setCoordinateIndex(8,0);
	setCoordinateIndex(9,3);
	setCoordinateIndex(10,7);
	setCoordinateIndex(11,4);

	setCoordinateIndex(12,1);
	setCoordinateIndex(13,5);
	setCoordinateIndex(14,6);
	setCoordinateIndex(15,2);

	setCoordinateIndex(16,5);
	setCoordinateIndex(17,4);
	setCoordinateIndex(18,7);
	setCoordinateIndex(19,6);

	setCoordinateIndex(20,2);
	setCoordinateIndex(21,6);
	setCoordinateIndex(22,7);
	setCoordinateIndex(23,3);
    }

    public void createTexture(){
	TexCoord2f[] t = new TexCoord2f[8];
	t[0] = new TexCoord2f(0.5f, 0.5f);
	t[1] = new TexCoord2f(0f, 0.5f);
	t[2] = new TexCoord2f(0f, 0f);
	t[3] = new TexCoord2f(0.5f, 0f);
	t[4] = new TexCoord2f(1.0f, 0.5f);
	t[5] = new TexCoord2f(0.5f, 0.5f);
	t[6] = new TexCoord2f(0.5f, 0f);
	t[7] = new TexCoord2f(1.0f, 0f);
	setTextureCoordinates(0, 0, t);
	int ind[] = new int[]{0,3,2,1,
                              7,6,5,4,
                              1,2,3,0,
                              5,4,7,6,
                              2,3,0,1,
                              2,7,4,1};
	setTextureCoordinateIndices(0, 0, ind);
    }
}

posted at 16:55 | category: /Java/Java3DTips | 固定リンク(テクスチャーの貼り付け方)

Picking した物体の座標を得るには

Picking した物体の座標を得るには com.sun.j3d.utils.picking.behaviors.PickingCallback インターフェースを使うと良い。 PickRotateBehavior や PickTranslateBehavior には setupCallback() メソッドがあるので、それを使って、 結びつける。すると、Picking した TransformGroup の値が変化したときには setupCallback(PickingCallback callback) によって結びつけられた callback の transformChanged() メソッドが実行される。

ActionListner と使い方は似ているので、比較してみると分かりやすいかもしれない。

インターフェース名 ActionListener PickingCallback
点火元と結びつけるメソッド addActionLisnter() setupCallback()
動作を定義するメソッド actionPerformed() transformChanged()

PickCallback を継承したクラスを作成し、その中の transformChanged() メソッドの中に実際の処理を書く。そして、PickTranslateBehavior などの インスタンスに setupCallback() メソッドでこのクラスのインスタンスを 結びつければ良い。

例えば Picking された TransformGroup の座標を調べるには

            PickTranslateBehavior pickTrans
                = new PickTranslateBehavior(scene,this,bounds);
            pickTrans.setupCallback(new PickingCallback(){
                    Vector3d vect = new Vector3d();   // 座標を格納する
                    Transform3D t3d = new Transform3D();
                    public void transformChanged(int type,TransformGroup tg){
                        if(type == PickingCallback.TRANSLATE){
                            tg.getTransform(t3d);
                            t3d.get(vect);
                            // ここで座標の処理をする。
                        }
                    }
                });
のようになる。単に座標を表示するだけのプログラムをサンプルとして下に挙げる。

posted at 16:54 | category: /Java/Java3DTips | 固定リンク(Picking した物体の座標を得るには)

Picking するには

物体を選択してマウスで動かしたりするには、PickMouseBehavior のサブクラス を使う。

  • 回転させる PickRotateBehavior
  • 動かす PickTranslateBehavior
  • ズームする PickZoomBehavior
これらは Java3D 1.2 以前では com.sun.j3d.utils.behaviors.picking パッケー ジに入っていたが、1.2 からは com.sun.j3d.utils.picking.behaviors パッ ケージに入っている。ここでは新しい方 (com.sun.j3d.utils.picking.behaviors)を使おう。

以下では物体を選んで回転させる方法について解説する。 PickRotateBehavior の部分を他のクラスに変えれば、他も同様にできる。 やるべきことは簡単で、PickRotateBehavior のインスタンスを作成し、 BranchGroup に addChild すればよい。Picking を有効にしたい Node を あらかじめ setCapability(TransformGroup.ENABLE_PICK_REPORTING) によって 属性を変えておくことを忘れずに。

        // ..... 途中から					     
        Canvas3D canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
        BranchGroup scene = new BranchGroup();
	TransformGroup[] trBox = new TransformGroup[2];
        for(int i=0;i<trBox.length;i++){
            trBox[i] = new TransformGroup();
            trBox[i].setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
            trBox[i].setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
            trBox[i].setCapability(TransformGroup.ENABLE_PICK_REPORTING);
            trBox[i].addChild(new ColorCube(0.1f));
        }

        BoundingSphere bounds = new BoundingSphere(new Point3d(), 100.0);
        
        // 立方体を別々に動かすためのピッキング
        pickRot = new PickRotateBehavior(scene,canvas,bounds);
        scene.addChild(pickRot);
        // ..... 以下略
上の例では、trBox[0]、trBox[1] が Picking 可能になっている。 そこに立方体が addChild されているので、最後の2行によって、 立方体を Picking によって個別に回転することができる。

posted at 16:19 | category: /Java/Java3DTips | 固定リンク(Picking するには)

Picking をカスタマイズするには

物体を選択したときの動作を自分で定義するには、 com.sun.j3d.utils.picking.behaviors.PickMouseBehavior を自分で拡張する。 PickMouseBehavior は抽象クラスで、updateScene(int xpos,int ypos) メソッ ドが抽象メソッドであるから、これを拡張する。ここでは Picking した物体 の座標を表示するプログラムを取り上げてみる。

PickMouseBehavior には pickCanvas と言うフィールドがある。 このクラスの setShapeLocation(xpos,ypos) と pickClosest() メソッドを使ってマウスをクリックした点に一番近い物は何かを を調べることができる。pickClosest() は調査の結果を PickResult クラスで返 すので、実際に Node を取り出すには、PickResult クラスの getNode() メソッ ドを用いる。雛型は次の通り。

        public void updateScene(int xpos,int ypos){
            TransformGroup tg = null;
            // マウスの座標を与える
            pickCanvas.setShapeLocation(xpos,ypos);
            // マウスの位置に一番近いノード
            PickResult res = pickCanvas.pickClosest();
            if(res != null){
                // 何かが Picking されているときには
                // その TransformGroup を取り出す
                if(((tg = (TransformGroup)res.getNode(PickResult.TRANSFORM_GROUP)) != null) &&
                   (tg.getCapability(TransformGroup.ALLOW_TRANSFORM_READ)) && 
                   (tg.getCapability(TransformGroup.ALLOW_TRANSFORM_WRITE))){
		   // ここで tg についての処理を行う
                }
            }
        }
今の場合は、tg についての処理のところで、getTransform() で座標を取り出し、 それを TextField に書き込んでいる。

posted at 16:16 | category: /Java/Java3DTips | 固定リンク(Picking をカスタマイズするには)

Picking した物体を Drag するには

Java3D 付属の Picking ではマウスで物体を選択することはできるが、 それを動かすときに、マウスカーソルに追従させることはできない。 それを可能にするための Behavior を書き直してみた。

もちろんx座標とy座標方向にしか動かすことはできない。 z座標方向は画面と垂直なので、マウスカーソルの位置で奥行を 変化させることはできないため。

また、Picking した物体がぶら下がっている TransformGroup を 動かしたときに標準の Picking では違った方向に動く仕様になっているが、 それも大域座標で計算しなおすような仕様に変更してある。

以下にソースを挙げる。使いかたは、PickingTranslateBehavior とほぼ同じ。 ただ、コンストラクタの引数の順番が異なる。

/**
 * @author TOKUNAGA Ken-ichi
 * @version Time-stamp: <03/02/28 03:17:20 tkenichi>
 *
 * 物体をピッキングして、それをマウスカーソルに追従させる。
 */

import com.sun.j3d.utils.picking.*;
import com.sun.j3d.utils.picking.behaviors.*;
import com.sun.j3d.utils.behaviors.mouse.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.media.j3d.*;
import javax.vecmath.*;

public class MouseDragBehavior extends Behavior 
    implements MouseBehaviorCallback{

    Vector3d currV3d = new Vector3d(),diffV3d = new Vector3d();
    Point3d cursorP3d = new Point3d(),viewP3d = new Point3d();
    Vector4d currV4d = new Vector4d();
    private PickingCallback callback = null;

    private PickCanvas pickCanvas;
    private WakeupOr wakeupCondition;
    private boolean picked = false;
    
    // ピッキングした座標を格納する
    private TransformGroup currGrp;
    private Transform3D 
        currT3d = new Transform3D(),       // ピッキングした座標
        localT3d = new Transform3D(),      // 局所座標
        inverse = new Transform3D(),       // 逆変換
        plate2world = new Transform3D();   // imageplate から仮想空間への変換

    public MouseDragBehavior(Canvas3D canvas,
                             BranchGroup root,
                             Bounds bounds){
        currGrp = new TransformGroup();
        currGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        currGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
        currGrp.setCapability(TransformGroup.ALLOW_LOCAL_TO_VWORLD_READ);
        // Behavior は Leaf だからその上の BranchGroup につける
        root.addChild(currGrp);
        pickCanvas = new PickCanvas(canvas, root);
        pickCanvas.setMode(PickCanvas.BOUNDS);
        setSchedulingBounds(bounds);
    }

    public void setMode(int pickMode) {
        pickCanvas.setMode(pickMode);
    }
    public int getMode() {
        return pickCanvas.getMode();
    }
    public void setTolerance(float tolerance) {
        pickCanvas.setTolerance(tolerance);
    }
    public float getTolerance() {
        return pickCanvas.getTolerance();
    }
    
    public void initialize() {
        // マウスを押したとき、離したとき、ドラッグしたときに
        // 起動する
        WakeupCriterion[] conditions = new WakeupCriterion[3];
        conditions[0] = new WakeupOnAWTEvent(MouseEvent.MOUSE_DRAGGED);
        conditions[1] = new WakeupOnAWTEvent(MouseEvent.MOUSE_PRESSED);
        conditions[2] = new WakeupOnAWTEvent(MouseEvent.MOUSE_RELEASED);
        wakeupCondition = new WakeupOr(conditions);
        wakeupOn(wakeupCondition);
    }
    
    public void processStimulus (Enumeration criteria) {
        WakeupCriterion wakeup;
        AWTEvent[] evt = null;
        int xpos = 0, ypos = 0;
        MouseEvent mevent;

        // AWTEvent を取り出す
        while(criteria.hasMoreElements()) {
            wakeup = (WakeupCriterion)criteria.nextElement();
            if (wakeup instanceof WakeupOnAWTEvent)
                evt = ((WakeupOnAWTEvent)wakeup).getAWTEvent();
        }
    
        // MouseEvent の場合
        if (evt[0] instanceof MouseEvent){
            mevent = (MouseEvent) evt[0];
            // マウスカーソルの2次元ピクセル座標
            xpos = mevent.getPoint().x;
            ypos = mevent.getPoint().y;

            switch(mevent.getID()){
            case MouseEvent.MOUSE_PRESSED:
                // 押されたとき
                System.out.println("mouse pressed");
                // ピッキングする
                if (!mevent.isAltDown() && mevent.isMetaDown()){
                    pickingTransformGroup(xpos,ypos);
                }
                break;
            case MouseEvent.MOUSE_RELEASED:
                // 離したとき
                // ピッキングをやめる
                picked = false;
                break;
            case MouseEvent.MOUSE_DRAGGED:
                // ドラッグしたとき
                // ピッキングされた TransformGroup を動かす
                if (picked && !mevent.isAltDown() && mevent.isMetaDown()){
                    translate(xpos,ypos);
                }
                break;
            default:
                System.out.println("other event");
            }
        }

        wakeupOn (wakeupCondition);
    }

    // ピッキングして TransformGroup を currGrp に格納する
    private void pickingTransformGroup(int xpos,int ypos){
        TransformGroup tg = null;
        
        // PickCanvas をつかってピッキングしているノードを探す
        pickCanvas.setShapeLocation(xpos, ypos);
        // LineArray と Vertex の両方が重なっている場合も
        // Vertex を取り出すために、pickAll() で全て取り出す
        PickResult pr[] = pickCanvas.pickAll();

        if(pr != null){
            for(int i=0;i<pr.length;i++){
                System.out.println(i + " = " + pr[i].getNode(PickResult.GROUP));
                // ピッキングした結果が読み書き可能な TransformGroup を取り出す
                if ((pr[i] != null) &&
                    ((tg = (TransformGroup)pr[i].getNode(PickResult.TRANSFORM_GROUP)) 
                     != null) &&
                    (tg.getCapability(TransformGroup.ALLOW_TRANSFORM_READ)) && 
                    (tg.getCapability(TransformGroup.ALLOW_TRANSFORM_WRITE))){
                    
                    System.out.println("success to pick " + tg);
                    
                    picked = true;
                    // ピッキングした結果の参照を currGrp にセットする
                    currGrp = tg;
                    
                    // 物体が乗っている座標系とその逆変換を得る
                    currGrp.getLocalToVworld(localT3d);
                    System.out.println(localT3d);
                    inverse.invert(localT3d);
                    System.out.println(inverse);
                    
                    // ImagePlate から仮想空間への変換行列を得る
                    pickCanvas.getCanvas().
                        getImagePlateToVworld(plate2world);
                    // 視点の位置を得る
                    pickCanvas.getCanvas().getCenterEyeInImagePlate(viewP3d);
                    plate2world.transform(viewP3d);
                    
                    // マウスカーソルの位置に物体を合わせる
                    translate(xpos,ypos);
                    //            freePickResult(pr);
                }
            }
        }
    }

    private void translate(int xpos,int ypos){
        // マウスカーソルのimageplate上の位置を得る
        pickCanvas.getCanvas().
            getPixelLocationInImagePlate(xpos,ypos,cursorP3d);
        plate2world.transform(cursorP3d);
        // ピッキングした物体の座標を通る
        currGrp.getTransform(currT3d);
        currT3d.get(currV3d);
        currV4d.set(currV3d.x,
                    currV3d.y,
                    currV3d.z,
                    1);
        localT3d.transform(currV4d);
        currV3d.set(currV4d.x,
                    currV4d.y,
                    currV4d.z);
        //System.out.println("cursor = " + cursorP3d);
        //System.out.println("current = " + currV3d);

        // 物体の座標をマウスカーソルの位置にあわせる
        // view と垂直方向な平面上を移動する
        currV3d.sub(viewP3d);
        cursorP3d.sub(viewP3d);
        double alpha = 
            (currV3d.x * viewP3d.x +
             currV3d.y * viewP3d.y +
             currV3d.z * viewP3d.z) /
            (cursorP3d.x * viewP3d.x +
             cursorP3d.y * viewP3d.y +
             cursorP3d.z * viewP3d.z);
        currV3d.scaleAdd(alpha,cursorP3d,viewP3d);
        // 大域座標を局所座標に直す
        currV4d.set(currV3d.x,
                    currV3d.y,
                    currV3d.z,
                    1);
        inverse.transform(currV4d);
        currV3d.set(currV4d.x,
                    currV4d.y,
                    currV4d.z);
        currT3d.setTranslation(currV3d);
        currGrp.setTransform(currT3d);
        transformChanged(MouseBehaviorCallback.TRANSLATE,
                         currT3d);
    }

    public void setupCallback(PickingCallback callback){
        this.callback = callback;
    }
    
    public void transformChanged(int type,Transform3D transform){
        if(callback != null){
            callback.transformChanged(type,currGrp);
        }
    }
}

posted at 16:14 | category: /Java/Java3DTips | 固定リンク(Picking した物体を Drag するには)

Sun, 12 Feb 2006

Java3D Behavior をボタンで On/Off するには

Behavior を Thread のように使ってアニメーションをするには

class TimerBehavior extends Behavior{
    WakeupOnElapsedTime won;
    
    public TimerBehavior(long sleep){
        won = new WakeupOnElapsedTime(sleep);
    }

    public void initialize(){
        wakeupOn(won);
    }

    // Thread.run() に相当
    public void processStimulus(java.util.Enumeration criteria){
        // ここで 3D の更新を行う
        wakeupOn(won);
    }
}
のような Behavior を継承したクラスを作成して addChild すればよい。 実行すると、sleep ミリ秒毎に 3D の更新を行ってアニメーションのように見える。 ただしこのままだと、動きっぱなしで制御することができない。

ボタンによって Behavior を On/Off するには postId() メソッドを用いて、 次のようにする。

  • Behavior の WakeupOnCriterion を WakeupOnElapsedTime と WakeupOnBehaviorPost の2種類用意する。
  • さらに現在どちらの WakeupOnCriterion を使っているかを判別するための flag を準備する。ここでは true のとき WakeupOnElapsedTime を呼ぶこと にする。
  • initialize() の中で、 wakeupOn() に WakeupOnBehaviorPost クラスのインスタンスをセットし、 flag を false にする。
  • processStimulus() メソッドで flag の値にしたがって、 次に wakeupOn() する WakeupOnCriterion を変更する。
Behavior の wakeupOn() は外から呼ぶことはできないが、postId() は外から呼ぶことができる。Behavior を On するには、
  • flag を true にする。
  • この Behavior クラスのインスタンスの postId() メソッドを呼ぶ。
とすればよく、Off するには、
  • flag を false にする。
だけでよい。

具体例で言うと、Behavior のほうは

class TimerBehavior extends Behavior{
    private WakeupCriterion awtWakeon,timeWakeon;
    boolean flag;  // true のときは timeWakeon を待つ

    public TimerBehavior(long time){
        timeWakeon = new WakeupOnElapsedTime(time);
	awtWakeon = new WakeupOnBehaviorPost(this,
                                             MouseEvent.MOUSE_CLICKED);
    }

    public void initialize() {
        wakeupOn(awtWakeon);
        flag = false;
    }

    public void processStimulus(java.util.Enumeration criteria) {
        if(flag){
            // ここでアニメーションの処理をする
            wakeupOn(timeWakeon);
	}else{
            wakeupOn(awtWakeon);
	}
    }
}
のようにする。 TimerBehavior のインスタンスを behavior とするとき、 呼び出すメソッドは VirtualUniverse や Applet のなかに
    public void stopBehavior(){
	behavior.flag = false;
    }

    public void startBehavior(){
	behavior.flag = true;
	behavior.postId(MouseEvent.MOUSE_CLICKED);
    }
のように記述する。このメソッドをボタンを押したときの actionPerformed() で呼べばよい。

posted at 22:16 | category: /Java/Java3DTips | 固定リンク(Java3D Behavior をボタンで On/Off するには)

Java3D Material

Material の属性の意味。

  • ambient 周囲の色
  • diffuse 反射の色
  • emissive 放射する色
  • specular 鏡の色

posted at 22:14 | category: /Java/Java3DTips | 固定リンク(Java3D Material)

Java3D Transform3D の set メソッドの具体的仕様

Transform3D ではその状態を、4行4列の行列、3行3列の行列、3次元のベクトル、 4元数で設定することができます。それぞれの間の関係をまず調べてみます。 4行4列の行列が一番情報量が多いので、おそらく4行4列の行列で表現すれば いいはず。set() メソッドがその他の形式から4行4列の行列への写像を与えてい ると考える。

  • スカラーから set(double scale)
    s  -> [s 0 0 0]
          [0 s 0 0]
          [0 0 s 0]
          [0 0 0 1]
    
  • 3次元ベクトルから set(Vector3f trans)
    [x0]  -> [1 0 0 x0]
    [x1]     [0 1 0 x1]
    [x2]     [0 0 1 x2]
             [0 0 0 1 ]
    
  • スカラーと3次元ベクトルから set(double scale, Vector3d v1)
    s,[x0]  -> [s 0 0 x0]
      [x1]     [0 s 0 x1]
      [x2]     [0 0 s x2]
               [0 0 0 1 ]
    
  • 3次元ベクトルとスカラーから set(Vector3d v1,double scale)
    [x0],s  -> [s 0 0 s*x0]
    [x1]       [0 s 0 s*x1]
    [x2]       [0 0 s s*x2]
               [0 0 0 1   ]
    
  • 3行3列の行列から
    [m00 m01 m02] -> [m00 m01 m02 0]
    [m10 m11 m12]    [m10 m11 m12 0]
    [m20 m21 m22]    [m20 m21 m22 0]
                     [0   0   0   1]
    

4元数は Quat4d では、フィールド x、y、z、w で表しているが、これは 数学の書き方をすると、

(x,y,z,w) = w + xi + yj + zk = q
である。4元数 q の随伴表現で、4元数の虚成分 (Sp(1)のリー環)に作用したものと考える。すなわち 4元数 q が3次元ベクトル v = (v1,v2,v3) に対して
 q(v) = q v q-1 
で作用する。この作用は q に対して一意ではないことに注意する。 これが set(Quat4d q) に他ならない。
[x] -> [(x*x-y*y-z*z+w*w)/r 2*(x*y-w*z)/r        2*(x*z+y*w)/r        0]
[y]    [2*(x*y+w*z)/r       (-x*x+y*y-z*z+w*w)/r 2*(y*z-x*w)/r        0]
[z]    [2*(x*z-y*w)/r       2*(y*z+x*w)/r        (-x*x-y*y+z*z+w*w)/r 0]
[w]    [0                   0                    0                    1]
ただし r = x*x + y*y + z*z + w*w となる。

posted at 22:12 | category: /Java/Java3DTips | 固定リンク(Java3D Transform3D の set メソッドの具体的仕様)

Java3D Behaviorについて

Behavior とは抽象クラスで、initialize() と processStimulus() メソッド を実装して用いる。これも Java3D の Node を継承しているので、 木構造に addChild() して使う。

initialize() は初期化をする。 processStimulus() は wakeupOn(WakeupCriterion criteria) によって 設定された起動条件 criteria が満たされたときに呼ばれるメソッド。

普通 initialize() のなかで wakeupOn() を呼び出し、最初の起動条件を 設定する。接待条件を満たすたびに processStimulus() を実行したいときは processStimulus() の中で再度 wakeupOn() を呼び出す。

criteria で記述された条件や processStimulus() で記述された動作によって アニメーションやマウスやキーボードなどのユーザインターフェースを 実現することができる。

実は PickMouseBehavior や Interpolator も Behavior の継承クラス。

Behavior で Animation をするには

WakeupCriterion に指定時間の経過後に起動する WakeupOnElapsedTime もしくは Frame が描き終わったときに起動する WakeupOnElapsedFrame を使うとよい。

posted at 22:09 | category: /Java/Java3DTips | 固定リンク(Java3D Behaviorについて)