001: /*
002: * Copyright (c) 2000 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: package com.db.layers.overlay;
037:
038: import javax.media.j3d.*;
039: import javax.vecmath.*;
040: import java.awt.*;
041: import java.awt.event.*;
042:
043: /** This class provides extra functionality that Canvas3D does not have. Also, the functions
044: * that overides Canvas3D methods are not cached so that there is not a frame lag when used
045: * in WakeUpOnElapsedFrame as long as the View Model and TransformGroups above the ViewPlatform
046: * are changed before these functions are used.
047: *
048: * This class assumes:
049: * The ViewPlatform has capabilities set to ALLOW_LOCAL_TO_VWORLD_READ
050: * <p>
051: * @author Blaine Bell
052: * @since JDK1.1
053: * @version 1.0
054: *
055: **/
056: public class FixedCanvas3D extends Canvas3D implements
057: ComponentListener {
058:
059: double _fclipdist = 0., _bclipdist = 0.;
060:
061: public FixedCanvas3D(
062: java.awt.GraphicsConfiguration graphicsConfiguration) {
063:
064: super (graphicsConfiguration);
065: addComponentListener(this );
066: refreshAllVariables();
067:
068: }
069:
070: public FixedCanvas3D(
071: java.awt.GraphicsConfiguration graphicsConfiguration,
072: boolean offScreen) {
073:
074: super (graphicsConfiguration, offScreen);
075: addComponentListener(this );
076: refreshAllVariables();
077:
078: }
079:
080: public void refreshAllVariables() {
081:
082: if (getView() != null) {
083: computeFrontClipValueInImagePlate();
084: computeBackClipValueInImagePlate();
085: }
086:
087: }
088:
089: public void componentHidden(ComponentEvent e) {
090:
091: refreshAllVariables();
092:
093: }
094:
095: public void componentShown(ComponentEvent e) {
096:
097: refreshAllVariables();
098:
099: }
100:
101: public void componentMoved(ComponentEvent e) {
102:
103: refreshAllVariables();
104:
105: }
106:
107: public void componentResized(ComponentEvent e) {
108:
109: refreshAllVariables();
110:
111: }
112:
113: public double getFrontClipValueInImagePlate() {
114:
115: return (_fclipdist);
116:
117: }
118:
119: public double computeFrontClipValueInImagePlate() {
120:
121: int fviewpolicy = getView().getFrontClipPolicy();
122: _fclipdist = -getView().getFrontClipDistance();
123:
124: if (fviewpolicy == View.VIRTUAL_EYE
125: || fviewpolicy == View.VIRTUAL_SCREEN) {
126: /** need to multiply it by virtual-phyiscal scale **/
127: if (getView().getWindowResizePolicy() == View.PHYSICAL_WORLD) {
128: /* Resize policy has effect on clipping planes */
129: _fclipdist *= getPhysicalWidth() / 2.;
130: } else {
131: _fclipdist *= getScreen3D().getPhysicalScreenWidth() / 2.;
132: }
133: } else if (getView().getWindowResizePolicy() == View.PHYSICAL_WORLD) {
134: _fclipdist *= getPhysicalWidth()
135: / getScreen3D().getPhysicalScreenWidth();
136: }
137: if (fviewpolicy == View.PHYSICAL_EYE
138: || fviewpolicy == View.VIRTUAL_EYE) {
139: Point3d eyepoint = new Point3d();
140: getCenterEyeInImagePlate(eyepoint);
141: _fclipdist += eyepoint.z;
142: }
143:
144: return (_fclipdist);
145:
146: }
147:
148: public double getBackClipValueInImagePlate() {
149:
150: return (_bclipdist);
151:
152: }
153:
154: public double computeBackClipValueInImagePlate() {
155:
156: int bviewpolicy = getView().getBackClipPolicy();
157: _bclipdist = -getView().getBackClipDistance();
158:
159: if (bviewpolicy == View.VIRTUAL_EYE
160: || bviewpolicy == View.VIRTUAL_SCREEN) {
161: /** need to multiply it by virtual-phyiscal scale **/
162: if (getView().getWindowResizePolicy() == View.PHYSICAL_WORLD) {
163: /* Resize policy has effect on clipping planes */
164: _bclipdist *= getPhysicalWidth() / 2.;
165: } else {
166: _bclipdist *= getScreen3D().getPhysicalScreenWidth() / 2.;
167: }
168: } else if (getView().getWindowResizePolicy() == View.PHYSICAL_WORLD) {
169: _bclipdist *= getPhysicalWidth()
170: / getScreen3D().getPhysicalScreenWidth();
171: }
172: if (bviewpolicy == View.PHYSICAL_EYE
173: || bviewpolicy == View.VIRTUAL_EYE) {
174: Point3d eyepoint = new Point3d();
175: getCenterEyeInImagePlate(eyepoint);
176: _bclipdist += eyepoint.z;
177: }
178: return (_bclipdist);
179:
180: }
181:
182: public void getImagePlateToVworld(Transform3D t) {
183:
184: ViewPlatform viewplatform = getView().getViewPlatform();
185: Transform3D vp2vw = new Transform3D();
186: viewplatform.getLocalToVworld(vp2vw);
187: getViewPlatformToImagePlate(t);
188: t.mul(vp2vw, t);
189:
190: }
191:
192: public void getViewPlatformToImagePlate(Transform3D t) {
193:
194: View view = getView();
195: ViewPlatform viewplatform = getView().getViewPlatform();
196: int resizepolicy = view.getWindowResizePolicy(), movementpolicy = view
197: .getWindowMovementPolicy(), viewattachmentpolicy = viewplatform
198: .getViewAttachPolicy();
199: Screen3D screen = getScreen3D();
200: Vector2d canvasPhysDimensions = null, screenPhysDimensions = new Vector2d(
201: screen.getPhysicalScreenWidth(), screen
202: .getPhysicalScreenHeight());
203: Point canvasLocation = null;
204: Dimension screenPixSize = null, canvasPixSize = null;
205: /** Need to compute canvas coordinates in imageplate using location on screen */
206: screenPixSize = screen.getSize();
207: try {
208: canvasLocation = getLocationOnScreen();
209: } catch (Exception e) {
210: t.setIdentity();
211: return;
212: }
213: canvasPixSize = getSize();
214: /** getLocationOnScreen returns from upper left, we want lower left */
215: canvasLocation.y = screenPixSize.height - canvasLocation.y
216: - canvasPixSize.height;
217:
218: canvasPhysDimensions = new Vector2d(screenPhysDimensions.x
219: * canvasPixSize.width / screenPixSize.width,
220: screenPhysDimensions.y * canvasPixSize.height
221: / screenPixSize.height);
222: t.setIdentity();
223: Vector3d translation = new Vector3d();
224: double scale = 1;
225: if (resizepolicy == View.VIRTUAL_WORLD) {
226: /** View Platform in center of screen */
227: scale = .5 * screenPhysDimensions.x;
228: } else {
229: /* The ratio of the widths between the canvas and screen */
230: scale = .5 * canvasPhysDimensions.x;
231: }
232: t.setScale(scale);
233: if (movementpolicy == View.VIRTUAL_WORLD) {
234: /** Middle of screen */
235: translation.x = .5 * screenPhysDimensions.x;
236: translation.y = .5 * screenPhysDimensions.y;
237: } else {
238: /** Size of Screen in VWorld is 2 wide
239: * since scale is */
240: translation.x = screenPhysDimensions.x
241: * (canvasLocation.x + canvasPixSize.width / 2.)
242: / screenPixSize.width;
243: translation.y = screenPhysDimensions.y
244: * (canvasLocation.y + canvasPixSize.height / 2.)
245: / (double) screenPixSize.height;
246: }
247:
248: if (view.getWindowEyepointPolicy() == View.RELATIVE_TO_FIELD_OF_VIEW) {
249: if (viewattachmentpolicy == View.NOMINAL_SCREEN) {
250: translation.z = 0.;
251: } else if (viewattachmentpolicy == View.NOMINAL_HEAD) {
252: translation.z = .5 * canvasPhysDimensions.x
253: / Math.tan(view.getFieldOfView() / 2.);
254: } else if (viewattachmentpolicy == View.NOMINAL_FEET) {
255: translation.y -= view.getPhysicalBody()
256: .getNominalEyeHeightFromGround()
257: * scale / (.5 * screenPhysDimensions.x);
258: ;
259: translation.z = .5 * canvasPhysDimensions.x
260: / Math.tan(view.getFieldOfView() / 2.);
261: }
262: } else {
263: if (viewattachmentpolicy == View.NOMINAL_SCREEN) {
264: translation.z = 0.;
265: } else if (viewattachmentpolicy == View.NOMINAL_HEAD) {
266: translation.z = view.getPhysicalBody()
267: .getNominalEyeOffsetFromNominalScreen();
268: } else if (viewattachmentpolicy == View.NOMINAL_FEET) {
269: translation.y -= view.getPhysicalBody()
270: .getNominalEyeHeightFromGround();
271: translation.z = view.getPhysicalBody()
272: .getNominalEyeOffsetFromNominalScreen();
273: }
274: }
275: t.setTranslation(translation);
276: try {
277: t.invert();
278: } catch (Exception e) {
279: System.out.println("t=" + t);
280: e.printStackTrace();
281: System.out.println("canvasLocation=" + canvasLocation
282: + " canvasPixSize=" + canvasPixSize
283: + " screenPhysDimensions=" + screenPhysDimensions
284: + " canvasPhysDimensions=" + canvasPhysDimensions);
285: }
286:
287: }
288:
289: public void getImagePlateToViewPlatform(Transform3D t) {
290:
291: getViewPlatformToImagePlate(t);
292: t.invert();
293:
294: }
295:
296: public void getVworldToImagePlate(Transform3D t) {
297:
298: getImagePlateToVworld(t);
299: t.invert();
300:
301: }
302:
303: public void getPixelLocationInImagePlate(int x, int y,
304: Point3d imagePlatePoint) {
305:
306: double dx = x, dy = y;
307: Screen3D screen = getScreen3D();
308: Dimension screenPixSize = screen.getSize(), canvasPixSize = getSize();
309: Point canvasLocation = getLocationOnScreen();
310: Vector2d canvasPhysDimensions = new Vector2d(
311: getPhysicalWidth(), getPhysicalHeight()), screenPhysDimensions = new Vector2d(
312: screen.getPhysicalScreenWidth(), screen
313: .getPhysicalScreenHeight());
314: imagePlatePoint.x = screenPhysDimensions.x
315: * ((canvasLocation.x + dx) / (double) screenPixSize.width);
316: imagePlatePoint.y = screenPhysDimensions.y
317: * ((screenPixSize.height - canvasLocation.y - dy - 1) / (double) screenPixSize.height);
318: imagePlatePoint.z = 0.;
319:
320: }
321:
322: public void getPixelLocationInImagePlate(Point2d pixelLocation,
323: Point3d imagePlatePoint) {
324:
325: getPixelLocationInImagePlate((int) Math.round(pixelLocation.x),
326: (int) Math.round(pixelLocation.y), imagePlatePoint);
327:
328: }
329:
330: }
|