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

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'をつける.

2009年9月27日日曜日

NyARToolkit-2.3.1 for Java on Snow Leopard (using OpenCV/JNI)

Environment
01. MacOSX 10.6.1 (Snow Leopard)
02. Eclipse (Java IDE)

Resouce
01. NyARToolkit-2.3.1 for Java (NyARToolkit-2.3.1.zip)
02. OpenCV / Processing and Java Library (opencv_01.zip) (reference: this, this)

Eclipse
01. Make a 'Java Project'
02. DnD (Drag and Drop) from 'NyARToolkit-2.3.1/src/jp' folder to 'src' folder.
03. DnD from 'NyARToolkit-2.3.1/src.utils/qt/jp' folder to 'src' folder.
04. DnD from 'NyARToolkit-2.3.1/sample/qt/jp' folder to 'src' folder.
05. DnD from 'NyARToolkit-2.3.1/Data' folder to the project top (project icon).
06. DnD from 'OpenCV/library' folder to the project top (project icon).
07. Add to build path the 'OpenCV/library/OpenCV.jar' file.
08. Delete the 'jp.nyatla.nyartoolkit.qt.utils.QtCameraCapture.java' file.
09. Create the 'test.CameraCapture.java' file.
package test;

import hypermedia.video.OpenCV;
import jp.nyatla.nyartoolkit.qt.utils.QtCaptureListener;

