Source Code Cross Referenced for View.java in  » 6.0-JDK-Modules » java-3d » javax » media » j3d » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » java 3d » javax.media.j3d 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $RCSfile: View.java,v $
0003:         *
0004:         * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
0005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0006:         *
0007:         * This code is free software; you can redistribute it and/or modify it
0008:         * under the terms of the GNU General Public License version 2 only, as
0009:         * published by the Free Software Foundation.  Sun designates this
0010:         * particular file as subject to the "Classpath" exception as provided
0011:         * by Sun in the LICENSE file that accompanied this code.
0012:         *
0013:         * This code is distributed in the hope that it will be useful, but WITHOUT
0014:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0015:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0016:         * version 2 for more details (a copy is included in the LICENSE file that
0017:         * accompanied this code).
0018:         *
0019:         * You should have received a copy of the GNU General Public License version
0020:         * 2 along with this work; if not, write to the Free Software Foundation,
0021:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0022:         *
0023:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0024:         * CA 95054 USA or visit www.sun.com if you need additional information or
0025:         * have any questions.
0026:         *
0027:         * $Revision: 1.13 $
0028:         * $Date: 2008/02/28 20:17:32 $
0029:         * $State: Exp $
0030:         */
0031:
0032:        package javax.media.j3d;
0033:
0034:        import javax.vecmath.*;
0035:        import java.util.Vector;
0036:        import java.util.ArrayList;
0037:        import java.util.LinkedList;
0038:        import java.util.Iterator;
0039:        import java.util.Enumeration;
0040:        import java.awt.*;
0041:        import com.sun.j3d.utils.universe.Viewer; // Needed for Support of DVR.
0042:
0043:        /**
0044:         * The View object contains all parameters needed in rendering a
0045:         * three dimensional scene from one viewpoint.  A view contains a list
0046:         * of Canvas3D objects that the view is rendered into.  It exists outside
0047:         * of the scene graph, but attaches to a ViewPlatform leaf node object
0048:         * in the scene graph.  It also contains a reference to a PhysicalBody
0049:         * and a PhysicalEnvironment object.
0050:         * <P>
0051:         * The View object is the main Java 3D object for controlling the
0052:         * Java 3D viewing model. All of the components that specify the
0053:         * view transform used to render to the 3D canvases are either contained
0054:         * in the View object or in objects that are referenced by the View
0055:         * object.
0056:         * <P>
0057:         * Java 3D allows applications to specify multiple simultaneously active
0058:         * View objects, each controlling its own set of canvases.
0059:         * <P>
0060:         * The Java 3D View object has several instance variables and methods,
0061:         * but most are calibration variables or user-helping functions. The
0062:         * viewing policies defined by the View object are described below.
0063:         * <P>
0064:         * <b>Policies</b><P>
0065:         *
0066:         * The View object defines the following policies:<P>
0067:         * <UL>
0068:         * <LI>View policy - informs Java 3D whether it should generate
0069:         * the view using the head-tracked system of transformations or the
0070:         * head-mounted system of transformations. These policies are attached
0071:         * to the Java 3D View object. There are two view policies:</LI><P>
0072:         * <UL>
0073:         * <LI>SCREEN_VIEW - specifies that Java 3D should compute a new
0074:         * viewpoint using the sequence of transforms appropriate to screen-based
0075:         * head-tracked display environments (fish-tank VR/portals/VR-desks).
0076:         * This is the default setting.</LI><P>
0077:         * <LI>HMD_VIEW - specifies that Java 3D should compute a new viewpoint
0078:         * using the sequence of transforms appropriate to head mounted display
0079:         * environments. This policy is not available in compatibility mode
0080:         * (see the setCompatibilityModeEnable method description).</LI><P>
0081:         * </UL>
0082:         * <LI>Projection policy - specifies whether Java 3D should generate
0083:         * a parallel projection or a perspective projection. This policy
0084:         * is attached to the Java 3D View object. There are two projection
0085:         * policies:</LI><P>
0086:         * <UL>
0087:         * <LI>PARALLEL_PROJECTION - specifies that a parallel projection
0088:         * transform is computed.</LI><P>
0089:         * <LI>PERSPECTIVE_PROJECTION - specifies that a perspective projection
0090:         * transform is computed. This is the default policy.</LI><P>
0091:         * </UL>
0092:         * <LI>Screen scale policy - specifies where the screen scale comes from.
0093:         * There are two screen scale policies:</LI><P>
0094:         * <UL>
0095:         * <LI>SCALE_SCREEN_SIZE - specifies that the scale is derived from the
0096:         * physical screen according to the following formula (this is the
0097:         * default mode):</LI>
0098:         * <UL>
0099:         * <code>screenScale = physicalScreenWidth / 2.0</code><P>
0100:         * </UL>
0101:         * <LI>SCALE_EXPLICIT - pecifies that the scale is taken directly from
0102:         * the user-provided <code>screenScale</code> attribute (see the
0103:         * setScreenScale method description).</LI><P>
0104:         * </UL>
0105:         * <LI>Window resize policy - specifies how Java 3D modifies the view
0106:         * when users resize windows. When users resize or move windows,
0107:         * Java 3D can choose to think of the window as attached either to
0108:         * the physical world or to the virtual world. The window resize
0109:         * policy allows an application to specify how the
0110:         * view model will handle resizing requests.
0111:         * There are two window resize policies:</LI><P>
0112:         * <UL>
0113:         * <LI>VIRTUAL_WORLD - implies that the original image remains the
0114:         * same size on the screen but the user sees more or less of the
0115:         * virtual world depending on whether the window grew or shrank
0116:         * in size.</LI><P>
0117:         * <LI>PHYSICAL_WORLD - implies that the original image continues
0118:         * to fill the window in the same way using more or less pixels
0119:         * depending on whether the window grew or shrank in size.</LI><P>
0120:         * </UL>
0121:         * <LI>Window movement policy - specifies what part of the virtual
0122:         * world Java 3D draws as a function of window placement on the screen.
0123:         * There are two window movement policies:</LI><P>
0124:         * <UL>
0125:         * <LI>VIRTUAL_WORLD - implies that the image seen in the window
0126:         * changes as the position of the window shifts on the screen.
0127:         * (This mode acts as if the window were a window into the virtual
0128:         * world.)</LI><P>
0129:         * <LI>PHYSICAL_WORLD - implies that the image seen in the window
0130:         * remains the same no matter where the user positions the window
0131:         * on the screen.</LI><P>
0132:         * </UL>
0133:         * <LI>Window eyepoint policy - comes into effect in a non-head-tracked
0134:         * environment. The policy tells Java 3D how to construct a new view
0135:         * frustum based on changes in the field of view and in the Canvas3D's
0136:         * location on the screen. The policy only comes into effect when the
0137:         * application changes a parameter that can change the placement of the
0138:         * eyepoint relative to the view frustum.
0139:         * There are three window eyepoint policies:</LI><P>
0140:         * <UL>
0141:         * <LI>RELATIVE_TO_SCREEN - tells Java 3D to interpret the eye's position
0142:         * relative to the entire screen. No matter where an end user moves a
0143:         * window (a Canvas3D), Java 3D continues to interpret the eye's position
0144:         * relative to the screen. This implies that the view frustum changes shape
0145:         * whenever an end user moves the location of a window on the screen.
0146:         * In this mode, the field of view is read-only.</LI><P>
0147:         * <LI>RELATIVE_TO_WINDOW - specifies that Java 3D should interpret the
0148:         * eye's position information relative to the window (Canvas3D). No matter
0149:         * where an end user moves a window (a Canvas3D), Java 3D continues to
0150:         * interpret the eye's position relative to that window. This implies
0151:         * that the frustum remains the same no matter where the end user
0152:         * moves the window on the screen. In this mode, the field of view
0153:         * is read-only.</LI><P>
0154:         * <LI>RELATIVE_TO_FIELD_OF_VIEW - tells Java 3D that it should
0155:         * modify the eyepoint position so it is located at the appropriate
0156:         * place relative to the window to match the specified field of view.
0157:         * This implies that the view frustum will change whenever the
0158:         * application changes the field of view. In this mode, the eye
0159:         * position is read-only. This is the default setting.</LI><P>
0160:         * <LI>RELATIVE_TO_COEXISTENCE - tells Java 3D to interpret the eye's
0161:         * position in coexistence coordinates. In this mode, the eye position
0162:         * is taken from the view (rather than the Canvas3D) and transformed from
0163:         * coexistence coordinates to image plate coordinates for each
0164:         * Canvas3D.  The resulting eye position is relative to the screen. As
0165:         * in RELATIVE_TO_SCREEN mode, this implies that the view frustum
0166:         * changes shape whenever an end user moves the location of a window
0167:         * on the screen.  In this mode, the field of view is
0168:         * read-only.</LI><P>
0169:         * </UL>
0170:         * <LI>Front and back clip policies - specifies how Java 3D
0171:         * interprets clipping distances to both the near and far clip
0172:         * planes. The policies can contain one of four values specifying
0173:         * whether a distance measurement should be interpreted in
0174:         * the physical or the virtual world and whether that distance
0175:         * measurement should be interpreted relative to the physical
0176:         * eyepoint or the physical screen.
0177:         * The front and back clip policies
0178:         * are specified separately. The front clip policy determines
0179:         * where Java 3D places the front clipping plane. The back clip
0180:         * policy determines where Java 3D places the back clipping plane.
0181:         * The values for both front and back clipping planes are:</LI><P>
0182:         * <UL>
0183:         * <LI>VIRTUAL_EYE - specifies that the associated distance is from
0184:         * the eye and in units of virtual distance.</LI><P>
0185:         * <LI>PHYSICAL_EYE - specifies that the associated distance is from
0186:         * the eye and in units of physical distance (in meters).
0187:         * This is the default policy for both front and back clipping.</LI><P>
0188:         * <LI>VIRTUAL_SCREEN  - specifies that the associated distance is
0189:         * from the screen and in units of virtual distance. </LI><P>
0190:         * <LI>PHYSICAL_SCREEN - specifies that the associated distance is
0191:         * from the screen and in units of physical distance (in meters).
0192:         * </LI><P>
0193:         * </UL>
0194:         * <LI>Visibility policy - specifies how visible and invisible objects
0195:         * are drawn. There are three visibility policies:</LI><P>
0196:         * <UL>
0197:         * <LI>VISIBILITY_DRAW_VISIBLE - only visible objects are drawn
0198:         * (this is the default).</LI><P>
0199:         * <LI>VISIBILITY_DRAW_INVISIBLE - only invisible objects are drawn.</LI><P>
0200:         * <LI>VISIBILITY_DRAW_ALL - both visible and invisible
0201:         * objects are drawn. </LI><P>
0202:         * </UL>
0203:         * <LI>Transparency sorting policy - specifies whether and how
0204:         * transparent objects are sorted.  Sorting multiple transparent
0205:         * objects is necessary to avoid artifacts caused by overlapping
0206:         * transparent objects.  There are two transparency sorting
0207:         * policies:</LI><P>
0208:         * <UL>
0209:         * <LI>TRANSPARENCY_SORT_NONE - no depth sorting of transparent
0210:         * objects is performed (this is the default).  Transparent objects
0211:         * are drawn after opaque objects, but are not sorted from back to
0212:         * front.</LI><P>
0213:         * <LI>TRANSPARENCY_SORT_GEOMETRY - transparent objects are
0214:         * depth-sorted on a per-geometry basis.  Each geometry object of each
0215:         * transparent Shape3D node is drawn from back to front.  Note that
0216:         * this policy will not split geometry into smaller pieces, so
0217:         * intersecting or intertwined objects may not be sorted
0218:         * correctly.  The method used for determining which geometry is closer
0219:         * is implementation dependent.</LI><P>
0220:         * </UL>
0221:         * </UL>
0222:         * <b>Projection and Clip Parameters</b><P>
0223:         * The projection and clip parameters determine the view model's
0224:         * field of view and the front and back clipping distances.<P>
0225:         * <UL>
0226:         * <LI>Field of view - specifies the view model's horizontal
0227:         * field of view in radians, when in the default non-head-tracked
0228:         * mode. This value is ignored when the view model is operating
0229:         * in head-tracked mode, or when the Canvas3D's window eyepoint
0230:         * policy is set to a value other than the default setting of
0231:         * RELATIVE_TO_FIELD_OF_VIEW.</LI><P>
0232:         * <LI>Front clip distance - specifies the distance away from the
0233:         * clip origin, specified by the front clip policy variable, in
0234:         * the direction of gaze where objects stop disappearing. Objects
0235:         * closer than the clip origin (eye or screen)
0236:         * plus the front clip distance are not drawn. Measurements are
0237:         * done in the space (physical or virtual) that is specified by
0238:         * the associated front clip policy parameter.</LI><P>
0239:         * <LI>Back clip distance - specifies the distance away from the
0240:         * clip origin (specified by the back clip policy variable) in the
0241:         * direction of gaze where objects begin disappearing. Objects
0242:         * farther away from the clip origin (eye or
0243:         * screen) plus the back clip distance are not drawn.
0244:         * Measurements are done in the space (physical or virtual) that
0245:         * is specified by the associated back clip policy
0246:         * parameter. The View object's back clip distance is ignored
0247:         * if the scene graph contains an active Clip leaf node.</LI><P>
0248:         * There are several considerations to take into account when
0249:         * choosing values for the front and back clip distances.<P>
0250:         * <UL>
0251:         * <LI>The front clip distance must be greater than 0.0 in physical
0252:         * eye coordinates.</LI><P>
0253:         * <LI>The front clipping plane must be in front of the back clipping
0254:         * plane, that is, the front clip distance must be less than the
0255:         * back clip distance in physical eye coordinates.</LI><P>
0256:         * <LI>The front and back clip distances, in physical eye coordinates,
0257:         * must be less than the largest positive single-precision floating
0258:         * point value, Float.MAX_VALUE. In practice, since these physical
0259:         * eye coordinate distances are in meters, the values
0260:         * should be much less than that.</LI><P>
0261:         * <LI>The ratio of the back distance divided by the front distance,
0262:         * in physical eye coordinates, affects Z-buffer precision. This ratio
0263:         * should be less than about 3000 to accommodate 16-bit Z-buffers.
0264:         * Values of 100 to less than 1000 will produce better results.</LI><P>
0265:         * </UL>
0266:         * Violating any of the above rules will result in undefined behavior.
0267:         * In many cases, no picture will be drawn.<P>
0268:         * </UL>
0269:         * <b>Frame Start Time, Duration, and Number</b><P>
0270:         *
0271:         * There are five methods used to get information about system
0272:         * execution and performance:<P>
0273:         * <UL>
0274:         * <code>getCurrentFrameStartTime</code> returns the time at which 
0275:         * the most recent rendering frame started.<P>
0276:         * <code>getLastFrameDuration</code> returns the duration, in milliseconds, of
0277:         * the most recently completed rendering frame.<P>
0278:         * <code>getFrameNumber</code> returns the frame number for this view.<P>
0279:         * <code>getMaxFrameStartTimes</code> retrieves the implementation-dependent
0280:         * maximum number of frames whose start times will be recorded by
0281:         * the system.<P>
0282:         * <code>getFrameStartTimes</code> copies the last k frame start time values
0283:         * into the user-specified array.<P>
0284:         * </UL>
0285:         * <b>View Traversal and Behavior Scheduling</b><P>
0286:         * The following methods control the traversal, the rendering, and
0287:         * the execution of the behavior scheduler for this view:<P>
0288:         * <UL>
0289:         * <code>startBehaviorScheduler</code> starts the behavior scheduler 
0290:         * running after it has been stopped.<P>
0291:         * <code>stopBehaviorScheduler</code> stops the behavior scheduler after all
0292:         * currently-scheduled behaviors are executed.<P>
0293:         * <code>isBehaviorSchedulerRunning</code> retrieves a flag that indicates
0294:         * whether the behavior scheduler is currently running.<P>
0295:         * <code>startView</code> starts traversing this view and starts the renderers
0296:         * associated with all canvases attached to this view.<P>
0297:         * <code>stopView</code> stops traversing this view after the current state of
0298:         * the scene graph is reflected on all canvases attached to this
0299:         * view.<P>
0300:         * <code>isViewRunning</code> returns a flag indicating whether the traverser
0301:         * is currently running on this view.<P>
0302:         * </UL>
0303:         * Note: The above six methods are heavy-weight methods intended
0304:         * for verification and image capture (recording). They are not
0305:         * intended to be used for flow control.<P>
0306:         *
0307:         * <b>Scene Antialiasing</b><P>
0308:         *
0309:         * The following methods set and retrieve the scene antialiasing
0310:         * flag. Scene antialiasing is either enabled or disabled for this
0311:         * view. If enabled, the entire scene will be antialiased on each
0312:         * canvas in which scene antialiasing is available. Scene
0313:         * antialiasing is disabled by default.<P>
0314:         * <UL>
0315:         * <code>setSceneAntialiasingEnable</code> sets the scene antialiasing flag.<P>
0316:         * <code>getSceneAntialiasingEnable</code> returns the scene antialiasing
0317:         * flag.<P>
0318:         * </UL>
0319:         * Note that line and point antialiasing are independent of scene 
0320:         * antialiasing. If antialiasing is enabled for lines and points, 
0321:         * the lines and points will be antialiased prior to scene antialiasing.
0322:         * If scene antialiasing is disabled, antialiased lines and points will
0323:         * still be antialiased.
0324:         * <p>
0325:         * <b>Note:</b> Scene antialiasing is ignored in pure immediate mode,
0326:         * but is supported in mixed-immediate mode.
0327:         * <p>
0328:         * <b>Depth Buffer</b><P>
0329:         *
0330:         * The following two methods enable and disable automatic freezing
0331:         * of the depth buffer for objects rendered during the transparent
0332:         * rendering pass (that is, objects rendered using alpha blending)
0333:         * for this view. If enabled, depth buffer writes are disabled
0334:         * during the transparent rendering pass regardless of the value
0335:         * of the depth-buffer-write-enable flag in the RenderingAttributes
0336:         * object for a particular node. This flag is enabled by default.<P>
0337:         * <UL>
0338:         * <code>setDepthBufferFreezeTransparent</code> enables depth buffer freezing.<P>
0339:         * <code>getDepthBufferFreezeTransparent</code> retrieves the depth buffer
0340:         * flag.<P>
0341:         * </UL>
0342:         * Transparent objects include BLENDED transparent primitives
0343:         * and antialiased lines
0344:         * and points. Transparent objects do not include opaque objects
0345:         * or primitives rendered with SCREEN_DOOR transparency.<p>
0346:         *
0347:         * <b>Sensors</b><P>
0348:         *
0349:         * The following methods retrieve the sensor's location in the
0350:         * virtual world:<P>
0351:         * <UL>
0352:         * <code>getSensorToVworld</code> takes the sensor's last reading and
0353:         * generates a sensor-to-vworld coordinate system transform. This
0354:         * Transform3D object takes points in that sensor's local coordinate
0355:         * system and transforms them into virtual world coordinates.<P>
0356:         *
0357:         * <code>getSensorHotSpotInVworld</code> retrieves the specified sensor's
0358:         * last hotspot location in virtual world coordinates.<P>
0359:         * </UL>
0360:         *
0361:         * <b>Compatibility Mode</b><P>
0362:         *
0363:         * A camera-based view model allows application programmers to think
0364:         * about the images displayed on the computer screen as if a virtual
0365:         * camera took those images. Such a view model allows application
0366:         * programmers to position and orient a virtual camera within a
0367:         * virtual scene, to manipulate some parameters of the virtual
0368:         * camera's lens (specify its field of view), and to specify the
0369:         * locations of the near and far clipping planes.<P>
0370:         * Java 3D allows applications to enable compatibility mode for
0371:         * room-mounted, non-head-tracked display environments, or to disable
0372:         * compatibility mode using the following methods. Camera-based
0373:         * viewing functions are only available in compatibility mode.<P>
0374:         * <UL>
0375:         * <code>setCompatibilityModeEnable</code> turns compatibility mode on or off.
0376:         * Compatibility mode is disabled by default.<P>
0377:         * <code>getCompatabilityModeEnable</code> returns the compatibility mode
0378:         * enable flag.<P>
0379:         * </UL>
0380:         * Use of these view-compatibility functions will disable some of
0381:         * Java 3D's view model features and limit the portability of Java
0382:         * 3D programs. These methods are primarily intended to help
0383:         * jump-start porting of existing applications.<P>
0384:         *
0385:         * Setting the Viewing Transform<P>
0386:         *
0387:         * The View object provides the following compatibility-mode
0388:         * methods that operate on the viewing transform.<P>
0389:         * <UL>
0390:         * <code>setVpcToEc</code> a compatibility mode method that 
0391:         * specifies the ViewPlatform
0392:         * coordinates (VPC) to eye coordinates viewing transform.<P>
0393:         * <code>getVpcToEc</code> returns the VPC.<P>
0394:         * </UL>
0395:         * Setting the Projection Transform
0396:         * <p>
0397:         * The View object provides the following compatibility-mode
0398:         * methods that operate on the projection transform:<P>
0399:         * <UL>
0400:         * The <code>setLeftProjection</code> and <code>setRightProjection</code> 
0401:         * methods specify
0402:         * a viewing frustum for the left and right eye that transforms
0403:         * points in eye coordinates to clipping coordinates.<P>
0404:         * 
0405:         * The <code>getLeftProjection</code> and <code>getRightProjection</code> 
0406:         * methods return
0407:         * the viewing frustum for the left and right eye.<P>
0408:         * </UL>
0409:         *
0410:         * <p>
0411:         * <b>Additional Information</b>
0412:         * <p>
0413:         * For more information, see the
0414:         * <a href="doc-files/intro.html">Introduction to the Java 3D API</a> and
0415:         * <a href="doc-files/ViewModel.html">View Model</a>
0416:         * documents.
0417:         *
0418:         * @see Canvas3D
0419:         * @see PhysicalBody
0420:         * @see PhysicalEnvironment
0421:         * @see ViewPlatform
0422:         * @see TransparencyAttributes
0423:         */
0424:
0425:        public class View extends Object {
0426:            /**
0427:             * Specifies a policy whereby the origin of physical or virtual
0428:             * coordinates is relative to the position of the nominal head.
0429:             * When used as a view attach policy, this sets the origin of view
0430:             * platform coordinates to be at the eyepoint.
0431:             * @see ViewPlatform#setViewAttachPolicy
0432:             * @see PhysicalEnvironment#setCoexistenceCenterInPworldPolicy
0433:             */
0434:            public static final int NOMINAL_HEAD = 0;
0435:
0436:            /**
0437:             * Specifies a policy whereby the origin of physical or virtual
0438:             * coordinates is relative to the position of the nominal feet.
0439:             * When used as a view attach policy, this sets the origin of view
0440:             * platform coordinates to be at the ground plane.
0441:             * @see ViewPlatform#setViewAttachPolicy
0442:             * @see PhysicalEnvironment#setCoexistenceCenterInPworldPolicy
0443:             */
0444:            public static final int NOMINAL_FEET = 1;
0445:
0446:            /**
0447:             * Specifies a policy whereby the origin of physical or virtual
0448:             * coordinates is relative to the screen.
0449:             * When used as a view attach policy, this sets the origin of view
0450:             * platform coordinates to be at the center of the window or screen,
0451:             * in effect, allowing the user to view objects from an optimal viewpoint.
0452:             * @see ViewPlatform#setViewAttachPolicy
0453:             * @see PhysicalEnvironment#setCoexistenceCenterInPworldPolicy
0454:             */
0455:            public static final int NOMINAL_SCREEN = 2;
0456:
0457:            /**
0458:             * Specifies that the screen scale for this view is derived from
0459:             * the physical screen size.  This scale factor is computed as follows:
0460:             * <ul>
0461:             * physical_screen_width / 2.0
0462:             * </ul>
0463:             * This allows an application to define a world in a normalized
0464:             * [-1,1] space and view it on a screen of any size.
0465:             * @see #setScreenScalePolicy
0466:             */
0467:            public static final int SCALE_SCREEN_SIZE = 0;
0468:
0469:            /**
0470:             * Specifies that the screen scale for this view is taken directly
0471:             * from the user-provided screenScale parameter.
0472:             * @see #setScreenScalePolicy
0473:             * @see #setScreenScale
0474:             */
0475:            public static final int SCALE_EXPLICIT = 1;
0476:
0477:            /**
0478:             * Specifies that the associated distance is measured
0479:             * from the screen in virtual world coordinates.
0480:             * Policy for interpreting clip plane distances.
0481:             * Used in specifying the policy in frontClipPolicy and backClipPolicy.
0482:             * @see #setFrontClipPolicy
0483:             * @see #setBackClipPolicy
0484:             */
0485:            public static final int VIRTUAL_SCREEN = 0;
0486:
0487:            /**
0488:             * Specifies that the associated distance is measured
0489:             * from the screen in meters.
0490:             * Policy for interpreting clip plane distances.
0491:             * Used in specifying the policy in frontClipPolicy and backClipPolicy.
0492:             * @see #setFrontClipPolicy
0493:             * @see #setBackClipPolicy
0494:             */
0495:            public static final int PHYSICAL_SCREEN = 1;
0496:
0497:            /**
0498:             * Specifies that the associated distance is measured
0499:             * from the eye in virtual world coordinates.
0500:             * Policy for interpreting clip plane distances.
0501:             * Used in specifying the policy in frontClipPolicy and backClipPolicy.
0502:             * @see #setFrontClipPolicy
0503:             * @see #setBackClipPolicy
0504:             */
0505:            public static final int VIRTUAL_EYE = 2;
0506:
0507:            /**
0508:             * Specifies that the associated distance is measured
0509:             * from the eye in meters.
0510:             * Policy for interpreting clip plane distances.
0511:             * Used in specifying the policy in frontClipPolicy and backClipPolicy.
0512:             * This is the default policy for both front and back clipping.
0513:             * @see #setFrontClipPolicy
0514:             * @see #setBackClipPolicy
0515:             */
0516:            public static final int PHYSICAL_EYE = 3;
0517:
0518:            /**
0519:             * Policy for resizing and moving windows.
0520:             * Used in specifying windowResizePolicy and windowMovementPolicy.
0521:             * VIRTUAL_WORLD specifies that the associated action takes place
0522:             * in the virtual world as well as in the physical world.
0523:             * @see #setWindowResizePolicy
0524:             * @see #setWindowMovementPolicy
0525:             */
0526:            public static final int VIRTUAL_WORLD = 0;
0527:
0528:            /**
0529:             * Policy for resizing and moving windows.
0530:             * Used in specifying windowResizePolicy and windowMovementPolicy.
0531:             * PHYSICAL_WORLD specifies that the specified action takes place
0532:             * only in the physical world.
0533:             * @see #setWindowResizePolicy
0534:             * @see #setWindowMovementPolicy
0535:             */
0536:            public static final int PHYSICAL_WORLD = 1;
0537:
0538:            /**
0539:             * Policy for placing the eyepoint in non-head-tracked modes.
0540:             * Specifies that Java 3D should interpret the
0541:             * given fixed eyepoint position as relative to the entire screen.
0542:             * This implies
0543:             * that the view frustum shape will change whenever a
0544:             * user moves the location of a window on the screen.
0545:             * @see #setWindowEyepointPolicy
0546:             */
0547:            public static final int RELATIVE_TO_SCREEN = 0;
0548:
0549:            /**
0550:             * Policy for placing the eyepoint in non-head-tracked modes.
0551:             * Specifies that Java 3D should interpret the
0552:             * given fixed-eyepoint position as relative to the window.
0553:             * @see #setWindowEyepointPolicy
0554:             */
0555:            public static final int RELATIVE_TO_WINDOW = 1;
0556:
0557:            /**
0558:             * Policy for placing the eyepoint in non-head-tracked modes.
0559:             * Specifies that Java 3D should
0560:             * modify the position of the eyepoint to match any changes in field
0561:             * of view; the view frustum will change whenever the application
0562:             * program changes the field of view.
0563:             * <p>
0564:             * NOTE: when this policy is specified, the Z coordinate of
0565:             * the derived eyepoint is used in place of
0566:             * nominalEyeOffsetFromNominalScreen.
0567:             * @see #setWindowEyepointPolicy
0568:             */
0569:            public static final int RELATIVE_TO_FIELD_OF_VIEW = 2;
0570:
0571:            /**
0572:             * Policy for placing the eyepoint in non-head-tracked modes.
0573:             * Specifies that Java 3D should interpret the fixed eyepoint
0574:             * position in the view as relative to the origin
0575:             * of coexistence coordinates.  This eyepoint is transformed from
0576:             * coexistence coordinates to image plate coordinates for each
0577:             * Canvas3D.
0578:             * As in RELATIVE_TO_SCREEN mode, this implies
0579:             * that the view frustum shape will change whenever a
0580:             * user moves the location of a window on the screen.
0581:             * @see #setWindowEyepointPolicy
0582:             *
0583:             * @since Java 3D 1.2
0584:             */
0585:            public static final int RELATIVE_TO_COEXISTENCE = 3;
0586:
0587:            /**
0588:             * Specifies that monoscopic view generated should be the view as seen
0589:             * from the left eye.
0590:             * @see Canvas3D#setMonoscopicViewPolicy
0591:             */
0592:            public static final int LEFT_EYE_VIEW = 0;
0593:
0594:            /**
0595:             * Specifies that monoscopic view generated should be the view as seen
0596:             * from the right eye.
0597:             * @see Canvas3D#setMonoscopicViewPolicy
0598:             */
0599:            public static final int RIGHT_EYE_VIEW = 1;
0600:
0601:            /**
0602:             * Specifies that monoscopic view generated should be the view as seen
0603:             * from the 'center eye', the fictional eye half-way between the left and
0604:             * right eye.
0605:             * @see Canvas3D#setMonoscopicViewPolicy
0606:             */
0607:            public static final int CYCLOPEAN_EYE_VIEW = 2;
0608:
0609:            /**
0610:             * Specifies that the viewing environment for this view is a
0611:             * standard screen-based display environment.
0612:             * In this mode, Java 3D will compute new viewpoints
0613:             * using that sequence of transforms appropriate to screen-based,
0614:             * display environments, that may or may not include head tracking
0615:             * (e.g., a monoscopic screen, fish-tank VR, portals, VR-desks).
0616:             * This is the default mode.
0617:             * @see #setViewPolicy
0618:             */
0619:            public static final int SCREEN_VIEW = 0;
0620:
0621:            /**
0622:             * Specifies that the viewing environment for this view is a
0623:             * head-mounted display environment.
0624:             * In this mode, Java 3D will compute new viewpoints
0625:             * using that sequence of transforms appropriate to head-mounted display
0626:             * environments.  These environments are generally head-tracked.
0627:             * @see #setViewPolicy
0628:             */
0629:            public static final int HMD_VIEW = 1;
0630:
0631:            /**
0632:             * Specifies that Java 3D should generate a parallel projection matrix
0633:             * for this View.
0634:             * @see #setProjectionPolicy
0635:             */
0636:            public static final int PARALLEL_PROJECTION = 0;
0637:
0638:            /**
0639:             * Specifies that Java 3D should generate a perspective projection matrix
0640:             * for this View.
0641:             * This is the default mode.
0642:             * @see #setProjectionPolicy
0643:             */
0644:            public static final int PERSPECTIVE_PROJECTION = 1;
0645:
0646:            /**
0647:             * Policy that specifies that only visible objects should be drawn.
0648:             * This is the default mode.
0649:             * @see #setVisibilityPolicy
0650:             *
0651:             * @since Java 3D 1.2
0652:             */
0653:            public static final int VISIBILITY_DRAW_VISIBLE = 0;
0654:
0655:            /**
0656:             * Policy that specifies that only invisible objects should be drawn.
0657:             * @see #setVisibilityPolicy
0658:             *
0659:             * @since Java 3D 1.2
0660:             */
0661:            public static final int VISIBILITY_DRAW_INVISIBLE = 1;
0662:
0663:            /**
0664:             * Policy that specifies that both visible and invisible objects
0665:             * should be drawn.
0666:             * @see #setVisibilityPolicy
0667:             *
0668:             * @since Java 3D 1.2
0669:             */
0670:            public static final int VISIBILITY_DRAW_ALL = 2;
0671:
0672:            /**
0673:             * Policy that specifies that no sorting of transparent objects
0674:             * is done.
0675:             * This is the default mode.
0676:             * @see #setTransparencySortingPolicy
0677:             *
0678:             * @since Java 3D 1.3
0679:             */
0680:            public static final int TRANSPARENCY_SORT_NONE = 0;
0681:
0682:            /**
0683:             * Policy that specifies that transparent objects
0684:             * are sorted from back to front on a per-geometry basis.
0685:             * @see #setTransparencySortingPolicy
0686:             *
0687:             * @since Java 3D 1.3
0688:             */
0689:            public static final int TRANSPARENCY_SORT_GEOMETRY = 1;
0690:
0691:            //
0692:            // The AWT window for display.
0693:            //
0694:            // This object can be queried to obtain:
0695:            // screen width in pixels
0696:            // screen height in pixels
0697:            // window width in pixels
0698:            // window height in pixels
0699:            // window upper left corner location in pixels relative to screen
0700:            //
0701:            // Use getCanvases() to access this
0702:            private Vector canvases = new Vector(3);
0703:
0704:            //
0705:            // The current universe associated with this view
0706:            //
0707:            VirtualUniverse universe = null;
0708:
0709:            //
0710:            // The RenderBin associated with this view.
0711:            //
0712:            RenderBin renderBin = null;
0713:
0714:            // This is the SoundScheduler associated with this view.
0715:            SoundScheduler soundScheduler = null;
0716:
0717:            // This is the thread associated with this view.
0718:            SoundRenderer soundRenderer = new SoundRenderer();
0719:
0720:            // AudioDevice enumerator current position
0721:            //    AudioDeviceEnumerator allAudioEnumerator = null;
0722:
0723:            // These are used for tracking the frame times
0724:            static final int NUMBER_FRAME_START_TIMES = 10;
0725:
0726:            long[] frameStartTimes = new long[NUMBER_FRAME_START_TIMES];
0727:            long[] frameNumbers = new long[NUMBER_FRAME_START_TIMES];
0728:            int currentFrameIndex = 0;
0729:
0730:            // These are the values that are set at the end of each frame
0731:            long currentFrameStartTime = 0;
0732:            long currentFrameDuration = 0;
0733:            long currentFrameNumber = 0;
0734:
0735:            // These are the ones that get updated directly by MC
0736:            long frameNumber = 0;
0737:            long startTime = 0;
0738:            long stopTime = 0;
0739:
0740:            // Support dynamic video resize -- DVR.
0741:            Viewer viewer = null; // Cached the associate viewer of this view.
0742:            boolean firstTime = true;
0743:            //    float dvrFactor = 1.0f;
0744:            //    boolean dvrResizeCompensation = true;
0745:
0746:            // User adjustable minimum frame cycle time
0747:            long minFrameCycleTime;
0748:
0749:            // True when stopBehaviorScheduler invoke
0750:            boolean stopBehavior;
0751:
0752:            //
0753:            // View cache for this view.
0754:            //
0755:            ViewCache viewCache = null;
0756:
0757:            // Compatibility mode related field has changed.
0758:            // { compatibilityModeEnable, compatVpcToEc, compatLeftProjection,
0759:            //   compatRightProjection }
0760:            static final int COMPATIBILITY_MODE_DIRTY = 0x01;
0761:            // ScreenScalePolicy field has changed.
0762:            static final int SCREEN_SCALE_POLICY_DIRTY = 0x02;
0763:            // Screen scale field has changed.
0764:            static final int SCREEN_SCALE_DIRTY = 0x04;
0765:            // Window Resize Policy field has changed.
0766:            static final int WINDOW_RESIZE_POLICY_DIRTY = 0x08;
0767:            // View Policy eye in image plate field has changed.
0768:            static final int VIEW_POLICY_DIRTY = 0x10;
0769:            // Clip related field has changed.
0770:            // { frontClipDistance, backClipDistance, frontClipPolicy, backClipPolicy }
0771:            static final int CLIP_DIRTY = 0x20;
0772:            // Projection Policy field has changed.
0773:            static final int PROJECTION_POLICY_DIRTY = 0x40;
0774:            // Window Movement Policy field has changed.
0775:            static final int WINDOW_MOVEMENT_POLICY_DIRTY = 0x80;
0776:            // Window Eye Point Policy field has changed.
0777:            static final int WINDOW_EYE_POINT_POLICY_DIRTY = 0x100;
0778:            // Monoscopic View Policy field has changed.
0779:            static final int MONOSCOPIC_VIEW_POLICY_DIRTY = 0x200;
0780:            // Field Of View field has changed.
0781:            static final int FIELD_OF_VIEW_DIRTY = 0x400;
0782:            // Tracking Enable field has changed.
0783:            static final int TRACKING_ENABLE_DIRTY = 0x800;
0784:            // User Head To Vworld Enable field has changed.
0785:            static final int USER_HEAD_TO_VWORLD_ENABLE_DIRTY = 0x1000;
0786:            // coexistenceCenteringEnable flag has changed.
0787:            static final int COEXISTENCE_CENTERING_ENABLE_DIRTY = 0x2000;
0788:            // leftManualEyeInCoexistence has changed.
0789:            static final int LEFT_MANUAL_EYE_IN_COEXISTENCE_DIRTY = 0x4000;
0790:            // rightManualEyeInCoexistence has changed.
0791:            static final int RIGHT_MANUAL_EYE_IN_COEXISTENCE_DIRTY = 0x8000;
0792:            // visibilityPolicy has changed.
0793:            static final int VISIBILITY_POLICY_DIRTY = 0x10000;
0794:
0795:            // This is not from View object. It is here for the purpose
0796:            // keeping all ViewCache's dirty mask bit declaration in one place.
0797:            // ViewPlatformRetained viewAttach Policy field has changed.
0798:            static final int VPR_VIEW_ATTACH_POLICY_DIRTY = 0x10000;
0799:            static final int VPR_VIEWPLATFORM_DIRTY = 0x20000;
0800:
0801:            // PhysicalEnvironment fields has changed.
0802:            static final int PE_COE_TO_TRACKER_BASE_DIRTY = 0x100000;
0803:            static final int PE_TRACKING_AVAILABLE_DIRTY = 0x200000;
0804:            static final int PE_COE_CENTER_IN_PWORLD_POLICY_DIRTY = 0x400000;
0805:
0806:            // PhysicalBody fields has changed.
0807:            static final int PB_EYE_POSITION_DIRTY = 0x1000000;
0808:            static final int PB_EAR_POSITION_DIRTY = 0x2000000;
0809:            static final int PB_NOMINAL_EYE_HEIGHT_FROM_GROUND_DIRTY = 0x4000000;
0810:            static final int PB_NOMINAL_EYE_OFFSET_FROM_NOMINAL_SCREEN_DIRTY = 0x8000000;
0811:
0812:            // Mask that indicates this View's view dependence info. has changed,
0813:            // and CanvasViewCache may need to recompute the final view matries.
0814:            int vDirtyMask = (COMPATIBILITY_MODE_DIRTY
0815:                    | SCREEN_SCALE_POLICY_DIRTY | SCREEN_SCALE_DIRTY
0816:                    | WINDOW_RESIZE_POLICY_DIRTY | VIEW_POLICY_DIRTY
0817:                    | CLIP_DIRTY | PROJECTION_POLICY_DIRTY
0818:                    | WINDOW_MOVEMENT_POLICY_DIRTY
0819:                    | WINDOW_EYE_POINT_POLICY_DIRTY
0820:                    | MONOSCOPIC_VIEW_POLICY_DIRTY | FIELD_OF_VIEW_DIRTY
0821:                    | TRACKING_ENABLE_DIRTY | USER_HEAD_TO_VWORLD_ENABLE_DIRTY
0822:                    | COEXISTENCE_CENTERING_ENABLE_DIRTY
0823:                    | LEFT_MANUAL_EYE_IN_COEXISTENCE_DIRTY
0824:                    | RIGHT_MANUAL_EYE_IN_COEXISTENCE_DIRTY | VISIBILITY_POLICY_DIRTY);
0825:
0826:            //
0827:            // This object contains a specification of the user's physical body.
0828:            //
0829:            // Attributes of this object are defined in head coordinates and
0830:            // include information such as the location of the user's eyes and 
0831:            // ears.
0832:            // The origin is defined to be halfway between the left and right eye
0833:            // in the plane of the face.
0834:            // The x-axis extends to the right (of the head looking out from the head).
0835:            // The y-axis extends up. The z-axis extends to the rear of the head.
0836:            //
0837:            PhysicalBody physicalBody;
0838:
0839:            // This object contains a specification of the physical environment.
0840:            PhysicalEnvironment physicalEnvironment;
0841:
0842:            // View model compatibility mode flag
0843:            boolean compatibilityModeEnable = false;
0844:
0845:            // View model coexistenceCenteringEnable flag
0846:            boolean coexistenceCenteringEnable = true;
0847:
0848:            Point3d leftManualEyeInCoexistence = new Point3d();
0849:            Point3d rightManualEyeInCoexistence = new Point3d();
0850:
0851:            //
0852:            // Indicates which major mode of view computation to use:
0853:            // HMD mode or screen/fish-tank-VR mode.
0854:            //
0855:            int viewPolicy = SCREEN_VIEW;
0856:
0857:            // The current projection policy (parallel versus perspective)
0858:            int projectionPolicy = PERSPECTIVE_PROJECTION;
0859:
0860:            //
0861:            // The view model's field of view.
0862:            //
0863:            double fieldOfView = 45.0 * Math.PI / 180.0;
0864:
0865:            //
0866:            // The distance away from the clip origin
0867:            // in the direction of gaze for the front and back clip planes.
0868:            // The default values are in meters.
0869:            //
0870:            double frontClipDistance = 0.1;
0871:            double backClipDistance = 10.0;
0872:
0873:            // This variable specifies where the screen scale comes from
0874:            int screenScalePolicy = SCALE_SCREEN_SIZE;
0875:
0876:            // The screen scale value used when the screen scale policy is
0877:            // SCALE_EXPLICIT
0878:            double screenScale = 1.0;
0879:
0880:            //
0881:            // This variable specifies how Java 3D modifies the view when
0882:            // the window is resized (VIRTUAL_WORLD or PHYSICAL_WORLD).
0883:            //
0884:            int windowResizePolicy = PHYSICAL_WORLD;
0885:
0886:            //
0887:            // This variable specifies how Java 3D modifies the view when
0888:            // the window is moved (VIRTUAL_WORLD or PHYSICAL_WORLD).
0889:            //
0890:            int windowMovementPolicy = PHYSICAL_WORLD;
0891:
0892:            //
0893:            // Specifies how Java 3D handles the predefined eyepoint in
0894:            // non-head-tracked environment (RELATIVE_TO_SCREEN,
0895:            // RELATIVE_TO_WINDOW, RELATIVE_TO_FIELD_OF_VIEW, or
0896:            // RELATIVE_TO_COEXISTENCE)
0897:            //
0898:            int windowEyepointPolicy = RELATIVE_TO_FIELD_OF_VIEW;
0899:
0900:            //
0901:            // Specifies how Java 3D generates monoscopic view
0902:            // (LEFT_EYE_VIEW, RIGHT_EYE_VIEW, or CYCLOPEAN_EYE_VIEW).
0903:            //
0904:            int monoscopicViewPolicy = CYCLOPEAN_EYE_VIEW;
0905:
0906:            /**
0907:             * Defines the policy for placing the front clipping plane.
0908:             * Legal values include PHYSICAL_EYE, PHYSICAL_SCREEN,
0909:             * VIRTUAL_EYE, and VIRTUAL_SCREEN.
0910:             */
0911:            int frontClipPolicy = PHYSICAL_EYE;
0912:
0913:            /**
0914:             * Defines the policy for placing the back clipping plane.
0915:             */
0916:            int backClipPolicy = PHYSICAL_EYE;
0917:
0918:            /**
0919:             * Defines the visibility policy.
0920:             */
0921:            int visibilityPolicy = VISIBILITY_DRAW_VISIBLE;
0922:
0923:            /**
0924:             * Defines the transparency sorting policy.
0925:             */
0926:            int transparencySortingPolicy = TRANSPARENCY_SORT_NONE;
0927:
0928:            /**
0929:             * Flag to enable tracking, if so allowed by the trackingAvailable flag.
0930:             */
0931:            boolean trackingEnable = false;
0932:
0933:            /**
0934:             * This setting enables the continuous updating by Java 3D of the
0935:             * userHeadToVworld transform.
0936:             */
0937:            boolean userHeadToVworldEnable = false;
0938:
0939:            /**
0940:             * The view platform currently associated with this view.
0941:             */
0942:            private ViewPlatform viewPlatform = null;
0943:
0944:            // The current compatibility mode view transform
0945:            Transform3D compatVpcToEc = new Transform3D();
0946:
0947:            // The current compatibility mode projection transforms
0948:            Transform3D compatLeftProjection = new Transform3D();
0949:            Transform3D compatRightProjection = new Transform3D();
0950:
0951:            // The long id of this view - used for dirty bit evaluation in the scene graph
0952:            Integer viewId = null;
0953:            int viewIndex = -1;
0954:
0955:            // A boolean that indicates whether or not this is the primary view
0956:            boolean primaryView = false;
0957:
0958:            // A boolean that indicates whether or not this view is active as
0959:            // seen by MasterControl
0960:            boolean active = false;
0961:
0962:            // A boolean that indicates whether or not this view is active as
0963:            // seen by this view. There is a delay before MasterControl set
0964:            // active flag, so a local activeStatus is used. Otherwise
0965:            // activate event may lost if it proceed by deactivate event
0966:            // but MC not yet set active to false. This happens in
0967:            // viewplatform detach and attach.
0968:            boolean activeStatus = false;
0969:
0970:            // This boolean indicates whether or not the view is running.  It
0971:            // is used for startView/stopView
0972:            volatile boolean isRunning = true;
0973:
0974:            // A flag to indicate that we are in a canvas callback routine
0975:            boolean inCanvasCallback = false;
0976:
0977:            //
0978:            // Flag to enable depth buffer freeze during trasparent rendering pass
0979:            //  
0980:            boolean depthBufferFreezeTransparent = true;
0981:
0982:            //
0983:            // Flag to enable scene antialiasing
0984:            //  
0985:            boolean sceneAntialiasingEnable = false;
0986:
0987:            //
0988:            // Flag to enable local eye lighting
0989:            //  
0990:            boolean localEyeLightingEnable = false;
0991:
0992:            // Array Lists to track the screens and canvases associated with this View.
0993:            // use getScreens() to access this
0994:            private ArrayList screenList = new ArrayList();
0995:
0996:            // use getCanvasList() to access this
0997:            private ArrayList canvasList = new ArrayList();
0998:
0999:            private Canvas3D[][] cachedCanvasList;
1000:            private Canvas3D[] cachedCanvases;
1001:            private Screen3D[] cachedScreens;
1002:            private int longestScreenList = 0;
1003:            private boolean canvasesDirty = true;
1004:
1005:            // Flag to notify user thread when renderOnce is finished
1006:            volatile boolean renderOnceFinish = true;
1007:
1008:            // Lock to synchronize start/stop/renderOnce call
1009:            private Object startStopViewLock = new Object();
1010:
1011:            // Lock for evaluateActive() only. This is used to prevent
1012:            // using lock this which will cause deadlock when MC call
1013:            // snapshot which waitForMC() in user thread.
1014:            private Object evaluateLock = new Object();
1015:
1016:            /**
1017:             * use for stop view, when stopview, set to count -1,
1018:             * when reach 1, call stopView() in MC and reset to -1.
1019:             */
1020:            int stopViewCount = -1;
1021:
1022:            /**
1023:             * False if current frame cycle time less than minimum frame cycle time 
1024:             */
1025:            boolean isMinCycleTimeAchieve = true;
1026:
1027:            // Time to sleep if minimum frame cycle time not achieve
1028:            long sleepTime = 0;
1029:
1030:            // use in pure immediate mode to tell whether this view rendering
1031:            // thread is added in MC renderThreadData
1032:            volatile boolean inRenderThreadData = false;
1033:
1034:            // use to notify MC that render bin has run once, and is ready for
1035:            // renderer to render
1036:            boolean renderBinReady = false;
1037:
1038:            // No of time setUniverse() is invoke
1039:            long universeCount = 0;
1040:
1041:            // The universe count when UNREGISTER_VIEW request is post,
1042:            // this is used to distingish whether new setUniverse() is
1043:            // invoked after UNREGISTER_VIEW request post to avoid
1044:            // resetting the newly set universe.
1045:            long resetUnivCount = 0;
1046:
1047:            // This notify user thread waitForMC() to continue when 
1048:            // MC finish unregisterView
1049:            volatile boolean doneUnregister = false;
1050:
1051:            static final int TRANSP_SORT_POLICY_CHANGED = 0x0001;
1052:            static final int OTHER_ATTRS_CHANGED = 0x0002;
1053:
1054:            /**
1055:             * Constructs a View object with default parameters.  The default
1056:             * values are as follows:
1057:             * <ul>
1058:             * view policy : SCREEN_VIEW<br>
1059:             * projection policy : PERSPECTIVE_PROJECTION<br>
1060:             * screen scale policy : SCALE_SCREEN_SIZE<br>
1061:             * window resize policy : PHYSICAL_WORLD<br>
1062:             * window movement policy : PHYSICAL_WORLD<br>
1063:             * window eyepoint policy : RELATIVE_TO_FIELD_OF_VIEW<br>
1064:             * monoscopic view policy : CYCLOPEAN_EYE_VIEW<br>
1065:             * front clip policy : PHYSICAL_EYE<br>
1066:             * back clip policy : PHYSICAL_EYE<br>
1067:             * visibility policy : VISIBILITY_DRAW_VISIBLE<br>
1068:             * transparency sorting policy : TRANSPARENCY_SORT_NONE<br>
1069:             * coexistenceCentering flag : true<br>
1070:             * compatibility mode : false<br>
1071:             * left projection : identity<br>
1072:             * right projection : identity<br>
1073:             * vpc to ec transform : identity<br>
1074:             * physical body : null<br>
1075:             * physical environment : null<br>
1076:             * screen scale : 1.0<br>
1077:             * field of view : PI/4<br>
1078:             * left manual eye in coexistence : (-0.033, 0.0, 0.4572)<br>
1079:             * right manual eye in coexistence : (0.033, 0.0, 0.4572)<br>
1080:             * front clip distance : 0.1<br>
1081:             * back clip distance : 10.0<br>
1082:             * tracking enable : false<br>
1083:             * user head to vworld enable : false<br>
1084:             * list of Canvas3D objects : empty<br>
1085:             * depth buffer freeze transparent : true<br>
1086:             * scene antialiasing : false<br>
1087:             * local eye lighting : false<br>
1088:             * view platform : null<br>
1089:             * behavior scheduler running : true<br>
1090:             * view running : true<br>
1091:             * minimum frame cycle time : 0<br>
1092:             * </ul>
1093:             */
1094:            public View() {
1095:                viewCache = new ViewCache(this );
1096:            }
1097:
1098:            /**
1099:             * Sets the policy for view computation.
1100:             * This variable specifies how Java 3D uses its transforms in
1101:             * computing new viewpoints.
1102:             * <UL>
1103:             * <LI>SCREEN_VIEW specifies that Java 3D should compute a new viewpoint
1104:             * using the sequence of transforms appropriate to screen-based
1105:             * head-tracked display environments (fish-tank VR/portals/VR-desks).
1106:             * </LI>
1107:             * <LI>HMD_VIEW specifies that Java 3D should compute a new viewpoint
1108:             * using the sequence of transforms appropriate to head mounted
1109:             * display environments.
1110:             * </LI>
1111:             * </UL>
1112:             * The default view policy is SCREEN_VIEW.
1113:             * @param policy the new policy, one of SCREEN_VIEW or HMD_VIEW
1114:             * @exception IllegalArgumentException if policy is a value other than
1115:             * SCREEN_VIEW or HMD_VIEW
1116:             * @exception IllegalStateException if the specified policy
1117:             * is HMD_VIEW and if any canvas associated with this view is
1118:             * a stereo canvas with a monoscopicEyePolicy of CYCLOPEAN_EYE_VIEW
1119:             */
1120:            public void setViewPolicy(int policy) {
1121:                if (policy != HMD_VIEW && policy != SCREEN_VIEW) {
1122:
1123:                    throw new IllegalArgumentException(J3dI18N
1124:                            .getString("View0"));
1125:                }
1126:                if (policy == HMD_VIEW) {
1127:                    // Check the following :
1128:                    // 1) If the view is in HMD mode and there exists a canvas in
1129:                    // CYCLOPEAN_EYE_VIEW mode then throw exception.
1130:                    synchronized (canvasList) {
1131:                        for (int i = canvases.size() - 1; i >= 0; i--) {
1132:                            Canvas3D c3d = (Canvas3D) canvases.elementAt(i);
1133:
1134:                            if ((c3d.monoscopicViewPolicy == View.CYCLOPEAN_EYE_VIEW)
1135:                                    && (!c3d.useStereo)) {
1136:                                throw new IllegalStateException(J3dI18N
1137:                                        .getString("View31"));
1138:                            }
1139:                        }
1140:                    }
1141:                }
1142:                synchronized (this ) {
1143:                    this .viewPolicy = policy;
1144:                    vDirtyMask |= View.VIEW_POLICY_DIRTY;
1145:                }
1146:                repaint();
1147:            }
1148:
1149:            /**
1150:             * Retrieves the current view computation policy for this View.
1151:             * @return one of: SCREEN_VIEW or HMD_VIEW.
1152:             */
1153:            public int getViewPolicy() {
1154:                return this .viewPolicy;
1155:            }
1156:
1157:            /**
1158:             * Sets the projection policy for this View.
1159:             * This variable specifies the type of projection transform that
1160:             * will be generated.  A value of PARALLEL_PROJECTION specifies that
1161:             * a parallel projection transform is generated.  A value of
1162:             * PERSPECTIVE_PROJECTION specifies that
1163:             * a perspective projection transform is generated.
1164:             * The default projection policy is PERSPECTIVE.
1165:             * @param policy the new policy, one of PARALLEL_PROJECTION or
1166:             * PERSPECTIVE_PROJECTION
1167:             * @exception IllegalArgumentException if policy is a value other than
1168:             * PARALLEL_PROJECTION or PERSPECTIVE_PROJECTION
1169:             */
1170:            public void setProjectionPolicy(int policy) {
1171:                if (policy != PERSPECTIVE_PROJECTION
1172:                        && policy != PARALLEL_PROJECTION) {
1173:
1174:                    throw new IllegalArgumentException(J3dI18N
1175:                            .getString("View1"));
1176:                }
1177:                synchronized (this ) {
1178:                    this .projectionPolicy = policy;
1179:                    vDirtyMask |= View.PROJECTION_POLICY_DIRTY;
1180:                }
1181:
1182:                repaint();
1183:            }
1184:
1185:            /**
1186:             * Retrieves the current projection policy for this View.
1187:             * @return one of: PARALLEL_PROJECTION or PERSPECTIVE_PROJECTION.
1188:             */
1189:            public int getProjectionPolicy() {
1190:                return this .projectionPolicy;
1191:            }
1192:
1193:            /**
1194:             * Sets the screen scale policy for this view.
1195:             * This policy specifies how the screen scale is derived.
1196:             * The value is either SCALE_SCREEN_SIZE or SCALE_EXPLICIT.
1197:             * A value of SCALE_SCREEN_SIZE specifies that the scale is derived
1198:             * from the size of the physical screen.  A value of SCALE_EXPLICIT
1199:             * specifies that the scale is taken directly from the screenScale
1200:             * parameter.
1201:             * The default screen scale policy is SCALE_SCREEN_SIZE.
1202:             * @param policy the new policy, one of SCALE_SCREEN_SIZE or
1203:             * SCALE_EXPLICIT.
1204:             */
1205:            public void setScreenScalePolicy(int policy) {
1206:
1207:                synchronized (this ) {
1208:                    this .screenScalePolicy = policy;
1209:                    vDirtyMask |= View.SCREEN_SCALE_POLICY_DIRTY;
1210:                }
1211:
1212:                repaint();
1213:            }
1214:
1215:            /**
1216:             * Returns the current screen scale policy, one of:
1217:             * SCALE_SCREEN_SIZE or SCALE_EXPLICIT.
1218:             * @return the current screen scale policy
1219:             */
1220:            public int getScreenScalePolicy() {
1221:                return this .screenScalePolicy;
1222:            }
1223:
1224:            /**
1225:             * Sets the window resize policy.
1226:             * This variable specifies how Java 3D modifies the view when
1227:             * users resize windows. The variable can contain one of
1228:             * VIRTUAL_WORLD or PHYSICAL_WORLD.
1229:             * A value of VIRTUAL_WORLD implies that the original image
1230:             * remains the same size on the screen but the user sees more
1231:             * or less of the virtual world depending on whether the window
1232:             * grew or shrank in size.
1233:             * A value of PHYSICAL_WORLD implies that the original image
1234:             * continues to fill the window in the same way using more or
1235:             * less pixels depending on whether the window grew or shrank
1236:             * in size.
1237:             * The default window resize policy is PHYSICAL_WORLD.
1238:             * @param policy the new policy, one of VIRTUAL_WORLD or PHYSICAL_WORLD
1239:             */
1240:            public void setWindowResizePolicy(int policy) {
1241:
1242:                synchronized (this ) {
1243:                    this .windowResizePolicy = policy;
1244:                    vDirtyMask |= View.WINDOW_RESIZE_POLICY_DIRTY;
1245:                }
1246:                repaint();
1247:            }
1248:
1249:            /**
1250:             * Returns the current window resize policy, one of:
1251:             * VIRTUAL_WORLD or PHYSICAL_WORLD.
1252:             * @return the current window resize policy
1253:             */
1254:            public int getWindowResizePolicy() {
1255:                return this .windowResizePolicy;
1256:            }
1257:
1258:            /**
1259:             * Sets the window movement policy.
1260:             * This variable specifies what part of the virtual world Java 3D
1261:             * draws as a function of window placement on the screen. The
1262:             * variable can contain one of VIRTUAL_WORLD or PHYSICAL_WORLD.
1263:             * A value of VIRTUAL_WORLD implies that the image seen in the
1264:             * window changes as the position of the window shifts on the
1265:             * screen.  (This mode acts as if the window were a window into
1266:             * the virtual world.)
1267:             * A value of PHYSICAL_WORLD implies that the image seen in the
1268:             * window remains the same no matter where the user positions
1269:             * the window on the screen.
1270:             * The default window movement policy is PHYSICAL_WORLD.
1271:             * @param policy the new policy, one of VIRTUAL_WORLD or PHYSICAL_WORLD
1272:             */
1273:            public void setWindowMovementPolicy(int policy) {
1274:
1275:                synchronized (this ) {
1276:                    this .windowMovementPolicy = policy;
1277:                    vDirtyMask |= View.WINDOW_MOVEMENT_POLICY_DIRTY;
1278:                }
1279:                repaint();
1280:            }
1281:
1282:            /**
1283:             * Returns the current window movement policy,
1284:             * one of: VIRTUAL_WORLD or PHYSICAL_WORLD.
1285:             * @return the current window movement policy
1286:             */
1287:            public int getWindowMovementPolicy() {
1288:                return this .windowMovementPolicy;
1289:            }
1290:
1291:            /**
1292:             * Sets the view model's window eyepoint policy.
1293:             * This variable specifies how Java 3D handles the predefined eye
1294:             * point in a non-head-tracked environment.  The variable can contain
1295:             * one of:
1296:             * <UL>
1297:             * <LI>RELATIVE_TO_SCREEN, Java 3D should interpret the
1298:             * given fixed-eyepoint position as relative to the screen (this
1299:             * implies that the view frustum shape will change whenever a
1300:             * user moves the location of a window on the screen).
1301:             * </LI>
1302:             * <LI>RELATIVE_TO_WINDOW, Java 3D should interpret the
1303:             * given fixed-eyepoint position as relative to the window.  In this
1304:             * mode, the X and Y values are taken as the center of the window and
1305:             * the Z value is taken from the canvas eyepoint position.
1306:             * </LI>
1307:             * <LI>RELATIVE_TO_FIELD_OF_VIEW, Java 3D should
1308:             * modify the position of the eyepoint to match any changes in field
1309:             * of view (the view frustum will change whenever the application
1310:             * program changes the field of view).
1311:             * </LI>
1312:             * <LI>RELATIVE_TO_COEXISTENCE, Java 3D should interpret the eye's
1313:             * position in coexistence coordinates. In this mode, the eye position
1314:             * is taken from the view (rather than the Canvas3D) and transformed from
1315:             * coexistence coordinates to image plate coordinates for each
1316:             * Canvas3D.  The resulting eye position is relative to the screen (this
1317:             * implies that the view frustum shape will change whenever a
1318:             * user moves the location of a window on the screen).
1319:             * </LI>
1320:             * </UL>
1321:             * The default window eyepoint policy is RELATIVE_TO_FIELD_OF_VIEW.
1322:             * @param policy the new policy, one of RELATIVE_TO_SCREEN,
1323:             * RELATIVE_TO_WINDOW, RELATIVE_TO_FIELD_OF_VIEW, or
1324:             * RELATIVE_TO_COEXISTENCE
1325:             */
1326:            public void setWindowEyepointPolicy(int policy) {
1327:                synchronized (this ) {
1328:                    this .windowEyepointPolicy = policy;
1329:                    vDirtyMask |= View.WINDOW_EYE_POINT_POLICY_DIRTY;
1330:                }
1331:
1332:                repaint();
1333:            }
1334:
1335:            /**
1336:             * Returns the current window eyepoint policy, one of:
1337:             * RELATIVE_TO_SCREEN, RELATIVE_TO_WINDOW, RELATIVE_TO_FIELD_OF_VIEW or
1338:             * RELATIVE_TO_COEXISTENCE.
1339:             * @return the current window eyepoint policy
1340:             */
1341:            public int getWindowEyepointPolicy() {
1342:                return this .windowEyepointPolicy;
1343:            }
1344:
1345:            /**
1346:             * @deprecated As of Java 3D version 1.2, replaced by
1347:             * <code>Canvas3D.setMonoscopicViewPolicy</code>
1348:             */
1349:            public void setMonoscopicViewPolicy(int policy) {
1350:                synchronized (this ) {
1351:                    this .monoscopicViewPolicy = policy;
1352:                    vDirtyMask |= View.MONOSCOPIC_VIEW_POLICY_DIRTY;
1353:                }
1354:                repaint();
1355:            }
1356:
1357:            /**
1358:             * @deprecated As of Java 3D version 1.2, replaced by
1359:             * <code>Canvas3D.getMonoscopicViewPolicy</code>
1360:             */
1361:            public int getMonoscopicViewPolicy() {
1362:                return this .monoscopicViewPolicy;
1363:            }
1364:
1365:            /**
1366:             * Sets the coexistenceCentering enable flag to true or false.
1367:             * If the coexistenceCentering flag is true, the center of
1368:             * coexistence in image plate coordinates, as specified by the
1369:             * trackerBaseToImagePlate transform, is translated to the center
1370:             * of either the window or the screen in image plate coordinates,
1371:             * according to the value of windowMovementPolicy.
1372:             *
1373:             * <p>
1374:             * By default, coexistenceCentering is enabled.  It should be
1375:             * disabled if the trackerBaseToImagePlate calibration transform
1376:             * is set to a value other than the identity (for example, when
1377:             * rendering to multiple screens or when head tracking is
1378:             * enabled).  This flag is ignored for HMD mode, or when the
1379:             * coexistenceCenterInPworldPolicy is <i>not</i>
1380:             * NOMINAL_SCREEN.
1381:             *
1382:             * @param flag the new coexistenceCentering enable flag
1383:             *
1384:             * @since Java 3D 1.2
1385:             */
1386:            public void setCoexistenceCenteringEnable(boolean flag) {
1387:                synchronized (this ) {
1388:                    this .coexistenceCenteringEnable = flag;
1389:                    vDirtyMask |= View.COEXISTENCE_CENTERING_ENABLE_DIRTY;
1390:                }
1391:                repaint();
1392:            }
1393:
1394:            /**
1395:             * Retrieves the coexistenceCentering enable flag.
1396:             *
1397:             * @return the current coexistenceCentering enable flag
1398:             *
1399:             * @since Java 3D 1.2
1400:             */
1401:            public boolean getCoexistenceCenteringEnable() {
1402:                return this .coexistenceCenteringEnable;
1403:            }
1404:
1405:            /**
1406:             * Sets the compatibility mode enable flag to true or false.
1407:             * Compatibility mode is disabled by default.
1408:             * @param flag the new compatibility mode enable flag
1409:             */
1410:            public void setCompatibilityModeEnable(boolean flag) {
1411:                synchronized (this ) {
1412:                    this .compatibilityModeEnable = flag;
1413:                    vDirtyMask |= View.COMPATIBILITY_MODE_DIRTY;
1414:                }
1415:                repaint();
1416:            }
1417:
1418:            /**
1419:             * Retrieves the compatibility mode enable flag.
1420:             * @return the current compatibility mode enable flag
1421:             */
1422:            public boolean getCompatibilityModeEnable() {
1423:                return this .compatibilityModeEnable;
1424:            }
1425:
1426:            /**
1427:             * Compatibility mode method that specifies a viewing frustum for
1428:             * the left eye that transforms points in Eye Coordinates (EC) to
1429:             * Clipping Coordinates (CC).
1430:             * If compatibility mode is disabled, then this transform is not used;
1431:             * the actual projection is derived from other values.
1432:             * In monoscopic mode, only the left eye projection matrix is used.
1433:             * @param projection the new left eye projection transform
1434:             * @exception RestrictedAccessException if compatibility mode is disabled.
1435:             */
1436:            public void setLeftProjection(Transform3D projection) {
1437:                if (!compatibilityModeEnable) {
1438:                    throw new RestrictedAccessException(J3dI18N
1439:                            .getString("View2"));
1440:                }
1441:
1442:                synchronized (this ) {
1443:                    compatLeftProjection.setWithLock(projection);
1444:                    vDirtyMask |= View.COMPATIBILITY_MODE_DIRTY;
1445:                }
1446:                repaint();
1447:            }
1448:
1449:            /**
1450:             * Compatibility mode method that specifies a viewing frustum for
1451:             * the right eye that transforms points in Eye Coordinates (EC) to
1452:             * Clipping Coordinates (CC).
1453:             * If compatibility mode is disabled, then this transform is not used;
1454:             * the actual projection is derived from other values.
1455:             * In monoscopic mode, the right eye projection matrix is ignored.
1456:             * @param projection the new right eye projection transform
1457:             * @exception RestrictedAccessException if compatibility mode is disabled.
1458:             */
1459:            public void setRightProjection(Transform3D projection) {
1460:                if (!compatibilityModeEnable) {
1461:                    throw new RestrictedAccessException(J3dI18N
1462:                            .getString("View2"));
1463:                }
1464:
1465:                synchronized (this ) {
1466:                    compatRightProjection.setWithLock(projection);
1467:                    vDirtyMask |= View.COMPATIBILITY_MODE_DIRTY;
1468:                }
1469:
1470:                repaint();
1471:            }
1472:
1473:            /**
1474:             * Compatibility mode method that retrieves the current
1475:             * compatibility mode projection transform for the left eye and
1476:             * places it into the specified object.
1477:             * @param projection the Transform3D object that will receive the
1478:             * projection
1479:             * @exception RestrictedAccessException if compatibility mode is disabled.
1480:             */
1481:            public void getLeftProjection(Transform3D projection) {
1482:                if (!compatibilityModeEnable) {
1483:                    throw new RestrictedAccessException(J3dI18N
1484:                            .getString("View4"));
1485:                }
1486:
1487:                projection.set(compatLeftProjection);
1488:            }
1489:
1490:            /**
1491:             * Compatibility mode method that retrieves the current
1492:             * compatibility mode projection transform for the right eye and
1493:             * places it into the specified object.
1494:             * @param projection the Transform3D object that will receive the
1495:             * projection
1496:             * @exception RestrictedAccessException if compatibility mode is disabled.
1497:             */
1498:            public void getRightProjection(Transform3D projection) {
1499:                if (!compatibilityModeEnable) {
1500:                    throw new RestrictedAccessException(J3dI18N
1501:                            .getString("View4"));
1502:                }
1503:
1504:                projection.set(compatRightProjection);
1505:            }
1506:
1507:            /**
1508:             * Compatibility mode method that specifies the ViewPlatform
1509:             * Coordinates (VPC) to Eye Coordinates (EC) transform.
1510:             * If compatibility mode is disabled, then this transform
1511:             * is derived from other values and is read-only.
1512:             * @param vpcToEc the new VPC to EC transform
1513:             * @exception RestrictedAccessException if compatibility mode is disabled.
1514:             * @exception BadTransformException if the transform is not affine.
1515:             */
1516:            public void setVpcToEc(Transform3D vpcToEc) {
1517:                if (!compatibilityModeEnable) {
1518:                    throw new RestrictedAccessException(J3dI18N
1519:                            .getString("View6"));
1520:                }
1521:
1522:                if (!vpcToEc.isAffine()) {
1523:                    throw new BadTransformException(J3dI18N.getString("View7"));
1524:                }
1525:
1526:                synchronized (this ) {
1527:                    compatVpcToEc.setWithLock(vpcToEc);
1528:                    vDirtyMask |= View.COMPATIBILITY_MODE_DIRTY;
1529:                }
1530:
1531:                repaint();
1532:            }
1533:
1534:            /**
1535:             * Compatibility mode method that retrieves the current
1536:             * ViewPlatform Coordinates (VPC) system to
1537:             * Eye Coordinates (EC) transform and copies it into the specified
1538:             * object.
1539:             * @param vpcToEc the object that will receive the vpcToEc transform.
1540:             * @exception RestrictedAccessException if compatibility mode is disabled.
1541:             */
1542:            public void getVpcToEc(Transform3D vpcToEc) {
1543:                if (!compatibilityModeEnable) {
1544:                    throw new RestrictedAccessException(J3dI18N
1545:                            .getString("View8"));
1546:                }
1547:
1548:                vpcToEc.set(compatVpcToEc);
1549:            }
1550:
1551:            /**
1552:             * Sets the view model's physical body to the PhysicalBody object provided.
1553:             * Java 3D uses the parameters in the PhysicalBody to ensure accurate
1554:             * image and sound generation when in head-tracked mode.
1555:             * @param physicalBody the new PhysicalBody object
1556:             */
1557:            public void setPhysicalBody(PhysicalBody physicalBody) {
1558:                // need to synchronize variable activateStatus
1559:                synchronized (canvasList) {
1560:                    if (activeStatus) {
1561:                        if (this .physicalBody != null) {
1562:                            this .physicalBody.removeUser(this );
1563:                        }
1564:                        physicalBody.addUser(this );
1565:                    }
1566:                }
1567:                this .physicalBody = physicalBody;
1568:                repaint();
1569:            }
1570:
1571:            /**
1572:             * Returns a reference to the view model's PhysicalBody object.
1573:             * @return the view object's PhysicalBody object
1574:             */
1575:            public PhysicalBody getPhysicalBody() {
1576:                return this .physicalBody;
1577:            }
1578:
1579:            /**
1580:             * Sets the view model's physical environment to the PhysicalEnvironment
1581:             * object provided.
1582:             * @param physicalEnvironment the new PhysicalEnvironment object
1583:             */
1584:            public void setPhysicalEnvironment(
1585:                    PhysicalEnvironment physicalEnvironment) {
1586:                synchronized (canvasList) {
1587:                    if (activeStatus) {
1588:                        if (this .physicalEnvironment != null) {
1589:                            this .physicalEnvironment.removeUser(this );
1590:                        }
1591:                        physicalEnvironment.addUser(this );
1592:                    }
1593:                }
1594:                this .physicalEnvironment = physicalEnvironment;
1595:
1596:                if ((viewPlatform != null) && viewPlatform.isLive()) {
1597:                    VirtualUniverse.mc.postRequest(
1598:                            MasterControl.PHYSICAL_ENV_CHANGE, this );
1599:                }
1600:                repaint();
1601:            }
1602:
1603:            /**
1604:             * Returns a reference to the view model's PhysicalEnvironment object.
1605:             * @return the view object's PhysicalEnvironment object
1606:             */
1607:            public PhysicalEnvironment getPhysicalEnvironment() {
1608:                return this .physicalEnvironment;
1609:            }
1610:
1611:            /**
1612:             * Sets the screen scale value for this view.
1613:             * This is used when the screen scale policy is SCALE_EXPLICIT.
1614:             * The default value is 1.0 (i.e., unscaled).
1615:             * @param scale the new screen scale
1616:             */
1617:            public void setScreenScale(double scale) {
1618:                synchronized (this ) {
1619:                    this .screenScale = scale;
1620:                    vDirtyMask |= View.SCREEN_SCALE_DIRTY;
1621:                }
1622:                repaint();
1623:            }
1624:
1625:            /**
1626:             * Returns the current screen scale value
1627:             * @return the current screen scale value
1628:             */
1629:            public double getScreenScale() {
1630:                return this .screenScale;
1631:            }
1632:
1633:            /**
1634:             * Sets the field of view used to compute the projection transform.
1635:             * This is used when head tracking is disabled and when the Canvas3D's
1636:             * windowEyepointPolicy is RELATIVE_TO_FIELD_OF_VIEW.
1637:             * @param fieldOfView the new field of view in radians
1638:             */
1639:            public void setFieldOfView(double fieldOfView) {
1640:                synchronized (this ) {
1641:                    this .fieldOfView = fieldOfView;
1642:                    vDirtyMask |= View.FIELD_OF_VIEW_DIRTY;
1643:                }
1644:                repaint();
1645:
1646:            }
1647:
1648:            /**
1649:             * Returns the current field of view.
1650:             * @return the current field of view in radians
1651:             */
1652:            public double getFieldOfView() {
1653:                return this .fieldOfView;
1654:            }
1655:
1656:            /**
1657:             * Sets the position of the manual left eye in coexistence
1658:             * coordinates.  This value determines eye placement when a head
1659:             * tracker is not in use and the application is directly controlling
1660:             * the eye position in coexistence coordinates.  This value is
1661:             * ignored when in head-tracked mode or when the
1662:             * windowEyePointPolicy is <i>not</i> RELATIVE_TO_COEXISTENCE.
1663:             *
1664:             * @param position the new manual left eye position
1665:             *
1666:             * @since Java 3D 1.2
1667:             */
1668:            public void setLeftManualEyeInCoexistence(Point3d position) {
1669:                synchronized (this ) {
1670:                    leftManualEyeInCoexistence.set(position);
1671:                    vDirtyMask |= View.LEFT_MANUAL_EYE_IN_COEXISTENCE_DIRTY;
1672:                }
1673:                repaint();
1674:            }
1675:
1676:            /**
1677:             * Sets the position of the manual right eye in coexistence
1678:             * coordinates.  This value determines eye placement when a head
1679:             * tracker is not in use and the application is directly controlling
1680:             * the eye position in coexistence coordinates.  This value is
1681:             * ignored when in head-tracked mode or when the
1682:             * windowEyePointPolicy is <i>not</i> RELATIVE_TO_COEXISTENCE.
1683:             *
1684:             * @param position the new manual right eye position
1685:             *
1686:             * @since Java 3D 1.2
1687:             */
1688:            public void setRightManualEyeInCoexistence(Point3d position) {
1689:                synchronized (this ) {
1690:                    rightManualEyeInCoexistence.set(position);
1691:                    vDirtyMask |= View.RIGHT_MANUAL_EYE_IN_COEXISTENCE_DIRTY;
1692:                }
1693:                repaint();
1694:            }
1695:
1696:            /**
1697:             * Retrieves the position of the user-specified, manual left eye
1698:             * in coexistence
1699:             * coordinates and copies that value into the object provided.
1700:             * @param position the object that will receive the position
1701:             *
1702:             * @since Java 3D 1.2
1703:             */
1704:            public void getLeftManualEyeInCoexistence(Point3d position) {
1705:                position.set(leftManualEyeInCoexistence);
1706:            }
1707:
1708:            /**
1709:             * Retrieves the position of the user-specified, manual right eye
1710:             * in coexistence
1711:             * coordinates and copies that value into the object provided.
1712:             * @param position the object that will receive the position
1713:             *
1714:             * @since Java 3D 1.2
1715:             */
1716:            public void getRightManualEyeInCoexistence(Point3d position) {
1717:                position.set(rightManualEyeInCoexistence);
1718:            }
1719:
1720:            /**
1721:             * Sets the view model's front clip distance.
1722:             * This value specifies the distance away from the eyepoint
1723:             * in the direction of gaze where objects stop disappearing.
1724:             * Objects closer to the eye than the front clip
1725:             * distance are not drawn. The default value is 0.1 meters.
1726:             * <p>
1727:             * There are several considerations that need to be taken into
1728:             * account when choosing values for the front and back clip
1729:             * distances.
1730:             * <ul>
1731:             * <li>The front clip distance must be greater than
1732:             * 0.0 in physical eye coordinates.</li>
1733:             * <li>The front clipping plane must be in front of the
1734:             * back clipping plane, that is, the front clip distance
1735:             * must be less than the back clip distance in physical eye
1736:             * coordinates.</li>
1737:             * <li>The front and back clip distances, in physical
1738:             * eye coordinates, must be less than the largest positive
1739:             * single-precision floating point value, <code>Float.MAX_VALUE</code>.
1740:             * In practice, since these physical eye coordinate distances are in
1741:             * meters, the values should be <i>much</i> less than that.
1742:             * <li>The ratio of the back distance divided by the front distance,
1743:             * in physical eye coordinates, affects Z-buffer precision. This
1744:             * ratio should be less than about 3000 in order to accommodate 16-bit
1745:             * Z-buffers. Values of 100 to less than 1000 will produce better
1746:             * results.</li>
1747:             * </ul>
1748:             * Violating any of the above rules will result in undefined
1749:             * behavior. In many cases, no picture will be drawn.
1750:             *
1751:             * @param distance the new front clip distance
1752:             * @see #setBackClipDistance
1753:             */
1754:            public void setFrontClipDistance(double distance) {
1755:                synchronized (this ) {
1756:                    this .frontClipDistance = distance;
1757:                    vDirtyMask |= View.CLIP_DIRTY;
1758:                }
1759:                repaint();
1760:            }
1761:
1762:            /**
1763:             * Returns the view model's front clip distance.
1764:             * @return the current front clip distance
1765:             */
1766:            public double getFrontClipDistance() {
1767:                return this .frontClipDistance;
1768:            }
1769:
1770:            /**
1771:             * Sets the view model's back clip distance.
1772:             * The parameter specifies the distance from the eyepoint
1773:             * in the direction of gaze to where objects begin disappearing.
1774:             * Objects farther away from the eye than the
1775:             * back clip distance are not drawn.
1776:             * The default value is 10.0 meters.
1777:             * <p>
1778:             * There are several considerations that need to be taken into
1779:             * account when choosing values for the front and back clip
1780:             * distances. These are enumerated in the description of
1781:             * <a href=#setFrontClipDistance(double)>setFrontClipDistance</a>.
1782:             * <p>
1783:             * Note that this attribute is only used if there is no Clip node
1784:             * that is in scope of the view platform associated with this view.
1785:             * @param distance the new back clip distance
1786:             * @see #setFrontClipDistance
1787:             * @see Clip#setBackDistance
1788:             */
1789:            public void setBackClipDistance(double distance) {
1790:                synchronized (this ) {
1791:                    this .backClipDistance = distance;
1792:                    vDirtyMask |= View.CLIP_DIRTY;
1793:                }
1794:                repaint();
1795:            }
1796:
1797:            /**
1798:             * Returns the view model's back clip distance.
1799:             * @return the current back clip distance
1800:             */
1801:            public double getBackClipDistance() {
1802:                return this .backClipDistance;
1803:            }
1804:
1805:            /**
1806:             * Retrieves the user-head to virtual-world transform
1807:             * and copies that value into the transform provided.
1808:             * @param t the Transform3D object that will receive the transform
1809:             */
1810:            public void getUserHeadToVworld(Transform3D t) {
1811:
1812:                if (userHeadToVworldEnable) {
1813:
1814:                    // get the calculated userHeadToVworld transform
1815:                    // from the view cache.
1816:                    // grab the first canvas -- not sure for multiple canvases
1817:                    Canvas3D canvas = (Canvas3D) this .canvases.firstElement();
1818:                    synchronized (canvas.canvasViewCache) {
1819:                        t.set(canvas.canvasViewCache.getHeadToVworld());
1820:                    }
1821:                } else {
1822:                    throw new RestrictedAccessException(J3dI18N
1823:                            .getString("View9"));
1824:                }
1825:            }
1826:
1827:            /**
1828:             * Sets the view model's front clip policy, the policy Java 3D uses
1829:             * in computing where to place the front clip plane. The variable 
1830:             * can contain one of:
1831:             * <UL>
1832:             * <LI>VIRTUAL_EYE, to specify that the associated distance is
1833:             * from the eye and in units of virtual distance
1834:             * </LI>
1835:             * <LI>PHYSICAL_EYE, to specify that the associated distance is
1836:             * from the eye and in units of physical distance (meters)
1837:             * </LI>
1838:             * <LI>VIRTUAL_SCREEN, to specify that the associated distance is
1839:             * from the screen and in units of virtual distance
1840:             * </LI>
1841:             * <LI>PHYSICAL_SCREEN, to specify that the associated distance is
1842:             * from the screen and in units of physical distance (meters)
1843:             * </LI>
1844:             * </UL>
1845:             * The default front clip policy is PHYSICAL_EYE.
1846:             * @param policy the new policy, one of PHYSICAL_EYE, PHYSICAL_SCREEN,
1847:             * VIRTUAL_EYE, or VIRTUAL_SCREEN
1848:             */
1849:            public void setFrontClipPolicy(int policy) {
1850:                synchronized (this ) {
1851:                    this .frontClipPolicy = policy;
1852:                    vDirtyMask |= View.CLIP_DIRTY;
1853:                }
1854:                repaint();
1855:            }
1856:
1857:            /**
1858:             * Returns the view model's current front clip policy.
1859:             * @return one of:
1860:             * VIRTUAL_EYE, PHYSICAL_EYE, VIRTUAL_SCREEN, or PHYSICAL_SCREEN
1861:             */
1862:            public int getFrontClipPolicy() {
1863:                return this .frontClipPolicy;
1864:            }
1865:
1866:            /**
1867:             * Sets the view model's back clip policy, the policy Java 3D uses
1868:             * in computing where to place the back clip plane. The variable 
1869:             * can contain one of:
1870:             * <UL>
1871:             * <LI>VIRTUAL_EYE, to specify that the associated distance is
1872:             * from the eye and in units of virtual distance
1873:             * </LI>
1874:             * <LI>PHYSICAL_EYE, to specify that the associated distance is
1875:             * from the eye and in units of physical distance (meters)
1876:             * </LI>
1877:             * <LI>VIRTUAL_SCREEN, to specify that the associated distance is
1878:             * from the screen and in units of virtual distance
1879:             * </LI>
1880:             * <LI>PHYSICAL_SCREEN, to specify that the associated distance is
1881:             * from the screen and in units of physical distance (meters)
1882:             * </LI>
1883:             * </UL>
1884:             * The default back clip policy is PHYSICAL_EYE.
1885:             * @param policy the new policy, one of PHYSICAL_EYE, PHYSICAL_SCREEN,
1886:             * VIRTUAL_EYE, or VIRTUAL_SCREEN
1887:             */
1888:            public void setBackClipPolicy(int policy) {
1889:                synchronized (this ) {
1890:                    this .backClipPolicy = policy;
1891:                    vDirtyMask |= View.CLIP_DIRTY;
1892:                }
1893:                repaint();
1894:            }
1895:
1896:            /**
1897:             * Returns the view model's current back clip policy.
1898:             * @return one of:
1899:             * VIRTUAL_EYE, PHYSICAL_EYE, VIRTUAL_SCREEN, or PHYSICAL_SCREEN
1900:             */
1901:            public int getBackClipPolicy() {
1902:                return this .backClipPolicy;
1903:            }
1904:
1905:            /**
1906:             * Sets the visibility policy for this view.  This attribute 
1907:             * is one of:
1908:             * <UL>
1909:             * <LI>VISIBILITY_DRAW_VISIBLE, to specify that only visible objects
1910:             * are drawn.
1911:             * </LI>
1912:             * <LI>VISIBILITY_DRAW_INVISIBLE, to specify that only invisible objects
1913:             * are drawn.
1914:             * </LI>
1915:             * <LI>VISIBILITY_DRAW_ALL, to specify that both visible and
1916:             * invisible objects are drawn.
1917:             * </LI>
1918:             * </UL>
1919:             * The default visibility policy is VISIBILITY_DRAW_VISIBLE.
1920:             *
1921:             * @param policy the new policy, one of VISIBILITY_DRAW_VISIBLE,
1922:             * VISIBILITY_DRAW_INVISIBLE, or VISIBILITY_DRAW_ALL.
1923:             *
1924:             * @see RenderingAttributes#setVisible
1925:             *
1926:             * @since Java 3D 1.2
1927:             */
1928:            public void setVisibilityPolicy(int policy) {
1929:
1930:                synchronized (this ) {
1931:                    this .visibilityPolicy = policy;
1932:                    vDirtyMask |= View.VISIBILITY_POLICY_DIRTY;
1933:                }
1934:
1935:                if (activeStatus && isRunning) {
1936:
1937:                    J3dMessage vpMessage = new J3dMessage();
1938:                    vpMessage.universe = universe;
1939:                    vpMessage.view = this ;
1940:                    vpMessage.type = J3dMessage.UPDATE_VIEW;
1941:                    vpMessage.threads = J3dThread.UPDATE_RENDER;
1942:                    vpMessage.args[0] = this ;
1943:                    synchronized (((ViewPlatformRetained) viewPlatform.retained).sphere) {
1944:                        vpMessage.args[1] = new Float(
1945:                                ((ViewPlatformRetained) viewPlatform.retained).sphere.radius);
1946:                    }
1947:                    vpMessage.args[2] = new Integer(OTHER_ATTRS_CHANGED);
1948:                    vpMessage.args[3] = new Integer(transparencySortingPolicy);
1949:                    VirtualUniverse.mc.processMessage(vpMessage);
1950:                }
1951:            }
1952:
1953:            /**
1954:             * Retrieves the current visibility policy.
1955:             * @return one of:
1956:             * VISIBILITY_DRAW_VISIBLE,
1957:             * VISIBILITY_DRAW_INVISIBLE, or VISIBILITY_DRAW_ALL.
1958:             *
1959:             * @since Java 3D 1.2
1960:             */
1961:            public int getVisibilityPolicy() {
1962:                return this .visibilityPolicy;
1963:            }
1964:
1965:            /**
1966:             * Sets the transparency sorting policy for this view.  This attribute 
1967:             * is one of:
1968:             *
1969:             * <UL>
1970:             * <LI>TRANSPARENCY_SORT_NONE, to specify that no depth sorting of
1971:             * transparent objects is performed.  Transparent objects are
1972:             * drawn after opaque objects, but are not sorted from back to
1973:             * front.</LI>
1974:             *
1975:             * <LI>TRANSPARENCY_SORT_GEOMETRY, to specify that transparent
1976:             * objects are depth-sorted on a per-geometry basis.  Each
1977:             * geometry object of each transparent Shape3D node is drawn from
1978:             * back to front.  Note that this policy will not split geometry
1979:             * into smaller pieces, so intersecting or intertwined objects may
1980:             * not be sorted correctly.</LI>
1981:             * </UL>
1982:             *
1983:             * The default policy is TRANSPARENCY_SORT_NONE.
1984:             *
1985:             * @param policy the new policy, one of TRANSPARENCY_SORT_NONE
1986:             * or TRANSPARENCY_SORT_GEOMETRY.
1987:             *
1988:             * @since Java 3D 1.3
1989:             */
1990:            public void setTransparencySortingPolicy(int policy) {
1991:                if (policy == transparencySortingPolicy) {
1992:                    return;
1993:                }
1994:
1995:                transparencySortingPolicy = policy;
1996:                if (activeStatus && isRunning) {
1997:
1998:                    J3dMessage vpMessage = new J3dMessage();
1999:                    vpMessage.universe = universe;
2000:                    vpMessage.view = this ;
2001:                    vpMessage.type = J3dMessage.UPDATE_VIEW;
2002:                    vpMessage.threads = J3dThread.UPDATE_RENDER;
2003:                    vpMessage.args[0] = this ;
2004:                    vpMessage.args[1] = null;
2005:                    vpMessage.args[2] = new Integer(TRANSP_SORT_POLICY_CHANGED);
2006:                    vpMessage.args[3] = new Integer(policy);
2007:                    VirtualUniverse.mc.processMessage(vpMessage);
2008:                }
2009:            }
2010:
2011:            /**
2012:             * Retrieves the current transparency sorting policy.
2013:             * @return one of:
2014:             * TRANSPARENCY_SORT_NONE or TRANSPARENCY_SORT_GEOMETRY.
2015:             *
2016:             * @since Java 3D 1.3
2017:             */
2018:            public int getTransparencySortingPolicy() {
2019:                return this .transparencySortingPolicy;
2020:            }
2021:
2022:            /**
2023:             * Turns head tracking on or off for this view.
2024:             * @param flag specifies whether head tracking is enabled or
2025:             * disabled for this view
2026:             */
2027:            public void setTrackingEnable(boolean flag) {
2028:
2029:                synchronized (this ) {
2030:                    this .trackingEnable = flag;
2031:                    vDirtyMask |= View.TRACKING_ENABLE_DIRTY;
2032:                }
2033:
2034:                repaint();
2035:            }
2036:
2037:            /**
2038:             * Returns a status flag indicating whether or not head tracking
2039:             * is enabled.
2040:             * @return a flag telling whether head tracking is enabled
2041:             */
2042:            public boolean getTrackingEnable() {
2043:                return this .trackingEnable;
2044:            }
2045:
2046:            /**
2047:             * Turns on or off the continuous
2048:             * updating of the userHeadToVworld transform.
2049:             * @param flag enables or disables continuous updating
2050:             */
2051:            public void setUserHeadToVworldEnable(boolean flag) {
2052:
2053:                synchronized (this ) {
2054:                    userHeadToVworldEnable = flag;
2055:                    vDirtyMask |= View.USER_HEAD_TO_VWORLD_ENABLE_DIRTY;
2056:                }
2057:                repaint();
2058:            }
2059:
2060:            /**
2061:             * Returns a status flag indicating whether or not
2062:             * Java 3D is continuously updating the userHeadToVworldEnable transform.
2063:             * @return a flag indicating if continuously updating userHeadToVworld
2064:             */
2065:            public boolean getUserHeadToVworldEnable() {
2066:                return userHeadToVworldEnable;
2067:            }
2068:
2069:            /**
2070:             * Computes the sensor to virtual-world transform
2071:             * and copies that value into the transform provided.
2072:             * The computed transforms takes points in the sensor's coordinate
2073:             * system and produces the point's corresponding value in
2074:             * virtual-world coordinates. 
2075:             * @param sensor the sensor in question
2076:             * @param t the object that will receive the transform
2077:             */
2078:            public void getSensorToVworld(Sensor sensor, Transform3D t) {
2079:                // grab the first canvas -- not sure for multiple canvases
2080:                Canvas3D canvas = (Canvas3D) this .canvases.firstElement();
2081:                Transform3D localTrans = new Transform3D();
2082:                synchronized (canvas.canvasViewCache) {
2083:                    t.set(canvas.canvasViewCache.getVworldToTrackerBase());
2084:                }
2085:                t.invert();
2086:                sensor.getRead(localTrans);
2087:                t.mul(localTrans);
2088:            }
2089:
2090:            /**
2091:             * Retrieves the position of the specified Sensor's 
2092:             * hotspot in virtual-world coordinates
2093:             * and copies that value into the position provided.
2094:             * This value is derived from other values and is read-only.
2095:             * @param sensor the sensor in question
2096:             * @param position the variable that will receive the position
2097:             */
2098:            public void getSensorHotspotInVworld(Sensor sensor, Point3f position) {
2099:
2100:                Canvas3D canvas = (Canvas3D) this .canvases.firstElement();
2101:                Transform3D sensorToVworld = new Transform3D();
2102:                Point3d hotspot3d = new Point3d();
2103:
2104:                getSensorToVworld(sensor, sensorToVworld);
2105:                sensor.getHotspot(hotspot3d);
2106:                position.set(hotspot3d);
2107:                sensorToVworld.transform(position);
2108:            }
2109:
2110:            /**
2111:             * Retrieves the position of the specified Sensor's 
2112:             * hotspot in virtual-world coordinates
2113:             * and copies that value into the position provided.
2114:             * This value is derived from other values and is read-only.
2115:             * @param sensor the sensor in question
2116:             * @param position the variable that will receive the position
2117:             */
2118:            public void getSensorHotspotInVworld(Sensor sensor, Point3d position) {
2119:
2120:                Canvas3D canvas = (Canvas3D) this .canvases.firstElement();
2121:                Transform3D sensorToVworld = new Transform3D();
2122:
2123:                getSensorToVworld(sensor, sensorToVworld);
2124:                sensor.getHotspot(position);
2125:                sensorToVworld.transform(position);
2126:            }
2127:
2128:            /**
2129:             * Sets given Canvas3D at the given index position.
2130:             * @param canvas3D the given Canvas3D to be set
2131:             * @param index the position to be set
2132:             * @exception IllegalStateException if the specified canvas is
2133:             * a stereo canvas with a monoscopicEyePolicy of CYCLOPEAN_EYE_VIEW,
2134:             * and the viewPolicy for this view is HMD_VIEW
2135:             * @exception IllegalSharingException if the specified canvas is
2136:             * associated with another view
2137:             */
2138:            public void setCanvas3D(Canvas3D canvas3D, int index) {
2139:
2140:                if ((viewPolicy == HMD_VIEW)
2141:                        && (canvas3D.monoscopicViewPolicy == View.CYCLOPEAN_EYE_VIEW)
2142:                        && (!canvas3D.useStereo)) {
2143:
2144:                    throw new IllegalStateException(J3dI18N.getString("View31"));
2145:                }
2146:
2147:                Canvas3D cv;
2148:
2149:                synchronized (canvasList) {
2150:                    if (canvas3D.getView() != null)
2151:                        throw new IllegalSharingException(J3dI18N
2152:                                .getString("View10"));
2153:                    cv = (Canvas3D) canvases.elementAt(index);
2154:                    canvases.setElementAt(canvas3D, index);
2155:                    removeFromCanvasList(cv);
2156:                    addToCanvasList(canvas3D);
2157:                    canvasesDirty = true;
2158:                }
2159:
2160:                canvas3D.setView(this );
2161:                cv.setView(null);
2162:
2163:                if (canvas3D.added) {
2164:                    evaluateActive();
2165:                }
2166:                if (cv.added) {
2167:                    evaluateActive();
2168:                }
2169:
2170:            }
2171:
2172:            /**
2173:             * Gets the Canvas3D at the specified index position.
2174:             * @param index the position from which to get Canvas3D object
2175:             * @return the Canvas3D at the sprcified index position
2176:             */
2177:            public Canvas3D getCanvas3D(int index) {
2178:                return (Canvas3D) this .canvases.elementAt(index);
2179:            }
2180:
2181:            /**
2182:             * Gets the enumeration object of all the Canvas3Ds.
2183:             * @return the enumeration object of all the Canvas3Ds.
2184:             */
2185:            public Enumeration getAllCanvas3Ds() {
2186:                return canvases.elements();
2187:            }
2188:
2189:            /**
2190:             * Returns the number of Canvas3Ds in this View.
2191:             * @return the number of Canvas3Ds in this View
2192:             *
2193:             * @since Java 3D 1.2
2194:             */
2195:            public int numCanvas3Ds() {
2196:                return canvases.size();
2197:            }
2198:
2199:            /**
2200:             * Adds the given Canvas3D at the end of the list.
2201:             * @param canvas3D the Canvas3D to be added
2202:             * @exception IllegalStateException if the specified canvas is
2203:             * a stereo canvas with a monoscopicEyePolicy of CYCLOPEAN_EYE_VIEW,
2204:             * and the viewPolicy for this view is HMD_VIEW
2205:             * @exception IllegalSharingException if the specified canvas is
2206:             * associated with another view
2207:             */
2208:            public void addCanvas3D(Canvas3D canvas3D) {
2209:
2210:                if ((viewPolicy == HMD_VIEW)
2211:                        && (canvas3D.monoscopicViewPolicy == View.CYCLOPEAN_EYE_VIEW)
2212:                        && (!canvas3D.useStereo)) {
2213:                    throw new IllegalStateException(J3dI18N.getString("View31"));
2214:                }
2215:
2216:                synchronized (canvasList) {
2217:                    if (canvas3D.getView() != null)
2218:                        throw new IllegalSharingException(J3dI18N
2219:                                .getString("View10"));
2220:                    canvases.addElement(canvas3D);
2221:                    addToCanvasList(canvas3D);
2222:                    canvasesDirty = true;
2223:                }
2224:
2225:                canvas3D.setView(this );
2226:
2227:                if (canvas3D.added) {
2228:                    if ((canvas3D.visible || canvas3D.offScreen)
2229:                            && canvas3D.firstPaintCalled) {
2230:                        canvas3D.active = true;
2231:                    }
2232:                    evaluateActive();
2233:                }
2234:            }
2235:
2236:            /**
2237:             * Inserts the Canvas3D at the given index position.
2238:             * @param canvas3D the Canvas3D to be inserted
2239:             * @param index the position to be inserted at
2240:             * @exception IllegalStateException if the specified canvas is
2241:             * a stereo canvas with a monoscopicEyePolicy of CYCLOPEAN_EYE_VIEW,
2242:             * and the viewPolicy for this view is HMD_VIEW
2243:             * @exception IllegalSharingException if the specified canvas is
2244:             * associated with another view
2245:             */
2246:            public void insertCanvas3D(Canvas3D canvas3D, int index) {
2247:
2248:                if ((viewPolicy == HMD_VIEW)
2249:                        && (canvas3D.monoscopicViewPolicy == View.CYCLOPEAN_EYE_VIEW)
2250:                        && (!canvas3D.useStereo)) {
2251:                    throw new IllegalStateException(J3dI18N.getString("View31"));
2252:                }
2253:
2254:                synchronized (canvasList) {
2255:                    if (canvas3D.getView() != null)
2256:                        throw new IllegalSharingException(J3dI18N
2257:                                .getString("View10"));
2258:                    this .canvases.insertElementAt(canvas3D, index);
2259:                    addToCanvasList(canvas3D);
2260:                    canvasesDirty = true;
2261:                }
2262:
2263:                canvas3D.setView(this );
2264:
2265:                if (canvas3D.added) {
2266:                    if ((canvas3D.visible || canvas3D.offScreen)
2267:                            && canvas3D.firstPaintCalled) {
2268:                        canvas3D.active = true;
2269:                    }
2270:                    evaluateActive();
2271:                }
2272:            }
2273:
2274:            /**
2275:             * Removes the Canvas3D from the given index position.
2276:             * @param index the position of Canvas3D object to be removed
2277:             */
2278:            public void removeCanvas3D(int index) {
2279:                // index -1 is possible if the view is unregistered first 
2280:                // because viewPlatform is clearLived,
2281:                // and then removeCanvas from the view
2282:                if (index == -1)
2283:                    return;
2284:
2285:                Canvas3D cv;
2286:
2287:                synchronized (canvasList) {
2288:                    cv = (Canvas3D) canvases.elementAt(index);
2289:
2290:                    canvases.removeElementAt(index);
2291:                    removeFromCanvasList(cv);
2292:                    canvasesDirty = true;
2293:                }
2294:
2295:                // reset canvas will set view to null also
2296:                VirtualUniverse.mc.postRequest(MasterControl.RESET_CANVAS, cv);
2297:                cv.pendingView = null;
2298:
2299:                computeCanvasesCached();
2300:
2301:                if (cv.added) {
2302:                    cv.active = false;
2303:                    evaluateActive();
2304:                }
2305:                if (universe != null) {
2306:                    universe.waitForMC();
2307:                }
2308:            }
2309:
2310:            /**
2311:             * Retrieves the index of the specified Canvas3D in
2312:             * this View's list of Canvas3Ds
2313:             *
2314:             * @param canvas3D the Canvas3D to be looked up.
2315:             * @return the index of the specified Canvas3D;
2316:             * returns -1 if the object is not in the list.
2317:             *
2318:             * @since Java 3D 1.3
2319:             */
2320:            public int indexOfCanvas3D(Canvas3D canvas3D) {
2321:                return canvases.indexOf(canvas3D);
2322:            }
2323:
2324:            /**
2325:             * Removes the specified Canvas3D from this View's
2326:             * list of Canvas3Ds.
2327:             * If the specified object is not in the list, the list is not modified.
2328:             *
2329:             * @param canvas3D the Canvas3D to be removed.
2330:             */
2331:            public void removeCanvas3D(Canvas3D canvas3D) {
2332:                removeCanvas3D(canvases.indexOf(canvas3D));
2333:            }
2334:
2335:            /**
2336:             * Removes all Canvas3Ds from this View.
2337:             *
2338:             * @since Java 3D 1.3
2339:             */
2340:            public void removeAllCanvas3Ds() {
2341:                LinkedList tmpCanvases = new LinkedList();
2342:
2343:                synchronized (canvasList) {
2344:                    int numCanvases = canvases.size();
2345:
2346:                    // Remove in reverse order to ensure valid indices
2347:                    for (int index = numCanvases - 1; index >= 0; index--) {
2348:                        Canvas3D cv;
2349:
2350:                        cv = (Canvas3D) canvases.elementAt(index);
2351:
2352:                        // Record list of canvases to be deleted;
2353:                        tmpCanvases.add(cv);
2354:
2355:                        canvases.removeElementAt(index);
2356:                        removeFromCanvasList(cv);
2357:                        canvasesDirty = true;
2358:                    }
2359:                }
2360:
2361:                // ISSUE 83: postRequest must *not* be called while holding
2362:                // canvasList lock. Holding the lock can cause a deadlock.
2363:
2364:                Iterator iterator = tmpCanvases.iterator();
2365:                while (iterator.hasNext()) {
2366:                    Canvas3D cv = (Canvas3D) iterator.next();
2367:
2368:                    // reset canvas will set view to null also
2369:                    VirtualUniverse.mc.postRequest(MasterControl.RESET_CANVAS,
2370:                            cv);
2371:                    cv.pendingView = null;
2372:
2373:                    if (cv.added) {
2374:                        cv.active = false;
2375:                    }
2376:                }
2377:
2378:                computeCanvasesCached();
2379:
2380:                evaluateActive();
2381:
2382:                if (universe != null) {
2383:                    universe.waitForMC();
2384:                }
2385:            }
2386:
2387:            // This adds this canvas and its screen to the screen list. 
2388:            // Locks are already acquired before this is called.
2389:            private void addToCanvasList(Canvas3D c) {
2390:
2391:                for (int i = screenList.size() - 1; i >= 0; i--) {
2392:                    if ((Screen3D) screenList.get(i) == c.screen) {
2393:                        // This is the right screen slot
2394:                        ((ArrayList) canvasList.get(i)).add(c);
2395:                        canvasesDirty = true;
2396:                        return;
2397:                    }
2398:                }
2399:
2400:                // Add a screen slot
2401:                screenList.add(c.screen);
2402:                ArrayList clist = new ArrayList();
2403:                canvasList.add(clist);
2404:                clist.add(c);
2405:                canvasesDirty = true;
2406:            }
2407:
2408:            // This removes this canvas and its screen from the screen list
2409:            // Locks are already acquired before this is called.
2410:            private void removeFromCanvasList(Canvas3D c) {
2411:
2412:                for (int i = screenList.size() - 1; i >= 0; i--) {
2413:                    if ((Screen3D) screenList.get(i) == c.screen) {
2414:                        // This is the right screen slot
2415:                        ArrayList clist = (ArrayList) canvasList.get(i);
2416:                        clist.remove(clist.indexOf(c));
2417:
2418:                        if (clist.size() == 0) {
2419:                            canvasList.remove(i);
2420:                            screenList.remove(i);
2421:                            canvasesDirty = true;
2422:                        }
2423:                        return;
2424:                    }
2425:                }
2426:            }
2427:
2428:            // Locks are not acquired before this is called.
2429:            void computeCanvasesCached() {
2430:
2431:                synchronized (canvasList) {
2432:                    ArrayList cv;
2433:                    int len = canvases.size();
2434:
2435:                    Canvas3D newCachedCanvases[] = new Canvas3D[len];
2436:                    for (int i = 0; i < len; i++) {
2437:                        newCachedCanvases[i] = (Canvas3D) canvases.get(i);
2438:                    }
2439:                    // Do this in one instruction so there is no need to
2440:                    // synchronized getCanvases()
2441:
2442:                    cachedCanvases = newCachedCanvases;
2443:                    len = 0;
2444:                    longestScreenList = 0;
2445:                    cachedCanvasList = new Canvas3D[canvasList.size()][0];
2446:                    for (int i = 0; i < cachedCanvasList.length; i++) {
2447:                        cv = (ArrayList) canvasList.get(i);
2448:                        len = cv.size();
2449:                        cachedCanvasList[i] = new Canvas3D[len];
2450:                        for (int j = 0; j < len; j++) {
2451:                            cachedCanvasList[i][j] = (Canvas3D) cv.get(j);
2452:                        }
2453:
2454:                        if (len > longestScreenList) {
2455:                            longestScreenList = len;
2456:                        }
2457:                    }
2458:                    len = screenList.size();
2459:                    Screen3D newCachedScreens[] = new Screen3D[len];
2460:
2461:                    for (int i = 0; i < len; i++) {
2462:                        newCachedScreens[i] = (Screen3D) screenList.get(i);
2463:                    }
2464:                    // Do this in one instruction so there is no need to
2465:                    // synchronized getScreens()
2466:                    cachedScreens = newCachedScreens;
2467:                    canvasesDirty = false;
2468:                }
2469:            }
2470:
2471:            // This creates a 2 dimentional list of canvases
2472:            // ONLY MC can call this procedure with canCompute=true, 
2473:            // since MC want the result return by
2474:            // evaluateCanvases and updateWorkThreads agree to each other,
2475:            // so only evaluateCanvases can compute a new list.
2476:            // Other threads should use getCanvasList(false).
2477:            Canvas3D[][] getCanvasList(boolean canCompute) {
2478:                if (canvasesDirty && canCompute) {
2479:                    computeCanvasesCached();
2480:                }
2481:                return cachedCanvasList;
2482:            }
2483:
2484:            // assume getCanvasList is called before
2485:            int getLongestScreenList() {
2486:                return longestScreenList;
2487:            }
2488:
2489:            // assume getCanvasList is called before
2490:            Canvas3D[] getCanvases() {
2491:                return cachedCanvases;
2492:            }
2493:
2494:            // assume getCanvasList is called before
2495:            Screen3D[] getScreens() {
2496:                return cachedScreens;
2497:            }
2498:
2499:            Canvas3D getFirstCanvas() {
2500:                synchronized (canvasList) {
2501:                    if (canvases.size() > 0) {
2502:                        return (Canvas3D) canvases.elementAt(0);
2503:                    }
2504:                    return null;
2505:                }
2506:            }
2507:
2508:            /**
2509:             * This method returns the time at which the most recent rendering
2510:             * frame started.  It is defined as the number of milliseconds
2511:             * since January 1, 1970 00:00:00 GMT.
2512:             * Since multiple canvases might be attached to this View,
2513:             * the start of a frame is defined as the point in time just prior
2514:             * to clearing any canvas attached to this view.
2515:             * @return the time at which the most recent rendering frame started
2516:             */
2517:            public long getCurrentFrameStartTime() {
2518:                synchronized (frameStartTimes) {
2519:                    return currentFrameStartTime;
2520:                }
2521:            }
2522:
2523:            /**
2524:             * This method returns the duration, in milliseconds, of the most
2525:             * recently completed rendering frame.  The time taken to render
2526:             * all canvases attached to this view is measured.  This duration
2527:             * is computed as the difference between the start of the most recently
2528:             * completed frame and the end of that frame.
2529:             * Since multiple canvases might be attached to this View,
2530:             * the start of a frame is defined as the point in time just prior
2531:             * to clearing any canvas attached to this view--before preRender
2532:             * is called for any canvas.  Similarly, the end of a frame is
2533:             * defined as the point in time just after swapping the buffer for
2534:             * all canvases--after postSwap is called for all canvases.
2535:             * Note that since the frame duration is measured from start to stop
2536:             * for this view only, the value returned is not the same as
2537:             * frame rate; it measures only the rendering time for this view.
2538:             *
2539:             * @return the duration, in milliseconds, of the most recently
2540:             * completed rendering frame
2541:             */
2542:            public long getLastFrameDuration() {
2543:                synchronized (frameStartTimes) {
2544:                    return currentFrameDuration;
2545:                }
2546:            }
2547:
2548:            /**
2549:             * This method returns the frame number for this view.  The frame
2550:             * number starts at 0 and is incremented at the start of each
2551:             * frame--prior to clearing all the canvases attached to this
2552:             * view.
2553:             *
2554:             * @return the current frame number for this view
2555:             */
2556:            public long getFrameNumber() {
2557:                synchronized (frameStartTimes) {
2558:                    return currentFrameNumber;
2559:                }
2560:            }
2561:
2562:            /**
2563:             * Retrieves the implementation-dependent maximum number of
2564:             * frames whose start times will be recorded by the system.  This
2565:             * value is guaranteed to be at least 10 for all implementations
2566:             * of the Java 3D API.
2567:             * @return the maximum number of frame start times recorded
2568:             */
2569:            public static int getMaxFrameStartTimes() {
2570:                return (NUMBER_FRAME_START_TIMES);
2571:            }
2572:
2573:            /**
2574:             * Copies the last <i>k</i> frame start time values into
2575:             * the user-specified array.  The most recent frame start time is
2576:             * copied to location 0 of the array, the next most recent frame
2577:             * start time is copied into location 1 of the array, and so forth.
2578:             * If times.length is smaller than
2579:             * maxFrameStartTimes, then only the last times.length values are
2580:             * copied.  If times.length is greater than maxFrameStartTimes,
2581:             * then all array elements after index maxFrameStartTimes-1 are
2582:             * set to 0.
2583:             *
2584:             * @return the frame number of the most recent frame in the array
2585:             *
2586:             * @see #setMinimumFrameCycleTime
2587:             */
2588:            public long getFrameStartTimes(long[] times) {
2589:                int index, i, loopCount;
2590:                long lastFrameNumber;
2591:
2592:                synchronized (frameStartTimes) {
2593:                    index = currentFrameIndex - 1;
2594:                    if (index < 0) {
2595:                        index = NUMBER_FRAME_START_TIMES - 1;
2596:                    }
2597:                    lastFrameNumber = frameNumbers[index];
2598:
2599:                    if (times.length <= NUMBER_FRAME_START_TIMES) {
2600:                        loopCount = times.length;
2601:                    } else {
2602:                        loopCount = NUMBER_FRAME_START_TIMES;
2603:                    }
2604:
2605:                    for (i = 0; i < loopCount; i++) {
2606:                        times[i] = frameStartTimes[index];
2607:                        index--;
2608:                        if (index < 0) {
2609:                            index = NUMBER_FRAME_START_TIMES - 1;
2610:                        }
2611:                    }
2612:
2613:                    if (times.length > NUMBER_FRAME_START_TIMES) {
2614:                        for (; i < times.length; i++) {
2615:                            times[i] = 0;
2616:                        }
2617:                    }
2618:                }
2619:
2620:                return (lastFrameNumber);
2621:            }
2622:
2623:            /**
2624:             * Sets the minimum frame cycle time, in milliseconds, for this
2625:             * view.  The Java 3D renderer will ensure that the time between
2626:             * the start of each successive frame is at least the specified
2627:             * number of milliseconds.  The default value is 0.
2628:             *
2629:             * @param minimumTime the minimum number of milliseconds between
2630:             * successive frames
2631:             *
2632:             * @exception IllegalArgumentException if <code>minimumTime < 0</code>
2633:             *
2634:             * @see #getFrameStartTimes
2635:             *
2636:             * @since Java 3D 1.2
2637:             */
2638:            public void setMinimumFrameCycleTime(long minimumTime) {
2639:                if (minimumTime < 0L)
2640:                    throw new IllegalArgumentException(J3dI18N
2641:                            .getString("View27"));
2642:
2643:                minFrameCycleTime = minimumTime;
2644:                VirtualUniverse.mc.setWork();
2645:            }
2646:
2647:            /**
2648:             * Retrieves the minimum frame cycle time, in milliseconds, for this view.
2649:             * @return the minimum frame cycle time for this view.
2650:             *
2651:             * @see #getFrameStartTimes
2652:             *
2653:             * @since Java 3D 1.2
2654:             */
2655:            public long getMinimumFrameCycleTime() {
2656:                return minFrameCycleTime;
2657:            }
2658:
2659:            /**
2660:             * This adds a frame time to the this of frame times
2661:             */
2662:            void setFrameTimingValues() {
2663:
2664:                synchronized (frameStartTimes) {
2665:                    if (currentFrameIndex == NUMBER_FRAME_START_TIMES) {
2666:                        currentFrameIndex = 0;
2667:                    }
2668:
2669:                    frameNumbers[currentFrameIndex] = frameNumber;
2670:
2671:                    frameStartTimes[currentFrameIndex++] = startTime;
2672:                    currentFrameStartTime = startTime;
2673:                    currentFrameDuration = stopTime - startTime;
2674:                    currentFrameNumber = frameNumber;
2675:                }
2676:            }
2677:
2678:            /**
2679:             * Return true if maximum fps impose by user reach
2680:             */
2681:            void computeCycleTime() {
2682:                if (minFrameCycleTime == 0) {
2683:                    isMinCycleTimeAchieve = true;
2684:                    sleepTime = 0;
2685:                } else {
2686:                    sleepTime = minFrameCycleTime
2687:                            - (J3dClock.currentTimeMillis() - startTime);
2688:                    isMinCycleTimeAchieve = (sleepTime <= 0);
2689:                }
2690:            }
2691:
2692:            /**
2693:             * Enables or disables automatic freezing of the depth buffer for
2694:             * objects rendered
2695:             * during the transparent rendering pass (i.e., objects rendered
2696:             * using alpha blending) for this view.
2697:             * If enabled, depth buffer writes will be disabled during the
2698:             * transparent rendering pass regardless of the value of
2699:             * the depth buffer write enable flag in the RenderingAttributes
2700:             * object for a particular node.
2701:             * This flag is enabled by default.
2702:             * @param flag indicates whether automatic freezing of the depth buffer
2703:             * for transparent/antialiased objects is enabled.
2704:             * @see RenderingAttributes#setDepthBufferWriteEnable
2705:             */
2706:            public void setDepthBufferFreezeTransparent(boolean flag) {
2707:                depthBufferFreezeTransparent = flag;
2708:                repaint();
2709:            }
2710:
2711:            /**
2712:             * Retrieves the current value of the depth buffer freeze transparent
2713:             * flag for this view.
2714:             * @return a flag that indicates whether or not the depth
2715:             * buffer is automatically frozen during the transparent rendering pass.
2716:             */
2717:            public boolean getDepthBufferFreezeTransparent() {
2718:                return depthBufferFreezeTransparent;
2719:            }
2720:
2721:            /**
2722:             * Enables or disables scene antialiasing for this view.
2723:             * If enabled, the entire scene will be antialiased on
2724:             * each canvas in which scene antialiasing is available.
2725:             * Scene antialiasing is disabled by default.
2726:             * <p>
2727:             * NOTE: Scene antialiasing is ignored in pure immediate mode,
2728:             * but is supported in mixed-immediate mode.
2729:             * @param flag indicates whether scene antialiasing is enabled
2730:             *
2731:             * @see Canvas3D#queryProperties
2732:             */
2733:            public void setSceneAntialiasingEnable(boolean flag) {
2734:                sceneAntialiasingEnable = flag;
2735:                repaint();
2736:            }
2737:
2738:            /**
2739:             * Returns a flag that indicates whether or not scene antialiasing
2740:             * is enabled for this view.
2741:             * @return a flag that indicates whether scene antialiasing is enabled
2742:             */
2743:            public boolean getSceneAntialiasingEnable() {
2744:                return sceneAntialiasingEnable;
2745:            }
2746:
2747:            /**
2748:             * Sets a flag that indicates whether the local eyepoint is used in
2749:             * lighting calculations for perspective projections.
2750:             * If this flag is set to true, the view vector is calculated per-vertex
2751:             * based on the direction from the actual eyepoint to the vertex.
2752:             * If this flag is set to false, a single view vector is computed from
2753:             * the eyepoint to the center of the view frustum.  This is
2754:             * called infinite eye lighting.
2755:             * Local eye lighting is disabled by default, and is ignored for
2756:             * parallel projections.
2757:             * @param flag indicates whether local eye lighting is enabled
2758:             */
2759:            public void setLocalEyeLightingEnable(boolean flag) {
2760:                localEyeLightingEnable = flag;
2761:                repaint();
2762:            }
2763:
2764:            /**
2765:             * Retrieves a flag that indicates whether or not local eye lighting
2766:             * is enabled for this view.
2767:             * @return a flag that indicates whether local eye lighting is enabled
2768:             */
2769:            public boolean getLocalEyeLightingEnable() {
2770:                return localEyeLightingEnable;
2771:            }
2772:
2773:            /**
2774:             * Attach viewPlatform structure to this view.
2775:             * @param vp the viewPlatform to be attached
2776:             */
2777:            public void attachViewPlatform(ViewPlatform vp) {
2778:
2779:                if ((vp != null) && (vp == viewPlatform)) {
2780:                    return;
2781:                }
2782:
2783:                if (viewPlatform != null) {
2784:                    ((ViewPlatformRetained) viewPlatform.retained)
2785:                            .removeView(this );
2786:                    if (viewPlatform.isLive()) {
2787:                        synchronized (evaluateLock) {
2788:                            viewPlatform = null;
2789:                            // cleanup View stuff for the old platform
2790:                            evaluateActive();
2791:                            viewPlatform = vp;
2792:                        }
2793:                        if (universe != null) {
2794:                            universe.waitForMC();
2795:                        }
2796:                    } else {
2797:                        viewPlatform = vp;
2798:                    }
2799:                } else {
2800:                    viewPlatform = vp;
2801:                }
2802:                if (vp != null) {
2803:                    if (vp.isLive()) {
2804:                        checkView();
2805:                        setUniverse(((ViewPlatformRetained) vp.retained).universe);
2806:                    }
2807:                    ((ViewPlatformRetained) vp.retained).setView(this );
2808:                }
2809:
2810:                evaluateActive();
2811:                if ((vp == null) && (universe != null)) {
2812:                    universe.waitForMC();
2813:                }
2814:            }
2815:
2816:            /**
2817:             * Retrieves the currently attached ViewPlatform object
2818:             * @return the currently attached ViewPlatform
2819:             */
2820:            public ViewPlatform getViewPlatform() {
2821:                return viewPlatform;
2822:            }
2823:
2824:            /**
2825:             * Checks view parameters for consistency
2826:             */
2827:            void checkView() {
2828:                if (physicalBody == null)
2829:                    throw new IllegalStateException(J3dI18N.getString("View13"));
2830:
2831:                if (physicalEnvironment == null)
2832:                    throw new IllegalStateException(J3dI18N.getString("View14"));
2833:            }
2834:
2835:            /**
2836:             * Stops the behavior scheduler after all
2837:             * currently scheduled behaviors are executed.  Any frame-based
2838:             * behaviors scheduled to wake up on the next frame will be
2839:             * executed at least once before the behavior scheduler is
2840:             * stopped.
2841:             * <p>
2842:             * NOTE: This is a heavy-weight method
2843:             * intended for verification and image capture (recording); it
2844:             * is <i>not</i> intended to be used for flow control.
2845:             * @return a pair of integers that specify the beginning and ending
2846:             * time (in milliseconds since January 1, 1970 00:00:00 GMT)
2847:             * of the behavior scheduler's last pass
2848:             * @exception IllegalStateException if this method is called
2849:             * from a Behavior method or from any Canvas3D render callback
2850:             * method
2851:             */
2852:            public final long[] stopBehaviorScheduler() {
2853:                long[] intervalTime = new long[2];
2854:
2855:                if (checkBehaviorSchedulerState("View15", "View16")) {
2856:                    if (activeStatus && isRunning
2857:                            && (universe.behaviorScheduler != null)) {
2858:                        // view is active
2859:                        universe.behaviorScheduler
2860:                                .stopBehaviorScheduler(intervalTime);
2861:                    } else {
2862:                        if ((universe != null)
2863:                                && (universe.behaviorScheduler != null)) {
2864:                            universe.behaviorScheduler.userStop = true;
2865:                        }
2866:                    }
2867:                }
2868:                stopBehavior = true;
2869:                return intervalTime;
2870:            }
2871:
2872:            /**
2873:             * Starts the behavior scheduler running after it has been stopped.
2874:             * @exception IllegalStateException if this method is called
2875:             * from a Behavior method or from any Canvas3D render callback
2876:             * method
2877:             */
2878:            public final void startBehaviorScheduler() {
2879:                if (checkBehaviorSchedulerState("View17", "View18")) {
2880:                    if (activeStatus && isRunning
2881:                            && (universe.behaviorScheduler != null)) {
2882:                        universe.behaviorScheduler.startBehaviorScheduler();
2883:
2884:                    } else {
2885:                        if ((universe != null)
2886:                                && (universe.behaviorScheduler != null)) {
2887:                            universe.behaviorScheduler.userStop = false;
2888:                        }
2889:                    }
2890:                }
2891:
2892:                stopBehavior = false;
2893:            }
2894:
2895:            /**
2896:             * Check if BehaviorScheduler is in valid state to start/stop
2897:             * itself. 
2898:             * @param s1 Exception String if method is called from a Canvas3D
2899:             * @param s2 Exception String if method is called from a Behavior method
2900:             * @return true if viewPlatform is live
2901:             * @exception IllegalStateException if this method is called
2902:             * from a Behavior method or from any Canvas3D render callback
2903:             * method
2904:             *
2905:             */
2906:            boolean checkBehaviorSchedulerState(String s1, String s2) {
2907:                Thread me = Thread.currentThread();
2908:
2909:                if (inCanvasCallback) {
2910:                    synchronized (canvasList) {
2911:                        for (int i = canvases.size() - 1; i >= 0; i--) {
2912:                            if (((Canvas3D) canvases.elementAt(i)).screen.renderer == me) {
2913:                                throw new IllegalStateException(J3dI18N
2914:                                        .getString(s1));
2915:                            }
2916:                        }
2917:                    }
2918:                }
2919:
2920:                if ((viewPlatform != null) && viewPlatform.isLive()) {
2921:                    if (universe.inBehavior
2922:                            && (universe.behaviorScheduler == me)) {
2923:                        throw new IllegalStateException(J3dI18N.getString(s2));
2924:                    }
2925:                    return true;
2926:                }
2927:                return false;
2928:            }
2929:
2930:            /**
2931:             * Retrieves a flag that indicates whether the behavior scheduler is
2932:             * currently running.
2933:             * @return true if the behavior scheduler is running, false otherwise
2934:             * @exception IllegalStateException if this method is called
2935:             * from a Behavior method or from any Canvas3D render callback
2936:             * method
2937:             */
2938:            public final boolean isBehaviorSchedulerRunning() {
2939:                return (((universe != null) && !stopBehavior && (universe.behaviorScheduler != null)) ? !universe.behaviorScheduler.userStop
2940:                        : false);
2941:            }
2942:
2943:            /**
2944:             * Stops traversing the scene graph for this
2945:             * view after the current state of the scene graph is reflected on
2946:             * all canvases attached to this view.  The renderers associated
2947:             * with these canvases are also stopped.
2948:             * <p>
2949:             * NOTE: This is a heavy-weight method
2950:             * intended for verification and image capture (recording); it
2951:             * is <i>not</i> intended to be used for flow control.
2952:             * @exception IllegalStateException if this method is called
2953:             * from a Behavior method or from any Canvas3D render callback
2954:             * method
2955:             */
2956:            public final void stopView() {
2957:                checkViewState("View19", "View20");
2958:                synchronized (startStopViewLock) {
2959:                    if (activeStatus && isRunning) {
2960:                        VirtualUniverse.mc.postRequest(MasterControl.STOP_VIEW,
2961:                                this );
2962:                        while (isRunning) {
2963:                            MasterControl.threadYield();
2964:                        }
2965:                    } else {
2966:                        isRunning = false;
2967:                    }
2968:                }
2969:            }
2970:
2971:            /**
2972:             * Starts
2973:             * traversing this view, and starts the renderers associated
2974:             * with all canvases attached to this view.
2975:             * @exception IllegalStateException if this method is called
2976:             * from a Behavior method or from any Canvas3D render callback
2977:             * method
2978:             */
2979:            public final void startView() {
2980:
2981:                checkViewState("View21", "View22");
2982:                synchronized (startStopViewLock) {
2983:                    if (activeStatus && !isRunning) {
2984:                        VirtualUniverse.mc.postRequest(
2985:                                MasterControl.START_VIEW, this );
2986:                        while (!isRunning) {
2987:                            MasterControl.threadYield();
2988:                        }
2989:                        VirtualUniverse.mc.sendRunMessage(this ,
2990:                                J3dThread.RENDER_THREAD);
2991:                    } else {
2992:                        isRunning = true;
2993:                    }
2994:                }
2995:
2996:            }
2997:
2998:            /**
2999:             *  This will throw IllegalStateException if not in valid state
3000:             *  for start/stop request.
3001:             */
3002:            void checkViewState(String s1, String s2)
3003:                    throws IllegalStateException {
3004:                if (inCanvasCallback) {
3005:                    Thread me = Thread.currentThread();
3006:                    synchronized (canvasList) {
3007:                        for (int i = canvases.size() - 1; i >= 0; i--) {
3008:                            Canvas3D cv = (Canvas3D) canvases.elementAt(i);
3009:                            if (cv.screen.renderer == me) {
3010:                                throw new IllegalStateException(J3dI18N
3011:                                        .getString(s1));
3012:                            }
3013:                        }
3014:                    }
3015:                }
3016:
3017:                if ((viewPlatform != null) && viewPlatform.isLive()) {
3018:                    if (universe.inBehavior
3019:                            && (Thread.currentThread() == universe.behaviorScheduler)) {
3020:                        throw new IllegalStateException(J3dI18N.getString(s2));
3021:                    }
3022:                }
3023:            }
3024:
3025:            /**
3026:             * Retrieves a flag that indicates whether the traverser is
3027:             * currently running on this view.
3028:             * @return true if the traverser is running, false otherwise
3029:             * @exception IllegalStateException if this method is called
3030:             * from a Behavior method or from any Canvas3D render callback
3031:             * method
3032:             */
3033:            public final boolean isViewRunning() {
3034:                return isRunning;
3035:            }
3036:
3037:            /**
3038:             * Renders one frame for a stopped View.  Functionally, this
3039:             * method is equivalent to <code>startView()</code> followed by
3040:             * <code>stopview()</code>, except that it is atomic, which
3041:             * guarantees that only one frame is rendered.
3042:             *
3043:             * @exception IllegalStateException if this method is called from
3044:             * a Behavior method or from any Canvas3D render callback, or if
3045:             * the view is currently running.
3046:             *
3047:             * @since Java 3D 1.2
3048:             */
3049:            public void renderOnce() {
3050:                checkViewState("View28", "View29");
3051:                synchronized (startStopViewLock) {
3052:                    if (isRunning) {
3053:                        throw new IllegalStateException(J3dI18N
3054:                                .getString("View30"));
3055:                    }
3056:                    renderOnceFinish = false;
3057:                    VirtualUniverse.mc.postRequest(MasterControl.RENDER_ONCE,
3058:                            this );
3059:                    while (!renderOnceFinish) {
3060:                        MasterControl.threadYield();
3061:                    }
3062:                    renderOnceFinish = true;
3063:                }
3064:            }
3065:
3066:            /**
3067:             * Requests that this View be scheduled for rendering as soon as
3068:             * possible.  The repaint method may return before the frame has
3069:             * been rendered.  If the view is stopped, or if the view is
3070:             * continuously running (for example, due to a free-running
3071:             * interpolator), this method will have no effect.  Most
3072:             * applications will not need to call this method, since any
3073:             * update to the scene graph or to viewing parameters will
3074:             * automatically cause all affected views to be rendered.
3075:             *
3076:             * @since Java 3D 1.2
3077:             */
3078:            public void repaint() {
3079:                if (activeStatus && isRunning) {
3080:                    VirtualUniverse.mc.sendRunMessage(this ,
3081:                            J3dThread.RENDER_THREAD);
3082:                }
3083:            }
3084:
3085:            /**
3086:             * Update the view cache associated with this view.  Also, shapshot
3087:             * the per-screen parameters associated with all screens attached
3088:             * to this view.
3089:             */
3090:            final void updateViewCache() {
3091:
3092:                // TODO KCR : remove obsolete DVR code (but make sure we don't end
3093:                // up with a leak in the Viewer Map object).
3094:
3095:                // DVR support
3096:                // This is a back door in j3d to provide DVR support.
3097:                // A better place to put this code segment is in
3098:                // ViewCache.snapshot(). Since it consists of some 
3099:                // back door code, I've decided to put it here to isolate
3100:                // it from the rest of view snapshot code.
3101:                if (firstTime) {
3102:                    // System.err.println("View : First Time is " + firstTime);
3103:                    // viewer = Viewer.getViewer(this);
3104:                    // Since we've the handler to the viewer, we can remove the entry 
3105:                    // now to avoid confusion and prevent memory leak problem.
3106:                    viewer = Viewer.removeViewerMapEntry(this );
3107:                    firstTime = false;
3108:                }
3109:
3110:                //	if(viewer != null)  {
3111:                //	    if(viewer.isDvrEnabled()) {
3112:                //		dvrFactor = viewer.getDvrFactor();
3113:                //		dvrResizeCompensation = 
3114:                //		    viewer.getDvrResizeCompensationEnable();
3115:                //		/*
3116:                //		System.err.println("View : dvrFactor is " + dvrFactor);
3117:                //		System.err.println("View : dvrResizeCompensation is " + 
3118:                //				   dvrResizeCompensation);		 
3119:                //		*/
3120:                //	    }
3121:                //	    else {
3122:                //		// Reset back to default.
3123:                //		dvrFactor = 1.0f;
3124:                //		dvrResizeCompensation = true;
3125:                //
3126:                //	    }
3127:                //	}
3128:                // End of back door -- DVR.
3129:
3130:                synchronized (this ) {
3131:                    viewCache.snapshot();
3132:                    viewCache.computeDerivedData();
3133:                }
3134:
3135:                // Just take the brute force approach and snapshot the
3136:                // parameters for each screen attached to each canvas.  We won't
3137:                // worry about whether a screen is cached more than once.
3138:                // Eventually, dirty bits will take care of this.
3139:
3140:                synchronized (canvasList) {
3141:                    int i = canvases.size() - 1;
3142:                    while (i >= 0) {
3143:                        Screen3D scr = ((Canvas3D) canvases.elementAt(i--))
3144:                                .getScreen3D();
3145:                        if (scr != null)
3146:                            scr.updateViewCache();
3147:                    }
3148:                }
3149:            }
3150:
3151:            /** 
3152:             * This routine activates or deactivates a view based on various information
3153:             */
3154:            void evaluateActive() {
3155:
3156:                synchronized (evaluateLock) {
3157:                    if (universe == null) {
3158:                        return;
3159:                    }
3160:
3161:                    if ((viewPlatform == null)
3162:                            || !viewPlatform.isLive()
3163:                            || !((ViewPlatformRetained) viewPlatform.retained).switchState.currentSwitchOn) {
3164:                        if (activeStatus) {
3165:                            deactivate();
3166:                            activeStatus = false;
3167:                        }
3168:                        // Destroy threads from MC
3169:                        if (VirtualUniverse.mc.isRegistered(this )
3170:                                && (universe.isEmpty() || (canvases.isEmpty() && ((viewPlatform == null) || !viewPlatform
3171:                                        .isLive())))) {
3172:                            // We can't wait until MC finish unregister view
3173:                            // here because user thread may
3174:                            // holds the universe.sceneGraphLock if branch
3175:                            // or locale remove in clearLive(). In this way
3176:                            // There is deadlock since MC also need need
3177:                            // sceneGraphLock in some threads 
3178:                            // (e.g. TransformStructure update thread)
3179:                            universe.unRegViewWaiting = this ;
3180:                            resetUnivCount = universeCount;
3181:                            VirtualUniverse.mc.postRequest(
3182:                                    MasterControl.UNREGISTER_VIEW, this );
3183:                        }
3184:                    } else {
3185:
3186:                        // We're on a live view platform.  See what the canvases say
3187:                        // If view not register, MC will register it automatically
3188:
3189:                        int i;
3190:                        VirtualUniverse u = null;
3191:                        synchronized (canvasList) {
3192:
3193:                            for (i = canvases.size() - 1; i >= 0; i--) {
3194:                                Canvas3D cv = (Canvas3D) canvases.elementAt(i);
3195:                                if (cv.active) {
3196:
3197:                                    if (!activeStatus
3198:                                            && (universeCount > resetUnivCount)) {
3199:                                        u = universe;
3200:                                    }
3201:                                    break;
3202:                                }
3203:                            }
3204:                        }
3205:
3206:                        // We should do this outside canvasList lock,
3207:                        // otherwise it may cause deadlock with MC
3208:                        if (u != null) {
3209:                            activate(u);
3210:                            activeStatus = true;
3211:                            return;
3212:                        }
3213:
3214:                        if ((i < 0) && activeStatus) {
3215:                            deactivate();
3216:                            activeStatus = false;
3217:                            return;
3218:                        }
3219:
3220:                        if (VirtualUniverse.mc.isRegistered(this )) {
3221:                            // notify MC that canvases state for this view changed
3222:                            VirtualUniverse.mc.postRequest(
3223:                                    MasterControl.REEVALUATE_CANVAS, this );
3224:                        }
3225:                    }
3226:                }
3227:            }
3228:
3229:            void setUniverse(VirtualUniverse universe) {
3230:
3231:                synchronized (VirtualUniverse.mc.requestObjList) {
3232:                    if ((renderBin == null) || (renderBin.universe != universe)) {
3233:                        if (renderBin != null) {
3234:                            renderBin.cleanup();
3235:                        }
3236:                        renderBin = new RenderBin(universe, this );
3237:                        renderBin.universe = universe;
3238:                    }
3239:
3240:                    if ((soundScheduler == null)
3241:                            || (soundScheduler.universe != universe)) {
3242:                        // create a sound scheduler for this view, with this universe
3243:                        if (soundScheduler != null) {
3244:                            soundScheduler.cleanup();
3245:                        }
3246:                        soundScheduler = new SoundScheduler(universe, this );
3247:                    }
3248:
3249:                    // This has to be the last call before 
3250:                    // RenderBin and SoundScheduler construct. Since it is
3251:                    // possible that canvas receive paint call and invoked
3252:                    // evaluateActive in another thread - which check for
3253:                    // universe == null and may let it pass before soundScheduler
3254:                    // and renderBin initialize.
3255:                    universeCount++;
3256:                    this .universe = universe;
3257:                }
3258:                evaluateActive();
3259:            }
3260:
3261:            /**
3262:             * This activates all traversers and renderers associated with this view.
3263:             */
3264:            void activate(VirtualUniverse universe) {
3265:
3266:                universe.checkForEnableEvents();
3267:
3268:                if (physicalBody != null) {
3269:                    physicalBody.addUser(this );
3270:                }
3271:
3272:                if (!VirtualUniverse.mc.isRegistered(this )) {
3273:                    universe.regViewWaiting = this ;
3274:                }
3275:
3276:                VirtualUniverse.mc.postRequest(MasterControl.ACTIVATE_VIEW,
3277:                        this );
3278:
3279:                if (!universe.isSceneGraphLock) {
3280:                    universe.waitForMC();
3281:                }
3282:                if (soundScheduler != null) {
3283:                    soundScheduler.reset();
3284:                }
3285:
3286:                J3dMessage vpMessage = new J3dMessage();
3287:                vpMessage.universe = universe;
3288:                vpMessage.view = this ;
3289:                vpMessage.type = J3dMessage.UPDATE_VIEW;
3290:                vpMessage.threads = J3dThread.SOUND_SCHEDULER
3291:                        | J3dThread.UPDATE_RENDER | J3dThread.UPDATE_BEHAVIOR;
3292:                vpMessage.args[0] = this ;
3293:                synchronized (((ViewPlatformRetained) viewPlatform.retained).sphere) {
3294:                    vpMessage.args[1] = new Float(
3295:                            ((ViewPlatformRetained) viewPlatform.retained).sphere.radius);
3296:                }
3297:                vpMessage.args[2] = new Integer(OTHER_ATTRS_CHANGED);
3298:                vpMessage.args[3] = new Integer(transparencySortingPolicy);
3299:                VirtualUniverse.mc.processMessage(vpMessage);
3300:            }
3301:
3302:            /**
3303:             * This deactivates all traversers and renderers associated with this view.
3304:             */
3305:            void deactivate() {
3306:                VirtualUniverse.mc.postRequest(MasterControl.DEACTIVATE_VIEW,
3307:                        this );
3308:                if (physicalBody != null) {
3309:                    physicalBody.removeUser(this );
3310:                }
3311:
3312:                // This is a temporary fix for bug 4267395 
3313:                // XXXX:cleanup in RenderBin after View detach
3314:                // universe.addViewIdToFreeList(viewId);
3315:
3316:                // using new property -Dj3d.forceReleaseView to disable bug fix 4267395
3317:                // this bug fix can produce memory leaks in *some* applications which creates 
3318:                // and destroy Canvas3D from time to time. This just add the view in the 
3319:                // FreeList earlier.
3320:                if (VirtualUniverse.mc.forceReleaseView) {
3321:                    universe.addViewIdToFreeList(viewId);
3322:                }
3323:
3324:                J3dMessage vpMessage = new J3dMessage();
3325:                vpMessage.universe = universe;
3326:                vpMessage.view = this ;
3327:                vpMessage.type = J3dMessage.UPDATE_VIEW;
3328:                vpMessage.threads = J3dThread.SOUND_SCHEDULER
3329:                        | J3dThread.UPDATE_RENDER | J3dThread.UPDATE_BEHAVIOR;
3330:                vpMessage.args[0] = this ;
3331:                if (viewPlatform != null) {
3332:                    synchronized (((ViewPlatformRetained) viewPlatform.retained).sphere) {
3333:                        vpMessage.args[1] = new Float(
3334:                                ((ViewPlatformRetained) viewPlatform.retained).sphere.radius);
3335:                    }
3336:                } else {
3337:                    vpMessage.args[1] = new Float(0);
3338:                }
3339:                vpMessage.args[2] = new Integer(OTHER_ATTRS_CHANGED);
3340:                vpMessage.args[3] = new Integer(transparencySortingPolicy);
3341:                VirtualUniverse.mc.processMessage(vpMessage);
3342:
3343:            }
3344:
3345:            void cleanupViewId() {
3346:                universe.addViewIdToFreeList(viewId);
3347:                viewId = null;
3348:            }
3349:
3350:            void assignViewId() {
3351:                if (viewId == null) {
3352:                    viewId = universe.getViewId();
3353:                    viewIndex = viewId.intValue();
3354:                }
3355:            }
3356:
3357:            /**
3358:             * This method passes window event to SoundScheduler
3359:             */
3360:            void sendEventToSoundScheduler(AWTEvent evt) {
3361:                if (soundScheduler != null) {
3362:                    soundScheduler.receiveAWTEvent(evt);
3363:                }
3364:            }
3365:
3366:            void reset() {
3367:
3368:                for (int i = 0; i < canvases.size(); i++) {
3369:                    ((Canvas3D) canvases.get(i)).reset();
3370:                }
3371:
3372:                // reset the renderBinReady flag
3373:                renderBinReady = false;
3374:
3375:                soundScheduler.cleanup();
3376:                soundScheduler = null;
3377:                soundRenderer = new SoundRenderer();
3378:
3379:                viewCache = new ViewCache(this );
3380:                getCanvasList(true);
3381:                cleanupViewId();
3382:                renderBin.cleanup();
3383:                renderBin = null;
3384:                universe = null;
3385:            }
3386:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.