001: /*
002: * $RCSfile: Viewer.java,v $
003: *
004: * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * - Redistribution of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * - Redistribution in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * Neither the name of Sun Microsystems, Inc. or the names of
019: * contributors may be used to endorse or promote products derived
020: * from this software without specific prior written permission.
021: *
022: * This software is provided "AS IS," without a warranty of any
023: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
024: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
025: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
026: * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
027: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
028: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
029: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
030: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
031: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
032: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
033: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
034: * POSSIBILITY OF SUCH DAMAGES.
035: *
036: * You acknowledge that this software is not designed, licensed or
037: * intended for use in the design, construction, operation or
038: * maintenance of any nuclear facility.
039: *
040: * $Revision: 1.1 $
041: * $Date: 2007/08/28 16:44:33 $
042: * $State: Exp $
043: */
044: package org.jdesktop.j3d.loaders.collada.test;
045:
046: import org.jdesktop.j3d.loaders.collada.Collada;
047: import com.sun.j3d.loaders.Scene;
048:
049: import com.sun.j3d.utils.universe.*;
050: import javax.media.j3d.*;
051: import javax.vecmath.*;
052: import java.awt.GraphicsConfiguration;
053: import java.net.MalformedURLException;
054: import java.net.URL;
055: import com.sun.j3d.utils.behaviors.vp.*;
056: import java.io.FileNotFoundException;
057: import javax.swing.JPopupMenu;
058: import javax.swing.ToolTipManager;
059: import org.jdesktop.j3d.utils.scenegraph.traverser.ChangePolygonAttributes;
060: import org.jdesktop.j3d.utils.view.ViewUtils;
061:
062: /**
063: * Simple Java 3D example program to display an .obj object.
064: */
065: public class Viewer extends javax.swing.JFrame {
066:
067: private String filename = null;
068:
069: private SimpleUniverse univ = null;
070: private BranchGroup scene = null;
071: private BranchGroup root = null;
072:
073: public BranchGroup createSceneGraph() {
074: // Create the root of the branch graph
075: BranchGroup objRoot = new BranchGroup();
076:
077: // Create a Transformgroup to scale all objects so they
078: // appear in the scene.
079: TransformGroup objScale = new TransformGroup();
080: Transform3D t3d = new Transform3D();
081: t3d.setScale(0.7);
082: objScale.setTransform(t3d);
083: objRoot.addChild(objScale);
084:
085: // Create the transform group node and initialize it to the
086: // identity. Enable the TRANSFORM_WRITE capability so that
087: // our behavior code can modify it at runtime. Add it to the
088: // root of the subgraph.
089: TransformGroup objTrans = new TransformGroup();
090: objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
091: objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
092: objScale.addChild(objTrans);
093:
094: Collada collada = new Collada();
095: Scene s = null;
096: try {
097: s = collada.load(filename);
098: } catch (FileNotFoundException e) {
099: System.err.println(e);
100: System.exit(1);
101: }
102:
103: objTrans.addChild(s.getSceneGroup());
104:
105: BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,
106: 0.0, 0.0), 500.0);
107:
108: // Set up the background
109: Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f);
110: Background bgNode = new Background(bgColor);
111: bgNode.setApplicationBounds(bounds);
112: objRoot.addChild(bgNode);
113:
114: return objRoot;
115: }
116:
117: private Canvas3D createUniverse() {
118: // Get the preferred graphics configuration for the default screen
119: GraphicsConfiguration config = SimpleUniverse
120: .getPreferredConfiguration();
121:
122: // Create a Canvas3D using the preferred configuration
123: Canvas3D canvas3d = new Canvas3D(config);
124:
125: // Create simple universe with view branch
126: univ = new SimpleUniverse(canvas3d);
127: BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,
128: 0.0, 0.0), 1000.0);
129:
130: // add mouse behaviors to the ViewingPlatform
131: ViewingPlatform viewingPlatform = univ.getViewingPlatform();
132:
133: PlatformGeometry pg = new PlatformGeometry();
134:
135: // Set up the ambient light
136: Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);
137: AmbientLight ambientLightNode = new AmbientLight(ambientColor);
138: ambientLightNode.setInfluencingBounds(bounds);
139: pg.addChild(ambientLightNode);
140:
141: // Set up the directional lights
142: Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
143: Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f);
144: Color3f light2Color = new Color3f(1.0f, 1.0f, 1.0f);
145: Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -1.0f);
146:
147: DirectionalLight light1 = new DirectionalLight(light1Color,
148: light1Direction);
149: light1.setInfluencingBounds(bounds);
150: pg.addChild(light1);
151:
152: DirectionalLight light2 = new DirectionalLight(light2Color,
153: light2Direction);
154: light2.setInfluencingBounds(bounds);
155: pg.addChild(light2);
156:
157: viewingPlatform.setPlatformGeometry(pg);
158:
159: // Ensure the entire model is in view
160: double fov = viewingPlatform.getViewers()[0].getView()
161: .getFieldOfView();
162: TransformGroup viewTG = viewingPlatform
163: .getViewPlatformTransform();
164: double distance = ViewUtils.setViewpoint(viewTG, scene
165: .getBounds(), fov, ViewUtils.Axis.POSITIVE_Z_AXIS);
166:
167: viewingPlatform.getViewers()[0].getView().setBackClipDistance(
168: distance * 1.25);
169:
170: Transform3D t3d = new Transform3D();
171: viewTG.getTransform(t3d);
172: System.out.println("Set tg " + t3d);
173:
174: OrbitBehavior orbit = new OrbitBehavior(canvas3d,
175: OrbitBehavior.REVERSE_ALL);
176: orbit.setSchedulingBounds(bounds);
177: viewingPlatform.setViewPlatformBehavior(orbit);
178:
179: return canvas3d;
180: }
181:
182: private void usage() {
183: // System.out.println(
184: // "Usage: java ObjLoad [-s] [-n] [-t] [-c degrees] <.obj file>");
185: // System.out.println(" -s Spin (no user interaction)");
186: // System.out.println(" -n No triangulation");
187: // System.out.println(" -t No stripification");
188: // System.out.println(
189: // " -c Set crease angle for normal generation (default is 60 without");
190: // System.out.println(
191: // " smoothing group info, otherwise 180 within smoothing groups)");
192: // System.exit(0);
193: } // End of usage
194:
195: /**
196: * Creates new form ObjLoad
197: */
198: public Viewer(String args[]) {
199: if (args.length != 0) {
200: for (int i = 0; i < args.length; i++) {
201: if (args[i].startsWith("-")) {
202: // if (args[i].equals("-s")) {
203: // spin = true;
204: // } else if (args[i].equals("-n")) {
205: // noTriangulate = true;
206: // } else if (args[i].equals("-t")) {
207: // noStripify = true;
208: // } else if (args[i].equals("-c")) {
209: // if (i < args.length - 1) {
210: // creaseAngle = (new Double(args[++i])).doubleValue();
211: // } else usage();
212: // } else {
213: // usage();
214: // }
215: } else {
216: // try {
217: // if ((args[i].indexOf("file:") == 0) ||
218: // (args[i].indexOf("http") == 0)) {
219: // filename = new URL(args[i]);
220: // } else if (args[i].charAt(0) != '/') {
221: // filename = new URL("file:./" + args[i]);
222: // } else {
223: // filename = new URL("file:" + args[i]);
224: // }
225: // } catch (MalformedURLException e) {
226: // System.err.println(e);
227: // System.exit(1);
228: // }
229: }
230: }
231: }
232:
233: if (filename == null) {
234: filename = "collada/samples/basic_samples/Cube/cube_triangulate.dae";
235: filename = "collada/samples/basic_samples/Duck/duck_triangulate.dae";
236:
237: if (filename == null) {
238: System.err.println("Must provide a file to load");
239: System.exit(1);
240: }
241: }
242:
243: // Initialize the GUI components
244: JPopupMenu.setDefaultLightWeightPopupEnabled(false);
245: ToolTipManager.sharedInstance().setLightWeightPopupEnabled(
246: false);
247: initComponents();
248:
249: // Create the content branch and add it to the universe
250: scene = createSceneGraph();
251:
252: // Create Canvas3D and SimpleUniverse; add canvas to drawing panel
253: Canvas3D c = createUniverse();
254: drawingPanel.add(c, java.awt.BorderLayout.CENTER);
255:
256: root = new BranchGroup();
257: root.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
258: root.setCapability(BranchGroup.ALLOW_CHILDREN_READ);
259: root.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
260: root.addChild(scene);
261: scene.setCapability(BranchGroup.ALLOW_DETACH);
262:
263: univ.addBranchGraph(root);
264: }
265:
266: // ----------------------------------------------------------------
267:
268: /** This method is called from within the constructor to
269: * initialize the form.
270: * WARNING: Do NOT modify this code. The content of this method is
271: * always regenerated by the Form Editor.
272: */
273: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
274: private void initComponents() {
275:
276: drawingPanel = new javax.swing.JPanel();
277: jMenuBar1 = new javax.swing.JMenuBar();
278: fileMenu = new javax.swing.JMenu();
279: loadMI = new javax.swing.JMenuItem();
280: exitMI = new javax.swing.JMenuItem();
281: View = new javax.swing.JMenu();
282: polygonFillMI = new javax.swing.JRadioButtonMenuItem();
283:
284: setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
285: setTitle("ObjLoad");
286:
287: drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
288: drawingPanel.setLayout(new java.awt.BorderLayout());
289: getContentPane()
290: .add(drawingPanel, java.awt.BorderLayout.CENTER);
291:
292: fileMenu.setText("File");
293:
294: loadMI.setText("Load...");
295: loadMI.setEnabled(false);
296: loadMI.addActionListener(new java.awt.event.ActionListener() {
297: public void actionPerformed(java.awt.event.ActionEvent evt) {
298: loadMIActionPerformed(evt);
299: }
300: });
301: fileMenu.add(loadMI);
302:
303: exitMI.setText("Exit");
304: exitMI.addActionListener(new java.awt.event.ActionListener() {
305: public void actionPerformed(java.awt.event.ActionEvent evt) {
306: exitMIActionPerformed(evt);
307: }
308: });
309: fileMenu.add(exitMI);
310:
311: jMenuBar1.add(fileMenu);
312:
313: View.setText("View");
314:
315: polygonFillMI.setSelected(true);
316: polygonFillMI.setText("Polygon Fill");
317: polygonFillMI
318: .setToolTipText("Select Filled or edge only rendering");
319: polygonFillMI
320: .addActionListener(new java.awt.event.ActionListener() {
321: public void actionPerformed(
322: java.awt.event.ActionEvent evt) {
323: polygonFillMIActionPerformed(evt);
324: }
325: });
326: View.add(polygonFillMI);
327:
328: jMenuBar1.add(View);
329:
330: setJMenuBar(jMenuBar1);
331:
332: pack();
333: }// </editor-fold>//GEN-END:initComponents
334:
335: private void loadMIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadMIActionPerformed
336: // TODO add your handling code here:
337: }//GEN-LAST:event_loadMIActionPerformed
338:
339: private void polygonFillMIActionPerformed(
340: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_polygonFillMIActionPerformed
341: // TODO add your handling code here:
342: int mode;
343:
344: if (polygonFillMI.isSelected()) {
345: mode = PolygonAttributes.POLYGON_FILL;
346: } else {
347: mode = PolygonAttributes.POLYGON_LINE;
348: }
349:
350: root.removeChild(scene);
351: ChangePolygonAttributes.setPolygonMode(scene, mode, true);
352: root.addChild(scene);
353: }//GEN-LAST:event_polygonFillMIActionPerformed
354:
355: private void exitMIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMIActionPerformed
356: System.exit(1);
357: }//GEN-LAST:event_exitMIActionPerformed
358:
359: /**
360: * @param args the command line arguments
361: */
362: public static void main(final String args[]) {
363: java.awt.EventQueue.invokeLater(new Runnable() {
364: public void run() {
365: Viewer viewer = new Viewer(args);
366: viewer.setVisible(true);
367: }
368: });
369: }
370:
371: // Variables declaration - do not modify//GEN-BEGIN:variables
372: private javax.swing.JMenu View;
373: private javax.swing.JPanel drawingPanel;
374: private javax.swing.JMenuItem exitMI;
375: private javax.swing.JMenu fileMenu;
376: private javax.swing.JMenuBar jMenuBar1;
377: private javax.swing.JMenuItem loadMI;
378: private javax.swing.JRadioButtonMenuItem polygonFillMI;
379: // End of variables declaration//GEN-END:variables
380:
381: }
|