2010年6月18日金曜日

GWT で onTouchStart / onTouchMove / onTouchEnd イベントを処理してみる

動機:
GWTFusenをiPadで使えるようにできないかしら?
あれこれ調べたらこれに出会った.
Lombardi Development Blog » Blog Archive » Supporting multi-touch events with GWT on mobile Safari

で,このコメントにある'touch.tar.gz'が動きそうなのでやってみよう!


やってみた:
1. EclipseのGWTプラグインが入っているとする.'SampleTouch' Web Application Projectを作成.
1.a 使わないものを片っ端から削除
src/test.client.GreetingService.java ファイル
src/test.client.GreetingServiceAsync.java ファイル
src/test.server パッケージ
src/test.shared パッケージ


1.b 'SampleTouch.java'を以下のようにする.
public class SampleTouch implements EntryPoint, TouchStartHandler,
TouchMoveHandler, TouchEndHandler {

private HTML html;

private TouchableFocusPanel tfp;

public void onModuleLoad() {
try {
VerticalPanel panel = new VerticalPanel();
html = new HTML();
panel.add(html);
tfp = new TouchableFocusPanel();
tfp.addTouchStartHandler(this);
tfp.addTouchMoveHandler(this);
tfp.addTouchEndHandler(this);
tfp.setSize("1000px", "1000px");
panel.add(tfp);
RootPanel.get().add(panel);
} catch (Exception e) {
e.printStackTrace();
}
}

@Override
public void onTouchStart(TouchStartEvent event) {
event.preventDefault();
String msg = "Start: ";
msg += createMessage(event.touches());
html.setHTML(msg);
}

@Override
public void onTouchMove(TouchMoveEvent event) {
event.preventDefault();
String msg = "Move: ";
msg += createMessage(event.touches());
html.setHTML(msg);
}

@Override
public void onTouchEnd(TouchEndEvent event) {
event.preventDefault();
String msg = "End: ";
msg += createMessage(event.touches());
html.setHTML(msg);
}

private String createMessage(JsArray touches) {
String msg = "";
if (touches.length() > 0) {
for (int i = 0; i < touches.length(); i++) {
Touch t = touches.get(i);
int x = t.getRelativeX(tfp.getElement());
int y = t.getRelativeY(tfp.getElement());
msg += i + ":{x:" + x + "," + y + "}, ";
}
}
return msg;
}
}



1.c 上記 'touch.tar.gz'を展開した中の'main/gwt/com'の'com'フォルダーをDnD等でプロジェクトのソースフォルダに設置する.

1.d war/SampleTouch.htmlの編集
bodyタグの中身を空っぽにする.

1.e src/com.google.gwt.user.MoblieSafari.gwt.xmlの編集
moduleタグの直下に以下を追加
<inherits name='com.google.gwt.user.User'/>
<inherits name='com.google.gwt.user.UserAgent'/>
<set-property name="user.agent" value="safari" />


1.f src/sample.touch.SampleTouch.gwt.xmlの編集
以下のコメント行の下に
<!-- Other module inherits -->

以下を追加する.
<inherits name='com.google.gwt.user.MobileSafari'/>
<inherits name='com.lombardi.mobilesafari.MobileSafariEvents'/>



2. GWT Compile
2.a プロジェクト内のファイルを選択して, GWT Compileをクリック.


2.b EntryPointModulesから'SampleTouch'以外をRemoveする.



2.c 'Compile'を実行する.


3. 'war'フォルダーをWebでhttpでアクセス可能な場所へ設置
例えば/Library/WebServer/Documents/の下などでWeb共有からアクセスするなど.



結果:
タッチ(スナップとるときどうしても指が動くのでMoveになってしまう…)

マルチタッチ


TwFusen:
で,GWTFusen改めTwFusenとしてこちらに置いてみた

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日火曜日

NyARToolkit for Java 2.3.2 を MacOSX/Eclipse でやってみた.'再: NyARToolkit for Java: QtJavaで読み込んで JOGLで書き出す'

