diff options
Diffstat (limited to 'src/javax/media/j3d/Screen3D.java')
-rw-r--r-- | src/javax/media/j3d/Screen3D.java | 468 |
1 files changed, 468 insertions, 0 deletions
diff --git a/src/javax/media/j3d/Screen3D.java b/src/javax/media/j3d/Screen3D.java new file mode 100644 index 0000000..988dc97 --- /dev/null +++ b/src/javax/media/j3d/Screen3D.java @@ -0,0 +1,468 @@ +/* + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package javax.media.j3d; + +import java.awt.Dimension; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.Hashtable; + +/** + * The Screen3D Object contains all information about a particular screen. + * All Canvas3D objects on the same physical screen (display device) + * refer to the same Screen3D object. Note that Screen3D has no public + * constructors--it is obtained from the Canvas3D via the getScreen3D + * method. + * <p> + * Default values for Screen3D parameters are as follows: + * <ul> + * physical screen width : 0.0254/90.0 * screen width (in pixels)<br> + * physical screen height : 0.0254/90.0 * screen height (in pixels)<br> + * tracker base to image plate transform : identity<br> + * head tracker to left image plate transform : identity<br> + * head tracker to right image plate transform : identity<br> + * off-screen size : (0,0)<br> + * </ul> + * <P> + * <b>Offscreen Rendering</b><P> + * New for Java 3D 1.2, an off-screen rendering mode allows rendering + * to a memory image, which is possibly larger than the screen. The + * setSize and getSize methods are defined specifically for this + * mode. Note that the off-screen size, physical width, and physical height + * must be set prior to rendering + * to the associated off-screen canvas. Failure to do so will result + * in an exception.<P> + * <b>Calibration Parameters</b><P> + * The Screen3D object must be calibrated with the coexistence volume. + * The Screen3D class provides several methods for defining the + * calibration parameters.<P> + * <UL>Measured Parameters<P> + * The screen's (image plate's) physical width and height (in meters) + * is set once, typically by a browser, calibration program, system + * administrator, or system calibrator, not by an applet. These values + * must be determined by measuring the display's active image width + * and height. In the case of a head-mounted display, this should be + * the display's apparent width and height at the focal plane. These + * values are defined by the setPhysicalScreenWidth and + * setPhysicalScreenHeight methods.<P> + * + * Head-tracker Coordinate System<P> + * If head tracking is enabled, one of two parameters need to be specified:<P> + * <UL><LI>If the view policy is SCREEN_VIEW, the tracker-base-to-image-plate + * coordinate system must be specified (setTrackerBaseToImagePlate method). + * This coordinate system must be recalibrated whenever the image + * plate moves relative to the tracker.</LI><P> + * + * <LI>If the view policy is HMD_VIEW, the head-tracker-to-left-image-plate + * and head-tracker-to-right-image-plate coordinate systems must be + * specified (setHeadTrackerToLeftImagePlate and + * setHeadTrackerToRightImagePlate methods).</LI><P></UL> + * </UL><P> + * + * <p> + * <b>Additional Information</b> + * <p> + * For more information, see the + * <a href="doc-files/intro.html">Introduction to the Java 3D API</a> and + * <a href="doc-files/ViewModel.html">View Model</a> + * documents. + * + * @see Canvas3D + * @see Canvas3D#getScreen3D + */ + +public class Screen3D extends Object { + private static final boolean debug = false; + + // Assume a default of 90 DPI: 90 pix/inch = 1/90 inch/pix = + // 0.0254/90 meter/pix + private static final double METERS_PER_PIXEL = 0.0254/90.0; + + // GraphicsDevice associated with this Screen3D object. Note that + // all on-screen Canvas3D objects that are created on the same + // GraphicsDevice will share the same Screen3D. + GraphicsDevice graphicsDevice; + + // Flag indicating whether this Screen3D is associated with + // an off-screen Canvas3D or with one or more on-screen Canvas3Ds + boolean offScreen; + + // Screen number + int screen; + + // The width and height of the screen in meters. + double physicalScreenWidth; + double physicalScreenHeight; + + // Screen size in pixels + Dimension screenSize = new Dimension(0, 0); + + // + // Tracker-base coordinate system to image-plate coordinate + // system transform. This transform + // is typically a calibration constant. + // This is used only in SCREEN_VIEW mode. + // + Transform3D trackerBaseToImagePlate = new Transform3D(); + + // + // Head-tracker coordinate system to left and right image-plate + // coordinate system transforms. These transforms are typically + // calibration constants. These are used only in HMD_VIEW mode. + // + Transform3D headTrackerToLeftImagePlate = new Transform3D(); + Transform3D headTrackerToRightImagePlate = new Transform3D(); + + + // Physical screen size related field has changed. + static final int PHYSICAL_SCREEN_SIZE_DIRTY = 0x01; + // Screen size field has changed. + static final int SCREEN_SIZE_DIRTY_DIRTY = 0x02; + // Tracker base to image plate field has changed. + static final int TRACKER_BASE_TO_IMAGE_PLATE_DIRTY = 0x04; + // Head tracker to image plate field has changed. + static final int HEAD_TRACKER_TO_IMAGE_PLATE_DIRTY = 0x08; + + // Mask that indicates this Screen3D view dependence info. has changed, + // and CanvasViewCache may need to recompute the final view matries. + int scrDirtyMask = (PHYSICAL_SCREEN_SIZE_DIRTY | SCREEN_SIZE_DIRTY_DIRTY + | TRACKER_BASE_TO_IMAGE_PLATE_DIRTY + | HEAD_TRACKER_TO_IMAGE_PLATE_DIRTY); + + // + // View cache for this screen + // + ScreenViewCache screenViewCache = null; + + // The renderer for this screen + Renderer renderer = null; + +// Hashtable that maps a GraphicsDevice to its associated renderer +static Hashtable<GraphicsDevice, Renderer> deviceRendererMap = new Hashtable<GraphicsDevice, Renderer>(); + + // A count of the number of canvases associated with this screen + int canvasCount = 0; + + // A list of Canvas3D Objects that refer to this + private final ArrayList<Canvas3D> users = new ArrayList<Canvas3D>(); + +// Add a user to the list of users +synchronized void removeUser(Canvas3D c) { + users.remove(c); +} + +// Add a user to the list of users +synchronized void addUser(Canvas3D c) { + if (!users.contains(c)) + users.add(c); +} + +// Add a user to the list of users +synchronized void notifyUsers() { + for (int i = 0; i < users.size(); i++) { + users.get(i).redraw(); + } +} + + /** + * Retrieves the width and height (in pixels) of this Screen3D. + * + * @return a new Dimension object containing the width and height + * of this Screen3D. + */ + public Dimension getSize() { + return new Dimension(screenSize); + } + + /** + * Retrieves the width and height (in pixels) of this Screen3D + * and copies it into the specified Dimension object. + * + * @param rv Dimension object into which the size of + * this Screen3D is copied. + * If <code>rv</code> is null, a new Dimension object is allocated. + * + * @return <code>rv</code> + * + * @since Java 3D 1.2 + */ + public Dimension getSize(Dimension rv) { + if (rv == null) { + return new Dimension(screenSize); + } + else { + rv.setSize(screenSize); + return rv; + } + } + + /** + * Sets the width and height (in pixels) of this off-screen Screen3D. + * The default size for off-screen Screen3D objects is (0,0). + * <br> + * NOTE: the size must be + * set prior to rendering to the associated off-screen canvas. + * Failure to do so will result in an exception. + * + * @param width the new width of this Screen3D object + * @param height the new height of this Screen3D object + * + * @exception IllegalStateException if this Screen3D is not in + * off-screen mode. + * + * @since Java 3D 1.2 + */ + public void setSize(int width, int height) { + + if (!offScreen) + throw new IllegalStateException(J3dI18N.getString("Screen3D1")); + + synchronized(this) { + screenSize.width = width; + screenSize.height = height; + scrDirtyMask |= SCREEN_SIZE_DIRTY_DIRTY; + } + } + + /** + * Sets the width and height (in pixels) of this off-screen Screen3D. + * The default size for off-screen Screen3D objects is (0,0). + * <br> + * NOTE: the size must be + * set prior to rendering to the associated off-screen canvas. + * Failure to do so will result in an exception. + * + * @param d the new dimension of this Screen3D object + * + * @exception IllegalStateException if this Screen3D is not in + * off-screen mode. + * + * @since Java 3D 1.2 + */ + public void setSize(Dimension d) { + if (!offScreen) + throw new IllegalStateException(J3dI18N.getString("Screen3D1")); + + synchronized(this) { + screenSize.width = d.width; + screenSize.height = d.height; + scrDirtyMask |= SCREEN_SIZE_DIRTY_DIRTY; + } + } + + /** + * Sets the screen physical width in meters. In the case of a + * head-mounted display, this should be the apparent width + * at the focal plane. + * @param width the screen's physical width in meters + */ + public void setPhysicalScreenWidth(double width) { + synchronized(this) { + physicalScreenWidth = width; + scrDirtyMask |= PHYSICAL_SCREEN_SIZE_DIRTY; + } + notifyUsers(); + } + + /** + * Retrieves the screen's physical width in meters. + * @return the screen's physical width in meters + */ + public double getPhysicalScreenWidth() { + return physicalScreenWidth; + } + + /** + * Sets the screen physical height in meters. In the case of a + * head-mounted display, this should be the apparent height + * at the focal plane. + * @param height the screen's physical height in meters + */ + public void setPhysicalScreenHeight(double height) { + synchronized(this) { + physicalScreenHeight = height; + scrDirtyMask |= PHYSICAL_SCREEN_SIZE_DIRTY; + } + notifyUsers(); + } + + /** + * Retrieves the the screen's physical height in meters. + * @return the screen's physical height in meters + */ + public double getPhysicalScreenHeight() { + return physicalScreenHeight; + } + + @Override + public String toString() { + return "Screen3D: size = " + + "(" + getSize().width + " x " + getSize().height + ")" + + ", physical size = " + + "(" + getPhysicalScreenWidth() + "m x " + + getPhysicalScreenHeight() + "m)"; + } + + // Static initializer for Screen3D class + static { + VirtualUniverse.loadLibraries(); + } + + /** + * Construct a new Screen3D object with the specified size in pixels. + * Note that currently, there is no AWT equivalent of screen so Java 3D + * users need to get this through the Canvas3D object (via getScreen()) if + * they need it. + * @param graphicsConfiguration the AWT graphics configuration associated + * with this Screen3D + * @param offScreen a flag that indicates whether this Screen3D is + * associated with an off-screen Canvas3D + */ + Screen3D(GraphicsConfiguration graphicsConfiguration, boolean offScreen) { + this.offScreen = offScreen; + this.graphicsDevice = graphicsConfiguration.getDevice(); + + screenViewCache = new ScreenViewCache(this); + + // Get the display handle and the screen number from the Pipeline + screen = Pipeline.getPipeline().getScreen(graphicsDevice); + + if (debug) + System.err.println("Screen3D: screen " + screen + " hashcode " + + this.hashCode()); + + if (!offScreen) { + // Store the information in this screen object + Rectangle bounds = graphicsConfiguration.getBounds(); + screenSize.width = bounds.width; + screenSize.height = bounds.height; + } + + // Set the default physical size based on size in pixels + physicalScreenWidth = screenSize.width * METERS_PER_PIXEL; + physicalScreenHeight = screenSize.height * METERS_PER_PIXEL; + } + + + /** + * Sets the tracker-base coordinate system to image-plate coordinate + * system transform. This transform + * is typically a calibration constant. + * This is used only in SCREEN_VIEW mode. + * @param t the new transform + * @exception BadTransformException if the transform is not rigid + */ + public void setTrackerBaseToImagePlate(Transform3D t) { + synchronized(this) { + if (!t.isRigid()) { + throw new BadTransformException(J3dI18N.getString("Screen3D0")); + } + trackerBaseToImagePlate.setWithLock(t); + scrDirtyMask |= Screen3D.TRACKER_BASE_TO_IMAGE_PLATE_DIRTY; + } + notifyUsers(); + } + + /** + * Retrieves the tracker-base coordinate system to image-plate + * coordinate system transform and copies it into the specified + * Transform3D object. + * @param t the object that will receive the transform + */ + public void getTrackerBaseToImagePlate(Transform3D t) { + t.set(trackerBaseToImagePlate); + } + + /** + * Sets the head-tracker coordinate system to left image-plate coordinate + * system transform. This transform + * is typically a calibration constant. + * This is used only in HMD_VIEW mode. + * @param t the new transform + * @exception BadTransformException if the transform is not rigid + */ + public void setHeadTrackerToLeftImagePlate(Transform3D t) { + synchronized(this) { + if (!t.isRigid()) { + throw new BadTransformException(J3dI18N.getString("Screen3D0")); + } + headTrackerToLeftImagePlate.setWithLock(t); + scrDirtyMask |= Screen3D.HEAD_TRACKER_TO_IMAGE_PLATE_DIRTY; + } + notifyUsers(); + } + + /** + * Retrieves the head-tracker coordinate system to left image-plate + * coordinate system transform and copies it into the specified + * Transform3D object. + * @param t the object that will receive the transform + */ + public void getHeadTrackerToLeftImagePlate(Transform3D t) { + t.set(headTrackerToLeftImagePlate); + } + + /** + * Sets the head-tracker coordinate system to right image-plate coordinate + * system transform. This transform + * is typically a calibration constant. + * This is used only in HMD_VIEW mode. + * @param t the new transform + * @exception BadTransformException if the transform is not rigid + */ + public void setHeadTrackerToRightImagePlate(Transform3D t) { + synchronized(this) { + if (!t.isRigid()) { + throw new BadTransformException(J3dI18N.getString("Screen3D0")); + } + headTrackerToRightImagePlate.setWithLock(t); + scrDirtyMask |= Screen3D.HEAD_TRACKER_TO_IMAGE_PLATE_DIRTY; + } + notifyUsers(); + } + + /** + * Retrieves the head-tracker coordinate system to right image-plate + * coordinate system transform and copies it into the specified + * Transform3D object. + * @param t the object that will receive the transform + */ + public void getHeadTrackerToRightImagePlate(Transform3D t) { + t.set(headTrackerToRightImagePlate); + } + + /** + * Update the view cache associated with this screen. + */ + void updateViewCache() { + synchronized(this) { + screenViewCache.snapshot(); + } + } +} |