月別アーカイブ: 2013年8月

てすt

最近は2Dの衝突判定処理を自作しようとしているのだが、前にObjective-Cで衝突判定処理を作ったときの反省を生かして、今回はデバッグやテストを十分に行うことにした。で、恥ずかしながら今さら、JUnitを本格的に使うことにした。

今までJUnit系はActionScriptで使ったことがあるが、なんかその時の面倒さから敬遠してて、Javaのウニットテストはmain関数にassertをばらまいたようなことをやっていた。今回はちゃんとやるぜ!

で、そのJUnit。NetBeansが母体となっているjME(jMonkeyEngine) SDKにインストールしてみたはいいんだが、動かねーぞ。原因は分かった。 テストケースのクラス名をHogeTestみたいに、最後をTestとつけなければNetBeansが認識しないらしい。それはnbprojectディレクトリに含まれる、build-impl.xmlに記述されている”**/**Test”と指定されているのが原因だと、どっかのWEBで言ってた。build-impl.xmlには手をつけたくない(というか手をつけてはいけない?)ので、黙ってその末尾Testルールに従う。

あと、今回はテストで画像ファイル(SVGファイル)を吐き出したいと思っている。その吐き出し先のディレクトリを指定したいのだが、普通のアプリの場合はmainの引数にコマンドラインオプションとして指定していた。が、テストケースの場合はその指定の仕方がいまいち良く分からない。面倒くさいからコマンドラインオプションはやめて、環境変数で指定することにした。

それをやるには System.getenv( str ) で出来る。簡単だね!

System.getProperty( str ) は似たようなやり方だが、Java VMのオプション -Dで追加しないといけないぞう。

マウスでグリグリ

3DCGArtsでポリゴンオブジェクトをグリグリ回転するような操作をトラックボール操作というらしい。なるほどねー、言われてみれば確かにトラックボールだ。

今回はそれをjME(jMonkeyEngine)で実装してみた。

最初は3Dの一般的なところから検索してみて、見つかったのがここのやり方。
http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20040321

ここに載っているアルゴリズムのように実装してみたのだが、どうもあまりうまく動いてくれない。たぶん、自分のプログラムはSpatialオブジェクトのWorldTransformではなく、LocalTransformを操作しているのが間違いなんだと思う。しかし、WorldTransformを直接変更する方法はなく、間接的に変更する方法も調べたが結局分からなかった。

あきらめてjMEの公式サイトを漁ってみたら、そのものズバリがソース付きで載っていた。http://hub.jmonkeyengine.org/forum/topic/trackball-samples/

にゃるほどお~、lookAt関数を使うのか。lookAt関数って中身のソースを見てみたけど、全然よく分からないのよね。というかlookAt関数の元となる考え方Quanternion(四元数)自体がよくわからん。近所の本屋に扱っている本がなかったし、近所の図書館にもなかった。(中央図書館にはあるみたいだけど)

3Dではバリバリ使われているの考え方なのに、一般ではあまり需要がないのかな?まー、いずれは本腰をあげて身につけたい分野ではある。

で、今回、実装したのはこんな感じだ!

マウスモーションのイベントハンドラで、lookAtとlookUpはVector3fのメンバ変数。対象のspatialのlookAt関数の引数に使用される。sign関数は単純なもので、引数が負であれば-1、正であれば+1、ゼロであれば0を返す。sign関数を使った処理でマウスをクリックしたまま方向転換した時に変な動きにならないように補正してある。

if( mousePressed ){
int x_ = ev_.getX();
int y_ = ev_.getY();
int dx_ = mouseX0 – x_;
int dy_ = mouseY0 – y_;
float sx_ = -(float)dx_/(float)screenWidth;
float sy_ = (float)dy_/(float)screenHeight;
{
int sign0_ = sign( lastX – mouseX0 );
int sign1_ = sign( x_ – lastX );
if( sign0_ != 0 && sign1_ != sign0_ ){
mouseX0 = lastX = x_;
}
lastX = x_;
}
{
int sign0_ = sign( lastY – mouseY0 );
int sign1_ = sign( y_ – lastY );
if( sign0_ != 0 && sign1_ != sign0_ ){
mouseY0 = lastY = y_;
}
lastY = y_;
}
++debugCount;
Quaternion xq_ = new Quaternion().fromAngleAxis(
FastMath.QUARTER_PI*sx_, Vector3f.UNIT_Y
);
Quaternion yq_ = new Quaternion().fromAngleAxis(
FastMath.QUARTER_PI*sy_, Vector3f.UNIT_X
);
xq_.multLocal( lookAt );
xq_.multLocal( lookUp );
yq_.multLocal( lookAt );
yq_.multLocal( lookUp );
}