OSDN Git Service

d5d00d651cc083151af29d2637b45609b9e4b2f7
[nyartoolkit-and/nyartoolkit-and.git] / sample / jogl / src.rpf / jp / nyatla / nyartoolkit / rpf / sample / Test_NyARRealityGl_ARMarker.java
1 /* \r
2  * PROJECT: NyARToolkit JOGL sample program.\r
3  * --------------------------------------------------------------------------------\r
4  * The MIT License\r
5  * Copyright (c) 2008-2011 nyatla\r
6  * airmail(at)ebony.plala.or.jp\r
7  * http://nyatla.jp/nyartoolkit/\r
8  * \r
9  * Permission is hereby granted, free of charge, to any person obtaining a copy\r
10  * of this software and associated documentation files (the "Software"), to deal\r
11  * in the Software without restriction, including without limitation the rights\r
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
13  * copies of the Software, and to permit persons to whom the Software is\r
14  * furnished to do so, subject to the following conditions:\r
15  * The above copyright notice and this permission notice shall be included in\r
16  * all copies or substantial portions of the Software.\r
17  * \r
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
24  * THE SOFTWARE.\r
25  * \r
26  */\r
27 package jp.nyatla.nyartoolkit.rpf.sample;\r
28 \r
29 import java.awt.Color;\r
30 import java.awt.Font;\r
31 import java.awt.Frame;\r
32 import java.awt.Insets;\r
33 import java.awt.event.WindowAdapter;\r
34 import java.awt.event.WindowEvent;\r
35 \r
36 import javax.media.Buffer;\r
37 import javax.media.opengl.*;\r
38 \r
39 \r
40 import jp.nyatla.nyartoolkit.NyARException;\r
41 import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
42 \r
43 import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
44 import jp.nyatla.nyartoolkit.core.types.matrix.NyARDoubleMatrix44;\r
45 import jp.nyatla.nyartoolkit.rpf.mklib.ARTKMarkerTable;\r
46 import jp.nyatla.nyartoolkit.rpf.reality.nyartk.NyARRealityTarget;\r
47 import jp.nyatla.nyartoolkit.rpf.reality.nyartk.NyARRealityTargetList;\r
48 import jp.nyatla.nyartoolkit.rpf.realitysource.nyartk.NyARRealitySource_Jmf;\r
49 import jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureDevice;\r
50 import jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureDeviceList;\r
51 import jp.nyatla.nyartoolkit.jmf.utils.JmfCaptureListener;\r
52 import jp.nyatla.nyartoolkit.jogl.utils.NyARGLDrawUtil;\r
53 import jp.nyatla.nyartoolkit.rpf.reality.nyartk.gl.NyARRealityGl;\r
54 \r
55 import com.sun.opengl.util.Animator;\r
56 \r
57 /**\r
58  * NyARRealityシステムのサンプル。\r
59  * ARToolkitスタイルのマーカの上に、立方体を表示します。\r
60  * 取り扱うマーカの種類は2種類(Hiro,Kanji)です。\r
61  * パターンの種類によっては、内側のパターンを誤認識する場合があります。\r
62  * @author nyatla\r
63  *\r
64  */\r
65 public class Test_NyARRealityGl_ARMarker implements GLEventListener, JmfCaptureListener\r
66 {\r
67 \r
68         private final static int SCREEN_X = 640;\r
69         private final static int SCREEN_Y = 480;\r
70 \r
71         private Animator _animator;\r
72         private JmfCaptureDevice _capture;\r
73 \r
74         private GL _gl;\r
75 \r
76         private Object _sync_object=new Object();\r
77 \r
78         NyARRealityGl _reality;\r
79         NyARRealitySource_Jmf _src;\r
80         ARTKMarkerTable _mklib;\r
81 \r
82         public Test_NyARRealityGl_ARMarker(NyARParam i_param) throws NyARException\r
83         {\r
84                 Frame frame = new Frame("NyARToolkit+RPF["+this.getClass().getName()+"]");\r
85                 \r
86                 // キャプチャの準備\r
87                 JmfCaptureDeviceList devlist = new JmfCaptureDeviceList();\r
88                 this._capture = devlist.getDevice(0);\r
89                 if (!this._capture.setCaptureFormat(SCREEN_X, SCREEN_Y, 30.0f)) {\r
90                         throw new NyARException();\r
91                 }\r
92                 this._capture.setOnCapture(this);\r
93                 //Realityの構築\r
94                 i_param.changeScreenSize(SCREEN_X, SCREEN_Y);   \r
95                 //キャプチャ画像と互換性のあるRealitySourceを構築(樽型歪みの少ないカメラの時は、distortionFactorをnullにすること。)\r
96 //              this._src=new NyARRealitySource_Jmf(this._capture.getCaptureFormat(),i_param.getDistortionFactor(),2,100);\r
97                 this._src=new NyARRealitySource_Jmf(this._capture.getCaptureFormat(),null,2,100);\r
98                 //OpenGL互換のRealityを構築               \r
99                 this._reality=new NyARRealityGl(i_param.getPerspectiveProjectionMatrix(),i_param.getScreenSize(),10,10000,3,10);\r
100                 //マーカライブラリ(ARTKId)の構築\r
101                 this._mklib= new ARTKMarkerTable(10,16,16,25,25,4);\r
102                 //マーカテーブルの作成(2種類)\r
103                 this._mklib.addMarkerFromARPattFile(PATT_HIRO,0,"HIRO",80,80);\r
104                 this._mklib.addMarkerFromARPattFile(PATT_KANJI,1,"KANJI",80,80);\r
105                                 \r
106                 // 3Dを描画するコンポーネント\r
107                 GLCanvas canvas = new GLCanvas();\r
108                 frame.add(canvas);\r
109                 canvas.addGLEventListener(this);\r
110                 frame.addWindowListener(new WindowAdapter() {\r
111                         public void windowClosing(WindowEvent e)\r
112                         {\r
113                                 System.exit(0);\r
114                         }\r
115                 });\r
116 \r
117                 frame.setVisible(true);\r
118                 Insets ins = frame.getInsets();\r
119                 frame.setSize(SCREEN_X + ins.left + ins.right, SCREEN_Y + ins.top + ins.bottom);\r
120                 canvas.setBounds(ins.left, ins.top, SCREEN_X, SCREEN_Y);\r
121         }\r
122 \r
123         public void init(GLAutoDrawable drawable)\r
124         {\r
125                 this._gl = drawable.getGL();\r
126                 this._gl.glEnable(GL.GL_DEPTH_TEST);\r
127                 this._gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);\r
128                 NyARGLDrawUtil.setFontStyle("SansSerif",Font.BOLD,24);\r
129                 // NyARToolkitの準備\r
130                 try {\r
131                         // キャプチャ開始\r
132                         _capture.start();\r
133                 } catch (Exception e) {\r
134                         e.printStackTrace();\r
135                 }\r
136                 this._animator = new Animator(drawable);\r
137                 this._animator.start();\r
138                 return;\r
139         }\r
140 \r
141         public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)\r
142         {\r
143                 _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);\r
144                 _gl.glViewport(0, 0, width, height);\r
145 \r
146                 // 視体積の設定\r
147                 _gl.glMatrixMode(GL.GL_PROJECTION);\r
148                 _gl.glLoadIdentity();\r
149                 // 見る位置\r
150                 _gl.glMatrixMode(GL.GL_MODELVIEW);\r
151                 _gl.glLoadIdentity();\r
152         }\r
153 \r
154         public void display(GLAutoDrawable drawable)\r
155         {\r
156                 //RealitySourceにデータが処理する。\r
157                 if(!this._src.isReady())\r
158                 {\r
159                         return;\r
160                 }\r
161                 \r
162                 // 背景を書く\r
163                 this._gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.\r
164                 try{\r
165                         synchronized(this._sync_object){\r
166                                 \r
167                                 this._reality.glDrawRealitySource(this._gl,this._src);\r
168                                 // Projection transformation.\r
169                                 this._gl.glMatrixMode(GL.GL_PROJECTION);\r
170                                 this._reality.glLoadCameraFrustum(this._gl);\r
171                                 //ターゲットリストを走査して、画面に内容を反映\r
172                                 NyARRealityTargetList tl=this._reality.refTargetList();\r
173                                 for(int i=tl.getLength()-1;i>=0;i--){\r
174                                         NyARRealityTarget t=tl.getItem(i);\r
175                                         switch(t.getTargetType())\r
176                                         {\r
177                                         case NyARRealityTarget.RT_KNOWN:\r
178                                                 //立方体の描画\r
179                                                 this._gl.glMatrixMode(GL.GL_MODELVIEW);\r
180                                                 this._gl.glLoadIdentity();\r
181                                                 NyARDoubleMatrix44 m=t.refTransformMatrix();\r
182                                                 this._reality.glLoadModelViewMatrix(this._gl,m);\r
183                                                 _gl.glPushMatrix(); // Save world coordinate system.\r
184                                                 _gl.glTranslatef(0f,0,20f); // Place base of cube on marker surface.\r
185                                                 _gl.glDisable(GL.GL_LIGHTING); // Just use colours.\r
186                                                 NyARGLDrawUtil.drawColorCube(this._gl,40f);\r
187                                                 _gl.glPopMatrix(); // Restore world coordinate system.\r
188                                                 //マーカ情報の描画\r
189                                                 _gl.glPushMatrix(); // Save world coordinate system.\r
190                                                 this._reality.glLoadModelViewMatrix(this._gl,m);\r
191                                                 _gl.glTranslatef(0,0,90f); // Place base of cube on marker surface.\r
192                                                 _gl.glRotatef(90,1.0f,0.0f,0.0f); // Place base of cube on marker surface.\r
193                                                 NyARGLDrawUtil.setFontColor(t.getGrabbRate()<50?Color.RED:Color.BLUE);\r
194                                                 ARTKMarkerTable.GetBestMatchTargetResult d=((ARTKMarkerTable.GetBestMatchTargetResult)(t.tag));\r
195                                                 NyARGLDrawUtil.drawText("Name:"+d.name+" GRUB:"+t.grab_rate+"%",0.5f);\r
196                                                 _gl.glPopMatrix();\r
197                                                 \r
198                                                 break;\r
199                                         case NyARRealityTarget.RT_UNKNOWN:\r
200                                                 NyARDoublePoint2d[] p=t.refTargetVertex();                                              \r
201                                                 NyARGLDrawUtil.beginScreenCoordinateSystem(this._gl,SCREEN_X,SCREEN_Y,true);\r
202                                                 _gl.glLineWidth(2);\r
203                                                 _gl.glColor3f(1.0f,0.0f,0.0f);\r
204                                                 _gl.glBegin(GL.GL_LINE_LOOP);\r
205                                                 _gl.glVertex2d(p[0].x,p[0].y);\r
206                                                 _gl.glVertex2d(p[1].x,p[1].y);\r
207                                                 _gl.glVertex2d(p[2].x,p[2].y);\r
208                                                 _gl.glVertex2d(p[3].x,p[3].y);\r
209                                                 _gl.glEnd();\r
210                                                 NyARGLDrawUtil.endScreenCoordinateSystem(this._gl);\r
211                                                 \r
212                                                 break;\r
213                                         }\r
214                                 }\r
215                         }\r
216                         Thread.sleep(1);// タスク実行権限を一旦渡す\r
217                 }catch(Exception e){\r
218                         e.printStackTrace();\r
219                 }\r
220 \r
221         }\r
222 \r
223         /**\r
224          * カメラのキャプチャした画像を非同期に受け取る関数。\r
225          * 画像を受け取ると、同期を取ってRealityを1サイクル進めます。\r
226          */\r
227         public void onUpdateBuffer(Buffer i_buffer)\r
228         {\r
229                 try {\r
230                         synchronized (this._sync_object)\r
231                         {\r
232                                 this._src.setImage(i_buffer);\r
233                                 this._reality.progress(this._src);\r
234                                 //UnknownTargetを1個取得して、遷移を試す。\r
235                                 NyARRealityTarget t=this._reality.selectSingleUnknownTarget();\r
236                                 if(t==null){\r
237                                         return;\r
238                                 }\r
239                                 //ターゲットに一致するデータを検索\r
240                                 ARTKMarkerTable.GetBestMatchTargetResult r=new ARTKMarkerTable.GetBestMatchTargetResult();\r
241                                 if(this._mklib.getBestMatchTarget(t,this._src,r)){\r
242                                         if(r.confidence<0.6)\r
243                                         {       //一致率が低すぎる。\r
244                                                 return;\r
245                                         }\r
246                                         //既に認識しているターゲットの内側のものでないか確認する?(この処理をすれば、二重認識は無くなる。)\r
247                                         \r
248                                         //一致度を確認して、80%以上ならKnownターゲットへ遷移\r
249                                         if(!this._reality.changeTargetToKnown(t,r.artk_direction,r.marker_width)){\r
250                                         //遷移の成功チェック\r
251                                                 return;//失敗\r
252                                         }\r
253                                         //遷移に成功したので、tagにResult情報をコピーしておく。(後で表示に使う)\r
254                                         t.tag=r;\r
255                                 }else{\r
256                                         //一致しないので、このターゲットは捨てる。\r
257                                         this._reality.changeTargetToDead(t,15);\r
258                                 }\r
259                         }\r
260                 } catch (Exception e) {\r
261                         e.printStackTrace();\r
262                 }\r
263         }\r
264 \r
265         public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)\r
266         {\r
267         }\r
268         \r
269         private final static String PARAM_FILE = "../../Data/camera_para.dat";\r
270         private final static String PATT_HIRO = "../../Data/patt.hiro";\r
271         private final static String PATT_KANJI = "../../Data/patt.kanji";\r
272 \r
273         public static void main(String[] args)\r
274         {\r
275                 try {\r
276                         NyARParam param = new NyARParam();\r
277                         param.loadARParamFromFile(PARAM_FILE);\r
278                         new Test_NyARRealityGl_ARMarker(param);\r
279                 } catch (Exception e) {\r
280                         e.printStackTrace();\r
281                 }\r
282                 return;\r
283         }\r
284 \r
285 }\r