OSDN Git Service

Fix compile error for Android SDK.
[nyartoolkit-and/nyartoolkit-and.git] / src / jp / androidgroup / nyartoolkit / ARToolkitDrawer.java
1 /*
2  * PROJECT: NyARToolkit for Android SDK
3  * --------------------------------------------------------------------------------
4  * This work is based on the original ARToolKit developed by
5  *   Hirokazu Kato
6  *   Mark Billinghurst
7  *   HITLab, University of Washington, Seattle
8  * http://www.hitl.washington.edu/artoolkit/
9  *
10  * NyARToolkit for Android SDK
11  *   Copyright (C)2010 NyARToolkit for Android team
12  *   Copyright (C)2010 R.Iizuka(nyatla)
13  *
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.
18  *
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.
23  *
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/>.
26  *
27  * For further information please contact.
28  *  http://sourceforge.jp/projects/nyartoolkit-and/
29  *
30  * This work is based on the NyARToolKit developed by
31  *  R.Iizuka (nyatla)
32  *    http://nyatla.jp/nyatoolkit/
33  *
34  * contributor(s)
35  *  Atsuo Igarashi
36  */
37
38 package jp.androidgroup.nyartoolkit;
39
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;
45
46 import java.io.InputStream;
47 import java.util.ArrayList;
48
49 import min3d.core.Renderer;
50
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;
60
61 /**
62  * ARToolKit Drawer
63  *  マーカー認識部分などが含まれたクラス
64  */
65 public class ARToolkitDrawer
66 {
67         /**
68          * マーカーのパターン数
69          */
70         private int mNumPatt;
71
72         /**
73          * 一回の処理で検出できる最大のマーカー数。誤認識分も含まれるので少なすぎても駄目、多すぎると処理負荷増
74          */
75         private static final int MARKER_MAX = 8;
76
77         /**
78          * @see jp.nyatla.nyartoolkit.detector.NyARDetectMarker
79          */
80         private NyARDetectMarker nya = null;
81
82         /**
83          * @see jp.nyatla.nyartoolkit.core.raster.rgb.NyARRgbRaster_RGB
84          */
85         private NyARRgbRaster_RGB raster = null;
86
87         /**
88          * カメラパラメータを保持するクラス
89          * @see jp.nyatla.nyartoolkit.core.param.NyARParam
90          */
91         private NyARParam ar_param = null;
92
93         /**
94          * マーカーのパターン情報を管理するクラス
95          * @see jp.nyatla.nyartoolkit.core.param.NyARParam
96          */
97         private NyARCode[] ar_code;
98
99         /**
100          * マーカーの幅
101          */
102         private double marker_width[];
103
104         /**
105          * 検出したマーカーの座標変換行列
106          * @see jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult
107          */
108         private NyARTransMatResult ar_transmat_result = new NyARTransMatResult();
109
110
111         // Renderer for metasequoia model
112 //      private ModelRenderer mRenderer = null;
113         // Renderer of min3d
114     private Renderer mRenderer;
115
116         private MediaPlayer mMediaPlayer = null;
117
118         static {
119                 System.loadLibrary("yuv420sp2rgb");
120         }
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);
123
124         /**
125          * Constructor
126          *
127          * @param camePara
128          * @param patt
129          * @param mRenderer
130          * @param mTranslucentBackground
131          * @param isYuv420spPreviewFormat
132          */
133         // Renderer for metasequoia model
134 //      public ARToolkitDrawer(InputStream camePara, int[] width, ArrayList<InputStream> patt, ModelRenderer mRenderer) {
135         // Renderer of min3d
136         public ARToolkitDrawer(InputStream camePara, int[] width, ArrayList<InputStream> patt, Renderer mRenderer) {
137                 this.mRenderer = mRenderer;
138
139                 this.initialization(camePara, width, patt);
140         }
141
142         /**
143          * 初期化処理
144          * マーカーパターン、カメラパラメータはここで読み込む
145          */
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];
150                 try {
151                         for (int i = 0; i < mNumPatt; i++) {
152                                 // マーカーの幅
153                                 marker_width[i] = width[i];
154
155                                 // マーカーの分割数
156                                 ar_code[i] = new NyARCode(16, 16);
157                                 ar_code[i].loadARPatt(patt.get(i));
158                         }
159
160                         ar_param = new NyARParam();
161                         ar_param.loadARParam(camePara);
162                 } catch (Exception e) {
163                         Log.e("nyar", "resource loading failed", e);
164                 }
165         }
166
167         /**
168          * NyARToolKitの初期化
169          *  カメラパラメータの読み込み
170          *
171          * @param w スクリーンサイズ(width)
172          * @param h スクリーンサイズ(height)
173          */
174         private void createNyARTool(int w, int h) {
175                 // NyARToolkit setting.
176                 try {
177                         if (nya == null) {
178                                 ar_param.changeScreenSize(w, h);
179
180                                 // マーカーの枠線幅を変えることは可能。
181                                 // NyARDetectMarker 内にコメントを追加したのでその部分を参照のこと
182                                 nya = new NyARDetectMarker(ar_param, ar_code, marker_width, mNumPatt, NyARBufferType.BYTE1D_B8G8R8_24);
183                                 nya.setContinueMode(true);
184                         }
185                         Log.d("nyar", "resources have been loaded");
186                 } catch (Exception e) {
187                         Log.e("nyar", "resource loading failed", e);
188                 }
189
190         }
191
192         /**
193          *
194          * @param mediaplayer
195          */
196         public void setMediaPlayer(MediaPlayer mediaplayer) {
197                 this.mMediaPlayer = mediaplayer;
198         }
199
200         /**
201          * NyARGLUtil.toCameraFrustumRH()の出力double[]をfloat[]に変換する
202          * @param i_arparam
203          * @param o_gl_projection
204          */
205         public static void toCameraFrustumRHf(NyARParam i_arparam, float[] o_gl_projection)
206         {
207                 double[] mf = new double[16];
208                 NyARGLUtil.toCameraFrustumRH(i_arparam, NyARGLUtil.SCALE_FACTOR_toCameraFrustumRH_NYAR2, 10, 10000, mf);
209
210                 for (int i = 0; i < mf.length; i++) {
211                         o_gl_projection[i] = (float) mf[i];
212                 }
213         }
214
215         /**
216          * NyARGLUtil.toCameraViewRH()の出力double[]をfloat[]に変換する
217          * @param i_ny_result
218          * @param o_gl_result
219          */
220         public static void toCameraViewRHf(NyARDoubleMatrix44 i_ny_result, float[] o_gl_result)
221         {
222                 double[] mf = new double[16];
223                 NyARGLUtil.toCameraViewRH(i_ny_result, NyARGLUtil.SCALE_FACTOR_toCameraViewRH_NYAR2, mf);
224
225                 for (int i = 0; i < mf.length; i++) {
226                         o_gl_result[i] = (float) mf[i];
227                 }
228         }
229
230         /**
231          * 描画処理部分
232          *  メインループ処理と読み替えても良い
233          * @param data
234          */
235         public void draw(byte[] data) {
236
237                 if(data == null) {
238                         Log.d("AR draw", "data= null");
239                         return;
240                 }
241                 Log.d("AR draw", "data.length= " + data.length);
242                 int width = 320;
243                 int height = 240;
244
245                 // start coordinates calculation.
246                 byte[] buf = new byte[width * height * 3];
247
248                 // assume YUV420SP
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");
254
255                 float[][] resultf = new float[MARKER_MAX][16];
256
257                 int found_markers;
258                 int ar_code_index[] = new int[MARKER_MAX];
259
260                 createNyARTool(width, height);
261                 // Marker detection
262                 try {
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);
269                         return;
270                 }
271
272                 boolean isDetect = false;
273
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);
280
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)
285                                         continue;
286                                 try {
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]);
291                                         isDetect = true;
292                                 } catch (NyARException e) {
293                                         Log.e("AR draw", "getCameraViewRH failed", e);
294                                         return;
295                                 }
296                         }
297                         mRenderer.objectPointChanged(found_markers, ar_code_index, resultf, cameraRHf);
298                 } else {
299                         Log.d("AR draw", "not exist marker.");
300
301                         mRenderer.objectClear();
302                 }
303                 if (isDetect) {
304                         if (mMediaPlayer != null) {
305                                 if (!mMediaPlayer.isPlaying())
306                                         mMediaPlayer.start();
307                         }
308                 }
309                 else {
310                         if (mMediaPlayer != null) {
311                                 if (mMediaPlayer.isPlaying())
312                                         mMediaPlayer.pause();
313                         }
314                 }
315         }
316 }