OSDN Git Service

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