追記(2010/06/13):'やってみた(2010/06/13 追加)'を追加
追記(2010/06/10):'やってみた(追加)'を修正
動機
元動画のようにARToolkit(前回(NyARToolkit)),とMMD(前々回(NyMmd))をくっつけたい!
感謝
各種リソース作者やマトメ等記事を書かれている方に感謝
やってみた0. 前回,前々回がそれぞれできていること.1. NyARToolkit側の前回実行に用いたjp.nyatla.nyartoolkit.jogl.sample.JavaSimpleLite.javaを編集していくのでNyARToolkitプロジェクトにNyMmdプロジェクトのクラスパスを追加する.
1.a プロジェクトの'Properties'で'Java Build Path'タブを開き'Add Class Folder…'ボタンで選択ダイアログを出す.
1.b NyMmdプロジェクトのbinフォルダを選択し,追加する.1.c NyMmdプロジェクト中のMmdフォルダ(pmd, vmdを入れたフォルダ)をNyARToolkitプロジェクトルートにDnD等で複写する.
1.c NyARToolkitプロジェクトルートにMmdフォルダを作成し,pmd, vmdファイル(およびテクスチャ)をDnD等で配置する.
2.eのコードで調整してもらってもよい.2. jp.nyatla.nyartoolkit.jogl.sample.JavaSimpleLite.javaを編集
2.a NyMmdプロジェクトのjp.nyatla.nymmd.test.MmdTest.javaより
MmdTestクラス中のinit(GLAutoDrawable drawable)メソッドをJavaSimpleLiteクラスに複写する.
ただし同名のメソッド名は既にあるので'mmd_'というprefixをつけて'mmd_init(…)'にする.
2.b NyMmdプロジェクトのjp.nyatla.nymmd.test.MmdTest.javaより
MmdTestクラス中のdisplay(GLAutoDrawable drawable)メソッドをJavaSimpleLiteクラスに複写する.
ただし同名のメソッド名は既にあるので'mmd_'というprefixをつけて'mmd_display(…)'にする.
2.c NyMmdプロジェクトのjp.nyatla.nymmd.test.MmdTest.javaより
MmdTestクラス中の以下のフィールド定義をJavaSimpleLiteクラスに複写する.
- animation_start_time
- _pmd
- _vmd
- _player
- _render
- _data_io
- prev_time
2.d NyMmdプロジェクトのjp.nyatla.nymmd.test.MmdTest.javaより
FileIOクラスをJavaSimpleLiteファイルに複写する.
2.e 以下のメソッドをに追加private void init_mmd_files() {
String pmd_file = "./Mmd/pmdfile.pmd";
String vmd_file = "./Mmd/vmdfile.vmd";
try {
this._pmd = new MmdPmdModel(new FileInputStream(pmd_file));
this._vmd = new MmdVmdMotion(new FileInputStream(vmd_file));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (MmdException e) {
e.printStackTrace();
}
this._player = new MmdMotionPlayer(this._pmd, this._vmd);
this._player.setLoop(true);
File f = new File(pmd_file);
this._data_io = new FileIO(f.getParentFile().getPath());
}
2.f JavaSimpleLiteクラスのdisplayメソッド中でdrawCubeメソッドを呼ぶところをコメントアウトする.
直後に
mmd_display(drawable);
を追加する.
2.g JavaSimpleLiteクラスのinitメソッド中最後のreturn直前にある
_animatorフィールドへの値の代入と同フィールドインスタンスのメソッド呼び出しをコメントアウトする.
直後に
mmd_init(drawable);
を追加する.
2.h JavaSimpleLiteクラスのコンストラクタの中,
最初に
mmd_init_files();
を追加する.
2.i mmd_displayメソッド内で以下の修正を加える.
- glClearメソッドを用いている行をコメントアウトする.
- glLoadIdentityメソッドを用いている行をコメントアウトする.
- glTranslatefメソッドを用いている行をコメントアウトする.
- glScalefで1.0,1.0,1.0としているところをモデルに合わせて調整する.0.1, 0.1, 0.1など
- 上記直後にx軸を90度まわしてやる.
_gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
2.j mmd_initメソッド内で以下の修正を加える.
- 光源位置のZ軸を負にしてあげる
3.実行
前回同様VM引数として'-d32 -Djava.library.path=./library:./lib'を与えて実行
やってみた(追加)
カメラ目線モード(?)を実行するにはJavaSimpleLiteクラスmmd_displayメソッド中の
以下のコメントアウト行の下に// this._player.updateNeckBone(100.0f,10f,10f);
次のコードを追加してみた.float x = (float) __display_wk[12];
float y = (float) __display_wk[13];
float z = (float) __display_wk[14];
this._player.updateNeckBone(-x, -y, -z);
それっぽく見えるときもあるんだけどやっぱり違うのかな,所々おかしな方向向いているきもする.
やってみた(追加)
モデル側座標系でみたカメラ(グローバル)側座標系の原点ということだろう.ということで以下のように訂正.
カメラ目線モード(?)を実行するにはJavaSimpleLiteクラスmmd_displayメソッド中の
以下のコメントアウト行の下に// this._player.updateNeckBone(100.0f,10f,10f);
次のコードを追加してみた.NyARMat a = new NyARMat(4, 4);
double[][] a_ary = a.getArray();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
a_ary[j][i] = __display_wk[j * 4 + i];
}
}
a.matrixSelfInv();
float x = (float) a_ary[3][0];
float y = (float) a_ary[3][1];
float z = (float) a_ary[3][2];
this._player.updateNeckBone(x, y, z);
どうだろう?
(NyARMat aはフィールドにする方がよいかもね)
やってみた(2010/06/13 追加)
上のやつをちょっと書き換えてみた.float m[] = new float[16];
_gl.glGetFloatv(GL.GL_MODELVIEW_MATRIX, m, 0);
NyARMat a = new NyARMat(4, 4);
double[][] a_ary = a.getArray();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
a_ary[j][i] = m[j * 4 + i];
}
}
a.matrixSelfInv();
double[] o = { 0.0, 0.0, 0.0, 1.0 };
double[] v = { 0.0, 0.0, 0.0 };
//o[2] = 10 * Math.sin(iTime / 1000.0);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
v[i] += a_ary[j][i] * o[j];
}
}
float x = (float) v[0];
float y = (float) v[1];
float z = (float) v[2];
this._player.updateNeckBone(x, y, z);
0 件のコメント:
コメントを投稿