View Javadoc

1   /* -------------------------------------------------------------------
2    * Java source file for the class ManipulatableRenderer
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: ManipulatableRenderer.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.renderer;
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.io.*;
28  
29  import javax.media.j3d.*;
30  import javax.swing.*;
31  import javax.swing.event.*;
32  import com.sun.j3d.loaders.*;
33  
34  import net.jbeans.ui.dial.*;
35  import net.jbeans.ui.label.*;
36  import net.jbeans.j3d.universe.*;
37  import net.jbeans.j3d.util.manipulator.*;
38  
39  /*====================================================================
40              Implementation of class ManipulatableRenderer             
41  ====================================================================*/
42  /***
43   * generally describe ManipulatableRenderer in here
44   * 
45   * @version $Revision: 1.3 $
46   * @author Masahiro Takatsuka (masa@jbeans.net)
47   * @see SelectableRenderer
48   * @see Externalizable
49   */
50  
51  public abstract class ManipulatableRenderer extends SelectableRenderer implements Externalizable {
52  	/***
53  	 * possible viewing mode.
54  	 */
55  	public static final int EXAMINE = 0x01;
56  	public static final int WALK = 0x02;
57  	public static final int FLY = 0x04;
58  	public static final int PLANE = 0x08;		
59  	public static final int DEFAULT = EXAMINE;	
60  
61  	public static final int ROTATE = ManipulatableUniverse.MOUSE_ROTATE;
62  	public static final int TRANSLATE = ManipulatableUniverse.MOUSE_TRANSLATE;
63  	public static final int ZOOM = ManipulatableUniverse.MOUSE_ZOOM;
64  	public static final int ROLL = ManipulatableUniverse.MOUSE_ROLL;
65  	public static final int SCALE = ManipulatableUniverse.MOUSE_SCALE;
66  	
67  	/* ------------------------ not serialized ------------------------ */
68  	/***
69  	 * Dial 1 is normally used to control rotation around X-axis.
70  	 */
71  	transient protected ThumbDial dial1;
72  
73  	/***
74  	* The title of the dial1
75  	*/
76  	transient protected OrientedLabel dial1Title;
77  
78  	/***
79  	 * Dial 2 is normally used to control rotation around Y-axis.
80  	 */
81  	transient protected ThumbDial dial2;
82  
83  	/***
84  	* The title of the dial2
85  	*/
86  	transient protected OrientedLabel dial2Title;
87  
88  	/***
89  	 * Dial 3 is normally used to control zoom.
90  	 */
91  	transient protected ThumbDial dial3;
92  
93  	/***
94  	* The title of the dial3
95  	*/
96  	transient protected OrientedLabel dial3Title;
97  
98  	/***
99  	 * Dial 4 is normally used to control scaling.
100 	 */
101 	transient protected ThumbDial dial4;
102 
103 	/***
104 	* The title of the dial4
105 	*/
106 	transient protected OrientedLabel dial4Title;
107 
108 	/***
109 	 * Dial 5 is normally used to control Hight in Walk mode.
110 	 */
111 	transient protected ThumbDial dial5;
112 
113 	/***
114 	* The title of the dial5
115 	*/
116 	transient protected OrientedLabel dial5Title;
117 
118 	transient private JPanel panel1;
119 	transient private JPanel panel2;
120 	transient private JPanel panel3;
121 	transient private JPanel panel4;
122 	
123 	transient private Stimulus stimulus;
124 	
125 	transient private DialListener dialListener;
126 
127 	
128 	/* -------------------------- serialized -------------------------- */
129 	/***
130 	 * A flag to indicate the visibility of control dials.
131 	 */
132 	private boolean dialsVisible;
133 	
134 	/***
135 	 * current viewing mode.
136 	 */
137 	private int viewingMode;
138 	
139 	/***
140 	* Constructs a new ManipulatableRenderer object.
141 	*/
142 	ManipulatableRenderer() {
143 		this("Manipulatable Renderer");
144 	}
145 	
146 	/***
147 	* Constructs a new Renderer object.
148 	*                                         Masahiro Takatsuka/1999-Jun-11
149 	*/
150 	ManipulatableRenderer(String title) {
151 		super(title);
152 		this.viewingMode = DEFAULT;
153 		this.dialsVisible = true;
154 		initializeMe();
155 	}
156 	
157 	private void initializeMe() {
158 		setViewingMode(this.viewingMode);
159 		setDialsVisible(this.dialsVisible);
160 		this.stimulus = new Stimulus();	// temp for sending stimulus
161 	}
162 
163 	public void setDialsVisible(boolean visible) {
164 		this.dialsVisible = visible;
165 		setControlerVisible(this.dialsVisible);
166 	}
167 
168 	public boolean getDialsVisible() {
169 		return this.dialsVisible;
170 	}
171 	
172 	public boolean isDialsVisible() {
173 		return getDialsVisible();
174 	}
175 
176 	public void setViewingMode(int mode) {
177 		this.viewingMode = mode;
178 		switch (this.viewingMode) {
179 		case EXAMINE:
180 			// set target TG
181 			this.dial1Title.setText("Rot X : ");
182 			this.dial2Title.setText("Rot Y : ");
183 			this.dial3Title.setText("Zoom : ");
184 			this.dial4Title.setText("Scale : ");
185 			this.dial5.setVisible(false);
186 			this.dial5Title.setVisible(false);			
187 			break;
188 		case WALK:
189 			// set target TG			
190 			this.dial1Title.setText("Tilt : ");
191 			this.dial2Title.setText("Pan : ");
192 			this.dial3Title.setText("Zoom : ");
193 			this.dial4Title.setText("Scale : ");
194 			this.dial5.setVisible(true);
195 			this.dial5Title.setText("Hight : ");			
196 			this.dial5Title.setVisible(true);			
197 			break;
198 		case FLY:
199 			// set target TG			
200 			this.dial1Title.setText("Tilt : ");
201 			this.dial2Title.setText("Pan : ");
202 			this.dial3Title.setText("Zoom : ");
203 			this.dial4Title.setText("Scale : ");
204 			this.dial5.setVisible(false);
205 			this.dial5Title.setVisible(false);			
206 			break;
207 		case PLANE:
208 			// set target TG			
209 			this.dial1Title.setText("Trans Y : ");
210 			this.dial2Title.setText("Trans X : ");
211 			this.dial3Title.setText("Zoom : ");
212 			this.dial4Title.setText("Scale : ");
213 			this.dial5.setVisible(false);
214 			this.dial5Title.setVisible(false);			
215 			break;
216 		}
217 	}
218 
219 	public int getViewingMode() {
220 		return this.viewingMode;
221 	}
222 
223     /***
224      * Serialization methods
225      */
226 	public void readExternal(ObjectInput in) throws ClassNotFoundException, IOException {
227 		this.dialsVisible = in.readBoolean();
228  		this.viewingMode = in.readInt();
229 		super.readExternal(in);
230   		initializeMe();
231 	}
232 
233     /***
234      * Serialization methods
235      */
236 	public void writeExternal(ObjectOutput out) throws IOException {
237  		out.writeBoolean(this.dialsVisible);
238  		out.writeInt(this.viewingMode);
239 		super.writeExternal(out);
240 	}
241 	
242 //    	protected Universe createUniverse(Canvas3D canvas3d) {
243 //    		return new ManipulatableUniverse(canvas3d);
244 //    	}
245 	
246 	protected JPanel initRendererPanel() {
247 		this.dialListener = new DialListener();
248 		JPanel rendererPanel = super.initRendererPanel(); // create basic renderer panel.
249 		JPanel rendererDialPanel = new JPanel();
250 		GridBagLayout gridbag = new GridBagLayout();
251 		GridBagConstraints c = new GridBagConstraints();
252 		rendererDialPanel.setLayout(gridbag);
253 		Insets insets = new Insets(0, 0, 0, 0);
254 		// add rendererPanel
255 		setGridBagConstraints(c, 1, 0, 2, 2, 1.0, 1.0, GridBagConstraints.NORTH, GridBagConstraints.BOTH, insets, 0, 0);
256 		gridbag.setConstraints(rendererPanel, c);
257 		rendererDialPanel.add(rendererPanel, c);
258 		
259 		// add x-rod dial
260 		this.panel1 = new JPanel();
261 		GridBagLayout gridbag1 = new GridBagLayout();
262 		GridBagConstraints c1 = new GridBagConstraints();
263 		this.panel1.setLayout(gridbag1);
264 		this.dial5 = new ThumbDial(Dial.VERTICAL);
265 		this.dial5.addChangeListener(this.dialListener);
266 		setGridBagConstraints(c1, 0, 0, 1, 1, 0, 0, GridBagConstraints.SOUTH, GridBagConstraints.NONE, insets, 0, 0);		
267 		gridbag1.setConstraints(this.dial5, c1);
268 		this.panel1.add(this.dial5, c1);				
269 		this.dial5Title = new OrientedLabel("H:");
270 		this.dial5Title.setAngle(Math.toRadians(90));
271 		setGridBagConstraints(c1, 0, 1, 1, 1, 0, 0, GridBagConstraints.SOUTH, GridBagConstraints.NONE, insets, 0, 0);		
272 		gridbag1.setConstraints(this.dial5Title, c1);		
273 		this.panel1.add(this.dial5Title, c1);
274 
275 		this.dial1 = new ThumbDial(Dial.VERTICAL);
276 		this.dial1.addChangeListener(this.dialListener);
277 		setGridBagConstraints(c1, 0, 2, 1, 1, 0, 0, GridBagConstraints.SOUTH, GridBagConstraints.NONE, insets, 0, 0);		
278 		gridbag1.setConstraints(this.dial1, c1);
279 		this.panel1.add(this.dial1, c1);				
280 		this.dial1Title = new OrientedLabel("X:");
281 		this.dial1Title.setAngle(Math.toRadians(90));
282 		setGridBagConstraints(c1, 0, 3, 1, 1, 0, 0, GridBagConstraints.SOUTH, GridBagConstraints.NONE, insets, 0, 0);		
283 		gridbag1.setConstraints(this.dial1Title, c1);		
284 		this.panel1.add(this.dial1Title, c1);
285 		setGridBagConstraints(c, 0, 1, 1, 1, 0, 0, GridBagConstraints.SOUTH, GridBagConstraints.NONE, insets, 0, 0);
286 		gridbag.setConstraints(this.panel1, c);
287 		rendererDialPanel.add(this.panel1, c);
288 		
289 		// add y-rod dial
290 		this.panel2 = new JPanel();
291 		this.dial2Title = new OrientedLabel("Y:");
292 		this.panel2.add(this.dial2Title);
293 		this.dial2 = new ThumbDial(Dial.HORIZONTAL);
294 		this.dial2.addChangeListener(this.dialListener);
295 		this.panel2.add(this.dial2);		
296 		setGridBagConstraints(c, 1, 3, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, insets, 0, 0);
297 		gridbag.setConstraints(this.panel2, c);
298 		rendererDialPanel.add(this.panel2, c);
299 
300 		// add scale slider.		
301 		this.panel4 = new JPanel();
302 		this.dial4Title = new OrientedLabel("S:");
303 		this.panel4.add(this.dial4Title);
304 		this.dial4 = new ThumbDial(Dial.HORIZONTAL);
305 		this.dial4.addChangeListener(this.dialListener);
306 		this.panel4.add(this.dial4);		
307 		setGridBagConstraints(c, 2, 3, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, insets, 0, 0);
308 		gridbag.setConstraints(this.panel4, c);
309 		rendererDialPanel.add(this.panel4, c);
310 		
311 		// add z-rod dial
312 		this.panel3 = new JPanel();
313 		GridBagLayout gridbag3 = new GridBagLayout();
314 		GridBagConstraints c3 = new GridBagConstraints();
315 		this.panel3.setLayout(gridbag3);
316 		this.dial3 = new ThumbDial(Dial.VERTICAL);
317 		this.dial3.addChangeListener(this.dialListener);
318 		setGridBagConstraints(c3, 0, 0, 1, 1, 0, 0, GridBagConstraints.SOUTH, GridBagConstraints.NONE, insets, 0, 0);		
319 		gridbag3.setConstraints(this.dial3, c3);
320 		this.panel3.add(this.dial3, c3);				
321 		this.dial3Title = new OrientedLabel("Z:");
322 		this.dial3Title.setAngle(Math.toRadians(90));		
323 		setGridBagConstraints(c3, 0, 1, 1, 1, 0, 0, GridBagConstraints.SOUTH, GridBagConstraints.NONE, insets, 0, 0);		
324 		gridbag3.setConstraints(this.dial3Title, c3);
325 		this.panel3.add(this.dial3Title, c3);
326 		setGridBagConstraints(c, 3, 1, 1, 1, 0, 0, GridBagConstraints.SOUTH, GridBagConstraints.NONE, insets, 0, 0);
327 		gridbag.setConstraints(this.panel3, c);
328 		rendererDialPanel.add(this.panel3, c);
329 
330 		return rendererDialPanel;
331 	}
332 
333 	private void setControlerVisible(boolean visible) {
334 		if (visible) {
335 			this.panel1.setVisible(true);
336 			this.panel2.setVisible(true);
337 			this.panel3.setVisible(true);
338 			this.panel4.setVisible(true);			
339 		} else {
340 			this.panel1.setVisible(false);
341 			this.panel2.setVisible(false);
342 			this.panel3.setVisible(false);
343 			this.panel4.setVisible(false);			
344 		}
345 	}
346 
347 	class DialListener implements ChangeListener {
348 		public void stateChanged(ChangeEvent e) {
349 			Object source = e.getSource();
350 			double dValue = 0.0;
351 			int iValue = 0;
352 			int mode = getViewingMode();
353 			int manMode = ROTATE;
354 			ManipulatableRenderer.this.stimulus.reset();
355 			ManipulatableUniverse univ = (ManipulatableUniverse) getUniverse();
356 			if (source instanceof Dial) {
357 				Dial dial = (Dial) source;
358 				iValue = dial.getMouseMovement();
359 				switch (mode) {
360 				case EXAMINE:
361 				case FLY:
362 					if (dial == ManipulatableRenderer.this.dial1) {
363 						ManipulatableRenderer.this.stimulus.setY(iValue);
364 						manMode = ROTATE;
365 					} else if (dial == ManipulatableRenderer.this.dial2) {
366 						ManipulatableRenderer.this.stimulus.setX(iValue);
367 						manMode = ROTATE;
368 					} else if (dial == ManipulatableRenderer.this.dial3) {
369 						ManipulatableRenderer.this.stimulus.setY(iValue);
370 						manMode = ZOOM;
371 					} else if (dial == ManipulatableRenderer.this.dial4) {
372 						ManipulatableRenderer.this.stimulus.setY(iValue);
373 						manMode = SCALE;
374 					}
375 					break;
376 				case WALK:
377 					if (dial == ManipulatableRenderer.this.dial1) {
378 						ManipulatableRenderer.this.stimulus.setY(iValue);
379 						manMode = ROTATE;
380 					} else if (dial == ManipulatableRenderer.this.dial2) {
381 						ManipulatableRenderer.this.stimulus.setX(iValue);
382 						manMode = ROTATE;
383 					} else if (dial == ManipulatableRenderer.this.dial3) {
384 						ManipulatableRenderer.this.stimulus.setY(iValue);
385 						manMode = ZOOM;
386 					} else if (dial == ManipulatableRenderer.this.dial4) {
387 						ManipulatableRenderer.this.stimulus.setY(iValue);
388 						manMode = SCALE;
389 					} else if (dial == ManipulatableRenderer.this.dial5) {
390 						ManipulatableRenderer.this.stimulus.setY(iValue);
391 						manMode = TRANSLATE;
392 					}
393 					break;
394 				case PLANE:
395 					if (dial == ManipulatableRenderer.this.dial1) {
396 						ManipulatableRenderer.this.stimulus.setY(iValue);
397 						manMode = TRANSLATE;
398 					} else if (dial == ManipulatableRenderer.this.dial2) {
399 						ManipulatableRenderer.this.stimulus.setX(iValue);
400 						manMode = TRANSLATE;
401 					} else if (dial == ManipulatableRenderer.this.dial3) {
402 						ManipulatableRenderer.this.stimulus.setY(iValue);
403 						manMode = ZOOM;
404 					} else if (dial == ManipulatableRenderer.this.dial4) {
405 						ManipulatableRenderer.this.stimulus.setY(iValue);
406 						manMode = SCALE;
407 					}
408 					break;
409 				}
410 				univ.manipulate(manMode, ManipulatableRenderer.this.stimulus);
411 			}
412 		}
413 	}
414 
415 	/***
416 	* Sets parameters for the specified GridBagConstraints object.
417 	* <PRE>
418 	* </PRE>
419 	* 
420 	* @param (parameter-name) (description)
421 	* @return void
422 	*/
423 	private void setGridBagConstraints(GridBagConstraints c, int gridx, int gridy, int gridwidth, int gridheight, double weightx, double weighty, int anchor, int fill, Insets insets, int ipadx, int ipady) {
424   		c.gridx = gridx;
425 		c.gridy = gridy;
426   		c.gridwidth = gridwidth;
427   		c.gridheight = gridheight;
428   		c.weightx = weightx;
429   		c.weighty = weighty;
430   		c.anchor = anchor;
431 		c.fill = fill;
432 		if (insets != null) {
433 			c.insets = insets;
434 		}
435   		c.ipadx = ipadx;
436   		c.ipady = ipady;
437 	}
438 }