ラベル NyMmd の投稿を表示しています。 すべての投稿を表示
ラベル NyMmd の投稿を表示しています。 すべての投稿を表示

2010年6月30日水曜日

NyMmdに影行列をやってみる

追記(2010/07/05): ARTK_MMDのコードではrenderForShadowってのがあって影行列適応時はこっちで描いてた.



動機
前回の続き.


やってみた
0. 以前の状況からスタート.


1. jp.nyatla.nymmd.test.MmdTest.javaの編集
1.1 MmdTestクラスにフィールドの追加
private float[] ShadowMatrix_ary = new float[16]; //影行列4x4


1.2 MmdTestクラスにメソッド追加
 private static void CalcShadowMatrixf(float[] planeAry, float[] lightPosAry,
float[] shadowMatrixAry) {
float dot = 0.0f;
for (int i = 0; i < 4; i++) {
dot += planeAry[i] * lightPosAry[i];
}

for (int loopY = 0; loopY < 4; ++loopY) {
for (int loopX = 0; loopX < 4; ++loopX) {
shadowMatrixAry[loopY * 4 + loopX] = -planeAry[loopY]
* lightPosAry[loopX];
if (loopX == loopY) {
shadowMatrixAry[loopY * 4 + loopX] += dot;
}
}
}
}

1.3 MmdTestクラス'public void init(GLAutoDrawable drawable);'メソッドの最後, 'return;'直前に以下を追加.
  {
_gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
float plane_ary[] = { 0.0f, 1.0f, 0.0f, 0.0f };
_gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, fLightPos, 0);
fLightPos[2] *= -1.0f;
CalcShadowMatrixf(plane_ary, fLightPos, ShadowMatrix_ary);
}

1.4 MmdTestクラス'public void display(GLAutoDrawable drawable):'メソッドの'this._render.render();'直後に以下を追加.
   {
_gl.glDisable(GL.GL_LIGHTING);
_gl.glDisable(GL.GL_LIGHT0);
_gl.glPushMatrix();
_gl.glMultMatrixf(ShadowMatrix_ary, 0);
_gl.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
//_gl.glColor4f(0.4f, 0.4f, 0.4f, 1.0f);
this._render.render();
_gl.glPopMatrix();
_gl.glEnable(GL.GL_LIGHTING);
_gl.glEnable(GL.GL_LIGHT0);
}


2. 実行
2.1 “VM arguments:に'-Djava.library.path=./lib'を入れる”を忘れずに.
2.2 pmd, vmdの順でファイルを指定する.


結果
できた(pmd: '初音ミク'(MMD添付モデル),vmd: '【MMD】みくみくにしてあげる♪【してやんよ】【Project DIVA】' 感謝).


モデルによっては明るめの色(0.4, 0.4, 0.4)を影に指定しても問題なさそう.テクスチャの有無が問題かしら?影に色がついてしまうモデルもあった.
内部で指定しているのだろうか?'_gl.glDisable (GL.GL_TEXTURE_2D);'とかは意味なかったな.はて?


追記
jp.nyatla.nymmd.MmdPmdRenderGL.javaのMmdPmdRenderGLクラスにあるrenderメソッド内でテクスチャの有無でgl.glEnable(GL.GL_TEXTURE_2D);を呼び出している箇所があった.
そこでこのメソッドの呼び出し時のGL_TEXTURE_2Dの状態に応じて,実行するかどうか判定するようにした.
で.影の描画時にはコード側でglDisable(GL.GL_TEXTURE_2D)としてからrenderメソッドを呼ぶようにしてあげた.
これで前述の影に色がついてしまうモデルでも色がつかず,指定した影の色での描画となることができた(pmd: '初音ミクmetal'(MMD添付モデル),vmd: '【MMD】みくみくにしてあげる♪【してやんよ】【Project DIVA】' 感謝).


jp.nyatla.nymmd.MmdPmdRenderGL.java MmdPmdRenderGLクラス renderメソッド内
   boolean b = gl.glIsEnabled(GL.GL_TEXTURE_2D);
if (条件 && b == true) {
// テクスチャあり

} else {
// テクスチャなし

}
…描画他…
if (b) {
gl.glEnable(GL.GL_TEXTURE_2D);
}



jp.nyatla.nymmd.test.MmdTest.java MmdTestクラス displayメソッド内
   {
_gl.glDisable(GL.GL_LIGHTING);
_gl.glDisable(GL.GL_LIGHT0);
_gl.glDisable(GL.GL_TEXTURE_2D);
_gl.glPushMatrix();
_gl.glMultMatrixf(ShadowMatrix_ary, 0);
//_gl.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
_gl.glColor4f(0.4f, 0.4f, 0.4f, 1.0f);
this._render.render();
_gl.glPopMatrix();
_gl.glEnable(GL.GL_LIGHTING);
_gl.glEnable(GL.GL_LIGHT0);
_gl.glEnable(GL.GL_TEXTURE_2D);
}


2010年6月9日水曜日

NyARToolkit + NyMmd をやってみた ( MacOSX 10.6 ( Snow Leopard ) / Eclipse )

追記(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);

2010年6月8日火曜日

NyMmd(JavaでMMD)をMacOSX/Eclipseでやってみた

動機
こちらを拝見し「カメラ目線モード」楽しそー.と思い,こちらで色々しりました!
で,NyMmd日記)を知りましてやってみよう!となりました.(NyMmdを動かすところまでね)

感謝
動機およびやってみたの各リンク先サイトに感謝!

やってみた
1.NyMmd(NyMmd-forJava-1.1.0.zip)とJOGL(jogl-1.1.1-macosx-universal.zip)を用意.
2.pmd/vmdファイルを用意.(MMDサイトVPVP wiki
2.EclipseにJavaプロジェクトをつくる.
3.NyMmdのsrcとNyMmdTestの下にあるjpフォルダをDnD等でプロジェクトのsrcフォルダへ.
4.JOGLのlibフォルダをプロジェクトに追加しjogl.jar, gluegen-rt.jarをbuild pathへ追加する.


5.jp.nyatla.nymmd.test.MmdTest.java内のFileIOクラスrequestメソッドないのファイルパスの区切り文字を変更する.
変更前 fs2 = new FileInputStream(this._dir + "\\" + i_name);
変更後 fs2 = new FileInputStream(this._dir + "/" + i_name);

6.実行時にVM arguments:に'-Djava.library.path=./lib'を入れる で実行


7.ファイルを2回きかれるのでpmd, vmdの順序で設定.pmdはテクスチャが同一フォルダにある必要がある.
8.動いた!

追加
jp.nyatla.nymmd.test.MmdTest.java内MmdTestクラスdisplayメソッド内でコメントになっている以下の行を有効にするとカメラ目線モード(特定方向注視)らしい(?)です.
// this._player.updateNeckBone(100.0f,10f,10f);