001: /*
002: * $RCSfile: PickTest.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.2 $
041: * $Date: 2007/02/09 17:21:48 $
042: * $State: Exp $
043: */
044:
045: package org.jdesktop.j3d.examples.picking;
046:
047: import com.sun.j3d.utils.pickfast.behaviors.*;
048: import com.sun.j3d.utils.pickfast.*;
049:
050: import java.applet.Applet;
051: import java.awt.BorderLayout;
052: import java.awt.event.*;
053: import java.awt.Component;
054: import com.sun.j3d.utils.applet.MainFrame;
055: import com.sun.j3d.utils.universe.*;
056: import javax.media.j3d.*;
057: import javax.vecmath.*;
058: import java.awt.Point;
059: import javax.swing.*;
060: import javax.swing.border.BevelBorder;
061:
062: /**
063: * PickTest shows how to use the Picking utilities on various GeometryArray
064: * subclasses and Morph object.
065: * Type of Geometry : CompressedGeometry ( GullCG.java )
066: * IndexedQuadArray ( CubeIQA.java )
067: * TriangleArray ( TetrahedronTA.java )
068: * IndexedTriangleArray ( TetrahedronITA.java )
069: * TriangleFanArray ( OctahedronTFA.java )
070: * IndexedTriangleFanArray ( OctahedronITA.java )
071: * TriangleStripArray ( IcosahedronTFA.java )
072: * IndexedTriangleStripArray ( IcosahedronITA.java )
073: * PointArray( TetrahedronPA.java )
074: * LineArray( TetrahedronLA.java )
075: * IndexLineArray( TetrahedronILA.java )
076: * LineStripArray( TetrahedronLSA.java )
077: * IndexLineStripArray( TetrahedronILSA.java )
078: *
079: * Morph Object uses : QuadArray ( ColorCube.java, ColorPyramidDown.java,
080: * and ColorPyramidUp.java ).
081: */
082:
083: public class PickTest extends Applet implements ActionListener {
084:
085: private View view = null;
086: private QuadArray geomMorph[] = new QuadArray[3];
087: private Morph morph;
088:
089: private PickRotateBehavior behavior1;
090: private PickZoomBehavior behavior2;
091: private PickTranslateBehavior behavior3;
092:
093: private SimpleUniverse u = null;
094:
095: public BranchGroup createSceneGraph(Canvas3D canvas) {
096: // Create the root of the branch graph
097: BranchGroup objRoot = new BranchGroup();
098:
099: // Create a Transformgroup to scale all objects so they
100: // appear in the scene.
101: TransformGroup objScale = new TransformGroup();
102: Transform3D t3d = new Transform3D();
103: t3d.setScale(1.0);
104: objScale.setTransform(t3d);
105: objRoot.addChild(objScale);
106:
107: // Create a bunch of objects with a behavior and add them
108: // into the scene graph.
109:
110: int row, col;
111: int numRows = 4, numCols = 4;
112:
113: for (int i = 0; i < numRows; i++) {
114: double ypos = (double) (i - numRows / 2) * 0.45 + 0.25;
115: for (int j = 0; j < numCols; j++) {
116: double xpos = (double) (j - numCols / 2) * 0.45 + 0.25;
117: objScale.addChild(createObject(i * numCols + j, 0.1,
118: xpos, ypos));
119: }
120: }
121:
122: BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,
123: 0.0, 0.0), 100.0);
124:
125: // Add a light.
126: Color3f lColor = new Color3f(1.0f, 1.0f, 1.0f);
127: Vector3f lDir = new Vector3f(0.0f, 0.0f, -1.0f);
128:
129: DirectionalLight lgt = new DirectionalLight(lColor, lDir);
130: lgt.setInfluencingBounds(bounds);
131: objRoot.addChild(lgt);
132:
133: // Now create the Alpha object that controls the speed of the
134: // morphing operation.
135: Alpha morphAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE
136: | Alpha.DECREASING_ENABLE, 0, 0, 4000, 1000, 500, 4000,
137: 1000, 500);
138:
139: // Finally, create the morphing behavior
140: MorphingBehavior mBeh = new MorphingBehavior(morphAlpha, morph);
141: mBeh.setSchedulingBounds(bounds);
142: objRoot.addChild(mBeh);
143:
144: behavior1 = new PickRotateBehavior(objRoot, canvas, bounds);
145: objRoot.addChild(behavior1);
146:
147: behavior2 = new PickZoomBehavior(objRoot, canvas, bounds);
148: objRoot.addChild(behavior2);
149:
150: behavior3 = new PickTranslateBehavior(objRoot, canvas, bounds);
151: objRoot.addChild(behavior3);
152:
153: // Let Java 3D perform optimizations on this scene graph.
154: objRoot.compile();
155:
156: return objRoot;
157: }
158:
159: private Group createObject(int index, double scale, double xpos,
160: double ypos) {
161:
162: Shape3D shape = null;
163: Geometry geom = null;
164:
165: // Create a transform group node to scale and position the object.
166: Transform3D t = new Transform3D();
167: t.set(scale, new Vector3d(xpos, ypos, 0.0));
168: TransformGroup objTrans = new TransformGroup(t);
169: objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
170: objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
171: objTrans.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
172:
173: // Create a second transform group node and initialize it to the
174: // identity. Enable the TRANSFORM_WRITE capability so that
175: // our behavior code can modify it at runtime.
176: TransformGroup spinTg = new TransformGroup();
177: spinTg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
178: spinTg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
179: spinTg.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
180:
181: Appearance appearance = new Appearance();
182:
183: switch (index) {
184: case 0:
185: geom = new GullCG();
186: break;
187: case 1:
188: geom = new TetrahedronTA();
189: break;
190: case 2:
191: geom = new OctahedronTFA();
192: break;
193: case 3:
194: geom = new IcosahedronTSA();
195: break;
196: case 4:
197: geom = new CubeIQA();
198: break;
199: case 5:
200: geom = new TetrahedronITA();
201: break;
202: case 6:
203: geom = new OctahedronITFA();
204: break;
205: case 7:
206: geom = new IcosahedronITSA();
207: break;
208: case 8:
209: geomMorph[0] = new ColorPyramidUp();
210: geomMorph[1] = new ColorCube();
211: geomMorph[2] = new ColorPyramidDown();
212: break;
213: case 9:
214: geom = new TetrahedronLA();
215: break;
216: case 10:
217: geom = new TetrahedronILA();
218: break;
219: case 11:
220: geom = new TetrahedronLSA();
221: break;
222: case 12:
223: geom = new TetrahedronILSA();
224: break;
225: case 13:
226: geom = new TetrahedronPA();
227: break;
228: case 14:
229: geom = new TetrahedronIPA();
230: break;
231: // TODO: other geo types, Text3D?
232: case 15:
233: geom = new TetrahedronTA();
234: break;
235: }
236:
237: Material m = new Material();
238:
239: if (index == 8) {
240: m.setLightingEnable(false);
241: appearance.setMaterial(m);
242: morph = new Morph((GeometryArray[]) geomMorph, appearance);
243: morph.setCapability(Morph.ALLOW_WEIGHTS_READ);
244: morph.setCapability(Morph.ALLOW_WEIGHTS_WRITE);
245: spinTg.addChild(morph);
246: } else {
247: // Geometry picking require this to be set.
248: if (index == 0)
249: m.setLightingEnable(true);
250: else
251: m.setLightingEnable(false);
252: appearance.setMaterial(m);
253:
254: if ((index == 13) || (index == 14)) {
255: PointAttributes pa = new PointAttributes();
256: pa.setPointSize(4.0f);
257: appearance.setPointAttributes(pa);
258: }
259:
260: shape = new Shape3D(geom, appearance);
261: shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
262: shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
263: shape.setCapability(Shape3D.ENABLE_PICK_REPORTING);
264: spinTg.addChild(shape);
265: }
266:
267: // add it to the scene graph.
268: objTrans.addChild(spinTg);
269:
270: return objTrans;
271: }
272:
273: private void setPickMode(int mode) {
274: behavior1.setMode(mode);
275: behavior2.setMode(mode);
276: behavior3.setMode(mode);
277: }
278:
279: private void setPickTolerance(float tolerance) {
280: behavior1.setTolerance(tolerance);
281: behavior2.setTolerance(tolerance);
282: behavior3.setTolerance(tolerance);
283: }
284:
285: private void setViewMode(int mode) {
286: view.setProjectionPolicy(mode);
287: }
288:
289: // GUI stuff
290:
291: String pickModeString = new String("Pick Mode");
292: String boundsString = new String("BOUNDS");
293: String geometryString = new String("GEOMETRY");
294: String toleranceString = new String("Pick Tolerance");
295: String tolerance0String = new String("0");
296: String tolerance2String = new String("2");
297: String tolerance4String = new String("4");
298: String tolerance8String = new String("8");
299: String viewModeString = new String("View Mode");
300: String perspectiveString = new String("Perspective");
301: String parallelString = new String("Parallel");
302:
303: private void addRadioButton(JPanel panel, ButtonGroup bg,
304: String ownerName, String buttonName, boolean selected) {
305: JRadioButton item;
306: item = new JRadioButton(buttonName);
307: item.setName(ownerName);
308: item.addActionListener(this );
309: if (selected) {
310: item.setSelected(true);
311: }
312: panel.add(item);
313: bg.add(item);
314: }
315:
316: private void setupGUI(JPanel panel) {
317: ButtonGroup bg;
318:
319: panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
320: panel.setBorder(new BevelBorder(BevelBorder.RAISED));
321:
322: panel.add(new JLabel(pickModeString));
323: bg = new ButtonGroup();
324: addRadioButton(panel, bg, pickModeString, boundsString, true);
325: addRadioButton(panel, bg, pickModeString, geometryString, false);
326:
327: panel.add(new JLabel(toleranceString));
328: bg = new ButtonGroup();
329: addRadioButton(panel, bg, toleranceString, tolerance0String,
330: false);
331: addRadioButton(panel, bg, toleranceString, tolerance2String,
332: true);
333: addRadioButton(panel, bg, toleranceString, tolerance4String,
334: false);
335: addRadioButton(panel, bg, toleranceString, tolerance8String,
336: false);
337:
338: panel.add(new JLabel(viewModeString));
339: bg = new ButtonGroup();
340: addRadioButton(panel, bg, viewModeString, perspectiveString,
341: true);
342: addRadioButton(panel, bg, viewModeString, parallelString, false);
343:
344: }
345:
346: public void actionPerformed(ActionEvent e) {
347: String name = ((Component) e.getSource()).getName();
348: String value = e.getActionCommand();
349: //System.out.println("action: name = " + name + " value = " + value);
350: if (name == pickModeString) {
351: if (value == boundsString) {
352: setPickMode(PickInfo.PICK_BOUNDS);
353: } else if (value == geometryString) {
354: setPickMode(PickInfo.PICK_GEOMETRY);
355: } else {
356: System.out.println("Unknown pick mode: " + value);
357: }
358: } else if (name == toleranceString) {
359: if (value == tolerance0String) {
360: setPickTolerance(0.0f);
361: } else if (value == tolerance2String) {
362: setPickTolerance(2.0f);
363: } else if (value == tolerance4String) {
364: setPickTolerance(4.0f);
365: } else if (value == tolerance8String) {
366: setPickTolerance(8.0f);
367: } else {
368: System.out.println("Unknown tolerance: " + value);
369: }
370: } else if (name == viewModeString) {
371: if (value == perspectiveString) {
372: setViewMode(View.PERSPECTIVE_PROJECTION);
373: } else if (value == parallelString) {
374: setViewMode(View.PARALLEL_PROJECTION);
375: }
376: } else {
377: System.out.println("Unknown action name: " + name);
378: }
379: }
380:
381: public PickTest() {
382: }
383:
384: public void init() {
385: setLayout(new BorderLayout());
386: Canvas3D c = new Canvas3D(SimpleUniverse
387: .getPreferredConfiguration());
388: add("Center", c);
389:
390: JPanel guiPanel = new JPanel();
391: setupGUI(guiPanel);
392: add(guiPanel, BorderLayout.EAST);
393:
394: // Create a scene and attach it to the virtual universe
395: BranchGroup scene = createSceneGraph(c);
396: u = new SimpleUniverse(c);
397:
398: // This will move the ViewPlatform back a bit so the
399: // objects in the scene can be viewed.
400: u.getViewingPlatform().setNominalViewingTransform();
401: view = u.getViewer().getView();
402:
403: u.addBranchGraph(scene);
404: }
405:
406: public void destroy() {
407: u.cleanup();
408: }
409:
410: public static void main(String argv[]) {
411:
412: BranchGroup group;
413:
414: new MainFrame(new PickTest(), 750, 550);
415: }
416: }
|