OSDN Git Service

[tag]NyARToolkit/2.5.1
[nyartoolkit-and/nyartoolkit-and.git] / tags / 2.5.1 / sample / jogl / jp / nyatla / nyartoolkit / jogl / sample / SingleARMarker.java
1 /* \r
2  * PROJECT: NyARToolkit JOGL sample program.\r
3  * --------------------------------------------------------------------------------\r
4  * The MIT License\r
5  * Copyright (c) 2008 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.jogl.sample;\r
28 \r
29 \r
30 import java.awt.event.*;\r
31 import java.awt.*;\r
32 import java.util.Date;\r
33 \r
34 import javax.media.Buffer;\r
35 import javax.media.opengl.*;\r
36 \r
37 import com.sun.opengl.util.*;\r
38 import com.sun.opengl.util.j2d.*;\r
39 import jp.nyatla.nyartoolkit.*;\r
40 import jp.nyatla.nyartoolkit.core.*;\r
41 import jp.nyatla.nyartoolkit.core.param.*;\r
42 import jp.nyatla.nyartoolkit.core.squaredetect.NyARSquare;\r
43 import jp.nyatla.nyartoolkit.core.transmat.*;\r
44 import jp.nyatla.nyartoolkit.jmf.utils.*;\r
45 import jp.nyatla.nyartoolkit.jogl.utils.*;\r
46 import jp.nyatla.nyartoolkit.processor.*;\r
47 \r
48 /*\r
49 \r
50 \r
51 */\r
52 \r
53 \r
54 public class SingleARMarker implements GLEventListener, JmfCaptureListener\r
55 {\r
56         class TextPanel\r
57         {\r
58                 private TextRenderer _tr;\r
59                 public TextPanel(int i_size)\r
60                 {\r
61                         this._tr=new TextRenderer(new Font("SansSerif", Font.BOLD, 36));\r
62 \r
63                 }\r
64                 public void draw(String i_str,float i_scale)\r
65                 {\r
66                         this._tr.begin3DRendering();\r
67                     this._tr.setColor(1.0f, 0.2f, 0.2f, 0.8f);\r
68                     this._tr.draw3D(i_str, 0f,0f,0f,i_scale);\r
69                         this._tr.end3DRendering();\r
70                         return;\r
71                 }\r
72         }       \r
73         /**\r
74          * 1個のRawBit-Idマーカを認識するロジッククラス。\r
75          * detectMarker関数の呼び出しに同期して、transmatとcurrent_idパラメタを更新します。\r
76          * \r
77          *\r
78          */\r
79         class MarkerProcessor extends SingleARMarkerProcesser\r
80         {\r
81                 private NyARGLUtil _glnya;\r
82                 public double[] gltransmat=new double[16];\r
83                 \r
84                 public int current_code=-1;\r
85 \r
86                 public MarkerProcessor(NyARParam i_cparam,int i_raster_format,NyARGLUtil i_glutil) throws NyARException\r
87                 {\r
88                         //アプリケーションフレームワークの初期化\r
89                         super();\r
90                         initInstance(i_cparam,i_raster_format);\r
91                         this._glnya=i_glutil;\r
92                         return;\r
93                 }\r
94                 protected void onEnterHandler(int i_code)\r
95                 {\r
96                         current_code=i_code;\r
97                 }\r
98                 protected void onLeaveHandler()\r
99                 {\r
100                         current_code=-1;\r
101                         return;                 \r
102                 }\r
103                 /**\r
104                  * i_square,resultの有効期間は、この関数の終了までです。\r
105                  */\r
106                 protected void onUpdateHandler(NyARSquare i_square, NyARTransMatResult result)\r
107                 {\r
108                         try{\r
109                                 this._glnya.toCameraViewRH(result, this.gltransmat);\r
110                         }catch(Exception e){\r
111                                 e.printStackTrace();\r
112                         }\r
113                 }\r
114         }\r
115         \r
116         private final String CARCODE_FILE1 = "../../Data/patt.hiro";\r
117         private final String CARCODE_FILE2 = "../../Data/patt.kanji";\r
118         \r
119         \r
120         private Animator _animator;\r
121         private GLNyARRaster_RGB _cap_image;\r
122         private JmfCaptureDevice _capture;\r
123 \r
124         private GL _gl;\r
125         private NyARGLUtil _glnya;\r
126         private TextPanel _panel;\r
127 \r
128 \r
129         //NyARToolkit関係\r
130         private NyARParam _ar_param;\r
131 \r
132         private double[] _camera_projection=new double[16];\r
133         \r
134         private Object _sync_object=new Object();\r
135         private MarkerProcessor _processor;\r
136         private NyARCode[] _code_table=new NyARCode[2];\r
137 \r
138         public SingleARMarker(NyARParam i_cparam) throws NyARException\r
139         {\r
140                 JmfCaptureDeviceList devlist=new JmfCaptureDeviceList();\r
141                 this._ar_param=i_cparam;\r
142 \r
143                 //キャプチャリソースの準備\r
144                 this._capture=devlist.getDevice(0);\r
145                 if(!this._capture.setCaptureFormat(SCREEN_X, SCREEN_Y,30.0f)){\r
146                         throw new NyARException();\r
147                 }\r
148                 this._capture.setOnCapture(this);\r
149                 this._cap_image = new GLNyARRaster_RGB(i_cparam,this._capture.getCaptureFormat());      \r
150 \r
151                 this._code_table[0]=new NyARCode(16,16);\r
152                 this._code_table[0].loadARPattFromFile(CARCODE_FILE1);\r
153                 this._code_table[1]=new NyARCode(16,16);\r
154                 this._code_table[1].loadARPattFromFile(CARCODE_FILE2);\r
155                 \r
156                 //OpenGLフレームの準備(OpenGLリソースの初期化、カメラの撮影開始は、initコールバック関数内で実行)\r
157                 Frame frame = new Frame("Java simpleLite with NyARToolkit");\r
158                 GLCanvas canvas = new GLCanvas();\r
159                 frame.add(canvas);\r
160                 canvas.addGLEventListener(this);\r
161                 frame.addWindowListener(new WindowAdapter() {\r
162                         public void windowClosing(WindowEvent e)\r
163                         {\r
164                                 System.exit(0);\r
165                         }\r
166                 });\r
167                 \r
168                 //ウインドウサイズの調整\r
169                 frame.setVisible(true);\r
170                 Insets ins = frame.getInsets();\r
171                 frame.setSize(SCREEN_X + ins.left + ins.right, SCREEN_Y + ins.top + ins.bottom);\r
172                 canvas.setBounds(ins.left, ins.top, SCREEN_X, SCREEN_Y);\r
173                 return;\r
174         }\r
175         public void init(GLAutoDrawable drawable)\r
176         {\r
177                 this._panel = new TextPanel(100);\r
178 \r
179 \r
180                 this._gl = drawable.getGL();\r
181                 this._gl.glEnable(GL.GL_DEPTH_TEST);\r
182 \r
183                 this._gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);\r
184                 //NyARToolkitの準備\r
185                 try {\r
186                         this._glnya = new NyARGLUtil(this._gl);\r
187                         //プロセッサの準備\r
188                         this._processor=new MarkerProcessor(this._ar_param,this._cap_image.getBufferType(),this._glnya);\r
189                         this._processor.setARCodeTable(_code_table,16,80.0);\r
190 \r
191                         //カメラパラメータの計算\r
192                         this._glnya.toCameraFrustumRH(this._ar_param,this._camera_projection);\r
193                         //キャプチャ開始\r
194                         this._capture.start();\r
195                 } catch (Exception e) {\r
196                         e.printStackTrace();\r
197                 }\r
198                 this._animator = new Animator(drawable);\r
199                 this._animator.start();\r
200                 return;\r
201         }\r
202 \r
203         public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)\r
204         {\r
205                 \r
206                 _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);\r
207                 _gl.glViewport(0, 0, width, height);\r
208 \r
209                 //視体積の設定\r
210                 _gl.glMatrixMode(GL.GL_PROJECTION);\r
211                 _gl.glLoadIdentity();\r
212                 //見る位置\r
213                 _gl.glMatrixMode(GL.GL_MODELVIEW);\r
214                 _gl.glLoadIdentity();\r
215         }\r
216         \r
217         \r
218         public void display(GLAutoDrawable drawable)\r
219         {\r
220                 if (!_cap_image.hasBuffer()) {\r
221                         return;\r
222                 }\r
223                 // 背景を書く\r
224                 this._gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.\r
225                 this._glnya.drawBackGround(this._cap_image, 1.0);\r
226                 //OnEnter,OnUpdateの間に、transmatに初回行列がストアされる実行されることを防ぎます。\r
227                 synchronized(this._sync_object)\r
228                 {\r
229                         if(this._processor.current_code<0){\r
230                                 \r
231                         }else{\r
232                                 try{\r
233                                         // Projection transformation.\r
234                                         this._gl.glMatrixMode(GL.GL_PROJECTION);\r
235                                         this._gl.glLoadMatrixd(_camera_projection, 0);\r
236                                         this._gl.glMatrixMode(GL.GL_MODELVIEW);\r
237                                         // Viewing transformation.\r
238                                         this._gl.glLoadIdentity();\r
239                                         this._gl.glLoadMatrixd(this._processor.gltransmat, 0);\r
240                                         // All other lighting and geometry goes here.\r
241                                         this._gl.glPushMatrix();\r
242                                         this._gl.glDisable(GL.GL_LIGHTING);\r
243 \r
244                                         \r
245                                         //マーカのXZ平面をマーカの左上、表示開始位置を10cm上空へ。\r
246                                         //くるーんくるん\r
247                                         Date d = new Date();\r
248                                         float r=(d.getTime()/50)%360;\r
249                                         this._gl.glRotatef(r,0f,0f,1.0f);\r
250                                         this._gl.glTranslatef(-1.0f,0f,1.0f);\r
251                                         this._gl.glRotatef(90,1.0f,0f,0f);\r
252                                         this._panel.draw("MarkerId:"+this._processor.current_code,0.01f);\r
253                                         this._gl.glPopMatrix();\r
254                                         Thread.sleep(1);// タスク実行権限を一旦渡す\r
255                                 }catch(Exception e){\r
256                                         e.printStackTrace();\r
257                                 }\r
258                         }\r
259                 }\r
260                 return;\r
261 \r
262         }\r
263         /**\r
264          * カメラデバイスからのコールバック\r
265          */\r
266         public void onUpdateBuffer(Buffer i_buffer)\r
267         {\r
268                 try {\r
269                         synchronized (this._sync_object) {\r
270                                 this._cap_image.setBuffer(i_buffer);\r
271                                 //フレームワークに画像を転送\r
272                                 this._processor.detectMarker(this._cap_image);\r
273                         }\r
274                 } catch (Exception e) {\r
275                         e.printStackTrace();\r
276                 }\r
277         }\r
278 \r
279         public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)\r
280         {\r
281         }\r
282 \r
283 \r
284         private final static int SCREEN_X = 640;\r
285         private final static int SCREEN_Y = 480;\r
286         private final static String PARAM_FILE = "../../Data/camera_para.dat";\r
287         //エントリポイント\r
288         public static void main(String[] args)\r
289         {\r
290                 try{\r
291                         NyARParam cparam= new NyARParam();\r
292                         cparam.loadARParamFromFile(PARAM_FILE);\r
293                         cparam.changeScreenSize(SCREEN_X, SCREEN_Y);            \r
294                         new SingleARMarker(cparam);\r
295                 }catch(Exception e){\r
296                         e.printStackTrace();\r
297                 }\r
298                 return;\r
299         }\r
300 }\r
301 \r