View Javadoc

1   /* -------------------------------------------------------------------
2    * Java source file for the class SelectableUniverse
3    * 
4    * Copyright (c), 2003, Masahiro Takatsuka.
5    * All Rights Researved.
6    * 
7    * Original Author: Masahiro Takatsuka (masa@jbeans.net)
8    * $Author: takatsukam $
9    * 
10   * $Date: 2004/03/03 11:53:06 $
11   * 
12   * $Id: SelectableUniverse.java,v 1.3 2004/03/03 11:53:06 takatsukam Exp $
13   * 
14   * Reference:		Document no:
15   * ___				___
16   * 
17   * To Do:
18   * ___
19   * 
20  ------------------------------------------------------------------- */
21  
22  /* --------------------------- Package ---------------------------- */
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                Implementation of class SelectableUniverse              
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   * this class needs to be public but its constructors can be package.
56   */
57  public class SelectableUniverse extends Universe implements PickMouseListener {
58  	private static final boolean DEBUG = Debug.getDebugFlag(SelectableUniverse.class);
59  	
60  	/* ------------------------ not serialized ------------------------ */
61  	private transient EventListenerList listenerList;
62  
63  	/* -------------------------- serialized -------------------------- */
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 		// set transform groups 
179 		setupTransformGroups(world);
180 			
181 		// setup PickMouseBehavior before addign the world to the locale.
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 		// get transform group of viewingplatform
195 		this.viewingTG = getViewingPlatform().getViewPlatformTransform();
196 		
197 		// get transform group of world
198 		this.worldTG = world.getWorldTransform();
199 
200 		// manipulate world TG as a default.
201   		this.currentTG = this.worldTG;		
202 	}
203 	
204 	protected void setupPickMouse(World world) {
205 		// set up selection behavior
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 		// add the behavior to the scene graph
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 	* @param nodeType is the logical OR of one o or more of:
226 	* PickObject.SHAPE3D, PickObject.MORPH, PickObject.PRIMITIVE,
227 	* PickObject.LINK, PickObject.GROUP, PickObject.TRANSFORM_GROUP,
228 	* PickObject.BRANCH_GROUP, PickObject.SWITCH
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)) { // left button double clicked
246 			if ((cond & Event.CTRL_MASK) != 0) {	// select CENTER !
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 {		// no intersection.
255 					this.center.set(0, 0, 0);
256 				}
257 			} else {			// select object.
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) { // shift key down! == select viewer
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 	* @param nodeType is the logical OR of one o or more of:
304 	* PickObject.SHAPE3D, PickObject.MORPH, PickObject.PRIMITIVE,
305 	* PickObject.LINK, PickObject.GROUP, PickObject.TRANSFORM_GROUP,
306 	* PickObject.BRANCH_GROUP, PickObject.SWITCH
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 }