001: /*
002: * $Header: /cvs/j3dfly/J3dEditor/src/org/jdesktop/j3dedit/locationeditor/ViewFrame.java,v 1.1 2005/04/20 22:20:35 paulby Exp $
003: *
004: * Sun Public License Notice
005: *
006: * The contents of this file are subject to the Sun Public License Version
007: * 1.0 (the "License"). You may not use this file except in compliance with
008: * the License. A copy of the License is available at http://www.sun.com/
009: *
010: * The Original Code is the Java 3D(tm) Scene Graph Editor.
011: * The Initial Developer of the Original Code is Paul Byrne.
012: * Portions created by Paul Byrne are Copyright (C) 2002.
013: * All Rights Reserved.
014: *
015: * Contributor(s): Paul Byrne.
016: *
017: **/
018: package org.jdesktop.j3dedit.locationeditor;
019:
020: import java.awt.event.KeyEvent;
021: import javax.media.j3d.Canvas3D;
022: import javax.media.j3d.BoundingSphere;
023: import javax.media.j3d.Node;
024: import javax.media.j3d.Transform3D;
025: import javax.media.j3d.TransformGroup;
026: import javax.vecmath.Point3d;
027: import javax.vecmath.Point3f;
028: import javax.vecmath.Vector3d;
029: import javax.vecmath.Vector3f;
030: import javax.vecmath.Matrix3d;
031: import com.sun.j3d.utils.universe.ViewingPlatform;
032: import com.sun.j3d.utils.universe.Viewer;
033: import com.sun.j3d.utils.picking.PickResult;
034:
035: import org.jdesktop.j3dedit.scenegrapheditor.nodeeditors.NodeEditorPanel;
036: import org.jdesktop.j3dedit.scenegrapheditor.visualtools.PointHighlightShape3D;
037: import org.jdesktop.j3dedit.scenegrapheditor.visualtools.PointHighlightControl;
038: import org.jdesktop.j3dedit.scenegrapheditor.visualtools.KBRotPosScaleSplinePathInterpolatorVisualTool;
039: import org.jdesktop.j3dedit.scenegrapheditor.VisualToolManager;
040: import org.jdesktop.j3dfly.utils.vpbehaviors.ViewUtils;
041: import org.jdesktop.j3dfly.utils.developmenttools.DevelopmentLocale;
042: import org.jdesktop.j3dfly.SelectionListener;
043:
044: /**
045: *
046: * @author paulby
047: * @version
048: */
049: public class ViewFrame extends javax.swing.JFrame implements
050: SelectionListener, org.jdesktop.j3dfly.event.FlyEventListener,
051: java.awt.event.KeyListener, java.awt.event.MouseListener {
052:
053: private ViewFrameSelectionControl selectionControl;
054: private Transform3D imagePlateToVworld = new Transform3D();
055: private Transform3D vWorldToPick = new Transform3D();
056: private Transform3D vWorldToImagePlate = new Transform3D();
057: private Transform3D pickToVworld = new Transform3D();
058:
059: private Vector3d imagePlateAdjust = new Vector3d();
060:
061: private TransformGroup viewTG;
062: private Transform3D viewTrans;
063: private ViewingPlatform viewingPlatform;
064: private DevelopmentLocale locale;
065:
066: private Canvas3D canvas;
067:
068: private Point3d previousCursorIP = null; // Cursor position in ImagePlate
069: // for last event
070:
071: /**
072: * Zoom the view out by zoomStep
073: */
074: private static final int ZOOM_OUT = 1;
075:
076: /**
077: * Zoom the view in by zoomStep
078: */
079: private static final int ZOOM_IN = 2;
080:
081: /**
082: * Zoom the view to the value of zoomStep
083: */
084: private static final int ZOOM_TO = 3;
085:
086: /**
087: * CHange zoom center
088: */
089: private static final int ZOOM_CENTER = 4;
090:
091: private int pressX;
092: private int pressY;
093: private Viewer viewer;
094:
095: private PointHighlightControl.PointHighlight pickPoint = null;
096:
097: private ViewFrameGroup viewGroup = null;
098:
099: // TODO Create a Weak reference for the viewingPlatform so that it can be
100: // GC'ed if the system needs it.
101:
102: /** Creates new form ViewFrame */
103: public ViewFrame(java.awt.GraphicsConfiguration config,
104: DevelopmentLocale locale, int axis, ViewFrameGroup viewGroup) {
105: this .locale = locale;
106: this .viewGroup = viewGroup;
107: initComponents();
108: jPopupMenu1.setDefaultLightWeightPopupEnabled(false);
109:
110: canvas = new Canvas3D(config);
111: canvas.addKeyListener(this );
112: canvas.addMouseListener(this );
113: viewer = new Viewer(canvas);
114: viewingPlatform = new ViewingPlatform();
115: viewingPlatform.setCapability(ViewingPlatform.ALLOW_DETACH);
116: viewer.setViewingPlatform(viewingPlatform);
117:
118: viewTG = viewingPlatform.getViewPlatformTransform();
119: viewTrans = new Transform3D();
120:
121: selectionControl = new ViewFrameSelectionControl(locale, canvas);
122: selectionControl.pushSelectionListener(this ,
123: ViewFrameSelectionControl.MOUSE_PRESSED);
124:
125: BoundingSphere worldBounds = new BoundingSphere(
126: new javax.vecmath.Point3d(), 2d);
127: ViewUtils.setViewpoint(viewer.getViewingPlatform()
128: .getViewPlatformTransform(), worldBounds, viewer
129: .getView().getFieldOfView(), axis);
130: this .getContentPane().add(canvas, java.awt.BorderLayout.CENTER);
131:
132: if (viewGroup != null)
133: viewGroup.addListener(this , ViewZoomEvent.class);
134:
135: pack();
136: }
137:
138: public void setActive(boolean active) {
139: if (active)
140: locale.getHiddenBranchGraph().addChild(viewingPlatform);
141: else
142: locale.getHiddenBranchGraph().removeChild(viewingPlatform);
143: }
144:
145: /** This method is called from within the constructor to
146: * initialize the form.
147: * WARNING: Do NOT modify this code. The content of this method is
148: * always regenerated by the FormEditor.
149: */
150: private void initComponents() {//GEN-BEGIN:initComponents
151: jPopupMenu1 = new javax.swing.JPopupMenu();
152: zoomInMI = new javax.swing.JMenuItem();
153: zoomOutMI = new javax.swing.JMenuItem();
154: showAllMI = new javax.swing.JMenuItem();
155: jSeparator1 = new javax.swing.JSeparator();
156: gotoMI = new javax.swing.JMenuItem();
157:
158: zoomInMI.setText("Zoom In");
159: zoomInMI.addActionListener(new java.awt.event.ActionListener() {
160: public void actionPerformed(java.awt.event.ActionEvent evt) {
161: zoomInMIActionPerformed(evt);
162: }
163: });
164:
165: jPopupMenu1.add(zoomInMI);
166: zoomOutMI.setText("Zoom Out");
167: zoomOutMI
168: .addActionListener(new java.awt.event.ActionListener() {
169: public void actionPerformed(
170: java.awt.event.ActionEvent evt) {
171: zoomOutMIActionPerformed(evt);
172: }
173: });
174:
175: jPopupMenu1.add(zoomOutMI);
176: showAllMI.setText("Show All");
177: showAllMI
178: .addActionListener(new java.awt.event.ActionListener() {
179: public void actionPerformed(
180: java.awt.event.ActionEvent evt) {
181: showAllMIActionPerformed(evt);
182: }
183: });
184:
185: jPopupMenu1.add(showAllMI);
186: jPopupMenu1.add(jSeparator1);
187: gotoMI.setText("Goto");
188: gotoMI
189: .setToolTipText("Move the point under the cursor to the center of the view");
190: gotoMI.addActionListener(new java.awt.event.ActionListener() {
191: public void actionPerformed(java.awt.event.ActionEvent evt) {
192: gotoMIActionPerformed(evt);
193: }
194: });
195:
196: jPopupMenu1.add(gotoMI);
197:
198: addWindowListener(new java.awt.event.WindowAdapter() {
199: public void windowClosing(java.awt.event.WindowEvent evt) {
200: exitForm(evt);
201: }
202: });
203:
204: }//GEN-END:initComponents
205:
206: private void showAllMIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showAllMIActionPerformed
207: // Add your handling code here:
208: KBRotPosScaleSplinePathInterpolatorVisualTool p = (KBRotPosScaleSplinePathInterpolatorVisualTool) VisualToolManager
209: .getManager()
210: .getVisualTool(
211: KBRotPosScaleSplinePathInterpolatorVisualTool.class);
212: System.out.println("***************** " + p);
213:
214: if (p == null)
215: return;
216:
217: BoundingSphere bounds = (BoundingSphere) p.getBounds();
218: System.out.println(bounds);
219:
220: double fieldOfView = viewer.getView().getFieldOfView();
221: if (fieldOfView == 0)
222: fieldOfView = Math.toRadians(60);
223: double distance = bounds.getRadius()
224: / Math.tan(fieldOfView / 2.0);
225:
226: System.out.println(distance);
227: Point3d center = new Point3d();
228: bounds.getCenter(center);
229:
230: if (viewGroup != null)
231: viewGroup.postEvent(new ViewZoomEvent(ZOOM_CENTER,
232: distance, center));
233: }//GEN-LAST:event_showAllMIActionPerformed
234:
235: private void gotoMIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_gotoMIActionPerformed
236: // Add your handling code here:
237: System.out.println("Goto not implemented");
238: }//GEN-LAST:event_gotoMIActionPerformed
239:
240: private void zoomInMIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomInMIActionPerformed
241: // Add your handling code here:
242: if (viewGroup != null)
243: viewGroup.postEvent(new ViewZoomEvent(ZOOM_IN));
244: }//GEN-LAST:event_zoomInMIActionPerformed
245:
246: private void zoomOutMIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomOutMIActionPerformed
247: // Add your handling code here:
248: if (viewGroup != null)
249: viewGroup.postEvent(new ViewZoomEvent(ZOOM_OUT));
250: }//GEN-LAST:event_zoomOutMIActionPerformed
251:
252: /** Exit the Application */
253: private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
254: System.exit(0);
255: }//GEN-LAST:event_exitForm
256:
257: private void processPick(int mouseX, int mouseY,
258: PointHighlightShape3D node, PickResult pick) {
259: pickPoint = node.getPointHighlight(pick.getSceneGraphPath());
260: pickPoint.setSelected(true);
261: }
262:
263: /**
264: * Invoked when the mouse has been clicked
265: */
266: public void mouseClicked(final java.awt.event.MouseEvent evt,
267: PickResult pick) {
268: if (pick != null) {
269: Node node = pick.getObject();
270: if (node instanceof PointHighlightShape3D) {
271: processPick(evt.getX(), evt.getY(),
272: (PointHighlightShape3D) node, pick);
273: } else {
274: System.out.println(node);
275: pickPoint = null;
276: }
277: } else {
278: if (pickPoint != null) {
279: pickPoint.setSelected(false);
280: pickPoint = null;
281: }
282: }
283: }
284:
285: /**
286: * Invoked when the mouse has been pressed
287: */
288: public void mousePressed(final java.awt.event.MouseEvent evt,
289: PickResult pick) {
290: if (pick != null) {
291: Node node = pick.getObject();
292: if (node instanceof PointHighlightShape3D) {
293: processPick(evt.getX(), evt.getY(),
294: (PointHighlightShape3D) node, pick);
295: } else {
296: System.out.println(node);
297: pickPoint = null;
298: }
299:
300: }
301: previousCursorIP = new Point3d();
302: canvas.getPixelLocationInImagePlate(evt.getX(), evt.getY(),
303: previousCursorIP);
304:
305: }
306:
307: /**
308: * Invoked when the mouse has been released
309: */
310: public void mouseReleased(final java.awt.event.MouseEvent evt,
311: PickResult pick) {
312: previousCursorIP = null;
313: }
314:
315: /**
316: * Invoked when the mouse is being moved
317: */
318: public void mouseMoved(final java.awt.event.MouseEvent evt,
319: PickResult pick) {
320: }
321:
322: /**
323: * Invoked when the mouse is being dragged
324: */
325: public void mouseDragged(final java.awt.event.MouseEvent evt,
326: PickResult pick) {
327: if (pickPoint != null)
328: dragPoint(evt);
329: else
330: dragCanvas(evt);
331: }
332:
333: /**
334: * Drag the canvas
335: *
336: * This is implemented by efectively dragging a point half way
337: * between the front and back clip plans.
338: */
339: private void dragCanvas(final java.awt.event.MouseEvent evt) {
340: //System.out.println("Drag Canvas");
341: Point3d cursor = new Point3d();
342: canvas.getPixelLocationInImagePlate(evt.getX(), evt.getY(),
343: cursor);
344:
345: canvas.getImagePlateToVworld(imagePlateToVworld);
346: vWorldToImagePlate = new Transform3D(imagePlateToVworld);
347: vWorldToImagePlate.invert();
348:
349: cursor.sub(previousCursorIP);
350:
351: double dragCenter = viewer.getView().getBackClipDistance()
352: - viewer.getView().getFrontClipDistance();
353:
354: Point3d loc = new Point3d(0, 0, dragCenter);
355:
356: //System.out.println("Point "+loc);
357: vWorldToImagePlate.transform(loc);
358: //System.out.println("Point in IP "+loc );
359:
360: Point3d eye = new Point3d();
361: canvas.getCenterEyeInImagePlate(eye);
362: //System.out.println("Eye in IP "+eye );
363:
364: double eyeToPoint = loc.z - eye.z;
365:
366: double eyeToCursor = eye.z;
367:
368: //System.out.println( "EyeToPoint "+eyeToPoint );
369: //System.out.println( "EyeToCursor "+eyeToCursor );
370:
371: Point3d newPoint = new Point3d((cursor.x * eyeToPoint)
372: / eyeToCursor, (cursor.y * eyeToPoint) / eyeToCursor, 0);
373:
374: //System.out.println( "Point delta in IP "+newPoint );
375:
376: loc.sub(newPoint);
377: imagePlateToVworld.transform(loc);
378: //System.out.println( "Point in Vworld "+loc);
379:
380: loc.z -= dragCenter;
381:
382: //System.out.println(loc);
383:
384: viewTG.getTransform(viewTrans);
385: Vector3d pos = new Vector3d();
386: viewTrans.get(pos);
387: pos.sub(loc);
388: viewTrans.setTranslation(pos);
389: viewTG.setTransform(viewTrans);
390:
391: canvas.getPixelLocationInImagePlate(evt.getX(), evt.getY(),
392: previousCursorIP);
393: }
394:
395: private void dragPoint(final java.awt.event.MouseEvent evt) {
396: // TODO tidy up to remove GC
397: Point3d cursor = new Point3d();
398: canvas.getPixelLocationInImagePlate(evt.getX(), evt.getY(),
399: cursor);
400:
401: canvas.getImagePlateToVworld(imagePlateToVworld);
402: vWorldToImagePlate = new Transform3D(imagePlateToVworld);
403: vWorldToImagePlate.invert();
404:
405: cursor.sub(previousCursorIP);
406:
407: Point3d loc = new Point3d();
408: pickPoint.getPosition(loc);
409:
410: //System.out.println("Point "+loc);
411: vWorldToImagePlate.transform(loc);
412: //System.out.println("Point in IP "+loc );
413:
414: Point3d eye = new Point3d();
415: canvas.getCenterEyeInImagePlate(eye);
416: //System.out.println("Eye in IP "+eye );
417:
418: double eyeToPoint = loc.z - eye.z;
419:
420: double eyeToCursor = eye.z;
421:
422: //System.out.println( "EyeToPoint "+eyeToPoint );
423: //System.out.println( "EyeToCursor "+eyeToCursor );
424:
425: Point3d newPoint = new Point3d((cursor.x * eyeToPoint)
426: / eyeToCursor, (cursor.y * eyeToPoint) / eyeToCursor, 0);
427:
428: //System.out.println( "Point delta in IP "+newPoint );
429:
430: loc.sub(newPoint);
431: imagePlateToVworld.transform(loc);
432: //System.out.println( "Point in Vworld "+loc);
433:
434: //System.out.println("Drag point "+loc);
435:
436: //System.out.println();
437: if (pickPoint != null)
438: pickPoint.movePoint(new Point3f(loc));
439:
440: canvas.getPixelLocationInImagePlate(evt.getX(), evt.getY(),
441: previousCursorIP);
442: }
443:
444: /**
445: * @param direction must be one of ZOOM_IN or ZOOM_OUT
446: */
447: private void zoomView(int direction, Point3d zoomCenter,
448: double zoomStep) {
449: viewTG.getTransform(viewTrans);
450: Point3d step = new Point3d();
451:
452: switch (direction) {
453: case ZOOM_IN:
454: //System.out.println("Zoom in");
455: step.z = -zoomStep;
456: break;
457: case ZOOM_OUT:
458: //System.out.println("Zoom out");
459: step.z = zoomStep;
460: break;
461: case ZOOM_TO:
462: step.z = zoomStep;
463: break;
464: case ZOOM_CENTER:
465: step.z = zoomStep;
466: break;
467: }
468:
469: Vector3d v3d = new Vector3d();
470: Matrix3d m3d = new Matrix3d();
471:
472: viewTrans.get(m3d, v3d);
473:
474: System.out.println("Current Pos " + v3d);
475:
476: if (direction == ZOOM_TO) {
477: Vector3d mask = new Vector3d(1, 1, 0);
478:
479: m3d.transform(mask);
480: m3d.transform(step);
481:
482: v3d.x *= mask.x;
483: v3d.y *= mask.y;
484: v3d.z *= mask.z;
485: System.out.println("Masked " + v3d);
486: System.out.println("Step " + step);
487: v3d.add(step);
488:
489: System.out.println("New Pos " + v3d);
490: } else if (direction == ZOOM_CENTER) {
491: m3d.transform(step);
492: v3d.set(zoomCenter);
493: //v3d.add( step );
494:
495: System.out.println("New Pos " + v3d);
496:
497: } else {
498: m3d.transform(step);
499: v3d.add(step);
500: }
501:
502: //System.out.println("Clip "+v3d.z+" "+viewer.getView().getBackClipDistance() );
503: if (Math.abs(v3d.z) > viewer.getView().getBackClipDistance()) {
504: viewer.getView().setBackClipDistance(
505: Math.abs(v3d.z) * 1.001);
506: }
507:
508: viewTrans.set(m3d, v3d, 1);
509:
510: viewTG.setTransform(viewTrans);
511: }
512:
513: public void keyPressed(java.awt.event.KeyEvent keyEvent) {
514: System.out.println(keyEvent);
515: if (keyEvent.getKeyCode() == KeyEvent.VK_COMMA
516: && viewGroup != null)
517: viewGroup.postEvent(new ViewZoomEvent(ZOOM_OUT));
518: else if (keyEvent.getKeyCode() == KeyEvent.VK_STOP
519: && viewGroup != null)
520: viewGroup.postEvent(new ViewZoomEvent(ZOOM_IN));
521: }
522:
523: public void keyReleased(java.awt.event.KeyEvent keyEvent) {
524: }
525:
526: public void keyTyped(java.awt.event.KeyEvent keyEvent) {
527: }
528:
529: public void mouseExited(java.awt.event.MouseEvent mouseEvent) {
530: }
531:
532: public void mouseReleased(java.awt.event.MouseEvent mouseEvent) {
533: }
534:
535: public void mousePressed(java.awt.event.MouseEvent mouseEvent) {
536: if (mouseEvent.isPopupTrigger())
537: jPopupMenu1
538: .show(this , mouseEvent.getX(), mouseEvent.getY());
539: }
540:
541: public void mouseClicked(java.awt.event.MouseEvent mouseEvent) {
542: }
543:
544: public void mouseEntered(java.awt.event.MouseEvent mouseEvent) {
545: }
546:
547: /**
548: * Called by EventProcessor when an event occurs for which this
549: * listener has registered interest
550: */
551: public void processFlyEvent(org.jdesktop.j3dfly.event.FlyEvent evt) {
552: if (evt instanceof ViewZoomEvent) {
553: ViewZoomEvent vze = (ViewZoomEvent) evt;
554: zoomView(vze.getZoomDirection(), vze.getZoomCenter(), vze
555: .getZoomStep());
556: }
557: }
558:
559: // Variables declaration - do not modify//GEN-BEGIN:variables
560: private javax.swing.JMenuItem gotoMI;
561: private javax.swing.JSeparator jSeparator1;
562: private javax.swing.JMenuItem zoomInMI;
563: private javax.swing.JPopupMenu jPopupMenu1;
564: private javax.swing.JMenuItem zoomOutMI;
565: private javax.swing.JMenuItem showAllMI;
566:
567: // End of variables declaration//GEN-END:variables
568:
569: public class ViewZoomEvent extends
570: org.jdesktop.j3dfly.event.FlyEvent {
571:
572: /** Holds value of property zoomDirection. */
573: private int zoomDirection;
574:
575: /**
576: * The size of the zoom
577: */
578: private double zoomStep;
579:
580: private Point3d zoomCenter = null;
581:
582: /** Creates new ViewZoomEvent
583: *
584: * zoomDirection should be either ViewFrame.ZOOM_IN, or ViewFrame.ZOOM_OUT
585: */
586: public ViewZoomEvent(int zoomMode, double zoomStep) {
587: this .zoomDirection = zoomMode;
588: this .zoomStep = zoomStep;
589: }
590:
591: public ViewZoomEvent(int zoomMode, double zoomDistance,
592: Point3d zoomCenter) {
593: this .zoomDirection = zoomMode;
594: this .zoomStep = zoomDistance;
595: this .zoomCenter = new Point3d(zoomCenter);
596: }
597:
598: /** Creates new ViewZoomEvent
599: *
600: * zoomStep defaults to 5
601: *
602: * zoomDirection should be either ViewFrame.ZOOM_IN, or ViewFrame.ZOOM_OUT
603: */
604: public ViewZoomEvent(int zoomMode) {
605: this (zoomMode, 5);
606: }
607:
608: /** Getter for property zoomDirection.
609: * @return Value of property zoomDirection.
610: */
611: public int getZoomDirection() {
612: return zoomDirection;
613: }
614:
615: /**
616: * Get the distance of the zoom step
617: */
618: public double getZoomStep() {
619: return zoomStep;
620: }
621:
622: public Point3d getZoomCenter() {
623: return zoomCenter;
624: }
625: }
626: }
|