動機
二年ぐらい前の怪しいエントリーOpenCV/JNIを利用したのと合わせて前回ぐらい簡単に書き直せないかしら.


感謝
各リンク先リソースに感謝!


やってみた
0. EclipseにJavaプロジェクトを作成
0.a ファイルのエンコーディングを'UTF-8'にしておく.


1. OpenCV
1.a OpenCV.Frameworkの取得とインストール
こちらのサイトの'1. Begin by downloading and installing the implementation of OpenCV appropriate to your platform:'のFor MacOSXの通りに実行
1.b OpenCV.jarの取得
こちらのサイトの'2. Download, unzip, and move the OpenCV Processing Library into your Processing libraries folder, or for Java users copy the content of the library folder in one of your Java Extensions folder.'の'OpenCV Processing Library'部のアンカーからopencv_01.zipをdownload.
1.c OpenCV.jarの設置
展開した中にある'library'フォルダをプロジェクトルートへDnD等で設置
library/OpenCV.jarをbuild pathに追加


2. JOGL
2.a 取得
こちらのサイトのjogl-1.1.1-macosx-universal.zip)をdownload.
2.b 設置
展開した中にある'lib'フォルダをプロジェクトルートへDnD等で設置
lib/gluegen-rt.jar, lib/jogl.jarをbuild pathに追加


3. NyARToolkit
3.a 取得
こちらのサイトよりNyARToolkit for Java - NyARToolkit CoreのNyARToolkit-2.5.2.zipをdownload
3.b 設置
展開した中にある'Data'フォルダをプロジェクトルートへDnD等で設置
展開した中にある'src/jp'フォルダをソースフォルダへDnD等で設置
展開した中にある'src.util/qt/jp'フォルダをソースフォルダへDnD等で設置
jp.nyatla.nyartoolkit.qt.utils packgageの QtCameraCapture.java削除
展開した中にある'src.util/jogl/jp'フォルダをソースフォルダへDnD等で設置
展開した中にある'sample/jogl/jp'フォルダをソースフォルダへDnD等で設置
jp.nyatla.nyartoolkitjogl.sample packageのJavaSimpleLite.javaを除いて削除(この時点ではJavaSimpleLite.javaにはエラーが出ているはず.)

3.c 追加
こちらの'Eclipse/09. Create the 'test.CameraCapture.java' file.'と同じように'text.CameraCapture.java'という以下のファイルを追加作成する

3.d 編集
jp.nyatla.nyartoolkitjogl.sample.JavaSimpleLite.javaを編集

  • 'JmfCaptureListener'を'QtCaptureListener'へ置換

  • 'JmfNyARRaster_RGB'を'QtNyARRaster_RGB'へ置換

  • 'JmfCaptureDevice'を'CameraCapture'へ置換

  • 'JavaSimpleLite'クラスの'onUpdateBuffer'メソッドの引数の型を'Buffer'から'byte[]'へ置換

  • 'JavaSimpleLite'クラスの'onUpdateBuffer'メソッド内,QtNyARRaster_RGBインスタンスのsetBufferメソッドをwrapBufferメソッドに置換


  • ここまでで残るはキャプチャとラスタの準備部だけがエラーになっているはず


  • で該当部をザックリコメントアウトして以下の様に追加する
    _capture = new CameraCapture(SCREEN_X, SCREEN_Y, 30f);
    _capture.setCaptureListener(this);
    _cap_image = new QtNyARRaster_RGB(SCREEN_X, SCREEN_Y);


  • あとはCARCODE_FILEとCARCODE_FILEの相対パスを"../../Data…"から"./Data…"に置き換える


ここまでのプロジェクトの状態


4. 実行
jp.nyatla.nyatoolkit.jogl.sample.JavaSimpleLite.javaを実行
実行時にはVM引数として'-d32 -Djava.library.path=./library:./lib'をつける.