📄 canvasviewcache.java
字号:
} /** * Computes the viewing matrices. * * computeView computes the following: * * <ul> * left (& right) eye viewing matrices (only left is valid for mono view) * </ul> * * This call works for both fixed screen and HMD displays. */ private void computeView(boolean doInfinite) { int i,j; int backClipPolicy; double Fl, Fr, B, scale, backClipDistance; // compute scale used for transforming clip and fog distances vworldToCoexistenceScale = vworldToVpc.getDistanceScale() * vpcToCoexistence.getDistanceScale(); if(doInfinite) { infVworldToCoexistenceScale = infVworldToVpc.getDistanceScale() * vpcToCoexistence.getDistanceScale(); } if((J3dDebug.devPhase) && (J3dDebug.canvasViewCache >= J3dDebug.LEVEL_2)) { System.err.println("vworldToCoexistenceScale = " + vworldToCoexistenceScale); } // compute coexistenceToVworld transform -- dirty bit candidate!! tempTrans.mul(viewCache.coexistenceToTrackerBase, vpcToCoexistence); vworldToTrackerBase.mul(tempTrans, vworldToVpc); // If we are in compatibility mode, compute the view and // projection matrices accordingly if (viewCache.compatibilityModeEnable) { leftProjection.set(viewCache.compatLeftProjection); leftVpcToEc.set(viewCache.compatVpcToEc); if((J3dDebug.devPhase) && (J3dDebug.canvasViewCache >= J3dDebug.LEVEL_1)) { System.err.println("Left projection and view matrices"); System.err.println("ecToCc (leftProjection) :"); System.err.println(leftProjection); System.err.println("vpcToEc:"); System.err.println(leftVpcToEc); } computeFrustumPlanes(leftProjection, leftVpcToEc, leftFrustumPlanes, leftFrustumPoints, leftCcToVworld); if(useStereo) { rightProjection.set(viewCache.compatRightProjection); rightVpcToEc.set(viewCache.compatVpcToEc); if((J3dDebug.devPhase) && (J3dDebug.canvasViewCache >= J3dDebug.LEVEL_1)) { System.err.println("Right projection and view matrices"); System.err.println("ecToCc:"); System.err.println("vpcToEc:"); System.err.println(rightVpcToEc); } computeFrustumPlanes(rightProjection, rightVpcToEc, rightFrustumPlanes, rightFrustumPoints, rightCcToVworld); } return; } // // The clipping plane distances are set from the internal policy. // // Note that the plane distance follows the standard Z axis // convention, e.g. negative numbers further away. // Note that for policy from eye, the distance is negative in // the direction of z in front of the eye. // Note that for policy from screen, the distance is negative for // locations behind the screen, and positive in front. // // The distance attributes are measured either in physical (plate) // units, or vworld units. // // Compute scale factor for front clip plane computation if (viewCache.frontClipPolicy == View.VIRTUAL_EYE || viewCache.frontClipPolicy == View.VIRTUAL_SCREEN) { scale = vworldToCoexistenceScale; } else { scale = windowScale; } // Set left and right front clipping plane distances. if(viewCache.frontClipPolicy == View.PHYSICAL_EYE || viewCache.frontClipPolicy == View.VIRTUAL_EYE) { Fl = leftEyeInImagePlate.z + scale * -viewCache.frontClipDistance; Fr = rightEyeInImagePlate.z + scale * -viewCache.frontClipDistance; } else { Fl = scale * -viewCache.frontClipDistance; Fr = scale * -viewCache.frontClipDistance; } // if there is an active clip node, use it and ignore the view's // backclip if ((renderBin != null) && (renderBin.backClipActive)) { backClipPolicy = View.VIRTUAL_EYE; backClipDistance = renderBin.backClipDistanceInVworld; } else { backClipPolicy = viewCache.backClipPolicy; backClipDistance = viewCache.backClipDistance; } // Compute scale factor for rear clip plane computation if (backClipPolicy == View.VIRTUAL_EYE || backClipPolicy == View.VIRTUAL_SCREEN) { scale = vworldToCoexistenceScale; } else { scale = windowScale; } // Set left and right rear clipping plane distnaces. if(backClipPolicy == View.PHYSICAL_EYE || backClipPolicy == View.VIRTUAL_EYE) { // Yes, left for both left and right rear. B = leftEyeInImagePlate.z + scale * -backClipDistance; } else { B = scale * -backClipDistance; } // XXXX: Can optimize for HMD case. if (true /*viewCache.viewPolicy != View.HMD_VIEW*/) { // Call buildProjView to build the projection and view matrices. if((J3dDebug.devPhase) && (J3dDebug.canvasViewCache >= J3dDebug.LEVEL_2)) { System.err.println("Left projection and view matrices"); System.err.println("Fl " + Fl + " B " + B); System.err.println("leftEyeInImagePlate\n" + leftEyeInImagePlate); System.err.println("Before : leftProjection\n" + leftProjection); System.err.println("Before leftVpcToEc\n" + leftVpcToEc); } buildProjView(leftEyeInImagePlate, coexistenceToLeftPlate, vpcToLeftPlate, Fl, B, leftProjection, leftVpcToEc, false); if((J3dDebug.devPhase) && (J3dDebug.canvasViewCache >= J3dDebug.LEVEL_2)) { System.err.println("After : leftProjection\n" + leftProjection); System.err.println("After leftVpcToEc\n" + leftVpcToEc); } computeFrustumPlanes(leftProjection, leftVpcToEc, leftFrustumPlanes, leftFrustumPoints, leftCcToVworld); if(useStereo) { if((J3dDebug.devPhase) && (J3dDebug.canvasViewCache >= J3dDebug.LEVEL_2)) System.err.println("Right projection and view matrices"); buildProjView(rightEyeInImagePlate, coexistenceToRightPlate, vpcToRightPlate, Fr, B, rightProjection, rightVpcToEc, false); computeFrustumPlanes(rightProjection, rightVpcToEc, rightFrustumPlanes, rightFrustumPoints, rightCcToVworld); } // // Now to compute the left (& right) eye (and infinite) // viewing matrices. if(doInfinite) { // Call buildProjView separately for infinite view buildProjView(leftEyeInImagePlate, coexistenceToLeftPlate, vpcToLeftPlate, leftEyeInImagePlate.z - 0.05, leftEyeInImagePlate.z - 1.5, infLeftProjection, infLeftVpcToEc, true); if(useStereo) { buildProjView(rightEyeInImagePlate, coexistenceToRightPlate, vpcToRightPlate, rightEyeInImagePlate.z - 0.05, rightEyeInImagePlate.z - 1.5, infRightProjection, infRightVpcToEc, true); } } } // XXXX: The following code has never been ported// else {// Point3d cen_eye;//// // HMD case. Just concatenate the approprate matrices together.// // Additional work just for now//// compute_lr_plate_to_cc( &cen_eye, Fl, B, 0, &vb, 0);//// if(useStereo) {// mat_mul_dpt(&right_eye_pos_in_head,// head_to_right_plate, &cen_eye);// compute_lr_plate_to_cc( &cen_eye, Fr, B,// 1, &vb, 0);// }//// // Make sure that coexistence_to_plate is current.// // (It is usually constant for fixed plates, always varies for HMDs.)// // For HMD case, computes finial matrices that will be used.// //// computeCoexistenceToPlate();// } } /** * Debugging routine to analyze the projection matrix. */ private void analyzeProjection(Transform3D p, double xMax) { if (viewCache.projectionPolicy == View.PARALLEL_PROJECTION) System.err.println("PARALLEL_PROJECTION ="); else System.err.println("PERSPECTIVE_PROJECTION ="); System.err.println(p); double projectionPlaneZ = ((p.mat[0] * xMax + p.mat[3] - p.mat[15]) / (p.mat[14] - p.mat[2])); System.err.println("projection plane at z = " + projectionPlaneZ); } /** * buildProjView creates a projection and viewing matrix. * * Inputs: * ep : eye point, in plate coordinates * coe2Plate : matrix from coexistence to image plate. * F, B : front, back clipping planes, in plate coordinates * doInfinite : flag to indicate ``at infinity'' view desired * * Output: * vpc2Plate : matric from vpc to image plate. * ecToCc : projection matrix from Eye Coordinates (EC) * to Clipping Coordinates (CC) * vpcToEc : view matrix from ViewPlatform Coordinates (VPC) * to Eye Coordinates (EC) */ private void buildProjView(Point3d ep, Transform3D coe2Plate, Transform3D vpc2Plate, double F, double B, Transform3D ecToCc, Transform3D vpcToEc, boolean doInfinite) { // Lx,Ly Hx,Hy will be adjusted window boundaries double Lx, Hx, Ly, Hy; Lx = physicalWindowXLeft; Hx = physicalWindowXRight; Ly = physicalWindowYBottom; Hy = physicalWindowYTop; ecToCc.setIdentity(); // XXXX: we have no concept of glass correction in the Java 3D API // // Correction in apparent 3D position of window due to glass/CRT // and spherical/cylinderical curvarure of CRT. // This boils down to producing modified values of Lx Ly Hx Hy // and is different for hot spot vs. window center corrections. // /* XXXX: double cx, cy; if(viewPolicy != HMD_VIEW && enable_crt_glass_correction) { if (correction_point == CORRECTION_POINT_WINDOW_CENTER) { correct_crt( ep, Lx, Ly, &cx, &cy); Lx = cx; Ly = cy; correct_crt( ep, Hx, Hy, &cx, &cy); Hx = cx; Hy = cy; } else { // must be hot spot correction // Not real code yet, for now just do same as above. correct_crt( ep, Lx, Ly, &cx, &cy); Lx = cx; Ly = cy; correct_crt( ep, Hx, Hy, &cx, &cy); Hx = cx; Hy = cy; } } */ if((J3dDebug.devPhase) && (J3dDebug.canvasViewCache >= J3dDebug.LEVEL_2)) { System.err.println("ep = " + ep); System.err.println("Lx = " + Lx + ", Hx = " + Hx); System.err.println("Ly = " + Ly + ", Hy = " + Hy); System.err.println("F = " + F + ", B = " + B); } // Compute the proper projection equation. Note that we // do this in two steps: first we generate ImagePlateToCc, // then we translate this by EcToPlate, resulting in a // projection from EctoCc. // // A more efficient (and more accurate) approach would be to // modify the equations below to directly project from EcToCc. if (viewCache.projectionPolicy == View.PARALLEL_PROJECTION) { double inv_dx, inv_dy, inv_dz; inv_dx = 1.0 / (Hx - Lx); inv_dy = 1.0 / (Hy - Ly); inv_dz = 1.0 / (F - B); ecToCc.mat[0] = 2.0 * inv_dx; ecToCc.mat[3] = -(Hx + Lx) * inv_dx; ecToCc.mat[5] = 2.0 * inv_dy; ecToCc.mat[7] = -(Hy + Ly) * inv_dy; ecToCc.mat[10] = 2.0 * inv_dz; ecToCc.mat[11] = -(F + B) * inv_dz; } else { double sxy, rzb, inv_dx, inv_dy; inv_dx = 1.0 / (Hx - Lx); inv_dy = 1.0 / (Hy - Ly); rzb = 1.0/(ep.z - B); sxy = ep.z*rzb; ecToCc.mat[0] = sxy*2.0*inv_dx; ecToCc.mat[5] = sxy*2.0*inv_dy; ecToCc.mat[2] = rzb*(Hx+Lx - 2.0*ep.x)*inv_dx; ecToCc.mat[6] = rzb*(Hy+Ly - 2.0*ep.y)*inv_dy; ecToCc.mat[10] = rzb*(B+F-2*ep.z)/(B-F); ecToCc.mat[14] = -rzb; ecToCc.mat[3] = sxy*(-Hx-Lx)*inv_dx; ecToCc.mat[7] = sxy*(-Hy-Ly)*inv_dy; ecToCc.mat[11] = rzb*(B - ep.z - B*(B+F - 2*ep.z)/(B-F)); ecToCc.mat[15] = sxy; } // Since we set the matrix elements ourselves, we need to set the // type field. A value of 0 means a non-affine matrix. ecToCc.setOrthoDirtyBit(); // EC to ImagePlate matrix is a simple translation. tVec1.set(ep.x, ep.y, ep.z); tMat1.set(tVec1); ecToCc.mul(tMat1); if((J3dDebug.devPhase) && (J3dDebug.canvasViewCache >= J3dDebug.LEVEL_2)) { System.err.println("ecToCc:"); analyzeProjection(ecToCc, Hx); } if(!doInfinite) { // View matrix is: // [plateToEc] [coexistence_to_plate] [vpc_to_coexistence] // where vpc_to_coexistence includes the viewPlatformScale // First compute ViewPlatform to Plate vpc2Plate.mul(coe2Plate, vpcToCoexistence); // ImagePlate to EC matrix is a simple translation. tVec1.set(-ep.x, -ep.y, -ep.z); tMat1.set(tVec1); vpcToEc.mul(tMat1, vpc2Plate); if((J3dDebug.devPhase) && (J3dDebug.canvasViewCache >= J3dDebug.LEVEL_2)) { System.err.println("vpcToEc:"); System.err.println(vpcToEc); } } else { // Final infinite composite is: // [coexistence_to_eye] [vpc_to_coexistence (vom)] // (does vworld_to_coe_scale_factor get used here??? ) // // The method is to relocate the coexistence org centered on // the eye rather than the window center (via coexistence_to_eye). // Computationaly simpler simplifed equation form may exist. // coexistence to eye is a simple translation./* tVec1.set(ep.x, ep.y, ep.z); tMat1.set(tVec1); vpcToEc.mul(tMat1, vpcToCoexistence); // First compute ViewPlatform to Plate vpcToPlate.mul(coexistenceToPlatevpcToPlate, vpcToCoexistence);*/ // ImagePlate to EC matrix is a simple translation. tVec1.set(-ep.x, -ep.y, -ep.z); tMat1.set(tVec1); tMat1.mul(tMat1, vpc2Plate); tMat1.getRotation(vpcToEc); // use only rotation component of transform } } /** * Compute the plane equations for the frustum in ViewPlatform * coordinates, plus its viewing frustum points. ccToVworld will
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -