私たちの中で GWT WebToolkitに関する以前の投稿 、の長所と特徴について話し合いました GWT 、これにより、一般的な考え方を思い出すと、JavaソースコードをJavaScriptにトランスパイルし、JavaライブラリとJavaScriptライブラリをシームレスに組み合わせることができます。 GWTによって生成されたJavaScriptが劇的に最適化されていることに注目しました。
今日の投稿では、もう少し深く掘り下げて、GWTツールキットの動作を確認したいと思います。 GWTを利用して独自のアプリケーションを構築する方法を示します。 拡張現実 (AR)ブラウザで完全にJavaScriptでリアルタイムに実行されるWebアプリケーション。
どの配色が目に心地よいが、視覚的な活気とコントラストに欠けているか
この記事では、GWTがWebRTCやWebGLなどの多くのJavaScript APIと簡単に対話できるようにし、ブラウザーでの使用を意図していない大規模なJavaライブラリーNyARToolkitを利用できるようにする方法に焦点を当てます。 GWTが私のチームと私をどのように許可したかを示します Jooink これらすべての要素を組み合わせてペットプロジェクトを作成するには、 Picshare 、ブラウザで試すことができるマーカーベースのARアプリケーション たった今 。
この投稿は、アプリケーションの構築方法の包括的なウォークスルーではなく、GWTを使用して一見圧倒的な課題を簡単に克服する方法を紹介します。
Picshare マーカーベースの拡張現実を使用します。このタイプのARアプリケーションは、シーンで マーカー :特定の、簡単に認識できる幾何学模様、 このような 。マーカーは、マークされたオブジェクトの位置と方向に関する情報を提供し、ソフトウェアが追加の3D風景を現実的な方法で画像に投影できるようにします。このプロセスの基本的な手順は次のとおりです。
WebGLやWebRTCなどのJavaScriptAPIを使用すると、ブラウザーとユーザーの間で予期しない異常な対話が可能になります。
たとえば、WebGLは、ハードウェアアクセラレーションによるグラフィックスを可能にし、 型付き配列 仕様では、JavaScriptエンジンがほぼネイティブのパフォーマンスで数値計算を実行できるようにします。同様に、WebRTCを使用すると、ブラウザーはコンピューターハードウェアから直接ビデオ(およびその他のデータ)ストリームにアクセスできます。
WebGLとWebRTCはどちらもJavaScriptライブラリであり、Webブラウザに組み込む必要があります。最新のHTML5ブラウザーのほとんどは、両方のAPIを少なくとも部分的にサポートしています(ご覧のとおり) ここに そして ここに )。しかし、Javaで書かれたGWTでこれらのツールをどのように利用できるでしょうか。なので 前の投稿で説明しました 、GWTの相互運用性レイヤー、 JsInterop (GWT 2.8で正式にリリースされました)これは簡単なことです。
GWT 2.8でJsInteropを使用するのは、-generateJsInteropExports
を追加するのと同じくらい簡単です。コンパイラへの引数として。使用可能なアノテーションは、jsinterop.annotations
にバンドルされているパッケージgwt-user.jar
で定義されています。
例として、最小限のコーディング作業で、WebRTCのgetUserMedia
を使用しますChromeとGWTは、書くのと同じくらい簡単になります。
Navigator.webkitGetUserMedia( configs, stream -> video.setSrc( URL.createObjectURL(stream) ), e -> Window.alert('Error: ' + e) );
クラスNavigator
の場所次のように定義できます。
@JsType(namespace = JsPackage.GLOBAL, isNative = true, name='navigator') final static class Navigator { public static native void webkitGetUserMedia( Configs configs, SuccessCallback success, ErrorCallback error); }
興味深いのは、インターフェースの定義ですSuccessCallback
およびErrorCallback
は、上記のラムダ式によって実装され、@JsFunction
によってJavaで定義されています。注釈:
@JsFunction public interface SuccessCallback { public void onMediaSuccess(MediaStream stream); } @JsFunction public interface ErrorCallback { public void onError(DomException error); }
最後に、クラスの定義URL
Navigator
とほぼ同じで、同様にConfigs
です。クラスは次のように定義できます。
@JsType(namespace = JsPackage.GLOBAL, isNative = true, name='Object') public static class Configs { @JsProperty public native void setVideo(boolean getVideo); }
これらすべての機能の実際の実装は、ブラウザのJavaScriptエンジンで行われます。
上記のコードはGitHubにあります ここに 。
この例では、簡単にするために、非推奨のnavigator.getUserMedia()
を使用します。 APIが使用されているのは、Chromeの現在の安定したリリースでポリフィルなしで機能する唯一のAPIだからです。本番アプリでは、 adapter.js 新しいnavigator.mediaDevices.getUserMedia()
を介してストリームにアクセスするにはAPI、すべてのブラウザで均一ですが、これは現在の説明の範囲を超えています。
GWTからWebGLを使用することは、WebRTCを使用することとそれほど違いはありませんが、OpenGL標準の本質的な複雑さのために、少し面倒です。
ここでのアプローチは、前のセクションで行ったアプローチを反映しています。ラッピングの結果は、で使用されているGWTWebGL実装で確認できます。 Picshare 、見つけることができます ここに 、およびGWTによって生成された結果の例を見つけることができます ここに 。
WebGLを単独で有効にしても、実際には3Dグラフィックス機能は提供されません。 グレッグタバレスが書いているように :
多くの人が知らないのは、WebGLが実際には3DAPIではなく2DAPIであるということです。
3D演算は、他のコードで実行し、WebGL用に2D画像に変換する必要があります。 3DWebGLグラフィックス用の優れたGWTライブラリがいくつかあります。私のお気に入りは 視差 、ただし、の最初のバージョンの場合 Picshare より「日曜大工」の道をたどり、単純な3Dメッシュをレンダリングするための小さなライブラリを作成しました。ライブラリを使用すると、 透視カメラ オブジェクトのシーンを管理します。お気軽にチェックしてください、 ここに 。
NyARToolkitは、の純粋なJavaポートです。 ARToolKit 、拡張現実アプリケーションを構築するためのソフトウェアライブラリ。ポートは日本の開発者によって書かれました ニャトラ 。元のARToolKitとNyatlaバージョンは、元の移植以降多少異なっていますが、NyARToolkitは引き続き積極的に維持され、改善されています。
マーカーベースのARは専門分野であり、ここで明らかなように、コンピュータービジョン、デジタル画像処理、および数学の能力が必要です。
から複製 ARToolKitのドキュメント 。
から複製 ARToolKitのドキュメント 。
ツールキットで使用されるすべてのアルゴリズムは文書化され、十分に理解されていますが、最初から書き直すのは長くてエラーが発生しやすいプロセスであるため、ARToolKitなどの既存の実績のあるツールキットを使用することをお勧めします。残念ながら、Webをターゲットにする場合、そのようなものはありません。最も強力で高度なツールキットには、主にHTMLドキュメントとデータの操作に使用される言語であるJavaScriptが実装されていません。これは、GWTがその非常に優れた強みを証明する場所であり、NyARToolkitをJavaScriptに単純にトランスパイルし、ほとんど手間をかけずにWebアプリケーションで使用できるようにします。
GWTプロジェクトは本質的にJavaプロジェクトであるため、NyARToolkitの使用は、ソースパスにソースファイルをインポートするだけです。ただし、GWTコードのJavaScriptへの変換はソースコードレベルで行われるため、コンパイルされたクラスを含むJARだけでなく、NyARToolkitのソースが必要であることに注意してください。
によって使用されるライブラリ Picshare 見つけることができます ここに 。 lib/src
内にあるパッケージにのみ依存しますおよびlib/src.markersystem
アーカイブされたNyARToolkitビルドから ここに 。これらのパッケージをコピーしてGWTプロジェクトにインポートする必要があります。
これらのサードパーティパッケージを独自の実装とは別にしておく必要がありますが、NyARToolkitの「GWT化」を進めるには、ソースを探す場所をGWTコンパイラに通知するXML構成ファイルを提供する必要があります。パッケージjp.nyatla.nyartoolkit
に、ファイルNyARToolkit.gwt.xml
を追加します。
com.jooink.gwt.nyartoolkit
ここで、メインパッケージGWT_NyARToolKit.gwt.xml
で、メイン構成ファイルNo source code is available for type java.io.InputStream; did you forget to inherit a required module?
を作成し、XMLファイルから継承してクラスパスにNyatlaのソースを含めるようコンパイラーに指示します。
InputStream
実際、かなり簡単です。ほとんどの場合、これですべてですが、残念ながらまだ完了していません。コンパイルまたは実行しようとすると スーパー開発モード この段階で、非常に驚くべきことに、次のようなエラーが発生します。
jre
これは、NyARToolkit(つまり、Javaプロジェクト向けのJavaライブラリ)が、GWTでサポートされていないJREのクラスを使用しているためです。 エミュレートされたJRE 。私達 これについて簡単に説明しました 前の投稿で。
この場合、問題はjava.io.FileInputStream java.io.InputStream java.io.InputStreamReader java.io.StreamTokenizer java.lang.reflect.Array java.nio.ByteBuffer java.nio.ByteOrder
にありますおよび関連するIOクラス。たまたま、これらのクラスのほとんどを使用する必要はありませんが、コンパイラーにいくつかの実装を提供する必要があります。 NyARToolkitソースからこれらの参照を手動で削除するのに多大な時間を費やすことができますが、それはおかしなことになります。 GWTは、より良いソリューションを提供します。XMLタグを介して、サポートされていないクラスの独自の実装を提供します。
で説明されているように 公式ドキュメント :
タグは、コンパイラにソースパスを再ルート化するように指示します。これは、GWTプロジェクトに既存のJava APIを再利用したいが、元のソースが利用できないか、翻訳できない場合に役立ちます。これの一般的な理由は、GWTによって実装されていないJREの一部をエミュレートすることです。
Soisはまさに私たちが必要としているものです。
java.lang.reflect.Array
を作成できますGWTプロジェクトのディレクトリ。ここで、問題の原因となっているクラスの実装を配置できます。
FileInputStream
package java.io; import java.io.InputStream; import com.google.gwt.user.client.Window; public class FileInputStream extends InputStream { public FileInputStream(String filename) { Window.alert('WARNING, FileInputStream created with filename: ' + filename ); } @Override public int read() { return 0; } }
を除いて、これらはすべて実際には使用されていないため、必要なのはダムの実装だけです。たとえば、Window.alert
次のように読みます:
java.lang.reflect.Array
package java.lang.reflect; import jp.nyatla.nyartoolkit.core.labeling.rlelabeling.NyARRleLabelFragmentInfo; import jp.nyatla.nyartoolkit.markersystem.utils.SquareStack; import com.google.gwt.user.client.Window; public class Array { public static Object newInstance(Class c, int n) { if( NyARRleLabelFragmentInfo.class.equals(c)) return new NyARRleLabelFragmentInfo[n]; else if(SquareStack.Item.class.equals(c)) return new SquareStack.Item[n]; else Window.alert('Creating array of size ' + n + ' of ' + c.toString()); return null; } }
コンストラクターのステートメントは、開発中に役立ちます。クラスをコンパイルできる必要がありますが、実際に使用しないようにしたいので、クラスが誤って使用された場合に警告が表示されます。
GWT_NyARToolkit.gwt.xml
は実際に必要なコードによって使用されるため、完全にダムではない実装が必要です。これは私たちのコードです:
Sensor.update()
ここで、// given a drawing context with appropriate width and height // and a where the mediastream is drawn ... // for each video frame // draw the video frame on the canvas ctx.drawImage(video, 0, 0, w, h); // extract image data from the canvas ImageData capt = ctx.getImageData(0, 0, w, h); // convert the image data in a format acceptable by NyARToolkit ImageDataRaster input = new ImageDataRaster(capt); // push the image in to a NyARSensor sensor.update(input); // update the NyARMarkerSystem with the sensor nyar.update(sensor); // the NyARMarkerSystem contains information about the marker patterns and is able to detect them. // After the call to update, all the markers are detected and we can get information for each // marker that was found. if( nyar.isExistMarker( marker_id ) ) { NyARDoubleMatrix44 m = nyar.getMarkerMatrix(marker_id); // m is now the matrix representing the pose (position and orientation) of // the marker in the scene, so we can use it to superimpose an object of // our choice ... } ...
に配置するとモジュールファイルを使用すると、プロジェクトでNyARToolkitを安全にコンパイルして使用できます。
今、私たちは次のような立場にあります。
現在の課題は、これらすべてのテクノロジーを統合することです。
これを実現する方法については詳しく説明しませんが、基本的な考え方は、ビデオ画像をシーンの背景(上の画像の「遠い」平面に適用されたテクスチャ)として使用し、3Dデータ構造を構築することです。 NyARToolkitの結果を使用して、この画像を宇宙に投影することができます。
テレグラムボットとは
この構造により、マーカー認識のためにNyARToolkitのライブラリと対話し、カメラのシーンの上に3Dモデルを描画するための適切な構造が得られます。
カメラストリームを使用可能にするのは少し注意が必要です。ビデオデータは要素にのみ描画できます。 HTML5elementは不透明であり、画像データを直接抽出できないため、ビデオを中間にコピーし、画像データを抽出してピクセルの配列に変換し、最後にNyARToolkitの| _ +にプッシュする必要があります。 _ |方法。次に、NyARToolkitは、画像内のマーカーを識別し、3D空間内のその位置に対応する変換行列を返す作業を実行できます。
これらの要素を使用して、ライブビデオストリームのマーカーの真上に3Dで合成オブジェクトを配置できます。 GWTの高性能のおかげで、十分な計算リソースがあるため、WebGLシーンの背景として使用する前に、セピアやぼかしなどのビデオ効果をキャンバスに適用することもできます。
次の要約コードは、プロセスのコアを説明しています。
|_+_|
この手法を使用すると、次のような結果を生成できます。
これは私たちが作成するために使用したプロセスです Picshare 、あなたが招待されている場所 プリントアウト マーカーまたは あなたの携帯電話にそれを表示します 、ブラウザでマーカーベースのARで遊んでください。楽しい!
Picshare Jooinkでの私たちにとっての長期的なペットプロジェクトです。最初の実装は数年前にさかのぼりますが、それでも印象的なほど高速でした。で このリンク 2012年にコンパイルされ、触れられたことのない以前の実験の1つを見ることができます。サンプルには1つしかないことに注意してください。他の2つのウィンドウは、処理の結果を表示する要素です。
GWTは2012年でも十分に強力でした。GWT2.8のリリースにより、JsInteropとの相互運用性レイヤーが大幅に改善され、パフォーマンスがさらに向上しました。また、多くの人を祝うために、はるかに優れた開発およびデバッグ環境であるSuper DevModeも入手しました。そうそう、Java8がサポートしています。
GWT 3.0を楽しみにしています!