OSDN Git Service

f9cc41c68f72431e5026dbe30fb086a180619f7a
[nyartoolkit-and/nyartoolkit-and.git] / src / jp / android_group / artoolkit / ARToolkitDrawer.java
1 package jp.android_group.artoolkit;
2
3 import java.io.ByteArrayOutputStream;
4 import java.io.InputStream;
5
6 import jp.android_group.artoolkit.model.VoicePlayer;
7 import jp.nyatla.nyartoolkit.NyARException;
8 import jp.nyatla.nyartoolkit.core.NyARCode;
9 import jp.nyatla.nyartoolkit.core.param.NyARParam;
10 import jp.nyatla.nyartoolkit.core.raster.rgb.NyARRgbRaster_RGB;
11 import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;
12 import jp.nyatla.nyartoolkit.core.types.NyARBufferType;
13 import jp.nyatla.nyartoolkit.detector.NyARSingleDetectMarker;
14 import jp.nyatla.nyartoolkit.jogl.utils.NyARGLUtil;
15 import android.graphics.Bitmap;
16 import android.graphics.BitmapFactory;
17 import android.util.Log;
18
19 public class ARToolkitDrawer {
20         
21         private NyARSingleDetectMarker nya = null;
22         private NyARRgbRaster_RGB raster = null;
23         private NyARGLUtil ar_util = null;
24         private NyARParam ar_param = null;
25         private NyARCode ar_code = null;
26         private NyARTransMatResult ar_transmat_result = new NyARTransMatResult();
27
28         
29         private ModelRenderer mRenderer = null;
30         private InputStream camePara = null;
31         private InputStream patt = null;
32         
33         private VoicePlayer mVoiceSound = null;
34         
35         public ARToolkitDrawer(InputStream camePara, InputStream patt, ModelRenderer mRenderer) {
36                 this.camePara = camePara;
37                 this.patt = patt;
38                 this.mRenderer = mRenderer;
39         }
40         
41         private void createNyARTool(int w, int h) {
42                 // NyARToolkit setting.
43                 try {
44                         if (ar_param == null) {
45                                 ar_util = new NyARGLUtil();
46                                 ar_param = new NyARParam();
47                                 ar_param.loadARParam(camePara);
48                                 ar_code = new NyARCode(16, 16);
49                                 ar_code.loadARPatt(patt);
50                                 //TODO 本当は、ここはifの外でないと行けない。だけど、出すとOutOfMemory
51                                 ar_param.changeScreenSize(w, h);
52                                 nya = new NyARSingleDetectMarker(ar_param, ar_code, 80.0, NyARBufferType.BYTE1D_B8G8R8_24);
53                                 nya.setContinueMode(false);
54                         }
55                         Log.d("nyar", "resources have been loaded");
56                 } catch (Exception e) {
57                         Log.e("nyar", "resource loading failed", e);
58                 }
59
60         }
61
62         public void setVoicePlayer(VoicePlayer mVoiceSound) {
63                 this.mVoiceSound = mVoiceSound;
64         }
65
66         public static final void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {
67                 final int frameSize = width * height;
68
69                 for (int j = 0, yp = 0; j < height; j++) {
70                         int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
71                         for (int i = 0; i < width; i++, yp++) {
72                                 int y = (0xff & ((int) yuv420sp[yp])) - 16;
73                                 if (y < 0) y = 0;
74                                 if ((i & 1) == 0) {
75                                         v = (0xff & yuv420sp[uvp++]) - 128;
76                                         u = (0xff & yuv420sp[uvp++]) - 128;
77                                 }
78
79                                 int y1192 = 1192 * y;
80                                 int r = (y1192 + 1634 * v);
81                                 int g = (y1192 - 833 * v - 400 * u);
82                                 int b = (y1192 + 2066 * u);
83
84                                 if (r < 0) r = 0; else if (r > 262143) r = 262143;
85                                 if (g < 0) g = 0; else if (g > 262143) g = 262143;
86                                 if (b < 0) b = 0; else if (b > 262143) b = 262143;
87
88                                 rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
89                         }
90                 }
91         }       
92         
93         public void draw(byte[] data) {
94                 
95                 if(data == null) {
96                         Log.d("AR draw", "data= null");
97                         return;
98                 }
99                 Log.d("AR draw", "data.length= " + data.length);
100
101                 BitmapFactory.Options options = new BitmapFactory.Options();
102         options.inSampleSize = 4;
103         Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
104
105                 if (bitmap != null) {
106                         // assume JPEG
107                         if(bitmap.getHeight() < 240) {
108                                 bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
109                         }
110                 } else {
111                         // assume YUV420SP
112                         final int width = 352;
113                         final int height = 288;
114 //                      final int width = 480;
115 //                      final int height = 320;
116                         int[] rgb = new int[(width * height)];
117                         try {
118                                 bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
119                         } catch (Exception e) {
120                                 Log.d("AR draw", "bitmap create error.");
121                                 return;
122                         }               
123                         decodeYUV420SP(rgb, data, width, height);
124                         bitmap.setPixels(rgb, 0, width, 0, 0, width, height);
125                 }
126
127                 if (bitmap == null) {
128                         Log.d("AR draw", "data is not BitMap data.");
129                         return;
130                 }
131                                         
132                 Log.d("AR draw", "bitmap.getHeight()= " + bitmap.getHeight());
133                 Log.d("AR draw", "bitmap.getWidth()= " + bitmap.getWidth());
134                 mRenderer.setBgBitmap(bitmap);
135                 // start coordinates calculation.
136                 int w = bitmap.getWidth();
137                 int h = bitmap.getHeight();
138                 int[] pixels = new int[w * h];
139                 byte[] buf = new byte[pixels.length * 3];
140                 float[] resultf = new float[16];
141                 
142                 boolean is_marker_exist = false;
143                 bitmap.getPixels(pixels, 0, w, 0, 0, w, h);
144                 Log.d("AR draw", "pixels:" + pixels.length);
145
146                 for (int i = 0; i < pixels.length; i++) {
147                         int argb = pixels[i];
148                         // byte a = (byte) (argb & 0xFF000000 >> 24);
149                         byte r = (byte) (argb & 0x00FF0000 >> 16);
150                         byte g = (byte) (argb & 0x0000FF00 >> 8);
151                         byte b = (byte) (argb & 0x000000FF);
152                         buf[i * 3] = r;
153                         buf[i * 3 + 1] = g;
154                         buf[i * 3 + 2] = b;
155                         argb = pixels[i];
156                 }
157                 
158                 createNyARTool(w, h);
159                 // Marker detection 
160                 try {
161                         Log.d("AR draw", "Marker detection.");
162                         raster = new NyARRgbRaster_RGB(w, h);
163                         raster.wrapBuffer(buf);
164                         is_marker_exist = nya.detectMarkerLite(raster, 100);
165                 } catch (NyARException e) {
166                         Log.e("AR draw", "marker detection failed", e);
167                         return;
168                 }
169                 
170                 // An OpenGL object will be drawn if matched.
171                 if (is_marker_exist) {
172                         Log.d("AR draw", "!!!!!!!!!!!exist marker.!!!!!!!!!!!");
173                         // Projection transformation.
174                         float[] cameraRHf = new float[16];
175                         ar_util.toCameraFrustumRHf(ar_param, cameraRHf);
176                         try {
177                                 NyARTransMatResult transmat_result = ar_transmat_result;
178                                 nya.getTransmationMatrix(transmat_result);
179                                 ar_util.toCameraViewRHf(transmat_result, resultf);
180                         } catch (NyARException e) {
181                                 Log.e("AR draw", "getCameraViewRH failed", e);
182                                 return;
183                         }
184                         mRenderer.objectPointChanged(resultf, cameraRHf);
185                         if(mVoiceSound != null)
186                                 mVoiceSound.startVoice();
187                 } else {
188                         Log.d("AR draw", "not exist marker.");
189                         if(mVoiceSound != null)
190                                 mVoiceSound.stopVoice();
191                         mRenderer.objectClear();
192                 }
193
194         }
195         
196 }