OSDN Git Service

[更新]NyARToolkit
[nyartoolkit-and/nyartoolkit-and.git] / src.utils / java3d / jp / nyatla / nyartoolkit / java3d / utils / NyARSingleMarkerBehaviorHolder.java
1 /* \r
2  * PROJECT: NyARToolkit Java3D utilities.\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.java3d.utils;\r
28 \r
29 import java.util.Enumeration;\r
30 \r
31 import javax.media.Buffer;\r
32 import javax.media.j3d.*;\r
33 import javax.vecmath.*;\r
34 \r
35 import jp.nyatla.nyartoolkit.NyARException;\r
36 import jp.nyatla.nyartoolkit.jmf.utils.*;\r
37 import jp.nyatla.nyartoolkit.core.*;\r
38 import jp.nyatla.nyartoolkit.core.param.NyARParam;\r
39 import jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult;\r
40 import jp.nyatla.nyartoolkit.detector.*;\r
41 import jp.nyatla.nyartoolkit.core.types.*;\r
42 \r
43 /**\r
44  * NyARToolkitと連動したBehaviorを返却するクラスです。\r
45  * 提供できるBehaviorは、BackgroundとTransformgroupです。\r
46  *\r
47  */\r
48 public class NyARSingleMarkerBehaviorHolder implements JmfCaptureListener\r
49 {\r
50         private NyARParam _cparam;\r
51 \r
52         private JmfCaptureDevice _capture;\r
53 \r
54         private J3dNyARRaster_RGB _nya_raster;//最大3スレッドで共有されるので、排他制御かけること。\r
55 \r
56         private NyARSingleDetectMarker _nya;\r
57 \r
58         //Behaviorホルダ\r
59         private NyARBehavior _nya_behavior;\r
60 \r
61         public NyARSingleMarkerBehaviorHolder(NyARParam i_cparam, float i_rate, NyARCode i_ar_code, double i_marker_width) throws NyARException\r
62         {\r
63                 this._nya_behavior = null;\r
64                 final NyARIntSize scr_size = i_cparam.getScreenSize();\r
65                 this._cparam = i_cparam;\r
66                 //キャプチャの準備\r
67                 JmfCaptureDeviceList devlist=new JmfCaptureDeviceList();\r
68                 this._capture=devlist.getDevice(0);\r
69                 this._capture.setCaptureFormat(JmfCaptureDevice.PIXEL_FORMAT_RGB,scr_size.w, scr_size.h,15f);\r
70                 this._capture.setOnCapture(this);               \r
71                 this._nya_raster = new J3dNyARRaster_RGB(this._cparam);\r
72                 this._nya = new NyARSingleDetectMarker(this._cparam, i_ar_code, i_marker_width);\r
73                 this._nya_behavior = new NyARBehavior(this._nya, this._nya_raster, i_rate);\r
74         }\r
75 \r
76         public Behavior getBehavior()\r
77         {\r
78                 return this._nya_behavior;\r
79         }\r
80 \r
81         /**\r
82          * i_back_groundにキャプチャ画像を転送するようにBehaviorを設定します。\r
83          * i_back_groungはALLOW_IMAGE_WRITE属性を持つものである必要があります。\r
84          * @param i_back_groung\r
85          * @return\r
86          */\r
87         public void setBackGround(Background i_back_ground)\r
88         {\r
89                 //コール先で排他制御\r
90                 this._nya_behavior.setRelatedBackGround(i_back_ground);\r
91         }\r
92 \r
93         /**\r
94          * i_trgroupの座標系をマーカーにあわせるようにBehaviorを設定します。\r
95          *\r
96          */\r
97         public void setTransformGroup(TransformGroup i_trgroup)\r
98         {\r
99                 //コール先で排他制御\r
100                 this._nya_behavior.setRelatedTransformGroup(i_trgroup);\r
101         }\r
102 \r
103         /**\r
104          * 座標系再計算後に呼び出されるリスナです。\r
105          * @param i_listener\r
106          */\r
107         public void setUpdateListener(NyARSingleMarkerBehaviorListener i_listener)\r
108         {\r
109                 //コール先で排他制御\r
110                 this._nya_behavior.setUpdateListener(i_listener);\r
111         }\r
112 \r
113         /**\r
114          * ラスタを更新 コールバック関数だから呼んじゃらめえ\r
115          */\r
116         public void onUpdateBuffer(Buffer i_buffer)\r
117         {\r
118                 try {\r
119                         synchronized (this._nya_raster) {\r
120                                 this._nya_raster.setBuffer(i_buffer);\r
121                         }\r
122                 } catch (Exception e) {\r
123                         e.printStackTrace();\r
124                 }\r
125         }\r
126 \r
127         public void start() throws NyARException\r
128         {\r
129                 //開始\r
130                 this._capture.start();\r
131         }\r
132 \r
133         public void stop()\r
134         {\r
135                 this._capture.stop();\r
136         }\r
137 }\r
138 \r
139 class NyARBehavior extends Behavior\r
140 {\r
141         private NyARTransMatResult trans_mat_result = new NyARTransMatResult();\r
142 \r
143         private NyARSingleDetectMarker related_nya;\r
144 \r
145         private TransformGroup trgroup;\r
146 \r
147         private Background back_ground;\r
148 \r
149         private J3dNyARRaster_RGB raster;\r
150 \r
151         private WakeupCondition wakeup;\r
152 \r
153         private NyARSingleMarkerBehaviorListener listener;\r
154 \r
155         public void initialize()\r
156         {\r
157                 wakeupOn(wakeup);\r
158         }\r
159 \r
160         /**\r
161          * i_related_ic2dの内容で定期的にi_back_groundを更新するBehavior\r
162          * @param i_back_ground\r
163          * @param i_related_ic2d\r
164          */\r
165         public NyARBehavior(NyARSingleDetectMarker i_related_nya, J3dNyARRaster_RGB i_related_raster, float i_rate)\r
166         {\r
167                 super();\r
168                 wakeup = new WakeupOnElapsedTime((int) (1000 / i_rate));\r
169                 related_nya = i_related_nya;\r
170                 trgroup = null;\r
171                 raster = i_related_raster;\r
172                 back_ground = null;\r
173                 listener = null;\r
174                 this.setSchedulingBounds(new BoundingSphere(new Point3d(), 100.0));\r
175         }\r
176 \r
177         public void setRelatedBackGround(Background i_back_ground)\r
178         {\r
179                 synchronized (raster) {\r
180                         back_ground = i_back_ground;\r
181                 }\r
182         }\r
183 \r
184         public void setRelatedTransformGroup(TransformGroup i_trgroup)\r
185         {\r
186                 synchronized (raster) {\r
187                         trgroup = i_trgroup;\r
188                 }\r
189         }\r
190 \r
191         public void setUpdateListener(NyARSingleMarkerBehaviorListener i_listener)\r
192         {\r
193                 synchronized (raster) {\r
194                         listener = i_listener;\r
195                 }\r
196         }\r
197 \r
198         /**\r
199          * いわゆるイベントハンドラ\r
200          */\r
201         public void processStimulus(Enumeration criteria)\r
202         {\r
203                 try {\r
204                         synchronized (raster) {\r
205                                 Transform3D t3d = null;\r
206                                 boolean is_marker_exist = false;\r
207                                 if (back_ground != null) {\r
208                                         raster.renewImageComponent2D();/*DirectXモードのときの対策*/\r
209                                         back_ground.setImage(raster.getImageComponent2D());\r
210                                 }\r
211                                 if (raster.hasData()) {\r
212                                         is_marker_exist = related_nya.detectMarkerLite(raster, 100);\r
213                                         if (is_marker_exist)\r
214                                         {\r
215                                                 final NyARTransMatResult src = this.trans_mat_result;\r
216                                                 related_nya.getTransmationMatrix(src);\r
217                                                 Matrix4d matrix = new Matrix4d(src.m00, -src.m10, -src.m20, 0, -src.m01, src.m11, src.m21, 0, -src.m02, src.m12, src.m22, 0, -src.m03, src.m13, src.m23, 1);\r
218                                                 matrix.transpose();\r
219                                                 t3d = new Transform3D(matrix);\r
220                                                 if (trgroup != null) {\r
221                                                         trgroup.setTransform(t3d);\r
222                                                 }\r
223                                         }\r
224                                 }\r
225                                 if (listener != null) {\r
226                                         listener.onUpdate(is_marker_exist, t3d);\r
227                                 }\r
228                         }\r
229                         wakeupOn(wakeup);\r
230                 } catch (Exception e) {\r
231                         e.printStackTrace();\r
232                 }\r
233         }\r
234 }\r