1 /*
2  * $RCSfile: ViewCache.java,v $
3  *
4  * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6  *
7  * This code is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License version 2 only, as
9  * published by the Free Software Foundation.  Sun designates this
10  * particular file as subject to the "Classpath" exception as provided
11  * by Sun in the LICENSE file that accompanied this code.
12  *
13  * This code is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16  * version 2 for more details (a copy is included in the LICENSE file that
17  * accompanied this code).
18  *
19  * You should have received a copy of the GNU General Public License version
20  * 2 along with this work; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
22  *
23  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
24  * CA 95054 USA or visit www.sun.com if you need additional information or
25  * have any questions.
26  *
27  * $Revision: 1.7 $
28  * $Date: 2008/02/28 20:17:32 $
29  * $State: Exp $
30  */
31 
32 package javax.media.j3d;
33 
34 import javax.vecmath.*;
35 
36 /**
37  * The ViewCache class is used to cache all data, both API data and derived
38  * data, that is independent of the Canvas3D and Screen3D.
39  */
40 class ViewCache extends Object {
41     // The view associated with this view cache
42     View view;
43 
44     //
45     // API/INPUT DATA
46     //
47 
48     // *********************
49     // * From ViewPlatform *
50     // *********************
51     int		viewAttachPolicy;
52 
53     // *********************
54     // * From PhysicalBody *
55     // *********************
56 
57     /**
58      * The user's left eye's position in head coordinates.
59      */
60     Point3d	leftEyePosInHead = new Point3d();
61 
62     /**
63      * The user's right eye's position in head coordinates.
64      */
65     Point3d	rightEyePosInHead = new Point3d();
66 
67     /**
68      * The user's left ear's position in head coordinates.
69      */
70     Point3d	leftEarPosInHead = new Point3d();
71 
72     /**
73      * The user's right ear's position in head coordinates.
74      */
75     Point3d	rightEarPosInHead = new Point3d();
76 
77     /**
78      * The user's nominal eye height as measured
79      * from the ground plane.
80      */
81     double	nominalEyeHeightFromGround;
82 
83     /**
84      * The amount to offset the system's
85      * viewpoint from the user's current eye-point.  This offset
86      * distance allows an "Over the shoulder" view of the scene
87      * as seen by the user.
88      */
89     double	nominalEyeOffsetFromNominalScreen;
90 
91     // Head to head-tracker coordinate system transform.
92     // If head tracking is enabled, this transform is a calibration
93     // constant.  If head tracking is not enabled, this transform is
94     // not used.
95     // This is only used in SCREEN_VIEW mode.
96     Transform3D headToHeadTracker = new Transform3D();
97 
98     // ****************************
99     // * 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     // *************
133     // * From View *
134     // *************
135 
136     // View model compatibility mode flag
137     boolean compatibilityModeEnable;
138 
139     // coexistenceCenteringEnable flag
140     boolean coexistenceCenteringEnable;
141 
142     Point3d leftManualEyeInCoexistence = new Point3d();
143     Point3d rightManualEyeInCoexistence = new Point3d();
144 
145     // Indicates which major mode of view computation to use:
146     // HMD mode or screen/fish-tank-VR mode.
147     int		viewPolicy;
148 
149     // The current projection policy (parallel versus perspective)
150     int projectionPolicy;
151 
152     // The current screen scale policy and scale value
153     int screenScalePolicy;
154     double screenScale;
155 
156     // The current window resize, movement and eyepoint policies
157     int windowResizePolicy;
158     int windowMovementPolicy;
159     int windowEyepointPolicy;
160 
161     // The current monoscopic view policy
162     int monoscopicViewPolicy;
163 
164     // The view model's field of view.
165     double	fieldOfView;
166 
167     // The distance away from the clip origin
168     // in the direction of gaze for the front and back clip planes.
169     double	frontClipDistance;
170     double	backClipDistance;
171 
172     // Front and back clip policies
173     int		frontClipPolicy;
174     int		backClipPolicy;
175 
176     // ViewPlatform of this view
177     ViewPlatformRetained vpRetained;
178 
179     /**
180      * Defines the visibility policy.
181      */
182     int		visibilityPolicy;
183 
184     // Flag to enable tracking, if so allowed by the trackingAvailable flag.
185     boolean		trackingEnable;
186 
187     // This setting enables the continuous updating by Java 3D of the
188     // userHeadToVworld transform.
189     boolean userHeadToVworldEnable;
190 
191     // The current compatibility mode view transform
192     Transform3D compatVpcToEc = new Transform3D();
193 
194     // The current compatibility mode projection transforms
195     Transform3D compatLeftProjection = new Transform3D();
196     Transform3D compatRightProjection = new Transform3D();
197 
198     // Mask that indicates ViewCache's view dependence info. has changed,
199     // and CanvasViewCache may need to recompute the final view matries.
200     int vcDirtyMask = 0;
201 
202     //
203     // DERIVED DATA
204     //
205 
206     // Flag indicating that head tracking will be used
207     private boolean doHeadTracking;
208 
209     //
210     // Matrix to transform from user-head to
211     // virtual-world coordinates. This matrix is a read-only
212     // value that Java 3D generates continuously, but only if enabled
213     // by userHeadToVworldEnableFlag.
214     //
215     Transform3D	userHeadToVworld = new Transform3D();
216 
217 
218     /**
219      * Take snapshot of all per-view API parameters and input values.
220      */
snapshot()221     synchronized void snapshot() {
222 
223 	// View parameters
224 	vcDirtyMask = view.vDirtyMask;
225 	view.vDirtyMask = 0;
226 	compatibilityModeEnable = view.compatibilityModeEnable;
227 	coexistenceCenteringEnable = view.coexistenceCenteringEnable;
228 	leftManualEyeInCoexistence.set(view.leftManualEyeInCoexistence);
229 	rightManualEyeInCoexistence.set(view.rightManualEyeInCoexistence);
230 	viewPolicy = view.viewPolicy;
231 	projectionPolicy = view.projectionPolicy;
232 	screenScalePolicy = view.screenScalePolicy;
233 	windowResizePolicy = view.windowResizePolicy;
234 	windowMovementPolicy = view.windowMovementPolicy;
235 	windowEyepointPolicy = view.windowEyepointPolicy;
236 	monoscopicViewPolicy = view.monoscopicViewPolicy;
237 
238 	fieldOfView = view.fieldOfView;
239 	screenScale = view.screenScale;
240 
241 	frontClipDistance = view.frontClipDistance;
242 	backClipDistance = view.backClipDistance;
243 	frontClipPolicy = view.frontClipPolicy;
244 	backClipPolicy = view.backClipPolicy;
245 
246 	visibilityPolicy = view.visibilityPolicy;
247 
248 	trackingEnable = view.trackingEnable;
249 	userHeadToVworldEnable = view.userHeadToVworldEnable;
250 
251 	view.compatVpcToEc.getWithLock(compatVpcToEc);
252 	view.compatLeftProjection.getWithLock(compatLeftProjection);
253 	view.compatRightProjection.getWithLock(compatRightProjection);
254 
255 	// ViewPlatform parameters
256 	ViewPlatform vpp = view.getViewPlatform();
257 
258 	if (vpp == null) {
259 	    // This happens when user attach a null viewplatform
260 	    // and MC still call updateViewCache() in run before
261 	    // the viewDeactivate request get.
262 	    return;
263 	}
264 
265 	vpRetained = (ViewPlatformRetained) vpp.retained;
266 
267 	synchronized(vpRetained) {
268 	    vcDirtyMask |= vpRetained.vprDirtyMask;
269 	    vpRetained.vprDirtyMask = 0;
270 	    viewAttachPolicy = vpRetained.viewAttachPolicy;
271 	    // System.err.println("ViewCache snapshot vcDirtyMask " + vcDirtyMask );
272 	}
273 
274 	// PhysicalEnvironment parameters
275 	PhysicalEnvironment env = view.getPhysicalEnvironment();
276 
277 	synchronized(env) {
278 	    vcDirtyMask |= env.peDirtyMask;
279 	    env.peDirtyMask = 0;
280 
281 	    env.coexistenceToTrackerBase.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(headTrackerToTrackerBase);
293 		vcDirtyMask |= View.TRACKING_ENABLE_DIRTY;
294 	    }
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 =
314 		body.nominalEyeOffsetFromNominalScreen;
315 	}
316 
317 	body.headToHeadTracker.getWithLock(headToHeadTracker);
318     }
319 
320 
321     /**
322      * Compute derived data using the snapshot of the per-view data.
323      */
computeDerivedData()324     synchronized void computeDerivedData() {
325 	if (doHeadTracking) {
326 	    trackerBaseToHeadTracker.invert(headTrackerToTrackerBase);
327 	    //System.err.println("trackerBaseToHeadTracker: ");
328 	    //System.err.println(trackerBaseToHeadTracker);
329 	}
330 	else {
331 	    trackerBaseToHeadTracker.setIdentity();
332 	}
333 
334 	// XXXX: implement head to vworld tracking if userHeadToVworldEnable is set
335     	userHeadToVworld.setIdentity();
336     }
337 
338 
339     // Get methods for returning derived data values.
340     // Eventually, these get functions will cause some of the parameters
341     // to be lazily evaluated.
342     //
343     // NOTE that in the case of Transform3D, and Tuple objects, a reference
344     // to the actual derived data is returned.  In these cases, the caller
345     // must ensure that the returned data is not modified.
346 
getDoHeadTracking()347     boolean getDoHeadTracking() {
348 	return doHeadTracking;
349     }
350 
351     /**
352      * Constructs and initializes a ViewCache object.
353      */
ViewCache(View view)354     ViewCache(View view) {
355 	this.view = view;
356 
357 	if (false)
358 	    System.err.println("Constructed a ViewCache");
359     }
360 
361 }
362