📄 viewinfo.java
字号:
* This method requires a Canvas3D. A different transform may be returned * for each canvas in the view if any of the following apply:<p><ul> * * <li>The window resize policy is <code>PHYSICAL_WORLD</code>, which * alters the scale depending upon the width of the canvas.</li><p> * * <li>The screen scale policy is <code>SCALE_SCREEN_SIZE</code>, * which alters the scale depending upon the width of the screen * associated with the canvas.</li><p> * * <li>A window eyepoint policy of <code>RELATIVE_TO_FIELD_OF_VIEW</code> * with a view attach policy of <code>NOMINAL_HEAD</code> in effect, * which sets the view platform Z offset in coexistence coordinates * based on the width of the canvas. These are the default policies. * The offset also follows the width of the canvas when the * <code>NOMINAL_FEET</code> view attach policy is used.</li></ul> * * @param c3d the Canvas3D to use * @param vp2coe the Transform3D to receive the transform */ public void getViewPlatformToCoexistence(Canvas3D c3d, Transform3D vp2coe) { CanvasInfo ci = updateCache (c3d, "getViewPlatformToCoexistence", false) ; getViewPlatformToCoexistence(ci) ; vp2coe.set(ci.viewPlatformToCoe) ; } private void getViewPlatformToCoexistence(CanvasInfo ci) { if (!ci.updateViewPlatformToCoe) return ; if (verbose) System.err.println("updating ViewPlatformToCoe") ; if (ci.viewPlatformToCoe == null) ci.viewPlatformToCoe = new Transform3D() ; // // The scale from view platform coordinates to coexistence coordinates // has two components -- the screen scale and the window scale. The // window scale only applies if the resize policy is PHYSICAL_WORLD. // // This scale is not the same as the vworld to view platform scale. // The latter is contained in the view platform's localToVworld // transform as defined by the scene graph. The complete scale factor // from virtual units to physical units is the product of the vworld // to view platform scale and the view platform to coexistence scale. // getScreenScale(ci) ; if (resizePolicy == View.PHYSICAL_WORLD) ci.viewPlatformToCoe.setScale(ci.screenScale * ci.windowScale) ; else ci.viewPlatformToCoe.setScale(ci.screenScale) ; if (viewPolicy == View.HMD_VIEW) { // In HMD mode view platform coordinates are the same as // coexistence coordinates, except for scale. ci.updateViewPlatformToCoe = false ; return ; } // // Otherwise, get the offset of the origin of view platform // coordinates relative to the origin of coexistence. This is is // specified by two policies: the view platform's view attach policy // and the physical environment's coexistence center in pworld policy. // double eyeOffset ; double eyeHeight = body.getNominalEyeHeightFromGround() ; int viewAttachPolicy = view.getViewPlatform().getViewAttachPolicy() ; int pworldAttachPolicy = env.getCoexistenceCenterInPworldPolicy() ; if (eyePolicy == View.RELATIVE_TO_FIELD_OF_VIEW) // The view platform origin is the same as the eye position. eyeOffset = ci.getFieldOfViewOffset() ; else // The view platform origin is independent of the eye position. eyeOffset = body.getNominalEyeOffsetFromNominalScreen() ; if (pworldAttachPolicy == View.NOMINAL_SCREEN) { // The default. The physical coexistence origin locates the // nominal screen. This is rarely, if ever, set to anything // else, and the intended effects of the other settings are // not well documented. if (viewAttachPolicy == View.NOMINAL_HEAD) { // The default. The view platform origin is at the origin // of the nominal head in coexistence coordinates, offset // from the screen along +Z. If the window eyepoint // policy is RELATIVE_TO_FIELD_OF_VIEW, then the eyepoint // is the same as the view platform origin. v3d.set(0.0, 0.0, eyeOffset) ; } else if (viewAttachPolicy == View.NOMINAL_SCREEN) { // View platform and coexistence are the same except for // scale. v3d.set(0.0, 0.0, 0.0) ; } else { // The view platform origin is at the ground beneath the // head. v3d.set(0.0, -eyeHeight, eyeOffset) ; } } else if (pworldAttachPolicy == View.NOMINAL_HEAD) { // The physical coexistence origin locates the nominal head. if (viewAttachPolicy == View.NOMINAL_HEAD) { // The view platform origin is set to the head; // coexistence and view platform coordinates differ only // in scale. v3d.set(0.0, 0.0, 0.0) ; } else if (viewAttachPolicy == View.NOMINAL_SCREEN) { // The view platform is set in front of the head, at the // nominal screen location. v3d.set(0.0, 0.0, -eyeOffset) ; } else { // The view platform origin is at the ground beneath the // head. v3d.set(0.0, -eyeHeight, 0.0) ; } } else { // The physical coexistence origin locates the nominal feet. if (viewAttachPolicy == View.NOMINAL_HEAD) { v3d.set(0.0, eyeHeight, 0.0) ; } else if (viewAttachPolicy == View.NOMINAL_SCREEN) { v3d.set(0.0, eyeHeight, -eyeOffset) ; } else { v3d.set(0.0, 0.0, 0.0) ; } } ci.viewPlatformToCoe.setTranslation(v3d) ; ci.updateViewPlatformToCoe = false ; if (verbose) t3dPrint(ci.viewPlatformToCoe, "vpToCoe") ; } /** * Gets the current transform from coexistence coordinates to * view platform coordinates and copies it into the given transform.<p> * * This method requires a Canvas3D. The returned transform may differ * across canvases for the same reasons as discussed in the description of * <code>getViewPlatformToCoexistence</code>.<p> * * @param c3d the Canvas3D to use * @param coe2vp the Transform3D to receive the transform * @see #getViewPlatformToCoexistence * getViewPlatformToCoexistence(Canvas3D, Transform3D) */ public void getCoexistenceToViewPlatform(Canvas3D c3d, Transform3D coe2vp) { CanvasInfo ci = updateCache (c3d, "getCoexistenceToViewPlatform", false) ; getCoexistenceToViewPlatform(ci) ; coe2vp.set(ci.coeToViewPlatform) ; } private void getCoexistenceToViewPlatform(CanvasInfo ci) { if (ci.updateCoeToViewPlatform) { if (verbose) System.err.println("updating CoeToViewPlatform") ; if (ci.coeToViewPlatform == null) ci.coeToViewPlatform = new Transform3D() ; getViewPlatformToCoexistence(ci) ; ci.coeToViewPlatform.invert(ci.viewPlatformToCoe) ; ci.updateCoeToViewPlatform = false ; if (verbose) t3dPrint(ci.coeToViewPlatform, "coeToVp") ; } } /** * Gets the current transform from coexistence coordinates to virtual * world coordinates and copies it into the given transform.<p> * * The View must be attached to a ViewPlatform which is part of a live * scene graph, and the ViewPlatform node must have its * <code>ALLOW_LOCAL_TO_VWORLD_READ</code> capability set.<p> * * This method requires a Canvas3D. The returned transform may differ * across canvases for the same reasons as discussed in the description of * <code>getViewPlatformToCoexistence</code>.<p> * * @param c3d the Canvas3D to use * @param coe2vw the Transform3D to receive the transform * @see #getViewPlatformToCoexistence * getViewPlatformToCoexistence(Canvas3D, Transform3D) */ public void getCoexistenceToVworld(Canvas3D c3d, Transform3D coe2vw) { CanvasInfo ci = updateCache(c3d, "getCoexistenceToVworld", true) ; getCoexistenceToVworld(ci) ; coe2vw.set(ci.coeToVworld) ; } private void getCoexistenceToVworld(CanvasInfo ci) { if (ci.updateCoeToVworld) { if (verbose) System.err.println("updating CoexistenceToVworld") ; if (ci.coeToVworld == null) ci.coeToVworld = new Transform3D() ; getCoexistenceToViewPlatform(ci) ; ci.coeToVworld.mul(vpi.viewPlatformToVworld, ci.coeToViewPlatform) ; ci.updateCoeToVworld = false ; } } /** * Gets the transforms from eye coordinates to image plate coordinates and * copies them into the Transform3Ds specified.<p> * * When head tracking is used the eye positions are taken from the head * position and set in relation to the image plates with each Screen3D's * <code>trackerBaseToImagePlate</code> transform. Otherwise the window * eyepoint policy is used to derive the eyepoint relative to the image * plate. When using a head mounted display the eye position is * determined solely by calibration constants in Screen3D and * PhysicalBody; see the source code for the private method * <code>getEyesHMD</code> for more information.<p> * * Eye coordinates are always aligned with image plate coordinates, so * these transforms are always just translations. With a monoscopic * canvas the eye transform is copied to the first argument and the second * argument is not used. For a stereo canvas the first argument receives * the left eye transform, and if the second argument is non-null it * receives the right eye transform. * * @param c3d the Canvas3D associated with the image plate * @param e2ipl the Transform3D to receive left transform * @param e2ipr the Transform3D to receive right transform, or null */ public void getEyeToImagePlate(Canvas3D c3d, Transform3D e2ipl, Transform3D e2ipr) { CanvasInfo ci = updateCache(c3d, "getEyeToImagePlate", false) ; getEyeToImagePlate(ci) ; e2ipl.set(ci.eyeToPlate) ; if (ci.useStereo && e2ipr != null) e2ipr.set(ci.rightEyeToPlate) ; } private void getEyeToImagePlate(CanvasInfo ci) { if (ci.updateEyeInPlate) { if (verbose) System.err.println("updating EyeInPlate") ; if (ci.eyeToPlate == null) ci.eyeToPlate = new Transform3D() ; if (viewPolicy == View.HMD_VIEW) { getEyesHMD(ci) ; } else if (useTracking) { getEyesTracked(ci) ; } else { getEyesFixedScreen(ci) ; } ci.updateEyeInPlate = false ; if (verbose) System.err.println("eyeInPlate: " + ci.eyeInPlate) ; } } // // Get physical eye positions for head mounted displays. These are // determined solely by the headTrackerToImagePlate and headToHeadTracker // calibration constants defined by Screen3D and the PhysicalBody. // // Note that headTrackerLeftToImagePlate and headTrackerToRightImagePlate // should be set according to the *apparent* position and orientation of // the image plates, relative to the head and head tracker, as viewed // through the HMD optics. This is also true of the "physical" screen // width and height specified by the Screen3D -- they should be the // *apparent* width and height as viewed through the HMD optics. They // must be set directly through the Screen3D methods; the default pixel // metrics of 90 pixels/inch used by Java 3D aren't appropriate for HMD // optics. // // Most HMDs have 100% overlap between the left and right displays; in // that case, headTrackerToLeftImagePlate and headTrackerToRightImagePlate // should be identical. The HMD manufacturer's specifications of the // optics in terms of field of view, image overlap, and distance to the // focal plane should be used to derive these parameters. // private void getEyesHMD(CanvasInfo ci) { if (ci.useStereo) { // This case is for head mounted displays driven by a single // stereo canvas on a single screen. These use a field sequential // stereo signal to split the left and right images. leftEye.set(leftEyeInHead) ; headToHeadTracker.transform(leftEye) ; ci.si.headTrackerToLeftPlate.transform(leftEye, ci.eyeInPlate) ; rightEye.set(rightEyeInHead) ; headToHeadTracker.transform(rightEye) ; ci.si.headTrackerToRightPlate.transform(rightEye, ci.rightEyeInPlate) ; if (ci.rightEyeToPlate == null) ci.rightEyeToPlate = new Transform3D() ; v3d.set(ci.rightEyeInPlate) ; ci.rightEyeToPlate.set(v3d) ; } else { // This case is for 2-channel head mounted displays driven by two // monoscopic screens, one for each eye. switch (ci.monoscopicPolicy) { case View.LEFT_EYE_VIEW:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -