OSDN Git Service

99e72d201133b6ebcc3eb3756380e7a10893c219
[nyartoolkit-and/nyartoolkit-and.git] / sample / jogl / src.rpf / jp / nyatla / nyartoolkit / rpf / sample / Test_NyARRealityGl_AsyncIdMarker.java
1 package jp.nyatla.nyartoolkit.rpf.sample;\r
2 \r
3 import java.awt.Color;\r
4 import java.awt.Font;\r
5 import java.awt.Frame;\r
6 import java.awt.Insets;\r
7 import java.awt.event.WindowAdapter;\r
8 import java.awt.event.WindowEvent;\r
9 \r
10 import javax.media.Buffer;\r
11 import javax.media.opengl.*;\r
12 \r
13 import jp.nyatla.nyartoolkit.NyARException;\r
14 import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
15 import jp.nyatla.nyartoolkit.core.types.NyARIntPoint2d;\r
16 import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix44;\r
17 import jp.nyatla.nyartoolkit.rpf.mklib.ASyncIdMarkerTable;\r
18 import jp.nyatla.nyartoolkit.rpf.mklib.RawbitSerialIdTable;\r
19 import jp.nyatla.nyartoolkit.rpf.mklib.ASyncIdMarkerTable.IResultListener;\r
20 import jp.nyatla.nyartoolkit.rpf.reality.nyartk.NyARRealityTarget;\r
21 import jp.nyatla.nyartoolkit.rpf.reality.nyartk.NyARRealityTargetList;\r
22 import jp.nyatla.nyartoolkit.rpf.realitysource.nyartk.NyARRealitySource_Jmf;\r
23 import jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureDevice;\r
24 import jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureDeviceList;\r
25 import jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureListener;\r
26 import jp.nyatla.nyartoolkit.jogl.utils.NyARGLDrawUtil;\r
27 import jp.nyatla.nyartoolkit.rpf.reality.nyartk.gl.NyARRealityGl;\r
28 \r
29 import com.sun.opengl.util.Animator;\r
30 \r
31 /**\r
32  * NyARRealityシステムのサンプル。\r
33  * このプログラムは、非同期マーカー認識の実験プログラムです。\r
34  * リアルタイムにマーカ一致を行わずに、外部プログラムやサーバなどで非同期にマーカ認識処理を行うテンプレートになります。\r
35  * \r
36  * このプログラムでは、IDマーカの非同期認識(別スレッドで認識)を行い、認識が成功したらその上に立方体を表示します。\r
37  * \r
38  * マーカには、IDマーカを使ってください。\r
39  * @author nyatla\r
40  *\r
41  */\r
42 public class Test_NyARRealityGl_AsyncIdMarker implements GLEventListener, JmfCaptureListener,IResultListener\r
43 {\r
44 \r
45         private final static int SCREEN_X = 320;\r
46         private final static int SCREEN_Y = 240;\r
47 \r
48         private Animator _animator;\r
49         private JmfCaptureDevice _capture;\r
50 \r
51         private GL _gl;\r
52 \r
53         private Object _sync_object=new Object();\r
54 \r
55         NyARRealityGl _reality;\r
56         NyARRealitySource_Jmf _src;\r
57         ASyncIdMarkerTable _mklib;\r
58 \r
59         public Test_NyARRealityGl_AsyncIdMarker(NyARParam i_param) throws NyARException\r
60         {\r
61                 Frame frame = new Frame("NyARReality on OpenGL");\r
62                 \r
63                 // キャプチャの準備\r
64                 JmfCaptureDeviceList devlist = new JmfCaptureDeviceList();\r
65                 this._capture = devlist.getDevice(0);\r
66                 if (!this._capture.setCaptureFormat(SCREEN_X, SCREEN_Y, 30.0f)) {\r
67                         throw new NyARException();\r
68                 }\r
69                 this._capture.setOnCapture(this);\r
70                 //Realityの構築\r
71                 i_param.changeScreenSize(SCREEN_X, SCREEN_Y);   \r
72                 //キャプチャ画像と互換性のあるRealitySourceを構築\r
73                 this._src=new NyARRealitySource_Jmf(this._capture.getCaptureFormat(),i_param.getDistortionFactor(),1,100);\r
74                 //OpenGL互換のRealityを構築               \r
75                 this._reality=new NyARRealityGl(i_param.getPerspectiveProjectionMatrix(),i_param.getScreenSize(),10,10000,3,3);\r
76                 //非同期マーカライブラリ(NyId)の構築\r
77                 this._mklib= new ASyncIdMarkerTable(this);\r
78                                 \r
79                 // 3Dを描画するコンポーネント\r
80                 GLCanvas canvas = new GLCanvas();\r
81                 frame.add(canvas);\r
82                 canvas.addGLEventListener(this);\r
83                 frame.addWindowListener(new WindowAdapter() {\r
84                         public void windowClosing(WindowEvent e)\r
85                         {\r
86                                 System.exit(0);\r
87                         }\r
88                 });\r
89 \r
90                 frame.setVisible(true);\r
91                 Insets ins = frame.getInsets();\r
92                 frame.setSize(SCREEN_X + ins.left + ins.right, SCREEN_Y + ins.top + ins.bottom);\r
93                 canvas.setBounds(ins.left, ins.top, SCREEN_X, SCREEN_Y);\r
94         }\r
95 \r
96         public void init(GLAutoDrawable drawable)\r
97         {\r
98                 this._gl = drawable.getGL();\r
99                 this._gl.glEnable(GL.GL_DEPTH_TEST);\r
100                 this._gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);\r
101                 NyARGLDrawUtil.setFontStyle("SansSerif",Font.BOLD,24);\r
102                 // NyARToolkitの準備\r
103                 try {\r
104                         // キャプチャ開始\r
105                         _capture.start();\r
106                 } catch (Exception e) {\r
107                         e.printStackTrace();\r
108                 }\r
109                 this._animator = new Animator(drawable);\r
110                 this._animator.start();\r
111                 return;\r
112         }\r
113 \r
114         public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)\r
115         {\r
116                 _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);\r
117                 _gl.glViewport(0, 0, width, height);\r
118 \r
119                 // 視体積の設定\r
120                 _gl.glMatrixMode(GL.GL_PROJECTION);\r
121                 _gl.glLoadIdentity();\r
122                 // 見る位置\r
123                 _gl.glMatrixMode(GL.GL_MODELVIEW);\r
124                 _gl.glLoadIdentity();\r
125         }\r
126 \r
127         public void display(GLAutoDrawable drawable)\r
128         {\r
129                 //RealitySourceにデータが処理する。\r
130                 if(!this._src.isReady())\r
131                 {\r
132                         return;\r
133                 }\r
134                 \r
135                 // 背景を書く\r
136                 this._gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.\r
137                 try{\r
138                         synchronized(this._sync_object){\r
139                                 \r
140                                 this._reality.glDrawRealitySource(this._gl,this._src);\r
141                                 // Projection transformation.\r
142                                 this._gl.glMatrixMode(GL.GL_PROJECTION);\r
143                                 this._reality.glLoadCameraFrustum(this._gl);\r
144                                 //ターゲットリストを走査して、画面に内容を反映\r
145                                 NyARRealityTargetList tl=this._reality.refTargetList();\r
146                                 for(int i=tl.getLength()-1;i>=0;i--){\r
147                                         NyARRealityTarget t=tl.getItem(i);\r
148                                         switch(t.getTargetType())\r
149                                         {\r
150                                         case NyARRealityTarget.RT_KNOWN:\r
151                                                 //立方体の描画\r
152                                                 this._gl.glMatrixMode(GL.GL_MODELVIEW);\r
153                                                 this._gl.glLoadIdentity();\r
154                                                 NyARDoubleMatrix44 m=t.refTransformMatrix();\r
155                                                 this._reality.glLoadModelViewMatrix(this._gl,m);\r
156                                                 _gl.glPushMatrix(); // Save world coordinate system.\r
157                                                 //_gl.glRotatef(90,0.0f,0.0f,1.0f); // Place base of cube on marker surface.\r
158                                                 \r
159                                                 _gl.glTranslatef(0,0,10f); // Place base of cube on marker surface.\r
160                                                 _gl.glDisable(GL.GL_LIGHTING); // Just use colours.\r
161                                                 NyARGLDrawUtil.drawColorCube(this._gl,20f);\r
162                                                 _gl.glPopMatrix(); // Restore world coordinate system.\r
163                                                 //マーカ情報の描画\r
164                                                 _gl.glPushMatrix(); // Save world coordinate system.\r
165                                                 this._reality.glLoadModelViewMatrix(this._gl,m);\r
166                                                 _gl.glTranslatef(-30,0,40f); // Place base of cube on marker surface.\r
167                                                 _gl.glRotatef(90,1.0f,0.0f,0.0f); // Place base of cube on marker surface.\r
168                                                 //マーカ情報の表示\r
169                                                 NyARGLDrawUtil.setFontColor(t.getGrabbRate()<50?Color.RED:Color.BLUE);\r
170                                                 NyARGLDrawUtil.drawText("ID:"+(Long)(t.tag)+" GRUB:"+t.grab_rate+"%",0.5f);\r
171                                                 _gl.glPopMatrix();\r
172                                                 \r
173                                                 break;\r
174                                         case NyARRealityTarget.RT_UNKNOWN:\r
175                                                 NyARGLDrawUtil.beginScreenCoordinateSystem(this._gl,SCREEN_X,SCREEN_Y,false);\r
176                                                 NyARGLDrawUtil.setFontColor(t.getGrabbRate()<50?Color.RED:Color.BLUE);\r
177                                                 NyARIntPoint2d cp=new NyARIntPoint2d();\r
178                                                 t.getTargetCenter(cp);\r
179                                                 _gl.glTranslated(cp.x,SCREEN_Y-cp.y,1);\r
180                                                 NyARGLDrawUtil.drawText("now matching marker.",1f);\r
181                                                 NyARGLDrawUtil.endScreenCoordinateSystem(this._gl);                                             \r
182                                                 break;\r
183                                         }\r
184                                 }\r
185                         }\r
186                         Thread.sleep(1);// タスク実行権限を一旦渡す\r
187                 }catch(Exception e){\r
188                         e.printStackTrace();\r
189                 }\r
190 \r
191         }\r
192         public void OnDetect(boolean i_result,long i_serial,int i_dir,double i_width,long i_id)\r
193         {\r
194                 try{\r
195                 //Realityを触るのでロック\r
196                 synchronized (this._sync_object)\r
197                 {\r
198                         NyARRealityTarget t=this._reality.refTargetList().getItemBySerial(i_serial);\r
199                         if(t==null){\r
200                                 return;\r
201                         }\r
202                         if(t.getTargetType()!=NyARRealityTarget.RT_UNKNOWN){\r
203                                 return;\r
204                         }\r
205                         if(i_result){\r
206                                 this._reality.changeTargetToKnown(t, i_dir, i_width);\r
207                                 t.tag=new Long(i_id);\r
208                         }else{\r
209                                 this._reality.changeTargetToDead(t);\r
210                         }\r
211                 }\r
212                 }catch(Exception e){\r
213                         //握りつぶす\r
214                         e.printStackTrace();\r
215                 }\r
216         }\r
217 \r
218         /**\r
219          * カメラのキャプチャした画像を非同期に受け取る関数。\r
220          * 画像を受け取ると、同期を取ってRealityを1サイクル進めます。\r
221          */\r
222         public void onUpdateBuffer(Buffer i_buffer)\r
223         {\r
224                 try {\r
225                         synchronized (this._sync_object)\r
226                         {\r
227                                 this._src.setImage(i_buffer);\r
228                                 this._reality.progress(this._src);\r
229                                 //UnknownTargetを1個取得して、遷移を試す。\r
230                                 NyARRealityTarget t=this._reality.selectSingleUnknownTarget();\r
231                                 if(t==null){\r
232                                         return;\r
233                                 }\r
234                                 //tagに何か入ってたらなにかやっている。\r
235                                 if(t.tag!=null){\r
236                                         return;\r
237                                 }\r
238                                 this._mklib.requestAsyncMarkerDetect(this._reality,this._src,t);\r
239                                 t.tag=new Long(-1);//-1は認識中ということで。\r
240                         }\r
241                 } catch (Exception e) {\r
242                         e.printStackTrace();\r
243                 }\r
244         }\r
245 \r
246         public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)\r
247         {\r
248         }\r
249         \r
250         private final static String PARAM_FILE = "../Data/camera_para.dat";\r
251 \r
252         public static void main(String[] args)\r
253         {\r
254                 try {\r
255                         NyARParam param = new NyARParam();\r
256                         param.loadARParamFromFile(PARAM_FILE);\r
257                         new Test_NyARRealityGl_AsyncIdMarker(param);\r
258                 } catch (Exception e) {\r
259                         e.printStackTrace();\r
260                 }\r
261                 return;\r
262         }\r
263 \r
264 }\r