View Javadoc

1   /* -------------------------------------------------------------------
2    * Java source file for the class Renderer
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: Renderer.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.awt.event.*;
28  import java.io.*;
29  
30  import javax.media.j3d.*;
31  import javax.vecmath.*;
32  import javax.swing.*;
33  import javax.swing.event.*;
34  import com.sun.j3d.loaders.*;
35  import com.sun.j3d.utils.picking.*;
36  
37  import net.jbeans.ui.dial.*;
38  import net.jbeans.ui.toolbar.*;
39  
40  import net.jbeans.j3d.universe.*;
41  import net.jbeans.j3d.util.manipulator.*;
42  import net.jbeans.j3d.util.picking.behavior.*;
43  
44  import net.jbeans.util.debug.*;
45  
46  /*====================================================================
47                     Implementation of class Renderer                   
48  ====================================================================*/
49  /***
50   * generally describe Renderer in here
51   * 
52   * @version $Revision: 1.3 $
53   * @author Masahiro Takatsuka (masa@jbeans.net)
54   * @see SeekableRenderer
55   * @see ActionListener
56   */
57  
58  public class Renderer extends SeekableRenderer implements ActionListener {
59  	private static final boolean DEBUG = Debug.getDebugFlag(Renderer.class);
60  
61  	protected static final int BUTTON_WIDTH  = 30;
62  	protected static final int BUTTON_HEIGHT  = 30;
63  	protected static final int PANEL_WIDTH  = MRG + BUTTON_WIDTH + MRG;
64  	protected static final int PANEL_HEIGHT = MRG + DEFAULT_CANVAS3D_HEIGHT + MRG;
65  
66  	public static final int SEEK = SeekableUniverse.MOUSE_SEEK;
67  
68  	public static final int LOOK_AT_NEVER = 0;
69  	public static final int LOOK_AT_ALWAYS = 1;	
70  	public static final int LOOK_AT_1ST = 2;
71  	
72  	/* ------------------------ not serialized ------------------------ */
73  	/***
74  	* A toolbar.
75  	*/
76  	transient protected ToolBar toolbar;
77  
78  	
79  	/* -------------------------- serialized -------------------------- */
80  	private int lookAtMode;
81  	private DirectionalLight headLight;
82  	private AmbientLight ambientLight;	
83  	
84  	/***
85  	* Constructs a new Renderer object.
86  	*/
87  	public Renderer() {
88  		this("Renderer");
89  	}
90  
91  	/***
92  	* Constructs a new Renderer object.
93  	*/
94  	public Renderer(String title) {
95  		super(title);
96  		this.lookAtMode = LOOK_AT_ALWAYS; // default
97  		
98  		initializeMe();
99  	}
100 
101 	private void initializeMe() {
102 		// create a headlight and ambient light before scene becomes live.
103 		setBasicLights();
104 
105 		// create toolbar
106   		setupToolBar();
107 		// add toolbar
108 		this.initRendererPanel.add(this.toolbar, BorderLayout.NORTH);
109 
110 		/*
111 		* This needs to be done in order to put popup menu on top of Canvas3D.
112 		* Masahiro Takatsuka/2001-Jun-05
113 		*/
114 		JPopupMenu.setDefaultLightWeightPopupEnabled(false);
115 
116 		/*
117 		* This needs to be done in order to put popup menu on top of Canvas3D.
118 		* However, it does not work well at the moment,
119 		* so I'm commenting it out.
120 		* Masahiro Takatsuka/2001-Jun-05
121 		*/
122 		ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false);
123 	}
124 	
125 	/***
126 	 * Get the value of lookAtMode.
127 	 * @return value of lookAtMode.
128 	 */
129 	public int getLookAtMode() {
130 		return this.lookAtMode;
131 	}
132 	
133 	/***
134 	 * Set the value of lookAtMode.
135 	 * @param v  Value to assign to lookAtMode.
136 	 */
137 	public void setLookAtMode(int  v) {
138 		this.lookAtMode = v;
139 	}
140 	
141     /***
142      * Serialization methods
143      */
144     public void readExternal(ObjectInput in) throws ClassNotFoundException, IOException {
145 		super.readExternal(in);
146 		initializeMe();
147     }
148 
149     /***
150      * Serialization methods
151      */
152     public void writeExternal(ObjectOutput out) throws IOException {
153 		super.writeExternal(out);
154     }
155 
156 	protected JPanel initRendererPanel() {
157 		JPanel rendererDialPanel = super.initRendererPanel();
158 		JPanel rendererToolPanel= new JPanel();
159 		rendererToolPanel.setLayout(new BorderLayout());
160 		rendererToolPanel.add(rendererDialPanel, BorderLayout.CENTER);
161 		return rendererToolPanel;
162 	}
163 
164 	private void setupToolBar() {
165 		Class klass = Renderer.class;
166 
167 		//this.toolbar = new ToolBar(JToolBar.VERTICAL);
168 		this.toolbar = new ToolBar();
169 		this.toolbar.setFlexible(true);	// use flexible toolbar
170 		
171 		// add mode button;
172 		String[] modDescs = {"Examine", "Walk"};
173 		String[] modIcons = {"resources/Renderer/ExamIconColor24.gif", "resources/Renderer/WalkIconColor24.gif"};
174 		Action[] modActions = {
175 			new AbstractAction() {
176 					public void actionPerformed(ActionEvent e) {
177 						setViewingMode(EXAMINE);
178 					}
179 				},
180 			new AbstractAction() {
181 					public void actionPerformed(ActionEvent e) {
182 						setViewingMode(WALK);
183 					}
184 				}
185 		};
186 		this.toolbar.addRadioButtonItems(klass, modDescs, modIcons, modActions, 0);
187 
188 		this.toolbar.addSeparator();
189 		// add headlight button;
190 		JToggleButton headlightButton = this.toolbar.addToggleButton(klass, "HeadLight", "resources/Renderer/HeadLightIconColor24.gif", new AbstractAction() {
191 				public void actionPerformed(ActionEvent e) {
192 					JToggleButton b = (JToggleButton) e.getSource();
193 					if (b.isSelected()) {
194 						Renderer.this.setHeadLightEnable(true);
195 					} else {
196 						Renderer.this.setHeadLightEnable(false);
197 					}
198 				}
199 			});
200 		headlightButton.setSelected(true);
201 		// add ambientlight button;
202 		JToggleButton ambientlightButton = this.toolbar.addToggleButton(klass, "AmbientLight", "resources/Renderer/AmbientLightIconColor24.gif", new AbstractAction() {
203 				public void actionPerformed(ActionEvent e) {
204 					JToggleButton b = (JToggleButton) e.getSource();
205 					if (b.isSelected()) {
206 						Renderer.this.setAmbientLightEnable(true);
207 					} else {
208 						Renderer.this.setAmbientLightEnable(false);
209 					}
210 				}
211 			});
212 		ambientlightButton.setSelected(true);
213 		this.toolbar.addSeparator();
214 		// add Home button;
215 		this.toolbar.addButton(klass, "Home", "resources/Renderer/HomeIconColor24.gif", new AbstractAction() {
216 				public void actionPerformed(ActionEvent e) {
217 					((ManipulatableUniverse) getUniverse()).resetCurrentTransformGroup();
218 				}
219 			});
220 		// add set Home button;
221 		this.toolbar.addButton(klass, "Set Home", "resources/Renderer/SetHomeIconColor24.gif", new AbstractAction() {
222 				public void actionPerformed(ActionEvent e) {
223 					((ManipulatableUniverse) getUniverse()).saveCurrentTransformGroup();
224 				}
225 			});
226 		// add view all button;
227 		this.toolbar.addButton(klass, "View All", "resources/Renderer/ViewAllIconColor24.gif", new AbstractAction() {
228 				public void actionPerformed(ActionEvent e) {
229 					//((SeekableUniverse) getUniverse()).viewAll();
230 					viewAll();
231 				}
232 			});
233 		
234 		// add seek button;
235 		this.toolbar.addButton(klass, "Seek", "resources/Renderer/SeekIconColor24.gif", new AbstractAction() {
236 				public void actionPerformed(ActionEvent e) {
237 					((SeekableUniverse) getUniverse()).setMouseButton1Mode(SEEK);
238 				}
239 			});
240 		
241 		this.toolbar.addSeparator();
242 		// add manipulation button;
243 		String[] manDescs = {"Rotation", "Translation", "Zoom", "Roll", "Scale"};
244 		String[] manIcons = {"resources/Renderer/RotationIconColor24.gif", "resources/Renderer/TranslationIconColor24.gif", "resources/Renderer/ZoomIconColor24.gif", "resources/Renderer/RollIconColor24.gif", "resources/Renderer/ScaleIconColor24.gif"};
245 		Action[] manActions = {
246 			new AbstractAction() {
247 				public void actionPerformed(ActionEvent e) {
248 					((SeekableUniverse) getUniverse()).setMouseButton1Mode(ROTATE);
249 				}
250 			},
251 			new AbstractAction() {
252 				public void actionPerformed(ActionEvent e) {
253 					((SeekableUniverse) getUniverse()).setMouseButton1Mode(TRANSLATE);
254 				}
255 			},
256 			new AbstractAction() {
257 				public void actionPerformed(ActionEvent e) {
258 					((SeekableUniverse) getUniverse()).setMouseButton1Mode(ZOOM);
259 				}
260 			},
261 			new AbstractAction() {
262 				public void actionPerformed(ActionEvent e) {
263 					((SeekableUniverse) getUniverse()).setMouseButton1Mode(ROLL);
264 				}
265 			},
266 			new AbstractAction() {
267 				public void actionPerformed(ActionEvent e) {
268 					((SeekableUniverse) getUniverse()).setMouseButton1Mode(SCALE);
269 				}
270 			}
271 		};
272 		this.toolbar.addRadioButtonItems(klass, manDescs, manIcons, manActions, 0);
273 		
274 		this.toolbar.addSeparator();
275 		// add projection button;
276 		String[] proDescs = {"Perspective", "Orthogonal"};
277 		String[] proIcons = {"resources/Renderer/PerspectiveIconColor24.gif", "resources/Renderer/OrthogonalIconColor24.gif"};
278 		Action[] proActions = {
279 			new AbstractAction() {
280 				public void actionPerformed(ActionEvent e) {
281 					BasicRenderer br = (BasicRenderer) Renderer.this;
282 					br.setPerspectiveProjection();
283 				}
284 			},
285 			new AbstractAction() {
286 				public void actionPerformed(ActionEvent e) {
287 					BasicRenderer br = (BasicRenderer) Renderer.this;
288 					br.setParallelProjection();
289 				}
290 			}
291 		};
292 		this.toolbar.addRadioButtonItems(klass, proDescs, proIcons, proActions, 0);
293 	}
294 
295 	private void updateMenuBar(JMenuBar menuBar) {
296 		JMenu m = new JMenu("Help");
297 		addMenuItem(this, m, new JMenuItem("About"));
298 		menuBar.add(m);
299 	}
300 
301     private void addMenuItem(ActionListener frame, JMenu m, JMenuItem mi) {
302 		mi.addActionListener(frame);
303 		// Add the menuitem to the menu
304 		m.add(mi);
305     }
306 
307 	public void actionPerformed(ActionEvent evt) {
308 
309 	}
310 	
311 	/***
312 	 * Adds a new branch graphoup to the scene.
313 	 * <PRE>
314 	 * </PRE>
315 	 *
316 	 * @param branch BranchGroup object to be added.
317 	 * @return void
318 	 */
319 	public void addBranchGraph(BranchGroup branch) {
320 		super.addBranchGraph(branch);
321 
322 		SeekableUniverse univ = (SeekableUniverse) getUniverse();
323 		switch (this.lookAtMode) {
324 		case LOOK_AT_1ST:
325 			int numChild = univ.getNumOfChildren();
326 			if (numChild != 1) {
327 				break;
328 			}
329 		case LOOK_AT_ALWAYS:
330 		default:
331 			//((SeekableUniverse) getUniverse()).viewAll();
332 			viewAll();
333 			break;
334 		case LOOK_AT_NEVER:
335 			break;
336 		}
337 	}
338 
339 	/***
340      * Invoked when an object is selected (single click).
341 	 * <PRE>
342 	 * </PRE>
343 	 *
344 	 * @param event the PickMouseEvent object containing selected
345 	 * information.
346 	 * @return void
347 	 */
348 	public void selected(PickMouseEvent event) {
349 		if (DEBUG) {
350 			System.out.println("Renderer.selected():");
351 		}
352 		// extract userData.
353 		Object userData;
354 		PickResult pickResult = event.getPickResult();
355 		if (pickResult != null) {
356 			Shape3D shape3d = (Shape3D) pickResult.getNode(PickResult.SHAPE3D);
357 			userData = shape3d.getUserData();
358 		} else {
359 			userData = null;
360 		}
361 		if (DEBUG) {
362 			System.out.println("Renderer: userData = " + userData);
363 		}
364 
365 		// set userData.
366 		event.setUserData(userData);
367 		
368 		// call super class's selected() method.
369 		super.selected(event);		
370 	}
371 
372 	public void setHeadLight(DirectionalLight light) {
373 		this.headLight = light;
374 	}
375 
376 	public DirectionalLight getHeadLight() {
377 		return this.headLight;
378 	}
379 	
380     public boolean getHeadLightEnable() {
381         return this.headLight.getEnable();
382     }
383 
384     public void setHeadLightEnable(boolean flag) {
385         this.headLight.setEnable(flag);
386     }
387 
388     public Color3f getHeadLightColor() {
389         Color3f color3f = new Color3f();
390         this.headLight.getColor(color3f);
391         return color3f;
392     }
393 
394     public void setHeadLightColor(Color3f color3f) {
395         this.headLight.setColor(color3f);
396     }
397 	
398     public void setHeadLightDirection(float f, float f1, float f2) {
399         ((DirectionalLight) this.headLight).setDirection(f, f1, f2);
400     }
401 
402     public Color3f getAmbientLightColor() {
403         Color3f color3f = new Color3f();
404         this.ambientLight.getColor(color3f);
405         return color3f;
406     }
407 
408     public void setAmbientLightColor(Color3f color3f) {
409         this.ambientLight.setColor(color3f);
410     }
411 
412     public boolean getAmbientLightEnable() {
413         return this.ambientLight.getEnable();
414     }
415 
416     public void setAmbientLightEnable(boolean flag) {
417         this.ambientLight.setEnable(flag);
418     }
419 
420 	private void setBasicLights() {
421         this.headLight = new net.jbeans.j3d.light.DirectionalLight(new Color3f(1.0F, 1.0F, 1.0F), new Vector3f(0.0F, 0.0F, -1.0F));
422 		this.headLight.setInfluencingBounds(DEFAULT_BOUNDS);
423 	
424         this.ambientLight = new net.jbeans.j3d.light.AmbientLight(true, new Color3f(0.2F, 0.2F, 0.2F));
425 		this.ambientLight.setInfluencingBounds(DEFAULT_BOUNDS);
426 		
427 		BranchGroup bg = new BranchGroup();
428 		bg.addChild(this.headLight);
429 		//this.headLight.addScope(this.universe.getWorld());
430 		bg.addChild(this.ambientLight);
431 		//this.ambientLight.addScope(this.universe.getWorld());
432 
433 		this.universe.getWorld().addChild(bg);
434 	}
435 	
436 }
437