001: /*
002: * Copyright (c) 2002 Silvere Martin-Michiellot All Rights Reserved.
003: *
004: * Silvere Martin-Michiellot grants you ("Licensee") a non-exclusive,
005: * royalty free, license to use, modify and redistribute this
006: * software in source and binary code form,
007: * provided that i) this copyright notice and license appear on all copies of
008: * the software; and ii) Licensee does not utilize the software in a manner
009: * which is disparaging to Silvere Martin-Michiellot.
010: *
011: * This software is provided "AS IS," without a warranty of any kind. ALL
012: * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
013: * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
014: * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. Silvere Martin-Michiellot
015: * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
016: * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
017: * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
018: * Silvere Martin-Michiellot OR ITS LICENSORS BE LIABLE
019: * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
020: * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
021: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
022: * OR INABILITY TO USE SOFTWARE, EVEN IF Silvere Martin-Michiellot HAS BEEN
023: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
024: *
025: * This software is not designed or intended for use in on-line control of
026: * aircraft, air traffic, aircraft navigation or aircraft communications; or in
027: * the design, construction, operation or maintenance of any nuclear
028: * facility. Licensee represents and warrants that it will not use or
029: * redistribute the Software for such purposes.
030: *
031: */
032:
033: // This code is reimplemented after the package edu.columbia.cs.cgui.j3d from Blaine Bell and is Copyright 2001 Columbia University, All Rights Reserved.
034: // Site ?
035: // Email blaine@cs.columbia.edu
036:
037: package com.db.layers.overlay;
038:
039: import javax.media.j3d.*;
040: import java.awt.*;
041: import javax.vecmath.*;
042: import java.util.*;
043:
044: /** This class provides the ability to place scenegraph objects relative to the Java3D Canvas3D.
045: * The implementation places a TransformGroup below the parent of the ViewPlatform, and
046: * reads all of the parameters in the View Model to determine the transformation from the
047: * ViewPlatform coordinate system to the pixel coordinate system. The origin of the Overlay Group
048: * is placed in the bottom left hand corner of the Canvas3D. It also allows you to place
049: * objects in specified Z.
050: * <p>
051: * This supports most (if not all) of the non-headtracking parts of the ViewModel. Currently,
052: * Java3D does not support Overlaying in a head-tracked View Model settings because the
053: * values of the Sensors get read AFTER the WakeUpOnElapsedFrame behaviors are run, but
054: * before the next frame is rendered. This is currently under inquiry with the Sun Java3D team,
055: * and hopefully will be fixed in the near future.
056: * <p>
057: * Also, when the Canvas3D is moved on the screen, the ImagePlate changes with respect to the
058: * ViewPlatform. These events (Window Move and Resize) are captured by AWT events, and therefore
059: * since their is a lag time/syncronization error between Java3D and AWT, this produces nasty
060: * jitter when these events happen. Better to not move/resize the window when possible.
061: *
062: * @author Blaine Bell
063: * @since JDK1.1
064: * @version 1.0
065: *
066: **/
067: public class OverlayGroup extends Object {
068:
069: FixedCanvas3D _canvas = null;
070: View _view = null;
071: Group _group = null;
072: static Vector allOverlayGroups = new Vector();
073: TransformGroup tg = new TransformGroup();
074: boolean setup = false;
075: boolean onNearClippingPlane = false, onNearSet = false;
076:
077: public OverlayGroup() {
078:
079: allOverlayGroups.add(this );
080:
081: }
082:
083: /** determines if you want to place the overlaygroup on the Near Clipping plane **/
084: public void setOnNearClippingPlane(boolean b) {
085:
086: onNearClippingPlane = b;
087: if (b) {
088: onNearSet = false;
089: }
090:
091: }
092:
093: /** Setups this OverlayGroup. Note: This needs to be called in order for the overlaygroup to
094: * work properly. Should only be called once.
095: * @param c The FixedCanvas3D that needs to be used in order for this to work properly
096: * @param groupAboveViewPlatform node directly above the ViewPlatform
097: * @param overlayAnchor the group node that is placed in the overlayplane/pixel coordinates
098: */
099: public void setupOverlayGroup(FixedCanvas3D c,
100: Group groupAboveViewPlatform, Group overlayAnchor) {
101:
102: _canvas = c;
103: _view = _canvas.getView();
104: _group = groupAboveViewPlatform;
105: setup = true;
106: if (!_group.isLive()) {
107: _group.setCapability(Group.ALLOW_CHILDREN_WRITE);
108: _group.setCapability(Group.ALLOW_CHILDREN_EXTEND);
109: }
110: if (!tg.isLive()) {
111: tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
112: tg.setCapability(Group.ALLOW_CHILDREN_WRITE);
113: }
114: tg.addChild(overlayAnchor);
115: BranchGroup bg = new BranchGroup();
116: bg.addChild(tg);
117: _group.addChild(bg);
118:
119: }
120:
121: Dimension screenSize = new Dimension(), canvSize = new Dimension();
122: /* from imageplane */
123: double zdist = 0.;
124:
125: static public void updateAllZValues() {
126:
127: for (Enumeration e = allOverlayGroups.elements(); e
128: .hasMoreElements();) {
129: ((OverlayGroup) e.nextElement()).updatePlacement();
130: }
131:
132: }
133:
134: /** Allows the Z value to change.
135: * @param z z-value in image-plate coordinates. Negative Z is typically further away
136: * from the eyepoint
137: */
138: public void updateZValue(double z) {
139:
140: zdist = z;
141: if (!onNearSet) {
142: if (setup) {
143: updatePlacement();
144: }
145: }
146:
147: }
148:
149: /** This function must be called once the View Model is set up properly
150: * in order for the overlaygroup to work. If any parameters of the View Model Changes,
151: * or the Z value is changed, this needs to be called again.
152: */
153: public void updatePlacement() {
154:
155: _canvas.refreshAllVariables();
156: if (onNearClippingPlane) {
157: /** This value is dependent on hardware/difference in clipping values
158: between front and back clipping planes **/
159: zdist = _canvas.computeFrontClipValueInImagePlate() - .0001;
160: onNearSet = true;
161: }
162: Transform3D t = new Transform3D(), t2 = new Transform3D(), t3 = new Transform3D();
163: Screen3D screen = _canvas.getScreen3D();
164: Point loconscreen = _canvas.getLocationOnScreen();
165: Point3d eyepoint = new Point3d();
166: screen.getSize(screenSize);
167: _canvas.getSize(canvSize);
168: _canvas.getCenterEyeInImagePlate(eyepoint);
169: _canvas.getViewPlatformToImagePlate(t);
170: double imagePlateScale = t.getScale();
171: Point3d screenOrigin = new Point3d();
172:
173: /* Translating eyepoint to origin */
174: t2.set(new Vector3d(eyepoint));
175: t.mul(t2);
176: t3.setScale((eyepoint.z - zdist) / eyepoint.z);
177: t.mul(t3);
178:
179: t2.set(new Vector3d(-eyepoint.x, -eyepoint.y, -eyepoint.z));
180: t.mul(t2);
181:
182: _canvas.getPixelLocationInImagePlate(0, canvSize.height - 1,
183: screenOrigin);
184: t2.set(new Vector3d(screenOrigin));
185: t.mul(t2);
186:
187: t3.setScale(new Vector3d(_canvas.getPhysicalWidth()
188: / canvSize.width, _canvas.getPhysicalHeight()
189: / canvSize.height, _canvas.getPhysicalWidth()
190: / canvSize.width));
191: t.mul(t3);
192: tg.setTransform(t);
193:
194: }
195:
196: }
|