public class CameraCapture implements Runnable {
private QtCaptureListener listener;
protected byte[] p;

int w;
int h;
int r;
private OpenCV cv;
private Thread t;

public CameraCapture(int _w, int _h, float _r) {
w = _w;
h = _h;
r = (int)(1000.0 / _r);
p = new byte[w * h * 3];

cv = new OpenCV();
cv.capture(w, h);
}

public void setCaptureListener(QtCaptureListener _listener) {
listener = _listener;
}

public void start() {
t = new Thread(this);
t.start();
}

public void stop() {
t = null;
cv.dispose();
}

public void run() {
while (t != null && cv != null) {
try {
Thread.sleep(r);
cv.read();
int[] p_int = cv.pixels();
int j = 0;
for (int i = 0; i < w * h; i++) {
p[j++] = (byte) (p_int[i] >> 16);
p[j++] = (byte) (p_int[i] >> 8);
p[j++] = (byte) (p_int[i]);
}
listener.onUpdateBuffer(p);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

Package Explorer like this

09. Edit the 'jp.nyatla.nyartoolkit.qt.sample.NyarToolkitLinkTest.java' file.
09.a the 2 variables's value
 private final String CARCODE_FILE = "./Data/patt.hiro";
private final String PARAM_FILE = "./Data/camera_para.dat";

09.b Replace from 'QtCameraCapture' to 'CameraCapture'.

10. Edit the 'jp.nyatla.nyartoolkit.qt.sample.NyarToolkitLinkTest.java' file and the 'jp.nyatla.nyartoolkit.qt.sample.QtCaptureTest.java'
10.a Add the 'import test.CameraCapture;'
10.b Replace from 'QtCameraCapture' to 'CameraCapture'.

11. Run
11.a Set the run configuretion

VM arguments: -d32 -Djava.library.path=${project_loc}/library
(The upper image is used a wrong name (lib).

11.b Run the 'jp.nyatla.nyartoolkit.qt.sample.NyarToolkitLinkTest'.


Result

2008年11月14日金曜日

Quartz Composer / Sample qc project about SingleMarkerDetector and MQOImporter patchs

追記(2010/05/27): FYI 'ARToolKit Coordinate Correction in Quartz Composer'

Don't forget that the ARToolKit is distributed under the GPL for non-commercial user. So, this Single Marker Detector is distributed under the GPL for non-commercial user./If you want to use for professional and commercial, you can't use this patch.


edit(2008/11/28):Thank you for using it.
http://gimpneek.com/blog/2008/11/artoolkit-and-quartz-composer/

edit(2008/11/19): If you did not use the MQOImporter and used other rendering patch, you could use the 'MatrixToParams(download)' patch. the patch can use like these images.



need a mqo file. free MQO files are here.

1. create the "sample1" marker. (print out the "ARToolKit/etc/pattSample1.pdf" file. this file is in SingleMarkerDetector Xcode project.)

2. open Quartz Composer, and choose "Blank Coposition" template.
3. find "MQO Importer patch" from Patch Creator panel.

4. deploy the patch, and open the patch's inspector, select setting tab.


5. push the 'File' button, and set the mqo file. (ex. iMac model)

6. change the inspector tab to input parameters, and adj. the values (In this image's case, change the values about Scale, Angle-X and Y-axis).

7. deploy other patchs and connect the pathcs like following image. Billboard patch's layer number have to set smaller than MQOImporter patch's number.

8. show the printed marker image to the video camera, if the SingleMarkerDetector patch can detect your marker, the mqo objet move in synchronization with the marker motion.

Option:
9. add the lfo patch.



if you didn't know the ARToolKit and now you get interested in the ARToolKit, please check these applied activities on other platforms.

2008年11月12日水曜日

Single Marker DetectorとMQO Importerを連携する時のコツ(?)

追記(2010/05/27): FYI 'ARToolKit Coordinate Correction in Quartz Composer'

Don't forget that the ARToolKit is distributed under the GPL for non-commercial user. So, this Single Marker Detector is distributed under the GPL for non-commercial user./If you want to use for professional and commercial, you can't use this patch.


I try to write in English version, but it is not good. If you want to read them, you brave the blog entries. 1. how to build the patchs. 2. how to use the patchs. If you used other model rendering path, you could use this patch with Single Marker Detector.
edit 2008/11/18: I made new patch. the patch disassemble the 4x4 homogenous transformation matrix to each paramators. The patch name is 'MatrixToParams'.
images:



まぁ試す時のサンプルと注意点みたいなもの.
  0.mqoファイルをどこかから調達する.
  1.同封のARToolKit/etc/pattSample1.pdfを印刷しておく.
  2.Quartz Composerを開き,MQO Importerをまず配置.
  3.Settingにてmqoファイルを指定する.
  4.MQO ImporterのInspector/Input ParametersでScaleを調整する(後で変換行列が変換してしまうので大きめで良い).
  5.Video Input, Single Marker Detecor, MQO ImportとなるようにImageとMatrixをつなぐ(Single Marker Detectorはデフォルトでsample1のマーカーを検出する.)
  6.Video Input, BillboardとなるようにImageをつなぐ
  7.Billboardの方がLayerが下(若い番号)になるように右上の番号をクリックして調整する.
  8.とりあえずMQO ImporterのEnableにチェックを入れておく
  9.重なった画像がでたらカメラの前でマーカーを動かしてみる.うまくmqoモデルが動くまであれこれがんばる(光量,光源などがたいせつみたいだけどよくわからない).
 10.Single Marker DetectorのouptutFoundとMQOImporterのenbaleをつなぐ.


 11.試す(あそぶ)

(12.時間があればp_g_へツブヤイてみるw.)

中級編(w): AngleにLFOで値をいれてみる.

上級編(w): 2回線にしてみる


なんかもっと安定して反応するようにならんもんかのぉ.こちらを参考にすべきでしょうかね.

間違いやお気づきの点がありましたらコメントもらえるとうれしいです.
以上です.

Quartz Composer / Single Marker Detector のXcodeプロジェクト 再び

追記(2010/05/27): FYI 'ARToolKit Coordinate Correction in Quartz Composer'

Don't forget that the ARToolKit is distributed under the GPL for non-commercial user. So, this Single Marker Detector is distributed under the GPL for non-commercial user./If you want to use for professional and commercial, you can't use this patch.
追記(2009/01/10):ダウンロード先のXcodeプロジェクトのzipファイルが壊れていたらしい.修復した.



GPLの配布ってどうすんのぉー.とこいつのことを悩んで忘れかけていたら某所(?)でご要望をいただいたので,突貫でやってみました.微妙にモデルの表示位置がおかしい気がする.などの問題はそのままです.

GPL配布についてはこちらを参考にさせていただきました.感謝!

ということでよろしくお願いします.
謝辞
ARToolKitの成果を利用させていただいています.ARToolKitフォルダ以下のコードやリソース類はARToolKit 2.72.1より配布されていたものです.ありがとうございます.
ライセンス
ARToolKitがnon-commercial利用ではGPL2なのでこれもnon-commercial利用に限ってのGPL2配布です.(あまりよくわかっていないので問題あればご指摘いただけると幸いです.)
そうでない人は使えません.
制約
MQO Importerパッチと連携すると便利です.これ自体は画像からパターンを見つけて変換マトリックスを出力するだけです.
作成環境
MBP (Intel) / MacOSX 10.5.5 / Xcode 3.1(確認 Quartz Composer 3.1)
ビルド
アクティブターゲットを"Build & Copy", アクティブなビルド構成を"Release"にしてビルドすると'${HOME}/Library/Graphics/Quartz\ Composer\ Plug-Ins'の下に'SingleMarkerDetector.plugin'ができてQCで使えるハズです.
使い方
1.QCにパッチを配置後,Video Inputのような画像をinputImageへつないでください.
2.マーカーの種類はパッチのSettingでsample1,2を選べます.画像はpattSample1.pdf, pattSample2.pdfに対応します.
3.うまく認識できれば'outputFound'がTrueに, 'outputMatrix'に出力がでます.
outputMatrixについて.変換の4x4行列が出力されます.立体モデルの座標を変換するための機能です.(中身は16個のdoubleをNSNumberに詰め込んでNSArrayで配列化したポートです.このdoubleの配列がglLoadMatrixdの引数とすればよい(ハズ)です.)
スナップショットのように接続する場合,注意点としてMQO ImporterのレイヤーがBillboardより大きい数字(合成上,手前(?))となるようにすることです.)
スナップショット

免責(?):
AS IS, 無保証でお願いします.とりあえずなんだか動いたよって程度のものだと認識してくださいね.
コードにおかしなところがありましたらご指摘いただけると幸いです.
ダウンロード:
こちらから (2010/09/08 変更)


配布状態に問題ありましたらご指摘ください.よろしくお願いします.
利用等でご不明の点ありましたらコメント等でご連絡ください.できる範囲で答えられたらなー.と思ってます.

2008年11月2日日曜日

Quartz Composer / Single Marker Detector のXcodeプロジェクト

追記(2010/05/27): FYI 'ARToolKit Coordinate Correction in Quartz Composer'

追記(2008/11/12): GPLの配布ってどうすんのぉー.とこいつのことを悩んで忘れかけていたら某所(?)でご要望をいただいたので,突貫でやってみました.微妙にモデルの表示位置がおかしい気がする.などの問題はそのままです.

追記(2008/11/03): 結局QCパッチのGPL2での配布,再配布の形式がよく理解できない状態なのでやめました.どうしたらいいのか.おいらに教えてくれる人を待ちます.公開はかまわないんですけどね.



ARToolKitのコードを含むのでどうやるべきなのかわからなかったのと,どうも出力するマトリックスの結果があやしいのと色々あったのですが,それぞれ,GPLだからコード公開すれば再配布可能らしい,まぁおいらの限界がここだろうということで置いてみました.問題あればご指摘いただけるとうれしいです.

で,こんなかんじ.

謝辞
ARToolKitの成果を利用させていただいています.ARToolKitフォルダ以下のコードやリソース類はARToolKit 2.72.1より配布されていたものです.ありがとうございます.
ライセンス
ARToolKitがGPL2なのでこれもGPL2配布です.(あまりよくわかっていないので問題あればご指摘いただけると幸いです.)
制約
MQO Importerパッチと連携すると便利です.これ自体は画像からパターンを見つけて変換マトリックスを出力するだけです.
作成環境
MBP (Intel) / MacOSX 10.5.5 / Xcode 3.1(確認 Quartz Composer 3.1)
ビルド
アクティブターゲットを"Build & Copy", アクティブなビルド構成を"Release"にしてビルドすると'${HOME}/Library/Graphics/Quartz\ Composer\ Plug-Ins'の下に'SingleMarkerDetector.plugin'ができてQCで使えるハズです.
使い方
1.QCにパッチを配置後,Video Inputのような画像をinputImageへつないでください.
2.マーカーの種類はパッチのSettingでsample1,2を選べます.画像はpattSample1.pdf, pattSample2.pdfに対応します.
3.うまく認識できれば'outputFound'がTrueに, 'outputMatrix'に出力がでます.
outputMatrixについて.変換の4x4行列が出力されます.立体モデルの座標を変換するための機能です.(中身は16個のdoubleをNSNumberに詰め込んでNSArrayで配列化したポートです.このdoubleの配列がglLoadMatrixdの引数とすればよい(ハズ)です.)
スナップショットのように接続する場合,注意点としてMQO ImporterのレイヤーがBillboardより大きい数字(合成上,手前(?))となるようにすることです.)
スナップショット

免責(?):
AS ISでお願いします.とりあえずなんだか動いたよって程度のものだと認識してくださいね.
コードにおかしなところがありましたらご指摘いただけると幸いです.
ダウンロード:
こちらから

2008年9月27日土曜日

とりあえずSingleMarkerDetectorとMQOImporterを複数用意すればいいのか.

追記(2010/05/27): FYI 'ARToolKit Coordinate Correction in Quartz Composer'

追記(2008/11/2):SingleMarkerDetectorのXcodeプロジェクト について.



複数にするためのARToolkitのサンプルを探そうかと思ったがその前にタイトルのようなことを妄想した.
で,SingleMarkerDetectorにpatternを複数積んでitem boxで切り替えられるようにUIを用意(こういうのがさくさく作れるInterfaceBuilderとのKVCって便利で強力だよなぁー.と実感).

やってみたのがこれ.


気がついたのだがモデルとマーカーが(けっこう)ズレテル?
…よくわかってないでイジくるのはコノあたりが限界かしら.

MQOImporterのプロジェクト / 修正版

追記(2008/11/2):SingleMarkerDetectorのXcodeプロジェクト について.



ということで修正しました.パッチ自身が描画します(Consumerタイプ).

先ほどと同じことを書いておきます.
名前
MQO Importer (名前と機能が一致しなくなってきた)

謝辞
MQOを読み込むところは工学ナビさんARToolkit解説等ページ.で配布されていたMQOファイルを読み込むヘッダ(GLMetaseq.h)を頼りにしています.ARToolkitの解説含めありがとうございます.

制約
ですのでMQOファイル内の書式等の都合でサポートできるファイルの制約等もそこからきます.(テクスチャの画像ファイルの読み込みはNSBitmapImageRepを利用しているのでGIF, JPEG, TIFF, PNGあたりも読み込めます.)

作成環境
MBP (Intel) / MacOSX 10.5.5 / Xcode 3.1 / Quartz Composer 3.1

ビルド
アクティブターゲットを"Build & Copy", アクティブなビルド構成を"Release"にしてビルドすると'${HOME}/Library/Graphics/Quartz\ Composer\ Plug-Ins'の下に'MQOImporter.plugin'ができてQCで使えるハズです.


使い方
QCにパッチを配置後,インスペクターのSettingパネル中にあるFileボタンをクリックしてmqoファイルを指定するだけです.サポートできる範囲のファイルは読み込めることでしょう.たぶん.で画像がViwerにでます.(注意:Scaleが0だとなにもでません.)

イメージ中のMQOファイルはこちらからDownloadしました(感謝).

免責(?):
AS ISでお願いします.とりあえずなんだか動いたよって程度のものだと認識してくださいね.

ダウンロード:
ここ (2010/09/08 変更).


で,ちょっと変わってimputMatrixというのを追加しました.ここに変換の4x4行列を入れるとモデルの座標を変換するという機能です.(中身は16個のdoubleをNSNumberに詰め込んでNSArrayで配列化したポートです.このdoubleの配列がglLoadMatrixdの引数となります.)
でこれと先日のSimpleLiteパッチを改良したSingle Marker Detectorパッチを使うとこんな感じのフローがつくれます.


パターンの選択とかのUIがあってもいいかなぁなどと思っているのですが…今日はここまで.

2008年9月23日火曜日

ARToolkitのSimpleLiteをQuartzComposerのPatchにしてみた.

追記(2008/9/27):
間違っているって決めつけるほどでもないかも…まぁ一応レイヤーで対応する方法へ進めてみる

追記(2008/9/26):
というか訂正.QCへの理解(考え方?)が間違っていました.やるとしたらこうですね.




あまりなにも考えず,やらかしてみた.

で,これ.
(クリックすれば元画像です)

一番は画像のバッファが
id<QCPlugInInputImageSource> image = self.inputImage; 
[image lockBufferRepresentationWithPixelFormat:QCPlugInPixelFormatARGB8
colorSpace:[image imageColorSpace]
forBounds:[image imageBounds]];

とすれば
ARUint8 *gARTImage = [image bufferBaseAddress];

とポインタ渡しで共用できたことが幸運.

でも,どうも認識がいまいち,WBとかが問題なのかしら?

2008年9月21日日曜日

NyARToolkit for Java: QtJavaで読み込んで JOGLで書き出す

追記(2010/06/08): NyARToolkit-2.3.2 MacOSX 10.6 / Eclipseについて書きました



先の例でVideoの読み込みはできたけど,書き出すのは普通にGraphicsに行列等文字列を書いてた.
そこで,まったくOpenGLとか知らない私が,NyARToolkit for Java付属のJOGLサンプルなどをつなぎ合わせて動かしてみようという試み.
間違っていたらごめんなさい.

環境:MacOS X 10.5.5 / Java 1.5

0.先の例のutilの作成(2.2)まではやっておく.

1.Javaプロジェクトを作成,'MyAR'とする.
1.1 先の例の3.2のようにプロジェクトのプロパティ/Java Build Path/プロジェクトタブに追加で'SampleARToolkit', 'SampleARToolkit_util'を加える.


2.libフォルダを用意.joglのライブラリを入れる.
2.1 ここから取得.https://jogl.dev.java.net/
2.2 libフォルダを作成して展開したフォルダをごっそり入れておく.
2.3 java build pathには'lib/jogl-1.1.2-pre-20080523-macosx-universal/lib/jogl.jar'と'lib/jogl-1.1.2-pre-20080523-macosx-universal/lib/glluegen-rt.jar'を追加.

3.NyARToolkit for Javaの'src.utils/jogl'下のファイルを入れる.
3.1 'jp/myatla.nyartoolkit.jogl.utils.GLNyARParam.java'をdndでsrcフォルダに入れる.
3.2 'jp/myatla.nyartoolkit.jogl.utils.GLNyARSingleDetectMarker.java'も同様にsrcフォルダに追加する.

4.どうしてもutilプロジェクト(先の記事でSampleARToolkit_utilsとしたモノ)内のファイルを編集する必要ができた…
4.1'src/jp/nyatla/nyartoolkit/qt/utils/QtNyARRaster_RGB.java'に以下のメソッドを追加.
src/jp/nyatla/nyartoolkit/qt/utils/QtNyARRaster_RGB.javaにメソッドを追加
 public byte[] get_Ref_buf() {
return this._ref_buf;
}


5.で,コードを作成.
5.1
src/MyAR.java
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import jp.nyatla.nyartoolkit.NyARException;

@SuppressWarnings("serial")
public class MyAR extends Frame {
public final static int SCREEN_X = 320;
public final static int SCREEN_Y = 240;

public MyAR() {
setTitle("MyAR");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
setVisible(true);
setSize(SCREEN_X, SCREEN_Y);

try {
add(new MyGLCanvas());
} catch (NyARException e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
new MyAR();
}
}


5.2
src/MyQtCameraCapture.java
import jp.nyatla.nyartoolkit.NyARException;
import jp.nyatla.nyartoolkit.qt.utils.QtCameraCapture;
import jp.nyatla.nyartoolkit.qt.utils.QtCaptureListener;
import jp.nyatla.nyartoolkit.qt.utils.QtNyARRaster_RGB;

public class MyQtCameraCapture extends QtCameraCapture implements
QtCaptureListener {
private QtNyARRaster_RGB _raster;

public MyQtCameraCapture() throws NyARException {
super(MyAR.SCREEN_X, MyAR.SCREEN_Y, 30f);
setCaptureListener(this);

_raster = new QtNyARRaster_RGB(MyAR.SCREEN_X, MyAR.SCREEN_Y);
}

public void onUpdateBuffer(byte[] pixels) {
try {
_raster.setBuffer(pixels);
} catch (Exception e) {
e.printStackTrace();
}
}

public QtNyARRaster_RGB get_raster() {
return _raster;
}
}

5.3 (JOGLでのsampleを参考)
src/MyGLCanvas.java
import java.nio.ByteBuffer;
import java.nio.IntBuffer;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;

import jp.nyatla.nyartoolkit.NyARException;
import jp.nyatla.nyartoolkit.core.NyARCode;
import jp.nyatla.nyartoolkit.core.types.NyARIntSize;
import jp.nyatla.nyartoolkit.jogl.utils.GLNyARParam;
import jp.nyatla.nyartoolkit.jogl.utils.GLNyARSingleDetectMarker;
import jp.nyatla.nyartoolkit.qt.utils.QtNyARRaster_RGB;

import com.sun.opengl.util.Animator;

@SuppressWarnings("serial")
public class MyGLCanvas extends GLCanvas implements GLEventListener {
private final String CARCODE_FILE = "./Data/patt.hiro";
private final String PARAM_FILE = "./Data/camera_para.dat";

private GL _gl;
private QtNyARRaster_RGB _raster;
private GLNyARSingleDetectMarker _nya;
private GLNyARParam _ar_param;

public MyGLCanvas() throws NyARException {
addGLEventListener(this);
setSize(MyAR.SCREEN_X, MyAR.SCREEN_Y);

MyQtCameraCapture _qtCapture = new MyQtCameraCapture();
_raster = _qtCapture.get_raster();
_qtCapture.start();
}

public void drawCube() {
int polyList = 0;
float fSize = 0.5f;
int f, i;
float[][] cube_vertices = new float[][] { { 1.0f, 1.0f, 1.0f },
{ 1.0f, -1.0f, 1.0f }, { -1.0f, -1.0f, 1.0f },
{ -1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f },
{ 1.0f, -1.0f, -1.0f }, { -1.0f, -1.0f, -1.0f },
{ -1.0f, 1.0f, -1.0f } };
float[][] cube_vertex_colors = new float[][] { { 1.0f, 1.0f, 1.0f },
{ 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f },
{ 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 1.0f },
{ 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f } };
int cube_num_faces = 6;
short[][] cube_faces = new short[][] { { 3, 2, 1, 0 }, { 2, 3, 7, 6 },
{ 0, 1, 5, 4 }, { 3, 0, 4, 7 }, { 1, 2, 6, 5 }, { 4, 5, 6, 7 } };
if (polyList == 0) {
polyList = _gl.glGenLists(1);
_gl.glNewList(polyList, GL.GL_COMPILE);
_gl.glBegin(GL.GL_QUADS);
for (f = 0; f < cube_num_faces; f++)
for (i = 0; i < 4; i++) {
_gl.glColor3f(cube_vertex_colors[cube_faces[f][i]][0],
cube_vertex_colors[cube_faces[f][i]][1],
cube_vertex_colors[cube_faces[f][i]][2]);
_gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize,
cube_vertices[cube_faces[f][i]][1] * fSize,
cube_vertices[cube_faces[f][i]][2] * fSize);
}
_gl.glEnd();
_gl.glColor3f(0.0f, 0.0f, 0.0f);
for (f = 0; f < cube_num_faces; f++) {
_gl.glBegin(GL.GL_LINE_LOOP);
for (i = 0; i < 4; i++)
_gl.glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize,
cube_vertices[cube_faces[f][i]][1] * fSize,
cube_vertices[cube_faces[f][i]][2] * fSize);
_gl.glEnd();
}
_gl.glEndList();
}
_gl.glPushMatrix(); // Save world coordinate system.
_gl.glTranslatef(0.0f, 0.0f, 0.5f); // Place base of cube on marker
// surface.
_gl.glRotatef(0.0f, 0.0f, 0.0f, 1.0f); // Rotate about z axis.
_gl.glDisable(GL.GL_LIGHTING); // Just use colours.
_gl.glCallList(polyList); // Draw the cube.
_gl.glPopMatrix(); // Restore world coordinate system.
}

public void display(GLAutoDrawable drawable) {
try {
if (!_raster.hasData()) {
return;
}
_gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

boolean is_marker_exist;
synchronized (_raster) {
is_marker_exist = _nya.detectMarkerLite(_raster, 100);
{
NyARIntSize rsize = _raster.getSize();
IntBuffer params = IntBuffer.allocate(4);
_gl.glDisable(GL.GL_TEXTURE_2D);
_gl.glGetIntegerv(GL.GL_VIEWPORT, params);
_gl.glPixelZoom(
1f * ((float) (params.get(2)) / (float) rsize.w),
-1f * ((float) (params.get(3)) / (float) rsize.h));
_gl.glWindowPos2f(0.0f, (float) rsize.h);
ByteBuffer buf = ByteBuffer.wrap(_raster.get_Ref_buf());
_gl.glDrawPixels(rsize.w, rsize.h, GL.GL_RGB,
GL.GL_UNSIGNED_BYTE, buf);
}

}
if (is_marker_exist) {

_gl.glMatrixMode(GL.GL_PROJECTION);
_gl.glLoadMatrixd(_ar_param.getCameraFrustumRH(), 0);
_gl.glMatrixMode(GL.GL_MODELVIEW);
_gl.glLoadIdentity();
_gl.glLoadMatrixd(_nya.getCameraViewRH(), 0);

drawCube();
}
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}

public void displayChanged(GLAutoDrawable drawable, boolean modeChanged,
boolean deviceChanged) {
}

public void init(GLAutoDrawable drawable) {
try {
// GL
_gl = drawable.getGL();
_gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

_ar_param = new GLNyARParam();
NyARCode ar_code = new NyARCode(16, 16);
_ar_param.loadARParamFromFile(PARAM_FILE);
_ar_param.changeScreenSize(320, 240);
_nya = new GLNyARSingleDetectMarker(_ar_param, ar_code, 80.0);
_nya.setContinueMode(false);
ar_code.loadARPattFromFile(CARCODE_FILE);

Animator _animator = new Animator(drawable);
_animator.start();
} catch (Exception e) {
e.printStackTrace();
}
}

public void reshape(GLAutoDrawable drawable, int x, int y, int width,
int height) {
_gl.glViewport(0, 0, width, height);
_gl.glMatrixMode(GL.GL_PROJECTION);
_gl.glLoadIdentity();
_gl.glMatrixMode(GL.GL_MODELVIEW);
_gl.glLoadIdentity();
}
}
ボールド体の場所はキャプチャ画像をOpenGLの出力先に書くところ.NyARToolkitのサンプルは丁寧に作成されているらしくチェックとかいろいろしているっぽかった(理解力不足ですみません).で,それを決めうちとか , 無くても動くところを省くとか勝手にしてみた.2Dを3Dに書くのっていろいろたいへん!


以上でプロジェクトはこうなっている.


6.実行
6.1 'MyAR.java'を実行させるのだがこのときVM引数を指定する.
Run Configurationsを開いてArgumentsタブのVM argumentsに以下を入力.
'-Djava.library.path=${workspace_loc:SampleJOGL}/lib/jogl-1.1.2-pre-20080523-macosx-universal/lib'


で動くとこうなる.


JOGL(MyGLCanvas)の部分はコピーやつぎはぎです.問題あればご指摘ください.

ーー
感謝:
NyARToolkit for Java
注意(?):
当然,NyARToolkit自身とutilsとこのプロジェクトを一つのsrcにしてもいいんですよ.

2008年9月20日土曜日

NyARToolkit for Javaを動かす.

追記(2009/9/27): Snow Leopardでの動作についてはこちら



NyARToolkit for Javaを発見.面白そうだから動かしてみた.
Macなのでライブラリ周りはQuickTime Java.
(JMFはMacのサポートどうなってんの?)

0.download.
NyARToolkit-2.0.0.zipを取得, 展開しておく
https://sourceforge.jp/projects/nyartoolkit/releases/32888

1.0 EclipseにJavaプロジェクト'SampleARToolkit'を作る.
1.1 srcに'NyARToolkit-2.0.0/src'以下のjpフォルダをdndで配置.


2.0 EclipseにJavaプロジェクト'SampleARToolkit_util'を作る.
2.1 srcに'NyARToolkit-2.0.0/src.util/qt'以下のjpフォルダをdndで配置.
2.2 プロジェクトのプロパティ/Java Build Path/プロジェクトタブに追加で'SampleARToolkit'を加える.



3.0EclipseにJavaプロジェクト'SampleARToolkit_Sample'を作る.
3.1 srcに'NyARToolkit-2.0.0/sample/qt'以下のjpフォルダをdndで配置.
3.2 プロジェクトのプロパティ/Java Build Path/プロジェクトタブに追加で'SampleARToolkit', 'SampleARToolkit_util'を加える.

3.3 'NyARToolkit-2.0.0/Data'フォルダをプロジェクトルートにdndで配置

3.4 'src/jp.nyatla.nyartoolkit.qt.sample/NyarToolkitLinkTest.java'を編集.
private final String CARCODE_FILE = "../../Data/patt.hiro";
private final String PARAM_FILE = "../../Data/camera_para.dat";


private final String CARCODE_FILE = "./Data/patt.hiro";
private final String PARAM_FILE = "./Data/camera_para.dat";

と変更する.

4.0'SampleARToolkit_Sample'内の'src/jp.nyatla.nyartoolkit.qt.sample/NyarToolkitLinkTest.java'を実行.
できた.

ARToolKitで遊ぶ.

昨日,おもしろ技術話題を仕事先の人と話していて以下のネタを紹介した.
Engadget Japanese
AR技術を使った「電脳フィギュア」 ARis
http://japanese.engadget.com/2008/07/21/denno-figure-ar-aris/

shi3zの日記
AR(拡張現実感)研究のための研究員(学生/社会人)を募集します
http://d.hatena.ne.jp/shi3z/20080702/1214955438

KODAWARISAN
iPhone 3G から 3Dキャラ
http://www.kodawarisan.com/k2008_02/archives/2008/08/iphone_3g_aa_3d_1.html
(こいつはこの記事とは関係ないかも)


そこへ(?),下記のつぶやきを発見.
akio0911さんのつぶやき
[book]3Dキャラクターが現実世界に誕生! ARToolKit拡張現実感プログラミング入門
https://twitter.com/akio0911/statuses/927689912


ARTookKit?ということでGoogle先生に聞いてみた.
工学ナビ
ARToolKitを使った拡張現実感プログラミング
http://www1.bbiq.jp/kougaku/ARToolKit.html

ほほぉー.でもWindowsかぁ.

…Download先にはソースコードはMac等もあるなぁ.などと思ってたら
シン石丸の電脳芸事ニッキ
Mac OS XでARToolKitを動かしてみる
http://shin-ishimaru.cocolog-nifty.com/blog/2007/10/mac_os_xartoolk_a92c.html


ということでやってみた.
build後,
1.patterns/pattHiro.pdfを印刷.
2.binの下のsimpleLite.appを実行(キャリブとかとりあえずいらない).
できた.ここまでは上記の通り.
(ちなみに動作はMacBook Pro(Intel)(iSightあり)/MacOS 10.5.5/Xcode 3.1という環境)

で,なんとなく思いついたので次のこともやってみた.
1.pattHiro.pdfをiPhone3GのAir Sharingへ.
2.pattHiro.pdfを表示
できた.

#Mailに添付でもよかったね….

そのうちARToolKitを含むiPhone Appがでるのかなぁ… 
電脳虫眼鏡(携帯カメラで覗き込むとナニカが見える)まであとちょっと.って感じ.
ーー
追記
と思ったら既にAndroidに載っけてる人がいた.NyARToolkit for Android