2 * PROJECT: NyARToolkit for Android SDK
3 * --------------------------------------------------------------------------------
4 * This work is based on the original ARToolKit developed by
7 * HITLab, University of Washington, Seattle
8 * http://www.hitl.washington.edu/artoolkit/
10 * NyARToolkit for Android SDK
11 * Copyright (C)2010 NyARToolkit for Android team
12 * Copyright (C)2010 R.Iizuka(nyatla)
14 * This program is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27 * For further information please contact.
28 * http://sourceforge.jp/projects/nyartoolkit-and/
30 * This work is based on the NyARToolKit developed by
32 * http://nyatla.jp/nyatoolkit/
38 package jp.androidgroup.nyartoolkit;
40 import android.graphics.Bitmap;
41 import android.graphics.BitmapFactory;
42 import android.media.MediaPlayer;
43 import android.os.SystemClock;
44 import android.util.Log;
46 import java.io.InputStream;
47 import java.util.ArrayList;
49 import min3d.core.Renderer;
51 import jp.nyatla.nyartoolkit.NyARException;
52 import jp.nyatla.nyartoolkit.core.NyARCode;
53 import jp.nyatla.nyartoolkit.core.param.NyARParam;
54 import jp.nyatla.nyartoolkit.core.raster.rgb.NyARRgbRaster_RGB;
55 import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;
56 import jp.nyatla.nyartoolkit.core.types.NyARBufferType;
57 import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix44;
58 import jp.nyatla.nyartoolkit.detector.NyARDetectMarker;
59 import jp.nyatla.nyartoolkit.jogl.utils.NyARGLUtil;
65 public class ARToolkitDrawer
73 * 一回の処理で検出できる最大のマーカー数。誤認識分も含まれるので少なすぎても駄目、多すぎると処理負荷増
75 private static final int MARKER_MAX = 8;
78 * @see jp.nyatla.nyartoolkit.detector.NyARDetectMarker
80 private NyARDetectMarker nya = null;
83 * @see jp.nyatla.nyartoolkit.core.raster.rgb.NyARRgbRaster_RGB
85 private NyARRgbRaster_RGB raster = null;
89 * @see jp.nyatla.nyartoolkit.core.param.NyARParam
91 private NyARParam ar_param = null;
95 * @see jp.nyatla.nyartoolkit.core.param.NyARParam
97 private NyARCode[] ar_code;
102 private double marker_width[];
106 * @see jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult
108 private NyARTransMatResult ar_transmat_result = new NyARTransMatResult();
111 // Renderer for metasequoia model
112 // private ModelRenderer mRenderer = null;
114 private Renderer mRenderer;
116 private MediaPlayer mMediaPlayer = null;
119 System.loadLibrary("yuv420sp2rgb");
121 public static native void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height, int type);
122 public static native void decodeYUV420SP(byte[] rgb, byte[] yuv420sp, int width, int height, int type);
130 * @param mTranslucentBackground
131 * @param isYuv420spPreviewFormat
133 // Renderer for metasequoia model
134 // public ARToolkitDrawer(InputStream camePara, int[] width, ArrayList<InputStream> patt, ModelRenderer mRenderer) {
136 public ARToolkitDrawer(InputStream camePara, int[] width, ArrayList<InputStream> patt, Renderer mRenderer) {
137 this.mRenderer = mRenderer;
139 this.initialization(camePara, width, patt);
144 * マーカーパターン、カメラパラメータはここで読み込む
146 private void initialization(InputStream camePara, int[] width, ArrayList<InputStream> patt) {
147 mNumPatt = patt.size();
148 marker_width = new double[mNumPatt];
149 ar_code = new NyARCode[mNumPatt];
151 for (int i = 0; i < mNumPatt; i++) {
153 marker_width[i] = width[i];
156 ar_code[i] = new NyARCode(16, 16);
157 ar_code[i].loadARPatt(patt.get(i));
160 ar_param = new NyARParam();
161 ar_param.loadARParam(camePara);
162 } catch (Exception e) {
163 Log.e("nyar", "resource loading failed", e);
171 * @param w スクリーンサイズ(width)
172 * @param h スクリーンサイズ(height)
174 private void createNyARTool(int w, int h) {
175 // NyARToolkit setting.
178 ar_param.changeScreenSize(w, h);
180 // マーカーの枠線幅を変えることは可能。
181 // NyARDetectMarker 内にコメントを追加したのでその部分を参照のこと
182 nya = new NyARDetectMarker(ar_param, ar_code, marker_width, mNumPatt, NyARBufferType.BYTE1D_B8G8R8_24);
183 nya.setContinueMode(true);
185 Log.d("nyar", "resources have been loaded");
186 } catch (Exception e) {
187 Log.e("nyar", "resource loading failed", e);
196 public void setMediaPlayer(MediaPlayer mediaplayer) {
197 this.mMediaPlayer = mediaplayer;
201 * NyARGLUtil.toCameraFrustumRH()の出力double[]をfloat[]に変換する
203 * @param o_gl_projection
205 public static void toCameraFrustumRHf(NyARParam i_arparam, float[] o_gl_projection)
207 double[] mf = new double[16];
208 NyARGLUtil.toCameraFrustumRH(i_arparam, NyARGLUtil.SCALE_FACTOR_toCameraFrustumRH_NYAR2, 10, 10000, mf);
210 for (int i = 0; i < mf.length; i++) {
211 o_gl_projection[i] = (float) mf[i];
216 * NyARGLUtil.toCameraViewRH()の出力double[]をfloat[]に変換する
220 public static void toCameraViewRHf(NyARDoubleMatrix44 i_ny_result, float[] o_gl_result)
222 double[] mf = new double[16];
223 NyARGLUtil.toCameraViewRH(i_ny_result, NyARGLUtil.SCALE_FACTOR_toCameraViewRH_NYAR2, mf);
225 for (int i = 0; i < mf.length; i++) {
226 o_gl_result[i] = (float) mf[i];
235 public void draw(byte[] data) {
238 Log.d("AR draw", "data= null");
241 Log.d("AR draw", "data.length= " + data.length);
245 // start coordinates calculation.
246 byte[] buf = new byte[width * height * 3];
249 long time1 = SystemClock.uptimeMillis();
250 // convert YUV420SP to RGB24
251 decodeYUV420SP(buf, data, width, height, 1);
252 long time2 = SystemClock.uptimeMillis();
253 Log.d("ARToolkitDrawer", "RGB decode time: " + (time2 - time1) + "ms");
255 float[][] resultf = new float[MARKER_MAX][16];
258 int ar_code_index[] = new int[MARKER_MAX];
260 createNyARTool(width, height);
263 Log.d("AR draw", "Marker detection.");
264 raster = new NyARRgbRaster_RGB(width, height);
265 raster.wrapBuffer(buf);
266 found_markers = nya.detectMarkerLite(raster, 100);
267 } catch (NyARException e) {
268 Log.e("AR draw", "marker detection failed", e);
272 boolean isDetect = false;
274 // An OpenGL object will be drawn if matched.
275 if (found_markers > 0) {
276 Log.d("AR draw", "!!!!!!!!!!!exist marker." + found_markers + "!!!!!!!!!!!");
277 // Projection transformation.
278 float[] cameraRHf = new float[16];
279 toCameraFrustumRHf(ar_param, cameraRHf);
281 if (found_markers > MARKER_MAX)
282 found_markers = MARKER_MAX;
283 for (int i = 0; i < found_markers; i++) {
284 if (nya.getConfidence(i) < 0.60f)
287 ar_code_index[i] = nya.getARCodeIndex(i);
288 NyARTransMatResult transmat_result = ar_transmat_result;
289 nya.getTransmationMatrix(i, transmat_result);
290 toCameraViewRHf(transmat_result, resultf[i]);
292 } catch (NyARException e) {
293 Log.e("AR draw", "getCameraViewRH failed", e);
297 mRenderer.objectPointChanged(found_markers, ar_code_index, resultf, cameraRHf);
299 Log.d("AR draw", "not exist marker.");
301 mRenderer.objectClear();
304 if (mMediaPlayer != null) {
305 if (!mMediaPlayer.isPlaying())
306 mMediaPlayer.start();
310 if (mMediaPlayer != null) {
311 if (mMediaPlayer.isPlaying())
312 mMediaPlayer.pause();