AREarthWebGL AREarthroidの地球表示部分をWebGL化 [Androidアプリ AREarthroid]
みなさんお気付きだろうか、本ブログにAREarthroidの地球表示部分を移植してみた。スクロールさせて、下の方に行くとあります(クリックすると自宅サイトにジャンプします)。
AREarthroidは、Android用なので、OpenGL/ESが使えた。
ブログに載せるには、WebGLが良いと思いやってみた。
AREarthroidは、JavaとC++で書いていたが、これをJavaScriptに変換しないといけないのである。
この作業が結構面倒。さらに、WebGLでは、シェーダーなるものを作ってやらないといけない。これも面倒。
さらには、できるのかもしれないが、今のところ一つのVBOしか描画できない。シェーダーが一つのVBOしか参照しない?
なので、地球オブジェクト一つだけしか表示されない。
なんで、作ってみたかというと、WiFiを使って取れた位置情報を表示してみたかったから。緯度と経度を単に表示するだけではつまらないので、インパクトの大きい方法で表示させたかった。それだけである。
本当は、現在地を示すマーカーも3Dオブジェクトにして、表示できたらカッコよかったかも知れない。
GPSでは、捕らえられた衛星の位置もわかるので、これも表示させてみたらカッコイイかなと思ったわけである。AREarthroidでは衛星を表示できる。
テクスチャマッピングで雲も表示できたし、まぁまぁ満足である。
関連記事
ラズパイGPSモジュール LCDに緯度経度を表示
WiFiで位置情報 ロケーションサービスを実験する
サイト内を検索
AREarthroidは、Android用なので、OpenGL/ESが使えた。
ブログに載せるには、WebGLが良いと思いやってみた。
AREarthroidは、JavaとC++で書いていたが、これをJavaScriptに変換しないといけないのである。
この作業が結構面倒。さらに、WebGLでは、シェーダーなるものを作ってやらないといけない。これも面倒。
さらには、できるのかもしれないが、今のところ一つのVBOしか描画できない。シェーダーが一つのVBOしか参照しない?
なので、地球オブジェクト一つだけしか表示されない。
なんで、作ってみたかというと、WiFiを使って取れた位置情報を表示してみたかったから。緯度と経度を単に表示するだけではつまらないので、インパクトの大きい方法で表示させたかった。それだけである。
本当は、現在地を示すマーカーも3Dオブジェクトにして、表示できたらカッコよかったかも知れない。
GPSでは、捕らえられた衛星の位置もわかるので、これも表示させてみたらカッコイイかなと思ったわけである。AREarthroidでは衛星を表示できる。
テクスチャマッピングで雲も表示できたし、まぁまぁ満足である。
関連記事
ラズパイGPSモジュール LCDに緯度経度を表示
WiFiで位置情報 ロケーションサービスを実験する
サイト内を検索
1.3.3にバージョンアップ [Androidアプリ AREarthroid]
本日は、AREarthroidバージョンアップのお知らせである。
AREarthroidは、バージョン1.3.3に更新された(1.3.2にはちょっとしたバグがあったので、即刻修正)。
更新内容を少し宣伝したい。
■3Dモデルの自動リサイズ
AREarthroidでは、任意のobj形式の3Dデータを読み込み、表示させることができる。1.3.3以前でも、3Dデータを任意の大きさに調整することができるが、1.3.3からは、地図の拡大・縮小により、見た目が同じように自動的にスケーリングされる。
地図の縮尺にかかわらず、3Dモデルの大きさは一定。
■3Dモデルの向き
向いている方向を調整できたが、1.3.3からは、端末向きと同じ方向に向くようなモードを付けた。
■objファイルのインポート
objファイルの読み込み時に、ファイルマネージャ的なものがインストールされていない場合、ファイルのピックアップに失敗する。例外を吐いて終了しないように、try catchでエラー処理するようにした。
また、objファイルの読み込み時に、mtlファイルを自動的にインポートするように機能拡張した。objファイルのインポートだけでローカルへのインポートは終了する。
■地図表示
Google Maps v2に移行、と思ったが、今回は見送り。
関連記事
http://asai-atsushi.blog.so-net.ne.jp/2013-01-22-1
■3Dビュー
ローパスフィルターのかけ方がおかしかったので、修正。
端末向きで、高度を変化させつつ、方角と反対方向に視点を移動させるようなアニメーション効果を導入。画面中央に3Dモデル(現在地)が表示されるので、けっこういい感じだと思っている。
長押しでARモードに移行する際に、ズームインするようなアニメーション効果を導入。ARモードからサテライトモードになる時には、逆にズームアウトする。
アニメーションは動画撮影しないといけないので、キャプチャ画像はなし。宣伝用のビデオもアップデートしたいなぁ...
■アイコン画像
アイコン画像を変更した。
左が新しいアイコン。右が今までのアイコン。並べてみると大した差はないが、地球の画像が高精細になっており、いい感じだと思っている。
■その他
その他、細かい部分でコードを最適化している。
サイト内を検索
AREarthroidは、バージョン1.3.3に更新された(1.3.2にはちょっとしたバグがあったので、即刻修正)。
更新内容を少し宣伝したい。
■3Dモデルの自動リサイズ
AREarthroidでは、任意のobj形式の3Dデータを読み込み、表示させることができる。1.3.3以前でも、3Dデータを任意の大きさに調整することができるが、1.3.3からは、地図の拡大・縮小により、見た目が同じように自動的にスケーリングされる。
地図の縮尺にかかわらず、3Dモデルの大きさは一定。
■3Dモデルの向き
向いている方向を調整できたが、1.3.3からは、端末向きと同じ方向に向くようなモードを付けた。
■objファイルのインポート
objファイルの読み込み時に、ファイルマネージャ的なものがインストールされていない場合、ファイルのピックアップに失敗する。例外を吐いて終了しないように、try catchでエラー処理するようにした。
また、objファイルの読み込み時に、mtlファイルを自動的にインポートするように機能拡張した。objファイルのインポートだけでローカルへのインポートは終了する。
■地図表示
Google Maps v2に移行、と思ったが、今回は見送り。
関連記事
http://asai-atsushi.blog.so-net.ne.jp/2013-01-22-1
■3Dビュー
ローパスフィルターのかけ方がおかしかったので、修正。
端末向きで、高度を変化させつつ、方角と反対方向に視点を移動させるようなアニメーション効果を導入。画面中央に3Dモデル(現在地)が表示されるので、けっこういい感じだと思っている。
長押しでARモードに移行する際に、ズームインするようなアニメーション効果を導入。ARモードからサテライトモードになる時には、逆にズームアウトする。
アニメーションは動画撮影しないといけないので、キャプチャ画像はなし。宣伝用のビデオもアップデートしたいなぁ...
■アイコン画像
アイコン画像を変更した。
左が新しいアイコン。右が今までのアイコン。並べてみると大した差はないが、地球の画像が高精細になっており、いい感じだと思っている。
■その他
その他、細かい部分でコードを最適化している。
サイト内を検索
AREarthroid Google playで評価をもらう [Androidアプリ AREarthroid]
本日は、AREarthroidの話題である。
ご存じのように、Google playには、ユーザーがコメントを書くことができる。だれでもコメントを書き込むことができるわけではなく、アプリをダウンロードしてインストールしているユーザだけ。
自分で、アプリをインストールしてコメントを書けなくもないと思うが、「自作自演」なのは、気が引けるのでしばらく、コメントなしの状態であった。
最近になって、コメントをもらった。しかも評価は「5つ星」
そのおかげなのか、インストール数が、大きく伸びた。やはり、評価が付いてないアプリは、なんだか怪しいもんね。
その後、評価3のコメントも付いている。
インストール数が伸びたこともあってか、新たなクラッシュ エラーが発生した模様。
java.lang.NoClassDefFoundError: android.security.MessageDigest
なにやらクラスが見つからない。
スタックトレースをみると、MapActivityのonCreateで発生している。えー、どういうこと?
「android.security.MessageDigest」で検索してみると、どうも場所が変更になったようである。MapActivityでは、APIキーが正しいかどうかをチェックする。APIキーはMD5のフィンガープリントで登録する。MD5の計算をする必要があるが、これにMessageDigestクラスを使っているのであろう。
「java.security.MessageDigest」の方を使え、ということらしい。
import android.security.MessageDigest;
となっている部分を、以下のように
import java.security.MessageDigest;
に変更すれば、よいのか?
しかし、MapActivity.javaをいじるわけにはいかないよなぁ。
しかし、日本語の情報がヒットしないなぁ... けっこうホットな話題なのかも。
英語で書かれている掲示板を翻訳しながら読んでいく。どうも、ライブラリとして使っているAndroid SDKのバージョンを4.2にしてtargetSdkも4.2にすればよいのか。これで、最新のライブラリがリンクされるので、OKみたい。
でも、Android 4.0.3のXperiaでも、Android 3.2.1のA100でもちゃんと地図表示できるが... 端末によるのか?
AndroidManifest.xmlを変更して、apkパッケージをビルド。
cameraのrequiredをfalseにもしてあるので、これも反映される。
英語のstrings.xmlに定義が足りなかったので、文字化けが発生していたのも修正。
これで、AREarthroid 1.3.1をアップした。
AREarthroid ARで地球を表示するアプリ
https://play.google.com/store/apps/details?id=cx.fam.asai.AREarthroid
サイト内を検索
ご存じのように、Google playには、ユーザーがコメントを書くことができる。だれでもコメントを書き込むことができるわけではなく、アプリをダウンロードしてインストールしているユーザだけ。
自分で、アプリをインストールしてコメントを書けなくもないと思うが、「自作自演」なのは、気が引けるのでしばらく、コメントなしの状態であった。
最近になって、コメントをもらった。しかも評価は「5つ星」
そのおかげなのか、インストール数が、大きく伸びた。やはり、評価が付いてないアプリは、なんだか怪しいもんね。
その後、評価3のコメントも付いている。
インストール数が伸びたこともあってか、新たなクラッシュ エラーが発生した模様。
java.lang.NoClassDefFoundError: android.security.MessageDigest
なにやらクラスが見つからない。
スタックトレースをみると、MapActivityのonCreateで発生している。えー、どういうこと?
「android.security.MessageDigest」で検索してみると、どうも場所が変更になったようである。MapActivityでは、APIキーが正しいかどうかをチェックする。APIキーはMD5のフィンガープリントで登録する。MD5の計算をする必要があるが、これにMessageDigestクラスを使っているのであろう。
「java.security.MessageDigest」の方を使え、ということらしい。
import android.security.MessageDigest;
となっている部分を、以下のように
import java.security.MessageDigest;
に変更すれば、よいのか?
しかし、MapActivity.javaをいじるわけにはいかないよなぁ。
しかし、日本語の情報がヒットしないなぁ... けっこうホットな話題なのかも。
英語で書かれている掲示板を翻訳しながら読んでいく。どうも、ライブラリとして使っているAndroid SDKのバージョンを4.2にしてtargetSdkも4.2にすればよいのか。これで、最新のライブラリがリンクされるので、OKみたい。
でも、Android 4.0.3のXperiaでも、Android 3.2.1のA100でもちゃんと地図表示できるが... 端末によるのか?
AndroidManifest.xmlを変更して、apkパッケージをビルド。
cameraのrequiredをfalseにもしてあるので、これも反映される。
英語のstrings.xmlに定義が足りなかったので、文字化けが発生していたのも修正。
これで、AREarthroid 1.3.1をアップした。
AREarthroid ARで地球を表示するアプリ
https://play.google.com/store/apps/details?id=cx.fam.asai.AREarthroid
サイト内を検索
AREarthライブ壁紙 [Androidアプリ AREarthroid]
本日は、Androidアプリの宣伝である。
ご存じのように、私が開発した「AREarthroid」をGoogle playで販売しているが、AREarthroidのライブ壁紙を作ってみた。その宣伝である。
名前はどうしようかと思ったが、「AREarthLiveWallpaperFree」とした。ちょっと長すぎたか。AREarthLWFとでも略しますか。
AREarthライブ壁紙
https://play.google.com/store/apps/details?id=cx.fam.asai.AREarthLiveWallpaperFree
Androidのホーム画面は、左右にスライドさせることで、壁紙が動いておもしろい。ライブ壁紙にすれば、もっと複雑な動きを実現できる。AREarthLWFでは、ホーム画面のホームの位置では、以下のような感じで表示される。
右にいくと、高度が上がっていく。
左にいくと、高度は下がり、一番左のホーム画面では、高度0。
動画でみてもらった方が話は早いか。
普通のライブ壁紙なら、動くのは左右にフリックしたときだけだが、AREarthLWFは少し違う。端末向きでも「グリグリ動いてしまう」のである。
ぜひ、このグリグリ感をダウンロードして試して欲しい。
AREarthライブ壁紙
https://play.google.com/store/apps/details?id=cx.fam.asai.AREarthLiveWallpaperFree
なお、標高データと詳細な衛星画像は、AREarthroid(Pro)から拝借している。AREarthLWF単独でも動作するが、標高データが含まれていないため、山は表示されない。AREarthroidまたは、有料版のAREarthroidProをインストールすることで、詳細な衛星画像と山が表示されるようになる。
サイト内を検索
ご存じのように、私が開発した「AREarthroid」をGoogle playで販売しているが、AREarthroidのライブ壁紙を作ってみた。その宣伝である。
名前はどうしようかと思ったが、「AREarthLiveWallpaperFree」とした。ちょっと長すぎたか。AREarthLWFとでも略しますか。
AREarthライブ壁紙
https://play.google.com/store/apps/details?id=cx.fam.asai.AREarthLiveWallpaperFree
Androidのホーム画面は、左右にスライドさせることで、壁紙が動いておもしろい。ライブ壁紙にすれば、もっと複雑な動きを実現できる。AREarthLWFでは、ホーム画面のホームの位置では、以下のような感じで表示される。
右にいくと、高度が上がっていく。
左にいくと、高度は下がり、一番左のホーム画面では、高度0。
動画でみてもらった方が話は早いか。
普通のライブ壁紙なら、動くのは左右にフリックしたときだけだが、AREarthLWFは少し違う。端末向きでも「グリグリ動いてしまう」のである。
ぜひ、このグリグリ感をダウンロードして試して欲しい。
AREarthライブ壁紙
https://play.google.com/store/apps/details?id=cx.fam.asai.AREarthLiveWallpaperFree
なお、標高データと詳細な衛星画像は、AREarthroid(Pro)から拝借している。AREarthLWF単独でも動作するが、標高データが含まれていないため、山は表示されない。AREarthroidまたは、有料版のAREarthroidProをインストールすることで、詳細な衛星画像と山が表示されるようになる。
サイト内を検索
AREarthroidの宣伝用ビデオ [Androidアプリ AREarthroid]
AREarthroidの宣伝用ビデオを撮影してみた。
ぐりぐり感がよくわかるでしょ。
最初、椅子に三脚を置き、ぐるぐる回転させてみたが、どうも「いまいち」。画面だけ撮影しても、周りの様子も一緒に写っていないと、AR感が伝わらない。
上の動画は、普通に、三脚は固定して、机の上で操作して撮影している。
車に積んで、カーナビ状態にして、撮影するのがいいかなぁ。外だとちゃんと写るか心配。
サイト内を検索
ぐりぐり感がよくわかるでしょ。
最初、椅子に三脚を置き、ぐるぐる回転させてみたが、どうも「いまいち」。画面だけ撮影しても、周りの様子も一緒に写っていないと、AR感が伝わらない。
上の動画は、普通に、三脚は固定して、机の上で操作して撮影している。
車に積んで、カーナビ状態にして、撮影するのがいいかなぁ。外だとちゃんと写るか心配。
サイト内を検索
AREarthroid Android 4.0対応 TRANSLUCENTがだめ [Androidアプリ AREarthroid]
久しぶりのブログ更新である。
本日のネタもAndroid。仕事がひと段落したので、AREarthroidのバージョンアップを行っている。
Android 4.0で動かした時に、背景がクリアされない現象は、どうも合成のために、OpenGLのサーフェースをTRANSLUCENTにするとダメになることが判明。
カメラプレビューと、OpenGLの画像を合成することで、AR的な画像が表示できる。OpenGLの背景の部分が、カメラプレビューになる、ということ。
GLSurfaceViewのコンストラクタで、以下のようにして設定を行っている。
最初は、カメラプレビューしていない状態から始まる。TRANSLUCENTになっていても、glClearで問題なく背景がクリアされていたが、Android 4.0になってから挙動が変わったらしい。
glClearでクリアする色のアルファ値を1.0に変更したところ、ちゃんと背景がクリアされるようにはなった。しかし、アルファブレンドで処理している部分に、残像が表示されてしまう。キャプチャできればよいのだが、残像はキャプチャできなかった。
TRANSLUCENTの設定をコメントアウトしてやってみると、残像が消えた。カメラプレビューのサーフェースにごみが書き込まれてしまっているのか?アルファ値が怪しそうなのだが...
TRANSLUCENTの設定をコメントアウトすると、当然ながら背景が透けない。カメラプレビューと合成できない。プレビュー開始時に、TRANSLUCENTの設定を行ってみると、ちゃんと合成された。
プレビューを終了する際に、元に戻したいのだが、どうすればよいのかわからない。プレビューは終了するが、残像が発生してしまう。カメラプレビューのON/OFFの方法に問題があるのかも?
とりあえずは、4.0の場合、TRANSLUCENTの設定をしないことで逃げることに。
ローパスフィルタ
ご存じのようにセンサーからの生データをそのまま使用すると、ノイズが多く、手ぶれ状態になる。ローパスフィルタをかけて、滑らかにしないと画面がブレてみれたものではない。原理は異なるが、ソフトウェアでVRをかける感じ。
AREarthroidでは、こんな感じでフィルタをかけている。
ここで、alphaの値を0.9とかにすると、滑らか度が増す。かわりに、反応は悪くなる。0.7にすると、反応はよくなるが、ブレブレな感じは増す。
AREarthroidでは、強、中、弱の設定が可能なようにした。
objファイルの選択
課題となっていた、objファイルの選択は、暗黙的インテントでファイルマネージャを起動することで行うことにした。以下のような、インテントを投げると、ファイルマネージャが起動する。
ファイルマネージャに、拡張子の登録がないと、リストされないが、そこまで面倒をみるのは大変。ユーザーに、やってもらうことにする。
ファイルマネージャ的なアプリが入っていないと、何も起動しないかも。
アクセス権の問題があるので、ローカルファイルにコピーしてきて、3Dデータを読み込む。obj形式の3Dデータには、マテリアルファイルが別にあるので、こちらのファイルも別途インポートしてもらう。少し手間がかかるが、しょうがない。
読み込んだ3Dデータの大きさは、スライドで調整できるようにした。調整できないと地球サイズのガンダムになってしまう。
関連ページ
http://asai-atsushi.blog.so-net.ne.jp/2012-06-12
回転マトリックス
AREarthroidでは、端末向きを計算して、カメラの位置を計算している。これが、ちょっとまどろっこしい方法になっていたので、getRotationMatrixで得られる回転マトリックスで回転させる方法に変更。
これで、少しブレブレ感を抑えることができた。また、カメラ位置の計算方法が変更になったので、地球から離れた位置からみたときの挙動が変わった。スペースシャトルから地球を「見下ろしている」感じになる。これがなかなか「かっこいい」。
端末を四方に並べてみたら、かなり面白そう。車に積んでみるのもいいか。
サイト内を検索
本日のネタもAndroid。仕事がひと段落したので、AREarthroidのバージョンアップを行っている。
Android 4.0で動かした時に、背景がクリアされない現象は、どうも合成のために、OpenGLのサーフェースをTRANSLUCENTにするとダメになることが判明。
カメラプレビューと、OpenGLの画像を合成することで、AR的な画像が表示できる。OpenGLの背景の部分が、カメラプレビューになる、ということ。
GLSurfaceViewのコンストラクタで、以下のようにして設定を行っている。
setEGLConfigChooser(8, 8, 8, 8, 16, 0); getHolder().setFormat(PixelFormat.TRANSLUCENT); renderer = new OpenGLRenderer(); setRenderer(renderer); setRenderMode(RENDERMODE_WHEN_DIRTY);
最初は、カメラプレビューしていない状態から始まる。TRANSLUCENTになっていても、glClearで問題なく背景がクリアされていたが、Android 4.0になってから挙動が変わったらしい。
glClearでクリアする色のアルファ値を1.0に変更したところ、ちゃんと背景がクリアされるようにはなった。しかし、アルファブレンドで処理している部分に、残像が表示されてしまう。キャプチャできればよいのだが、残像はキャプチャできなかった。
TRANSLUCENTの設定をコメントアウトしてやってみると、残像が消えた。カメラプレビューのサーフェースにごみが書き込まれてしまっているのか?アルファ値が怪しそうなのだが...
TRANSLUCENTの設定をコメントアウトすると、当然ながら背景が透けない。カメラプレビューと合成できない。プレビュー開始時に、TRANSLUCENTの設定を行ってみると、ちゃんと合成された。
プレビューを終了する際に、元に戻したいのだが、どうすればよいのかわからない。プレビューは終了するが、残像が発生してしまう。カメラプレビューのON/OFFの方法に問題があるのかも?
とりあえずは、4.0の場合、TRANSLUCENTの設定をしないことで逃げることに。
ローパスフィルタ
ご存じのようにセンサーからの生データをそのまま使用すると、ノイズが多く、手ぶれ状態になる。ローパスフィルタをかけて、滑らかにしないと画面がブレてみれたものではない。原理は異なるが、ソフトウェアでVRをかける感じ。
AREarthroidでは、こんな感じでフィルタをかけている。
public void onSensorChanged(SensorEvent event) { float alpha = 0.8; // ローパスフィルター accelerometerValues[0] = alpha * accelerometerValues[0] + (1.0f - alpha) * event.values[0]; accelerometerValues[1] = alpha * accelerometerValues[1] + (1.0f - alpha) * event.values[1]; accelerometerValues[2] = alpha * accelerometerValues[2] + (1.0f - alpha) * event.values[2]; }
ここで、alphaの値を0.9とかにすると、滑らか度が増す。かわりに、反応は悪くなる。0.7にすると、反応はよくなるが、ブレブレな感じは増す。
AREarthroidでは、強、中、弱の設定が可能なようにした。
objファイルの選択
課題となっていた、objファイルの選択は、暗黙的インテントでファイルマネージャを起動することで行うことにした。以下のような、インテントを投げると、ファイルマネージャが起動する。
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("text/plain"); startActivityForResult(intent, REQUEST_CODE_PICK_OBJ);
ファイルマネージャに、拡張子の登録がないと、リストされないが、そこまで面倒をみるのは大変。ユーザーに、やってもらうことにする。
ファイルマネージャ的なアプリが入っていないと、何も起動しないかも。
アクセス権の問題があるので、ローカルファイルにコピーしてきて、3Dデータを読み込む。obj形式の3Dデータには、マテリアルファイルが別にあるので、こちらのファイルも別途インポートしてもらう。少し手間がかかるが、しょうがない。
読み込んだ3Dデータの大きさは、スライドで調整できるようにした。調整できないと地球サイズのガンダムになってしまう。
関連ページ
http://asai-atsushi.blog.so-net.ne.jp/2012-06-12
回転マトリックス
AREarthroidでは、端末向きを計算して、カメラの位置を計算している。これが、ちょっとまどろっこしい方法になっていたので、getRotationMatrixで得られる回転マトリックスで回転させる方法に変更。
これで、少しブレブレ感を抑えることができた。また、カメラ位置の計算方法が変更になったので、地球から離れた位置からみたときの挙動が変わった。スペースシャトルから地球を「見下ろしている」感じになる。これがなかなか「かっこいい」。
端末を四方に並べてみたら、かなり面白そう。車に積んでみるのもいいか。
サイト内を検索
XperiaをAndroid 4.0にアップデート AREarthroidもアップデート [Androidアプリ AREarthroid]
本日は、Android 4.0とAREarthroidネタである。
Xperiaに通知が届き、なにやらアップデートのお知らせ。リビジョンアップかと思いアップデートしたら、なんとAndroid 4.0にバージョンアップした。
AREarthroidを動かしてみると、なんかおかしい。そういえば、4.0のエミュレータで動かしていた時もなんか変だったなぁ... 関連記事
これは、問題である。これから、Android 4.0の端末が増えるだろうし...
ということで、緊急デバッグを開始。
オーバーレイして上に乗っけているモニタ表示は、ほっておくとどんどん重ねて描画されていく感じ。アルファ値の設定がどこかで上書きされているのか?
いや違うっぽい。どうも、背景がきちんと消されていない感じ。前のフレームの残像が残っている。
onDrawFrameで、glClearで消しているけどなぁ... 3.0や2.3では動いているし。
これは、クリアする値の方が問題か?
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
全部0でクリアしている。背景は黒っていうこと。アルファ値は、これでいいのか?クリアする値だから0でいいのか?ちょっと変えてみるか。
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
おお、まともになった。
背景がクリアされない理由は、これか。しかし、Android 3.0ではちゃんとクリアされる。アルファ値は無視しているっていうこと?
Android 4.0になってアルファブレンドの方法が少し変更されたっぽいなぁ。NとかSの方角にまだ残像が残っている感じ。これは、じっくりやらないとわからないなぁ。そのままでもおかしくはないのでここは後回し。
カメラもなんかおかしいし... Android 4.0になったからといって、カメラプレビューの大きさが変更できないのは解決していない。機種依存なのか。
とりあえず、「スマホ型(サイズ固定)」を作って逃げることに。
というわけで、AREarthroidはバージョン1.2.9となりました。
サイト内を検索
Xperiaに通知が届き、なにやらアップデートのお知らせ。リビジョンアップかと思いアップデートしたら、なんとAndroid 4.0にバージョンアップした。
AREarthroidを動かしてみると、なんかおかしい。そういえば、4.0のエミュレータで動かしていた時もなんか変だったなぁ... 関連記事
これは、問題である。これから、Android 4.0の端末が増えるだろうし...
ということで、緊急デバッグを開始。
オーバーレイして上に乗っけているモニタ表示は、ほっておくとどんどん重ねて描画されていく感じ。アルファ値の設定がどこかで上書きされているのか?
いや違うっぽい。どうも、背景がきちんと消されていない感じ。前のフレームの残像が残っている。
onDrawFrameで、glClearで消しているけどなぁ... 3.0や2.3では動いているし。
これは、クリアする値の方が問題か?
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
全部0でクリアしている。背景は黒っていうこと。アルファ値は、これでいいのか?クリアする値だから0でいいのか?ちょっと変えてみるか。
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
おお、まともになった。
背景がクリアされない理由は、これか。しかし、Android 3.0ではちゃんとクリアされる。アルファ値は無視しているっていうこと?
Android 4.0になってアルファブレンドの方法が少し変更されたっぽいなぁ。NとかSの方角にまだ残像が残っている感じ。これは、じっくりやらないとわからないなぁ。そのままでもおかしくはないのでここは後回し。
カメラもなんかおかしいし... Android 4.0になったからといって、カメラプレビューの大きさが変更できないのは解決していない。機種依存なのか。
とりあえず、「スマホ型(サイズ固定)」を作って逃げることに。
というわけで、AREarthroidはバージョン1.2.9となりました。
サイト内を検索
Androidアプリ開発 OBJ形式のファイルを開くために「ファイル選択ダイアログ」が欲しい [Androidアプリ AREarthroid]
えーと、本日はAREarthroid関係のネタである。
AREarthroidでは、OpenGLを使用して3Dデータを表示している。自分でモデリングして作成した3Dデータを地球上に置くことができたら、かっこいいのではないかと思っている。
しかし、プログラムが「便利かどうか」ではなく「かっこいいかどうか」で機能拡張されていく気がしてならない。いいのだろうか... まぁ、いいとしよう。
でもって、3Dデータといってもいろいろな形式があるわけだが、無難なのは、OBJ形式かなぁ。
他には、DXFとか、3DSといった形式がある。OBJ形式は、Wavefrontの汎用フォーマットなわけね。
OBJ形式といってもバイナリじゃなくてテキスト。拡張子.objだとコンパイラが生成するオブジェクトファイルのイメージが強いので、バイナリか?と思ってしまうが、テキスト形式である。
開いて見てみると、数値がたくさん並んでいるだけ。ぱっと見何がなんやらわけがわからない。まぁ、3次元での座標値が書いてあるだけなので、ファイルの内容をみても何がなんだか、らわからなくて当たり前。
まずは、読み込み部分を作るか。えーと、最初から作成するのも骨が折れるので、検索。
http://www.saturn.dti.ne.jp/npaka/android/HelloGL10_21/index.html
にあるOBJ読み込みコードを参考にして作り始めた。
えーと、OBJファイルのフォーマットがわかっていないとプログラムも作れんなぁ。
上記のサイトにフォーマットの説明もあった。
なになに、基本「行」でひとつのデータになるのね。mtlibはマテリアルデータファイルの指定か。マテリアルは別のファイルになっているのか。
gは、グループ。
vが頂点座標(XYZ)。
vtは、テクスチャマッピングの座標(UV)。
vnは、法線(XYZ)。
usemtlでマテリアル名を指定。
fでポリゴン。
だいだいわかった。
しかし、Javaで書いたら「遅そう」。と思いつつも、なんとか完成。
とりあえず、初音ミクのOBJ形式データをassets/miku.objで作成して読み込ませてみた。案の定遅い。しかもバグっていてちゃんと表示されないし。
OpenGL ESでは、三角形のポリゴンしか表示できない。四角形もあるじゃないの。
なんか、テクスチャ座標番号の入っていないところもあるし。
なんやかんやいろいろと修正。ついでにparseFloatが遅いので、C/C++で作成。少し速くなった。
でどうなったかというと、今のところ、こんな感じです。
スケールを自動調整しないと、だめだなぁ。いくらなんでもでかすぎ。
ガンダムも表示してみた。
日光の当たり具合で、後ろ向きじゃないと逆行で真っ黒になってしまう。
ガンダムは、地面にめりこんでるなぁ。初音ミクは浮いてるし。標高データの精度が悪いっていうことか。これはいたしかたなしか...
どちらのデータもOBJファイルで1.3M程度の大きさ。頂点数もshortで収まっているので、2万個程度。メモリ的には大丈夫らしい。VBOにはまだしていないが、いずれはするつもり。描画速度はそれほど悪くない。読み込みには2秒程かかる。
テクスチャマッピングはしない方向で考えている。
ファイル選択したい
ここからが、本題。長い前振りであった。
外部にあるOBJファイルを選択して、AREarthroidに読み込ませたいと思っている。OBJファイルをインポートして、ローカルファイルにバイナリで保存しておけば、読み込み速度も改善されるでしょう。
それはよいとして、問題はどうやってファイル選択をするかである。画像ファイルなら、暗黙的インテントでピックアップすればよかったが、OBJファイルってテキストファイル。どういったインテントを投げればいいのやら... MIMEタイプをtext/plainにすればいいだけなのか?...
ファイルマネージャ的なアプリがインストールされていれば、そこに向かってインテントを投げてやればよさそうな気がするが、Android標準のファイルマネージャっていうのがありません(よね?)。
OBJファイルは、どこからかダウンロードしてくるであろうから、/download以下のファイルをリストするアクティビティでも作るか。/downloadならダウンロードアプリを起動すればいいかも?
ということで、ファイル選択の方法で行き詰っている。
初音ミクのOBJデータは、以下のURLにあった「Blenderデータ」を使って、適当にポーズを付けてエクスポートして作成。
キオ式アニキャラ3D act.3
http://kiomodel3.sblo.jp/
ガンダムの方は、以下のサイトにあったのを使わせてもらっている。
SeaGate Blog
http://pub.ne.jp/seagate/
他にも3Dデータがいろいろあるなぁ。Androidアプリも開発しているのか。とても参考になりそう。
「かんたんAndroidアプリ作成入門」には、インテントの使い方も載ってます。
サイト内を検索
AREarthroidでは、OpenGLを使用して3Dデータを表示している。自分でモデリングして作成した3Dデータを地球上に置くことができたら、かっこいいのではないかと思っている。
しかし、プログラムが「便利かどうか」ではなく「かっこいいかどうか」で機能拡張されていく気がしてならない。いいのだろうか... まぁ、いいとしよう。
でもって、3Dデータといってもいろいろな形式があるわけだが、無難なのは、OBJ形式かなぁ。
他には、DXFとか、3DSといった形式がある。OBJ形式は、Wavefrontの汎用フォーマットなわけね。
OBJ形式といってもバイナリじゃなくてテキスト。拡張子.objだとコンパイラが生成するオブジェクトファイルのイメージが強いので、バイナリか?と思ってしまうが、テキスト形式である。
開いて見てみると、数値がたくさん並んでいるだけ。ぱっと見何がなんやらわけがわからない。まぁ、3次元での座標値が書いてあるだけなので、ファイルの内容をみても何がなんだか、らわからなくて当たり前。
まずは、読み込み部分を作るか。えーと、最初から作成するのも骨が折れるので、検索。
http://www.saturn.dti.ne.jp/npaka/android/HelloGL10_21/index.html
にあるOBJ読み込みコードを参考にして作り始めた。
えーと、OBJファイルのフォーマットがわかっていないとプログラムも作れんなぁ。
上記のサイトにフォーマットの説明もあった。
なになに、基本「行」でひとつのデータになるのね。mtlibはマテリアルデータファイルの指定か。マテリアルは別のファイルになっているのか。
gは、グループ。
vが頂点座標(XYZ)。
vtは、テクスチャマッピングの座標(UV)。
vnは、法線(XYZ)。
usemtlでマテリアル名を指定。
fでポリゴン。
だいだいわかった。
しかし、Javaで書いたら「遅そう」。と思いつつも、なんとか完成。
とりあえず、初音ミクのOBJ形式データをassets/miku.objで作成して読み込ませてみた。案の定遅い。しかもバグっていてちゃんと表示されないし。
OpenGL ESでは、三角形のポリゴンしか表示できない。四角形もあるじゃないの。
なんか、テクスチャ座標番号の入っていないところもあるし。
なんやかんやいろいろと修正。ついでにparseFloatが遅いので、C/C++で作成。少し速くなった。
でどうなったかというと、今のところ、こんな感じです。
スケールを自動調整しないと、だめだなぁ。いくらなんでもでかすぎ。
ガンダムも表示してみた。
日光の当たり具合で、後ろ向きじゃないと逆行で真っ黒になってしまう。
ガンダムは、地面にめりこんでるなぁ。初音ミクは浮いてるし。標高データの精度が悪いっていうことか。これはいたしかたなしか...
どちらのデータもOBJファイルで1.3M程度の大きさ。頂点数もshortで収まっているので、2万個程度。メモリ的には大丈夫らしい。VBOにはまだしていないが、いずれはするつもり。描画速度はそれほど悪くない。読み込みには2秒程かかる。
テクスチャマッピングはしない方向で考えている。
ファイル選択したい
ここからが、本題。長い前振りであった。
外部にあるOBJファイルを選択して、AREarthroidに読み込ませたいと思っている。OBJファイルをインポートして、ローカルファイルにバイナリで保存しておけば、読み込み速度も改善されるでしょう。
それはよいとして、問題はどうやってファイル選択をするかである。画像ファイルなら、暗黙的インテントでピックアップすればよかったが、OBJファイルってテキストファイル。どういったインテントを投げればいいのやら... MIMEタイプをtext/plainにすればいいだけなのか?...
ファイルマネージャ的なアプリがインストールされていれば、そこに向かってインテントを投げてやればよさそうな気がするが、Android標準のファイルマネージャっていうのがありません(よね?)。
OBJファイルは、どこからかダウンロードしてくるであろうから、/download以下のファイルをリストするアクティビティでも作るか。/downloadならダウンロードアプリを起動すればいいかも?
ということで、ファイル選択の方法で行き詰っている。
初音ミクのOBJデータは、以下のURLにあった「Blenderデータ」を使って、適当にポーズを付けてエクスポートして作成。
キオ式アニキャラ3D act.3
http://kiomodel3.sblo.jp/
ガンダムの方は、以下のサイトにあったのを使わせてもらっている。
SeaGate Blog
http://pub.ne.jp/seagate/
他にも3Dデータがいろいろあるなぁ。Androidアプリも開発しているのか。とても参考になりそう。
「かんたんAndroidアプリ作成入門」には、インテントの使い方も載ってます。
かんたんAndroidアプリ作成入門 (プログラミングの教科書)
- 作者: 朝井 淳
- 出版社/メーカー: 技術評論社
- 発売日: 2013/04/16
- メディア: 単行本(ソフトカバー)
関連記事
Android 4.0対応AREarthroid Android 4.0対応 TRANSLUCENTがだめ
OpenGLの記事を最初から読みたいなら、以下からどうぞ。
Androidアプリ開発 OpenGLを使う GLSurfaceView
Android 4.0対応AREarthroid Android 4.0対応 TRANSLUCENTがだめ
OpenGLの記事を最初から読みたいなら、以下からどうぞ。
Androidアプリ開発 OpenGLを使う GLSurfaceView
サイト内を検索
Androidアプリ開発 ExifInterfaceでExif情報を読み込む [Androidアプリ AREarthroid]
本日は、Androidネタである。ご存じのように、デジカメで撮影した画像データには、Exifデータが添付される。Exifデータには、撮影日時やデジカメの機種、露出、などの情報が含まれている。
スマホを含む携帯電話で撮影すると、位置情報がExifデータとして画像データに含まれる。もちろん、GPS付きの携帯電話じゃないと、位置情報は含まれない。位置情報は、緯度と経度。
Androidで撮影すると、位置情報が画像データに含まれるわけである。これをAREarthroidでその位置に表示できたら、かっこいいかなぁ、ということでExif情報の取得について調べてみることに。
Exifデータは、画像データに含まれている。インテントで画像ファイルを受け取れるようにすれば、OKなはず。
インテントで受けた画像データをExifInterfaceクラスに渡してやるとExifデータを取得できる模様。
http://techbooster.jpn.org/andriod/multimedia/3098/
によると、
とのこと。AREarthroidは、2.2以降なので、問題なし。
取得したいのは、GPSLatitudeとGPSLongitudeなのだが、これはどのバージョンからサポートされているのかなぁ...
http://y-anz-m.blogspot.jp/2011/03/exif.html
によると、
Y.A.MさんのところはAndroidの情報量がすごい。Android女子部に入ってみたい気もするが、オジサンはだめか。
2.3以降なら、高度情報も取れるのか。もちろん、画像データに入っていればっていう話ではあるが。
えーと、どうすればいいのかっていうと、ExifInterfaceクラスのインスタンスを作って、getAttributeIntや、getAttributeで欲しい情報のタグを指定すれば戻ってくるのね。了解。
タグは、TAG_GPS_LATITUDE、TAG_GPS_LONGITUDE、TAG_GPS_ALTITUDEの3つか...
TAG_GPS_LATITUDE_REF、TAG_GPS_LONGITUDE_REF、TAG_GPS_ALTITUDE_REFも必要なのか。
こいつらは、文字列なのね。了解。
ExitInterfaceクラスをnewするときに、IOExceptionが発生するかも知れないので、tryで囲むのね。了解。
よしやってみよう。
とここまで書いたが、文字列形式の緯度、経度ってどんな形式?
緯度 : "num1/denom1,num2/denom2,num3/denom3" 形式のフォーマット
とY.A.Mさんのページに書いてある。
カンマ区切りで時,分,秒なのか。/はどういうこと?
とりあえずは、ログに出してみよう。
05-25 09:05:00.680: V/EXIF(921): latitudeRef=N
05-25 09:05:00.680: V/EXIF(921): latitude=35/1,49/1,13446/1000
05-25 09:05:00.680: V/EXIF(921): longitudeRef=E
05-25 09:05:00.680: V/EXIF(921): longitude=142/1,43/1,10623/1000
05-25 09:05:00.680: V/EXIF(921): altitudeRef=0
05-25 09:05:00.680: V/EXIF(921): altitude=0/1
緯度、経度で自宅の場所がバレバレなのも困るので、数値は変えてある。
latitudeRefはNが入っているこれは、間違いなく北緯のN。
latitudeは、やはり時,分,秒。時と分は/1。35度49分っていうことなのであろう。13446/1000っていうのが秒なのだが、これって13.446秒っていうことなのかな。
高度については0。
よし、わかった。以下のようなコードを書いてみた。
実行させてみたところ、あってそうなので、AREarthroidにも組み込んでみることにする。
(ver 1.2.7には組み込み済み)
サイト内を検索
スマホを含む携帯電話で撮影すると、位置情報がExifデータとして画像データに含まれる。もちろん、GPS付きの携帯電話じゃないと、位置情報は含まれない。位置情報は、緯度と経度。
Androidで撮影すると、位置情報が画像データに含まれるわけである。これをAREarthroidでその位置に表示できたら、かっこいいかなぁ、ということでExif情報の取得について調べてみることに。
Exifデータは、画像データに含まれている。インテントで画像ファイルを受け取れるようにすれば、OKなはず。
インテントで受けた画像データをExifInterfaceクラスに渡してやるとExifデータを取得できる模様。
http://techbooster.jpn.org/andriod/multimedia/3098/
によると、
ExifInterfaceクラスはAndroid2.0(API5)から追加されたクラスです。さらに、Android2.2(API8)、Android2.3(API9)、Android3.0(Honeycomb)でそれぞれ取得出来るExifのタグが増えています。
とのこと。AREarthroidは、2.2以降なので、問題なし。
取得したいのは、GPSLatitudeとGPSLongitudeなのだが、これはどのバージョンからサポートされているのかなぁ...
http://y-anz-m.blogspot.jp/2011/03/exif.html
によると、
* Android 2.3 ・ JPEG ファイルの EXIF メタデータで新しく altitude tag (高度情報)に対応した ・ EXIF altitude tag の値を取得するために新しく getAltitude() メソッドが追加された http://developer.android.com/sdk/android-2.3.html#api の Mixable audio effects 部分
Y.A.MさんのところはAndroidの情報量がすごい。Android女子部に入ってみたい気もするが、オジサンはだめか。
2.3以降なら、高度情報も取れるのか。もちろん、画像データに入っていればっていう話ではあるが。
えーと、どうすればいいのかっていうと、ExifInterfaceクラスのインスタンスを作って、getAttributeIntや、getAttributeで欲しい情報のタグを指定すれば戻ってくるのね。了解。
タグは、TAG_GPS_LATITUDE、TAG_GPS_LONGITUDE、TAG_GPS_ALTITUDEの3つか...
TAG_GPS_LATITUDE_REF、TAG_GPS_LONGITUDE_REF、TAG_GPS_ALTITUDE_REFも必要なのか。
こいつらは、文字列なのね。了解。
ExitInterfaceクラスをnewするときに、IOExceptionが発生するかも知れないので、tryで囲むのね。了解。
よしやってみよう。
try { ExifInterface exifInterface = new ExifInterface(filename); String latitudeRef = exifInterface.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF); String latitude = exifInterface.getAttribute(ExifInterface.TAG_GPS_LATITUDE); String longitudeRef = exifInterface.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF); String longitude = exifInterface.getAttribute(ExifInterface.TAG_GPS_LONGITUDE); String altitudeRef = exifInterface.getAttribute(ExifInterface.TAG_GPS_ALTITUDE_REF); String altitude = exifInterface.getAttribute(ExifInterface.TAG_GPS_ALTITUDE); } catch (Exception ex) { ex.printStackTrace(); }
とここまで書いたが、文字列形式の緯度、経度ってどんな形式?
緯度 : "num1/denom1,num2/denom2,num3/denom3" 形式のフォーマット
とY.A.Mさんのページに書いてある。
カンマ区切りで時,分,秒なのか。/はどういうこと?
とりあえずは、ログに出してみよう。
05-25 09:05:00.680: V/EXIF(921): latitudeRef=N
05-25 09:05:00.680: V/EXIF(921): latitude=35/1,49/1,13446/1000
05-25 09:05:00.680: V/EXIF(921): longitudeRef=E
05-25 09:05:00.680: V/EXIF(921): longitude=142/1,43/1,10623/1000
05-25 09:05:00.680: V/EXIF(921): altitudeRef=0
05-25 09:05:00.680: V/EXIF(921): altitude=0/1
緯度、経度で自宅の場所がバレバレなのも困るので、数値は変えてある。
latitudeRefはNが入っているこれは、間違いなく北緯のN。
latitudeは、やはり時,分,秒。時と分は/1。35度49分っていうことなのであろう。13446/1000っていうのが秒なのだが、これって13.446秒っていうことなのかな。
高度については0。
よし、わかった。以下のようなコードを書いてみた。
private double ExifHourMinSecToDegrees(String exifhourminsec) { String hourminsec[] = exifhourminsec.split(","); String hour[] = hourminsec[0].split("/"); String min[] = hourminsec[1].split("/"); String sec[] = hourminsec[2].split("/"); double dhour = (double)Integer.parseInt(hour[0]) / (double)Integer.parseInt(hour[1]); double dmin = (double)Integer.parseInt(min[0]) / (double)Integer.parseInt(min[1]); double dsec = (double)Integer.parseInt(sec[0]) / (double)Integer.parseInt(sec[1]); double degrees = dhour + dmin / 60.0 + dsec / 3600.0; return degrees; } private double ExifLatitudeToDegrees(String ref, String latitude) { return ref.equals("S") ? -1.0 : 1.0 * ExifHourMinSecToDegrees(latitude); } private double ExifLongitudeToDegrees(String ref, String longitude) { return ref.equals("W") ? -1.0 : 1.0 * ExifHourMinSecToDegrees(longitude); }
実行させてみたところ、あってそうなので、AREarthroidにも組み込んでみることにする。
(ver 1.2.7には組み込み済み)
サイト内を検索
タグ:Android
Copyright Atsushi Asai Google+朝井淳
[データベースの気持ちがわかる]SQLはじめの一歩 (WEB+DB PRESS plus)
- 作者: 朝井 淳
- 出版社/メーカー: 技術評論社
- 発売日: 2015/03/03
- メディア: 単行本(ソフトカバー)
Access クエリ 徹底活用ガイド ~仕事の現場で即使える
- 作者: 朝井 淳
- 出版社/メーカー: 技術評論社
- 発売日: 2018/05/25
- メディア: 大型本