これまで、サンプルアプリのコアとなっている部分の処理について説明してきましたが、NyARToolkitでAndroidのARアプリを作成するには多くの処理を実装する必要があります。
また、説明していない部分ではメモリの確保などのさまざまな工夫が入っており、これらの処理を初級者がゼロから実装するのは、かなり難しいです。
ですので初めは、このサンプルを基にタッチイベントの追加やサーバから3Dモデルデータを取得するなど、カスタマイズして利用するのがいいでしょう。その際には、これまで説明してきた処理のポイントを抑えておくと、カスタマイズした際の問題に対処しやすくなると思います。
そこで以降では、このサンプルアプリをベースに、自分で作成したマーカーの上に3Dモデルを表示する方法について説明します。
まずは、検出させたいARマーカーの作成方法について説明します。
ARマーカーの検出にはサンプルの「res/raw/patthiro」のようなパターンファイルが必要になります。このパターンファイルを作成するには、「ARToolkit」付属の「ARToolKit\bin\mkpatt.exe」というツールを使うことで作成できます。
ただし、このツールはWebカメラがなければ利用できないため注意が必要です。
また、タロタローグ氏が公開している「ARToolKit Marker Generator Online」を利用するとWebから作成できます。また、アップロードした画像からパターンファイルを作成も可能であるため、Webカメラがなくてもパターンファイルの作成が可能です。
今回は、ARToolKit Marker Generator Online で図6のマーカーからパターンファイルを作成します。
ARToolkitのマーカーは正方形で、黒枠:白のパターン領域:黒枠の比が1:2:1のものが想定されており、オリジナルのARToolkit内に黒枠とパターン領域が1:2:1のブランクマーカーが付属されているので、今回はそれを用いてマーカーを作成します。
なお、標準では1:2:1となっていますが、この比率が極端に崩れていなければある程度マーカー検出は可能です。しかし、マーカー検出の精度が悪い場合はライブラリを直接修正する必要があります。
パターンファイルの作成にはマーカーサイズとマーカー分割数が指定できます。マーカーサイズは黒枠とパターン領域の比の設定です。黒枠とパターン領域の比が1:2:1であれば50%、黒枠が標準よりも細い場合はパーセンテージを上げ、太い場合は下げて設定します。
マーカー分割数は枠内のパターンを数値化する際の解像度の設定です。分割数を上げるとマーカー検出の精度が上がる代わりに計算量が増えます。逆に分割数を下げるとマーカー検出の精度が下がる代わりに計算量も減ります。
なお、NyARToolkitのデフォルトは16×16分割となっており、分割数を変更した場合はARToolkitDrawer.initialization()の以下の処理を変更します。
// マーカーの分割数 ar_code[i] = new NyARCode(16, 16);
今回はデフォルトの16×16でパターンファイルを作成しています。
作成したパターンファイルpattfaceは「res/raw」ディレクトリに配置します。そして、NyARToolkitAndroidActivity.initializeGLSurfaceView()のマーカーパターン読み込み部分を以下のように変更します。
patt.add(getResources().openRawResource(R.raw.pattface)); //patt.add(getResources().openRawResource(R.raw.patthiro));
マーカーのパターンファイルが正しく作成できていれば、この変更だけで作成したマーカー上に3Dモデルが表示されるようになります。
マーカーの準備ができたので、次は3Dモデルを準備します。サンプルでは、3Dのモデルデータ+アニメデータを持つMD2形式の3Dモデルを表示していましたが、ここでは簡単に作成できるアニメーションのない「WaveFront」形式の3Dモデルを表示したいと思います。
表示する3Dモデルの作成は「Blender」というオープンソースの3Dモデリングツールを利用しています。
表示する3Dモデルは長方形のオブジェクトにテクスチャとして自動販売機の画像を張って作成した自動販売機モデルにしたいと思います。
WaveFront形式の3Dモデルは頂点情報などが記述されているobjファイル、マテリアル情報などを含んだmtlファイルの2ファイルからなります。これらのファイルをそれぞれAndroidプロジェクトの以下のディレクトリに配置します。
ここで注意しなければいけないのが、objファイルとmtlファイルのファイル名です。
Blenderで3Dモデルをエクスポートすると、これらのファイルは同じファイル名で拡張子の違うファイルが作成されます。しかし、min3dライブラリはファイル名_obj、ファイル名_mtlというファイル名を使うようになっています。これは、Androidではres/raw以下に配置したファイルはR.javaでファイル名をIDとして管理されるため、そのままのファイル名だとエラーになるためです。そのため、「ファイル名.obj」「ファイル名.mtl」を「ファイル名_obj」「ファイル名_mtl」とリネームする必要があります。
なお、objファイルにはマテリアルファイルの情報としてファイル名.mtlという記述がありますが、この内容はmin3dのObjParserで"."を"_"に置換しているため修正する必要はありません。
もう1点注意しなければいけないのが、テクスチャ画像のサイズです。これはOpenGL ESの制限なのですが、テクスチャ画像の辺の長さは64×128や128×128などのように、2のべき乗にする必要があります。
ファイルが配置できたら、サンプルのNyARToolkitAndroidActivity.initScene()を以下のように変更します。
IParser parser = Parser.createParser(Parser.Type.OBJ, getResources(), "jp.androidgroup.nyartoolkit:raw/vendor_obj", true); //vendor_obj:自動販売機の3Dモデル parser.parse(); Object3dContainer objModel = null; objModel = parser.getParsedObject(); Object3d o = objModel.getChildAt(0); o.position().x = -1; o.position().z = 2; o.rotation().x = 0.0f; o.rotation().y = 180.0f; o.rotation().z = 180.0f; o.scale().x = o.scale().y = o.scale().z = 1.0f; scene.addChild(o);
変更点としては、ParserのタイプをOBJにし、パーサから受け取る3DモデルのオブジェクトをObject3dContainerクラスにしています。そして、今回用意した3Dモデルにはオブジェクトの親子関係がないため、Object3dContainerから3dオブジェクトを取り出し初期設定をした後でsceneに追加しています。
また、アニメーションも入っていないため、アニメーションに関する処理をなくしています。
実行結果は以下のとおりです。
次回は、Androidアプリで利用できる、もう1つのオープンソースライブラリ「AndAR」を使ったアプリについて、NyARToolKitとの違いなどを交えつつ説明します。
Copyright © ITmedia, Inc. All Rights Reserved.