1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package net.jbeans.j3d.universe;
24
25 /* ------------------ Import classes (packages) ------------------- *//package-summary/html">class="comment"> ------------------ Import classes (packages) ------------------- *//package-summary.html">class="comment">/* ------------------ Import classes (packages) ------------------- *//package-summary.html">class="comment"> ------------------ Import classes (packages) ------------------- */
26 import java.awt.*;
27 import java.awt.event.*;
28 import java.net.*;
29 import java.util.*;
30 import javax.media.j3d.*;
31 import javax.vecmath.*;
32 import javax.swing.event.*;
33 import com.sun.j3d.utils.universe.*;
34 import com.sun.j3d.utils.picking.*;
35
36 import net.jbeans.j3d.util.*;
37 import net.jbeans.j3d.util.picking.behavior.*;
38
39 import net.jbeans.util.debug.*;
40
41
42
43
44 /***
45 * This class is basically the same as the SimpleUniverse. It, however,
46 * allows a user to select an object.
47 *
48 * @version $Revision: 1.3 $
49 * @author Masahiro Takatsuka (masa@jbeans.net)
50 * @see Universe
51 * @see PickMouseListener
52 */
53
54
55
56
57 public class SelectableUniverse extends Universe implements PickMouseListener {
58 private static final boolean DEBUG = Debug.getDebugFlag(SelectableUniverse.class);
59
60
61 private transient EventListenerList listenerList;
62
63
64 /***
65 * Node selection behavior
66 */
67 private PickMouseBehavior pickMouseBehavior;
68
69 /***
70 * A transform group of viewingplatform
71 */
72 protected TransformGroup viewingTG;
73
74 /***
75 * A transform group of world
76 */
77 protected TransformGroup worldTG;
78
79 /***
80 * A current transform group which is the target of for rot/trans/zoom
81 */
82 protected TransformGroup currentTG;
83
84 /***
85 * A current shape3d object which is the target of for rot/trans/zoom
86 */
87 private Shape3D currentS3D;
88
89 /***
90 * A current center which is the target of for rot/trans/zoom
91 */
92 protected Point3d center;
93
94 /***
95 * A current boundingbox which is the target of for rot/trans/zoom
96 */
97 private Bounds currentBounds;
98
99 private Vector4d tmpcenter;
100
101 /***
102 * Creates a locale, a single ViewingPlatform, and
103 * and a Viewer object (both with their default values).
104 *
105 * @see Locale
106 * @see Viewer
107 * @see ViewingPlatform
108 */
109 SelectableUniverse() {
110 this(null, 1, null, null);
111 }
112
113 /***
114 * Creates a locale, a single ViewingPlatform (with default values), and
115 * and a Viewer object. The Viewer object uses default values for
116 * everything but the canvas.
117 *
118 * @param canvas The canvas to associate with the Viewer object. Passing
119 * in null will cause this parameter to be ignored and a canvas to be
120 * created by the utility.
121 *
122 * @see Locale
123 * @see Viewer
124 * @see ViewingPlatform
125 */
126 SelectableUniverse(Canvas3D canvas) {
127 this(null, 1, canvas, null);
128 }
129
130 /***
131 * Creates the "view" side of the scene graph. The passed in parameters
132 * override the default values where appropriate.
133 *
134 * @param origin The origin used to set the origin of the Locale object.
135 * If this object is null, then 0.0 is used.
136 * @param numTransforms The number of transforms to be in the
137 * MultiTransformGroup object.
138 * @param canvas The canvas to draw into. If this is null, it is
139 * ignored and a canvas will be created by the utility.
140 * @param userConfig The URL to the user's configuration file, used
141 * by the Viewer object. Passing in null causes the default values
142 * to be used.
143 *
144 * @see Locale
145 * @see Viewer
146 * @see ViewingPlatform
147 * @see MultiTransformGroup
148 */
149 SelectableUniverse(HiResCoord origin, int numTransforms, Canvas3D canvas, URL userConfig) {
150 super(origin, numTransforms, canvas, userConfig);
151 this.center = new Point3d();
152 }
153
154 /***
155 * Creates the "view" side of the scene graph.
156 *
157 * @param viewingPlatform The viewingPlatform to use to create
158 * the "view" side of the scene graph.
159 * @param viewer The viewer object to use to create
160 * the "view" side of the scene graph.
161 */
162 SelectableUniverse(ViewingPlatform viewingPlatform, Viewer viewer) {
163 super(viewingPlatform, viewer);
164 this.center = new Point3d();
165 }
166
167 protected void setCenter(Point3d center) {
168 this.center = center;
169 }
170
171 protected Point3d getCenter() {
172 return this.center;
173 }
174
175 protected World createNewWorld(int numTransformGroup) {
176 World world = super.createNewWorld(numTransformGroup);
177
178
179 setupTransformGroups(world);
180
181
182 setupPickMouse(world);
183
184 return world;
185 }
186
187 public void setPickMode(int pickMode) {
188 if (this.pickMouseBehavior != null) {
189 this.pickMouseBehavior.setMode(pickMode);
190 }
191 }
192
193 protected void setupTransformGroups(World world) {
194
195 this.viewingTG = getViewingPlatform().getViewPlatformTransform();
196
197
198 this.worldTG = world.getWorldTransform();
199
200
201 this.currentTG = this.worldTG;
202 }
203
204 protected void setupPickMouse(World world) {
205
206 Canvas3D canvas3d = getCanvas();
207 this.pickMouseBehavior = new PickMouseBehavior(canvas3d,
208 world,
209 J3DUtil.DEFAULT_BOUNDS,
210 PickTool.GEOMETRY_INTERSECT_INFO);
211 this.pickMouseBehavior.addPickMouseListener(this);
212
213 world.addChild(this.pickMouseBehavior);
214 }
215
216 /***
217 * Invoked when an object is picked.
218 * <PRE>
219 * </PRE>
220 *
221 * @param node the picked node
222 * @return void
223 */
224
225
226
227
228
229
230 public void picked(PickMouseEvent event) {
231 MouseEvent mevent = event.getMouseEvent();
232 int cond = mevent.getModifiers();
233 int clickCount = mevent.getClickCount();
234 PickResult pickResult = event.getPickResult();
235 PickIntersection intersection = null;
236 Point3d pickedPoint = null;
237 if (pickResult != null) {
238 intersection = pickResult.getIntersection(0);
239 pickedPoint = intersection.getPointCoordinatesVW();
240 }
241 if (DEBUG) {
242 System.out.println("SelectableUniverse:picked cond = " + cond);
243 }
244 if (((cond & InputEvent.BUTTON1_MASK) != 0) &&
245 (clickCount > 1)) {
246 if ((cond & Event.CTRL_MASK) != 0) {
247 if (pickedPoint != null) {
248 this.center.x = pickedPoint.x;
249 this.center.y = pickedPoint.y;
250 this.center.z = pickedPoint.z;
251 if (DEBUG) {
252 System.out.println("SelectableUniverse:picked center = " + this.center);
253 }
254 } else {
255 this.center.set(0, 0, 0);
256 }
257 } else {
258 if (pickResult != null) {
259 this.currentTG = (TransformGroup) pickResult.getNode(PickResult.TRANSFORM_GROUP);
260 this.currentS3D = (Shape3D) pickResult.getNode(PickResult.SHAPE3D);
261 } else {
262 this.currentTG = null;
263 }
264 if (DEBUG) {
265 System.out.println("SelectableUniverse: target = " + this.currentTG);
266 }
267 if (this.currentTG == null) {
268 if ((cond & Event.SHIFT_MASK) != 0) {
269 this.currentTG = this.viewingTG;
270 if (DEBUG) {
271 System.out.println("SelectableUniverse: target = viewer");
272 }
273 } else {
274 this.currentTG = this.worldTG;
275 if (DEBUG) {
276 System.out.println("SelectableUniverse: target = world");
277 }
278 }
279 this.currentS3D = null;
280 }
281 try {
282 if (this.currentS3D != null) {
283 this.currentBounds = this.currentS3D.getBounds();
284 }
285 } catch (CapabilityNotSetException e) {
286 System.out.println("An exception occured, but it's ignored..");
287 e.printStackTrace();
288 }
289 }
290 }
291 firePickedEvent(event);
292 }
293
294 /***
295 * Invoked when an object is selected.
296 * <PRE>
297 * </PRE>
298 *
299 * @param node the selected node
300 * @return void
301 */
302
303
304
305
306
307
308 public void selected(PickMouseEvent event) {
309 MouseEvent mevent = event.getMouseEvent();
310 int cond = mevent.getModifiers();
311 int clickCount = mevent.getClickCount();
312 PickResult pickResult = event.getPickResult();
313 PickIntersection intersection = null;
314 Point3d pickedPoint = null;
315
316 fireSelectedEvent(event);
317 }
318
319 private void checkListeners() {
320 if (this.listenerList == null) {
321 this.listenerList = new EventListenerList();
322 }
323 }
324
325 /***
326 * Adds a PickMouseListener to the slider.
327 *
328 * @param l the PickMouseListener to add
329 */
330 public void addPickMouseListener(PickMouseListener l) {
331 checkListeners();
332 this.listenerList.add(PickMouseListener.class, l);
333 }
334
335 /***
336 * Removes a PickMouseListener from the slider.
337 *
338 * @param l the PickMouseListener to remove
339
340 */
341 public void removePickMouseListener(PickMouseListener l) {
342 checkListeners();
343 this.listenerList.remove(PickMouseListener.class, l);
344 }
345
346 /***
347 * Send the Pick node to listeners.
348 */
349 protected void firePickedEvent(PickMouseEvent event) {
350 checkListeners();
351 Object[] listeners = this.listenerList.getListenerList();
352 for (int i = listeners.length - 2; i >= 0; i -= 2) {
353 if (listeners[i] == PickMouseListener.class) {
354 ((PickMouseListener)listeners[i+1]).picked(event);
355 }
356 }
357 }
358
359 /***
360 * Send the Selection node to listeners.
361 */
362 protected void fireSelectedEvent(PickMouseEvent event) {
363 checkListeners();
364 Object[] listeners = this.listenerList.getListenerList();
365 for (int i = listeners.length - 2; i >= 0; i -= 2) {
366 if (listeners[i] == PickMouseListener.class) {
367 ((PickMouseListener)listeners[i+1]).selected(event);
368 }
369 }
370 }
371 }