001: /*
002: * $RCSfile: ViewCache.java,v $
003: *
004: * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
006: *
007: * This code is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License version 2 only, as
009: * published by the Free Software Foundation. Sun designates this
010: * particular file as subject to the "Classpath" exception as provided
011: * by Sun in the LICENSE file that accompanied this code.
012: *
013: * This code is distributed in the hope that it will be useful, but WITHOUT
014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: * version 2 for more details (a copy is included in the LICENSE file that
017: * accompanied this code).
018: *
019: * You should have received a copy of the GNU General Public License version
020: * 2 along with this work; if not, write to the Free Software Foundation,
021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
022: *
023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
024: * CA 95054 USA or visit www.sun.com if you need additional information or
025: * have any questions.
026: *
027: * $Revision: 1.7 $
028: * $Date: 2008/02/28 20:17:32 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import javax.vecmath.*;
035:
036: /**
037: * The ViewCache class is used to cache all data, both API data and derived
038: * data, that is independent of the Canvas3D and Screen3D.
039: */
040: class ViewCache extends Object {
041: // The view associated with this view cache
042: View view;
043:
044: //
045: // API/INPUT DATA
046: //
047:
048: // *********************
049: // * From ViewPlatform *
050: // *********************
051: int viewAttachPolicy;
052:
053: // *********************
054: // * From PhysicalBody *
055: // *********************
056:
057: /**
058: * The user's left eye's position in head coordinates.
059: */
060: Point3d leftEyePosInHead = new Point3d();
061:
062: /**
063: * The user's right eye's position in head coordinates.
064: */
065: Point3d rightEyePosInHead = new Point3d();
066:
067: /**
068: * The user's left ear's position in head coordinates.
069: */
070: Point3d leftEarPosInHead = new Point3d();
071:
072: /**
073: * The user's right ear's position in head coordinates.
074: */
075: Point3d rightEarPosInHead = new Point3d();
076:
077: /**
078: * The user's nominal eye height as measured
079: * from the ground plane.
080: */
081: double nominalEyeHeightFromGround;
082:
083: /**
084: * The amount to offset the system's
085: * viewpoint from the user's current eye-point. This offset
086: * distance allows an "Over the shoulder" view of the scene
087: * as seen by the user.
088: */
089: double nominalEyeOffsetFromNominalScreen;
090:
091: // Head to head-tracker coordinate system transform.
092: // If head tracking is enabled, this transform is a calibration
093: // constant. If head tracking is not enabled, this transform is
094: // not used.
095: // This is only used in SCREEN_VIEW mode.
096: Transform3D headToHeadTracker = new Transform3D();
097:
098: // ****************************
099: // * From PhysicalEnvironment *
100: // ****************************
101:
102: // Coexistence coordinate system to tracker-base coordinate
103: // system transform. If head tracking is enabled, this transform
104: // is a calibration constant. If head tracking is not enabled,
105: // this transform is not used.
106: // This is used in both SCREEN_VIEW and HMD_VIEW modes.
107: Transform3D coexistenceToTrackerBase = new Transform3D();
108:
109: // Transform generated by the head tracker to transform
110: // from tracker base to head tracker coordinates (and the inverse).
111: Transform3D headTrackerToTrackerBase = new Transform3D();
112: Transform3D trackerBaseToHeadTracker = new Transform3D();
113:
114: //
115: // Indicates whether the underlying hardware implementation
116: // supports tracking.
117: //
118: boolean trackingAvailable;
119:
120: // Sensor index for head tracker
121: int headIndex;
122:
123: //
124: // This variable specifies the policy Java 3D will use in placing
125: // the user's eye position relative to the user's head position
126: // (NOMINAL_SCREEN, NOMINAL_HEAD, or NOMINAL_FEET).
127: // It is used in the calibration process.
128: //
129: int coexistenceCenterInPworldPolicy;
130:
131: // *************
132: // * From View *
133: // *************
134:
135: // View model compatibility mode flag
136: boolean compatibilityModeEnable;
137:
138: // coexistenceCenteringEnable flag
139: boolean coexistenceCenteringEnable;
140:
141: Point3d leftManualEyeInCoexistence = new Point3d();
142: Point3d rightManualEyeInCoexistence = new Point3d();
143:
144: // Indicates which major mode of view computation to use:
145: // HMD mode or screen/fish-tank-VR mode.
146: int viewPolicy;
147:
148: // The current projection policy (parallel versus perspective)
149: int projectionPolicy;
150:
151: // The current screen scale policy and scale value
152: int screenScalePolicy;
153: double screenScale;
154:
155: // The current window resize, movement and eyepoint policies
156: int windowResizePolicy;
157: int windowMovementPolicy;
158: int windowEyepointPolicy;
159:
160: // The current monoscopic view policy
161: int monoscopicViewPolicy;
162:
163: // The view model's field of view.
164: double fieldOfView;
165:
166: // The distance away from the clip origin
167: // in the direction of gaze for the front and back clip planes.
168: double frontClipDistance;
169: double backClipDistance;
170:
171: // Front and back clip policies
172: int frontClipPolicy;
173: int backClipPolicy;
174:
175: // ViewPlatform of this view
176: ViewPlatformRetained vpRetained;
177:
178: /**
179: * Defines the visibility policy.
180: */
181: int visibilityPolicy;
182:
183: // Flag to enable tracking, if so allowed by the trackingAvailable flag.
184: boolean trackingEnable;
185:
186: // This setting enables the continuous updating by Java 3D of the
187: // userHeadToVworld transform.
188: boolean userHeadToVworldEnable;
189:
190: // The current compatibility mode view transform
191: Transform3D compatVpcToEc = new Transform3D();
192:
193: // The current compatibility mode projection transforms
194: Transform3D compatLeftProjection = new Transform3D();
195: Transform3D compatRightProjection = new Transform3D();
196:
197: // Mask that indicates ViewCache's view dependence info. has changed,
198: // and CanvasViewCache may need to recompute the final view matries.
199: int vcDirtyMask = 0;
200:
201: //
202: // DERIVED DATA
203: //
204:
205: // Flag indicating that head tracking will be used
206: private boolean doHeadTracking;
207:
208: //
209: // Matrix to transform from user-head to
210: // virtual-world coordinates. This matrix is a read-only
211: // value that Java 3D generates continuously, but only if enabled
212: // by userHeadToVworldEnableFlag.
213: //
214: Transform3D userHeadToVworld = new Transform3D();
215:
216: /**
217: * Take snapshot of all per-view API parameters and input values.
218: */
219: synchronized void snapshot() {
220:
221: // View parameters
222: vcDirtyMask = view.vDirtyMask;
223: view.vDirtyMask = 0;
224: compatibilityModeEnable = view.compatibilityModeEnable;
225: coexistenceCenteringEnable = view.coexistenceCenteringEnable;
226: leftManualEyeInCoexistence.set(view.leftManualEyeInCoexistence);
227: rightManualEyeInCoexistence
228: .set(view.rightManualEyeInCoexistence);
229: viewPolicy = view.viewPolicy;
230: projectionPolicy = view.projectionPolicy;
231: screenScalePolicy = view.screenScalePolicy;
232: windowResizePolicy = view.windowResizePolicy;
233: windowMovementPolicy = view.windowMovementPolicy;
234: windowEyepointPolicy = view.windowEyepointPolicy;
235: monoscopicViewPolicy = view.monoscopicViewPolicy;
236:
237: fieldOfView = view.fieldOfView;
238: screenScale = view.screenScale;
239:
240: frontClipDistance = view.frontClipDistance;
241: backClipDistance = view.backClipDistance;
242: frontClipPolicy = view.frontClipPolicy;
243: backClipPolicy = view.backClipPolicy;
244:
245: visibilityPolicy = view.visibilityPolicy;
246:
247: trackingEnable = view.trackingEnable;
248: userHeadToVworldEnable = view.userHeadToVworldEnable;
249:
250: view.compatVpcToEc.getWithLock(compatVpcToEc);
251: view.compatLeftProjection.getWithLock(compatLeftProjection);
252: view.compatRightProjection.getWithLock(compatRightProjection);
253:
254: // ViewPlatform parameters
255: ViewPlatform vpp = view.getViewPlatform();
256:
257: if (vpp == null) {
258: // This happens when user attach a null viewplatform
259: // and MC still call updateViewCache() in run before
260: // the viewDeactivate request get.
261: return;
262: }
263:
264: vpRetained = (ViewPlatformRetained) vpp.retained;
265:
266: synchronized (vpRetained) {
267: vcDirtyMask |= vpRetained.vprDirtyMask;
268: vpRetained.vprDirtyMask = 0;
269: viewAttachPolicy = vpRetained.viewAttachPolicy;
270: // System.err.println("ViewCache snapshot vcDirtyMask " + vcDirtyMask );
271: }
272:
273: // PhysicalEnvironment parameters
274: PhysicalEnvironment env = view.getPhysicalEnvironment();
275:
276: synchronized (env) {
277: vcDirtyMask |= env.peDirtyMask;
278: env.peDirtyMask = 0;
279:
280: env.coexistenceToTrackerBase
281: .getWithLock(coexistenceToTrackerBase);
282: trackingAvailable = env.trackingAvailable;
283: coexistenceCenterInPworldPolicy = env.coexistenceCenterInPworldPolicy;
284:
285: // NOTE: this is really derived data, but we need it here in order
286: // to avoid reading head tracked data when no tracker is available
287: // and enabled.
288: doHeadTracking = trackingEnable && trackingAvailable;
289:
290: if (doHeadTracking) {
291: headIndex = env.getHeadIndex();
292: env.getSensor(headIndex).getRead(
293: headTrackerToTrackerBase);
294: vcDirtyMask |= View.TRACKING_ENABLE_DIRTY;
295: } else {
296: headTrackerToTrackerBase.setIdentity();
297: }
298: }
299:
300: // PhysicalBody parameters
301: PhysicalBody body = view.getPhysicalBody();
302:
303: synchronized (body) {
304: vcDirtyMask |= body.pbDirtyMask;
305: body.pbDirtyMask = 0;
306:
307: leftEyePosInHead.set(body.leftEyePosition);
308: rightEyePosInHead.set(body.rightEyePosition);
309: leftEarPosInHead.set(body.leftEarPosition);
310: rightEarPosInHead.set(body.rightEarPosition);
311:
312: nominalEyeHeightFromGround = body.nominalEyeHeightFromGround;
313: nominalEyeOffsetFromNominalScreen = body.nominalEyeOffsetFromNominalScreen;
314: }
315:
316: body.headToHeadTracker.getWithLock(headToHeadTracker);
317: }
318:
319: /**
320: * Compute derived data using the snapshot of the per-view data.
321: */
322: synchronized void computeDerivedData() {
323: if (doHeadTracking) {
324: trackerBaseToHeadTracker.invert(headTrackerToTrackerBase);
325: //System.err.println("trackerBaseToHeadTracker: ");
326: //System.err.println(trackerBaseToHeadTracker);
327: } else {
328: trackerBaseToHeadTracker.setIdentity();
329: }
330:
331: // XXXX: implement head to vworld tracking if userHeadToVworldEnable is set
332: userHeadToVworld.setIdentity();
333: }
334:
335: // Get methods for returning derived data values.
336: // Eventually, these get functions will cause some of the parameters
337: // to be lazily evaluated.
338: //
339: // NOTE that in the case of Transform3D, and Tuple objects, a reference
340: // to the actual derived data is returned. In these cases, the caller
341: // must ensure that the returned data is not modified.
342:
343: boolean getDoHeadTracking() {
344: return doHeadTracking;
345: }
346:
347: /**
348: * Constructs and initializes a ViewCache object.
349: */
350: ViewCache(View view) {
351: this .view = view;
352:
353: if (false)
354: System.err.println("Constructed a ViewCache");
355: }
356:
357: }
|