1 package jp.nyatla.nyartoolkit.rpf.sample;
\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
10 import javax.media.Buffer;
\r
11 import javax.media.opengl.*;
\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
29 import com.sun.opengl.util.Animator;
\r
32 * NyARRealityシステムのサンプル。
\r
33 * このプログラムは、非同期マーカー認識の実験プログラムです。
\r
34 * リアルタイムにマーカ一致を行わずに、外部プログラムやサーバなどで非同期にマーカ認識処理を行うテンプレートになります。
\r
36 * このプログラムでは、IDマーカの非同期認識(別スレッドで認識)を行い、認識が成功したらその上に立方体を表示します。
\r
38 * マーカには、IDマーカを使ってください。
\r
42 public class Test_NyARRealityGl_AsyncIdMarker implements GLEventListener, JmfCaptureListener,IResultListener
\r
45 private final static int SCREEN_X = 320;
\r
46 private final static int SCREEN_Y = 240;
\r
48 private Animator _animator;
\r
49 private JmfCaptureDevice _capture;
\r
53 private Object _sync_object=new Object();
\r
55 NyARRealityGl _reality;
\r
56 NyARRealitySource_Jmf _src;
\r
57 ASyncIdMarkerTable _mklib;
\r
59 public Test_NyARRealityGl_AsyncIdMarker(NyARParam i_param) throws NyARException
\r
61 Frame frame = new Frame("NyARReality on OpenGL");
\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
69 this._capture.setOnCapture(this);
\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
80 GLCanvas canvas = new GLCanvas();
\r
82 canvas.addGLEventListener(this);
\r
83 frame.addWindowListener(new WindowAdapter() {
\r
84 public void windowClosing(WindowEvent e)
\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
96 public void init(GLAutoDrawable drawable)
\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
106 } catch (Exception e) {
\r
107 e.printStackTrace();
\r
109 this._animator = new Animator(drawable);
\r
110 this._animator.start();
\r
114 public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
\r
116 _gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
\r
117 _gl.glViewport(0, 0, width, height);
\r
120 _gl.glMatrixMode(GL.GL_PROJECTION);
\r
121 _gl.glLoadIdentity();
\r
123 _gl.glMatrixMode(GL.GL_MODELVIEW);
\r
124 _gl.glLoadIdentity();
\r
127 public void display(GLAutoDrawable drawable)
\r
129 //RealitySourceにデータが処理する。
\r
130 if(!this._src.isReady())
\r
136 this._gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.
\r
138 synchronized(this._sync_object){
\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
150 case NyARRealityTarget.RT_KNOWN:
\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
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
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
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
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
186 Thread.sleep(1);// タスク実行権限を一旦渡す
\r
187 }catch(Exception e){
\r
188 e.printStackTrace();
\r
192 public void OnDetect(boolean i_result,long i_serial,int i_dir,double i_width,long i_id)
\r
196 synchronized (this._sync_object)
\r
198 NyARRealityTarget t=this._reality.refTargetList().getItemBySerial(i_serial);
\r
202 if(t.getTargetType()!=NyARRealityTarget.RT_UNKNOWN){
\r
206 this._reality.changeTargetToKnown(t, i_dir, i_width);
\r
207 t.tag=new Long(i_id);
\r
209 this._reality.changeTargetToDead(t);
\r
212 }catch(Exception e){
\r
214 e.printStackTrace();
\r
219 * カメラのキャプチャした画像を非同期に受け取る関数。
\r
220 * 画像を受け取ると、同期を取ってRealityを1サイクル進めます。
\r
222 public void onUpdateBuffer(Buffer i_buffer)
\r
225 synchronized (this._sync_object)
\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
234 //tagに何か入ってたらなにかやっている。
\r
238 this._mklib.requestAsyncMarkerDetect(this._reality,this._src,t);
\r
239 t.tag=new Long(-1);//-1は認識中ということで。
\r
241 } catch (Exception e) {
\r
242 e.printStackTrace();
\r
246 public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged)
\r
250 private final static String PARAM_FILE = "../Data/camera_para.dat";
\r
252 public static void main(String[] args)
\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